@forcefield/mcp-server 0.1.9 → 0.1.11

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.
@@ -48,7 +48,78 @@ import { join as join3 } from "path";
48
48
  import { access as access2 } from "fs/promises";
49
49
  import { dirname, join as join2 } from "path";
50
50
  import { fileURLToPath } from "url";
51
+
52
+ // package.json
53
+ var package_default = {
54
+ name: "@forcefield/mcp-server",
55
+ version: "0.1.11",
56
+ description: "AI-powered corporate compliance MCP server",
57
+ license: "UNLICENSED",
58
+ type: "module",
59
+ publishConfig: {
60
+ access: "public",
61
+ tag: "beta"
62
+ },
63
+ bin: {
64
+ forcefield: "build/cli/index.js",
65
+ "forcefield-mcp": "build/index.js",
66
+ "forcefield-setup": "build/cli/index.js"
67
+ },
68
+ files: [
69
+ "build/",
70
+ "workflows/"
71
+ ],
72
+ engines: {
73
+ node: ">=20.0.0"
74
+ },
75
+ repository: {
76
+ type: "git",
77
+ url: "git+https://github.com/forcefield-ai/forcefield.git"
78
+ },
79
+ keywords: [
80
+ "mcp",
81
+ "compliance",
82
+ "corporate",
83
+ "formation",
84
+ "cap-table"
85
+ ],
86
+ scripts: {
87
+ build: "tsup",
88
+ dev: "tsup --watch",
89
+ "release:check": "node --import tsx scripts/check-release-policy.ts",
90
+ prepublishOnly: "npm run release:check && npm run build",
91
+ "seed:data": "tsx scripts/seed-static-content.ts",
92
+ "local:user": "tsx scripts/local-user.ts"
93
+ },
94
+ dependencies: {
95
+ "@clack/prompts": "^1.0.1",
96
+ "@modelcontextprotocol/sdk": "^1.26.0",
97
+ "@supabase/supabase-js": "^2.97.0",
98
+ exceljs: "^4.4.0",
99
+ figlet: "^1.10.0",
100
+ "gradient-string": "^3.0.0",
101
+ "html-to-docx": "^1.8.0",
102
+ "markdown-it": "^14.1.1",
103
+ mupdf: "^1.27.0",
104
+ officeparser: "^5.1.1",
105
+ "pdfjs-dist": "^4.10.38",
106
+ picocolors: "^1.1.1",
107
+ "tesseract.js": "^5.1.1",
108
+ zod: "^4.3.6"
109
+ },
110
+ devDependencies: {
111
+ "@forcefield/shared": "workspace:*",
112
+ "@types/figlet": "^1.7.0",
113
+ "@types/gradient-string": "^1.1.6",
114
+ "@types/markdown-it": "^14.1.2"
115
+ }
116
+ };
117
+
118
+ // setup/ide-adapters/mcp-runtime.ts
51
119
  var __dirname = dirname(fileURLToPath(import.meta.url));
120
+ var MCP_PACKAGE_NAME = "@forcefield/mcp-server";
121
+ var DEFAULT_NPM_REGISTRY_URL = "https://registry.npmjs.org";
122
+ var NPM_METADATA_TIMEOUT_MS = 2e3;
52
123
  var LOCAL_ENTRY_CANDIDATES = [
53
124
  join2(__dirname, "..", "..", "build", "index.js"),
54
125
  join2(__dirname, "..", "..", "index.js")
@@ -60,6 +131,100 @@ var FORWARDED_ENV_KEYS = [
60
131
  "FORCEFIELD_DISABLE_GATING",
61
132
  "FORCEFIELD_LOCAL_DATA_FALLBACK"
62
133
  ];
134
+ var metadataCache = null;
135
+ function getEnv(name) {
136
+ const value = process.env[name];
137
+ if (!value) return void 0;
138
+ const trimmed = value.trim();
139
+ return trimmed.length > 0 ? trimmed : void 0;
140
+ }
141
+ function getLocalPackageVersion() {
142
+ const version = typeof package_default === "object" && package_default && "version" in package_default ? package_default.version : void 0;
143
+ return version?.trim() || void 0;
144
+ }
145
+ function getDefaultDistTag() {
146
+ const publishConfig = typeof package_default === "object" && package_default && "publishConfig" in package_default ? package_default.publishConfig : void 0;
147
+ const packageTag = publishConfig && typeof publishConfig.tag === "string" ? publishConfig.tag.trim() : "";
148
+ return packageTag || "latest";
149
+ }
150
+ function getTargetDistTag() {
151
+ return getEnv("FORCEFIELD_SETUP_MCP_DIST_TAG") ?? getDefaultDistTag();
152
+ }
153
+ function getRegistryUrl() {
154
+ const configured = getEnv("FORCEFIELD_NPM_REGISTRY_URL") ?? DEFAULT_NPM_REGISTRY_URL;
155
+ return configured.replace(/\/+$/, "");
156
+ }
157
+ function getPackageOverride() {
158
+ return getEnv("FORCEFIELD_SETUP_MCP_PACKAGE");
159
+ }
160
+ function isExactVersion(value) {
161
+ return /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(value);
162
+ }
163
+ function extractExactMcpVersion(specifier) {
164
+ const prefix = `${MCP_PACKAGE_NAME}@`;
165
+ if (!specifier.startsWith(prefix)) return void 0;
166
+ const version = specifier.slice(prefix.length).trim();
167
+ if (!isExactVersion(version)) return void 0;
168
+ return version;
169
+ }
170
+ async function fetchPackageMetadata(registryUrl) {
171
+ const encodedPackage = encodeURIComponent(MCP_PACKAGE_NAME);
172
+ const endpoint = `${registryUrl}/${encodedPackage}`;
173
+ try {
174
+ const response = await fetch(endpoint, {
175
+ headers: {
176
+ Accept: "application/json"
177
+ },
178
+ signal: AbortSignal.timeout(NPM_METADATA_TIMEOUT_MS)
179
+ });
180
+ if (!response.ok) {
181
+ return null;
182
+ }
183
+ const payload = await response.json();
184
+ if (!payload || typeof payload !== "object") {
185
+ return null;
186
+ }
187
+ return payload;
188
+ } catch {
189
+ return null;
190
+ }
191
+ }
192
+ async function getPackageMetadata(registryUrl) {
193
+ if (metadataCache && metadataCache.registryUrl === registryUrl) {
194
+ return metadataCache.promise;
195
+ }
196
+ const promise = fetchPackageMetadata(registryUrl);
197
+ metadataCache = { registryUrl, promise };
198
+ return promise;
199
+ }
200
+ async function resolvePackageSpecifier() {
201
+ const override = getPackageOverride();
202
+ if (override) return override;
203
+ const localVersion = getLocalPackageVersion();
204
+ const targetDistTag = getTargetDistTag();
205
+ if (isExactVersion(targetDistTag)) {
206
+ return `${MCP_PACKAGE_NAME}@${targetDistTag}`;
207
+ }
208
+ const metadata = await getPackageMetadata(getRegistryUrl());
209
+ if (!metadata) {
210
+ return `${MCP_PACKAGE_NAME}@${targetDistTag}`;
211
+ }
212
+ if (localVersion && metadata.versions && localVersion in metadata.versions) {
213
+ return `${MCP_PACKAGE_NAME}@${localVersion}`;
214
+ }
215
+ const distTags = metadata["dist-tags"];
216
+ const pinnedDistTagVersion = distTags && typeof distTags[targetDistTag] === "string" ? String(distTags[targetDistTag]).trim() : "";
217
+ if (pinnedDistTagVersion) {
218
+ return `${MCP_PACKAGE_NAME}@${pinnedDistTagVersion}`;
219
+ }
220
+ return `${MCP_PACKAGE_NAME}@${targetDistTag}`;
221
+ }
222
+ async function isMcpVersionPublished(version) {
223
+ if (!isExactVersion(version)) return false;
224
+ const metadata = await getPackageMetadata(getRegistryUrl());
225
+ if (!metadata) return null;
226
+ return Boolean(metadata.versions && version in metadata.versions);
227
+ }
63
228
  function isTruthy(value) {
64
229
  if (!value) return false;
65
230
  const normalized = value.trim().toLowerCase();
@@ -85,9 +250,10 @@ async function getMcpLaunchConfig() {
85
250
  };
86
251
  }
87
252
  }
253
+ const packageSpecifier = await resolvePackageSpecifier();
88
254
  return {
89
255
  command: "npx",
90
- args: ["-y", "-p", "@forcefield/mcp-server", "forcefield-mcp"]
256
+ args: ["-y", "-p", packageSpecifier, "forcefield-mcp"]
91
257
  };
92
258
  }
93
259
  function buildMcpEnv(apiKey) {
@@ -629,7 +795,7 @@ var WORKFLOW_DIR_CANDIDATES = [
629
795
  join7(__dirname2, "..", "..", "workflows")
630
796
  ];
631
797
  var CONFIG_FILE = ".forcefield.json";
632
- var VERSION = "0.1.9";
798
+ var VERSION = "0.1.11";
633
799
  var BANNER_TEXT = "Forcefield";
634
800
  var BANNER_FONT = "Rowan Cap";
635
801
  var BANNER_MIN_COLUMNS = 80;
@@ -718,6 +884,10 @@ async function runDoctor(projectDir, args) {
718
884
  label: "MCP config",
719
885
  detail: `${mcp.filePath} \u2014 ${mcp.detail}`
720
886
  });
887
+ const packageCheck = await evaluateMcpPackageSpecifier(mcp.packageSpecifier);
888
+ if (packageCheck) {
889
+ checks.push(packageCheck);
890
+ }
721
891
  if (mcp.key) {
722
892
  const verified = await verifyApiKey(mcp.key, {
723
893
  localDev: isLocalSetupMode(args),
@@ -795,15 +965,18 @@ async function inspectJsonMcpConfig(filePath, rootKey) {
795
965
  }
796
966
  const ffServer = servers.forcefield;
797
967
  const command = typeof ffServer.command === "string" ? ffServer.command : "";
968
+ const args = Array.isArray(ffServer.args) ? ffServer.args : [];
798
969
  const env = typeof ffServer.env === "object" && ffServer.env != null ? ffServer.env : {};
799
970
  const key = typeof env.FORCEFIELD_API_KEY === "string" ? env.FORCEFIELD_API_KEY : void 0;
800
971
  const supabaseUrl = typeof env.SUPABASE_URL === "string" ? env.SUPABASE_URL : void 0;
972
+ const packageSpecifier = extractPackageSpecifierFromNpxArgs(args);
801
973
  if (!command) {
802
974
  return {
803
975
  ok: false,
804
976
  filePath,
805
977
  key,
806
978
  supabaseUrl,
979
+ packageSpecifier,
807
980
  detail: "forcefield entry missing command."
808
981
  };
809
982
  }
@@ -812,6 +985,7 @@ async function inspectJsonMcpConfig(filePath, rootKey) {
812
985
  filePath,
813
986
  key,
814
987
  supabaseUrl,
988
+ packageSpecifier,
815
989
  detail: `Found forcefield entry (command: ${command}${supabaseUrl ? `, supabase: ${supabaseUrl}` : ""}).`
816
990
  };
817
991
  }
@@ -829,6 +1003,10 @@ async function inspectCodexMcpConfig(filePath) {
829
1003
  const command = extractTomlValue(raw, /^\s*command\s*=\s*"([^"]+)"/m);
830
1004
  const key = extractTomlValue(raw, /^\s*FORCEFIELD_API_KEY\s*=\s*"([^"]+)"/m);
831
1005
  const supabaseUrl = extractTomlValue(raw, /^\s*SUPABASE_URL\s*=\s*"([^"]+)"/m);
1006
+ const packageSpecifier = extractTomlValue(
1007
+ raw,
1008
+ /^\s*args\s*=\s*\[[^\]]*(?:"-p"|"--package")\s*,\s*"([^"]+)"[^\]]*\]/m
1009
+ );
832
1010
  const hasServerSection = raw.includes("[mcp_servers.forcefield]");
833
1011
  if (!hasServerSection) {
834
1012
  return {
@@ -836,6 +1014,7 @@ async function inspectCodexMcpConfig(filePath) {
836
1014
  filePath,
837
1015
  key,
838
1016
  supabaseUrl,
1017
+ packageSpecifier,
839
1018
  detail: "Missing [mcp_servers.forcefield] section."
840
1019
  };
841
1020
  }
@@ -845,6 +1024,7 @@ async function inspectCodexMcpConfig(filePath) {
845
1024
  filePath,
846
1025
  key,
847
1026
  supabaseUrl,
1027
+ packageSpecifier,
848
1028
  detail: "forcefield section missing command."
849
1029
  };
850
1030
  }
@@ -853,9 +1033,49 @@ async function inspectCodexMcpConfig(filePath) {
853
1033
  filePath,
854
1034
  key,
855
1035
  supabaseUrl,
1036
+ packageSpecifier,
856
1037
  detail: `Found forcefield section (command: ${command}${supabaseUrl ? `, supabase: ${supabaseUrl}` : ""}).`
857
1038
  };
858
1039
  }
