@mukulaggarwal/pacman 0.1.5 → 0.1.6
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.
- package/dist/{chunk-DNI6TIXZ.js → chunk-LKKDJ5A7.js} +3 -3
- package/dist/{chunk-WH3UMGHQ.js → chunk-S5ZLV5QT.js} +2 -2
- package/dist/{chunk-YJ32S56Q.js → chunk-X6CHTBN2.js} +5 -3
- package/dist/chunk-X6CHTBN2.js.map +1 -0
- package/dist/daemon.js +1 -1
- package/dist/{dist-WFQSK6BF.js → dist-6XSJ2XC4.js} +48 -7
- package/dist/dist-6XSJ2XC4.js.map +1 -0
- package/dist/{dist-RFHCRKM3.js → dist-GJFZVMLI.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp-compat.js +2 -2
- package/dist/onboarding-server.js +1684 -93
- package/dist/onboarding-server.js.map +1 -1
- package/dist/onboarding-web/assets/index-BwF9HPxA.css +1 -0
- package/dist/onboarding-web/assets/index-C0NQ8pNs.js +99 -0
- package/dist/onboarding-web/index.html +2 -2
- package/dist/slack-listener.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-YJ32S56Q.js.map +0 -1
- package/dist/dist-WFQSK6BF.js.map +0 -1
- package/dist/onboarding-web/assets/index-BOAOMlJT.css +0 -1
- package/dist/onboarding-web/assets/index-DBwmBIzA.js +0 -71
- /package/dist/{chunk-DNI6TIXZ.js.map → chunk-LKKDJ5A7.js.map} +0 -0
- /package/dist/{chunk-WH3UMGHQ.js.map → chunk-S5ZLV5QT.js.map} +0 -0
- /package/dist/{dist-RFHCRKM3.js.map → dist-GJFZVMLI.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/onboarding-server.ts","../../template-engine/dist/index.js","../src/project-structure.ts"],"sourcesContent":["import express from 'express';\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\nimport { createLocalStorage } from '@personal-assistant/storage-local';\nimport { createGDriveStorage } from '@personal-assistant/storage-gdrive';\nimport { createConfigManager } from '@personal-assistant/config-manager';\nimport { createContextManager } from '@personal-assistant/context-manager';\nimport {\n getTemplate,\n renderTemplate,\n listProfiles,\n getResponsibilities,\n} from '@personal-assistant/template-engine';\nimport { validateIntegrationConfig } from '@personal-assistant/integration-runtime';\nimport { createSlackConnector, validateSlackAppToken } from '@personal-assistant/integrations-slack';\nimport { createNoopEventClient } from '@personal-assistant/event-client';\nimport { WORKSPACE_PATHS } from '@personal-assistant/core-types';\nimport type {\n AppConfig,\n LlmProvider,\n ProfileType,\n UserProfile,\n StorageConfig,\n GDriveStorageConfig,\n IntegrationConfig,\n SyncConfig,\n} from '@personal-assistant/core-types';\nimport { validateProviderConfig } from './provider-runtime.js';\nimport { buildProjectStructurePreview } from './project-structure.js';\n\ninterface GDriveAuthSession {\n clientId: string;\n clientSecret: string;\n status: 'pending' | 'authenticated' | 'complete' | 'error';\n // set after OAuth callback\n accessToken?: string;\n refreshToken?: string;\n // set after folder creation\n folderId?: string;\n folderName?: string;\n folderPath?: string;\n error?: string;\n}\n\ntype FolderPickerPurpose = 'local-source' | 'storage';\n\ninterface FolderPickerRequest {\n defaultPath?: string;\n purpose?: FolderPickerPurpose;\n}\n\nconst PICKER_COPY: Record<FolderPickerPurpose, { prompt: string; title: string }> = {\n 'local-source': {\n prompt: 'Select a local project folder to tag in Pac-Man',\n title: 'Select project source folder',\n },\n storage: {\n prompt: 'Select the Pac-Man workspace folder',\n title: 'Select workspace folder',\n },\n};\n\nasync function resolvePickerStartPath(defaultPath?: string): Promise<string | undefined> {\n const trimmed = defaultPath?.trim();\n if (!trimmed) {\n return undefined;\n }\n\n const resolvedPath = path.resolve(trimmed);\n const candidates = [resolvedPath, path.dirname(resolvedPath)];\n\n for (const candidate of candidates) {\n try {\n const stats = await fs.stat(candidate);\n if (stats.isDirectory()) {\n return candidate;\n }\n } catch {\n // keep checking fallback candidates\n }\n }\n\n return undefined;\n}\n\nfunction escapeAppleScriptString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\nfunction escapePowerShellString(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\nfunction ensureTrailingSeparator(folderPath: string): string {\n return folderPath.endsWith(path.sep) ? folderPath : `${folderPath}${path.sep}`;\n}\n\nfunction isPickerCancelledError(err: unknown): boolean {\n const message = String(err).toLowerCase();\n return message.includes('user canceled') || message.includes('user cancelled') || message.includes('cancel');\n}\n\nasync function openNativeFolderPicker(\n platform: NodeJS.Platform,\n purpose: FolderPickerPurpose,\n startPath?: string,\n): Promise<string> {\n const copy = PICKER_COPY[purpose];\n\n if (platform === 'darwin') {\n const script = startPath\n ? `POSIX path of (choose folder with prompt \"${escapeAppleScriptString(copy.prompt)}\" default location POSIX file \"${escapeAppleScriptString(startPath)}\")`\n : `POSIX path of (choose folder with prompt \"${escapeAppleScriptString(copy.prompt)}\")`;\n const { stdout } = await execFileAsync('osascript', ['-e', script]);\n return stdout.trim();\n }\n\n if (platform === 'linux') {\n const args = ['--file-selection', '--directory', `--title=${copy.title}`];\n if (startPath) {\n args.push(`--filename=${ensureTrailingSeparator(startPath)}`);\n }\n const { stdout } = await execFileAsync('zenity', args);\n return stdout.trim();\n }\n\n if (platform === 'win32') {\n const script = [\n 'Add-Type -AssemblyName System.Windows.Forms',\n '$dialog = New-Object System.Windows.Forms.FolderBrowserDialog',\n `$dialog.Description = '${escapePowerShellString(copy.prompt)}'`,\n ...(startPath ? [`$dialog.SelectedPath = '${escapePowerShellString(startPath)}'`] : []),\n 'if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $dialog.SelectedPath }',\n ].join('; ');\n const { stdout } = await execFileAsync('powershell', ['-NoProfile', '-Command', script]);\n return stdout.trim();\n }\n\n throw new Error('Folder picker not supported on this platform');\n}\n\nexport async function startOnboardingServer(\n port: number,\n workspacePath: string,\n): Promise<void> {\n const app = express();\n app.use(express.json());\n\n let gdriveAuthSession: GDriveAuthSession | null = null;\n\n const onboardingStaticPath = await resolveOnboardingStaticPath();\n\n // Try to serve built static files; fallback to inline HTML\n if (onboardingStaticPath) {\n app.use(express.static(onboardingStaticPath));\n } else {\n // Serve inline onboarding page if the web app isn't built\n app.get('/', (_req, res) => {\n res.send(getInlineOnboardingHtml());\n });\n }\n\n // --- API Routes ---\n\n app.get('/api/profiles', (_req, res) => {\n const profiles = listProfiles();\n res.json({ profiles });\n });\n\n app.get('/api/responsibilities/:profileType', (req, res) => {\n try {\n const responsibilities = getResponsibilities(req.params.profileType as ProfileType);\n res.json({ responsibilities });\n } catch {\n res.status(400).json({ error: 'Invalid profile type' });\n }\n });\n\n app.get('/api/template/:profileType', (req, res) => {\n try {\n const template = getTemplate(req.params.profileType as ProfileType);\n res.json({ template });\n } catch {\n res.status(400).json({ error: 'Invalid profile type' });\n }\n });\n\n app.post('/api/preview-template', (req, res) => {\n const { profileType, name, assistantName, responsibilities } = req.body;\n try {\n const template = getTemplate(profileType);\n const files = renderTemplate(template, { name, assistantName, responsibilities });\n res.json({ files });\n } catch (err) {\n res.status(400).json({ error: String(err) });\n }\n });\n\n app.post('/api/project-structure-preview', async (req, res) => {\n const {\n profileType,\n name,\n assistantName,\n responsibilities,\n localFolders,\n integrations,\n } = req.body as {\n profileType: ProfileType;\n name: string;\n assistantName: string;\n responsibilities: string[];\n localFolders?: Array<{ path: string; project?: string }>;\n integrations?: string[];\n };\n\n try {\n const preview = await buildProjectStructurePreview({\n profileType,\n name,\n assistantName,\n responsibilities: responsibilities ?? [],\n localFolders: localFolders ?? [],\n integrations: integrations ?? [],\n });\n res.json(preview);\n } catch (err) {\n res.status(400).json({ error: String(err) });\n }\n });\n\n app.post('/api/save', async (req, res) => {\n try {\n const payload = req.body as AppConfig & {\n templateFiles?: Record<string, string>;\n inferredProjects?: Array<{ slug?: string; name?: string }>;\n };\n const config: AppConfig = payload;\n\n // Use the user-chosen local path if provided, otherwise fall back to CLI --dir\n const effectivePath =\n config.storage.mode === 'local' && (config.storage as { workspacePath?: string }).workspacePath\n ? path.resolve((config.storage as { workspacePath: string }).workspacePath)\n : workspacePath;\n\n // Ensure the local directory exists (needed for bootstrap even in GDrive mode)\n await fs.mkdir(effectivePath, { recursive: true });\n\n // Save a global pointer so CLI commands can find the workspace without --dir\n const rcPath = path.join(process.env.HOME ?? process.env.USERPROFILE ?? '~', '.personal-assistant-rc.json');\n await fs.writeFile(rcPath, JSON.stringify({ workspacePath: effectivePath }, null, 2), 'utf-8');\n\n // Always save storage.json locally for bootstrap (so MCP server knows which backend to use)\n const localStorage = createLocalStorage(effectivePath);\n const localConfigManager = createConfigManager(localStorage);\n await localConfigManager.saveConfig(config);\n\n // Resolve the user's chosen storage backend\n let targetStorage: import('@personal-assistant/core-types').StorageBackend = localStorage;\n if (config.storage.mode === 'gdrive') {\n const gdriveConfig = config.storage as GDriveStorageConfig;\n const resolvedCachePath = path.isAbsolute(gdriveConfig.cachePath)\n ? gdriveConfig.cachePath\n : path.resolve(path.dirname(effectivePath), gdriveConfig.cachePath);\n\n const gdriveStorage = createGDriveStorage({\n ...gdriveConfig,\n cachePath: resolvedCachePath,\n });\n await gdriveStorage.initialize();\n targetStorage = gdriveStorage;\n\n // Write config to GDrive so all reads go through GDrive\n const gdriveConfigManager = createConfigManager(gdriveStorage);\n await gdriveConfigManager.saveConfig(config);\n }\n\n const contextManager = createContextManager(targetStorage);\n\n // Initialize workspace structure on the target backend\n await contextManager.initWorkspace();\n\n // Render and write template files to the target backend\n const files =\n payload.templateFiles && Object.keys(payload.templateFiles).length > 0\n ? payload.templateFiles\n : renderTemplate(getTemplate(config.user.profileType), {\n name: config.user.name,\n assistantName: config.user.assistantName,\n responsibilities: config.user.responsibilities,\n });\n await contextManager.writeCanonicalFiles(files);\n\n if (payload.inferredProjects && payload.inferredProjects.length > 0) {\n await targetStorage.write(\n WORKSPACE_PATHS.context.derived.suggestions.inferredProjects,\n JSON.stringify(\n payload.inferredProjects.map((project, index) => ({\n name: project.slug ?? project.name ?? `project-${index + 1}`,\n score: Number((1 - index * 0.1).toFixed(2)),\n })),\n null,\n 2,\n ),\n );\n }\n\n // Emit onboarding completed event\n const eventClient = createNoopEventClient();\n await eventClient.emit('onboarding_completed', {\n profile: config.user.profileType,\n storage_mode: config.storage.mode,\n });\n\n res.json({ success: true, workspacePath: effectivePath });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // --- Integration credential validation ---\n\n app.post('/api/validate-integration', async (req, res) => {\n const { type, credentials } = req.body as {\n type: string;\n credentials: Record<string, string>;\n };\n\n try {\n const result = await validateIntegrationConfig({\n type: type as IntegrationConfig['type'],\n enabled: true,\n credentials,\n });\n\n if (result.ok) {\n res.json({ valid: true, info: result.summary ?? `Connected to ${type}` });\n return;\n }\n\n res.json({\n valid: false,\n error: [result.reason, ...(result.fix ?? [])].filter(Boolean).join(' '),\n });\n } catch (err) {\n res.json({ valid: false, error: String(err) });\n }\n });\n\n app.post('/api/validate-provider', async (req, res) => {\n const { provider, apiKey, model } = req.body as {\n provider: LlmProvider;\n apiKey: string;\n model?: string;\n };\n\n try {\n const result = await validateProviderConfig(provider, apiKey, model);\n res.json(result);\n } catch (err) {\n res.json({ valid: false, error: String(err) });\n }\n });\n\n app.post('/api/validate-slack-runtime', async (req, res) => {\n const {\n botToken,\n appToken,\n generationEnabled,\n providers,\n } = req.body as {\n botToken?: string;\n appToken?: string;\n generationEnabled?: boolean;\n providers?: {\n openai?: { apiKey?: string; model?: string };\n anthropic?: { apiKey?: string; model?: string };\n };\n };\n\n if (!botToken || !appToken) {\n res.json({ valid: false, error: 'Slack bot token and app token are required.' });\n return;\n }\n\n if (!botToken.startsWith('xoxb-')) {\n res.json({\n valid: false,\n error: 'Slack bot token must start with xoxb-. Paste the Bot User OAuth Token from OAuth & Permissions.',\n });\n return;\n }\n\n if (!appToken.startsWith('xapp-')) {\n res.json({\n valid: false,\n error: 'Slack Socket Mode app token must start with xapp-. Create an App-Level Token with connections:write under Socket Mode.',\n });\n return;\n }\n\n try {\n const connector = createSlackConnector();\n await connector.authenticate({\n type: 'slack',\n enabled: true,\n credentials: { botToken },\n });\n const health = await connector.healthCheck();\n await validateSlackAppToken(appToken);\n\n if (generationEnabled) {\n const providerEntries = [\n ['openai', providers?.openai],\n ['anthropic', providers?.anthropic],\n ] as const;\n\n const configuredProviders = providerEntries.filter(([, value]) => value?.apiKey);\n if (configuredProviders.length === 0) {\n res.json({ valid: false, error: 'Enable at least one provider when Slack generation is turned on.' });\n return;\n }\n\n for (const [provider, value] of configuredProviders) {\n const result = await validateProviderConfig(provider, value?.apiKey ?? '', value?.model);\n if (!result.valid) {\n res.json({ valid: false, error: result.error ?? `Failed to validate ${provider}` });\n return;\n }\n }\n }\n\n res.json({\n valid: true,\n info: `${health.summary ?? 'Slack connected'} via Socket Mode. Atlas will monitor channels where the bot is added.`,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes('not_allowed_token_type')) {\n res.json({\n valid: false,\n error: 'Slack rejected the Socket Mode token. Use an App-Level Token that starts with xapp- and has the connections:write scope.',\n });\n return;\n }\n\n res.json({\n valid: false,\n error: message,\n });\n }\n });\n\n // --- Local folder picker ---\n\n app.post('/api/pick-folder', async (req, res) => {\n const { defaultPath, purpose = 'storage' } = req.body as FolderPickerRequest;\n const pickerPurpose: FolderPickerPurpose = purpose === 'local-source' ? 'local-source' : 'storage';\n const requestStartedAt = Date.now();\n const startPath = await resolvePickerStartPath(defaultPath);\n\n console.info(\n `[onboarding] folder picker requested purpose=${pickerPurpose} start=${startPath ?? 'system-default'}`,\n );\n\n try {\n const folderPath = await openNativeFolderPicker(process.platform, pickerPurpose, startPath);\n\n if (!folderPath) {\n console.info(\n `[onboarding] folder picker returned no path after ${Date.now() - requestStartedAt}ms`,\n );\n res.json({ cancelled: true, durationMs: Date.now() - requestStartedAt });\n return;\n }\n\n console.info(\n `[onboarding] folder picker resolved in ${Date.now() - requestStartedAt}ms path=${folderPath}`,\n );\n res.json({ path: folderPath, durationMs: Date.now() - requestStartedAt });\n } catch (err) {\n if (isPickerCancelledError(err)) {\n console.info(\n `[onboarding] folder picker cancelled after ${Date.now() - requestStartedAt}ms`,\n );\n res.json({ cancelled: true, durationMs: Date.now() - requestStartedAt });\n return;\n }\n console.error('[onboarding] folder picker failed', err);\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - requestStartedAt,\n });\n }\n });\n\n // --- Google Drive OAuth routes ---\n\n app.post('/api/gdrive/auth-start', async (req, res) => {\n const { clientId, clientSecret } = req.body as { clientId?: string; clientSecret?: string };\n if (!clientId || !clientSecret) {\n res.status(400).json({ error: 'clientId and clientSecret are required' });\n return;\n }\n\n try {\n const { google } = await import('googleapis');\n const redirectUri = `http://localhost:${port}/api/gdrive/callback`;\n const oauth2Client = new google.auth.OAuth2(clientId, clientSecret, redirectUri);\n const authUrl = oauth2Client.generateAuthUrl({\n access_type: 'offline',\n prompt: 'consent',\n scope: ['https://www.googleapis.com/auth/drive.file'],\n });\n\n gdriveAuthSession = { clientId, clientSecret, status: 'pending' };\n res.json({ authUrl });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n app.get('/api/gdrive/callback', async (req, res) => {\n const { code } = req.query as { code?: string };\n\n if (!code || !gdriveAuthSession) {\n res.status(400).send('Invalid OAuth callback — no pending auth session.');\n return;\n }\n\n try {\n const { google } = await import('googleapis');\n const redirectUri = `http://localhost:${port}/api/gdrive/callback`;\n const oauth2Client = new google.auth.OAuth2(\n gdriveAuthSession.clientId,\n gdriveAuthSession.clientSecret,\n redirectUri,\n );\n\n const { tokens } = await oauth2Client.getToken(code);\n\n // Store tokens only — folder is created in a separate step\n gdriveAuthSession = {\n ...gdriveAuthSession,\n status: 'authenticated',\n refreshToken: tokens.refresh_token ?? undefined,\n accessToken: tokens.access_token ?? undefined,\n };\n\n res.send(`<!DOCTYPE html><html><body>\n <script>window.close();</script>\n <p style=\"font-family:sans-serif;padding:2rem;color:#4ade80;\">\n ✓ Authentication successful — you can close this tab and return to the setup.\n </p>\n </body></html>`);\n } catch (err) {\n if (gdriveAuthSession) {\n gdriveAuthSession.status = 'error';\n gdriveAuthSession.error = String(err);\n }\n res.status(500).send('Authentication failed: ' + String(err));\n }\n });\n\n app.get('/api/gdrive/auth-status', (_req, res) => {\n if (!gdriveAuthSession) {\n res.json({ status: 'idle' });\n return;\n }\n const { clientId: _cid, clientSecret: _csec, accessToken: _at, refreshToken: _rt, ...publicSession } = gdriveAuthSession;\n res.json(publicSession);\n });\n\n app.post('/api/gdrive/create-folder', async (req, res) => {\n if (!gdriveAuthSession || gdriveAuthSession.status !== 'authenticated') {\n res.status(400).json({ error: 'Not authenticated. Please connect Google Drive first.' });\n return;\n }\n\n const { folderName = 'Personal Assistant', parentFolderName = '' } =\n req.body as { folderName?: string; parentFolderName?: string };\n\n try {\n const { google } = await import('googleapis');\n const redirectUri = `http://localhost:${port}/api/gdrive/callback`;\n const oauth2Client = new google.auth.OAuth2(\n gdriveAuthSession.clientId,\n gdriveAuthSession.clientSecret,\n redirectUri,\n );\n oauth2Client.setCredentials({\n access_token: gdriveAuthSession.accessToken,\n refresh_token: gdriveAuthSession.refreshToken,\n });\n\n const drive = google.drive({ version: 'v3', auth: oauth2Client });\n\n // Resolve parent folder\n let parentId = 'root';\n let locationPath = 'My Drive';\n\n if (parentFolderName.trim()) {\n const searchRes = await drive.files.list({\n q: `name='${parentFolderName.trim()}' and mimeType='application/vnd.google-apps.folder' and trashed=false`,\n fields: 'files(id,name)',\n spaces: 'drive',\n });\n\n if (searchRes.data.files && searchRes.data.files.length > 0) {\n parentId = searchRes.data.files[0].id!;\n } else {\n // Create the parent folder at root\n const parentRes = await drive.files.create({\n requestBody: {\n name: parentFolderName.trim(),\n mimeType: 'application/vnd.google-apps.folder',\n },\n fields: 'id',\n });\n parentId = parentRes.data.id!;\n }\n locationPath = `My Drive / ${parentFolderName.trim()}`;\n }\n\n // Check if the main folder already exists under the parent before creating\n let folderId: string | undefined;\n let resolvedFolderName = folderName.trim();\n const existingSearch = await drive.files.list({\n q: `name='${resolvedFolderName}' and '${parentId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,\n fields: 'files(id,name)',\n spaces: 'drive',\n });\n\n if (existingSearch.data.files && existingSearch.data.files.length > 0) {\n folderId = existingSearch.data.files[0].id!;\n resolvedFolderName = existingSearch.data.files[0].name!;\n } else {\n const folderRes = await drive.files.create({\n requestBody: {\n name: resolvedFolderName,\n mimeType: 'application/vnd.google-apps.folder',\n parents: [parentId],\n },\n fields: 'id,name',\n });\n folderId = folderRes.data.id!;\n resolvedFolderName = folderRes.data.name!;\n }\n\n const folderPath = `${locationPath} / ${resolvedFolderName}`;\n\n // Refresh tokens in case they were rotated\n const freshCredentials = await oauth2Client.getAccessToken();\n const latestRefreshToken =\n (oauth2Client.credentials.refresh_token as string | undefined) ??\n gdriveAuthSession.refreshToken;\n\n gdriveAuthSession = {\n ...gdriveAuthSession,\n status: 'complete',\n folderId: folderId!,\n folderName: resolvedFolderName,\n folderPath,\n refreshToken: latestRefreshToken,\n accessToken: freshCredentials.token ?? undefined,\n };\n\n res.json({\n folderId,\n folderName: resolvedFolderName,\n folderPath,\n refreshToken: latestRefreshToken,\n });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n app.get('/api/status', async (_req, res) => {\n const storage = createLocalStorage(workspacePath);\n const configManager = createConfigManager(storage);\n try {\n const config = await configManager.loadConfig();\n res.json({ configured: true, config });\n } catch {\n res.json({ configured: false });\n }\n });\n\n // Start server\n const server = app.listen(port, () => {\n const url = `http://localhost:${port}`;\n console.log(`Onboarding server running at ${url}`);\n\n // Try to open browser\n import('open')\n .then((openModule) => openModule.default(url))\n .catch(() => {\n console.log(`Open ${url} in your browser to continue.`);\n });\n });\n\n // Handle graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\nShutting down onboarding server...');\n server.close();\n process.exit(0);\n });\n}\n\nasync function resolveOnboardingStaticPath(): Promise<string | null> {\n const baseDir = import.meta.dirname ?? __dirname;\n const candidates = [\n path.resolve(baseDir, './onboarding-web'),\n path.resolve(baseDir, '../../../apps/onboarding-web/dist'),\n ];\n\n for (const candidate of candidates) {\n try {\n await fs.access(path.join(candidate, 'index.html'));\n return candidate;\n } catch {\n // keep looking\n }\n }\n\n return null;\n}\n\nfunction getInlineOnboardingHtml(): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Personal Assistant - Setup</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #0f172a; color: #e2e8f0; min-height: 100vh; }\n .container { max-width: 640px; margin: 0 auto; padding: 2rem; }\n h1 { font-size: 1.8rem; margin-bottom: 0.5rem; color: #f8fafc; }\n h2 { font-size: 1.2rem; margin-bottom: 1rem; color: #94a3b8; font-weight: 400; }\n .step { display: none; }\n .step.active { display: block; }\n .progress { display: flex; gap: 0.5rem; margin-bottom: 2rem; }\n .progress-dot { width: 2rem; height: 0.25rem; background: #334155; border-radius: 2px; transition: background 0.3s; }\n .progress-dot.done { background: #3b82f6; }\n .progress-dot.current { background: #60a5fa; }\n label { display: block; margin-bottom: 0.5rem; color: #cbd5e1; font-size: 0.9rem; }\n input, select, textarea { width: 100%; padding: 0.75rem; background: #1e293b; border: 1px solid #334155; border-radius: 0.5rem; color: #f8fafc; font-size: 1rem; margin-bottom: 1rem; }\n input:focus, select:focus, textarea:focus { outline: none; border-color: #3b82f6; }\n textarea { min-height: 200px; font-family: 'SF Mono', 'Fira Code', monospace; font-size: 0.85rem; }\n button { padding: 0.75rem 1.5rem; border: none; border-radius: 0.5rem; font-size: 1rem; cursor: pointer; transition: all 0.2s; }\n .btn-primary { background: #3b82f6; color: white; }\n .btn-primary:hover { background: #2563eb; }\n .btn-secondary { background: #334155; color: #e2e8f0; }\n .btn-secondary:hover { background: #475569; }\n .btn-group { display: flex; gap: 0.75rem; margin-top: 1.5rem; }\n .checkbox-group { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; margin-bottom: 1rem; }\n .checkbox-item { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem; background: #1e293b; border: 1px solid #334155; border-radius: 0.375rem; cursor: pointer; }\n .checkbox-item:hover { border-color: #475569; }\n .checkbox-item input[type=\"checkbox\"] { width: auto; margin: 0; }\n .radio-group { display: flex; gap: 1rem; margin-bottom: 1rem; }\n .radio-item { flex: 1; padding: 1rem; background: #1e293b; border: 2px solid #334155; border-radius: 0.5rem; cursor: pointer; text-align: center; transition: all 0.2s; }\n .radio-item:hover { border-color: #475569; }\n .radio-item.selected { border-color: #3b82f6; background: #1e3a5f; }\n .success { text-align: center; padding: 3rem 0; }\n .success h2 { color: #4ade80; font-size: 1.5rem; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"progress\" id=\"progress\"></div>\n\n <!-- Step 1: Identity -->\n <div class=\"step active\" data-step=\"0\">\n <h1>Welcome</h1>\n <h2>Let's set up your personal assistant</h2>\n <label>Your Name</label>\n <input type=\"text\" id=\"userName\" placeholder=\"Jane Smith\">\n <label>Assistant Name</label>\n <input type=\"text\" id=\"assistantName\" placeholder=\"Atlas\" value=\"Atlas\">\n <label>Profile</label>\n <select id=\"profileType\">\n <option value=\"software-engineer\">Software Engineer</option>\n <option value=\"product-manager\">Product Manager</option>\n <option value=\"engineering-manager\">Engineering Manager</option>\n <option value=\"devops\">DevOps Engineer</option>\n </select>\n <div class=\"btn-group\"><button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button></div>\n </div>\n\n <!-- Step 2: Responsibilities -->\n <div class=\"step\" data-step=\"1\">\n <h1>Responsibilities</h1>\n <h2>Select your core responsibilities</h2>\n <div class=\"checkbox-group\" id=\"responsibilitiesGroup\"></div>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button>\n </div>\n </div>\n\n <!-- Step 3: Template Preview -->\n <div class=\"step\" data-step=\"2\">\n <h1>Context Template</h1>\n <h2>Preview and customize your context template</h2>\n <textarea id=\"templatePreview\"></textarea>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button>\n </div>\n </div>\n\n <!-- Step 4: Storage -->\n <div class=\"step\" data-step=\"3\">\n <h1>Storage</h1>\n <h2>Where should your context be stored?</h2>\n <div class=\"radio-group\">\n <div class=\"radio-item selected\" onclick=\"selectStorage('local')\" id=\"storage-local\">\n <strong>Local Workspace</strong><br><small>Files stored on this machine</small>\n </div>\n <div class=\"radio-item\" onclick=\"selectStorage('gdrive')\" id=\"storage-gdrive\">\n <strong>Google Drive</strong><br><small>Files stored in your Drive folder</small>\n </div>\n </div>\n <div id=\"storage-local-fields\">\n <label>Storage path</label>\n <div style=\"display:flex;gap:0.5rem;align-items:center;\">\n <input type=\"text\" id=\"localPath\" value=\".personal-assistant\" placeholder=\".personal-assistant\" style=\"flex:1;margin-bottom:0;\">\n <button class=\"btn-secondary\" onclick=\"browseFolder()\" id=\"browseBtn\" style=\"white-space:nowrap;flex-shrink:0;\">Browse</button>\n </div>\n <small style=\"color:#64748b;font-size:0.8rem;display:block;margin-top:0.4rem;margin-bottom:1rem;\">Click Browse to open a folder picker, or type a path directly.</small>\n </div>\n <div id=\"storage-gdrive-fields\" style=\"display:none;\">\n <p style=\"color:#f59e0b;font-size:0.85rem;margin-bottom:1rem;\">\n Google Drive OAuth is only supported in the full onboarding UI.<br>\n Run <code>pnpm build</code> in <code>apps/onboarding-web</code> then restart <code>pacman init</code>.\n </p>\n </div>\n <div style=\"background:#1c1917;border:1px solid #92400e;border-radius:0.5rem;padding:0.75rem 1rem;margin-bottom:1.5rem;font-size:0.85rem;color:#fbbf24;\">\n ⚠️ Do not delete, move, or rename the folder structure created by this setup. Claude and the sync daemon rely on the exact file layout to load and update your context.\n </div>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button>\n </div>\n </div>\n\n <!-- Step 5: Integrations -->\n <div class=\"step\" data-step=\"4\">\n <h1>Integrations</h1>\n <h2>Connect your tools (optional)</h2>\n <div class=\"checkbox-group\" id=\"integrationsGroup\">\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"slack\"> Slack</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"gmail\"> Gmail</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"github\"> GitHub</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"gitlab\"> GitLab</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"gdrive\"> Google Drive Docs</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"gchat\"> Google Chat</label>\n </div>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button>\n </div>\n </div>\n\n <!-- Step 6: Sync Schedule -->\n <div class=\"step\" data-step=\"5\">\n <h1>Sync Schedule</h1>\n <h2>When should context be refreshed?</h2>\n <label>Daily Sync Time</label>\n <input type=\"time\" id=\"syncTime\" value=\"08:00\">\n <label>Timezone</label>\n <select id=\"timezone\">\n <option value=\"America/New_York\">Eastern Time (ET)</option>\n <option value=\"America/Chicago\">Central Time (CT)</option>\n <option value=\"America/Denver\">Mountain Time (MT)</option>\n <option value=\"America/Los_Angeles\">Pacific Time (PT)</option>\n <option value=\"UTC\">UTC</option>\n <option value=\"Europe/London\">London (GMT/BST)</option>\n <option value=\"Europe/Berlin\">Berlin (CET)</option>\n <option value=\"Asia/Tokyo\">Tokyo (JST)</option>\n <option value=\"Asia/Kolkata\">India (IST)</option>\n <option value=\"Australia/Sydney\">Sydney (AEST)</option>\n </select>\n <div class=\"checkbox-group\">\n <label class=\"checkbox-item\"><input type=\"checkbox\" id=\"manualSync\" checked> Manual sync</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" id=\"asyncUpdate\" checked> Async updates</label>\n </div>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button>\n </div>\n </div>\n\n <!-- Step 7: Finish -->\n <div class=\"step\" data-step=\"6\">\n <h1>All Set!</h1>\n <h2>Review and save your configuration</h2>\n <div id=\"summary\" style=\"background:#1e293b;padding:1rem;border-radius:0.5rem;margin-bottom:1rem;font-family:monospace;font-size:0.85rem;white-space:pre-wrap;\"></div>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"saveConfig()\">Save & Finish</button>\n </div>\n </div>\n\n <!-- Success -->\n <div class=\"step\" data-step=\"7\">\n <div class=\"success\">\n <h2>Setup Complete!</h2>\n <p style=\"margin-top:1rem;color:#94a3b8;\">Your personal assistant context has been initialized.</p>\n <p style=\"margin-top:1rem;color:#94a3b8;\">Next steps:</p>\n <pre style=\"text-align:left;margin-top:1rem;background:#1e293b;padding:1rem;border-radius:0.5rem;font-size:0.85rem;\">\n# Install Claude Code integration\npacman claude install\npacman mcp claude install\n\n# Install Codex integration\npacman codex install\npacman mcp codex install\n\n# Start the sync daemon\npacman daemon\n\n# Start the real-time Slack listener\npacman slack listen\n\n# Use in Claude Code\n/pacman start <project>\n\n# Use in Codex\nAsk Codex to load or refresh your Pac-Man context for <project></pre>\n <p style=\"margin-top:1rem;color:#64748b;font-size:0.85rem;\">Restart Claude Code or Codex after installing the MCP server.<br>If <code style=\"background:#1e293b;padding:0 4px;border-radius:3px;\">pacman</code> is not found, link it first:<br>\n <code style=\"background:#1e293b;padding:2px 6px;border-radius:3px;\">pnpm setup && source ~/.zshrc && cd packages/cli && pnpm link --global</code></p>\n </div>\n </div>\n </div>\n\n <script>\n let currentStep = 0;\n const totalSteps = 7;\n let state = { storageMode: 'local', responsibilities: [] };\n\n function updateProgress() {\n const bar = document.getElementById('progress');\n bar.innerHTML = '';\n for (let i = 0; i < totalSteps; i++) {\n const dot = document.createElement('div');\n dot.className = 'progress-dot' + (i < currentStep ? ' done' : i === currentStep ? ' current' : '');\n bar.appendChild(dot);\n }\n }\n\n function showStep(n) {\n document.querySelectorAll('.step').forEach(s => s.classList.remove('active'));\n document.querySelector('[data-step=\"' + n + '\"]').classList.add('active');\n currentStep = n;\n updateProgress();\n }\n\n async function nextStep() {\n if (currentStep === 0) await loadResponsibilities();\n if (currentStep === 1) await loadTemplatePreview();\n if (currentStep === 5) updateSummary();\n showStep(currentStep + 1);\n }\n\n function prevStep() { showStep(currentStep - 1); }\n\n async function loadResponsibilities() {\n const profileType = document.getElementById('profileType').value;\n const res = await fetch('/api/responsibilities/' + profileType);\n const data = await res.json();\n const group = document.getElementById('responsibilitiesGroup');\n group.innerHTML = data.responsibilities.map(r =>\n '<label class=\"checkbox-item\"><input type=\"checkbox\" value=\"' + r + '\" checked> ' + r + '</label>'\n ).join('');\n }\n\n async function loadTemplatePreview() {\n const profileType = document.getElementById('profileType').value;\n const name = document.getElementById('userName').value;\n const assistantName = document.getElementById('assistantName').value;\n const responsibilities = Array.from(document.querySelectorAll('#responsibilitiesGroup input:checked')).map(c => c.value);\n state.responsibilities = responsibilities;\n\n const res = await fetch('/api/preview-template', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ profileType, name, assistantName, responsibilities })\n });\n const data = await res.json();\n const preview = Object.entries(data.files).map(([f, c]) => '--- ' + f + ' ---\\\\n' + c).join('\\\\n\\\\n');\n document.getElementById('templatePreview').value = preview;\n }\n\n function selectStorage(mode) {\n state.storageMode = mode;\n document.querySelectorAll('.radio-item').forEach(r => r.classList.remove('selected'));\n document.getElementById('storage-' + mode).classList.add('selected');\n document.getElementById('storage-local-fields').style.display = mode === 'local' ? 'block' : 'none';\n document.getElementById('storage-gdrive-fields').style.display = mode === 'gdrive' ? 'block' : 'none';\n }\n\n async function browseFolder() {\n const btn = document.getElementById('browseBtn');\n btn.textContent = 'Opening...';\n btn.disabled = true;\n try {\n const res = await fetch('/api/pick-folder', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n defaultPath: document.getElementById('localPath').value,\n purpose: 'storage'\n })\n });\n const data = await res.json();\n if (!data.cancelled && data.path) {\n document.getElementById('localPath').value = data.path;\n }\n } catch (e) {\n // ignore — user can type path manually\n } finally {\n btn.textContent = 'Browse';\n btn.disabled = false;\n }\n }\n\n function updateSummary() {\n const config = buildConfig();\n document.getElementById('summary').textContent = JSON.stringify(config, null, 2);\n }\n\n function buildConfig() {\n const integrations = Array.from(document.querySelectorAll('#integrationsGroup input:checked')).map(c => ({\n type: c.value, enabled: true, credentials: {}, cursor: null, lastSyncAt: null\n }));\n\n return {\n user: {\n name: document.getElementById('userName').value,\n assistantName: document.getElementById('assistantName').value,\n profileType: document.getElementById('profileType').value,\n responsibilities: state.responsibilities\n },\n storage: state.storageMode === 'local'\n ? { mode: 'local', workspacePath: document.getElementById('localPath').value || '.personal-assistant' }\n : { mode: 'gdrive', folderId: '', folderName: 'Personal Assistant', cachePath: '.personal-assistant/cache' },\n integrations,\n sync: {\n dailySyncTime: document.getElementById('syncTime').value,\n timezone: document.getElementById('timezone').value,\n manualSyncEnabled: document.getElementById('manualSync').checked,\n asyncUpdateEnabled: document.getElementById('asyncUpdate').checked\n }\n };\n }\n\n async function saveConfig() {\n const config = buildConfig();\n const res = await fetch('/api/save', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(config)\n });\n const data = await res.json();\n if (data.success) showStep(7);\n else alert('Error: ' + data.error);\n }\n\n updateProgress();\n </script>\n</body>\n</html>`;\n}\n","// src/index.ts\nvar PROFILE_TEMPLATES = {\n \"software-engineer\": {\n profileType: \"software-engineer\",\n name: \"Software Engineer\",\n description: \"Context template for software engineers\",\n responsibilities: [\n \"Code review and PR management\",\n \"Feature development\",\n \"Bug fixing and debugging\",\n \"Architecture decisions\",\n \"Technical documentation\",\n \"On-call and incident response\",\n \"Mentoring junior engineers\",\n \"Sprint planning and estimation\",\n \"CI/CD pipeline maintenance\",\n \"API design and development\"\n ],\n sections: [\n {\n name: \"Overview\",\n fileName: \"overview.md\",\n required: true,\n defaultContent: `# Overview\n\n## Role\nSoftware Engineer\n\n## Team\n<!-- Your team name -->\n\n## Primary Focus\n<!-- Main area of work -->\n\n## Key Repositories\n<!-- List your main repos -->\n\n## Tech Stack\n<!-- Languages, frameworks, tools -->\n`\n },\n {\n name: \"Responsibilities\",\n fileName: \"responsibilities.md\",\n required: true,\n defaultContent: `# Responsibilities\n\n## Core Duties\n<!-- Your primary responsibilities -->\n\n## On-Call\n<!-- On-call schedule and escalation paths -->\n\n## Code Review\n<!-- Review expectations and areas -->\n`\n },\n {\n name: \"Stakeholders\",\n fileName: \"stakeholders.md\",\n required: false,\n defaultContent: `# Stakeholders\n\n## Direct Manager\n<!-- Name, role -->\n\n## Team Members\n<!-- Key teammates -->\n\n## Cross-Team Contacts\n<!-- People you work with in other teams -->\n\n## Escalation Path\n<!-- Who to escalate to and when -->\n`\n },\n {\n name: \"Documentation\",\n fileName: \"docs.md\",\n required: false,\n defaultContent: `# Documentation References\n\n## Internal Docs\n<!-- Links to internal documentation -->\n\n## Runbooks\n<!-- Links to runbooks -->\n\n## Architecture Docs\n<!-- Links to architecture documents -->\n`\n }\n ]\n },\n \"product-manager\": {\n profileType: \"product-manager\",\n name: \"Product Manager\",\n description: \"Context template for product managers\",\n responsibilities: [\n \"Product roadmap management\",\n \"Feature prioritization\",\n \"Stakeholder communication\",\n \"User research and interviews\",\n \"Metrics and KPI tracking\",\n \"Sprint planning and grooming\",\n \"Go-to-market strategy\",\n \"Competitive analysis\",\n \"Cross-team coordination\",\n \"Product requirements documentation\"\n ],\n sections: [\n {\n name: \"Overview\",\n fileName: \"overview.md\",\n required: true,\n defaultContent: `# Overview\n\n## Role\nProduct Manager\n\n## Product Area\n<!-- Your product area -->\n\n## Key Metrics\n<!-- North star and supporting metrics -->\n\n## Current Quarter Goals\n<!-- OKRs or key goals -->\n`\n },\n {\n name: \"Responsibilities\",\n fileName: \"responsibilities.md\",\n required: true,\n defaultContent: `# Responsibilities\n\n## Product Areas\n<!-- Products/features you own -->\n\n## Decision Authority\n<!-- What you can decide vs. escalate -->\n\n## Regular Meetings\n<!-- Recurring meetings and cadences -->\n`\n },\n {\n name: \"Stakeholders\",\n fileName: \"stakeholders.md\",\n required: false,\n defaultContent: `# Stakeholders\n\n## Engineering Leads\n<!-- Engineering partners -->\n\n## Design Partners\n<!-- Design team contacts -->\n\n## Business Stakeholders\n<!-- Sales, marketing, exec sponsors -->\n\n## Customers\n<!-- Key customer contacts or segments -->\n`\n },\n {\n name: \"Documentation\",\n fileName: \"docs.md\",\n required: false,\n defaultContent: `# Documentation References\n\n## PRDs\n<!-- Product requirement documents -->\n\n## Roadmap\n<!-- Roadmap links -->\n\n## Analytics Dashboards\n<!-- Links to dashboards -->\n`\n }\n ]\n },\n \"engineering-manager\": {\n profileType: \"engineering-manager\",\n name: \"Engineering Manager\",\n description: \"Context template for engineering managers\",\n responsibilities: [\n \"Team management and 1:1s\",\n \"Hiring and interviewing\",\n \"Performance reviews\",\n \"Technical strategy\",\n \"Cross-team coordination\",\n \"Sprint planning and velocity\",\n \"Incident management\",\n \"Budget and resource planning\",\n \"Career development coaching\",\n \"Process improvement\"\n ],\n sections: [\n {\n name: \"Overview\",\n fileName: \"overview.md\",\n required: true,\n defaultContent: `# Overview\n\n## Role\nEngineering Manager\n\n## Team\n<!-- Team name and size -->\n\n## Charter\n<!-- Team charter / mission -->\n\n## Key Systems\n<!-- Systems your team owns -->\n`\n },\n {\n name: \"Responsibilities\",\n fileName: \"responsibilities.md\",\n required: true,\n defaultContent: `# Responsibilities\n\n## People Management\n<!-- Direct reports, 1:1 cadence -->\n\n## Technical Oversight\n<!-- Architecture, code quality, tech debt -->\n\n## Process\n<!-- Agile ceremonies, team rituals -->\n\n## Hiring\n<!-- Open roles, pipeline -->\n`\n },\n {\n name: \"Stakeholders\",\n fileName: \"stakeholders.md\",\n required: false,\n defaultContent: `# Stakeholders\n\n## Direct Reports\n<!-- Team members -->\n\n## Skip Level\n<!-- Your manager -->\n\n## Product Partners\n<!-- PMs you work with -->\n\n## Peer Managers\n<!-- Other EMs -->\n`\n },\n {\n name: \"Documentation\",\n fileName: \"docs.md\",\n required: false,\n defaultContent: `# Documentation References\n\n## Team Docs\n<!-- Team wiki, confluence pages -->\n\n## Process Docs\n<!-- Runbooks, playbooks -->\n\n## HR Resources\n<!-- Performance review templates, etc. -->\n`\n }\n ]\n },\n devops: {\n profileType: \"devops\",\n name: \"DevOps Engineer\",\n description: \"Context template for DevOps engineers\",\n responsibilities: [\n \"CI/CD pipeline management\",\n \"Infrastructure as code\",\n \"Monitoring and alerting\",\n \"Incident response\",\n \"Security compliance\",\n \"Cost optimization\",\n \"Deployment automation\",\n \"Container orchestration\",\n \"Database management\",\n \"Disaster recovery planning\"\n ],\n sections: [\n {\n name: \"Overview\",\n fileName: \"overview.md\",\n required: true,\n defaultContent: `# Overview\n\n## Role\nDevOps Engineer\n\n## Infrastructure\n<!-- Cloud provider, key services -->\n\n## Key Environments\n<!-- Production, staging, dev -->\n\n## Monitoring Stack\n<!-- Tools and dashboards -->\n`\n },\n {\n name: \"Responsibilities\",\n fileName: \"responsibilities.md\",\n required: true,\n defaultContent: `# Responsibilities\n\n## Infrastructure\n<!-- IaC, cloud resources -->\n\n## CI/CD\n<!-- Pipelines, deployment processes -->\n\n## On-Call\n<!-- PagerDuty, escalation paths -->\n\n## Security\n<!-- Compliance, access management -->\n`\n },\n {\n name: \"Stakeholders\",\n fileName: \"stakeholders.md\",\n required: false,\n defaultContent: `# Stakeholders\n\n## Platform Team\n<!-- Team members -->\n\n## Engineering Teams\n<!-- Teams you support -->\n\n## Security Team\n<!-- Security contacts -->\n\n## Vendor Contacts\n<!-- Cloud, tooling vendors -->\n`\n },\n {\n name: \"Documentation\",\n fileName: \"docs.md\",\n required: false,\n defaultContent: `# Documentation References\n\n## Runbooks\n<!-- Incident response runbooks -->\n\n## Architecture Diagrams\n<!-- Infrastructure diagrams -->\n\n## Compliance Docs\n<!-- SOC2, security policies -->\n`\n }\n ]\n }\n};\nfunction getTemplate(profileType) {\n const template = PROFILE_TEMPLATES[profileType];\n if (!template) {\n throw new Error(`Unknown profile type: ${profileType}`);\n }\n return { ...template };\n}\nfunction listProfiles() {\n return Object.keys(PROFILE_TEMPLATES);\n}\nfunction getResponsibilities(profileType) {\n const template = PROFILE_TEMPLATES[profileType];\n if (!template) {\n throw new Error(`Unknown profile type: ${profileType}`);\n }\n return [...template.responsibilities];\n}\nfunction renderTemplate(template, user) {\n const files = {};\n for (const section of template.sections) {\n let content = section.defaultContent;\n content = content.replace(\"<!-- Your team name -->\", `${user.name}'s team`);\n if (section.fileName === \"responsibilities.md\" && user.responsibilities.length > 0) {\n content += \"\\n## Selected Responsibilities\\n\";\n for (const r of user.responsibilities) {\n content += `- ${r}\n`;\n }\n }\n files[section.fileName] = content;\n }\n return files;\n}\nfunction getTemplateSections(profileType) {\n const template = PROFILE_TEMPLATES[profileType];\n if (!template) {\n throw new Error(`Unknown profile type: ${profileType}`);\n }\n return template.sections.map((s) => ({ ...s }));\n}\nexport {\n getResponsibilities,\n getTemplate,\n getTemplateSections,\n listProfiles,\n renderTemplate\n};\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { ProfileType } from '@personal-assistant/core-types';\nimport { getTemplate, renderTemplate } from '@personal-assistant/template-engine';\n\nconst MAX_DIR_ENTRIES = 10;\nconst README_CANDIDATES = ['README.md', 'readme.md', 'README.txt', 'readme.txt'];\nconst OLLAMA_BASE_URL = 'http://127.0.0.1:11434';\n\nexport interface LocalFolderInput {\n path: string;\n project?: string;\n}\n\nexport interface InferredProject {\n slug: string;\n name: string;\n summary: string;\n primaryFocus: string;\n sourceFolders: string[];\n connectedIntegrations: string[];\n keySignals: string[];\n}\n\nexport interface ProjectInferenceMeta {\n strategy: 'ollama' | 'heuristic';\n model?: string;\n note: string;\n}\n\nexport interface ProjectStructurePreview {\n files: Record<string, string>;\n projects: InferredProject[];\n inference: ProjectInferenceMeta;\n}\n\ninterface FolderSignal {\n path: string;\n explicitProject?: string;\n basename: string;\n packageName?: string;\n readmeHeading?: string;\n entries: string[];\n notes: string[];\n}\n\nexport async function buildProjectStructurePreview(input: {\n profileType: ProfileType;\n name: string;\n assistantName: string;\n responsibilities: string[];\n localFolders: LocalFolderInput[];\n integrations: string[];\n}): Promise<ProjectStructurePreview> {\n const baseFiles = renderTemplate(getTemplate(input.profileType), {\n name: input.name,\n assistantName: input.assistantName,\n responsibilities: input.responsibilities,\n });\n\n const folderSignals = await Promise.all(\n input.localFolders\n .filter((folder) => folder.path.trim())\n .map((folder) => collectFolderSignal(folder)),\n );\n\n const heuristicProjects = buildHeuristicProjects(folderSignals, input.integrations);\n const ollamaResult = await enrichProjectsWithOllama(\n heuristicProjects,\n folderSignals,\n input.integrations,\n );\n\n const projects = ollamaResult?.projects ?? heuristicProjects;\n const inference =\n ollamaResult?.inference ?? {\n strategy: 'heuristic' as const,\n note:\n 'Structured locally from folder tags, folder names, and visible directory signals. No external API calls were made.',\n };\n\n return {\n files: buildTemplateFiles(baseFiles, projects, folderSignals, input.integrations),\n projects,\n inference,\n };\n}\n\nfunction buildTemplateFiles(\n baseFiles: Record<string, string>,\n projects: InferredProject[],\n folderSignals: FolderSignal[],\n integrations: string[],\n): Record<string, string> {\n const files = { ...baseFiles };\n const integrationNames = integrations.map(formatIntegrationName);\n\n files['overview.md'] = [\n baseFiles['overview.md'] ?? '# Overview',\n '',\n '## Confirmed Project Structure',\n '',\n projects.length > 0\n ? projects\n .map((project) => `- **${project.name}** — ${project.primaryFocus || project.summary}`)\n .join('\\n')\n : '- No project groups were inferred yet. Add local folders or integrations and revisit this step.',\n ].join('\\n');\n\n const sourceLines: string[] = [];\n if (folderSignals.length > 0) {\n sourceLines.push('## Local Sources', '');\n sourceLines.push(...folderSignals.map((signal) => `- \\`${signal.path}\\``));\n sourceLines.push('');\n }\n if (integrationNames.length > 0) {\n sourceLines.push('## Connected Integrations', '');\n sourceLines.push(...integrationNames.map((name) => `- ${name}`));\n sourceLines.push('');\n }\n if (sourceLines.length > 0) {\n files['docs.md'] = [baseFiles['docs.md'] ?? '# Documentation References', '', ...sourceLines].join(\n '\\n',\n );\n }\n\n if (integrationNames.length > 0) {\n files['integrations.md'] = [\n '# Connected Integrations',\n '',\n ...integrationNames.map((name) => `- ${name}`),\n '',\n '## Notes',\n '',\n 'These integrations are workspace-level sources. Confirm project-specific mappings after the first sync.',\n '',\n ].join('\\n');\n }\n\n for (const project of projects) {\n files[`projects/${project.slug}.md`] = buildProjectFile(project);\n }\n\n return files;\n}\n\nfunction buildProjectFile(project: InferredProject): string {\n return [\n `# ${project.name}`,\n '',\n '## Summary',\n '',\n project.summary || '<!-- Add a short summary for this project -->',\n '',\n '## Primary Focus',\n '',\n project.primaryFocus || '<!-- Capture the main problem area, domain, or ownership -->',\n '',\n '## Local Sources',\n '',\n formatBulletList(\n project.sourceFolders.map((folder) => `\\`${folder}\\``),\n 'No local folders linked to this project yet.',\n ),\n '',\n '## Connected Integrations',\n '',\n formatBulletList(\n project.connectedIntegrations,\n 'No integrations connected during onboarding.',\n ),\n '',\n '## Grouping Signals',\n '',\n formatBulletList(project.keySignals, 'Add more details after the first sync.'),\n '',\n '## Notes To Confirm',\n '',\n '- Owners:',\n '- Key repos/docs:',\n '- Important decisions:',\n '',\n ].join('\\n');\n}\n\nfunction formatBulletList(items: string[], fallback: string): string {\n if (items.length === 0) {\n return `- ${fallback}`;\n }\n return items.map((item) => `- ${item}`).join('\\n');\n}\n\nasync function collectFolderSignal(folder: LocalFolderInput): Promise<FolderSignal> {\n const rawPath = folder.path.trim();\n const resolvedPath = path.resolve(rawPath);\n const basename = path.basename(resolvedPath);\n const notes: string[] = [];\n const entries: string[] = [];\n let packageName: string | undefined;\n let readmeHeading: string | undefined;\n\n if (folder.project?.trim()) {\n notes.push(`Tagged as \"${folder.project.trim()}\" during onboarding`);\n }\n\n try {\n const dirEntries = await fs.readdir(resolvedPath, { withFileTypes: true });\n const visibleEntries = dirEntries\n .filter((entry) => !entry.name.startsWith('.'))\n .slice(0, MAX_DIR_ENTRIES)\n .map((entry) => (entry.isDirectory() ? `${entry.name}/` : entry.name));\n\n entries.push(...visibleEntries);\n\n if (visibleEntries.length > 0) {\n notes.push(`Top entries: ${visibleEntries.slice(0, 5).join(', ')}`);\n }\n } catch {\n notes.push('Folder contents could not be read during onboarding');\n }\n\n try {\n const packageJson = await fs.readFile(path.join(resolvedPath, 'package.json'), 'utf-8');\n const parsed = JSON.parse(packageJson) as { name?: string };\n if (parsed.name?.trim()) {\n packageName = parsed.name.trim();\n notes.push(`package.json name: ${packageName}`);\n }\n } catch {\n // Ignore missing or invalid package.json\n }\n\n for (const candidate of README_CANDIDATES) {\n try {\n const readme = await fs.readFile(path.join(resolvedPath, candidate), 'utf-8');\n const heading = extractReadmeHeading(readme);\n if (heading) {\n readmeHeading = heading;\n notes.push(`README heading: ${heading}`);\n break;\n }\n } catch {\n // Ignore missing README files\n }\n }\n\n return {\n path: rawPath,\n explicitProject: folder.project?.trim() || undefined,\n basename,\n packageName,\n readmeHeading,\n entries,\n notes,\n };\n}\n\nfunction extractReadmeHeading(contents: string): string | undefined {\n for (const rawLine of contents.split('\\n').slice(0, 30)) {\n const line = rawLine.trim();\n if (!line) continue;\n if (line.startsWith('#')) {\n return line.replace(/^#+\\s*/, '').trim();\n }\n if (line.length <= 80) {\n return line;\n }\n }\n return undefined;\n}\n\nfunction buildHeuristicProjects(\n folderSignals: FolderSignal[],\n integrations: string[],\n): InferredProject[] {\n const integrationNames = integrations.map(formatIntegrationName);\n const groups = new Map<string, InferredProject>();\n\n if (folderSignals.length === 0 && integrationNames.length > 0) {\n return [\n {\n slug: 'workspace-context',\n name: 'Workspace Context',\n summary:\n 'Connected integrations are ready, but no local folders were added during onboarding. Confirm the main project boundaries after the first sync.',\n primaryFocus: 'Cross-project workspace context',\n sourceFolders: [],\n connectedIntegrations: integrationNames,\n keySignals: integrationNames.map((name) => `Connected integration: ${name}`),\n },\n ];\n }\n\n for (const signal of folderSignals) {\n const groupName = signal.explicitProject || inferProjectName(signal);\n const slug = slugify(groupName) || 'untitled-project';\n const existing = groups.get(slug);\n\n if (existing) {\n existing.sourceFolders.push(signal.path);\n existing.keySignals = unique([...existing.keySignals, ...signal.notes]);\n continue;\n }\n\n groups.set(slug, {\n slug,\n name: groupName,\n summary: buildHeuristicSummary(groupName, signal, integrationNames),\n primaryFocus: buildHeuristicFocus(signal),\n sourceFolders: [signal.path],\n connectedIntegrations: integrationNames,\n keySignals: unique(signal.notes),\n });\n }\n\n return [...groups.values()].sort((left, right) => left.name.localeCompare(right.name));\n}\n\nfunction buildHeuristicSummary(\n projectName: string,\n signal: FolderSignal,\n integrationNames: string[],\n): string {\n const integrationSuffix =\n integrationNames.length > 0\n ? ` It will also pull from ${integrationNames.join(', ')} once sync is enabled.`\n : '';\n\n if (signal.readmeHeading) {\n return `${projectName} appears to center on \"${signal.readmeHeading}\". Review and tighten this summary before finishing setup.${integrationSuffix}`;\n }\n\n if (signal.packageName) {\n return `${projectName} was inferred from the local package \"${signal.packageName}\". Review and tighten this summary before finishing setup.${integrationSuffix}`;\n }\n\n return `${projectName} was inferred from the selected local workspace folder. Review and tighten this summary before finishing setup.${integrationSuffix}`;\n}\n\nfunction buildHeuristicFocus(signal: FolderSignal): string {\n if (signal.packageName) {\n return `Owns or contributes to the ${humanizeLabel(signal.packageName)} codebase.`;\n }\n\n if (signal.entries.some((entry) => entry === 'docs/' || entry.toLowerCase().includes('docs'))) {\n return 'Mix of implementation and documentation workflows.';\n }\n\n if (signal.entries.some((entry) => entry === 'src/' || entry === 'app/' || entry.endsWith('.ts'))) {\n return 'Application code, implementation details, and related project context.';\n }\n\n return `Local context collected from the ${humanizeLabel(signal.basename)} workspace folder.`;\n}\n\nfunction inferProjectName(signal: FolderSignal): string {\n if (signal.packageName) {\n return humanizeLabel(signal.packageName);\n }\n\n const basename = humanizeLabel(signal.basename);\n return basename || 'Untitled Project';\n}\n\nasync function enrichProjectsWithOllama(\n projects: InferredProject[],\n folderSignals: FolderSignal[],\n integrations: string[],\n): Promise<{ projects: InferredProject[]; inference: ProjectInferenceMeta } | null> {\n if (projects.length === 0) {\n return null;\n }\n\n const model = await resolveOllamaModel();\n if (!model) {\n return null;\n }\n\n const prompt = [\n 'You are organizing local workspace context during onboarding.',\n 'Return strict JSON only in the format:',\n '{\"projects\":[{\"slug\":\"\",\"name\":\"\",\"summary\":\"\",\"primaryFocus\":\"\",\"keySignals\":[\"\"]}]}',\n 'Rules:',\n '- Keep the existing slugs exactly as provided.',\n '- Do not invent repositories, teams, or integrations that are not in the input.',\n '- Preserve the current project grouping; do not add or remove source folders.',\n '- Summaries should be concise and grounded in the visible folder signals.',\n '- Primary focus should be a short sentence.',\n '',\n JSON.stringify(\n {\n integrations: integrations.map(formatIntegrationName),\n folders: folderSignals,\n projects,\n },\n null,\n 2,\n ),\n ].join('\\n');\n\n try {\n const response = await fetch(`${OLLAMA_BASE_URL}/api/generate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model,\n prompt,\n stream: false,\n format: 'json',\n options: {\n temperature: 0.2,\n },\n }),\n signal: AbortSignal.timeout(15000),\n });\n\n if (!response.ok) {\n return null;\n }\n\n const payload = (await response.json()) as { response?: string };\n if (!payload.response) {\n return null;\n }\n\n const parsed = JSON.parse(payload.response) as {\n projects?: Array<{\n slug?: string;\n name?: string;\n summary?: string;\n primaryFocus?: string;\n keySignals?: string[];\n }>;\n };\n\n const enrichedBySlug = new Map(\n (parsed.projects ?? [])\n .filter((project) => project.slug?.trim())\n .map((project) => [project.slug!.trim(), project]),\n );\n\n const enrichedProjects = projects.map((project) => {\n const enriched = enrichedBySlug.get(project.slug);\n if (!enriched) {\n return project;\n }\n\n return {\n ...project,\n name: enriched.name?.trim() || project.name,\n summary: enriched.summary?.trim() || project.summary,\n primaryFocus: enriched.primaryFocus?.trim() || project.primaryFocus,\n keySignals:\n enriched.keySignals?.map((signal) => signal.trim()).filter(Boolean).slice(0, 5) ??\n project.keySignals,\n };\n });\n\n return {\n projects: enrichedProjects,\n inference: {\n strategy: 'ollama',\n model,\n note: `Structured locally and enriched with Ollama (${model}). No external API calls were made.`,\n },\n };\n } catch {\n return null;\n }\n}\n\nasync function resolveOllamaModel(): Promise<string | null> {\n try {\n const response = await fetch(`${OLLAMA_BASE_URL}/api/tags`, {\n signal: AbortSignal.timeout(1500),\n });\n if (!response.ok) {\n return null;\n }\n\n const payload = (await response.json()) as {\n models?: Array<{ name?: string }>;\n };\n\n const modelNames = (payload.models ?? [])\n .map((model) => model.name?.trim() ?? '')\n .filter(Boolean);\n\n if (modelNames.length === 0) {\n return null;\n }\n\n return (\n modelNames.find((name) => /qwen|llama|mistral|gemma/i.test(name)) ??\n modelNames[0]\n );\n } catch {\n return null;\n }\n}\n\nfunction formatIntegrationName(id: string): string {\n const names: Record<string, string> = {\n slack: 'Slack',\n github: 'GitHub',\n gitlab: 'GitLab',\n gmail: 'Gmail',\n gdrive: 'Google Drive',\n gchat: 'Google Chat',\n };\n\n return names[id] ?? humanizeLabel(id);\n}\n\nfunction slugify(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction humanizeLabel(value: string): string {\n return value\n .replace(/[-_]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values.filter(Boolean))];\n}\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0VT;","names":["path","fs","basename"]}
|
|
1
|
+
{"version":3,"sources":["../src/onboarding-server.ts","../../template-engine/dist/index.js","../src/google-auth.ts","../src/project-structure.ts","../src/slack-manifest.ts"],"sourcesContent":["import express from 'express';\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\nimport { createLocalStorage } from '@personal-assistant/storage-local';\nimport { createGDriveStorage } from '@personal-assistant/storage-gdrive';\nimport { createConfigManager } from '@personal-assistant/config-manager';\nimport { createContextManager } from '@personal-assistant/context-manager';\nimport {\n getTemplate,\n getTemplateSections,\n renderTemplate,\n listProfiles,\n getResponsibilities,\n} from '@personal-assistant/template-engine';\nimport { validateIntegrationConfig } from '@personal-assistant/integration-runtime';\nimport { createSlackConnector, validateSlackAppToken } from '@personal-assistant/integrations-slack';\nimport { createNoopEventClient } from '@personal-assistant/event-client';\nimport { WORKSPACE_PATHS } from '@personal-assistant/core-types';\nimport type {\n AppConfig,\n LlmProvider,\n ProfileType,\n UserProfile,\n StorageConfig,\n GDriveStorageConfig,\n IntegrationConfig,\n SyncConfig,\n} from '@personal-assistant/core-types';\nimport {\n GOOGLE_SCOPES_BY_FEATURE,\n getGoogleScopesForFeatures,\n normalizeGoogleScopes,\n type GoogleAuthFeature,\n} from './google-auth.js';\nimport { validateProviderConfig } from './provider-runtime.js';\nimport {\n buildProjectKnowledgeFiles,\n buildProjectStructurePreview,\n type KnowledgeGraphProvider,\n} from './project-structure.js';\nimport { buildSlackManifest } from './slack-manifest.js';\n\ninterface GoogleAuthSession {\n clientId: string;\n clientSecret: string;\n callbackPath: '/api/google/callback' | '/api/gdrive/callback';\n requestedFeatures: GoogleAuthFeature[];\n requestedScopes: string[];\n grantedScopes: string[];\n status: 'pending' | 'authenticated' | 'complete' | 'error';\n accessToken?: string;\n refreshToken?: string;\n accountEmail?: string;\n folderId?: string;\n folderName?: string;\n folderPath?: string;\n error?: string;\n}\n\ninterface GoogleCredentialPayload {\n clientId?: string;\n clientSecret?: string;\n refreshToken?: string;\n grantedScopes?: string[];\n}\n\ntype FolderPickerPurpose = 'local-source' | 'storage';\n\ninterface FolderPickerRequest {\n defaultPath?: string;\n purpose?: FolderPickerPurpose;\n}\n\nconst PICKER_COPY: Record<FolderPickerPurpose, { prompt: string; title: string }> = {\n 'local-source': {\n prompt: 'Select a local project folder to tag in Pac-Man',\n title: 'Select project source folder',\n },\n storage: {\n prompt: 'Select the Pac-Man workspace folder',\n title: 'Select workspace folder',\n },\n};\n\nconst pickerPathCache = new Map<string, { resolvedPath: string; validatedAt: number }>();\nconst PICKER_PATH_CACHE_TTL = 30_000; // 30 seconds\n\nasync function resolvePickerStartPath(defaultPath?: string): Promise<string | undefined> {\n const trimmed = defaultPath?.trim();\n if (!trimmed) {\n return undefined;\n }\n\n const resolvedPath = path.resolve(trimmed);\n\n // Check cache first to avoid redundant fs.stat calls\n const cached = pickerPathCache.get(resolvedPath);\n if (cached && Date.now() - cached.validatedAt < PICKER_PATH_CACHE_TTL) {\n return cached.resolvedPath;\n }\n\n // Check both candidates in parallel\n const candidates = [resolvedPath, path.dirname(resolvedPath)];\n const results = await Promise.allSettled(\n candidates.map(async (candidate) => {\n const stats = await fs.stat(candidate);\n return stats.isDirectory() ? candidate : null;\n }),\n );\n\n for (const result of results) {\n if (result.status === 'fulfilled' && result.value) {\n pickerPathCache.set(resolvedPath, { resolvedPath: result.value, validatedAt: Date.now() });\n return result.value;\n }\n }\n\n return undefined;\n}\n\nfunction escapeAppleScriptString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\nfunction escapePowerShellString(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\nfunction ensureTrailingSeparator(folderPath: string): string {\n return folderPath.endsWith(path.sep) ? folderPath : `${folderPath}${path.sep}`;\n}\n\nfunction isPickerCancelledError(err: unknown): boolean {\n const message = String(err).toLowerCase();\n return message.includes('user canceled') || message.includes('user cancelled') || message.includes('cancel');\n}\n\nasync function openNativeFolderPicker(\n platform: NodeJS.Platform,\n purpose: FolderPickerPurpose,\n startPath?: string,\n): Promise<string> {\n const copy = PICKER_COPY[purpose];\n\n if (platform === 'darwin') {\n const script = startPath\n ? `POSIX path of (choose folder with prompt \"${escapeAppleScriptString(copy.prompt)}\" default location POSIX file \"${escapeAppleScriptString(startPath)}\")`\n : `POSIX path of (choose folder with prompt \"${escapeAppleScriptString(copy.prompt)}\")`;\n const { stdout } = await execFileAsync('osascript', ['-e', script]);\n return stdout.trim();\n }\n\n if (platform === 'linux') {\n const args = ['--file-selection', '--directory', `--title=${copy.title}`];\n if (startPath) {\n args.push(`--filename=${ensureTrailingSeparator(startPath)}`);\n }\n const { stdout } = await execFileAsync('zenity', args);\n return stdout.trim();\n }\n\n if (platform === 'win32') {\n const script = [\n 'Add-Type -AssemblyName System.Windows.Forms',\n '$dialog = New-Object System.Windows.Forms.FolderBrowserDialog',\n `$dialog.Description = '${escapePowerShellString(copy.prompt)}'`,\n ...(startPath ? [`$dialog.SelectedPath = '${escapePowerShellString(startPath)}'`] : []),\n 'if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $dialog.SelectedPath }',\n ].join('; ');\n const { stdout } = await execFileAsync('powershell', ['-NoProfile', '-Command', script]);\n return stdout.trim();\n }\n\n throw new Error('Folder picker not supported on this platform');\n}\n\nexport async function startOnboardingServer(\n port: number,\n workspacePath: string,\n): Promise<void> {\n const app = express();\n app.use((req, res, next) => {\n const origin = req.headers.origin;\n if (origin) {\n res.header('Access-Control-Allow-Origin', origin);\n res.header('Vary', 'Origin');\n } else {\n res.header('Access-Control-Allow-Origin', '*');\n }\n res.header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type, Accept');\n\n if (req.method === 'OPTIONS') {\n res.sendStatus(204);\n return;\n }\n\n next();\n });\n app.use(express.json());\n\n let googleAuthSession: GoogleAuthSession | null = null;\n\n const onboardingStaticPath = await resolveOnboardingStaticPath();\n\n // Try to serve built static files; fallback to inline HTML\n if (onboardingStaticPath) {\n app.use(express.static(onboardingStaticPath));\n } else {\n // Serve inline onboarding page if the web app isn't built\n app.get('/', (_req, res) => {\n res.send(getInlineOnboardingHtml());\n });\n }\n\n // --- API Routes ---\n\n app.get('/api/profiles', (_req, res) => {\n const profiles = listProfiles();\n res.json({ profiles });\n });\n\n app.get('/api/responsibilities/:profileType', (req, res) => {\n try {\n const responsibilities = getResponsibilities(req.params.profileType as ProfileType);\n res.json({ responsibilities });\n } catch {\n res.status(400).json({ error: 'Invalid profile type' });\n }\n });\n\n app.get('/api/template/:profileType', (req, res) => {\n try {\n const template = getTemplate(req.params.profileType as ProfileType);\n res.json({ template });\n } catch {\n res.status(400).json({ error: 'Invalid profile type' });\n }\n });\n\n app.post('/api/preview-template', (req, res) => {\n const { profileType, name, assistantName, responsibilities } = req.body;\n try {\n const template = getTemplate(profileType);\n const files = renderTemplate(template, { name, assistantName, responsibilities });\n res.json({ files });\n } catch (err) {\n res.status(400).json({ error: String(err) });\n }\n });\n\n app.post('/api/project-structure-preview', async (req, res) => {\n const {\n profileType,\n name,\n assistantName,\n responsibilities,\n localFolders,\n driveFolders,\n integrations,\n } = req.body as {\n profileType: ProfileType;\n name: string;\n assistantName: string;\n responsibilities: string[];\n localFolders?: Array<{ path: string; project?: string }>;\n driveFolders?: Array<{ id: string; name: string; path: string }>;\n integrations?: string[];\n };\n\n try {\n const preview = await buildProjectStructurePreview({\n profileType,\n name,\n assistantName,\n responsibilities: responsibilities ?? [],\n localFolders: localFolders ?? [],\n driveFolders: driveFolders ?? [],\n integrations: integrations ?? [],\n });\n res.json(preview);\n } catch (err) {\n res.status(400).json({ error: String(err) });\n }\n });\n\n app.post('/api/build-project-knowledge', async (req, res) => {\n const { project, files, provider, userProfile, integrations, localFolders, driveFolders } = req.body as {\n project?: {\n slug?: string;\n name?: string;\n summary?: string;\n primaryFocus?: string;\n sourceFolders?: string[];\n connectedIntegrations?: string[];\n githubBranches?: string[];\n gitlabBranches?: string[];\n slackChannels?: string[];\n gdriveFolders?: string[];\n gdocDocuments?: string[];\n keySignals?: string[];\n llmInstructions?: string;\n templateFiles?: string[];\n };\n files?: Record<string, string>;\n provider?: {\n type?: 'openai' | 'anthropic' | 'ollama';\n apiKey?: string;\n model?: string;\n };\n userProfile?: {\n name?: string;\n email?: string;\n assistantName?: string;\n profileType?: string;\n responsibilities?: string[];\n };\n integrations?: string[];\n localFolders?: Array<{ path: string; project?: string }>;\n driveFolders?: Array<{ id: string; name: string; path: string }>;\n };\n\n if (!project?.slug || !project.name) {\n res.status(400).json({ error: 'Project slug and name are required.' });\n return;\n }\n\n try {\n const selectedProvider: KnowledgeGraphProvider | undefined =\n provider?.type === 'openai' || provider?.type === 'anthropic'\n ? {\n type: provider.type,\n apiKey: provider.apiKey ?? '',\n model: provider.model,\n }\n : provider?.type === 'ollama'\n ? { type: 'ollama' }\n : undefined;\n\n // Fetch template sections for the user's profile type so the LLM\n // can generate project-specific versions of the base template files\n let templateSections: Array<{ name: string; fileName: string; defaultContent: string }> | undefined;\n if (userProfile?.profileType) {\n try {\n const sections = getTemplateSections(userProfile.profileType as ProfileType);\n templateSections = sections.map((s) => ({\n name: s.name,\n fileName: s.fileName,\n defaultContent: s.defaultContent,\n }));\n } catch {\n // Unknown profile type — continue without template sections\n }\n }\n\n const result = await buildProjectKnowledgeFiles({\n project: {\n slug: project.slug,\n name: project.name,\n summary: project.summary ?? '',\n primaryFocus: project.primaryFocus ?? '',\n sourceFolders: project.sourceFolders ?? [],\n connectedIntegrations: project.connectedIntegrations ?? [],\n githubBranches: project.githubBranches ?? [],\n gitlabBranches: project.gitlabBranches ?? [],\n slackChannels: project.slackChannels ?? [],\n gdriveFolders: project.gdriveFolders ?? [],\n gdocDocuments: project.gdocDocuments ?? [],\n keySignals: project.keySignals ?? [],\n llmInstructions: project.llmInstructions ?? '',\n templateFiles: project.templateFiles ?? [],\n },\n files: files ?? {},\n provider: selectedProvider,\n userProfile: userProfile ? {\n name: userProfile.name ?? '',\n profileType: userProfile.profileType ?? '',\n assistantName: userProfile.assistantName ?? '',\n responsibilities: userProfile.responsibilities ?? [],\n } : undefined,\n integrations: integrations ?? [],\n localFolders: localFolders ?? [],\n driveFolders: driveFolders ?? [],\n templateSections,\n });\n\n res.json({\n files: result.files,\n message: `Project knowledge generated with ${result.model}. Review the files before finishing onboarding.`,\n });\n } catch (err) {\n res.status(500).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n app.post('/api/save', async (req, res) => {\n try {\n const payload = req.body as AppConfig & {\n templateFiles?: Record<string, string>;\n inferredProjects?: Array<{\n slug?: string;\n name?: string;\n summary?: string;\n primaryFocus?: string;\n sourceFolders?: string[];\n connectedIntegrations?: string[];\n githubBranches?: string[];\n gitlabBranches?: string[];\n slackChannels?: string[];\n gdriveFolders?: string[];\n gdocDocuments?: string[];\n keySignals?: string[];\n llmInstructions?: string;\n templateFiles?: string[];\n }>;\n };\n const config: AppConfig = payload;\n\n // Use the user-chosen local path if provided, otherwise fall back to CLI --dir\n const effectivePath =\n config.storage.mode === 'local' && (config.storage as { workspacePath?: string }).workspacePath\n ? path.resolve((config.storage as { workspacePath: string }).workspacePath)\n : workspacePath;\n\n // Ensure the local directory exists (needed for bootstrap even in GDrive mode)\n await fs.mkdir(effectivePath, { recursive: true });\n\n // Save a global pointer so CLI commands can find the workspace without --dir\n const rcPath = path.join(process.env.HOME ?? process.env.USERPROFILE ?? '~', '.personal-assistant-rc.json');\n await fs.writeFile(rcPath, JSON.stringify({ workspacePath: effectivePath }, null, 2), 'utf-8');\n\n // Always save storage.json locally for bootstrap (so MCP server knows which backend to use)\n const localStorage = createLocalStorage(effectivePath);\n const localConfigManager = createConfigManager(localStorage);\n await localConfigManager.saveConfig(config);\n\n // Resolve the user's chosen storage backend\n let targetStorage: import('@personal-assistant/core-types').StorageBackend = localStorage;\n if (config.storage.mode === 'gdrive') {\n const gdriveConfig = config.storage as GDriveStorageConfig;\n const resolvedCachePath = path.isAbsolute(gdriveConfig.cachePath)\n ? gdriveConfig.cachePath\n : path.resolve(path.dirname(effectivePath), gdriveConfig.cachePath);\n\n const gdriveStorage = createGDriveStorage({\n ...gdriveConfig,\n cachePath: resolvedCachePath,\n });\n await gdriveStorage.initialize();\n targetStorage = gdriveStorage;\n\n // Write config to GDrive so all reads go through GDrive\n const gdriveConfigManager = createConfigManager(gdriveStorage);\n await gdriveConfigManager.saveConfig(config);\n }\n\n const contextManager = createContextManager(targetStorage);\n\n // Initialize workspace structure on the target backend\n await contextManager.initWorkspace();\n\n // Render and write template files to the target backend\n const files =\n payload.templateFiles && Object.keys(payload.templateFiles).length > 0\n ? payload.templateFiles\n : renderTemplate(getTemplate(config.user.profileType), {\n name: config.user.name,\n assistantName: config.user.assistantName,\n responsibilities: config.user.responsibilities,\n });\n await contextManager.writeCanonicalFiles(files);\n\n if (payload.inferredProjects && payload.inferredProjects.length > 0) {\n await targetStorage.write(\n WORKSPACE_PATHS.context.derived.suggestions.inferredProjects,\n JSON.stringify(\n payload.inferredProjects.map((project, index) => ({\n name: project.slug ?? project.name ?? `project-${index + 1}`,\n score: Number((1 - index * 0.1).toFixed(2)),\n slug: project.slug ?? `project-${index + 1}`,\n summary: project.summary ?? '',\n primaryFocus: project.primaryFocus ?? '',\n sourceFolders: project.sourceFolders ?? [],\n connectedIntegrations: project.connectedIntegrations ?? [],\n githubBranches: project.githubBranches ?? [],\n gitlabBranches: project.gitlabBranches ?? [],\n slackChannels: project.slackChannels ?? [],\n gdriveFolders: project.gdriveFolders ?? [],\n keySignals: project.keySignals ?? [],\n llmInstructions: project.llmInstructions ?? '',\n templateFiles: project.templateFiles ?? [],\n })),\n null,\n 2,\n ),\n );\n }\n\n // Emit onboarding completed event\n const eventClient = createNoopEventClient();\n await eventClient.emit('onboarding_completed', {\n profile: config.user.profileType,\n storage_mode: config.storage.mode,\n });\n\n res.json({ success: true, workspacePath: effectivePath });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // --- Per-project save (persists individual project to draft storage) ---\n\n app.post('/api/save-project', async (req, res) => {\n try {\n const { project, templateFiles, allProjects } = req.body as {\n project?: {\n slug?: string;\n name?: string;\n summary?: string;\n primaryFocus?: string;\n sourceFolders?: string[];\n connectedIntegrations?: string[];\n githubBranches?: string[];\n gitlabBranches?: string[];\n slackChannels?: string[];\n gdriveFolders?: string[];\n gdocDocuments?: string[];\n keySignals?: string[];\n llmInstructions?: string;\n templateFiles?: string[];\n };\n templateFiles?: Record<string, string>;\n allProjects?: Array<{\n slug?: string;\n name?: string;\n summary?: string;\n primaryFocus?: string;\n sourceFolders?: string[];\n connectedIntegrations?: string[];\n githubBranches?: string[];\n gitlabBranches?: string[];\n slackChannels?: string[];\n gdriveFolders?: string[];\n gdocDocuments?: string[];\n keySignals?: string[];\n llmInstructions?: string;\n templateFiles?: string[];\n }>;\n };\n\n if (!project?.slug || !project.name) {\n res.status(400).json({ error: 'Project slug and name are required.' });\n return;\n }\n\n // Write the inferred projects list to the workspace so it persists across refreshes\n const effectivePath = workspacePath;\n await fs.mkdir(effectivePath, { recursive: true });\n\n const projectsToSave = allProjects ?? [project];\n const suggestionsDir = path.dirname(\n path.join(effectivePath, WORKSPACE_PATHS.context.derived.suggestions.inferredProjects),\n );\n await fs.mkdir(suggestionsDir, { recursive: true });\n\n await fs.writeFile(\n path.join(effectivePath, WORKSPACE_PATHS.context.derived.suggestions.inferredProjects),\n JSON.stringify(\n projectsToSave.map((p, index) => ({\n name: p.slug ?? p.name ?? `project-${index + 1}`,\n score: Number((1 - index * 0.1).toFixed(2)),\n slug: p.slug ?? `project-${index + 1}`,\n summary: p.summary ?? '',\n primaryFocus: p.primaryFocus ?? '',\n sourceFolders: p.sourceFolders ?? [],\n connectedIntegrations: p.connectedIntegrations ?? [],\n githubBranches: p.githubBranches ?? [],\n gitlabBranches: p.gitlabBranches ?? [],\n slackChannels: p.slackChannels ?? [],\n gdriveFolders: p.gdriveFolders ?? [],\n keySignals: p.keySignals ?? [],\n llmInstructions: p.llmInstructions ?? '',\n templateFiles: p.templateFiles ?? [],\n })),\n null,\n 2,\n ),\n 'utf-8',\n );\n\n // Write template files for this project if provided\n if (templateFiles) {\n const canonicalDir = path.join(effectivePath, 'context', 'canonical');\n for (const [filePath, content] of Object.entries(templateFiles)) {\n if (filePath.startsWith(`projects/${project.slug}`) || filePath.startsWith(`${project.slug}/`)) {\n const fullPath = path.join(canonicalDir, filePath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n await fs.writeFile(fullPath, content, 'utf-8');\n }\n }\n }\n\n res.json({ success: true, slug: project.slug });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // --- Per-project delete (removes project from persisted draft) ---\n\n app.post('/api/delete-project', async (req, res) => {\n try {\n const { slug, allProjects } = req.body as {\n slug?: string;\n allProjects?: Array<{\n slug?: string;\n name?: string;\n summary?: string;\n primaryFocus?: string;\n sourceFolders?: string[];\n connectedIntegrations?: string[];\n githubBranches?: string[];\n gitlabBranches?: string[];\n slackChannels?: string[];\n gdriveFolders?: string[];\n gdocDocuments?: string[];\n keySignals?: string[];\n llmInstructions?: string;\n templateFiles?: string[];\n }>;\n };\n\n if (!slug) {\n res.status(400).json({ error: 'Project slug is required.' });\n return;\n }\n\n const effectivePath = workspacePath;\n const suggestionsFile = path.join(\n effectivePath,\n WORKSPACE_PATHS.context.derived.suggestions.inferredProjects,\n );\n\n // Update the inferred projects file, excluding the deleted project\n const projectsToSave = (allProjects ?? []).filter((p) => p.slug !== slug);\n const suggestionsDir = path.dirname(suggestionsFile);\n await fs.mkdir(suggestionsDir, { recursive: true });\n await fs.writeFile(\n suggestionsFile,\n JSON.stringify(\n projectsToSave.map((p, index) => ({\n name: p.slug ?? p.name ?? `project-${index + 1}`,\n score: Number((1 - index * 0.1).toFixed(2)),\n slug: p.slug ?? `project-${index + 1}`,\n summary: p.summary ?? '',\n primaryFocus: p.primaryFocus ?? '',\n sourceFolders: p.sourceFolders ?? [],\n connectedIntegrations: p.connectedIntegrations ?? [],\n githubBranches: p.githubBranches ?? [],\n gitlabBranches: p.gitlabBranches ?? [],\n slackChannels: p.slackChannels ?? [],\n gdriveFolders: p.gdriveFolders ?? [],\n keySignals: p.keySignals ?? [],\n llmInstructions: p.llmInstructions ?? '',\n templateFiles: p.templateFiles ?? [],\n })),\n null,\n 2,\n ),\n 'utf-8',\n );\n\n // Clean up the project's canonical files\n const canonicalDir = path.join(effectivePath, 'context', 'canonical');\n const projectDir = path.join(canonicalDir, slug);\n const projectFile = path.join(canonicalDir, 'projects', `${slug}.md`);\n\n try { await fs.rm(projectDir, { recursive: true, force: true }); } catch { /* ignore */ }\n try { await fs.rm(projectFile, { force: true }); } catch { /* ignore */ }\n\n res.json({ success: true, slug });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // --- Integration credential validation ---\n\n app.post('/api/validate-integration', async (req, res) => {\n const { type, credentials } = req.body as {\n type: string;\n credentials: Record<string, string>;\n };\n\n try {\n const result = await validateIntegrationConfig({\n type: type as IntegrationConfig['type'],\n enabled: true,\n credentials,\n });\n\n if (result.ok) {\n res.json({ valid: true, info: result.summary ?? `Connected to ${type}` });\n return;\n }\n\n res.json({\n valid: false,\n error: [result.reason, ...(result.fix ?? [])].filter(Boolean).join(' '),\n });\n } catch (err) {\n res.json({ valid: false, error: String(err) });\n }\n });\n\n app.post('/api/validate-provider', async (req, res) => {\n const { provider, apiKey, model } = req.body as {\n provider: LlmProvider;\n apiKey: string;\n model?: string;\n };\n\n try {\n const result = await validateProviderConfig(provider, apiKey, model);\n res.json(result);\n } catch (err) {\n res.json({ valid: false, error: String(err) });\n }\n });\n\n app.post('/api/slack-manifest', (req, res) => {\n const { assistantName } = req.body as { assistantName?: string };\n\n try {\n res.json(buildSlackManifest({ assistantName }));\n } catch (err) {\n res.status(400).json({ error: String(err) });\n }\n });\n\n app.post('/api/validate-slack-runtime', async (req, res) => {\n const {\n botToken,\n appToken,\n generationEnabled,\n providers,\n } = req.body as {\n botToken?: string;\n appToken?: string;\n generationEnabled?: boolean;\n providers?: {\n openai?: { apiKey?: string; model?: string };\n anthropic?: { apiKey?: string; model?: string };\n };\n };\n\n if (!botToken || !appToken) {\n res.json({ valid: false, error: 'Slack bot token and app token are required.' });\n return;\n }\n\n if (!botToken.startsWith('xoxb-')) {\n res.json({\n valid: false,\n error: 'Slack bot token must start with xoxb-. Paste the Bot User OAuth Token from OAuth & Permissions.',\n });\n return;\n }\n\n if (!appToken.startsWith('xapp-')) {\n res.json({\n valid: false,\n error: 'Slack Socket Mode app token must start with xapp-. Create an App-Level Token with connections:write under Socket Mode.',\n });\n return;\n }\n\n try {\n const connector = createSlackConnector();\n await connector.authenticate({\n type: 'slack',\n enabled: true,\n credentials: { botToken },\n });\n const health = await connector.healthCheck();\n await validateSlackAppToken(appToken);\n\n if (generationEnabled) {\n const providerEntries = [\n ['openai', providers?.openai],\n ['anthropic', providers?.anthropic],\n ] as const;\n\n const configuredProviders = providerEntries.filter(([, value]) => value?.apiKey);\n if (configuredProviders.length === 0) {\n res.json({ valid: false, error: 'Enable at least one provider when Slack generation is turned on.' });\n return;\n }\n\n for (const [provider, value] of configuredProviders) {\n const result = await validateProviderConfig(provider, value?.apiKey ?? '', value?.model);\n if (!result.valid) {\n res.json({ valid: false, error: result.error ?? `Failed to validate ${provider}` });\n return;\n }\n }\n }\n\n res.json({\n valid: true,\n info: `${health.summary ?? 'Slack connected'} via Socket Mode. Atlas will monitor channels where the bot is added.`,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes('not_allowed_token_type')) {\n res.json({\n valid: false,\n error: 'Slack rejected the Socket Mode token. Use an App-Level Token that starts with xapp- and has the connections:write scope.',\n });\n return;\n }\n\n res.json({\n valid: false,\n error: message,\n });\n }\n });\n\n app.post('/api/slack/channels', async (req, res) => {\n const { botToken } = req.body as { botToken?: string };\n\n if (!botToken) {\n res.status(400).json({ error: 'Slack bot token is required.' });\n return;\n }\n\n try {\n const connector = createSlackConnector();\n await connector.authenticate({\n type: 'slack',\n enabled: true,\n credentials: { botToken },\n });\n const channels = (await connector.listChannels()).slice(0, 100);\n res.json({\n options: channels.map((channel) => ({\n value: channel.id,\n label: `#${channel.name}${channel.isPrivate ? ' (private)' : ''}`,\n })),\n });\n } catch (err) {\n res.status(400).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n app.post('/api/github/branches', async (req, res) => {\n const { token } = req.body as { token?: string };\n\n if (!token) {\n res.status(400).json({ error: 'GitHub personal access token is required.' });\n return;\n }\n\n try {\n const headers = {\n Authorization: `token ${token}`,\n Accept: 'application/vnd.github+json',\n 'User-Agent': 'personal-assistant',\n };\n\n const userResponse = await fetch('https://api.github.com/user', {\n headers,\n signal: AbortSignal.timeout(4000),\n });\n if (!userResponse.ok) {\n throw new Error('Failed to load the authenticated GitHub user.');\n }\n const user = (await userResponse.json()) as { login?: string };\n if (!user.login) {\n throw new Error('GitHub did not return the authenticated login.');\n }\n\n const eventsResponse = await fetch(\n `https://api.github.com/users/${encodeURIComponent(user.login)}/events?per_page=50`,\n {\n headers,\n signal: AbortSignal.timeout(5000),\n },\n );\n if (!eventsResponse.ok) {\n throw new Error('Failed to load recent GitHub activity for branch selection.');\n }\n\n const events = (await eventsResponse.json()) as Array<{\n type?: string;\n repo?: { name?: string };\n payload?: { ref?: string };\n }>;\n\n const seen = new Set<string>();\n const options = events\n .filter((event) => event.type === 'PushEvent')\n .map((event) => {\n const repo = event.repo?.name?.trim();\n const ref = event.payload?.ref?.trim() ?? '';\n const branch = ref.startsWith('refs/heads/') ? ref.replace('refs/heads/', '') : '';\n if (!repo || !branch) {\n return null;\n }\n const value = `${repo}:${branch}`;\n if (seen.has(value)) {\n return null;\n }\n seen.add(value);\n return {\n value,\n label: `${repo} · ${branch}`,\n };\n })\n .filter((option): option is { value: string; label: string } => Boolean(option))\n .slice(0, 40);\n\n res.json({\n options,\n });\n } catch (err) {\n res.status(400).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n app.post('/api/gitlab/branches', async (req, res) => {\n const { token, baseUrl } = req.body as { token?: string; baseUrl?: string };\n\n if (!token) {\n res.status(400).json({ error: 'GitLab personal access token is required.' });\n return;\n }\n\n const resolvedBaseUrl = (baseUrl?.trim() || 'https://gitlab.com/api/v4').replace(/\\/$/, '');\n\n try {\n const headers = { 'PRIVATE-TOKEN': token };\n const eventsResponse = await fetch(\n `${resolvedBaseUrl}/events?action=pushed&per_page=50`,\n {\n headers,\n signal: AbortSignal.timeout(5000),\n },\n );\n if (!eventsResponse.ok) {\n throw new Error('Failed to load recent GitLab push activity for branch selection.');\n }\n\n const events = (await eventsResponse.json()) as Array<{\n project_id?: number;\n project?: { path_with_namespace?: string };\n push_data?: { ref?: string };\n }>;\n\n const seen = new Set<string>();\n const options = events\n .map((event) => {\n const repo = event.project?.path_with_namespace?.trim();\n const branch = event.push_data?.ref?.trim() ?? '';\n if (!repo || !branch) {\n return null;\n }\n const value = `${repo}:${branch}`;\n if (seen.has(value)) {\n return null;\n }\n seen.add(value);\n return {\n value,\n label: `${repo} · ${branch}`,\n };\n })\n .filter((option): option is { value: string; label: string } => Boolean(option))\n .slice(0, 40);\n\n res.json({\n options,\n });\n } catch (err) {\n res.status(400).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n // --- Local folder picker ---\n\n app.post('/api/pick-folder', async (req, res) => {\n const { defaultPath, purpose = 'storage' } = req.body as FolderPickerRequest;\n const pickerPurpose: FolderPickerPurpose = purpose === 'local-source' ? 'local-source' : 'storage';\n const requestStartedAt = Date.now();\n const startPath = await resolvePickerStartPath(defaultPath);\n\n console.info(\n `[onboarding] folder picker requested purpose=${pickerPurpose} start=${startPath ?? 'system-default'}`,\n );\n\n try {\n const folderPath = await openNativeFolderPicker(process.platform, pickerPurpose, startPath);\n\n if (!folderPath) {\n console.info(\n `[onboarding] folder picker returned no path after ${Date.now() - requestStartedAt}ms`,\n );\n res.json({ cancelled: true, durationMs: Date.now() - requestStartedAt });\n return;\n }\n\n console.info(\n `[onboarding] folder picker resolved in ${Date.now() - requestStartedAt}ms path=${folderPath}`,\n );\n res.json({ path: folderPath, durationMs: Date.now() - requestStartedAt });\n } catch (err) {\n if (isPickerCancelledError(err)) {\n console.info(\n `[onboarding] folder picker cancelled after ${Date.now() - requestStartedAt}ms`,\n );\n res.json({ cancelled: true, durationMs: Date.now() - requestStartedAt });\n return;\n }\n console.error('[onboarding] folder picker failed', err);\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - requestStartedAt,\n });\n }\n });\n\n // --- Google Drive OAuth routes ---\n\n const createGoogleDriveClient = async (\n requiredScopes: string[] = [],\n credentials?: GoogleCredentialPayload,\n ) => {\n const activeSession =\n googleAuthSession && (googleAuthSession.status === 'authenticated' || googleAuthSession.status === 'complete')\n ? googleAuthSession\n : null;\n const fallbackClientId = credentials?.clientId?.trim() ?? '';\n const fallbackClientSecret = credentials?.clientSecret?.trim() ?? '';\n const fallbackRefreshToken = credentials?.refreshToken?.trim() ?? '';\n const fallbackGrantedScopes = Array.isArray(credentials?.grantedScopes)\n ? credentials!.grantedScopes\n .filter((scope): scope is string => typeof scope === 'string')\n .map((scope) => scope.trim())\n .filter(Boolean)\n : [];\n\n if (!activeSession && (!fallbackClientId || !fallbackClientSecret || !fallbackRefreshToken)) {\n throw new Error('Not authenticated. Please connect Google first.');\n }\n\n const grantedScopes = activeSession?.grantedScopes ?? fallbackGrantedScopes;\n const missingScopes =\n grantedScopes.length > 0\n ? requiredScopes.filter((scope) => !grantedScopes.includes(scope))\n : [];\n if (missingScopes.length > 0) {\n throw new Error(\n missingScopes.includes(GOOGLE_SCOPES_BY_FEATURE.gdrive[0])\n ? 'Google Drive read access has not been granted yet. Reconnect Google and allow Drive read access.'\n : 'Google Drive storage access has not been granted yet. Reconnect Google and allow Drive storage access.',\n );\n }\n\n const { google } = await import('googleapis');\n const redirectUri = activeSession\n ? `http://localhost:${port}${activeSession.callbackPath}`\n : `http://localhost:${port}/api/google/callback`;\n const oauth2Client = new google.auth.OAuth2(\n activeSession?.clientId ?? fallbackClientId,\n activeSession?.clientSecret ?? fallbackClientSecret,\n redirectUri,\n );\n oauth2Client.setCredentials({\n access_token: activeSession?.accessToken,\n refresh_token: activeSession?.refreshToken ?? fallbackRefreshToken,\n });\n\n return {\n oauth2Client,\n drive: google.drive({ version: 'v3', auth: oauth2Client }),\n };\n };\n\n const buildGoogleStatusPayload = (session: GoogleAuthSession | null) => {\n if (!session) {\n return { status: 'idle' as const };\n }\n\n return {\n status: session.status,\n requestedFeatures: session.requestedFeatures,\n requestedScopes: session.requestedScopes,\n grantedScopes: session.grantedScopes,\n accountEmail: session.accountEmail,\n refreshToken: session.refreshToken,\n folderId: session.folderId,\n folderName: session.folderName,\n folderPath: session.folderPath,\n error: session.error,\n };\n };\n\n const beginGoogleAuth = async (\n clientId: string,\n clientSecret: string,\n features: GoogleAuthFeature[],\n callbackPath: '/api/google/callback' | '/api/gdrive/callback',\n ) => {\n const { google } = await import('googleapis');\n const redirectUri = `http://localhost:${port}${callbackPath}`;\n const requestedScopes = getGoogleScopesForFeatures(features);\n const oauth2Client = new google.auth.OAuth2(clientId, clientSecret, redirectUri);\n const authUrl = oauth2Client.generateAuthUrl({\n access_type: 'offline',\n include_granted_scopes: true,\n prompt: 'consent',\n scope: requestedScopes,\n });\n\n const previousSession =\n googleAuthSession &&\n googleAuthSession.clientId === clientId &&\n googleAuthSession.clientSecret === clientSecret\n ? googleAuthSession\n : null;\n\n googleAuthSession = {\n clientId,\n clientSecret,\n callbackPath,\n requestedFeatures: features,\n requestedScopes,\n grantedScopes: previousSession?.grantedScopes ?? [],\n status: 'pending',\n refreshToken: previousSession?.refreshToken,\n accountEmail: previousSession?.accountEmail,\n };\n\n return { authUrl, requestedScopes };\n };\n\n const completeGoogleAuth = async (code: string, callbackPath: '/api/google/callback' | '/api/gdrive/callback') => {\n if (!googleAuthSession || googleAuthSession.callbackPath !== callbackPath) {\n throw new Error('Invalid OAuth callback — no pending auth session.');\n }\n\n const { google } = await import('googleapis');\n const redirectUri = `http://localhost:${port}${callbackPath}`;\n const oauth2Client = new google.auth.OAuth2(\n googleAuthSession.clientId,\n googleAuthSession.clientSecret,\n redirectUri,\n );\n\n const { tokens } = await oauth2Client.getToken(code);\n oauth2Client.setCredentials(tokens);\n\n const grantedScopes =\n normalizeGoogleScopes(tokens.scope) ??\n googleAuthSession.requestedScopes;\n\n let accountEmail = googleAuthSession.accountEmail;\n try {\n if (grantedScopes.includes(GOOGLE_SCOPES_BY_FEATURE.gmail[0])) {\n const gmail = google.gmail({ version: 'v1', auth: oauth2Client });\n const profile = await gmail.users.getProfile({ userId: 'me' });\n accountEmail = profile.data.emailAddress ?? googleAuthSession.accountEmail;\n } else if (\n grantedScopes.includes(GOOGLE_SCOPES_BY_FEATURE.storage[0]) ||\n grantedScopes.includes(GOOGLE_SCOPES_BY_FEATURE.gdrive[0])\n ) {\n const drive = google.drive({ version: 'v3', auth: oauth2Client });\n const about = await drive.about.get({ fields: 'user(emailAddress)' });\n accountEmail = about.data.user?.emailAddress ?? googleAuthSession.accountEmail;\n }\n } catch {\n // If the profile lookup fails, keep the auth session usable.\n }\n\n googleAuthSession = {\n ...googleAuthSession,\n status: 'authenticated',\n refreshToken: tokens.refresh_token ?? googleAuthSession.refreshToken,\n accessToken: tokens.access_token ?? undefined,\n grantedScopes: grantedScopes.length > 0 ? grantedScopes : googleAuthSession.requestedScopes,\n accountEmail,\n error: undefined,\n };\n };\n\n const handleGoogleCallback = async (\n code: string | undefined,\n callbackPath: '/api/google/callback' | '/api/gdrive/callback',\n res: express.Response,\n ) => {\n if (!code) {\n res.status(400).send('Invalid OAuth callback — no pending auth session.');\n return;\n }\n\n try {\n await completeGoogleAuth(code, callbackPath);\n\n res.send(`<!DOCTYPE html><html><body>\n <script>window.close();</script>\n <p style=\"font-family:sans-serif;padding:2rem;color:#4ade80;\">\n ✓ Authentication successful — you can close this tab and return to the setup.\n </p>\n </body></html>`);\n } catch (err) {\n if (googleAuthSession) {\n googleAuthSession.status = 'error';\n googleAuthSession.error = String(err);\n }\n res.status(500).send('Authentication failed: ' + String(err));\n }\n };\n\n app.post('/api/google/auth-start', async (req, res) => {\n const { clientId, clientSecret, features } = req.body as {\n clientId?: string;\n clientSecret?: string;\n features?: GoogleAuthFeature[];\n };\n\n if (!clientId || !clientSecret) {\n res.status(400).json({ error: 'clientId and clientSecret are required' });\n return;\n }\n\n const requestedFeatures = Array.isArray(features)\n ? [...new Set(features.filter((feature): feature is GoogleAuthFeature => feature === 'storage' || feature === 'gmail' || feature === 'gdrive'))]\n : [];\n\n if (requestedFeatures.length === 0) {\n res.status(400).json({ error: 'At least one Google feature is required.' });\n return;\n }\n\n try {\n const result = await beginGoogleAuth(clientId, clientSecret, requestedFeatures, '/api/google/callback');\n res.json({\n authUrl: result.authUrl,\n requestedFeatures,\n requestedScopes: result.requestedScopes,\n });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n app.get('/api/google/callback', async (req, res) => {\n const { code } = req.query as { code?: string };\n await handleGoogleCallback(code, '/api/google/callback', res);\n });\n\n app.get('/api/google/auth-status', (_req, res) => {\n res.json(buildGoogleStatusPayload(googleAuthSession));\n });\n\n app.post('/api/gdrive/auth-start', async (req, res) => {\n const { clientId, clientSecret } = req.body as { clientId?: string; clientSecret?: string };\n if (!clientId || !clientSecret) {\n res.status(400).json({ error: 'clientId and clientSecret are required' });\n return;\n }\n\n try {\n const result = await beginGoogleAuth(clientId, clientSecret, ['storage'], '/api/gdrive/callback');\n res.json({ authUrl: result.authUrl });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n app.get('/api/gdrive/callback', async (req, res) => {\n const { code } = req.query as { code?: string };\n await handleGoogleCallback(code, '/api/gdrive/callback', res);\n });\n\n app.get('/api/gdrive/auth-status', (_req, res) => {\n res.json(buildGoogleStatusPayload(googleAuthSession));\n });\n\n const listGoogleDocsInFolderScope = async (\n drive: any,\n folders: Array<{ id: string; path?: string }>,\n ): Promise<Array<{ value: string; label: string }>> => {\n const pending = folders\n .filter((folder) => folder.id.trim())\n .map((folder) => ({\n id: folder.id.trim(),\n path: folder.path?.trim() || folder.id.trim(),\n }));\n const visited = new Set<string>();\n const documents = new Map<string, { value: string; label: string }>();\n\n while (pending.length > 0) {\n const current = pending.shift();\n if (!current || visited.has(current.id)) {\n continue;\n }\n visited.add(current.id);\n\n let pageToken: string | undefined;\n do {\n const response = await drive.files.list({\n q: `'${current.id}' in parents and trashed=false and (mimeType='application/vnd.google-apps.folder' or mimeType='application/vnd.google-apps.document')`,\n fields: 'nextPageToken, files(id,name,mimeType)',\n orderBy: 'name_natural',\n pageSize: 100,\n pageToken,\n });\n\n for (const file of response.data.files ?? []) {\n if (!file.id || !file.name) {\n continue;\n }\n\n const nextPath = `${current.path} / ${file.name}`;\n if (file.mimeType === 'application/vnd.google-apps.folder') {\n pending.push({ id: file.id, path: nextPath });\n continue;\n }\n\n if (file.mimeType === 'application/vnd.google-apps.document') {\n documents.set(file.id, {\n value: nextPath,\n label: nextPath,\n });\n }\n }\n\n pageToken = response.data.nextPageToken ?? undefined;\n } while (pageToken);\n }\n\n return [...documents.values()].sort((left, right) => left.label.localeCompare(right.label));\n };\n\n const listRecentGoogleDocs = async (drive: any): Promise<Array<{ value: string; label: string }>> => {\n const response = await drive.files.list({\n q: `mimeType='application/vnd.google-apps.document' and trashed=false`,\n fields: 'files(id,name)',\n orderBy: 'modifiedTime desc',\n pageSize: 100,\n });\n\n return (response.data.files ?? [])\n .filter(\n (\n file: { id?: string | null; name?: string | null } | null | undefined,\n ): file is {\n id: string;\n name: string;\n } => Boolean(file?.id && file?.name),\n )\n .map((file: { id: string; name: string }) => ({\n value: file.name,\n label: file.name,\n }));\n };\n\n const handleGoogleDriveFolders = async (\n parentId: string,\n credentials: GoogleCredentialPayload | undefined,\n res: express.Response,\n ) => {\n try {\n const { drive } = await createGoogleDriveClient([], credentials);\n const response = await drive.files.list({\n q: `'${parentId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,\n fields: 'files(id,name)',\n orderBy: 'name_natural',\n pageSize: 200,\n });\n\n res.json({\n folders: (response.data.files ?? [])\n .filter((file) => file.id && file.name)\n .map((file) => ({\n id: file.id!,\n name: file.name!,\n })),\n });\n } catch (err) {\n res.status(400).json({ error: err instanceof Error ? err.message : String(err) });\n }\n };\n\n app.get('/api/google/drive-folders', async (req, res) => {\n const parentId =\n typeof req.query.parentId === 'string' && req.query.parentId.trim()\n ? req.query.parentId.trim()\n : 'root';\n\n await handleGoogleDriveFolders(parentId, undefined, res);\n });\n\n app.post('/api/google/drive-folders', async (req, res) => {\n const parentId =\n typeof req.body?.parentId === 'string' && req.body.parentId.trim()\n ? req.body.parentId.trim()\n : 'root';\n\n await handleGoogleDriveFolders(parentId, req.body as GoogleCredentialPayload, res);\n });\n\n app.post('/api/google/access-token', async (req, res) => {\n const clientId = (req.body as GoogleCredentialPayload).clientId?.trim();\n const clientSecret = (req.body as GoogleCredentialPayload).clientSecret?.trim();\n const refreshToken = (req.body as GoogleCredentialPayload).refreshToken?.trim();\n\n if (!clientId || !clientSecret || !refreshToken) {\n res.status(400).json({ error: 'clientId, clientSecret, and refreshToken are required.' });\n return;\n }\n\n try {\n const { google } = await import('googleapis');\n const oauth2Client = new google.auth.OAuth2(clientId, clientSecret);\n oauth2Client.setCredentials({ refresh_token: refreshToken });\n const { token } = await oauth2Client.getAccessToken();\n\n if (!token) {\n res.status(500).json({ error: 'Failed to obtain access token.' });\n return;\n }\n\n res.json({ accessToken: token });\n } catch (err) {\n res.status(500).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n app.post('/api/google/documents', async (req, res) => {\n const folders = Array.isArray(req.body?.folders)\n ? req.body.folders.filter(\n (folder: unknown): folder is { id: string; path?: string } =>\n Boolean(folder) &&\n typeof folder === 'object' &&\n typeof (folder as { id?: string }).id === 'string',\n )\n : [];\n\n try {\n const { drive } = await createGoogleDriveClient(\n [GOOGLE_SCOPES_BY_FEATURE.gdrive[0]],\n req.body as GoogleCredentialPayload,\n );\n const options =\n folders.length > 0\n ? await listGoogleDocsInFolderScope(drive, folders)\n : await listRecentGoogleDocs(drive);\n\n res.json({ options });\n } catch (err) {\n res.status(400).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n app.post('/api/gdrive/create-folder', async (req, res) => {\n const { folderName = 'Personal Assistant', parentFolderName = '' } =\n req.body as { folderName?: string; parentFolderName?: string };\n\n try {\n const { oauth2Client, drive } = await createGoogleDriveClient([GOOGLE_SCOPES_BY_FEATURE.storage[0]]);\n\n // Resolve parent folder\n let parentId = 'root';\n let locationPath = 'My Drive';\n\n if (parentFolderName.trim()) {\n const searchRes = await drive.files.list({\n q: `name='${parentFolderName.trim()}' and mimeType='application/vnd.google-apps.folder' and trashed=false`,\n fields: 'files(id,name)',\n spaces: 'drive',\n });\n\n if (searchRes.data.files && searchRes.data.files.length > 0) {\n parentId = searchRes.data.files[0].id!;\n } else {\n // Create the parent folder at root\n const parentRes = await drive.files.create({\n requestBody: {\n name: parentFolderName.trim(),\n mimeType: 'application/vnd.google-apps.folder',\n },\n fields: 'id',\n });\n parentId = parentRes.data.id!;\n }\n locationPath = `My Drive / ${parentFolderName.trim()}`;\n }\n\n // Check if the main folder already exists under the parent before creating\n let folderId: string | undefined;\n let resolvedFolderName = folderName.trim();\n const existingSearch = await drive.files.list({\n q: `name='${resolvedFolderName}' and '${parentId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,\n fields: 'files(id,name)',\n spaces: 'drive',\n });\n\n if (existingSearch.data.files && existingSearch.data.files.length > 0) {\n folderId = existingSearch.data.files[0].id!;\n resolvedFolderName = existingSearch.data.files[0].name!;\n } else {\n const folderRes = await drive.files.create({\n requestBody: {\n name: resolvedFolderName,\n mimeType: 'application/vnd.google-apps.folder',\n parents: [parentId],\n },\n fields: 'id,name',\n });\n folderId = folderRes.data.id!;\n resolvedFolderName = folderRes.data.name!;\n }\n\n const folderPath = `${locationPath} / ${resolvedFolderName}`;\n\n // Refresh tokens in case they were rotated\n const freshCredentials = await oauth2Client.getAccessToken();\n const currentSession = googleAuthSession;\n if (!currentSession) {\n throw new Error('Google auth session was lost before the folder could be saved.');\n }\n const latestRefreshToken =\n (oauth2Client.credentials.refresh_token as string | undefined) ??\n currentSession.refreshToken;\n\n googleAuthSession = {\n ...currentSession,\n status: 'complete',\n folderId: folderId!,\n folderName: resolvedFolderName,\n folderPath,\n refreshToken: latestRefreshToken,\n accessToken: freshCredentials.token ?? undefined,\n };\n\n res.json({\n folderId,\n folderName: resolvedFolderName,\n folderPath,\n refreshToken: latestRefreshToken,\n });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n app.get('/api/status', async (_req, res) => {\n const storage = createLocalStorage(workspacePath);\n const configManager = createConfigManager(storage);\n try {\n const config = await configManager.loadConfig();\n res.json({ configured: true, config });\n } catch {\n res.json({ configured: false });\n }\n });\n\n // Start server\n const server = app.listen(port, () => {\n const url = `http://localhost:${port}`;\n console.log(`Onboarding server running at ${url}`);\n\n // Try to open browser\n import('open')\n .then((openModule) => openModule.default(url))\n .catch(() => {\n console.log(`Open ${url} in your browser to continue.`);\n });\n });\n\n // Handle graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\nShutting down onboarding server...');\n server.close();\n process.exit(0);\n });\n}\n\nasync function resolveOnboardingStaticPath(): Promise<string | null> {\n const baseDir = import.meta.dirname ?? __dirname;\n const candidates = [\n path.resolve(baseDir, './onboarding-web'),\n path.resolve(baseDir, '../../../apps/onboarding-web/dist'),\n ];\n\n for (const candidate of candidates) {\n try {\n await fs.access(path.join(candidate, 'index.html'));\n return candidate;\n } catch {\n // keep looking\n }\n }\n\n return null;\n}\n\nfunction getInlineOnboardingHtml(): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Personal Assistant - Setup</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #0f172a; color: #e2e8f0; min-height: 100vh; }\n .container { max-width: 640px; margin: 0 auto; padding: 2rem; }\n h1 { font-size: 1.8rem; margin-bottom: 0.5rem; color: #f8fafc; }\n h2 { font-size: 1.2rem; margin-bottom: 1rem; color: #94a3b8; font-weight: 400; }\n .step { display: none; }\n .step.active { display: block; }\n .progress { display: flex; gap: 0.5rem; margin-bottom: 2rem; }\n .progress-dot { width: 2rem; height: 0.25rem; background: #334155; border-radius: 2px; transition: background 0.3s; }\n .progress-dot.done { background: #3b82f6; }\n .progress-dot.current { background: #60a5fa; }\n label { display: block; margin-bottom: 0.5rem; color: #cbd5e1; font-size: 0.9rem; }\n input, select, textarea { width: 100%; padding: 0.75rem; background: #1e293b; border: 1px solid #334155; border-radius: 0.5rem; color: #f8fafc; font-size: 1rem; margin-bottom: 1rem; }\n input:focus, select:focus, textarea:focus { outline: none; border-color: #3b82f6; }\n textarea { min-height: 200px; font-family: 'SF Mono', 'Fira Code', monospace; font-size: 0.85rem; }\n button { padding: 0.75rem 1.5rem; border: none; border-radius: 0.5rem; font-size: 1rem; cursor: pointer; transition: all 0.2s; }\n .btn-primary { background: #3b82f6; color: white; }\n .btn-primary:hover { background: #2563eb; }\n .btn-secondary { background: #334155; color: #e2e8f0; }\n .btn-secondary:hover { background: #475569; }\n .btn-group { display: flex; gap: 0.75rem; margin-top: 1.5rem; }\n .checkbox-group { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; margin-bottom: 1rem; }\n .checkbox-item { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem; background: #1e293b; border: 1px solid #334155; border-radius: 0.375rem; cursor: pointer; }\n .checkbox-item:hover { border-color: #475569; }\n .checkbox-item input[type=\"checkbox\"] { width: auto; margin: 0; }\n .radio-group { display: flex; gap: 1rem; margin-bottom: 1rem; }\n .radio-item { flex: 1; padding: 1rem; background: #1e293b; border: 2px solid #334155; border-radius: 0.5rem; cursor: pointer; text-align: center; transition: all 0.2s; }\n .radio-item:hover { border-color: #475569; }\n .radio-item.selected { border-color: #3b82f6; background: #1e3a5f; }\n .success { text-align: center; padding: 3rem 0; }\n .success h2 { color: #4ade80; font-size: 1.5rem; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"progress\" id=\"progress\"></div>\n\n <!-- Step 1: Identity -->\n <div class=\"step active\" data-step=\"0\">\n <h1>Welcome</h1>\n <h2>Let's set up your personal assistant</h2>\n <label>Your Name</label>\n <input type=\"text\" id=\"userName\" placeholder=\"Jane Smith\">\n <label>Assistant Name</label>\n <input type=\"text\" id=\"assistantName\" placeholder=\"Atlas\" value=\"Atlas\">\n <label>Profile</label>\n <select id=\"profileType\">\n <option value=\"software-engineer\">Software Engineer</option>\n <option value=\"product-manager\">Product Manager</option>\n <option value=\"engineering-manager\">Engineering Manager</option>\n <option value=\"devops\">DevOps Engineer</option>\n </select>\n <div class=\"btn-group\"><button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button></div>\n </div>\n\n <!-- Step 2: Responsibilities -->\n <div class=\"step\" data-step=\"1\">\n <h1>Responsibilities</h1>\n <h2>Select your core responsibilities</h2>\n <div class=\"checkbox-group\" id=\"responsibilitiesGroup\"></div>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button>\n </div>\n </div>\n\n <!-- Step 3: Template Preview -->\n <div class=\"step\" data-step=\"2\">\n <h1>Context Template</h1>\n <h2>Preview and customize your context template</h2>\n <textarea id=\"templatePreview\"></textarea>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button>\n </div>\n </div>\n\n <!-- Step 4: Storage -->\n <div class=\"step\" data-step=\"3\">\n <h1>Storage</h1>\n <h2>Where should your context be stored?</h2>\n <div class=\"radio-group\">\n <div class=\"radio-item selected\" onclick=\"selectStorage('local')\" id=\"storage-local\">\n <strong>Local Workspace</strong><br><small>Files stored on this machine</small>\n </div>\n <div class=\"radio-item\" onclick=\"selectStorage('gdrive')\" id=\"storage-gdrive\">\n <strong>Google Drive</strong><br><small>Files stored in your Drive folder</small>\n </div>\n </div>\n <div id=\"storage-local-fields\">\n <label>Storage path</label>\n <div style=\"display:flex;gap:0.5rem;align-items:center;\">\n <input type=\"text\" id=\"localPath\" value=\".personal-assistant\" placeholder=\".personal-assistant\" style=\"flex:1;margin-bottom:0;\">\n <button class=\"btn-secondary\" onclick=\"browseFolder()\" id=\"browseBtn\" style=\"white-space:nowrap;flex-shrink:0;\">Browse</button>\n </div>\n <small style=\"color:#64748b;font-size:0.8rem;display:block;margin-top:0.4rem;margin-bottom:1rem;\">Click Browse to open a folder picker, or type a path directly.</small>\n </div>\n <div id=\"storage-gdrive-fields\" style=\"display:none;\">\n <p style=\"color:#f59e0b;font-size:0.85rem;margin-bottom:1rem;\">\n Google Drive OAuth is only supported in the full onboarding UI.<br>\n Run <code>pnpm build</code> in <code>apps/onboarding-web</code> then restart <code>pacman init</code>.\n </p>\n </div>\n <div style=\"background:#1c1917;border:1px solid #92400e;border-radius:0.5rem;padding:0.75rem 1rem;margin-bottom:1.5rem;font-size:0.85rem;color:#fbbf24;\">\n ⚠️ Do not delete, move, or rename the folder structure created by this setup. Claude and the sync daemon rely on the exact file layout to load and update your context.\n </div>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button>\n </div>\n </div>\n\n <!-- Step 5: Integrations -->\n <div class=\"step\" data-step=\"4\">\n <h1>Integrations</h1>\n <h2>Connect your tools (optional)</h2>\n <div class=\"checkbox-group\" id=\"integrationsGroup\">\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"slack\"> Slack</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"gmail\"> Gmail</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"github\"> GitHub</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"gitlab\"> GitLab</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"gdrive\"> Google Drive Docs</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" value=\"gchat\"> Google Chat</label>\n </div>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button>\n </div>\n </div>\n\n <!-- Step 6: Sync Schedule -->\n <div class=\"step\" data-step=\"5\">\n <h1>Sync Schedule</h1>\n <h2>When should context be refreshed?</h2>\n <label>Daily Sync Time</label>\n <input type=\"time\" id=\"syncTime\" value=\"08:00\">\n <label>Timezone</label>\n <select id=\"timezone\">\n <option value=\"America/New_York\">Eastern Time (ET)</option>\n <option value=\"America/Chicago\">Central Time (CT)</option>\n <option value=\"America/Denver\">Mountain Time (MT)</option>\n <option value=\"America/Los_Angeles\">Pacific Time (PT)</option>\n <option value=\"UTC\">UTC</option>\n <option value=\"Europe/London\">London (GMT/BST)</option>\n <option value=\"Europe/Berlin\">Berlin (CET)</option>\n <option value=\"Asia/Tokyo\">Tokyo (JST)</option>\n <option value=\"Asia/Kolkata\">India (IST)</option>\n <option value=\"Australia/Sydney\">Sydney (AEST)</option>\n </select>\n <div class=\"checkbox-group\">\n <label class=\"checkbox-item\"><input type=\"checkbox\" id=\"manualSync\" checked> Manual sync</label>\n <label class=\"checkbox-item\"><input type=\"checkbox\" id=\"asyncUpdate\" checked> Async updates</label>\n </div>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"nextStep()\">Continue</button>\n </div>\n </div>\n\n <!-- Step 7: Finish -->\n <div class=\"step\" data-step=\"6\">\n <h1>All Set!</h1>\n <h2>Review and save your configuration</h2>\n <div id=\"summary\" style=\"background:#1e293b;padding:1rem;border-radius:0.5rem;margin-bottom:1rem;font-family:monospace;font-size:0.85rem;white-space:pre-wrap;\"></div>\n <div class=\"btn-group\">\n <button class=\"btn-secondary\" onclick=\"prevStep()\">Back</button>\n <button class=\"btn-primary\" onclick=\"saveConfig()\">Save & Finish</button>\n </div>\n </div>\n\n <!-- Success -->\n <div class=\"step\" data-step=\"7\">\n <div class=\"success\">\n <h2>Setup Complete!</h2>\n <p style=\"margin-top:1rem;color:#94a3b8;\">Your personal assistant context has been initialized.</p>\n <p style=\"margin-top:1rem;color:#94a3b8;\">Next steps:</p>\n <pre style=\"text-align:left;margin-top:1rem;background:#1e293b;padding:1rem;border-radius:0.5rem;font-size:0.85rem;\">\n# Install Claude Code integration\npacman claude install\npacman mcp claude install\n\n# Install Codex integration\npacman codex install\npacman mcp codex install\n\n# Start the sync daemon\npacman daemon\n\n# Start the real-time Slack listener\npacman slack listen\n\n# Use in Claude Code\n/pacman start <project>\n\n# Use in Codex\nAsk Codex to load or refresh your Pac-Man context for <project></pre>\n <p style=\"margin-top:1rem;color:#64748b;font-size:0.85rem;\">Restart Claude Code or Codex after installing the MCP server.<br>If <code style=\"background:#1e293b;padding:0 4px;border-radius:3px;\">pacman</code> is not found, link it first:<br>\n <code style=\"background:#1e293b;padding:2px 6px;border-radius:3px;\">pnpm setup && source ~/.zshrc && cd packages/cli && pnpm link --global</code></p>\n </div>\n </div>\n </div>\n\n <script>\n let currentStep = 0;\n const totalSteps = 7;\n let state = { storageMode: 'local', responsibilities: [] };\n\n function updateProgress() {\n const bar = document.getElementById('progress');\n bar.innerHTML = '';\n for (let i = 0; i < totalSteps; i++) {\n const dot = document.createElement('div');\n dot.className = 'progress-dot' + (i < currentStep ? ' done' : i === currentStep ? ' current' : '');\n bar.appendChild(dot);\n }\n }\n\n function showStep(n) {\n document.querySelectorAll('.step').forEach(s => s.classList.remove('active'));\n document.querySelector('[data-step=\"' + n + '\"]').classList.add('active');\n currentStep = n;\n updateProgress();\n }\n\n async function nextStep() {\n if (currentStep === 0) await loadResponsibilities();\n if (currentStep === 1) await loadTemplatePreview();\n if (currentStep === 5) updateSummary();\n showStep(currentStep + 1);\n }\n\n function prevStep() { showStep(currentStep - 1); }\n\n async function loadResponsibilities() {\n const profileType = document.getElementById('profileType').value;\n const res = await fetch('/api/responsibilities/' + profileType);\n const data = await res.json();\n const group = document.getElementById('responsibilitiesGroup');\n group.innerHTML = data.responsibilities.map(r =>\n '<label class=\"checkbox-item\"><input type=\"checkbox\" value=\"' + r + '\" checked> ' + r + '</label>'\n ).join('');\n }\n\n async function loadTemplatePreview() {\n const profileType = document.getElementById('profileType').value;\n const name = document.getElementById('userName').value;\n const assistantName = document.getElementById('assistantName').value;\n const responsibilities = Array.from(document.querySelectorAll('#responsibilitiesGroup input:checked')).map(c => c.value);\n state.responsibilities = responsibilities;\n\n const res = await fetch('/api/preview-template', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ profileType, name, assistantName, responsibilities })\n });\n const data = await res.json();\n const preview = Object.entries(data.files).map(([f, c]) => '--- ' + f + ' ---\\\\n' + c).join('\\\\n\\\\n');\n document.getElementById('templatePreview').value = preview;\n }\n\n function selectStorage(mode) {\n state.storageMode = mode;\n document.querySelectorAll('.radio-item').forEach(r => r.classList.remove('selected'));\n document.getElementById('storage-' + mode).classList.add('selected');\n document.getElementById('storage-local-fields').style.display = mode === 'local' ? 'block' : 'none';\n document.getElementById('storage-gdrive-fields').style.display = mode === 'gdrive' ? 'block' : 'none';\n }\n\n async function browseFolder() {\n const btn = document.getElementById('browseBtn');\n btn.textContent = 'Opening...';\n btn.disabled = true;\n try {\n const res = await fetch('/api/pick-folder', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n defaultPath: document.getElementById('localPath').value,\n purpose: 'storage'\n })\n });\n const data = await res.json();\n if (!data.cancelled && data.path) {\n document.getElementById('localPath').value = data.path;\n }\n } catch (e) {\n // ignore — user can type path manually\n } finally {\n btn.textContent = 'Browse';\n btn.disabled = false;\n }\n }\n\n function updateSummary() {\n const config = buildConfig();\n document.getElementById('summary').textContent = JSON.stringify(config, null, 2);\n }\n\n function buildConfig() {\n const integrations = Array.from(document.querySelectorAll('#integrationsGroup input:checked')).map(c => ({\n type: c.value, enabled: true, credentials: {}, cursor: null, lastSyncAt: null\n }));\n\n return {\n user: {\n name: document.getElementById('userName').value,\n assistantName: document.getElementById('assistantName').value,\n profileType: document.getElementById('profileType').value,\n responsibilities: state.responsibilities\n },\n storage: state.storageMode === 'local'\n ? { mode: 'local', workspacePath: document.getElementById('localPath').value || '.personal-assistant' }\n : { mode: 'gdrive', folderId: '', folderName: 'Personal Assistant', cachePath: '.personal-assistant/cache' },\n integrations,\n sync: {\n dailySyncTime: document.getElementById('syncTime').value,\n timezone: document.getElementById('timezone').value,\n manualSyncEnabled: document.getElementById('manualSync').checked,\n asyncUpdateEnabled: document.getElementById('asyncUpdate').checked\n }\n };\n }\n\n async function saveConfig() {\n const config = buildConfig();\n const res = await fetch('/api/save', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(config)\n });\n const data = await res.json();\n if (data.success) showStep(7);\n else alert('Error: ' + data.error);\n }\n\n updateProgress();\n </script>\n</body>\n</html>`;\n}\n","// src/index.ts\nvar PROFILE_TEMPLATES = {\n \"software-engineer\": {\n profileType: \"software-engineer\",\n name: \"Software Engineer\",\n description: \"Context template for software engineers\",\n responsibilities: [\n \"Code review and PR management\",\n \"Feature development\",\n \"Bug fixing and debugging\",\n \"Architecture decisions\",\n \"Technical documentation\",\n \"On-call and incident response\",\n \"Mentoring junior engineers\",\n \"Sprint planning and estimation\",\n \"CI/CD pipeline maintenance\",\n \"API design and development\"\n ],\n sections: [\n {\n name: \"Overview\",\n fileName: \"overview.md\",\n required: true,\n defaultContent: `# Overview\n\n## Role\nSoftware Engineer\n\n## Team\n<!-- Your team name -->\n\n## Primary Focus\n<!-- Main area of work -->\n\n## Key Repositories\n<!-- List your main repos -->\n\n## Tech Stack\n<!-- Languages, frameworks, tools -->\n`\n },\n {\n name: \"Context Details\",\n fileName: \"context-details.md\",\n required: false,\n defaultContent: `# Context Details\n\n## Executive Summary\n<!-- One-paragraph project overview: status, owner, key objective, current phase -->\n\n## Key Context\n\n| Attribute | Value |\n|-----------|-------|\n| Tech Stack | <!-- Languages, frameworks, key libraries --> |\n| Team Size | <!-- Number of engineers --> |\n| Dependencies | <!-- Upstream/downstream services --> |\n| Blockers | <!-- Current blockers or risks --> |\n| Repo(s) | <!-- Primary repositories --> |\n| Deploy Target | <!-- Where this runs (k8s, lambda, etc.) --> |\n\n## Timeline\n\n| Milestone | Date | Status | Owner |\n|-----------|------|--------|-------|\n| <!-- Milestone 1 --> | <!-- Date --> | <!-- On track / At risk / Done --> | <!-- Owner --> |\n| <!-- Milestone 2 --> | <!-- Date --> | <!-- Status --> | <!-- Owner --> |\n\n## Active Decisions\n\n| Decision | Options | Status | Deadline | Owner |\n|----------|---------|--------|----------|-------|\n| <!-- Decision 1 --> | <!-- A / B / C --> | <!-- Open / Decided --> | <!-- Date --> | <!-- Owner --> |\n\n## Metrics & Health\n\n| Metric | Target | Current | Trend |\n|--------|--------|---------|-------|\n| Build time | <!-- e.g. < 5 min --> | <!-- Current --> | <!-- Up / Down / Stable --> |\n| Test coverage | <!-- e.g. > 80% --> | <!-- Current --> | <!-- Trend --> |\n| P0 bugs | <!-- e.g. 0 --> | <!-- Current --> | <!-- Trend --> |\n| Deploy frequency | <!-- e.g. daily --> | <!-- Current --> | <!-- Trend --> |\n\n## Communication Map\n\n| Stakeholder | Role | Channel | Cadence |\n|-------------|------|---------|---------|\n| <!-- Name --> | <!-- Role --> | <!-- Slack / Email / Meeting --> | <!-- Weekly / Ad-hoc --> |\n\n## Risk Register\n\n| Risk | Likelihood | Impact | Mitigation | Owner |\n|------|-----------|--------|------------|-------|\n| <!-- Risk 1 --> | <!-- Low / Med / High --> | <!-- Low / Med / High --> | <!-- Mitigation plan --> | <!-- Owner --> |\n\n## Quick Reference\n\n- **Primary repo:** <!-- link -->\n- **CI dashboard:** <!-- link -->\n- **Monitoring:** <!-- link -->\n- **Runbook:** <!-- link -->\n- **On-call rotation:** <!-- link -->\n- **Team channel:** <!-- link -->\n`\n },\n {\n name: \"Responsibilities\",\n fileName: \"responsibilities.md\",\n required: true,\n defaultContent: `# Responsibilities\n\n## Core Duties\n<!-- Your primary responsibilities -->\n\n## On-Call\n<!-- On-call schedule and escalation paths -->\n\n## Code Review\n<!-- Review expectations and areas -->\n`\n },\n {\n name: \"Stakeholders\",\n fileName: \"stakeholders.md\",\n required: false,\n defaultContent: `# Stakeholders\n\n## Direct Manager\n<!-- Name, role -->\n\n## Team Members\n<!-- Key teammates -->\n\n## Cross-Team Contacts\n<!-- People you work with in other teams -->\n\n## Escalation Path\n<!-- Who to escalate to and when -->\n`\n },\n {\n name: \"Documentation\",\n fileName: \"docs.md\",\n required: false,\n defaultContent: `# Documentation References\n\n## Internal Docs\n<!-- Links to internal documentation -->\n\n## Runbooks\n<!-- Links to runbooks -->\n\n## Architecture Docs\n<!-- Links to architecture documents -->\n`\n }\n ]\n },\n \"product-manager\": {\n profileType: \"product-manager\",\n name: \"Product Manager\",\n description: \"Context template for product managers\",\n responsibilities: [\n \"Product roadmap management\",\n \"Feature prioritization\",\n \"Stakeholder communication\",\n \"User research and interviews\",\n \"Metrics and KPI tracking\",\n \"Sprint planning and grooming\",\n \"Go-to-market strategy\",\n \"Competitive analysis\",\n \"Cross-team coordination\",\n \"Product requirements documentation\"\n ],\n sections: [\n {\n name: \"Overview\",\n fileName: \"overview.md\",\n required: true,\n defaultContent: `# Overview\n\n## Role\nProduct Manager\n\n## Product Area\n<!-- Your product area -->\n\n## Key Metrics\n<!-- North star and supporting metrics -->\n\n## Current Quarter Goals\n<!-- OKRs or key goals -->\n`\n },\n {\n name: \"Context Details\",\n fileName: \"context-details.md\",\n required: false,\n defaultContent: `# Context Details\n\n## Executive Summary\n<!-- One-paragraph product overview: current phase, strategic priority, key objective, owner -->\n\n## Key Context\n\n| Attribute | Value |\n|-----------|-------|\n| Product Area | <!-- Feature area or product line --> |\n| User Segment | <!-- Target users --> |\n| Revenue Impact | <!-- ARR / MRR contribution --> |\n| Dependencies | <!-- Eng teams, design, legal, etc. --> |\n| Blockers | <!-- Current blockers or open questions --> |\n| Launch Vehicle | <!-- How this ships: feature flag, release train, etc. --> |\n\n## Timeline\n\n| Milestone | Date | Status | Owner |\n|-----------|------|--------|-------|\n| <!-- Milestone 1 --> | <!-- Date --> | <!-- On track / At risk / Done --> | <!-- Owner --> |\n| <!-- Milestone 2 --> | <!-- Date --> | <!-- Status --> | <!-- Owner --> |\n\n## Active Decisions\n\n| Decision | Options | Status | Deadline | Owner |\n|----------|---------|--------|----------|-------|\n| <!-- Decision 1 --> | <!-- A / B / C --> | <!-- Open / Decided --> | <!-- Date --> | <!-- Owner --> |\n\n## Metrics & Health\n\n| Metric | Target | Current | Trend |\n|--------|--------|---------|-------|\n| Adoption rate | <!-- e.g. 30% of MAU --> | <!-- Current --> | <!-- Trend --> |\n| NPS / CSAT | <!-- Target --> | <!-- Current --> | <!-- Trend --> |\n| Feature usage | <!-- Target --> | <!-- Current --> | <!-- Trend --> |\n| Conversion | <!-- Target --> | <!-- Current --> | <!-- Trend --> |\n\n## Communication Map\n\n| Stakeholder | Role | Channel | Cadence |\n|-------------|------|---------|---------|\n| <!-- Name --> | <!-- Role --> | <!-- Slack / Email / Meeting --> | <!-- Weekly / Ad-hoc --> |\n\n## Risk Register\n\n| Risk | Likelihood | Impact | Mitigation | Owner |\n|------|-----------|--------|------------|-------|\n| <!-- Risk 1 --> | <!-- Low / Med / High --> | <!-- Low / Med / High --> | <!-- Mitigation plan --> | <!-- Owner --> |\n\n## Quick Reference\n\n- **PRD:** <!-- link -->\n- **Roadmap:** <!-- link -->\n- **Analytics dashboard:** <!-- link -->\n- **Design files:** <!-- link -->\n- **Competitor research:** <!-- link -->\n- **Team channel:** <!-- link -->\n`\n },\n {\n name: \"Responsibilities\",\n fileName: \"responsibilities.md\",\n required: true,\n defaultContent: `# Responsibilities\n\n## Product Areas\n<!-- Products/features you own -->\n\n## Decision Authority\n<!-- What you can decide vs. escalate -->\n\n## Regular Meetings\n<!-- Recurring meetings and cadences -->\n`\n },\n {\n name: \"Stakeholders\",\n fileName: \"stakeholders.md\",\n required: false,\n defaultContent: `# Stakeholders\n\n## Engineering Leads\n<!-- Engineering partners -->\n\n## Design Partners\n<!-- Design team contacts -->\n\n## Business Stakeholders\n<!-- Sales, marketing, exec sponsors -->\n\n## Customers\n<!-- Key customer contacts or segments -->\n`\n },\n {\n name: \"Documentation\",\n fileName: \"docs.md\",\n required: false,\n defaultContent: `# Documentation References\n\n## PRDs\n<!-- Product requirement documents -->\n\n## Roadmap\n<!-- Roadmap links -->\n\n## Analytics Dashboards\n<!-- Links to dashboards -->\n`\n }\n ]\n },\n \"engineering-manager\": {\n profileType: \"engineering-manager\",\n name: \"Engineering Manager\",\n description: \"Context template for engineering managers\",\n responsibilities: [\n \"Team management and 1:1s\",\n \"Hiring and interviewing\",\n \"Performance reviews\",\n \"Technical strategy\",\n \"Cross-team coordination\",\n \"Sprint planning and velocity\",\n \"Incident management\",\n \"Budget and resource planning\",\n \"Career development coaching\",\n \"Process improvement\"\n ],\n sections: [\n {\n name: \"Overview\",\n fileName: \"overview.md\",\n required: true,\n defaultContent: `# Overview\n\n## Role\nEngineering Manager\n\n## Team\n<!-- Team name and size -->\n\n## Charter\n<!-- Team charter / mission -->\n\n## Key Systems\n<!-- Systems your team owns -->\n`\n },\n {\n name: \"Context Details\",\n fileName: \"context-details.md\",\n required: false,\n defaultContent: `# Context Details\n\n## Executive Summary\n<!-- One-paragraph overview: team mission, current priorities, headcount, key challenges -->\n\n## Key Context\n\n| Attribute | Value |\n|-----------|-------|\n| Team Size | <!-- Current headcount --> |\n| Open Roles | <!-- Positions being hired for --> |\n| Tech Domains | <!-- Systems the team owns --> |\n| Dependencies | <!-- Cross-team dependencies --> |\n| Blockers | <!-- Current blockers or risks --> |\n| Budget | <!-- Eng budget or resource constraints --> |\n\n## Timeline\n\n| Milestone | Date | Status | Owner |\n|-----------|------|--------|-------|\n| <!-- Milestone 1 --> | <!-- Date --> | <!-- On track / At risk / Done --> | <!-- Owner --> |\n| <!-- Milestone 2 --> | <!-- Date --> | <!-- Status --> | <!-- Owner --> |\n\n## Active Decisions\n\n| Decision | Options | Status | Deadline | Owner |\n|----------|---------|--------|----------|-------|\n| <!-- Decision 1 --> | <!-- A / B / C --> | <!-- Open / Decided --> | <!-- Date --> | <!-- Owner --> |\n\n## Metrics & Health\n\n| Metric | Target | Current | Trend |\n|--------|--------|---------|-------|\n| Sprint velocity | <!-- Target --> | <!-- Current --> | <!-- Trend --> |\n| Team satisfaction | <!-- Target --> | <!-- Current --> | <!-- Trend --> |\n| Attrition risk | <!-- e.g. Low --> | <!-- Current --> | <!-- Trend --> |\n| Hiring pipeline | <!-- Target fill rate --> | <!-- Current --> | <!-- Trend --> |\n\n## Communication Map\n\n| Stakeholder | Role | Channel | Cadence |\n|-------------|------|---------|---------|\n| <!-- Name --> | <!-- Role --> | <!-- Slack / Email / Meeting --> | <!-- Weekly / Ad-hoc --> |\n\n## Risk Register\n\n| Risk | Likelihood | Impact | Mitigation | Owner |\n|------|-----------|--------|------------|-------|\n| <!-- Risk 1 --> | <!-- Low / Med / High --> | <!-- Low / Med / High --> | <!-- Mitigation plan --> | <!-- Owner --> |\n\n## Quick Reference\n\n- **Team wiki:** <!-- link -->\n- **Sprint board:** <!-- link -->\n- **1:1 doc:** <!-- link -->\n- **Performance review system:** <!-- link -->\n- **Hiring tracker:** <!-- link -->\n- **Team channel:** <!-- link -->\n`\n },\n {\n name: \"Responsibilities\",\n fileName: \"responsibilities.md\",\n required: true,\n defaultContent: `# Responsibilities\n\n## People Management\n<!-- Direct reports, 1:1 cadence -->\n\n## Technical Oversight\n<!-- Architecture, code quality, tech debt -->\n\n## Process\n<!-- Agile ceremonies, team rituals -->\n\n## Hiring\n<!-- Open roles, pipeline -->\n`\n },\n {\n name: \"Stakeholders\",\n fileName: \"stakeholders.md\",\n required: false,\n defaultContent: `# Stakeholders\n\n## Direct Reports\n<!-- Team members -->\n\n## Skip Level\n<!-- Your manager -->\n\n## Product Partners\n<!-- PMs you work with -->\n\n## Peer Managers\n<!-- Other EMs -->\n`\n },\n {\n name: \"Documentation\",\n fileName: \"docs.md\",\n required: false,\n defaultContent: `# Documentation References\n\n## Team Docs\n<!-- Team wiki, confluence pages -->\n\n## Process Docs\n<!-- Runbooks, playbooks -->\n\n## HR Resources\n<!-- Performance review templates, etc. -->\n`\n }\n ]\n },\n devops: {\n profileType: \"devops\",\n name: \"DevOps Engineer\",\n description: \"Context template for DevOps engineers\",\n responsibilities: [\n \"CI/CD pipeline management\",\n \"Infrastructure as code\",\n \"Monitoring and alerting\",\n \"Incident response\",\n \"Security compliance\",\n \"Cost optimization\",\n \"Deployment automation\",\n \"Container orchestration\",\n \"Database management\",\n \"Disaster recovery planning\"\n ],\n sections: [\n {\n name: \"Overview\",\n fileName: \"overview.md\",\n required: true,\n defaultContent: `# Overview\n\n## Role\nDevOps Engineer\n\n## Infrastructure\n<!-- Cloud provider, key services -->\n\n## Key Environments\n<!-- Production, staging, dev -->\n\n## Monitoring Stack\n<!-- Tools and dashboards -->\n`\n },\n {\n name: \"Context Details\",\n fileName: \"context-details.md\",\n required: false,\n defaultContent: `# Context Details\n\n## Executive Summary\n<!-- One-paragraph overview: infrastructure scope, current priorities, reliability posture, key challenges -->\n\n## Key Context\n\n| Attribute | Value |\n|-----------|-------|\n| Cloud Provider | <!-- AWS / GCP / Azure / Multi --> |\n| Infra-as-Code | <!-- Terraform / Pulumi / CDK --> |\n| Container Runtime | <!-- k8s / ECS / Nomad --> |\n| CI/CD Platform | <!-- GitHub Actions / Jenkins / ArgoCD --> |\n| Dependencies | <!-- Shared services, vendor SLAs --> |\n| Blockers | <!-- Current blockers or risks --> |\n\n## Timeline\n\n| Milestone | Date | Status | Owner |\n|-----------|------|--------|-------|\n| <!-- Milestone 1 --> | <!-- Date --> | <!-- On track / At risk / Done --> | <!-- Owner --> |\n| <!-- Milestone 2 --> | <!-- Date --> | <!-- Status --> | <!-- Owner --> |\n\n## Active Decisions\n\n| Decision | Options | Status | Deadline | Owner |\n|----------|---------|--------|----------|-------|\n| <!-- Decision 1 --> | <!-- A / B / C --> | <!-- Open / Decided --> | <!-- Date --> | <!-- Owner --> |\n\n## Metrics & Health\n\n| Metric | Target | Current | Trend |\n|--------|--------|---------|-------|\n| Uptime (SLA) | <!-- e.g. 99.95% --> | <!-- Current --> | <!-- Trend --> |\n| MTTR | <!-- e.g. < 30 min --> | <!-- Current --> | <!-- Trend --> |\n| Deploy frequency | <!-- e.g. 10/day --> | <!-- Current --> | <!-- Trend --> |\n| Infra cost | <!-- Monthly target --> | <!-- Current --> | <!-- Trend --> |\n\n## Communication Map\n\n| Stakeholder | Role | Channel | Cadence |\n|-------------|------|---------|---------|\n| <!-- Name --> | <!-- Role --> | <!-- Slack / Email / Meeting --> | <!-- Weekly / Ad-hoc --> |\n\n## Risk Register\n\n| Risk | Likelihood | Impact | Mitigation | Owner |\n|------|-----------|--------|------------|-------|\n| <!-- Risk 1 --> | <!-- Low / Med / High --> | <!-- Low / Med / High --> | <!-- Mitigation plan --> | <!-- Owner --> |\n\n## Quick Reference\n\n- **Infra repo:** <!-- link -->\n- **Monitoring dashboard:** <!-- link -->\n- **PagerDuty:** <!-- link -->\n- **Runbooks:** <!-- link -->\n- **Cost dashboard:** <!-- link -->\n- **Incident channel:** <!-- link -->\n`\n },\n {\n name: \"Responsibilities\",\n fileName: \"responsibilities.md\",\n required: true,\n defaultContent: `# Responsibilities\n\n## Infrastructure\n<!-- IaC, cloud resources -->\n\n## CI/CD\n<!-- Pipelines, deployment processes -->\n\n## On-Call\n<!-- PagerDuty, escalation paths -->\n\n## Security\n<!-- Compliance, access management -->\n`\n },\n {\n name: \"Stakeholders\",\n fileName: \"stakeholders.md\",\n required: false,\n defaultContent: `# Stakeholders\n\n## Platform Team\n<!-- Team members -->\n\n## Engineering Teams\n<!-- Teams you support -->\n\n## Security Team\n<!-- Security contacts -->\n\n## Vendor Contacts\n<!-- Cloud, tooling vendors -->\n`\n },\n {\n name: \"Documentation\",\n fileName: \"docs.md\",\n required: false,\n defaultContent: `# Documentation References\n\n## Runbooks\n<!-- Incident response runbooks -->\n\n## Architecture Diagrams\n<!-- Infrastructure diagrams -->\n\n## Compliance Docs\n<!-- SOC2, security policies -->\n`\n }\n ]\n }\n};\nfunction getTemplate(profileType) {\n const template = PROFILE_TEMPLATES[profileType];\n if (!template) {\n throw new Error(`Unknown profile type: ${profileType}`);\n }\n return { ...template };\n}\nfunction listProfiles() {\n return Object.keys(PROFILE_TEMPLATES);\n}\nfunction getResponsibilities(profileType) {\n const template = PROFILE_TEMPLATES[profileType];\n if (!template) {\n throw new Error(`Unknown profile type: ${profileType}`);\n }\n return [...template.responsibilities];\n}\nfunction renderTemplate(template, user) {\n const files = {};\n for (const section of template.sections) {\n let content = section.defaultContent;\n content = content.replace(\"<!-- Your team name -->\", `${user.name}'s team`);\n if (section.fileName === \"responsibilities.md\" && user.responsibilities.length > 0) {\n content += \"\\n## Selected Responsibilities\\n\";\n for (const r of user.responsibilities) {\n content += `- ${r}\n`;\n }\n }\n files[section.fileName] = content;\n }\n return files;\n}\nfunction getTemplateSections(profileType) {\n const template = PROFILE_TEMPLATES[profileType];\n if (!template) {\n throw new Error(`Unknown profile type: ${profileType}`);\n }\n return template.sections.map((s) => ({ ...s }));\n}\nexport {\n getResponsibilities,\n getTemplate,\n getTemplateSections,\n listProfiles,\n renderTemplate\n};\n","export type GoogleAuthFeature = 'storage' | 'gmail' | 'gdrive';\n\nexport const GOOGLE_SCOPES_BY_FEATURE: Record<GoogleAuthFeature, string[]> = {\n storage: [\n 'https://www.googleapis.com/auth/drive.file',\n 'https://www.googleapis.com/auth/drive.readonly',\n ],\n gmail: ['https://www.googleapis.com/auth/gmail.readonly'],\n gdrive: ['https://www.googleapis.com/auth/drive.readonly'],\n};\n\nexport function getGoogleScopesForFeatures(features: GoogleAuthFeature[]): string[] {\n const scopes = new Set<string>();\n\n for (const feature of features) {\n for (const scope of GOOGLE_SCOPES_BY_FEATURE[feature]) {\n scopes.add(scope);\n }\n }\n\n return [...scopes];\n}\n\nexport function normalizeGoogleScopes(scopes: string | string[] | undefined): string[] {\n const values = Array.isArray(scopes) ? scopes : typeof scopes === 'string' ? scopes.split(/\\s+/) : [];\n return [...new Set(values.map((scope) => scope.trim()).filter(Boolean))];\n}\n\nexport function hasGoogleScopes(grantedScopes: string[], requestedScopes: string[]): boolean {\n const granted = new Set(grantedScopes);\n return requestedScopes.every((scope) => granted.has(scope));\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport type { ProfileType } from '@personal-assistant/core-types';\nimport { getTemplate, renderTemplate } from '@personal-assistant/template-engine';\n\nconst MAX_DIR_ENTRIES = 10;\nconst README_CANDIDATES = ['README.md', 'readme.md', 'README.txt', 'readme.txt'];\nconst OLLAMA_BASE_URL = 'http://127.0.0.1:11434';\nconst MAX_KNOWLEDGE_SOURCE_FILES = 8;\nconst MAX_KNOWLEDGE_SOURCE_FILE_CATALOG = 20;\nconst MAX_KNOWLEDGE_SOURCE_SNIPPET_CHARS = 1800;\nconst MAX_KNOWLEDGE_SOURCE_TOTAL_CHARS = 12000;\nconst MAX_KNOWLEDGE_SOURCE_DEPTH = 3;\nconst PDFTOTEXT_CANDIDATES = ['pdftotext', '/opt/homebrew/bin/pdftotext'];\nconst TEXTUTIL_CANDIDATES = ['/usr/bin/textutil', 'textutil'];\nconst IGNORED_KNOWLEDGE_SOURCE_DIRS = new Set([\n '.git',\n '.next',\n '.turbo',\n 'build',\n 'coverage',\n 'dist',\n 'node_modules',\n 'out',\n 'tmp',\n]);\nconst execFileAsync = promisify(execFile);\n\ninterface LocalKnowledgeEvidence {\n folderPath: string;\n notes: string[];\n excerpts: Array<{ relativePath: string; snippet: string }>;\n fileCatalog: Array<{ relativePath: string; status: string }>;\n}\n\ninterface KnowledgeSourceReadResult {\n snippet: string | null;\n status: 'sampled' | 'ocr-needed' | 'unreadable';\n}\n\nexport interface LocalFolderInput {\n path: string;\n project?: string;\n}\n\nexport interface DriveFolderInput {\n id: string;\n name: string;\n path: string;\n}\n\nexport interface InferredProject {\n slug: string;\n name: string;\n summary: string;\n primaryFocus: string;\n sourceFolders: string[];\n connectedIntegrations: string[];\n githubBranches: string[];\n gitlabBranches: string[];\n slackChannels: string[];\n gdriveFolders: string[];\n gdocDocuments: string[];\n keySignals: string[];\n llmInstructions: string;\n templateFiles: string[];\n}\n\nexport interface ProjectInferenceMeta {\n strategy: 'ollama' | 'heuristic';\n model?: string;\n note: string;\n}\n\nexport interface ProjectStructurePreview {\n files: Record<string, string>;\n projects: InferredProject[];\n inference: ProjectInferenceMeta;\n}\n\ninterface FolderSignal {\n sourceType: 'local' | 'gdrive';\n path: string;\n explicitProject?: string;\n basename: string;\n packageName?: string;\n readmeHeading?: string;\n entries: string[];\n notes: string[];\n}\n\nexport async function buildProjectStructurePreview(input: {\n profileType: ProfileType;\n name: string;\n assistantName: string;\n responsibilities: string[];\n localFolders: LocalFolderInput[];\n driveFolders?: DriveFolderInput[];\n integrations: string[];\n}): Promise<ProjectStructurePreview> {\n const baseFiles = renderTemplate(getTemplate(input.profileType), {\n name: input.name,\n assistantName: input.assistantName,\n responsibilities: input.responsibilities,\n });\n\n const localFolderSignals = await Promise.all(\n input.localFolders\n .filter((folder) => folder.path.trim())\n .map((folder) => collectFolderSignal(folder)),\n );\n const driveFolderSignals = (input.driveFolders ?? [])\n .filter((folder) => folder.path.trim())\n .map((folder) => collectDriveFolderSignal(folder));\n const folderSignals = [...localFolderSignals, ...driveFolderSignals];\n\n const heuristicProjects = buildHeuristicProjects(folderSignals, input.integrations);\n const ollamaResult = await enrichProjectsWithOllama(\n heuristicProjects,\n folderSignals,\n input.integrations,\n );\n\n const projects = ollamaResult?.projects ?? heuristicProjects;\n const inference =\n ollamaResult?.inference ?? {\n strategy: 'heuristic' as const,\n note:\n 'Structured locally from selected source folders, folder names, and visible directory signals. No external API calls were made.',\n };\n\n return {\n files: buildTemplateFiles(baseFiles, projects, folderSignals, input.integrations),\n projects,\n inference,\n };\n}\n\nexport interface KnowledgeGraphProvider {\n type: 'openai' | 'anthropic' | 'ollama';\n apiKey?: string;\n model?: string;\n}\n\nconst OPENAI_BASE_URL = 'https://api.openai.com/v1';\nconst ANTHROPIC_BASE_URL = 'https://api.anthropic.com/v1';\n\nexport interface KnowledgeGraphContext {\n userProfile?: {\n name: string;\n profileType: string;\n assistantName?: string;\n responsibilities: string[];\n };\n integrations?: string[];\n localFolders?: Array<{ path: string; project?: string }>;\n driveFolders?: Array<{ id: string; name: string; path: string }>;\n templateSections?: Array<{ name: string; fileName: string; defaultContent: string }>;\n}\n\nexport async function buildProjectKnowledgeFiles(input: {\n project: InferredProject;\n files: Record<string, string>;\n provider?: KnowledgeGraphProvider;\n userProfile?: KnowledgeGraphContext['userProfile'];\n integrations?: string[];\n localFolders?: Array<{ path: string; project?: string }>;\n driveFolders?: Array<{ id: string; name: string; path: string }>;\n templateSections?: KnowledgeGraphContext['templateSections'];\n}): Promise<{ files: Record<string, string>; model: string }> {\n const prompt = await buildKnowledgePrompt(input);\n const provider = input.provider ?? { type: 'ollama' as const };\n\n let rawJson: string;\n let modelLabel: string;\n\n if (provider.type === 'openai') {\n if (!provider.apiKey) throw new Error('OpenAI API key is required.');\n const model = provider.model || 'gpt-4.1-mini';\n modelLabel = `OpenAI ${model}`;\n\n const response = await fetch(`${OPENAI_BASE_URL}/chat/completions`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${provider.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n model,\n temperature: 0.2,\n response_format: { type: 'json_object' },\n messages: [\n { role: 'system', content: 'Return strict JSON only.' },\n { role: 'user', content: prompt },\n ],\n }),\n signal: AbortSignal.timeout(90000),\n });\n\n if (!response.ok) {\n throw new Error(`OpenAI returned HTTP ${response.status} while building project knowledge.`);\n }\n\n const data = await response.json() as {\n choices?: Array<{ message?: { content?: string } }>;\n };\n rawJson = data.choices?.[0]?.message?.content ?? '';\n } else if (provider.type === 'anthropic') {\n if (!provider.apiKey) throw new Error('Anthropic API key is required.');\n const model = provider.model || 'claude-sonnet-4-20250514';\n modelLabel = `Anthropic ${model}`;\n\n const response = await fetch(`${ANTHROPIC_BASE_URL}/messages`, {\n method: 'POST',\n headers: {\n 'x-api-key': provider.apiKey,\n 'anthropic-version': '2023-06-01',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n model,\n max_tokens: 8192,\n temperature: 0.2,\n system: 'Return strict JSON only.',\n messages: [{ role: 'user', content: prompt }],\n }),\n signal: AbortSignal.timeout(90000),\n });\n\n if (!response.ok) {\n throw new Error(`Anthropic returned HTTP ${response.status} while building project knowledge.`);\n }\n\n const data = await response.json() as {\n content?: Array<{ type: string; text?: string }>;\n };\n rawJson = data.content?.find((c) => c.type === 'text')?.text ?? '';\n } else {\n const ollamaModel = await resolveOllamaModel();\n if (!ollamaModel) {\n throw new Error('No local Ollama model is available. Start Ollama first, or configure an OpenAI / Anthropic API key.');\n }\n modelLabel = `Ollama ${ollamaModel}`;\n\n const response = await fetch(`${OLLAMA_BASE_URL}/api/generate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model: ollamaModel,\n prompt,\n stream: false,\n format: 'json',\n options: { temperature: 0.2 },\n }),\n signal: AbortSignal.timeout(120000),\n });\n\n if (!response.ok) {\n throw new Error(`Ollama returned HTTP ${response.status} while building project knowledge.`);\n }\n\n const payload = (await response.json()) as { response?: string };\n rawJson = payload.response ?? '';\n }\n\n if (!rawJson.trim()) {\n throw new Error(`${modelLabel} returned an empty response while building project knowledge.`);\n }\n\n const parsed = JSON.parse(rawJson) as { files?: Record<string, string> };\n const llmFiles = parsed.files ?? {};\n const normalizedFiles: Record<string, string> = {};\n\n // Include all originally-provided files, filling in LLM content where available\n for (const [filePath, existingContent] of Object.entries(input.files)) {\n normalizedFiles[filePath] = llmFiles[filePath]?.trim() ? llmFiles[filePath] : existingContent;\n }\n\n // Also include any NEW files the LLM created under the project slug\n const projectPrefix = `projects/${input.project.slug}/`;\n for (const [filePath, content] of Object.entries(llmFiles)) {\n if (\n normalizedFiles[filePath] === undefined &&\n content?.trim() &&\n filePath.startsWith(projectPrefix)\n ) {\n normalizedFiles[filePath] = content;\n }\n }\n\n return { files: normalizedFiles, model: modelLabel };\n}\n\nasync function buildKnowledgePrompt(input: {\n project: InferredProject;\n files: Record<string, string>;\n userProfile?: KnowledgeGraphContext['userProfile'];\n integrations?: string[];\n localFolders?: Array<{ path: string; project?: string }>;\n driveFolders?: Array<{ id: string; name: string; path: string }>;\n templateSections?: KnowledgeGraphContext['templateSections'];\n}): Promise<string> {\n const slug = input.project.slug;\n const lines: string[] = [];\n const agreementReviewMode = isAgreementReviewProject(input);\n const localKnowledgeEvidence = await collectLocalKnowledgeEvidence(\n input.project,\n input.localFolders ?? [],\n );\n\n // ── System framing ──\n lines.push(\n 'You are a project knowledge generator for a personal assistant called Pac-Man.',\n 'Your job: given a project and its context, produce richly-filled markdown files',\n `that live under the \"projects/${slug}/\" subfolder.`,\n '',\n );\n\n // ── User profile ──\n if (input.userProfile) {\n lines.push(\n '# User Profile',\n `- Name: ${input.userProfile.name}`,\n `- Role: ${input.userProfile.profileType}`,\n ...(input.userProfile.assistantName ? [`- Assistant name: ${input.userProfile.assistantName}`] : []),\n ...(input.userProfile.responsibilities.length > 0\n ? ['- Responsibilities:', ...input.userProfile.responsibilities.map((r) => ` - ${r}`)]\n : []),\n '',\n );\n }\n\n // ── Project details ──\n lines.push(\n '# Project',\n `- Name: ${input.project.name}`,\n `- Slug: ${slug}`,\n ...(input.project.summary ? [`- Summary: ${input.project.summary}`] : []),\n ...(input.project.primaryFocus ? [`- Primary Focus: ${input.project.primaryFocus}`] : []),\n );\n\n if (input.project.sourceFolders.length > 0) {\n lines.push('- Source Folders:', ...input.project.sourceFolders.map((f) => ` - ${f}`));\n }\n if (input.project.connectedIntegrations.length > 0) {\n lines.push('- Connected Integrations:', ...input.project.connectedIntegrations.map((i) => ` - ${i}`));\n }\n if (input.project.githubBranches.length > 0) {\n lines.push('- GitHub Branches:', ...input.project.githubBranches.map((b) => ` - ${b}`));\n }\n if (input.project.gitlabBranches.length > 0) {\n lines.push('- GitLab Branches:', ...input.project.gitlabBranches.map((b) => ` - ${b}`));\n }\n if (input.project.slackChannels.length > 0) {\n lines.push('- Slack Channels:', ...input.project.slackChannels.map((c) => ` - ${c}`));\n }\n if (input.project.gdriveFolders.length > 0) {\n lines.push('- GDrive Folders:', ...input.project.gdriveFolders.map((f) => ` - ${f}`));\n }\n if (input.project.gdocDocuments.length > 0) {\n lines.push('- Google Docs:', ...input.project.gdocDocuments.map((d) => ` - ${d}`));\n }\n if (input.project.keySignals.length > 0) {\n lines.push('- Key Signals:', ...input.project.keySignals.map((s) => ` - ${s}`));\n }\n if (input.project.llmInstructions) {\n lines.push('', '## LLM Instructions (follow these)', input.project.llmInstructions);\n }\n lines.push('');\n\n if (agreementReviewMode) {\n lines.push(\n '# Analysis Mode',\n 'This project is a contract / agreement review, not a software delivery project.',\n '- Prioritize agreement-by-agreement summaries, counterparties, dates, commercial terms, exclusivity, obligations, governing law, notice, renewal / termination clauses, and diligence risks.',\n '- Treat the source evidence as the primary truth. User role templates are secondary structure only.',\n '- If a template section such as tech stack, CI, deploy target, or sprint metrics is not supported by evidence, write \"Not applicable for this agreement review\" or add a TODO. Do not invent software-project details.',\n '',\n );\n }\n\n // ── Connected integrations context ──\n if (input.integrations && input.integrations.length > 0) {\n lines.push('# Workspace Integrations', ...input.integrations.map((i) => `- ${i}`), '');\n }\n\n // ── Source folders ──\n const projectLocalFolders = (input.localFolders ?? []).filter(\n (f) => f.project === input.project.name || input.project.sourceFolders.includes(f.path),\n );\n const otherLocalFolders = (input.localFolders ?? []).filter(\n (f) => !projectLocalFolders.includes(f),\n );\n if (projectLocalFolders.length > 0) {\n lines.push(\n '# Local Folders (this project)',\n ...projectLocalFolders.map((f) => `- ${f.path}`),\n '',\n );\n }\n if (otherLocalFolders.length > 0) {\n lines.push(\n '# Local Folders (other projects)',\n ...otherLocalFolders.map((f) => `- ${f.path}${f.project ? ` (${f.project})` : ''}`),\n '',\n );\n }\n\n // ── GDrive folders ──\n const projectDriveFolders = (input.driveFolders ?? []).filter(\n (f) => input.project.gdriveFolders.includes(f.name) || input.project.gdriveFolders.includes(f.path),\n );\n if (projectDriveFolders.length > 0) {\n lines.push(\n '# Google Drive Folders (this project)',\n ...projectDriveFolders.map((f) => `- ${f.name} (${f.path})`),\n '',\n );\n }\n\n if (localKnowledgeEvidence.length > 0) {\n lines.push(\n '# Local Source Evidence',\n 'Use these excerpts as primary grounding when filling in context, decisions, notes, and project-specific template files.',\n '',\n );\n\n for (const evidence of localKnowledgeEvidence) {\n lines.push(`## Folder: ${evidence.folderPath}`);\n if (evidence.notes.length > 0) {\n lines.push(...evidence.notes.map((note) => `- ${note}`));\n }\n if (evidence.fileCatalog.length > 0) {\n lines.push(\n '### File Catalog',\n ...evidence.fileCatalog.map((file) => `- ${file.relativePath} — ${file.status}`),\n );\n }\n if (evidence.excerpts.length > 0) {\n for (const excerpt of evidence.excerpts) {\n lines.push(\n `### File: ${excerpt.relativePath}`,\n '```text',\n excerpt.snippet,\n '```',\n );\n }\n } else {\n lines.push('- No readable text files were sampled from this folder.');\n }\n lines.push('');\n }\n }\n\n // ── Template sections ──\n if (input.templateSections && input.templateSections.length > 0) {\n lines.push(\n '# Base Template Sections',\n 'These are the template sections for this user role. Use them as structure for the project-specific files.',\n '',\n );\n for (const section of input.templateSections) {\n lines.push(\n `## ${section.name} (${section.fileName})`,\n '```',\n section.defaultContent,\n '```',\n '',\n );\n }\n }\n\n // ── Output instruction ──\n lines.push(\n '# Output Instructions',\n '',\n 'Return strict JSON only in this format:',\n '{\"files\":{\"projects/<slug>/filename.md\":\"# Markdown content\", ...}}',\n '',\n `All file paths MUST start with \"projects/${slug}/\".`,\n '',\n 'Required files to generate:',\n );\n\n // List the files the LLM must create\n const requiredFiles: Record<string, string> = {};\n\n // The main project file\n const projectMainPath = `projects/${slug}/project.md`;\n requiredFiles[projectMainPath] = input.files[projectMainPath] ?? '';\n lines.push(`- \"${projectMainPath}\" — the main project overview file`);\n\n if (agreementReviewMode) {\n const matrixPath = `projects/${slug}/agreement-matrix.md`;\n requiredFiles[matrixPath] =\n input.files[matrixPath] ??\n [\n '# Agreement Matrix',\n '',\n '| File | Counterparty | Agreement Type | Effective Date | Commercial Terms | Key Obligations | Exclusivity / Territory | Term / Termination | Governing Law / Dispute | Risks / Gaps | Evidence Quality |',\n '|------|--------------|----------------|----------------|------------------|-----------------|-------------------------|--------------------|------------------------|--------------|------------------|',\n '| TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO | TODO |',\n ].join('\\n');\n lines.push(`- \"${matrixPath}\" — agreement-by-agreement summary table grounded in the source files`);\n }\n\n // Template-based files in the project subfolder\n if (input.templateSections && input.templateSections.length > 0) {\n for (const section of input.templateSections) {\n const filePath = `projects/${slug}/${section.fileName}`;\n requiredFiles[filePath] = input.files[filePath] ?? section.defaultContent;\n lines.push(`- \"${filePath}\" — ${section.name} (project-specific version of the base template)`);\n }\n }\n\n // Existing template files the user added manually\n for (const [filePath, content] of Object.entries(input.files)) {\n if (!requiredFiles[filePath]) {\n requiredFiles[filePath] = content;\n lines.push(`- \"${filePath}\" — user-created schema file`);\n }\n }\n\n lines.push(\n '',\n 'Rules:',\n '- Return content for EVERY file path listed above.',\n `- You MAY also add new files under \"projects/${slug}/\" if the project context warrants it (e.g., \"projects/${slug}/runbook.md\", \"projects/${slug}/decisions.md\").`,\n '- Fill in template placeholders and HTML comments with real content derived from the project context.',\n '- Ground all content in the provided project details, source folders, integrations, branches, channels, and signals.',\n '- Use the user role and responsibilities only as secondary context for structure. Source evidence takes precedence.',\n '- If specific details are missing, add actionable TODO bullets instead of inventing facts.',\n '- Prefer concise, structured markdown. Use headings, bullets, and tables.',\n '- Follow any LLM Instructions provided in the project.',\n '- DO NOT invent repositories, tech stack, CI, deploy targets, sprint timelines, metrics, or team structure unless directly supported by evidence.',\n '- If a source file could not be read because it is scan-only or OCR is missing, explicitly say so and keep the related fields as TODO / OCR-needed.',\n ...(agreementReviewMode\n ? [\n '- For agreement review projects, summarize each agreement individually and cross-reference the file name.',\n '- Extract party names, dates, commission / fee mechanics, lead-generation flow, obligations, confidentiality, indemnity, exclusivity, customer support allocation, governing law, dispute resolution, and termination / notice periods whenever present.',\n '- If a clause is missing from the extracted evidence, mark it as not found instead of inferring it.',\n ]\n : []),\n '',\n '# Seed Files (fill these in or improve them)',\n '',\n JSON.stringify(requiredFiles, null, 2),\n );\n\n return lines.join('\\n');\n}\n\nfunction buildTemplateFiles(\n baseFiles: Record<string, string>,\n projects: InferredProject[],\n folderSignals: FolderSignal[],\n integrations: string[],\n): Record<string, string> {\n const files = { ...baseFiles };\n const integrationNames = integrations.map(formatIntegrationName);\n\n files['overview.md'] = [\n baseFiles['overview.md'] ?? '# Overview',\n '',\n '## Confirmed Project Structure',\n '',\n projects.length > 0\n ? projects\n .map((project) => `- **${project.name}** — ${project.primaryFocus || project.summary}`)\n .join('\\n')\n : '- No project groups were inferred yet. Add local folders or integrations and revisit this step.',\n ].join('\\n');\n\n const sourceLines: string[] = [];\n if (folderSignals.length > 0) {\n sourceLines.push('## Selected Sources', '');\n sourceLines.push(...folderSignals.map((signal) => `- \\`${signal.path}\\``));\n sourceLines.push('');\n }\n if (integrationNames.length > 0) {\n sourceLines.push('## Connected Integrations', '');\n sourceLines.push(...integrationNames.map((name) => `- ${name}`));\n sourceLines.push('');\n }\n if (sourceLines.length > 0) {\n files['docs.md'] = [baseFiles['docs.md'] ?? '# Documentation References', '', ...sourceLines].join(\n '\\n',\n );\n }\n\n if (integrationNames.length > 0) {\n files['integrations.md'] = [\n '# Connected Integrations',\n '',\n ...integrationNames.map((name) => `- ${name}`),\n '',\n '## Notes',\n '',\n 'These integrations are workspace-level sources. Confirm project-specific mappings after the first sync.',\n '',\n ].join('\\n');\n }\n\n for (const project of projects) {\n files[`projects/${project.slug}/project.md`] = buildProjectFile(project);\n }\n\n return files;\n}\n\nfunction buildProjectFile(project: InferredProject): string {\n return [\n `# ${project.name}`,\n '',\n '## Summary',\n '',\n project.summary || '<!-- Add a short summary for this project -->',\n '',\n '## Primary Focus',\n '',\n project.primaryFocus || '<!-- Capture the main problem area, domain, or ownership -->',\n '',\n '## Sources',\n '',\n formatBulletList(\n [...project.sourceFolders, ...project.gdriveFolders, ...project.gdocDocuments].map((item) => `\\`${item}\\``),\n 'No source folders linked to this project yet.',\n ),\n '',\n '## Connected Integrations',\n '',\n formatBulletList(\n project.connectedIntegrations,\n 'No integrations connected during onboarding.',\n ),\n '',\n '## Source Monitoring',\n '',\n '### GitHub Branches',\n '',\n formatBulletList(project.githubBranches, 'No GitHub branches scoped yet.'),\n '',\n '### GitLab Branches',\n '',\n formatBulletList(project.gitlabBranches, 'No GitLab branches scoped yet.'),\n '',\n '### Slack Channels',\n '',\n formatBulletList(project.slackChannels, 'No Slack channels scoped yet.'),\n '',\n '### Google Drive Folders',\n '',\n formatBulletList(\n project.gdriveFolders.map((folder) => `\\`${folder}\\``),\n 'No Google Drive folders scoped yet.',\n ),\n '',\n '### Google Docs',\n '',\n formatBulletList(\n project.gdocDocuments.map((document) => `\\`${document}\\``),\n 'No Google Docs scoped yet.',\n ),\n '',\n '## Grouping Signals',\n '',\n formatBulletList(project.keySignals, 'Add more details after the first sync.'),\n '',\n '## Project Context Files',\n '',\n formatBulletList(\n project.templateFiles.map((filePath) => `\\`${filePath}\\``),\n 'No project context files linked yet.',\n ),\n '',\n '## Instructions For LLM',\n '',\n project.llmInstructions || '<!-- Add project-specific instructions that the LLM should follow -->',\n '',\n '## Notes To Confirm',\n '',\n '- Owners:',\n '- Key repos/docs:',\n '- Important decisions:',\n '',\n ].join('\\n');\n}\n\nfunction formatBulletList(items: string[], fallback: string): string {\n if (items.length === 0) {\n return `- ${fallback}`;\n }\n return items.map((item) => `- ${item}`).join('\\n');\n}\n\nasync function collectLocalKnowledgeEvidence(\n project: InferredProject,\n localFolders: LocalFolderInput[],\n): Promise<LocalKnowledgeEvidence[]> {\n const projectLocalFolders = localFolders.filter((folder) => {\n const trimmedPath = folder.path.trim();\n if (!trimmedPath) {\n return false;\n }\n return folder.project === project.name || project.sourceFolders.includes(trimmedPath);\n });\n\n const evidence = await Promise.all(\n projectLocalFolders.map((folder) => collectLocalFolderKnowledgeEvidence(folder)),\n );\n\n return evidence.filter((item) => item !== null);\n}\n\nasync function collectLocalFolderKnowledgeEvidence(\n folder: LocalFolderInput,\n): Promise<LocalKnowledgeEvidence | null> {\n const rawPath = folder.path.trim();\n if (!rawPath) {\n return null;\n }\n\n const resolvedPath = path.resolve(rawPath);\n const signal = await collectFolderSignal(folder);\n const candidates: Array<{ absolutePath: string; relativePath: string; score: number }> = [];\n\n await walkKnowledgeSourceDirectory(resolvedPath, '', 0, candidates);\n\n candidates.sort((left, right) => right.score - left.score || left.relativePath.localeCompare(right.relativePath));\n\n const excerpts: Array<{ relativePath: string; snippet: string }> = [];\n const fileCatalog: Array<{ relativePath: string; status: string }> = [];\n let totalChars = 0;\n const rankedCandidates = candidates.slice(0, MAX_KNOWLEDGE_SOURCE_FILE_CATALOG);\n\n for (const candidate of rankedCandidates) {\n const result = await readKnowledgeSourceSnippet(candidate.absolutePath);\n\n fileCatalog.push({\n relativePath: candidate.relativePath,\n status:\n result.status === 'sampled'\n ? 'text extracted'\n : result.status === 'ocr-needed'\n ? 'OCR or manual review needed'\n : 'no readable text extracted',\n });\n\n if (\n result.status !== 'sampled' ||\n !result.snippet ||\n excerpts.length >= MAX_KNOWLEDGE_SOURCE_FILES ||\n totalChars >= MAX_KNOWLEDGE_SOURCE_TOTAL_CHARS\n ) {\n continue;\n }\n\n const remaining = MAX_KNOWLEDGE_SOURCE_TOTAL_CHARS - totalChars;\n const trimmedSnippet = result.snippet.slice(0, remaining);\n excerpts.push({\n relativePath: candidate.relativePath,\n snippet: trimmedSnippet,\n });\n totalChars += trimmedSnippet.length;\n }\n\n return {\n folderPath: rawPath,\n notes: signal.notes,\n excerpts,\n fileCatalog,\n };\n}\n\nasync function walkKnowledgeSourceDirectory(\n directoryPath: string,\n relativeDir: string,\n depth: number,\n candidates: Array<{ absolutePath: string; relativePath: string; score: number }>,\n): Promise<void> {\n if (depth > MAX_KNOWLEDGE_SOURCE_DEPTH) {\n return;\n }\n\n let entries: fs.Dirent[];\n try {\n entries = await fs.readdir(directoryPath, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name.startsWith('.')) {\n continue;\n }\n\n const absolutePath = path.join(directoryPath, entry.name);\n const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;\n\n if (entry.isDirectory()) {\n if (IGNORED_KNOWLEDGE_SOURCE_DIRS.has(entry.name)) {\n continue;\n }\n await walkKnowledgeSourceDirectory(absolutePath, relativePath, depth + 1, candidates);\n continue;\n }\n\n if (!entry.isFile()) {\n continue;\n }\n\n const score = scoreKnowledgeSourceFile(relativePath);\n if (score <= 0) {\n continue;\n }\n\n candidates.push({ absolutePath, relativePath, score });\n }\n}\n\nfunction scoreKnowledgeSourceFile(relativePath: string): number {\n const normalized = relativePath.toLowerCase();\n const baseName = path.basename(normalized);\n const extension = path.extname(normalized);\n\n if (!isKnowledgeSourceTextFile(baseName, extension)) {\n return 0;\n }\n\n let score = 10;\n if (baseName === 'readme.md' || baseName === 'readme.txt') {\n score += 120;\n }\n if (baseName === 'package.json') {\n score += 70;\n }\n if (/(context|overview|summary|decision|decisions|adr|spec|design|roadmap|plan|note|notes|docs|doc|requirement|brief|meeting|architecture|product|vision|status)/.test(normalized)) {\n score += 90;\n }\n if (normalized.includes('/docs/') || normalized.includes('/notes/') || normalized.includes('/decisions/')) {\n score += 40;\n }\n if (extension === '.md' || extension === '.mdx' || extension === '.txt') {\n score += 30;\n }\n if (extension === '.json' || extension === '.yaml' || extension === '.yml') {\n score += 20;\n }\n if (extension === '.docx' || extension === '.doc') {\n score += 60;\n }\n if (extension === '.pdf') {\n score += 80;\n }\n if (extension === '.xlsx' || extension === '.xls' || extension === '.csv') {\n score += 15;\n }\n if (/(agreement|contract|mou|partner|annexure|term|marketing)/.test(normalized)) {\n score += 110;\n }\n\n return score;\n}\n\nfunction isKnowledgeSourceTextFile(baseName: string, extension: string): boolean {\n if (baseName === 'package.json') {\n return true;\n }\n\n return new Set(['.md', '.mdx', '.txt', '.json', '.yaml', '.yml', '.pdf', '.xlsx', '.xls', '.csv', '.docx', '.doc']).has(extension);\n}\n\nasync function readKnowledgeSourceSnippet(filePath: string): Promise<KnowledgeSourceReadResult> {\n try {\n const extension = path.extname(filePath).toLowerCase();\n let normalized: string;\n\n if (extension === '.pdf') {\n const pdfSnippet = await extractPdfSnippet(filePath);\n if (pdfSnippet === null) {\n return {\n snippet: null,\n status: 'ocr-needed',\n };\n }\n normalized = pdfSnippet.trim();\n } else if (extension === '.docx' || extension === '.doc') {\n normalized = (await extractDocxSnippet(filePath))?.trim() ?? '';\n } else if (extension === '.xlsx' || extension === '.xls') {\n normalized = (await extractSpreadsheetSnippet(filePath))?.trim() ?? '';\n } else {\n const raw = await fs.readFile(filePath, 'utf-8');\n normalized = raw.trim();\n if (extension === '.json') {\n try {\n normalized = JSON.stringify(JSON.parse(normalized), null, 2);\n } catch {\n // keep original string if parsing fails\n }\n }\n }\n\n if (!normalized) {\n return {\n snippet: null,\n status: 'unreadable',\n };\n }\n\n return {\n snippet: normalized.slice(0, MAX_KNOWLEDGE_SOURCE_SNIPPET_CHARS),\n status: 'sampled',\n };\n } catch {\n return {\n snippet: null,\n status: 'unreadable',\n };\n }\n}\n\nasync function extractPdfSnippet(filePath: string): Promise<string | null> {\n for (const candidate of PDFTOTEXT_CANDIDATES) {\n try {\n const { stdout } = await execFileAsync(candidate, [filePath, '-'], {\n timeout: 15000,\n maxBuffer: 4 * 1024 * 1024,\n });\n const normalized = normalizeKnowledgeSourceText(stdout);\n if (normalized && !isLowSignalPdfText(normalized)) {\n return normalized;\n }\n } catch {\n // Try the next installed pdftotext binary, if any.\n }\n }\n\n return null;\n}\n\nasync function extractDocxSnippet(filePath: string): Promise<string | null> {\n for (const candidate of TEXTUTIL_CANDIDATES) {\n try {\n const { stdout } = await execFileAsync(candidate, ['-convert', 'txt', '-stdout', filePath], {\n timeout: 15000,\n maxBuffer: 4 * 1024 * 1024,\n });\n const normalized = normalizeKnowledgeSourceText(stdout);\n if (normalized) {\n return normalized;\n }\n } catch {\n // Try the next textutil binary, if any.\n }\n }\n\n return null;\n}\n\nasync function extractSpreadsheetSnippet(filePath: string): Promise<string | null> {\n try {\n const sharedStrings = await execFileAsync('unzip', ['-p', filePath, 'xl/sharedStrings.xml'], {\n timeout: 15000,\n maxBuffer: 2 * 1024 * 1024,\n });\n const normalized = normalizeKnowledgeSourceText(stripXmlTags(sharedStrings.stdout));\n if (normalized) {\n return normalized;\n }\n } catch {\n // Fall back to the workbook filename when shared strings are unavailable.\n }\n\n return `Workbook file: ${path.basename(filePath)}`;\n}\n\nfunction stripXmlTags(value: string): string {\n return value\n .replace(/<[^>]+>/g, ' ')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\nfunction normalizeKnowledgeSourceText(value: string): string {\n return value\n .replace(/\\u0000/g, ' ')\n .replace(/\\f/g, '\\n')\n .replace(/[ \\t]+\\n/g, '\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .replace(/[^\\S\\n]{2,}/g, ' ')\n .trim();\n}\n\nfunction isLowSignalPdfText(value: string): boolean {\n const normalized = value\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .trim();\n\n if (!normalized) {\n return true;\n }\n\n const withoutScannerWatermarks = normalized\n .replace(/scanned (with|by) camscanner/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n\n return withoutScannerWatermarks.length === 0;\n}\n\nfunction isAgreementReviewProject(input: {\n project: InferredProject;\n localFolders?: Array<{ path: string; project?: string }>;\n}): boolean {\n const haystack = [\n input.project.name,\n input.project.summary,\n input.project.primaryFocus,\n input.project.llmInstructions,\n ...input.project.sourceFolders,\n ...(input.localFolders ?? []).map((folder) => folder.path),\n ...input.project.keySignals,\n ]\n .join(' ')\n .toLowerCase();\n\n return /(agreement|agreements|contract|contracts|mou|due diligence|diligence|legal|partner|annexure|insurance documents|channel partner)/.test(\n haystack,\n );\n}\n\nasync function collectFolderSignal(folder: LocalFolderInput): Promise<FolderSignal> {\n const rawPath = folder.path.trim();\n const resolvedPath = path.resolve(rawPath);\n const basename = path.basename(resolvedPath);\n const notes: string[] = [];\n const entries: string[] = [];\n let packageName: string | undefined;\n let readmeHeading: string | undefined;\n\n if (folder.project?.trim()) {\n notes.push(`Tagged as \"${folder.project.trim()}\" during onboarding`);\n }\n\n try {\n const dirEntries = await fs.readdir(resolvedPath, { withFileTypes: true });\n const visibleEntries = dirEntries\n .filter((entry) => !entry.name.startsWith('.'))\n .slice(0, MAX_DIR_ENTRIES)\n .map((entry) => (entry.isDirectory() ? `${entry.name}/` : entry.name));\n\n entries.push(...visibleEntries);\n\n if (visibleEntries.length > 0) {\n notes.push(`Top entries: ${visibleEntries.slice(0, 5).join(', ')}`);\n }\n } catch {\n notes.push('Folder contents could not be read during onboarding');\n }\n\n try {\n const packageJson = await fs.readFile(path.join(resolvedPath, 'package.json'), 'utf-8');\n const parsed = JSON.parse(packageJson) as { name?: string };\n if (parsed.name?.trim()) {\n packageName = parsed.name.trim();\n notes.push(`package.json name: ${packageName}`);\n }\n } catch {\n // Ignore missing or invalid package.json\n }\n\n for (const candidate of README_CANDIDATES) {\n try {\n const readme = await fs.readFile(path.join(resolvedPath, candidate), 'utf-8');\n const heading = extractReadmeHeading(readme);\n if (heading) {\n readmeHeading = heading;\n notes.push(`README heading: ${heading}`);\n break;\n }\n } catch {\n // Ignore missing README files\n }\n }\n\n return {\n sourceType: 'local',\n path: rawPath,\n explicitProject: folder.project?.trim() || undefined,\n basename,\n packageName,\n readmeHeading,\n entries,\n notes,\n };\n}\n\nfunction collectDriveFolderSignal(folder: DriveFolderInput): FolderSignal {\n const rawPath = folder.path.trim();\n const basename =\n folder.name.trim() ||\n rawPath.split('/').filter(Boolean).pop() ||\n 'Drive Folder';\n\n return {\n sourceType: 'gdrive',\n path: rawPath,\n basename,\n entries: [],\n notes: [\n 'Google Drive folder selected during onboarding',\n `Drive path: ${rawPath}`,\n ],\n };\n}\n\nfunction extractReadmeHeading(contents: string): string | undefined {\n for (const rawLine of contents.split('\\n').slice(0, 30)) {\n const line = rawLine.trim();\n if (!line) continue;\n if (line.startsWith('#')) {\n return line.replace(/^#+\\s*/, '').trim();\n }\n if (line.length <= 80) {\n return line;\n }\n }\n return undefined;\n}\n\nfunction buildHeuristicProjects(\n folderSignals: FolderSignal[],\n integrations: string[],\n): InferredProject[] {\n const integrationNames = integrations.map(formatIntegrationName);\n const groups = new Map<string, InferredProject>();\n\n if (folderSignals.length === 0 && integrationNames.length > 0) {\n return [\n {\n slug: 'workspace-context',\n name: 'Workspace Context',\n summary:\n 'Connected integrations are ready, but no local folders were added during onboarding. Confirm the main project boundaries after the first sync.',\n primaryFocus: 'Cross-project workspace context',\n sourceFolders: [],\n connectedIntegrations: integrationNames,\n githubBranches: [],\n gitlabBranches: [],\n slackChannels: [],\n gdriveFolders: [],\n gdocDocuments: [],\n keySignals: integrationNames.map((name) => `Connected integration: ${name}`),\n llmInstructions: '',\n templateFiles: [],\n },\n ];\n }\n\n for (const signal of folderSignals) {\n const groupName = signal.explicitProject || inferProjectName(signal);\n const slug = slugify(groupName) || 'untitled-project';\n const existing = groups.get(slug);\n\n if (existing) {\n if (signal.sourceType === 'gdrive') {\n existing.gdriveFolders.push(signal.path);\n } else {\n existing.sourceFolders.push(signal.path);\n }\n existing.keySignals = unique([...existing.keySignals, ...signal.notes]);\n continue;\n }\n\n groups.set(slug, {\n slug,\n name: groupName,\n summary: buildHeuristicSummary(groupName, signal, integrationNames),\n primaryFocus: buildHeuristicFocus(signal),\n sourceFolders: signal.sourceType === 'gdrive' ? [] : [signal.path],\n connectedIntegrations: integrationNames,\n githubBranches: [],\n gitlabBranches: [],\n slackChannels: [],\n gdriveFolders: signal.sourceType === 'gdrive' ? [signal.path] : [],\n gdocDocuments: [],\n keySignals: unique(signal.notes),\n llmInstructions: '',\n templateFiles: [],\n });\n }\n\n return [...groups.values()].sort((left, right) => left.name.localeCompare(right.name));\n}\n\nfunction buildHeuristicSummary(\n projectName: string,\n signal: FolderSignal,\n integrationNames: string[],\n): string {\n const integrationSuffix =\n integrationNames.length > 0\n ? ` It will also pull from ${integrationNames.join(', ')} once sync is enabled.`\n : '';\n\n if (signal.readmeHeading) {\n return `${projectName} appears to center on \"${signal.readmeHeading}\". Review and tighten this summary before finishing setup.${integrationSuffix}`;\n }\n\n if (signal.packageName) {\n return `${projectName} was inferred from the local package \"${signal.packageName}\". Review and tighten this summary before finishing setup.${integrationSuffix}`;\n }\n\n return `${\n signal.sourceType === 'gdrive'\n ? `${projectName} was inferred from the selected Google Drive folder.`\n : `${projectName} was inferred from the selected local workspace folder.`\n } Review and tighten this summary before finishing setup.${integrationSuffix}`;\n}\n\nfunction buildHeuristicFocus(signal: FolderSignal): string {\n if (signal.sourceType === 'gdrive') {\n return `Google Drive context collected from the ${humanizeLabel(signal.basename)} folder.`;\n }\n\n if (signal.packageName) {\n return `Owns or contributes to the ${humanizeLabel(signal.packageName)} codebase.`;\n }\n\n if (signal.entries.some((entry) => entry === 'docs/' || entry.toLowerCase().includes('docs'))) {\n return 'Mix of implementation and documentation workflows.';\n }\n\n if (signal.entries.some((entry) => entry === 'src/' || entry === 'app/' || entry.endsWith('.ts'))) {\n return 'Application code, implementation details, and related project context.';\n }\n\n return `Local context collected from the ${humanizeLabel(signal.basename)} workspace folder.`;\n}\n\nfunction inferProjectName(signal: FolderSignal): string {\n if (signal.packageName) {\n return humanizeLabel(signal.packageName);\n }\n\n const basename = humanizeLabel(signal.basename);\n return basename || 'Untitled Project';\n}\n\nasync function enrichProjectsWithOllama(\n projects: InferredProject[],\n folderSignals: FolderSignal[],\n integrations: string[],\n): Promise<{ projects: InferredProject[]; inference: ProjectInferenceMeta } | null> {\n if (projects.length === 0) {\n return null;\n }\n\n const model = await resolveOllamaModel();\n if (!model) {\n return null;\n }\n\n const prompt = [\n 'You are organizing local workspace context during onboarding.',\n 'Return strict JSON only in the format:',\n '{\"projects\":[{\"slug\":\"\",\"name\":\"\",\"summary\":\"\",\"primaryFocus\":\"\",\"keySignals\":[\"\"]}]}',\n 'Rules:',\n '- Keep the existing slugs exactly as provided.',\n '- Do not invent repositories, teams, or integrations that are not in the input.',\n '- Preserve the current project grouping; do not add or remove source folders.',\n '- Summaries should be concise and grounded in the visible folder signals.',\n '- Primary focus should be a short sentence.',\n '',\n JSON.stringify(\n {\n integrations: integrations.map(formatIntegrationName),\n folders: folderSignals,\n projects,\n },\n null,\n 2,\n ),\n ].join('\\n');\n\n try {\n const response = await fetch(`${OLLAMA_BASE_URL}/api/generate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model,\n prompt,\n stream: false,\n format: 'json',\n options: {\n temperature: 0.2,\n },\n }),\n signal: AbortSignal.timeout(15000),\n });\n\n if (!response.ok) {\n return null;\n }\n\n const payload = (await response.json()) as { response?: string };\n if (!payload.response) {\n return null;\n }\n\n const parsed = JSON.parse(payload.response) as {\n projects?: Array<{\n slug?: string;\n name?: string;\n summary?: string;\n primaryFocus?: string;\n keySignals?: string[];\n }>;\n };\n\n const enrichedBySlug = new Map(\n (parsed.projects ?? [])\n .filter((project) => project.slug?.trim())\n .map((project) => [project.slug!.trim(), project]),\n );\n\n const enrichedProjects = projects.map((project) => {\n const enriched = enrichedBySlug.get(project.slug);\n if (!enriched) {\n return project;\n }\n\n return {\n ...project,\n name: enriched.name?.trim() || project.name,\n summary: enriched.summary?.trim() || project.summary,\n primaryFocus: enriched.primaryFocus?.trim() || project.primaryFocus,\n keySignals:\n enriched.keySignals?.map((signal) => signal.trim()).filter(Boolean).slice(0, 5) ??\n project.keySignals,\n };\n });\n\n return {\n projects: enrichedProjects,\n inference: {\n strategy: 'ollama',\n model,\n note: `Structured locally and enriched with Ollama (${model}). No external API calls were made.`,\n },\n };\n } catch {\n return null;\n }\n}\n\nasync function resolveOllamaModel(): Promise<string | null> {\n try {\n const response = await fetch(`${OLLAMA_BASE_URL}/api/tags`, {\n signal: AbortSignal.timeout(1500),\n });\n if (!response.ok) {\n return null;\n }\n\n const payload = (await response.json()) as {\n models?: Array<{ name?: string }>;\n };\n\n const modelNames = (payload.models ?? [])\n .map((model) => model.name?.trim() ?? '')\n .filter(Boolean);\n\n if (modelNames.length === 0) {\n return null;\n }\n\n return (\n modelNames.find((name) => /qwen|llama|mistral|gemma/i.test(name)) ??\n modelNames[0]\n );\n } catch {\n return null;\n }\n}\n\nfunction formatIntegrationName(id: string): string {\n const names: Record<string, string> = {\n slack: 'Slack',\n github: 'GitHub',\n gitlab: 'GitLab',\n gmail: 'Gmail',\n 'google-drive-storage': 'GDrive',\n gdrive: 'GDocs',\n gchat: 'Google Chat',\n };\n\n return names[id] ?? humanizeLabel(id);\n}\n\nfunction slugify(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction humanizeLabel(value: string): string {\n return value\n .replace(/[-_]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values.filter(Boolean))];\n}\n","const SLACK_BOT_SCOPES = [\n 'channels:history',\n 'channels:read',\n 'groups:history',\n 'groups:read',\n 'im:history',\n 'app_mentions:read',\n 'chat:write',\n] as const;\n\nconst SLACK_BOT_EVENTS = [\n 'message.channels',\n 'message.groups',\n 'app_mention',\n] as const;\n\nconst SLACK_LONG_DESCRIPTION =\n 'Pac-Man connects Slack threads to your local project context so every reply can reference saved notes, project summaries, folder-derived evidence, and prior decisions. It helps teams answer questions faster without losing the audit trail back to the workspace that produced the draft.';\n\nexport interface SlackManifestInput {\n assistantName?: string;\n}\n\nexport interface SlackAppManifest {\n _metadata: {\n major_version: number;\n minor_version: number;\n };\n display_information: {\n name: string;\n description: string;\n long_description: string;\n background_color: string;\n };\n features: {\n bot_user: {\n display_name: string;\n always_online: boolean;\n };\n };\n oauth_config: {\n scopes: {\n bot: string[];\n };\n };\n settings: {\n event_subscriptions: {\n bot_events: string[];\n };\n org_deploy_enabled: boolean;\n socket_mode_enabled: boolean;\n is_hosted: boolean;\n token_rotation_enabled: boolean;\n };\n}\n\nexport interface SlackManifestResult {\n appName: string;\n botDisplayName: string;\n manifest: SlackAppManifest;\n manifestJson: string;\n createUrl: string;\n}\n\nexport function buildSlackManifest(input: SlackManifestInput = {}): SlackManifestResult {\n const assistantName = normalizeAssistantName(input.assistantName);\n const appName = truncateSlackAppName(`Pac-Man ${assistantName}`);\n const botDisplayName = sanitizeSlackBotDisplayName(assistantName);\n\n const manifest: SlackAppManifest = {\n _metadata: {\n major_version: 2,\n minor_version: 1,\n },\n display_information: {\n name: appName,\n description: 'Project-aware Slack replies grounded in your Pac-Man workspace.',\n long_description: SLACK_LONG_DESCRIPTION,\n background_color: '#0B1220',\n },\n features: {\n bot_user: {\n display_name: botDisplayName,\n always_online: false,\n },\n },\n oauth_config: {\n scopes: {\n bot: [...SLACK_BOT_SCOPES],\n },\n },\n settings: {\n event_subscriptions: {\n bot_events: [...SLACK_BOT_EVENTS],\n },\n org_deploy_enabled: false,\n socket_mode_enabled: true,\n is_hosted: false,\n token_rotation_enabled: false,\n },\n };\n\n const manifestJson = JSON.stringify(manifest, null, 2);\n const createUrl = `https://api.slack.com/apps?new_app=1&manifest_json=${encodeURIComponent(manifestJson)}`;\n\n return {\n appName,\n botDisplayName,\n manifest,\n manifestJson,\n createUrl,\n };\n}\n\nfunction normalizeAssistantName(value?: string): string {\n const trimmed = value?.trim().replace(/\\s+/g, ' ') ?? '';\n return trimmed || 'Atlas';\n}\n\nfunction truncateSlackAppName(value: string): string {\n const collapsed = value.replace(/\\s+/g, ' ').trim();\n return collapsed.slice(0, 35).trimEnd() || 'Pac-Man Atlas';\n}\n\nfunction sanitizeSlackBotDisplayName(value: string): string {\n const sanitized = value\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9._-]/g, '')\n .replace(/[-_.]{2,}/g, '-')\n .replace(/^[-_.]+|[-_.]+$/g, '')\n .slice(0, 80);\n\n return sanitized || 'atlas';\n}\n"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0VT;","names":["path","fs","execFile","promisify","basename","execFileAsync","promisify","execFile"]}
|