@mukulaggarwal/pacman 0.1.0
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/README.md +39 -0
- package/dist/chunk-3QNXXON5.js +330 -0
- package/dist/chunk-3QNXXON5.js.map +1 -0
- package/dist/chunk-43PUZDIZ.js +148 -0
- package/dist/chunk-43PUZDIZ.js.map +1 -0
- package/dist/chunk-7D4SUZUM.js +38 -0
- package/dist/chunk-7D4SUZUM.js.map +1 -0
- package/dist/chunk-AYFIQNZ5.js +807 -0
- package/dist/chunk-AYFIQNZ5.js.map +1 -0
- package/dist/chunk-FH6ZHWGR.js +37 -0
- package/dist/chunk-FH6ZHWGR.js.map +1 -0
- package/dist/chunk-O6T35A4O.js +137 -0
- package/dist/chunk-O6T35A4O.js.map +1 -0
- package/dist/chunk-TRQIZP6Z.js +451 -0
- package/dist/chunk-TRQIZP6Z.js.map +1 -0
- package/dist/chunk-UWT6AFJB.js +471 -0
- package/dist/chunk-UWT6AFJB.js.map +1 -0
- package/dist/chunk-ZKKMIDRK.js +3923 -0
- package/dist/chunk-ZKKMIDRK.js.map +1 -0
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.js +141 -0
- package/dist/daemon.js.map +1 -0
- package/dist/dist-3PIJOFZ4.js +91 -0
- package/dist/dist-3PIJOFZ4.js.map +1 -0
- package/dist/dist-L76NGFFH.js +102 -0
- package/dist/dist-L76NGFFH.js.map +1 -0
- package/dist/dist-NV2YVVHI.js +178 -0
- package/dist/dist-NV2YVVHI.js.map +1 -0
- package/dist/dist-RMYCRZIU.js +41 -0
- package/dist/dist-RMYCRZIU.js.map +1 -0
- package/dist/dist-THLCZNOZ.js +14 -0
- package/dist/dist-THLCZNOZ.js.map +1 -0
- package/dist/dist-TWNHTXYH.js +95 -0
- package/dist/dist-TWNHTXYH.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +452 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-compat.d.ts +1 -0
- package/dist/mcp-compat.js +78 -0
- package/dist/mcp-compat.js.map +1 -0
- package/dist/onboarding-server.d.ts +3 -0
- package/dist/onboarding-server.js +1172 -0
- package/dist/onboarding-server.js.map +1 -0
- package/dist/provider-runtime.d.ts +11 -0
- package/dist/provider-runtime.js +10 -0
- package/dist/provider-runtime.js.map +1 -0
- package/dist/slack-listener.d.ts +49 -0
- package/dist/slack-listener.js +888 -0
- package/dist/slack-listener.js.map +1 -0
- package/dist/storage.d.ts +8 -0
- package/dist/storage.js +9 -0
- package/dist/storage.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/onboarding-server.ts","../../template-engine/dist/index.js"],"sourcesContent":["import express from 'express';\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\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 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';\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\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 // Serve static files from onboarding-web dist\n const staticPath = path.resolve(\n import.meta.dirname ?? __dirname,\n '../../../apps/onboarding-web/dist',\n );\n\n // Try to serve built static files; fallback to inline HTML\n try {\n await fs.access(staticPath);\n app.use(express.static(staticPath));\n } catch {\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/save', async (req, res) => {\n try {\n const config: AppConfig = req.body;\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 template = getTemplate(config.user.profileType);\n const files = renderTemplate(template, {\n name: config.user.name,\n assistantName: config.user.assistantName,\n responsibilities: config.user.responsibilities,\n });\n await contextManager.writeCanonicalFiles(files);\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.get('/api/pick-folder', async (_req, res) => {\n try {\n let folderPath: string;\n const platform = process.platform;\n\n if (platform === 'darwin') {\n const { stdout } = await execAsync(\n `osascript -e 'POSIX path of (choose folder with prompt \"Select a folder for your personal assistant context\")'`,\n );\n folderPath = stdout.trim();\n } else if (platform === 'linux') {\n const { stdout } = await execAsync(\n 'zenity --file-selection --directory --title=\"Select storage folder\"',\n );\n folderPath = stdout.trim();\n } else if (platform === 'win32') {\n const ps =\n '[System.Reflection.Assembly]::LoadWithPartialName(\\'System.windows.forms\\') | Out-Null; ' +\n '$f = New-Object System.Windows.Forms.FolderBrowserDialog; ' +\n '$f.Description = \\'Select a folder for your personal assistant context\\'; ' +\n '$f.ShowDialog() | Out-Null; $f.SelectedPath';\n const { stdout } = await execAsync(`powershell -command \"${ps}\"`);\n folderPath = stdout.trim();\n } else {\n res.status(400).json({ error: 'Folder picker not supported on this platform' });\n return;\n }\n\n if (!folderPath) {\n res.json({ cancelled: true });\n return;\n }\n\n res.json({ path: folderPath });\n } catch (err) {\n // osascript throws when the user clicks Cancel — treat as cancellation\n if (String(err).includes('User canceled') || String(err).includes('cancel')) {\n res.json({ cancelled: true });\n return;\n }\n res.status(500).json({ error: String(err) });\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\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/personal-assistant start <project>\n\n# Use in Codex\nAsk Codex to load or refresh your Personal Assistant 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. The legacy alias <code style=\"background:#1e293b;padding:0 4px;border-radius:3px;\">personal-assistant</code> also remains available:<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 = '…';\n btn.disabled = true;\n try {\n const res = await fetch('/api/pick-folder');\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"],"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;AAmVT;","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LlmProvider, LlmProvidersConfig, ReplyInput, DraftOutput } from '@personal-assistant/core-types';
|
|
2
|
+
|
|
3
|
+
interface ProviderValidationResult {
|
|
4
|
+
valid: boolean;
|
|
5
|
+
info?: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
declare function validateProviderConfig(provider: LlmProvider, apiKey: string, model?: string): Promise<ProviderValidationResult>;
|
|
9
|
+
declare function generateDraft(provider: LlmProvider, model: string, providers: LlmProvidersConfig | undefined, input: ReplyInput): Promise<DraftOutput>;
|
|
10
|
+
|
|
11
|
+
export { type ProviderValidationResult, generateDraft, validateProviderConfig };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { SlackEventPayload } from '@personal-assistant/integrations-slack';
|
|
2
|
+
import { AppConfig, StorageBackend, IntegrationConfig, SlackRuntimeConfig, SlackChannelMapping } from '@personal-assistant/core-types';
|
|
3
|
+
|
|
4
|
+
type RuntimeDeps = {
|
|
5
|
+
config: AppConfig;
|
|
6
|
+
storage: StorageBackend;
|
|
7
|
+
slackIntegration: IntegrationConfig;
|
|
8
|
+
slackRuntime: SlackRuntimeConfig;
|
|
9
|
+
};
|
|
10
|
+
type ProjectResolutionSource = {
|
|
11
|
+
projectName: string;
|
|
12
|
+
latestSummary: string;
|
|
13
|
+
contextText: string;
|
|
14
|
+
};
|
|
15
|
+
type ProjectResolutionCandidate = {
|
|
16
|
+
projectName: string;
|
|
17
|
+
normalizedProject: string;
|
|
18
|
+
latestSummary: string;
|
|
19
|
+
matchedNameTokens: string[];
|
|
20
|
+
matchedContextTokens: string[];
|
|
21
|
+
matchedAliasTokens: string[];
|
|
22
|
+
cosineSimilarity: number;
|
|
23
|
+
coverageScore: number;
|
|
24
|
+
aliasScore: number;
|
|
25
|
+
phraseScore: number;
|
|
26
|
+
score: number;
|
|
27
|
+
};
|
|
28
|
+
type ProjectResolutionDebug = {
|
|
29
|
+
threadText: string;
|
|
30
|
+
normalizedText: string;
|
|
31
|
+
queryTokens: string[];
|
|
32
|
+
candidates: ProjectResolutionCandidate[];
|
|
33
|
+
selectedProject?: string;
|
|
34
|
+
};
|
|
35
|
+
declare function startSlackListener(workspacePath: string): Promise<void>;
|
|
36
|
+
declare function handleSlackEvent(event: SlackEventPayload, deps: RuntimeDeps): Promise<void>;
|
|
37
|
+
declare function shouldHandleSlackEvent(event: SlackEventPayload): boolean;
|
|
38
|
+
declare function isReplyCandidate(event: SlackEventPayload, assistantName?: string): boolean;
|
|
39
|
+
declare function resolveChannelMapping(channelId: string, mappings: SlackChannelMapping[]): SlackChannelMapping | undefined;
|
|
40
|
+
declare function extractGitHubResources(text: string): Array<{
|
|
41
|
+
repo: string;
|
|
42
|
+
kind: 'issues' | 'pull';
|
|
43
|
+
number: string;
|
|
44
|
+
}>;
|
|
45
|
+
declare function extractGoogleDocIds(text: string): string[];
|
|
46
|
+
declare function resolveProjectFromText(projectNames: string[], text: string): string | undefined;
|
|
47
|
+
declare function inspectProjectResolution(sources: ProjectResolutionSource[], text: string): ProjectResolutionDebug;
|
|
48
|
+
|
|
49
|
+
export { extractGitHubResources, extractGoogleDocIds, handleSlackEvent, inspectProjectResolution, isReplyCandidate, resolveChannelMapping, resolveProjectFromText, shouldHandleSlackEvent, startSlackListener };
|