1040
+ function extractPackageSpecifierFromNpxArgs(args) {
1041
+ const stringArgs = args.filter((value) => typeof value === "string");
1042
+ const pkgIndex = stringArgs.findIndex((value) => value === "-p" || value === "--package");
1043
+ if (pkgIndex < 0) return void 0;
1044
+ const specifier = stringArgs[pkgIndex + 1];
1045
+ if (!specifier) return void 0;
1046
+ return specifier;
1047
+ }
1048
+ async function evaluateMcpPackageSpecifier(packageSpecifier) {
1049
+ if (!packageSpecifier) return null;
1050
+ const exactVersion = extractExactMcpVersion(packageSpecifier);
1051
+ if (!exactVersion) {
1052
+ return {
1053
+ ok: true,
1054
+ label: "MCP package version",
1055
+ detail: `Using tag-based MCP package specifier (${packageSpecifier}).`
1056
+ };
1057
+ }
1058
+ const published = await isMcpVersionPublished(exactVersion);
1059
+ if (published === false) {
1060
+ return {
1061
+ ok: false,
1062
+ label: "MCP package version",
1063
+ detail: `Configured MCP package ${packageSpecifier} is not published. Run forcefield setup to rewrite MCP config to a published version.`
1064
+ };
1065
+ }
1066
+ if (published === true) {
1067
+ return {
1068
+ ok: true,
1069
+ label: "MCP package version",
1070
+ detail: `Published MCP package detected (${packageSpecifier}).`
1071
+ };
1072
+ }
1073
+ return {
1074
+ ok: true,
1075
+ label: "MCP package version",
1076
+ detail: `Could not verify ${packageSpecifier} publication (registry unreachable).`
1077
+ };
1078
+ }
859
1079
  function extractTomlValue(content, pattern) {
860
1080
  const match = content.match(pattern);
861
1081
  return match?.[1];
@@ -1287,4 +1507,4 @@ export {
1287
1507
  parseArgs,
1288
1508
  runSetupCli
1289
1509
  };
1290
- //# sourceMappingURL=chunk-DGBLHABK.js.map
1510
+ //# sourceMappingURL=chunk-7CDDYIDW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../setup/wizard.ts","../setup/ide-detect.ts","../setup/ide-adapters/claude-code.ts","../setup/ide-adapters/mcp-runtime.ts","../package.json","../setup/ide-adapters/cursor.ts","../setup/ide-adapters/codex.ts","../setup/ide-adapters/windsurf.ts","../setup/ide-adapters/index.ts","../setup/auth.ts","../setup/index.ts"],"sourcesContent":["/**\n * setup/wizard.ts — Interactive setup wizard using @clack/prompts.\n *\n * Orchestrates the full setup flow:\n * 1. Welcome banner\n * 2. Existing setup check\n * 3. IDE detection + selection\n * 4. Mode selection (Core vs Full)\n * 5. Authentication\n * 6. Configure + install\n * 7. Verify + success\n */\n\nimport * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport figlet from 'figlet';\nimport gradient from 'gradient-string';\nimport { readFile, writeFile, access } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Ide, SetupMode, SetupConfig, CliArgs } from './types.js';\nimport { detectIde } from './ide-detect.js';\nimport { getAdapter, IDE_CHOICES } from './ide-adapters/index.js';\nimport {\n authenticateAccountAndCreateApiKey,\n authenticateLocalAndCreateApiKey,\n authenticateWithRetry,\n verifyApiKey,\n} from './auth.js';\nimport { extractExactMcpVersion, isMcpVersionPublished } from './ide-adapters/mcp-runtime.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst WORKFLOW_DIR_CANDIDATES = [\n join(__dirname, '..', 'workflows'),\n join(__dirname, '..', '..', 'workflows'),\n];\nconst CONFIG_FILE = '.forcefield.json';\nconst VERSION = '0.1.11';\nconst BANNER_TEXT = 'Forcefield';\nconst BANNER_FONT = 'Rowan Cap';\nconst BANNER_MIN_COLUMNS = 80;\nconst BANNER_FALLBACK_TEXT = ' Forcefield';\nconst BANNER_SUBTITLE = ' Corporate compliance copilot\\n';\n// rainbow2-like palette cycling red -> violet for the terminal banner\nconst BANNER_GRADIENT_STOPS = ['#ff3b3b', '#ff9f1a', '#ffe74c', '#2ed573', '#1e90ff', '#7d5fff', '#e056fd'];\nconst bannerGradient = gradient(BANNER_GRADIENT_STOPS);\n\nasync function resolveWorkflowsDir(): Promise<string> {\n for (const dir of WORKFLOW_DIR_CANDIDATES) {\n try {\n await access(dir);\n return dir;\n } catch {\n // try next candidate\n }\n }\n throw new Error(\n `Unable to locate workflow templates. Checked: ${WORKFLOW_DIR_CANDIDATES.join(', ')}`,\n );\n}\n\n/**\n * Run the interactive setup wizard.\n */\nexport async function runWizard(projectDir: string, args: CliArgs): Promise<void> {\n // --status: read-only check\n if (args.status) {\n await showStatus(projectDir);\n return;\n }\n\n // --doctor: setup diagnostics\n if (args.doctor) {\n await runDoctor(projectDir, args);\n return;\n }\n\n // Non-interactive mode\n if (args.ide && args.mode && (args.token || args.localAuth || (args.email && args.password))) {\n await runNonInteractive(projectDir, args);\n return;\n }\n\n // Interactive mode\n await runInteractive(projectDir, args);\n}\n\n// === Welcome Banner ===\n\nfunction showBanner(): void {\n const cols = process.stdout.columns || 80;\n\n if (cols >= BANNER_MIN_COLUMNS) {\n try {\n const banner = figlet.textSync(BANNER_TEXT, { font: BANNER_FONT });\n const colored = applyBannerGradient(banner);\n console.log(colored);\n } catch {\n // figlet font not available — use fallback\n console.log(pc.bold(applyBannerGradient(BANNER_FALLBACK_TEXT)));\n }\n } else {\n console.log(pc.bold(applyBannerGradient(BANNER_FALLBACK_TEXT)));\n }\n console.log(pc.dim(BANNER_SUBTITLE));\n}\n\nfunction applyBannerGradient(text: string): string {\n return bannerGradient.multiline(text);\n}\n\n// === Status Check ===\n\nasync function showStatus(projectDir: string): Promise<void> {\n const config = await readConfig(projectDir);\n\n if (!config) {\n console.log(pc.yellow('No Forcefield setup found in this directory.'));\n console.log(`Run ${pc.cyan('forcefield setup')} to get started.`);\n process.exit(1);\n }\n\n console.log(pc.bold('Forcefield Setup Status'));\n console.log(` IDE: ${pc.cyan(config.ide)}`);\n console.log(` Mode: ${pc.cyan(config.mode)}`);\n console.log(` Version: ${pc.cyan(config.version)}`);\n console.log(` Installed: ${pc.dim(config.installed_at)}`);\n}\n\ninterface DoctorCheckResult {\n ok: boolean;\n label: string;\n detail: string;\n}\n\ninterface McpCheckResult {\n ok: boolean;\n filePath: string;\n key?: string;\n supabaseUrl?: string;\n packageSpecifier?: string;\n detail: string;\n}\n\nasync function runDoctor(projectDir: string, args: CliArgs): Promise<void> {\n console.log(pc.bold('Forcefield Setup Doctor'));\n console.log(pc.dim(`Project: ${projectDir}`));\n\n const checks: DoctorCheckResult[] = [];\n const config = await readConfig(projectDir);\n\n if (!config) {\n checks.push({\n ok: false,\n label: 'Setup config',\n detail: `Missing ${CONFIG_FILE}. Run forcefield setup first.`,\n });\n } else {\n checks.push({\n ok: true,\n label: 'Setup config',\n detail: `${config.ide} / ${config.mode} / v${config.version}`,\n });\n\n const mcp = await inspectMcpConfig(projectDir, config.ide);\n checks.push({\n ok: mcp.ok,\n label: 'MCP config',\n detail: `${mcp.filePath} — ${mcp.detail}`,\n });\n\n const packageCheck = await evaluateMcpPackageSpecifier(mcp.packageSpecifier);\n if (packageCheck) {\n checks.push(packageCheck);\n }\n\n if (mcp.key) {\n const verified = await verifyApiKey(mcp.key, {\n localDev: isLocalSetupMode(args),\n supabaseUrl: mcp.supabaseUrl,\n });\n checks.push({\n ok: verified.valid,\n label: 'API key exchange',\n detail: verified.valid\n ? `Key exchange succeeded${mcp.supabaseUrl ? ` (${mcp.supabaseUrl})` : ''}.`\n : (verified.error ?? 'Key exchange failed.'),\n });\n } else {\n checks.push({\n ok: false,\n label: 'API key exchange',\n detail: 'FORCEFIELD_API_KEY not found in MCP config env.',\n });\n }\n }\n\n for (const check of checks) {\n const symbol = check.ok ? pc.green('✓') : pc.red('✗');\n console.log(`${symbol} ${pc.bold(check.label)}: ${check.detail}`);\n }\n\n const failures = checks.filter((check) => !check.ok);\n if (failures.length > 0) {\n console.log('');\n console.log(pc.yellow('Suggested fixes:'));\n console.log(` 1. Re-run ${pc.cyan('forcefield setup')} in this project.`);\n console.log(` 2. Confirm your coding agent shows Forcefield connected (${pc.cyan('/mcp')}).`);\n console.log(` 3. Re-run ${pc.cyan('forcefield doctor')} after setup.`);\n process.exit(1);\n }\n\n console.log('');\n console.log(pc.green('Doctor checks passed. Forcefield should be ready.'));\n}\n\nasync function inspectMcpConfig(projectDir: string, ide: Ide): Promise<McpCheckResult> {\n if (ide === 'claude-code') {\n return inspectJsonMcpConfig(join(projectDir, '.mcp.json'), 'mcpServers');\n }\n\n if (ide === 'cursor') {\n return inspectJsonMcpConfig(join(projectDir, '.cursor', 'mcp.json'), 'mcpServers');\n }\n\n if (ide === 'windsurf') {\n return inspectJsonMcpConfig(join(projectDir, '.windsurf', 'mcp_config.json'), 'mcpServers');\n }\n\n return inspectCodexMcpConfig(join(projectDir, '.codex', 'config.toml'));\n}\n\nasync function inspectJsonMcpConfig(\n filePath: string,\n rootKey: string,\n): Promise<McpCheckResult> {\n let raw = '';\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'File not found.',\n };\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'Invalid JSON.',\n };\n }\n\n const servers =\n typeof parsed[rootKey] === 'object' && parsed[rootKey] != null\n ? (parsed[rootKey] as Record<string, unknown>)\n : null;\n\n if (!servers || typeof servers.forcefield !== 'object' || servers.forcefield == null) {\n return {\n ok: false,\n filePath,\n detail: 'Missing forcefield MCP server entry.',\n };\n }\n\n const ffServer = servers.forcefield as Record<string, unknown>;\n const command = typeof ffServer.command === 'string' ? ffServer.command : '';\n const args = Array.isArray(ffServer.args) ? ffServer.args : [];\n const env = typeof ffServer.env === 'object' && ffServer.env != null\n ? (ffServer.env as Record<string, unknown>)\n : {};\n const key = typeof env.FORCEFIELD_API_KEY === 'string'\n ? env.FORCEFIELD_API_KEY\n : undefined;\n const supabaseUrl = typeof env.SUPABASE_URL === 'string'\n ? env.SUPABASE_URL\n : undefined;\n const packageSpecifier = extractPackageSpecifierFromNpxArgs(args);\n\n if (!command) {\n return {\n ok: false,\n filePath,\n key,\n supabaseUrl,\n packageSpecifier,\n detail: 'forcefield entry missing command.',\n };\n }\n\n return {\n ok: true,\n filePath,\n key,\n supabaseUrl,\n packageSpecifier,\n detail: `Found forcefield entry (command: ${command}${supabaseUrl ? `, supabase: ${supabaseUrl}` : ''}).`,\n };\n}\n\nasync function inspectCodexMcpConfig(filePath: string): Promise<McpCheckResult> {\n let raw = '';\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'File not found.',\n };\n }\n\n const command = extractTomlValue(raw, /^\\s*command\\s*=\\s*\"([^\"]+)\"/m);\n const key = extractTomlValue(raw, /^\\s*FORCEFIELD_API_KEY\\s*=\\s*\"([^\"]+)\"/m);\n const supabaseUrl = extractTomlValue(raw, /^\\s*SUPABASE_URL\\s*=\\s*\"([^\"]+)\"/m);\n const packageSpecifier = extractTomlValue(\n raw,\n /^\\s*args\\s*=\\s*\\[[^\\]]*(?:\"-p\"|\"--package\")\\s*,\\s*\"([^\"]+)\"[^\\]]*\\]/m,\n );\n const hasServerSection = raw.includes('[mcp_servers.forcefield]');\n\n if (!hasServerSection) {\n return {\n ok: false,\n filePath,\n key,\n supabaseUrl,\n packageSpecifier,\n detail: 'Missing [mcp_servers.forcefield] section.',\n };\n }\n\n if (!command) {\n return {\n ok: false,\n filePath,\n key,\n supabaseUrl,\n packageSpecifier,\n detail: 'forcefield section missing command.',\n };\n }\n\n return {\n ok: true,\n filePath,\n key,\n supabaseUrl,\n packageSpecifier,\n detail: `Found forcefield section (command: ${command}${supabaseUrl ? `, supabase: ${supabaseUrl}` : ''}).`,\n };\n}\n\nfunction extractPackageSpecifierFromNpxArgs(args: unknown[]): string | undefined {\n const stringArgs = args.filter((value): value is string => typeof value === 'string');\n const pkgIndex = stringArgs.findIndex((value) => value === '-p' || value === '--package');\n if (pkgIndex < 0) return undefined;\n const specifier = stringArgs[pkgIndex + 1];\n if (!specifier) return undefined;\n return specifier;\n}\n\nasync function evaluateMcpPackageSpecifier(\n packageSpecifier: string | undefined,\n): Promise<DoctorCheckResult | null> {\n if (!packageSpecifier) return null;\n\n const exactVersion = extractExactMcpVersion(packageSpecifier);\n if (!exactVersion) {\n return {\n ok: true,\n label: 'MCP package version',\n detail: `Using tag-based MCP package specifier (${packageSpecifier}).`,\n };\n }\n\n const published = await isMcpVersionPublished(exactVersion);\n if (published === false) {\n return {\n ok: false,\n label: 'MCP package version',\n detail: `Configured MCP package ${packageSpecifier} is not published. Run forcefield setup to rewrite MCP config to a published version.`,\n };\n }\n\n if (published === true) {\n return {\n ok: true,\n label: 'MCP package version',\n detail: `Published MCP package detected (${packageSpecifier}).`,\n };\n }\n\n return {\n ok: true,\n label: 'MCP package version',\n detail: `Could not verify ${packageSpecifier} publication (registry unreachable).`,\n };\n}\n\nfunction extractTomlValue(content: string, pattern: RegExp): string | undefined {\n const match = content.match(pattern);\n return match?.[1];\n}\n\n// === Non-Interactive Mode ===\n\nasync function runNonInteractive(projectDir: string, args: CliArgs): Promise<void> {\n const ide = args.ide!;\n const mode = args.mode!;\n let apiKey = args.token;\n\n if (args.localAuth) {\n if (!args.email || !args.password) {\n console.error(pc.red('Non-interactive local auth requires --email and --password.'));\n process.exit(1);\n }\n\n const auth = await authenticateLocalAndCreateApiKey(args.email, args.password, {\n label: 'Setup Wizard (Local)',\n });\n apiKey = auth.apiKey;\n console.log(`Created local API key for ${auth.email}.`);\n } else if (!apiKey && args.email && args.password) {\n const auth = await authenticateAccountAndCreateApiKey(args.email, args.password, {\n label: 'Setup Wizard Key',\n localDev: isLocalSetupMode(args),\n });\n apiKey = auth.apiKey;\n console.log(`Created API key for ${auth.email}.`);\n } else if (apiKey) {\n const verified = await authenticateWithRetry(async () => apiKey ?? null, {\n localDev: isLocalSetupMode(args),\n });\n if (!verified.valid) {\n console.error(pc.red(verified.error ?? 'API key validation failed.'));\n process.exit(1);\n }\n apiKey = verified.apiKey;\n }\n\n if (!apiKey) {\n console.error(pc.red('Missing auth input. Pass --token, --local-auth, or --email/--password.'));\n process.exit(1);\n }\n\n console.log(`Setting up Forcefield for ${ide} in ${mode} mode...`);\n\n await configure(projectDir, ide, mode, apiKey);\n\n console.log(pc.green('Setup complete!'));\n for (const line of getPostSetupInstructions(ide, mode, projectDir)) {\n console.log(line);\n }\n}\n\n// === Interactive Mode ===\n\nasync function runInteractive(projectDir: string, preArgs: CliArgs): Promise<void> {\n showBanner();\n\n p.intro(pc.bgCyan(pc.black(' Forcefield Setup ')));\n\n // Step 1: Check existing setup\n const existingConfig = await readConfig(projectDir);\n if (existingConfig) {\n const updateChoice = await p.select({\n message: `Forcefield is already set up (${existingConfig.ide}, ${existingConfig.mode} mode).`,\n options: [\n { value: 'update', label: 'Update existing setup', hint: 'Refresh workflows + auth' },\n { value: 'fresh', label: 'Start fresh', hint: 'Remove existing config and reconfigure' },\n ],\n });\n\n if (p.isCancel(updateChoice)) {\n p.cancel('Setup cancelled.');\n process.exit(0);\n }\n\n if (updateChoice === 'update') {\n // Re-run configure with existing settings\n const apiKey = await promptApiKey();\n if (!apiKey) return;\n await configure(projectDir, existingConfig.ide, existingConfig.mode, apiKey);\n showSuccess(existingConfig.ide, existingConfig.mode, projectDir);\n return;\n }\n // fresh → continue with full wizard\n }\n\n // Step 2: IDE detection + selection\n const ide = preArgs.ide ?? await promptIde(projectDir);\n if (!ide) return;\n\n // Step 3: Mode selection\n const mode = preArgs.mode ?? await promptMode();\n if (!mode) return;\n\n // Step 4: Authentication\n const apiKey = preArgs.token ?? await promptApiKey(preArgs);\n if (!apiKey) return;\n\n // Step 5: Configure + install\n const s = p.spinner();\n s.start('Configuring Forcefield...');\n\n try {\n await configure(projectDir, ide, mode, apiKey);\n s.stop('Configuration complete.');\n } catch (err) {\n s.stop('Configuration failed.');\n p.cancel(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n\n // Step 6: Success\n showSuccess(ide, mode, projectDir);\n}\n\n// === Prompts ===\n\nasync function promptIde(projectDir: string): Promise<Ide | null> {\n const detection = await detectIde(projectDir);\n\n if (detection.detected) {\n const adapter = getAdapter(detection.detected);\n const confirm = await p.confirm({\n message: `Detected ${adapter.name} (${detection.markers[0]!.marker} found). Use ${adapter.name}?`,\n });\n\n if (p.isCancel(confirm)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (confirm) return detection.detected;\n }\n\n const choice = await p.select({\n message: 'Which IDE do you use?',\n options: IDE_CHOICES,\n });\n\n if (p.isCancel(choice)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return choice as Ide;\n}\n\nasync function promptMode(): Promise<SetupMode | null> {\n const choice = await p.select({\n message: 'Installation type:',\n options: [\n { value: 'full' as const, label: 'Full — MCP server + guided workflows', hint: 'Recommended' },\n { value: 'core' as const, label: 'Core — MCP server only', hint: 'Minimal' },\n ],\n });\n\n if (p.isCancel(choice)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return choice as SetupMode;\n}\n\nasync function promptApiKey(preArgs?: CliArgs): Promise<string | null> {\n if (preArgs?.localAuth) {\n const preEmail = preArgs.email ?? await promptTextValue('Local test email:', 'alice@test.local');\n const prePassword = preArgs.password ?? await promptPasswordValue(\n 'Local test password:',\n 'Confirm local test password:',\n );\n if (!preEmail || !prePassword) return null;\n\n try {\n const result = await authenticateLocalAndCreateApiKey(preEmail, prePassword, {\n label: 'Setup Wizard (Local)',\n });\n p.log.success(`Created local API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Failed local auth');\n return null;\n }\n }\n\n const localMode = isLocalSetupMode(preArgs);\n const methodOptions = [\n { value: 'account', label: 'Sign in / create account + API key', hint: 'Recommended' },\n { value: 'paste', label: 'Paste existing API key', hint: 'Use an existing ff_live_... key' },\n ];\n\n if (localMode) {\n methodOptions.push({\n value: 'local',\n label: 'Create local account + API key',\n hint: 'For local Supabase testing',\n });\n }\n\n const method = await p.select({\n message: 'How do you want to authenticate?',\n options: methodOptions,\n });\n\n if (p.isCancel(method)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (method === 'account') {\n const email = await promptTextValue('Account email:', preArgs?.email ?? 'you@company.com');\n const password = preArgs?.password ?? await promptPasswordValue(\n 'Account password:',\n 'Confirm account password:',\n );\n if (!email || !password) return null;\n\n try {\n const result = await authenticateAccountAndCreateApiKey(email, password, {\n label: 'Setup Wizard Key',\n localDev: localMode,\n });\n p.log.success(`Created API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Account authentication failed');\n return null;\n }\n }\n\n if (method === 'local') {\n const email = await promptTextValue('Local test email:', 'alice@test.local');\n const password = await promptPasswordValue(\n 'Local test password:',\n 'Confirm local test password:',\n );\n if (!email || !password) return null;\n\n try {\n const result = await authenticateLocalAndCreateApiKey(email, password, {\n label: 'Setup Wizard (Local)',\n });\n p.log.success(`Created local API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Failed local auth');\n return null;\n }\n }\n\n const auth = await authenticateWithRetry(\n async () => {\n const key = await p.text({\n message: 'Enter your Forcefield API key:',\n placeholder: 'ff_live_...',\n validate: (value) => {\n if (!value) return 'API key is required.';\n if (!value.startsWith('ff_live_')) return 'Key must start with \"ff_live_\".';\n if (value.length < 20) return 'Key seems too short.';\n return undefined;\n },\n });\n\n if (p.isCancel(key)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return key;\n },\n {\n localDev: localMode,\n },\n );\n\n if (!auth.valid) {\n p.log.error(auth.error ?? 'Authentication failed. Check your credentials and retry.');\n return null;\n }\n\n return auth.apiKey;\n}\n\nfunction isLocalSetupMode(preArgs?: CliArgs): boolean {\n if (preArgs?.localAuth) return true;\n const localValue = process.env.FORCEFIELD_LOCAL_DEV;\n if (localValue) {\n const normalized = localValue.trim().toLowerCase();\n if (['1', 'true', 'yes', 'on'].includes(normalized)) {\n return true;\n }\n }\n\n const supabaseUrl = process.env.SUPABASE_URL;\n if (!supabaseUrl) return false;\n try {\n const parsed = new URL(supabaseUrl);\n return parsed.hostname === '127.0.0.1' || parsed.hostname === 'localhost';\n } catch {\n return false;\n }\n}\n\nasync function promptTextValue(\n message: string,\n placeholder: string,\n): Promise<string | null> {\n const value = await p.text({\n message,\n placeholder,\n validate: (input) => {\n if (!input) return 'This field is required.';\n return undefined;\n },\n });\n\n if (p.isCancel(value)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n return value;\n}\n\nasync function promptPasswordValue(\n message: string,\n confirmMessage?: string,\n): Promise<string | null> {\n const password = await p.password({\n message,\n validate: (input) => {\n if (!input) return 'Password is required.';\n if (input.length < 8) return 'Password must be at least 8 characters.';\n return undefined;\n },\n });\n\n if (p.isCancel(password)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (!confirmMessage) {\n return password;\n }\n\n const confirm = await p.password({\n message: confirmMessage,\n validate: (input) => {\n if (!input) return 'Please confirm your password.';\n return undefined;\n },\n });\n\n if (p.isCancel(confirm)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (password !== confirm) {\n p.log.error('Passwords do not match. Please run setup again.');\n return null;\n }\n\n return password;\n}\n\n// === Configure ===\n\nasync function configure(\n projectDir: string,\n ide: Ide,\n mode: SetupMode,\n apiKey: string,\n): Promise<void> {\n const adapter = getAdapter(ide);\n\n // Configure MCP\n await adapter.configureMcp(projectDir, apiKey);\n\n // Install workflows (full mode only)\n let workflowCount = 0;\n if (mode === 'full') {\n const workflowsDir = await resolveWorkflowsDir();\n workflowCount = await adapter.installWorkflows(projectDir, workflowsDir);\n }\n\n // Write config\n const config: SetupConfig = {\n ide,\n mode,\n installed_at: new Date().toISOString(),\n version: VERSION,\n };\n await writeConfig(projectDir, config);\n\n void workflowCount; // Used in logging below\n}\n\nfunction getPostSetupInstructions(ide: Ide, mode: SetupMode, projectDir: string): string[] {\n const repo = pc.cyan(projectDir);\n const dashboardHint = [\n `Optional beta companion: run ${pc.cyan('forcefield dashboard start')} to scaffold and launch the local dashboard (hosted backend by default).`,\n `If ${pc.cyan('forcefield')} is not installed globally, use ${pc.cyan('npx -y @forcefield/forcefield dashboard start')}. Advanced mode: pass ${pc.cyan('--local')} for local Supabase.`,\n ];\n\n if (mode === 'core') {\n return [\n `Next: open your coding agent in ${repo} and use Forcefield MCP tools directly (e.g. ${pc.cyan('ff_system(action: \"health\")')}).`,\n ...dashboardHint,\n ];\n }\n\n const common = [\n `Next: start your coding agent in ${repo}.`,\n `Then in IDE chat (not terminal), run ${pc.cyan('/ff-onboard')} to set up your company profile and deadlines.`,\n `Optional: run ${pc.cyan('/ff-start')} only if you want a command primer or connection troubleshooting.`,\n `If connection fails, run ${pc.cyan('forcefield doctor')} in terminal for diagnostics.`,\n ...dashboardHint,\n ];\n\n if (ide === 'claude-code') {\n return [\n ...common,\n `If tools are missing, run ${pc.cyan('/mcp')} and confirm ${pc.cyan('forcefield')} is connected.`,\n ];\n }\n\n return common;\n}\n\nfunction showSuccess(ide: Ide, mode: SetupMode, projectDir: string): void {\n const adapter = getAdapter(ide);\n const workflowStatus =\n mode === 'full'\n ? `${pc.green('✓')} Project workflow commands installed`\n : `${pc.yellow('•')} Core mode selected (no slash-command workflows installed)`;\n\n p.note(\n [\n `${pc.green('✓')} MCP server configured`,\n workflowStatus,\n `${pc.green('✓')} IDE: ${adapter.name}`,\n ].join('\\n'),\n 'Setup Complete',\n );\n\n p.outro(getPostSetupInstructions(ide, mode, projectDir).join('\\n'));\n}\n\n// === Config File ===\n\nasync function readConfig(projectDir: string): Promise<SetupConfig | null> {\n const configPath = join(projectDir, CONFIG_FILE);\n try {\n await access(configPath);\n const raw = await readFile(configPath, 'utf-8');\n return JSON.parse(raw) as SetupConfig;\n } catch {\n return null;\n }\n}\n\nasync function writeConfig(projectDir: string, config: SetupConfig): Promise<void> {\n const configPath = join(projectDir, CONFIG_FILE);\n await writeFile(configPath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport {\n readConfig,\n writeConfig,\n CONFIG_FILE,\n VERSION,\n BANNER_FONT,\n BANNER_MIN_COLUMNS,\n BANNER_GRADIENT_STOPS,\n showBanner,\n applyBannerGradient,\n getPostSetupInstructions,\n inspectMcpConfig,\n inspectJsonMcpConfig,\n inspectCodexMcpConfig,\n extractPackageSpecifierFromNpxArgs,\n evaluateMcpPackageSpecifier,\n extractTomlValue,\n};\n","/**\n * setup/ide-detect.ts — Auto-detect IDE from project directory markers.\n */\n\nimport { access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { Ide } from './types.js';\n\ninterface DetectionResult {\n detected: Ide | null;\n markers: Array<{ ide: Ide; marker: string }>;\n}\n\nconst IDE_MARKERS: Array<{ ide: Ide; marker: string; isDir: boolean }> = [\n { ide: 'claude-code', marker: '.claude', isDir: true },\n { ide: 'cursor', marker: '.cursor', isDir: true },\n { ide: 'codex', marker: 'AGENTS.md', isDir: false },\n { ide: 'windsurf', marker: '.windsurfrules', isDir: false },\n];\n\nexport async function detectIde(projectDir: string): Promise<DetectionResult> {\n const found: Array<{ ide: Ide; marker: string }> = [];\n\n for (const { ide, marker } of IDE_MARKERS) {\n const markerPath = join(projectDir, marker);\n try {\n await access(markerPath);\n found.push({ ide, marker });\n } catch {\n // Marker not found — skip\n }\n }\n\n return {\n detected: found.length === 1 ? found[0]!.ide : null,\n markers: found,\n };\n}\n\nexport { IDE_MARKERS };\n","/**\n * IDE adapter for Claude Code.\n * Workflows → .claude/commands/ff-*.md\n * MCP → project-scoped .mcp.json entry\n */\n\nimport { mkdir, readdir, copyFile, rm, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nexport const claudeCodeAdapter: IdeAdapter = {\n name: 'Claude Code',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n // Ensure Claude config folder exists for slash-command workflows.\n const claudeDir = join(projectDir, '.claude');\n await mkdir(claudeDir, { recursive: true });\n\n // Configure project-scoped MCP entry used by Claude Code.\n const launch = await getMcpLaunchConfig();\n const mcpPath = join(projectDir, '.mcp.json');\n\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(await readFile(mcpPath, 'utf-8')) as Record<string, unknown>;\n } catch {\n // file missing/invalid: start fresh\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? (existing.mcpServers as Record<string, unknown>)\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const nextConfig = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(mcpPath, JSON.stringify(nextConfig, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const commandsDir = join(projectDir, '.claude', 'commands');\n await mkdir(commandsDir, { recursive: true });\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n for (const file of mdFiles) {\n await copyFile(join(workflowsDir, file), join(commandsDir, file));\n }\n\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const commandsDir = join(projectDir, '.claude', 'commands');\n try {\n const files = await readdir(commandsDir);\n for (const file of files) {\n if (file.startsWith('ff-') && file.endsWith('.md')) {\n await rm(join(commandsDir, file));\n }\n }\n } catch {\n // Directory doesn't exist — nothing to remove\n }\n },\n};\n","import { access } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport packageJson from '../../package.json';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst MCP_PACKAGE_NAME = '@forcefield/mcp-server';\nconst DEFAULT_NPM_REGISTRY_URL = 'https://registry.npmjs.org';\nconst NPM_METADATA_TIMEOUT_MS = 2000;\nconst LOCAL_ENTRY_CANDIDATES = [\n join(__dirname, '..', '..', 'build', 'index.js'),\n join(__dirname, '..', '..', 'index.js'),\n];\n\nconst FORWARDED_ENV_KEYS = [\n 'SUPABASE_URL',\n 'SUPABASE_ANON_KEY',\n 'FORCEFIELD_LOCAL_DEV',\n 'FORCEFIELD_DISABLE_GATING',\n 'FORCEFIELD_LOCAL_DATA_FALLBACK',\n] as const;\n\ninterface NpmPackageMetadata {\n versions?: Record<string, unknown>;\n 'dist-tags'?: Record<string, unknown>;\n}\n\nlet metadataCache: { registryUrl: string; promise: Promise<NpmPackageMetadata | null> } | null = null;\n\nexport function resetMcpRuntimeCacheForTests(): void {\n metadataCache = null;\n}\n\nfunction getEnv(name: string): string | undefined {\n const value = process.env[name];\n if (!value) return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction getLocalPackageVersion(): string | undefined {\n const version =\n typeof packageJson === 'object' && packageJson && 'version' in packageJson\n ? (packageJson.version as string | undefined)\n : undefined;\n return version?.trim() || undefined;\n}\n\nfunction getDefaultDistTag(): string {\n const publishConfig =\n typeof packageJson === 'object' && packageJson && 'publishConfig' in packageJson\n ? (packageJson.publishConfig as Record<string, unknown>)\n : undefined;\n const packageTag =\n publishConfig && typeof publishConfig.tag === 'string'\n ? publishConfig.tag.trim()\n : '';\n return packageTag || 'latest';\n}\n\nfunction getTargetDistTag(): string {\n return getEnv('FORCEFIELD_SETUP_MCP_DIST_TAG') ?? getDefaultDistTag();\n}\n\nfunction getRegistryUrl(): string {\n const configured = getEnv('FORCEFIELD_NPM_REGISTRY_URL') ?? DEFAULT_NPM_REGISTRY_URL;\n return configured.replace(/\\/+$/, '');\n}\n\nfunction getPackageOverride(): string | undefined {\n return getEnv('FORCEFIELD_SETUP_MCP_PACKAGE');\n}\n\nfunction isExactVersion(value: string): boolean {\n return /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$/.test(value);\n}\n\nexport function extractExactMcpVersion(specifier: string): string | undefined {\n const prefix = `${MCP_PACKAGE_NAME}@`;\n if (!specifier.startsWith(prefix)) return undefined;\n const version = specifier.slice(prefix.length).trim();\n if (!isExactVersion(version)) return undefined;\n return version;\n}\n\nasync function fetchPackageMetadata(registryUrl: string): Promise<NpmPackageMetadata | null> {\n const encodedPackage = encodeURIComponent(MCP_PACKAGE_NAME);\n const endpoint = `${registryUrl}/${encodedPackage}`;\n\n try {\n const response = await fetch(endpoint, {\n headers: {\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(NPM_METADATA_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n return null;\n }\n\n const payload = await response.json();\n if (!payload || typeof payload !== 'object') {\n return null;\n }\n return payload as NpmPackageMetadata;\n } catch {\n return null;\n }\n}\n\nasync function getPackageMetadata(registryUrl: string): Promise<NpmPackageMetadata | null> {\n if (metadataCache && metadataCache.registryUrl === registryUrl) {\n return metadataCache.promise;\n }\n\n const promise = fetchPackageMetadata(registryUrl);\n metadataCache = { registryUrl, promise };\n return promise;\n}\n\nasync function resolvePackageSpecifier(): Promise<string> {\n const override = getPackageOverride();\n if (override) return override;\n\n const localVersion = getLocalPackageVersion();\n const targetDistTag = getTargetDistTag();\n\n if (isExactVersion(targetDistTag)) {\n return `${MCP_PACKAGE_NAME}@${targetDistTag}`;\n }\n\n const metadata = await getPackageMetadata(getRegistryUrl());\n if (!metadata) {\n return `${MCP_PACKAGE_NAME}@${targetDistTag}`;\n }\n\n if (localVersion && metadata.versions && localVersion in metadata.versions) {\n return `${MCP_PACKAGE_NAME}@${localVersion}`;\n }\n\n const distTags = metadata['dist-tags'];\n const pinnedDistTagVersion =\n distTags && typeof distTags[targetDistTag] === 'string'\n ? String(distTags[targetDistTag]).trim()\n : '';\n\n if (pinnedDistTagVersion) {\n return `${MCP_PACKAGE_NAME}@${pinnedDistTagVersion}`;\n }\n\n return `${MCP_PACKAGE_NAME}@${targetDistTag}`;\n}\n\nexport async function isMcpVersionPublished(version: string): Promise<boolean | null> {\n if (!isExactVersion(version)) return false;\n const metadata = await getPackageMetadata(getRegistryUrl());\n if (!metadata) return null;\n return Boolean(metadata.versions && version in metadata.versions);\n}\n\nfunction isTruthy(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';\n}\n\nasync function resolveLocalEntry(): Promise<string | null> {\n for (const candidate of LOCAL_ENTRY_CANDIDATES) {\n try {\n await access(candidate);\n return candidate;\n } catch {\n // try next candidate\n }\n }\n return null;\n}\n\nexport async function getMcpLaunchConfig(): Promise<{ command: string; args: string[] }> {\n if (\n isTruthy(process.env.FORCEFIELD_LOCAL_DEV)\n || isTruthy(process.env.FORCEFIELD_SETUP_USE_LOCAL_BUILD)\n ) {\n const localEntry = await resolveLocalEntry();\n if (localEntry) {\n return {\n command: process.execPath,\n args: [localEntry],\n };\n }\n }\n\n const packageSpecifier = await resolvePackageSpecifier();\n return {\n command: 'npx',\n args: ['-y', '-p', packageSpecifier, 'forcefield-mcp'],\n };\n}\n\nexport function buildMcpEnv(apiKey: string): Record<string, string> {\n const env: Record<string, string> = {\n FORCEFIELD_API_KEY: apiKey,\n };\n\n // Default to hosted-first deterministic config.\n // Forwarding setup-shell env into MCP runtime is opt-in to avoid\n // accidentally persisting local/dev flags into project config.\n if (!isTruthy(process.env.FORCEFIELD_SETUP_FORWARD_ENV)) {\n return env;\n }\n\n for (const key of FORWARDED_ENV_KEYS) {\n const value = process.env[key];\n if (value && value.trim().length > 0) {\n env[key] = value;\n }\n }\n\n return env;\n}\n","{\n \"name\": \"@forcefield/mcp-server\",\n \"version\": \"0.1.11\",\n \"description\": \"AI-powered corporate compliance MCP server\",\n \"license\": \"UNLICENSED\",\n \"type\": \"module\",\n \"publishConfig\": {\n \"access\": \"public\",\n \"tag\": \"beta\"\n },\n \"bin\": {\n \"forcefield\": \"build/cli/index.js\",\n \"forcefield-mcp\": \"build/index.js\",\n \"forcefield-setup\": \"build/cli/index.js\"\n },\n \"files\": [\n \"build/\",\n \"workflows/\"\n ],\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/forcefield-ai/forcefield.git\"\n },\n \"keywords\": [\n \"mcp\",\n \"compliance\",\n \"corporate\",\n \"formation\",\n \"cap-table\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"release:check\": \"node --import tsx scripts/check-release-policy.ts\",\n \"prepublishOnly\": \"npm run release:check && npm run build\",\n \"seed:data\": \"tsx scripts/seed-static-content.ts\",\n \"local:user\": \"tsx scripts/local-user.ts\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.0.1\",\n \"@modelcontextprotocol/sdk\": \"^1.26.0\",\n \"@supabase/supabase-js\": \"^2.97.0\",\n \"exceljs\": \"^4.4.0\",\n \"figlet\": \"^1.10.0\",\n \"gradient-string\": \"^3.0.0\",\n \"html-to-docx\": \"^1.8.0\",\n \"markdown-it\": \"^14.1.1\",\n \"mupdf\": \"^1.27.0\",\n \"officeparser\": \"^5.1.1\",\n \"pdfjs-dist\": \"^4.10.38\",\n \"picocolors\": \"^1.1.1\",\n \"tesseract.js\": \"^5.1.1\",\n \"zod\": \"^4.3.6\"\n },\n \"devDependencies\": {\n \"@forcefield/shared\": \"workspace:*\",\n \"@types/figlet\": \"^1.7.0\",\n \"@types/gradient-string\": \"^1.1.6\",\n \"@types/markdown-it\": \"^14.1.2\"\n }\n}\n","/**\n * IDE adapter for Cursor.\n * Workflows → .cursor/rules/ff-*.md\n * MCP → .cursor/mcp.json\n */\n\nimport { mkdir, readdir, copyFile, rm, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\ntype CursorMcpConfig = {\n mcpServers?: Record<string, { command: string; args: string[]; env?: Record<string, string> }>;\n};\n\nexport const cursorAdapter: IdeAdapter = {\n name: 'Cursor',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const cursorDir = join(projectDir, '.cursor');\n await mkdir(cursorDir, { recursive: true });\n\n const configPath = join(cursorDir, 'mcp.json');\n const launch = await getMcpLaunchConfig();\n\n let existing: CursorMcpConfig = {};\n try {\n existing = JSON.parse(await readFile(configPath, 'utf-8')) as CursorMcpConfig;\n } catch {\n // file missing/invalid: overwrite with fresh config\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? existing.mcpServers\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const merged: CursorMcpConfig = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(configPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const rulesDir = join(projectDir, '.cursor', 'rules');\n await mkdir(rulesDir, { recursive: true });\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n for (const file of mdFiles) {\n await copyFile(join(workflowsDir, file), join(rulesDir, file));\n }\n\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const rulesDir = join(projectDir, '.cursor', 'rules');\n try {\n const files = await readdir(rulesDir);\n for (const file of files) {\n if (file.startsWith('ff-') && file.endsWith('.md')) {\n await rm(join(rulesDir, file));\n }\n }\n } catch {\n // Directory doesn't exist\n }\n },\n};\n","/**\n * IDE adapter for Codex (OpenAI).\n * Workflows → appended to AGENTS.md with markers\n * MCP → .codex/config.toml or project-level config\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nconst START_MARKER = '<!-- forcefield:start -->';\nconst END_MARKER = '<!-- forcefield:end -->';\nconst MCP_START_MARKER = '# forcefield:mcp:start';\nconst MCP_END_MARKER = '# forcefield:mcp:end';\n\nexport const codexAdapter: IdeAdapter = {\n name: 'Codex',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const codexDir = join(projectDir, '.codex');\n await mkdir(codexDir, { recursive: true });\n\n const configPath = join(codexDir, 'config.toml');\n const launch = await getMcpLaunchConfig();\n const env = buildMcpEnv(apiKey);\n\n const forcefieldBlock = buildForcefieldTomlBlock(launch.command, launch.args, env);\n\n let existing = '';\n try {\n existing = await readFile(configPath, 'utf-8');\n } catch {\n // file missing — create new\n }\n\n const cleaned = removeTomlForcefieldSection(existing).trim();\n const final = cleaned ? `${cleaned}\\n\\n${forcefieldBlock}\\n` : `${forcefieldBlock}\\n`;\n await writeFile(configPath, final, 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const agentsPath = join(projectDir, 'AGENTS.md');\n const { readdir } = await import('node:fs/promises');\n\n // Read all workflow files\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n const workflowContents: string[] = [];\n for (const file of mdFiles) {\n const content = await readFile(join(workflowsDir, file), 'utf-8');\n workflowContents.push(content);\n }\n\n const forcefieldSection = [\n START_MARKER,\n '',\n '# Forcefield Workflows',\n '',\n 'The following workflows are available for compliance management:',\n '',\n ...workflowContents.map((c) => c + '\\n\\n---\\n'),\n END_MARKER,\n ].join('\\n');\n\n // Read existing AGENTS.md or create new\n let existing = '';\n try {\n existing = await readFile(agentsPath, 'utf-8');\n } catch {\n // File doesn't exist — will create\n }\n\n // Remove existing Forcefield section if present\n const cleaned = removeSection(existing);\n\n // Append new section\n const final = cleaned.trim()\n ? cleaned.trim() + '\\n\\n' + forcefieldSection\n : forcefieldSection;\n\n await writeFile(agentsPath, final, 'utf-8');\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const agentsPath = join(projectDir, 'AGENTS.md');\n try {\n const content = await readFile(agentsPath, 'utf-8');\n const cleaned = removeSection(content);\n await writeFile(agentsPath, cleaned, 'utf-8');\n } catch {\n // File doesn't exist — nothing to remove\n }\n },\n};\n\nfunction removeSection(content: string): string {\n const startIdx = content.indexOf(START_MARKER);\n const endIdx = content.indexOf(END_MARKER);\n\n if (startIdx === -1 || endIdx === -1) return content;\n\n const before = content.slice(0, startIdx).trimEnd();\n const after = content.slice(endIdx + END_MARKER.length).trimStart();\n\n return before + (after ? '\\n\\n' + after : '');\n}\n\nfunction removeTomlForcefieldSection(content: string): string {\n const markerStart = content.indexOf(MCP_START_MARKER);\n const markerEnd = content.indexOf(MCP_END_MARKER);\n\n if (markerStart !== -1 && markerEnd !== -1) {\n const before = content.slice(0, markerStart).trimEnd();\n const after = content.slice(markerEnd + MCP_END_MARKER.length).trimStart();\n return before + (after ? '\\n\\n' + after : '');\n }\n\n // Backward-compatible cleanup if a previous config wrote unmanaged sections.\n return content\n .replace(/^\\[mcp_servers\\.forcefield\\]\\n[\\s\\S]*?(?=^\\[|$)/gm, '')\n .replace(/^\\[mcp_servers\\.forcefield\\.env\\]\\n[\\s\\S]*?(?=^\\[|$)/gm, '')\n .trim();\n}\n\nfunction buildForcefieldTomlBlock(\n command: string,\n args: string[],\n env: Record<string, string>,\n): string {\n const envLines = Object.entries(env)\n .map(([key, value]) => `${key} = \"${escapeTomlString(value)}\"`);\n\n return [\n MCP_START_MARKER,\n '[mcp_servers.forcefield]',\n `command = \"${escapeTomlString(command)}\"`,\n `args = [${args.map((arg) => `\"${escapeTomlString(arg)}\"`).join(', ')}]`,\n '[mcp_servers.forcefield.env]',\n ...envLines,\n MCP_END_MARKER,\n ].join('\\n');\n}\n\nfunction escapeTomlString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n","/**\n * IDE adapter for Windsurf.\n * Workflows → appended to .windsurfrules with markers\n * MCP → Windsurf MCP config\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nconst START_MARKER = '<!-- forcefield:start -->';\nconst END_MARKER = '<!-- forcefield:end -->';\n\nexport const windsurfAdapter: IdeAdapter = {\n name: 'Windsurf',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const configDir = join(projectDir, '.windsurf');\n await mkdir(configDir, { recursive: true });\n\n const configPath = join(configDir, 'mcp_config.json');\n const launch = await getMcpLaunchConfig();\n\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(await readFile(configPath, 'utf-8')) as Record<string, unknown>;\n } catch {\n // file missing/invalid: start fresh\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? (existing.mcpServers as Record<string, unknown>)\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const merged = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(configPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const rulesPath = join(projectDir, '.windsurfrules');\n const { readdir } = await import('node:fs/promises');\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n const workflowContents: string[] = [];\n for (const file of mdFiles) {\n const content = await readFile(join(workflowsDir, file), 'utf-8');\n workflowContents.push(content);\n }\n\n const forcefieldSection = [\n START_MARKER,\n '',\n '# Forcefield Workflows',\n '',\n ...workflowContents.map((c) => c + '\\n\\n---\\n'),\n END_MARKER,\n ].join('\\n');\n\n let existing = '';\n try {\n existing = await readFile(rulesPath, 'utf-8');\n } catch {\n // File doesn't exist\n }\n\n const cleaned = removeSection(existing);\n const final = cleaned.trim()\n ? cleaned.trim() + '\\n\\n' + forcefieldSection\n : forcefieldSection;\n\n await writeFile(rulesPath, final, 'utf-8');\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const rulesPath = join(projectDir, '.windsurfrules');\n try {\n const content = await readFile(rulesPath, 'utf-8');\n const cleaned = removeSection(content);\n await writeFile(rulesPath, cleaned, 'utf-8');\n } catch {\n // File doesn't exist\n }\n },\n};\n\nfunction removeSection(content: string): string {\n const startIdx = content.indexOf(START_MARKER);\n const endIdx = content.indexOf(END_MARKER);\n\n if (startIdx === -1 || endIdx === -1) return content;\n\n const before = content.slice(0, startIdx).trimEnd();\n const after = content.slice(endIdx + END_MARKER.length).trimStart();\n\n return before + (after ? '\\n\\n' + after : '');\n}\n","/**\n * IDE adapter registry.\n */\n\nimport type { Ide, IdeAdapter } from '../types.js';\nimport { claudeCodeAdapter } from './claude-code.js';\nimport { cursorAdapter } from './cursor.js';\nimport { codexAdapter } from './codex.js';\nimport { windsurfAdapter } from './windsurf.js';\n\nconst adapters: Record<Ide, IdeAdapter> = {\n 'claude-code': claudeCodeAdapter,\n 'cursor': cursorAdapter,\n 'codex': codexAdapter,\n 'windsurf': windsurfAdapter,\n};\n\nexport function getAdapter(ide: Ide): IdeAdapter {\n return adapters[ide];\n}\n\nexport const IDE_CHOICES: Array<{ value: Ide; label: string; hint: string }> = [\n { value: 'claude-code', label: 'Claude Code', hint: '.claude/commands/' },\n { value: 'cursor', label: 'Cursor', hint: '.cursor/rules/' },\n { value: 'codex', label: 'Codex (OpenAI)', hint: 'AGENTS.md' },\n { value: 'windsurf', label: 'Windsurf', hint: '.windsurfrules' },\n];\n","/**\n * setup/auth.ts — Authentication and API key issuance for setup wizard.\n */\n\nimport { createHash, randomBytes } from 'node:crypto';\nimport { createClient } from '@supabase/supabase-js';\nimport {\n LOCAL_SUPABASE_ANON_KEY,\n LOCAL_SUPABASE_SERVICE_ROLE_KEY,\n PRODUCTION_SUPABASE_PUBLISHABLE_KEY,\n PRODUCTION_SUPABASE_URL,\n} from '../src/supabase-defaults.js';\n\nconst API_KEY_PREFIX = 'ff_live_';\nconst MAX_RETRIES = 3;\n\nexport interface AuthResult {\n valid: boolean;\n apiKey: string;\n error?: string;\n}\n\nexport interface LocalAuthResult {\n apiKey: string;\n userId: string;\n email: string;\n}\n\ninterface SetupAuthOptions {\n supabaseUrl?: string;\n anonKey?: string;\n localDev?: boolean;\n}\n\nfunction isTruthy(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';\n}\n\nfunction getSupabaseUrl(options?: SetupAuthOptions): string {\n return options?.supabaseUrl ?? process.env.SUPABASE_URL ?? PRODUCTION_SUPABASE_URL;\n}\n\nfunction isLocalSupabaseUrl(supabaseUrl: string): boolean {\n try {\n const parsed = new URL(supabaseUrl);\n return parsed.hostname === '127.0.0.1' || parsed.hostname === 'localhost';\n } catch {\n return false;\n }\n}\n\nfunction isLocalMode(options?: SetupAuthOptions): boolean {\n if (options?.localDev !== undefined) return options.localDev;\n if (isTruthy(process.env.FORCEFIELD_LOCAL_DEV)) return true;\n return isLocalSupabaseUrl(getSupabaseUrl(options));\n}\n\nfunction getAnonKey(supabaseUrl: string, options?: SetupAuthOptions): string {\n const explicit = options?.anonKey ?? process.env.SUPABASE_ANON_KEY;\n if (explicit && explicit.trim().length > 0) return explicit;\n\n if (isLocalSupabaseUrl(supabaseUrl)) {\n return LOCAL_SUPABASE_ANON_KEY;\n }\n\n return PRODUCTION_SUPABASE_PUBLISHABLE_KEY;\n}\n\nfunction getServiceRoleKey(supabaseUrl: string): string | null {\n const explicit = process.env.SUPABASE_SERVICE_ROLE_KEY;\n if (explicit && explicit.trim().length > 0) return explicit;\n\n if (isLocalSupabaseUrl(supabaseUrl)) {\n return LOCAL_SUPABASE_SERVICE_ROLE_KEY;\n }\n\n return null;\n}\n\n/**\n * Validate API key format.\n */\nexport function validateApiKeyFormat(key: string): boolean {\n return key.startsWith(API_KEY_PREFIX) && key.length > API_KEY_PREFIX.length + 8;\n}\n\n/**\n * Verify an API key through key-exchange endpoint.\n */\nexport async function verifyApiKey(apiKey: string, options?: SetupAuthOptions): Promise<AuthResult> {\n if (!validateApiKeyFormat(apiKey)) {\n return {\n valid: false,\n apiKey: '',\n error: 'Invalid API key format. Keys must start with \"ff_live_\".',\n };\n }\n\n const supabaseUrl = getSupabaseUrl(options);\n const endpoint = `${supabaseUrl}/functions/v1/key-exchange`;\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n const payload = await response.json().catch(() => ({})) as { error?: string };\n const detail = payload.error ?? 'API key invalid or revoked.';\n return {\n valid: false,\n apiKey: '',\n error: `Authentication failed (${response.status}): ${detail}`,\n };\n }\n\n return { valid: true, apiKey };\n } catch {\n return {\n valid: false,\n apiKey: '',\n error: `Could not reach Forcefield backend at ${supabaseUrl}. Check SUPABASE_URL/network and retry.`,\n };\n }\n}\n\n/**\n * Authenticate with retries.\n */\nexport async function authenticateWithRetry(\n getKey: () => Promise<string | null>,\n options?: SetupAuthOptions,\n): Promise<AuthResult> {\n let lastError: string | undefined;\n\n for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n const key = await getKey();\n\n if (!key) {\n return { valid: false, apiKey: '', error: 'No API key provided.' };\n }\n\n const verified = await verifyApiKey(key, options);\n if (verified.valid) {\n return verified;\n }\n\n lastError = verified.error;\n\n if (attempt < MAX_RETRIES) {\n continue;\n }\n }\n\n return {\n valid: false,\n apiKey: '',\n error: lastError ?? `Authentication failed after ${MAX_RETRIES} attempts.`,\n };\n}\n\nfunction generateApiKey(): { plaintext: string; hash: string; prefix: string } {\n const raw = randomBytes(32).toString('hex');\n const plaintext = `${API_KEY_PREFIX}${raw}`;\n const hash = createHash('sha256').update(plaintext).digest('hex');\n const prefix = plaintext.slice(0, 12);\n return { plaintext, hash, prefix };\n}\n\n/**\n * Hosted/local account flow:\n * 1. Sign in (or sign up + sign in)\n * 2. Insert API key under authenticated user\n */\nexport async function authenticateAccountAndCreateApiKey(\n email: string,\n password: string,\n options?: {\n supabaseUrl?: string;\n anonKey?: string;\n label?: string;\n localDev?: boolean;\n },\n): Promise<LocalAuthResult> {\n const supabaseUrl = getSupabaseUrl(options);\n const anonKey = getAnonKey(supabaseUrl, options);\n\n const supabase = createClient(supabaseUrl, anonKey, {\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n let signIn = await supabase.auth.signInWithPassword({ email, password });\n\n if (signIn.error || !signIn.data.user) {\n await supabase.auth.signUp({ email, password });\n signIn = await supabase.auth.signInWithPassword({ email, password });\n }\n\n if (signIn.error || !signIn.data.user) {\n const message = signIn.error?.message ?? 'Invalid login credentials';\n if (/email.*not confirmed/i.test(message)) {\n throw new Error(\n 'Authentication failed: Email not confirmed. Confirm the inbox for this account, or disable email confirmation in Supabase Auth settings for beta.',\n );\n }\n throw new Error(`Authentication failed: ${message}`);\n }\n\n const userId = signIn.data.user.id;\n const { plaintext, hash, prefix } = generateApiKey();\n const { error: insertError } = await supabase\n .from('api_keys')\n .insert({\n user_id: userId,\n key_hash: hash,\n key_prefix: prefix,\n label: options?.label ?? 'Setup Wizard Key',\n tier: 'free',\n });\n\n if (insertError) {\n if (isLocalMode(options)) {\n const serviceRoleKey = getServiceRoleKey(supabaseUrl);\n if (serviceRoleKey) {\n return createApiKeyViaServiceRole({\n supabaseUrl,\n serviceRoleKey,\n email,\n password,\n label: options?.label ?? 'Setup Wizard Key',\n });\n }\n }\n\n throw new Error(`Failed to create API key: ${insertError.message}`);\n }\n\n return {\n apiKey: plaintext,\n userId,\n email,\n };\n}\n\n/**\n * Local auth flow preserved for scripted local development.\n */\nexport async function authenticateLocalAndCreateApiKey(\n email: string,\n password: string,\n options?: { supabaseUrl?: string; anonKey?: string; label?: string },\n): Promise<LocalAuthResult> {\n return authenticateAccountAndCreateApiKey(email, password, {\n ...options,\n localDev: true,\n label: options?.label ?? 'Local Setup Key',\n });\n}\n\nasync function createApiKeyViaServiceRole(params: {\n supabaseUrl: string;\n serviceRoleKey: string;\n email: string;\n password: string;\n label: string;\n}): Promise<LocalAuthResult> {\n const admin = createClient(params.supabaseUrl, params.serviceRoleKey, {\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n let userId: string | undefined;\n const createUser = await admin.auth.admin.createUser({\n email: params.email,\n password: params.password,\n email_confirm: true,\n });\n\n if (createUser.data.user?.id) {\n userId = createUser.data.user.id;\n } else if (createUser.error) {\n const authDb = createClient(params.supabaseUrl, params.serviceRoleKey, {\n db: { schema: 'auth' },\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n const existingUser = await authDb\n .from('users')\n .select('id,email')\n .eq('email', params.email)\n .limit(1)\n .maybeSingle();\n\n if (existingUser.error) {\n throw new Error(`Local login failed: ${createUser.error.message}`);\n }\n userId = existingUser.data?.id;\n }\n\n if (!userId) {\n throw new Error('Local login failed: could not resolve user account');\n }\n\n const { plaintext, hash, prefix } = generateApiKey();\n const { error: insertError } = await admin.from('api_keys').insert({\n user_id: userId,\n key_hash: hash,\n key_prefix: prefix,\n label: params.label,\n tier: 'free',\n });\n\n if (insertError) {\n throw new Error(`Failed to create local API key: ${insertError.message}`);\n }\n\n return {\n apiKey: plaintext,\n userId,\n email: params.email,\n };\n}\n\nexport { API_KEY_PREFIX, MAX_RETRIES };\n","/**\n * Forcefield Setup Wizard — entry point.\n *\n * This is the setup wizard binary (forcefield-setup), usually invoked via\n * `forcefield setup` (or `npx -y @forcefield/forcefield setup`).\n * Parses CLI arguments and launches the interactive wizard.\n */\n\nimport type { CliArgs, Ide, SetupMode } from './types.js';\nimport { runWizard } from './wizard.js';\nimport { pathToFileURL } from 'node:url';\n\nfunction parseArgs(argv: string[]): CliArgs {\n const args: CliArgs = {};\n\n for (let i = 2; i < argv.length; i++) {\n const arg = argv[i]!;\n\n if (arg === '--status') {\n args.status = true;\n } else if (arg === '--doctor') {\n args.doctor = true;\n } else if (arg === '--ide' && argv[i + 1]) {\n const ide = argv[++i]!;\n if (['claude-code', 'cursor', 'codex', 'windsurf'].includes(ide)) {\n args.ide = ide as Ide;\n }\n } else if (arg === '--mode' && argv[i + 1]) {\n const mode = argv[++i]!;\n if (['full', 'core'].includes(mode)) {\n args.mode = mode as SetupMode;\n }\n } else if (arg === '--token' && argv[i + 1]) {\n args.token = argv[++i]!;\n } else if (arg === '--email' && argv[i + 1]) {\n args.email = argv[++i]!;\n } else if (arg === '--password' && argv[i + 1]) {\n args.password = argv[++i]!;\n } else if (arg === '--local-auth') {\n args.localAuth = true;\n }\n }\n\n return args;\n}\n\nasync function main(): Promise<void> {\n const args = parseArgs(process.argv);\n const projectDir = process.cwd();\n\n try {\n await runWizard(projectDir, args);\n } catch (err) {\n console.error('Setup failed:', err instanceof Error ? err.message : err);\n process.exit(1);\n }\n}\n\nexport async function runSetupCli(argv: string[] = process.argv): Promise<void> {\n const originalArgv = process.argv;\n process.argv = argv;\n try {\n await main();\n } finally {\n process.argv = originalArgv;\n }\n}\n\nfunction isExecutedDirectly(metaUrl: string): boolean {\n const entryPath = process.argv[1];\n if (!entryPath) return false;\n return metaUrl === pathToFileURL(entryPath).href;\n}\n\nif (isExecutedDirectly(import.meta.url)) {\n void runSetupCli();\n}\n\nexport { parseArgs };\n"],"mappings":"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","names":["readFile","writeFile","access","join","dirname","fileURLToPath","join","access","join","join","access","join","mkdir","readdir","copyFile","rm","readFile","writeFile","join","join","mkdir","readFile","writeFile","readdir","copyFile","rm","mkdir","readFile","writeFile","join","join","mkdir","readFile","writeFile","readdir","mkdir","readFile","writeFile","join","START_MARKER","END_MARKER","join","mkdir","readFile","writeFile","readdir","removeSection","isTruthy","password","__dirname","dirname","fileURLToPath","join","access","text","readFile","apiKey","confirm","password","writeFile"]}
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-K464TYAJ.js";
5
5
  import {
6
6
  runSetupCli
7
- } from "../chunk-DGBLHABK.js";
7
+ } from "../chunk-7CDDYIDW.js";
8
8
  import {
9
9
  LOCAL_SUPABASE_URL,
10
10
  PRODUCTION_SUPABASE_PUBLISHABLE_KEY,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  parseArgs,
4
4
  runSetupCli
5
- } from "../chunk-DGBLHABK.js";
5
+ } from "../chunk-7CDDYIDW.js";
6
6
  import "../chunk-UOMOGP46.js";
7
7
  export {
8
8
  parseArgs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forcefield/mcp-server",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "AI-powered corporate compliance MCP server",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../setup/wizard.ts","../setup/ide-detect.ts","../setup/ide-adapters/claude-code.ts","../setup/ide-adapters/mcp-runtime.ts","../setup/ide-adapters/cursor.ts","../setup/ide-adapters/codex.ts","../setup/ide-adapters/windsurf.ts","../setup/ide-adapters/index.ts","../setup/auth.ts","../setup/index.ts"],"sourcesContent":["/**\n * setup/wizard.ts — Interactive setup wizard using @clack/prompts.\n *\n * Orchestrates the full setup flow:\n * 1. Welcome banner\n * 2. Existing setup check\n * 3. IDE detection + selection\n * 4. Mode selection (Core vs Full)\n * 5. Authentication\n * 6. Configure + install\n * 7. Verify + success\n */\n\nimport * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport figlet from 'figlet';\nimport gradient from 'gradient-string';\nimport { readFile, writeFile, access } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Ide, SetupMode, SetupConfig, CliArgs } from './types.js';\nimport { detectIde } from './ide-detect.js';\nimport { getAdapter, IDE_CHOICES } from './ide-adapters/index.js';\nimport {\n authenticateAccountAndCreateApiKey,\n authenticateLocalAndCreateApiKey,\n authenticateWithRetry,\n verifyApiKey,\n} from './auth.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst WORKFLOW_DIR_CANDIDATES = [\n join(__dirname, '..', 'workflows'),\n join(__dirname, '..', '..', 'workflows'),\n];\nconst CONFIG_FILE = '.forcefield.json';\nconst VERSION = '0.1.9';\nconst BANNER_TEXT = 'Forcefield';\nconst BANNER_FONT = 'Rowan Cap';\nconst BANNER_MIN_COLUMNS = 80;\nconst BANNER_FALLBACK_TEXT = ' Forcefield';\nconst BANNER_SUBTITLE = ' Corporate compliance copilot\\n';\n// rainbow2-like palette cycling red -> violet for the terminal banner\nconst BANNER_GRADIENT_STOPS = ['#ff3b3b', '#ff9f1a', '#ffe74c', '#2ed573', '#1e90ff', '#7d5fff', '#e056fd'];\nconst bannerGradient = gradient(BANNER_GRADIENT_STOPS);\n\nasync function resolveWorkflowsDir(): Promise<string> {\n for (const dir of WORKFLOW_DIR_CANDIDATES) {\n try {\n await access(dir);\n return dir;\n } catch {\n // try next candidate\n }\n }\n throw new Error(\n `Unable to locate workflow templates. Checked: ${WORKFLOW_DIR_CANDIDATES.join(', ')}`,\n );\n}\n\n/**\n * Run the interactive setup wizard.\n */\nexport async function runWizard(projectDir: string, args: CliArgs): Promise<void> {\n // --status: read-only check\n if (args.status) {\n await showStatus(projectDir);\n return;\n }\n\n // --doctor: setup diagnostics\n if (args.doctor) {\n await runDoctor(projectDir, args);\n return;\n }\n\n // Non-interactive mode\n if (args.ide && args.mode && (args.token || args.localAuth || (args.email && args.password))) {\n await runNonInteractive(projectDir, args);\n return;\n }\n\n // Interactive mode\n await runInteractive(projectDir, args);\n}\n\n// === Welcome Banner ===\n\nfunction showBanner(): void {\n const cols = process.stdout.columns || 80;\n\n if (cols >= BANNER_MIN_COLUMNS) {\n try {\n const banner = figlet.textSync(BANNER_TEXT, { font: BANNER_FONT });\n const colored = applyBannerGradient(banner);\n console.log(colored);\n } catch {\n // figlet font not available — use fallback\n console.log(pc.bold(applyBannerGradient(BANNER_FALLBACK_TEXT)));\n }\n } else {\n console.log(pc.bold(applyBannerGradient(BANNER_FALLBACK_TEXT)));\n }\n console.log(pc.dim(BANNER_SUBTITLE));\n}\n\nfunction applyBannerGradient(text: string): string {\n return bannerGradient.multiline(text);\n}\n\n// === Status Check ===\n\nasync function showStatus(projectDir: string): Promise<void> {\n const config = await readConfig(projectDir);\n\n if (!config) {\n console.log(pc.yellow('No Forcefield setup found in this directory.'));\n console.log(`Run ${pc.cyan('forcefield setup')} to get started.`);\n process.exit(1);\n }\n\n console.log(pc.bold('Forcefield Setup Status'));\n console.log(` IDE: ${pc.cyan(config.ide)}`);\n console.log(` Mode: ${pc.cyan(config.mode)}`);\n console.log(` Version: ${pc.cyan(config.version)}`);\n console.log(` Installed: ${pc.dim(config.installed_at)}`);\n}\n\ninterface DoctorCheckResult {\n ok: boolean;\n label: string;\n detail: string;\n}\n\ninterface McpCheckResult {\n ok: boolean;\n filePath: string;\n key?: string;\n supabaseUrl?: string;\n detail: string;\n}\n\nasync function runDoctor(projectDir: string, args: CliArgs): Promise<void> {\n console.log(pc.bold('Forcefield Setup Doctor'));\n console.log(pc.dim(`Project: ${projectDir}`));\n\n const checks: DoctorCheckResult[] = [];\n const config = await readConfig(projectDir);\n\n if (!config) {\n checks.push({\n ok: false,\n label: 'Setup config',\n detail: `Missing ${CONFIG_FILE}. Run forcefield setup first.`,\n });\n } else {\n checks.push({\n ok: true,\n label: 'Setup config',\n detail: `${config.ide} / ${config.mode} / v${config.version}`,\n });\n\n const mcp = await inspectMcpConfig(projectDir, config.ide);\n checks.push({\n ok: mcp.ok,\n label: 'MCP config',\n detail: `${mcp.filePath} — ${mcp.detail}`,\n });\n\n if (mcp.key) {\n const verified = await verifyApiKey(mcp.key, {\n localDev: isLocalSetupMode(args),\n supabaseUrl: mcp.supabaseUrl,\n });\n checks.push({\n ok: verified.valid,\n label: 'API key exchange',\n detail: verified.valid\n ? `Key exchange succeeded${mcp.supabaseUrl ? ` (${mcp.supabaseUrl})` : ''}.`\n : (verified.error ?? 'Key exchange failed.'),\n });\n } else {\n checks.push({\n ok: false,\n label: 'API key exchange',\n detail: 'FORCEFIELD_API_KEY not found in MCP config env.',\n });\n }\n }\n\n for (const check of checks) {\n const symbol = check.ok ? pc.green('✓') : pc.red('✗');\n console.log(`${symbol} ${pc.bold(check.label)}: ${check.detail}`);\n }\n\n const failures = checks.filter((check) => !check.ok);\n if (failures.length > 0) {\n console.log('');\n console.log(pc.yellow('Suggested fixes:'));\n console.log(` 1. Re-run ${pc.cyan('forcefield setup')} in this project.`);\n console.log(` 2. Confirm your coding agent shows Forcefield connected (${pc.cyan('/mcp')}).`);\n console.log(` 3. Re-run ${pc.cyan('forcefield doctor')} after setup.`);\n process.exit(1);\n }\n\n console.log('');\n console.log(pc.green('Doctor checks passed. Forcefield should be ready.'));\n}\n\nasync function inspectMcpConfig(projectDir: string, ide: Ide): Promise<McpCheckResult> {\n if (ide === 'claude-code') {\n return inspectJsonMcpConfig(join(projectDir, '.mcp.json'), 'mcpServers');\n }\n\n if (ide === 'cursor') {\n return inspectJsonMcpConfig(join(projectDir, '.cursor', 'mcp.json'), 'mcpServers');\n }\n\n if (ide === 'windsurf') {\n return inspectJsonMcpConfig(join(projectDir, '.windsurf', 'mcp_config.json'), 'mcpServers');\n }\n\n return inspectCodexMcpConfig(join(projectDir, '.codex', 'config.toml'));\n}\n\nasync function inspectJsonMcpConfig(\n filePath: string,\n rootKey: string,\n): Promise<McpCheckResult> {\n let raw = '';\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'File not found.',\n };\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'Invalid JSON.',\n };\n }\n\n const servers =\n typeof parsed[rootKey] === 'object' && parsed[rootKey] != null\n ? (parsed[rootKey] as Record<string, unknown>)\n : null;\n\n if (!servers || typeof servers.forcefield !== 'object' || servers.forcefield == null) {\n return {\n ok: false,\n filePath,\n detail: 'Missing forcefield MCP server entry.',\n };\n }\n\n const ffServer = servers.forcefield as Record<string, unknown>;\n const command = typeof ffServer.command === 'string' ? ffServer.command : '';\n const env = typeof ffServer.env === 'object' && ffServer.env != null\n ? (ffServer.env as Record<string, unknown>)\n : {};\n const key = typeof env.FORCEFIELD_API_KEY === 'string'\n ? env.FORCEFIELD_API_KEY\n : undefined;\n const supabaseUrl = typeof env.SUPABASE_URL === 'string'\n ? env.SUPABASE_URL\n : undefined;\n\n if (!command) {\n return {\n ok: false,\n filePath,\n key,\n supabaseUrl,\n detail: 'forcefield entry missing command.',\n };\n }\n\n return {\n ok: true,\n filePath,\n key,\n supabaseUrl,\n detail: `Found forcefield entry (command: ${command}${supabaseUrl ? `, supabase: ${supabaseUrl}` : ''}).`,\n };\n}\n\nasync function inspectCodexMcpConfig(filePath: string): Promise<McpCheckResult> {\n let raw = '';\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'File not found.',\n };\n }\n\n const command = extractTomlValue(raw, /^\\s*command\\s*=\\s*\"([^\"]+)\"/m);\n const key = extractTomlValue(raw, /^\\s*FORCEFIELD_API_KEY\\s*=\\s*\"([^\"]+)\"/m);\n const supabaseUrl = extractTomlValue(raw, /^\\s*SUPABASE_URL\\s*=\\s*\"([^\"]+)\"/m);\n const hasServerSection = raw.includes('[mcp_servers.forcefield]');\n\n if (!hasServerSection) {\n return {\n ok: false,\n filePath,\n key,\n supabaseUrl,\n detail: 'Missing [mcp_servers.forcefield] section.',\n };\n }\n\n if (!command) {\n return {\n ok: false,\n filePath,\n key,\n supabaseUrl,\n detail: 'forcefield section missing command.',\n };\n }\n\n return {\n ok: true,\n filePath,\n key,\n supabaseUrl,\n detail: `Found forcefield section (command: ${command}${supabaseUrl ? `, supabase: ${supabaseUrl}` : ''}).`,\n };\n}\n\nfunction extractTomlValue(content: string, pattern: RegExp): string | undefined {\n const match = content.match(pattern);\n return match?.[1];\n}\n\n// === Non-Interactive Mode ===\n\nasync function runNonInteractive(projectDir: string, args: CliArgs): Promise<void> {\n const ide = args.ide!;\n const mode = args.mode!;\n let apiKey = args.token;\n\n if (args.localAuth) {\n if (!args.email || !args.password) {\n console.error(pc.red('Non-interactive local auth requires --email and --password.'));\n process.exit(1);\n }\n\n const auth = await authenticateLocalAndCreateApiKey(args.email, args.password, {\n label: 'Setup Wizard (Local)',\n });\n apiKey = auth.apiKey;\n console.log(`Created local API key for ${auth.email}.`);\n } else if (!apiKey && args.email && args.password) {\n const auth = await authenticateAccountAndCreateApiKey(args.email, args.password, {\n label: 'Setup Wizard Key',\n localDev: isLocalSetupMode(args),\n });\n apiKey = auth.apiKey;\n console.log(`Created API key for ${auth.email}.`);\n } else if (apiKey) {\n const verified = await authenticateWithRetry(async () => apiKey ?? null, {\n localDev: isLocalSetupMode(args),\n });\n if (!verified.valid) {\n console.error(pc.red(verified.error ?? 'API key validation failed.'));\n process.exit(1);\n }\n apiKey = verified.apiKey;\n }\n\n if (!apiKey) {\n console.error(pc.red('Missing auth input. Pass --token, --local-auth, or --email/--password.'));\n process.exit(1);\n }\n\n console.log(`Setting up Forcefield for ${ide} in ${mode} mode...`);\n\n await configure(projectDir, ide, mode, apiKey);\n\n console.log(pc.green('Setup complete!'));\n for (const line of getPostSetupInstructions(ide, mode, projectDir)) {\n console.log(line);\n }\n}\n\n// === Interactive Mode ===\n\nasync function runInteractive(projectDir: string, preArgs: CliArgs): Promise<void> {\n showBanner();\n\n p.intro(pc.bgCyan(pc.black(' Forcefield Setup ')));\n\n // Step 1: Check existing setup\n const existingConfig = await readConfig(projectDir);\n if (existingConfig) {\n const updateChoice = await p.select({\n message: `Forcefield is already set up (${existingConfig.ide}, ${existingConfig.mode} mode).`,\n options: [\n { value: 'update', label: 'Update existing setup', hint: 'Refresh workflows + auth' },\n { value: 'fresh', label: 'Start fresh', hint: 'Remove existing config and reconfigure' },\n ],\n });\n\n if (p.isCancel(updateChoice)) {\n p.cancel('Setup cancelled.');\n process.exit(0);\n }\n\n if (updateChoice === 'update') {\n // Re-run configure with existing settings\n const apiKey = await promptApiKey();\n if (!apiKey) return;\n await configure(projectDir, existingConfig.ide, existingConfig.mode, apiKey);\n showSuccess(existingConfig.ide, existingConfig.mode, projectDir);\n return;\n }\n // fresh → continue with full wizard\n }\n\n // Step 2: IDE detection + selection\n const ide = preArgs.ide ?? await promptIde(projectDir);\n if (!ide) return;\n\n // Step 3: Mode selection\n const mode = preArgs.mode ?? await promptMode();\n if (!mode) return;\n\n // Step 4: Authentication\n const apiKey = preArgs.token ?? await promptApiKey(preArgs);\n if (!apiKey) return;\n\n // Step 5: Configure + install\n const s = p.spinner();\n s.start('Configuring Forcefield...');\n\n try {\n await configure(projectDir, ide, mode, apiKey);\n s.stop('Configuration complete.');\n } catch (err) {\n s.stop('Configuration failed.');\n p.cancel(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n\n // Step 6: Success\n showSuccess(ide, mode, projectDir);\n}\n\n// === Prompts ===\n\nasync function promptIde(projectDir: string): Promise<Ide | null> {\n const detection = await detectIde(projectDir);\n\n if (detection.detected) {\n const adapter = getAdapter(detection.detected);\n const confirm = await p.confirm({\n message: `Detected ${adapter.name} (${detection.markers[0]!.marker} found). Use ${adapter.name}?`,\n });\n\n if (p.isCancel(confirm)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (confirm) return detection.detected;\n }\n\n const choice = await p.select({\n message: 'Which IDE do you use?',\n options: IDE_CHOICES,\n });\n\n if (p.isCancel(choice)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return choice as Ide;\n}\n\nasync function promptMode(): Promise<SetupMode | null> {\n const choice = await p.select({\n message: 'Installation type:',\n options: [\n { value: 'full' as const, label: 'Full — MCP server + guided workflows', hint: 'Recommended' },\n { value: 'core' as const, label: 'Core — MCP server only', hint: 'Minimal' },\n ],\n });\n\n if (p.isCancel(choice)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return choice as SetupMode;\n}\n\nasync function promptApiKey(preArgs?: CliArgs): Promise<string | null> {\n if (preArgs?.localAuth) {\n const preEmail = preArgs.email ?? await promptTextValue('Local test email:', 'alice@test.local');\n const prePassword = preArgs.password ?? await promptPasswordValue(\n 'Local test password:',\n 'Confirm local test password:',\n );\n if (!preEmail || !prePassword) return null;\n\n try {\n const result = await authenticateLocalAndCreateApiKey(preEmail, prePassword, {\n label: 'Setup Wizard (Local)',\n });\n p.log.success(`Created local API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Failed local auth');\n return null;\n }\n }\n\n const localMode = isLocalSetupMode(preArgs);\n const methodOptions = [\n { value: 'account', label: 'Sign in / create account + API key', hint: 'Recommended' },\n { value: 'paste', label: 'Paste existing API key', hint: 'Use an existing ff_live_... key' },\n ];\n\n if (localMode) {\n methodOptions.push({\n value: 'local',\n label: 'Create local account + API key',\n hint: 'For local Supabase testing',\n });\n }\n\n const method = await p.select({\n message: 'How do you want to authenticate?',\n options: methodOptions,\n });\n\n if (p.isCancel(method)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (method === 'account') {\n const email = await promptTextValue('Account email:', preArgs?.email ?? 'you@company.com');\n const password = preArgs?.password ?? await promptPasswordValue(\n 'Account password:',\n 'Confirm account password:',\n );\n if (!email || !password) return null;\n\n try {\n const result = await authenticateAccountAndCreateApiKey(email, password, {\n label: 'Setup Wizard Key',\n localDev: localMode,\n });\n p.log.success(`Created API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Account authentication failed');\n return null;\n }\n }\n\n if (method === 'local') {\n const email = await promptTextValue('Local test email:', 'alice@test.local');\n const password = await promptPasswordValue(\n 'Local test password:',\n 'Confirm local test password:',\n );\n if (!email || !password) return null;\n\n try {\n const result = await authenticateLocalAndCreateApiKey(email, password, {\n label: 'Setup Wizard (Local)',\n });\n p.log.success(`Created local API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Failed local auth');\n return null;\n }\n }\n\n const auth = await authenticateWithRetry(\n async () => {\n const key = await p.text({\n message: 'Enter your Forcefield API key:',\n placeholder: 'ff_live_...',\n validate: (value) => {\n if (!value) return 'API key is required.';\n if (!value.startsWith('ff_live_')) return 'Key must start with \"ff_live_\".';\n if (value.length < 20) return 'Key seems too short.';\n return undefined;\n },\n });\n\n if (p.isCancel(key)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return key;\n },\n {\n localDev: localMode,\n },\n );\n\n if (!auth.valid) {\n p.log.error(auth.error ?? 'Authentication failed. Check your credentials and retry.');\n return null;\n }\n\n return auth.apiKey;\n}\n\nfunction isLocalSetupMode(preArgs?: CliArgs): boolean {\n if (preArgs?.localAuth) return true;\n const localValue = process.env.FORCEFIELD_LOCAL_DEV;\n if (localValue) {\n const normalized = localValue.trim().toLowerCase();\n if (['1', 'true', 'yes', 'on'].includes(normalized)) {\n return true;\n }\n }\n\n const supabaseUrl = process.env.SUPABASE_URL;\n if (!supabaseUrl) return false;\n try {\n const parsed = new URL(supabaseUrl);\n return parsed.hostname === '127.0.0.1' || parsed.hostname === 'localhost';\n } catch {\n return false;\n }\n}\n\nasync function promptTextValue(\n message: string,\n placeholder: string,\n): Promise<string | null> {\n const value = await p.text({\n message,\n placeholder,\n validate: (input) => {\n if (!input) return 'This field is required.';\n return undefined;\n },\n });\n\n if (p.isCancel(value)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n return value;\n}\n\nasync function promptPasswordValue(\n message: string,\n confirmMessage?: string,\n): Promise<string | null> {\n const password = await p.password({\n message,\n validate: (input) => {\n if (!input) return 'Password is required.';\n if (input.length < 8) return 'Password must be at least 8 characters.';\n return undefined;\n },\n });\n\n if (p.isCancel(password)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (!confirmMessage) {\n return password;\n }\n\n const confirm = await p.password({\n message: confirmMessage,\n validate: (input) => {\n if (!input) return 'Please confirm your password.';\n return undefined;\n },\n });\n\n if (p.isCancel(confirm)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (password !== confirm) {\n p.log.error('Passwords do not match. Please run setup again.');\n return null;\n }\n\n return password;\n}\n\n// === Configure ===\n\nasync function configure(\n projectDir: string,\n ide: Ide,\n mode: SetupMode,\n apiKey: string,\n): Promise<void> {\n const adapter = getAdapter(ide);\n\n // Configure MCP\n await adapter.configureMcp(projectDir, apiKey);\n\n // Install workflows (full mode only)\n let workflowCount = 0;\n if (mode === 'full') {\n const workflowsDir = await resolveWorkflowsDir();\n workflowCount = await adapter.installWorkflows(projectDir, workflowsDir);\n }\n\n // Write config\n const config: SetupConfig = {\n ide,\n mode,\n installed_at: new Date().toISOString(),\n version: VERSION,\n };\n await writeConfig(projectDir, config);\n\n void workflowCount; // Used in logging below\n}\n\nfunction getPostSetupInstructions(ide: Ide, mode: SetupMode, projectDir: string): string[] {\n const repo = pc.cyan(projectDir);\n const dashboardHint = [\n `Optional beta companion: run ${pc.cyan('forcefield dashboard start')} to scaffold and launch the local dashboard (hosted backend by default).`,\n `If ${pc.cyan('forcefield')} is not installed globally, use ${pc.cyan('npx -y @forcefield/forcefield dashboard start')}. Advanced mode: pass ${pc.cyan('--local')} for local Supabase.`,\n ];\n\n if (mode === 'core') {\n return [\n `Next: open your coding agent in ${repo} and use Forcefield MCP tools directly (e.g. ${pc.cyan('ff_system(action: \"health\")')}).`,\n ...dashboardHint,\n ];\n }\n\n const common = [\n `Next: start your coding agent in ${repo}.`,\n `Then in IDE chat (not terminal), run ${pc.cyan('/ff-onboard')} to set up your company profile and deadlines.`,\n `Optional: run ${pc.cyan('/ff-start')} only if you want a command primer or connection troubleshooting.`,\n `If connection fails, run ${pc.cyan('forcefield doctor')} in terminal for diagnostics.`,\n ...dashboardHint,\n ];\n\n if (ide === 'claude-code') {\n return [\n ...common,\n `If tools are missing, run ${pc.cyan('/mcp')} and confirm ${pc.cyan('forcefield')} is connected.`,\n ];\n }\n\n return common;\n}\n\nfunction showSuccess(ide: Ide, mode: SetupMode, projectDir: string): void {\n const adapter = getAdapter(ide);\n const workflowStatus =\n mode === 'full'\n ? `${pc.green('✓')} Project workflow commands installed`\n : `${pc.yellow('•')} Core mode selected (no slash-command workflows installed)`;\n\n p.note(\n [\n `${pc.green('✓')} MCP server configured`,\n workflowStatus,\n `${pc.green('✓')} IDE: ${adapter.name}`,\n ].join('\\n'),\n 'Setup Complete',\n );\n\n p.outro(getPostSetupInstructions(ide, mode, projectDir).join('\\n'));\n}\n\n// === Config File ===\n\nasync function readConfig(projectDir: string): Promise<SetupConfig | null> {\n const configPath = join(projectDir, CONFIG_FILE);\n try {\n await access(configPath);\n const raw = await readFile(configPath, 'utf-8');\n return JSON.parse(raw) as SetupConfig;\n } catch {\n return null;\n }\n}\n\nasync function writeConfig(projectDir: string, config: SetupConfig): Promise<void> {\n const configPath = join(projectDir, CONFIG_FILE);\n await writeFile(configPath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport {\n readConfig,\n writeConfig,\n CONFIG_FILE,\n VERSION,\n BANNER_FONT,\n BANNER_MIN_COLUMNS,\n BANNER_GRADIENT_STOPS,\n showBanner,\n applyBannerGradient,\n getPostSetupInstructions,\n inspectMcpConfig,\n inspectJsonMcpConfig,\n inspectCodexMcpConfig,\n extractTomlValue,\n};\n","/**\n * setup/ide-detect.ts — Auto-detect IDE from project directory markers.\n */\n\nimport { access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { Ide } from './types.js';\n\ninterface DetectionResult {\n detected: Ide | null;\n markers: Array<{ ide: Ide; marker: string }>;\n}\n\nconst IDE_MARKERS: Array<{ ide: Ide; marker: string; isDir: boolean }> = [\n { ide: 'claude-code', marker: '.claude', isDir: true },\n { ide: 'cursor', marker: '.cursor', isDir: true },\n { ide: 'codex', marker: 'AGENTS.md', isDir: false },\n { ide: 'windsurf', marker: '.windsurfrules', isDir: false },\n];\n\nexport async function detectIde(projectDir: string): Promise<DetectionResult> {\n const found: Array<{ ide: Ide; marker: string }> = [];\n\n for (const { ide, marker } of IDE_MARKERS) {\n const markerPath = join(projectDir, marker);\n try {\n await access(markerPath);\n found.push({ ide, marker });\n } catch {\n // Marker not found — skip\n }\n }\n\n return {\n detected: found.length === 1 ? found[0]!.ide : null,\n markers: found,\n };\n}\n\nexport { IDE_MARKERS };\n","/**\n * IDE adapter for Claude Code.\n * Workflows → .claude/commands/ff-*.md\n * MCP → project-scoped .mcp.json entry\n */\n\nimport { mkdir, readdir, copyFile, rm, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nexport const claudeCodeAdapter: IdeAdapter = {\n name: 'Claude Code',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n // Ensure Claude config folder exists for slash-command workflows.\n const claudeDir = join(projectDir, '.claude');\n await mkdir(claudeDir, { recursive: true });\n\n // Configure project-scoped MCP entry used by Claude Code.\n const launch = await getMcpLaunchConfig();\n const mcpPath = join(projectDir, '.mcp.json');\n\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(await readFile(mcpPath, 'utf-8')) as Record<string, unknown>;\n } catch {\n // file missing/invalid: start fresh\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? (existing.mcpServers as Record<string, unknown>)\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const nextConfig = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(mcpPath, JSON.stringify(nextConfig, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const commandsDir = join(projectDir, '.claude', 'commands');\n await mkdir(commandsDir, { recursive: true });\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n for (const file of mdFiles) {\n await copyFile(join(workflowsDir, file), join(commandsDir, file));\n }\n\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const commandsDir = join(projectDir, '.claude', 'commands');\n try {\n const files = await readdir(commandsDir);\n for (const file of files) {\n if (file.startsWith('ff-') && file.endsWith('.md')) {\n await rm(join(commandsDir, file));\n }\n }\n } catch {\n // Directory doesn't exist — nothing to remove\n }\n },\n};\n","import { access } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst LOCAL_ENTRY_CANDIDATES = [\n join(__dirname, '..', '..', 'build', 'index.js'),\n join(__dirname, '..', '..', 'index.js'),\n];\n\nconst FORWARDED_ENV_KEYS = [\n 'SUPABASE_URL',\n 'SUPABASE_ANON_KEY',\n 'FORCEFIELD_LOCAL_DEV',\n 'FORCEFIELD_DISABLE_GATING',\n 'FORCEFIELD_LOCAL_DATA_FALLBACK',\n] as const;\n\nfunction isTruthy(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';\n}\n\nasync function resolveLocalEntry(): Promise<string | null> {\n for (const candidate of LOCAL_ENTRY_CANDIDATES) {\n try {\n await access(candidate);\n return candidate;\n } catch {\n // try next candidate\n }\n }\n return null;\n}\n\nexport async function getMcpLaunchConfig(): Promise<{ command: string; args: string[] }> {\n if (\n isTruthy(process.env.FORCEFIELD_LOCAL_DEV)\n || isTruthy(process.env.FORCEFIELD_SETUP_USE_LOCAL_BUILD)\n ) {\n const localEntry = await resolveLocalEntry();\n if (localEntry) {\n return {\n command: process.execPath,\n args: [localEntry],\n };\n }\n }\n\n return {\n command: 'npx',\n args: ['-y', '-p', '@forcefield/mcp-server', 'forcefield-mcp'],\n };\n}\n\nexport function buildMcpEnv(apiKey: string): Record<string, string> {\n const env: Record<string, string> = {\n FORCEFIELD_API_KEY: apiKey,\n };\n\n // Default to hosted-first deterministic config.\n // Forwarding setup-shell env into MCP runtime is opt-in to avoid\n // accidentally persisting local/dev flags into project config.\n if (!isTruthy(process.env.FORCEFIELD_SETUP_FORWARD_ENV)) {\n return env;\n }\n\n for (const key of FORWARDED_ENV_KEYS) {\n const value = process.env[key];\n if (value && value.trim().length > 0) {\n env[key] = value;\n }\n }\n\n return env;\n}\n","/**\n * IDE adapter for Cursor.\n * Workflows → .cursor/rules/ff-*.md\n * MCP → .cursor/mcp.json\n */\n\nimport { mkdir, readdir, copyFile, rm, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\ntype CursorMcpConfig = {\n mcpServers?: Record<string, { command: string; args: string[]; env?: Record<string, string> }>;\n};\n\nexport const cursorAdapter: IdeAdapter = {\n name: 'Cursor',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const cursorDir = join(projectDir, '.cursor');\n await mkdir(cursorDir, { recursive: true });\n\n const configPath = join(cursorDir, 'mcp.json');\n const launch = await getMcpLaunchConfig();\n\n let existing: CursorMcpConfig = {};\n try {\n existing = JSON.parse(await readFile(configPath, 'utf-8')) as CursorMcpConfig;\n } catch {\n // file missing/invalid: overwrite with fresh config\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? existing.mcpServers\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const merged: CursorMcpConfig = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(configPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const rulesDir = join(projectDir, '.cursor', 'rules');\n await mkdir(rulesDir, { recursive: true });\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n for (const file of mdFiles) {\n await copyFile(join(workflowsDir, file), join(rulesDir, file));\n }\n\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const rulesDir = join(projectDir, '.cursor', 'rules');\n try {\n const files = await readdir(rulesDir);\n for (const file of files) {\n if (file.startsWith('ff-') && file.endsWith('.md')) {\n await rm(join(rulesDir, file));\n }\n }\n } catch {\n // Directory doesn't exist\n }\n },\n};\n","/**\n * IDE adapter for Codex (OpenAI).\n * Workflows → appended to AGENTS.md with markers\n * MCP → .codex/config.toml or project-level config\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nconst START_MARKER = '<!-- forcefield:start -->';\nconst END_MARKER = '<!-- forcefield:end -->';\nconst MCP_START_MARKER = '# forcefield:mcp:start';\nconst MCP_END_MARKER = '# forcefield:mcp:end';\n\nexport const codexAdapter: IdeAdapter = {\n name: 'Codex',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const codexDir = join(projectDir, '.codex');\n await mkdir(codexDir, { recursive: true });\n\n const configPath = join(codexDir, 'config.toml');\n const launch = await getMcpLaunchConfig();\n const env = buildMcpEnv(apiKey);\n\n const forcefieldBlock = buildForcefieldTomlBlock(launch.command, launch.args, env);\n\n let existing = '';\n try {\n existing = await readFile(configPath, 'utf-8');\n } catch {\n // file missing — create new\n }\n\n const cleaned = removeTomlForcefieldSection(existing).trim();\n const final = cleaned ? `${cleaned}\\n\\n${forcefieldBlock}\\n` : `${forcefieldBlock}\\n`;\n await writeFile(configPath, final, 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const agentsPath = join(projectDir, 'AGENTS.md');\n const { readdir } = await import('node:fs/promises');\n\n // Read all workflow files\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n const workflowContents: string[] = [];\n for (const file of mdFiles) {\n const content = await readFile(join(workflowsDir, file), 'utf-8');\n workflowContents.push(content);\n }\n\n const forcefieldSection = [\n START_MARKER,\n '',\n '# Forcefield Workflows',\n '',\n 'The following workflows are available for compliance management:',\n '',\n ...workflowContents.map((c) => c + '\\n\\n---\\n'),\n END_MARKER,\n ].join('\\n');\n\n // Read existing AGENTS.md or create new\n let existing = '';\n try {\n existing = await readFile(agentsPath, 'utf-8');\n } catch {\n // File doesn't exist — will create\n }\n\n // Remove existing Forcefield section if present\n const cleaned = removeSection(existing);\n\n // Append new section\n const final = cleaned.trim()\n ? cleaned.trim() + '\\n\\n' + forcefieldSection\n : forcefieldSection;\n\n await writeFile(agentsPath, final, 'utf-8');\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const agentsPath = join(projectDir, 'AGENTS.md');\n try {\n const content = await readFile(agentsPath, 'utf-8');\n const cleaned = removeSection(content);\n await writeFile(agentsPath, cleaned, 'utf-8');\n } catch {\n // File doesn't exist — nothing to remove\n }\n },\n};\n\nfunction removeSection(content: string): string {\n const startIdx = content.indexOf(START_MARKER);\n const endIdx = content.indexOf(END_MARKER);\n\n if (startIdx === -1 || endIdx === -1) return content;\n\n const before = content.slice(0, startIdx).trimEnd();\n const after = content.slice(endIdx + END_MARKER.length).trimStart();\n\n return before + (after ? '\\n\\n' + after : '');\n}\n\nfunction removeTomlForcefieldSection(content: string): string {\n const markerStart = content.indexOf(MCP_START_MARKER);\n const markerEnd = content.indexOf(MCP_END_MARKER);\n\n if (markerStart !== -1 && markerEnd !== -1) {\n const before = content.slice(0, markerStart).trimEnd();\n const after = content.slice(markerEnd + MCP_END_MARKER.length).trimStart();\n return before + (after ? '\\n\\n' + after : '');\n }\n\n // Backward-compatible cleanup if a previous config wrote unmanaged sections.\n return content\n .replace(/^\\[mcp_servers\\.forcefield\\]\\n[\\s\\S]*?(?=^\\[|$)/gm, '')\n .replace(/^\\[mcp_servers\\.forcefield\\.env\\]\\n[\\s\\S]*?(?=^\\[|$)/gm, '')\n .trim();\n}\n\nfunction buildForcefieldTomlBlock(\n command: string,\n args: string[],\n env: Record<string, string>,\n): string {\n const envLines = Object.entries(env)\n .map(([key, value]) => `${key} = \"${escapeTomlString(value)}\"`);\n\n return [\n MCP_START_MARKER,\n '[mcp_servers.forcefield]',\n `command = \"${escapeTomlString(command)}\"`,\n `args = [${args.map((arg) => `\"${escapeTomlString(arg)}\"`).join(', ')}]`,\n '[mcp_servers.forcefield.env]',\n ...envLines,\n MCP_END_MARKER,\n ].join('\\n');\n}\n\nfunction escapeTomlString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n","/**\n * IDE adapter for Windsurf.\n * Workflows → appended to .windsurfrules with markers\n * MCP → Windsurf MCP config\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nconst START_MARKER = '<!-- forcefield:start -->';\nconst END_MARKER = '<!-- forcefield:end -->';\n\nexport const windsurfAdapter: IdeAdapter = {\n name: 'Windsurf',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const configDir = join(projectDir, '.windsurf');\n await mkdir(configDir, { recursive: true });\n\n const configPath = join(configDir, 'mcp_config.json');\n const launch = await getMcpLaunchConfig();\n\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(await readFile(configPath, 'utf-8')) as Record<string, unknown>;\n } catch {\n // file missing/invalid: start fresh\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? (existing.mcpServers as Record<string, unknown>)\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const merged = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(configPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const rulesPath = join(projectDir, '.windsurfrules');\n const { readdir } = await import('node:fs/promises');\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n const workflowContents: string[] = [];\n for (const file of mdFiles) {\n const content = await readFile(join(workflowsDir, file), 'utf-8');\n workflowContents.push(content);\n }\n\n const forcefieldSection = [\n START_MARKER,\n '',\n '# Forcefield Workflows',\n '',\n ...workflowContents.map((c) => c + '\\n\\n---\\n'),\n END_MARKER,\n ].join('\\n');\n\n let existing = '';\n try {\n existing = await readFile(rulesPath, 'utf-8');\n } catch {\n // File doesn't exist\n }\n\n const cleaned = removeSection(existing);\n const final = cleaned.trim()\n ? cleaned.trim() + '\\n\\n' + forcefieldSection\n : forcefieldSection;\n\n await writeFile(rulesPath, final, 'utf-8');\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const rulesPath = join(projectDir, '.windsurfrules');\n try {\n const content = await readFile(rulesPath, 'utf-8');\n const cleaned = removeSection(content);\n await writeFile(rulesPath, cleaned, 'utf-8');\n } catch {\n // File doesn't exist\n }\n },\n};\n\nfunction removeSection(content: string): string {\n const startIdx = content.indexOf(START_MARKER);\n const endIdx = content.indexOf(END_MARKER);\n\n if (startIdx === -1 || endIdx === -1) return content;\n\n const before = content.slice(0, startIdx).trimEnd();\n const after = content.slice(endIdx + END_MARKER.length).trimStart();\n\n return before + (after ? '\\n\\n' + after : '');\n}\n","/**\n * IDE adapter registry.\n */\n\nimport type { Ide, IdeAdapter } from '../types.js';\nimport { claudeCodeAdapter } from './claude-code.js';\nimport { cursorAdapter } from './cursor.js';\nimport { codexAdapter } from './codex.js';\nimport { windsurfAdapter } from './windsurf.js';\n\nconst adapters: Record<Ide, IdeAdapter> = {\n 'claude-code': claudeCodeAdapter,\n 'cursor': cursorAdapter,\n 'codex': codexAdapter,\n 'windsurf': windsurfAdapter,\n};\n\nexport function getAdapter(ide: Ide): IdeAdapter {\n return adapters[ide];\n}\n\nexport const IDE_CHOICES: Array<{ value: Ide; label: string; hint: string }> = [\n { value: 'claude-code', label: 'Claude Code', hint: '.claude/commands/' },\n { value: 'cursor', label: 'Cursor', hint: '.cursor/rules/' },\n { value: 'codex', label: 'Codex (OpenAI)', hint: 'AGENTS.md' },\n { value: 'windsurf', label: 'Windsurf', hint: '.windsurfrules' },\n];\n","/**\n * setup/auth.ts — Authentication and API key issuance for setup wizard.\n */\n\nimport { createHash, randomBytes } from 'node:crypto';\nimport { createClient } from '@supabase/supabase-js';\nimport {\n LOCAL_SUPABASE_ANON_KEY,\n LOCAL_SUPABASE_SERVICE_ROLE_KEY,\n PRODUCTION_SUPABASE_PUBLISHABLE_KEY,\n PRODUCTION_SUPABASE_URL,\n} from '../src/supabase-defaults.js';\n\nconst API_KEY_PREFIX = 'ff_live_';\nconst MAX_RETRIES = 3;\n\nexport interface AuthResult {\n valid: boolean;\n apiKey: string;\n error?: string;\n}\n\nexport interface LocalAuthResult {\n apiKey: string;\n userId: string;\n email: string;\n}\n\ninterface SetupAuthOptions {\n supabaseUrl?: string;\n anonKey?: string;\n localDev?: boolean;\n}\n\nfunction isTruthy(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';\n}\n\nfunction getSupabaseUrl(options?: SetupAuthOptions): string {\n return options?.supabaseUrl ?? process.env.SUPABASE_URL ?? PRODUCTION_SUPABASE_URL;\n}\n\nfunction isLocalSupabaseUrl(supabaseUrl: string): boolean {\n try {\n const parsed = new URL(supabaseUrl);\n return parsed.hostname === '127.0.0.1' || parsed.hostname === 'localhost';\n } catch {\n return false;\n }\n}\n\nfunction isLocalMode(options?: SetupAuthOptions): boolean {\n if (options?.localDev !== undefined) return options.localDev;\n if (isTruthy(process.env.FORCEFIELD_LOCAL_DEV)) return true;\n return isLocalSupabaseUrl(getSupabaseUrl(options));\n}\n\nfunction getAnonKey(supabaseUrl: string, options?: SetupAuthOptions): string {\n const explicit = options?.anonKey ?? process.env.SUPABASE_ANON_KEY;\n if (explicit && explicit.trim().length > 0) return explicit;\n\n if (isLocalSupabaseUrl(supabaseUrl)) {\n return LOCAL_SUPABASE_ANON_KEY;\n }\n\n return PRODUCTION_SUPABASE_PUBLISHABLE_KEY;\n}\n\nfunction getServiceRoleKey(supabaseUrl: string): string | null {\n const explicit = process.env.SUPABASE_SERVICE_ROLE_KEY;\n if (explicit && explicit.trim().length > 0) return explicit;\n\n if (isLocalSupabaseUrl(supabaseUrl)) {\n return LOCAL_SUPABASE_SERVICE_ROLE_KEY;\n }\n\n return null;\n}\n\n/**\n * Validate API key format.\n */\nexport function validateApiKeyFormat(key: string): boolean {\n return key.startsWith(API_KEY_PREFIX) && key.length > API_KEY_PREFIX.length + 8;\n}\n\n/**\n * Verify an API key through key-exchange endpoint.\n */\nexport async function verifyApiKey(apiKey: string, options?: SetupAuthOptions): Promise<AuthResult> {\n if (!validateApiKeyFormat(apiKey)) {\n return {\n valid: false,\n apiKey: '',\n error: 'Invalid API key format. Keys must start with \"ff_live_\".',\n };\n }\n\n const supabaseUrl = getSupabaseUrl(options);\n const endpoint = `${supabaseUrl}/functions/v1/key-exchange`;\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n const payload = await response.json().catch(() => ({})) as { error?: string };\n const detail = payload.error ?? 'API key invalid or revoked.';\n return {\n valid: false,\n apiKey: '',\n error: `Authentication failed (${response.status}): ${detail}`,\n };\n }\n\n return { valid: true, apiKey };\n } catch {\n return {\n valid: false,\n apiKey: '',\n error: `Could not reach Forcefield backend at ${supabaseUrl}. Check SUPABASE_URL/network and retry.`,\n };\n }\n}\n\n/**\n * Authenticate with retries.\n */\nexport async function authenticateWithRetry(\n getKey: () => Promise<string | null>,\n options?: SetupAuthOptions,\n): Promise<AuthResult> {\n let lastError: string | undefined;\n\n for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n const key = await getKey();\n\n if (!key) {\n return { valid: false, apiKey: '', error: 'No API key provided.' };\n }\n\n const verified = await verifyApiKey(key, options);\n if (verified.valid) {\n return verified;\n }\n\n lastError = verified.error;\n\n if (attempt < MAX_RETRIES) {\n continue;\n }\n }\n\n return {\n valid: false,\n apiKey: '',\n error: lastError ?? `Authentication failed after ${MAX_RETRIES} attempts.`,\n };\n}\n\nfunction generateApiKey(): { plaintext: string; hash: string; prefix: string } {\n const raw = randomBytes(32).toString('hex');\n const plaintext = `${API_KEY_PREFIX}${raw}`;\n const hash = createHash('sha256').update(plaintext).digest('hex');\n const prefix = plaintext.slice(0, 12);\n return { plaintext, hash, prefix };\n}\n\n/**\n * Hosted/local account flow:\n * 1. Sign in (or sign up + sign in)\n * 2. Insert API key under authenticated user\n */\nexport async function authenticateAccountAndCreateApiKey(\n email: string,\n password: string,\n options?: {\n supabaseUrl?: string;\n anonKey?: string;\n label?: string;\n localDev?: boolean;\n },\n): Promise<LocalAuthResult> {\n const supabaseUrl = getSupabaseUrl(options);\n const anonKey = getAnonKey(supabaseUrl, options);\n\n const supabase = createClient(supabaseUrl, anonKey, {\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n let signIn = await supabase.auth.signInWithPassword({ email, password });\n\n if (signIn.error || !signIn.data.user) {\n await supabase.auth.signUp({ email, password });\n signIn = await supabase.auth.signInWithPassword({ email, password });\n }\n\n if (signIn.error || !signIn.data.user) {\n const message = signIn.error?.message ?? 'Invalid login credentials';\n if (/email.*not confirmed/i.test(message)) {\n throw new Error(\n 'Authentication failed: Email not confirmed. Confirm the inbox for this account, or disable email confirmation in Supabase Auth settings for beta.',\n );\n }\n throw new Error(`Authentication failed: ${message}`);\n }\n\n const userId = signIn.data.user.id;\n const { plaintext, hash, prefix } = generateApiKey();\n const { error: insertError } = await supabase\n .from('api_keys')\n .insert({\n user_id: userId,\n key_hash: hash,\n key_prefix: prefix,\n label: options?.label ?? 'Setup Wizard Key',\n tier: 'free',\n });\n\n if (insertError) {\n if (isLocalMode(options)) {\n const serviceRoleKey = getServiceRoleKey(supabaseUrl);\n if (serviceRoleKey) {\n return createApiKeyViaServiceRole({\n supabaseUrl,\n serviceRoleKey,\n email,\n password,\n label: options?.label ?? 'Setup Wizard Key',\n });\n }\n }\n\n throw new Error(`Failed to create API key: ${insertError.message}`);\n }\n\n return {\n apiKey: plaintext,\n userId,\n email,\n };\n}\n\n/**\n * Local auth flow preserved for scripted local development.\n */\nexport async function authenticateLocalAndCreateApiKey(\n email: string,\n password: string,\n options?: { supabaseUrl?: string; anonKey?: string; label?: string },\n): Promise<LocalAuthResult> {\n return authenticateAccountAndCreateApiKey(email, password, {\n ...options,\n localDev: true,\n label: options?.label ?? 'Local Setup Key',\n });\n}\n\nasync function createApiKeyViaServiceRole(params: {\n supabaseUrl: string;\n serviceRoleKey: string;\n email: string;\n password: string;\n label: string;\n}): Promise<LocalAuthResult> {\n const admin = createClient(params.supabaseUrl, params.serviceRoleKey, {\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n let userId: string | undefined;\n const createUser = await admin.auth.admin.createUser({\n email: params.email,\n password: params.password,\n email_confirm: true,\n });\n\n if (createUser.data.user?.id) {\n userId = createUser.data.user.id;\n } else if (createUser.error) {\n const authDb = createClient(params.supabaseUrl, params.serviceRoleKey, {\n db: { schema: 'auth' },\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n const existingUser = await authDb\n .from('users')\n .select('id,email')\n .eq('email', params.email)\n .limit(1)\n .maybeSingle();\n\n if (existingUser.error) {\n throw new Error(`Local login failed: ${createUser.error.message}`);\n }\n userId = existingUser.data?.id;\n }\n\n if (!userId) {\n throw new Error('Local login failed: could not resolve user account');\n }\n\n const { plaintext, hash, prefix } = generateApiKey();\n const { error: insertError } = await admin.from('api_keys').insert({\n user_id: userId,\n key_hash: hash,\n key_prefix: prefix,\n label: params.label,\n tier: 'free',\n });\n\n if (insertError) {\n throw new Error(`Failed to create local API key: ${insertError.message}`);\n }\n\n return {\n apiKey: plaintext,\n userId,\n email: params.email,\n };\n}\n\nexport { API_KEY_PREFIX, MAX_RETRIES };\n","/**\n * Forcefield Setup Wizard — entry point.\n *\n * This is the setup wizard binary (forcefield-setup), usually invoked via\n * `forcefield setup` (or `npx -y @forcefield/forcefield setup`).\n * Parses CLI arguments and launches the interactive wizard.\n */\n\nimport type { CliArgs, Ide, SetupMode } from './types.js';\nimport { runWizard } from './wizard.js';\nimport { pathToFileURL } from 'node:url';\n\nfunction parseArgs(argv: string[]): CliArgs {\n const args: CliArgs = {};\n\n for (let i = 2; i < argv.length; i++) {\n const arg = argv[i]!;\n\n if (arg === '--status') {\n args.status = true;\n } else if (arg === '--doctor') {\n args.doctor = true;\n } else if (arg === '--ide' && argv[i + 1]) {\n const ide = argv[++i]!;\n if (['claude-code', 'cursor', 'codex', 'windsurf'].includes(ide)) {\n args.ide = ide as Ide;\n }\n } else if (arg === '--mode' && argv[i + 1]) {\n const mode = argv[++i]!;\n if (['full', 'core'].includes(mode)) {\n args.mode = mode as SetupMode;\n }\n } else if (arg === '--token' && argv[i + 1]) {\n args.token = argv[++i]!;\n } else if (arg === '--email' && argv[i + 1]) {\n args.email = argv[++i]!;\n } else if (arg === '--password' && argv[i + 1]) {\n args.password = argv[++i]!;\n } else if (arg === '--local-auth') {\n args.localAuth = true;\n }\n }\n\n return args;\n}\n\nasync function main(): Promise<void> {\n const args = parseArgs(process.argv);\n const projectDir = process.cwd();\n\n try {\n await runWizard(projectDir, args);\n } catch (err) {\n console.error('Setup failed:', err instanceof Error ? err.message : err);\n process.exit(1);\n }\n}\n\nexport async function runSetupCli(argv: string[] = process.argv): Promise<void> {\n const originalArgv = process.argv;\n process.argv = argv;\n try {\n await main();\n } finally {\n process.argv = originalArgv;\n }\n}\n\nfunction isExecutedDirectly(metaUrl: string): boolean {\n const entryPath = process.argv[1];\n if (!entryPath) return false;\n return metaUrl === pathToFileURL(entryPath).href;\n}\n\nif (isExecutedDirectly(import.meta.url)) {\n void runSetupCli();\n}\n\nexport { parseArgs };\n"],"mappings":"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","names":["readFile","writeFile","access","join","dirname","fileURLToPath","join","access","join","join","mkdir","readdir","copyFile","rm","readFile","writeFile","join","join","mkdir","readFile","writeFile","readdir","copyFile","rm","mkdir","readFile","writeFile","join","join","mkdir","readFile","writeFile","readdir","mkdir","readFile","writeFile","join","START_MARKER","END_MARKER","join","mkdir","readFile","writeFile","readdir","removeSection","isTruthy","password","__dirname","dirname","fileURLToPath","join","access","text","readFile","apiKey","confirm","password","writeFile"]}