@posthog/wizard 2.76.1 → 2.78.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.
Files changed (176) hide show
  1. package/README.md +30 -15
  2. package/dist/README.md +16 -15
  3. package/dist/{add-mcp-server-to-clients-4yHaRvOo.js → add-mcp-server-to-clients-JMv8LP-O.js} +429 -114
  4. package/dist/add-mcp-server-to-clients-JMv8LP-O.js.map +1 -0
  5. package/dist/agent-bCZ3i3fh.js +3085 -0
  6. package/dist/agent-bCZ3i3fh.js.map +1 -0
  7. package/dist/{agent-interface-DPaPdIjS.js → agent-interface-BAOIHuXS.js} +452 -377
  8. package/dist/agent-interface-BAOIHuXS.js.map +1 -0
  9. package/dist/{agent-prompt-loader-BlhabNM2.js → agent-prompt-loader-7Pd4CfZO.js} +24 -8
  10. package/dist/agent-prompt-loader-7Pd4CfZO.js.map +1 -0
  11. package/dist/analytics-BcV-WCM4.js +2 -0
  12. package/dist/{analytics-DSVyjIVF.js → analytics-CHCZ_qUR.js} +10 -6
  13. package/dist/analytics-CHCZ_qUR.js.map +1 -0
  14. package/dist/{api-Ci0dZWLR.js → api-Diy_2fp8.js} +4 -17
  15. package/dist/api-Diy_2fp8.js.map +1 -0
  16. package/dist/bin.js +410 -68
  17. package/dist/bin.js.map +1 -1
  18. package/dist/{bounded-fs-FbZJ_vJ_.js → bounded-fs-Bx9zTe6m.js} +4 -4
  19. package/dist/bounded-fs-Bx9zTe6m.js.map +1 -0
  20. package/dist/check-screens.tsx +1 -1
  21. package/dist/{ci-install-CEVCqahf.js → ci-install-CDdQYsPe.js} +6 -5
  22. package/dist/ci-install-CDdQYsPe.js.map +1 -0
  23. package/dist/constants-jFI2SaE1.js +260 -0
  24. package/dist/constants-jFI2SaE1.js.map +1 -0
  25. package/dist/debug-Ch4BDOtD.js +171 -0
  26. package/dist/debug-Ch4BDOtD.js.map +1 -0
  27. package/dist/{debug-C6KWXbQi.js → debug-M2gV2iDq.js} +1 -1
  28. package/dist/{defaults-DulzMJpN.js → defaults-C6J7yL4O.js} +26 -3
  29. package/dist/defaults-C6J7yL4O.js.map +1 -0
  30. package/dist/endpoints-DCVbM06L.js +108 -0
  31. package/dist/endpoints-DCVbM06L.js.map +1 -0
  32. package/dist/{env-api-key-DwmkB3fm.js → env-api-key-Qx8NnYHm.js} +3 -3
  33. package/dist/env-api-key-Qx8NnYHm.js.map +1 -0
  34. package/dist/{environment-1wA7uwAS.js → environment-B07Bmxae.js} +6 -6
  35. package/dist/environment-B07Bmxae.js.map +1 -0
  36. package/dist/{errors--OqLxmWR.js → errors-CQ9kttJD.js} +30 -35
  37. package/dist/errors-CQ9kttJD.js.map +1 -0
  38. package/dist/{file-C3HGL1IM.js → file-BcLTjU16.js} +2 -2
  39. package/dist/{file-C3HGL1IM.js.map → file-BcLTjU16.js.map} +1 -1
  40. package/dist/{file-watcher-D8s0b-VT.js → file-watcher-DWc_bTs6.js} +2 -2
  41. package/dist/{file-watcher-D8s0b-VT.js.map → file-watcher-DWc_bTs6.js.map} +1 -1
  42. package/dist/{gateway-session-OqzCMpZ9.js → gateway-CjoShdLa.js} +175 -20
  43. package/dist/gateway-CjoShdLa.js.map +1 -0
  44. package/dist/generate-version.cjs +1 -1
  45. package/dist/{headless-ui-DRGWDg9Z.js → headless-ui-BFFmYC4v.js} +13 -2
  46. package/dist/headless-ui-BFFmYC4v.js.map +1 -0
  47. package/dist/{interactive-B6OlvhSf.js → interactive-D6zV7brJ.js} +2 -2
  48. package/dist/{interactive-B6OlvhSf.js.map → interactive-D6zV7brJ.js.map} +1 -1
  49. package/dist/{local-dev-DPZiIPCK.js → local-dev-McsurOC-.js} +2 -2
  50. package/dist/local-dev-McsurOC-.js.map +1 -0
  51. package/dist/logging-ui-_TwoMNbG.js +226 -0
  52. package/dist/logging-ui-_TwoMNbG.js.map +1 -0
  53. package/dist/mcp-DAgaoGk5.js +97 -0
  54. package/dist/mcp-DAgaoGk5.js.map +1 -0
  55. package/dist/{mcp-prompt-streaming-E1d8DJcX.js → mcp-prompt-streaming-I2U_X7BC.js} +7 -6
  56. package/dist/mcp-prompt-streaming-I2U_X7BC.js.map +1 -0
  57. package/dist/{mint-failure-C82j0RMC.js → mint-failure-D4nd2XmZ.js} +134 -48
  58. package/dist/mint-failure-D4nd2XmZ.js.map +1 -0
  59. package/dist/models-DDdBJKwT.js +83 -0
  60. package/dist/models-DDdBJKwT.js.map +1 -0
  61. package/dist/{non-interactive-DGT2H_n4.js → non-interactive-Dzow7YKY.js} +3 -3
  62. package/dist/non-interactive-Dzow7YKY.js.map +1 -0
  63. package/dist/oauth-session-DJ8h6GFa.js +74 -0
  64. package/dist/oauth-session-DJ8h6GFa.js.map +1 -0
  65. package/dist/{orchestrator-tools-BBBNV1z5.js → orchestrator-tools-szcdscwn.js} +5 -5
  66. package/dist/orchestrator-tools-szcdscwn.js.map +1 -0
  67. package/dist/{package-json-xt3eeyBI.js → package-json-DY70kkNp.js} +2 -2
  68. package/dist/package-json-DY70kkNp.js.map +1 -0
  69. package/dist/{pi-fG5fT50Y.js → pi-D3h5Ok0i.js} +329 -65
  70. package/dist/pi-D3h5Ok0i.js.map +1 -0
  71. package/dist/{playground-UFSHP-Yn.js → playground-5AB4WgNF.js} +18 -10
  72. package/dist/playground-5AB4WgNF.js.map +1 -0
  73. package/dist/{posthog-O9kKcnda.js → posthog-DNn574nW.js} +8 -3
  74. package/dist/posthog-DNn574nW.js.map +1 -0
  75. package/dist/{provisioning-B-tzjG4r.js → provisioning-B8uSqRZk.js} +6 -5
  76. package/dist/provisioning-B8uSqRZk.js.map +1 -0
  77. package/dist/{queue-tools-7Oso-fpt.js → queue-tools-9OOVx5TE.js} +11 -86
  78. package/dist/queue-tools-9OOVx5TE.js.map +1 -0
  79. package/dist/{registry-D1L5e-WQ.js → registry-8YG-kuXk.js} +265 -6
  80. package/dist/registry-8YG-kuXk.js.map +1 -0
  81. package/dist/run-agent-legacy-d7rWlzQR.js +3739 -0
  82. package/dist/run-agent-legacy-d7rWlzQR.js.map +1 -0
  83. package/dist/{security-n3-xdINN.js → security-Cg_4a7vB.js} +6 -6
  84. package/dist/security-Cg_4a7vB.js.map +1 -0
  85. package/dist/{setup-utils-Bj0gejEf.js → setup-utils-CmTCTPkX.js} +46 -18
  86. package/dist/setup-utils-CmTCTPkX.js.map +1 -0
  87. package/dist/smoke-test.sh +1 -1
  88. package/dist/{start-tui-BowrTPXm.js → start-tui-CB2PZs1x.js} +42 -48
  89. package/dist/start-tui-CB2PZs1x.js.map +1 -0
  90. package/dist/{steps-CpNTGu9N.js → steps-BZcXRJNY.js} +7 -7
  91. package/dist/{steps-CpNTGu9N.js.map → steps-BZcXRJNY.js.map} +1 -1
  92. package/dist/{store-CVkJKlny.js → store-UN7c-ASf.js} +18 -55
  93. package/dist/store-UN7c-ASf.js.map +1 -0
  94. package/dist/{subagent-SxmvfDfp.js → subagent-BofIDK-O.js} +8 -3
  95. package/dist/subagent-BofIDK-O.js.map +1 -0
  96. package/dist/{task-nF7Ry8ff.js → task-r9t1UhQP.js} +124 -36
  97. package/dist/task-r9t1UhQP.js.map +1 -0
  98. package/dist/{task-stream-C9BLiAhz.js → task-stream-CMUilu54.js} +45 -15
  99. package/dist/task-stream-CMUilu54.js.map +1 -0
  100. package/dist/{tasks-BEEVIBcT.js → tasks-Bbv_lOBG.js} +17 -13
  101. package/dist/tasks-Bbv_lOBG.js.map +1 -0
  102. package/dist/{telemetry-PD7bhcda.js → telemetry-D6ruCtnv.js} +5 -5
  103. package/dist/telemetry-D6ruCtnv.js.map +1 -0
  104. package/dist/{terminal-NhNl-BIA.js → terminal-DrGyci_a.js} +63 -94
  105. package/dist/terminal-DrGyci_a.js.map +1 -0
  106. package/dist/{tools-BBdpgcIf.js → tools-Dyfh9aCD.js} +11 -11
  107. package/dist/tools-Dyfh9aCD.js.map +1 -0
  108. package/dist/ui-BBVuTM1v.js +15 -0
  109. package/dist/ui-BBVuTM1v.js.map +1 -0
  110. package/dist/version-aXxpgRKx.js +6 -0
  111. package/dist/version-aXxpgRKx.js.map +1 -0
  112. package/dist/warlock-smoke-test.ts +2 -2
  113. package/dist/{wizard-abort-hqHF-9xD.js → wizard-abort-BBkiUxfS.js} +23 -20
  114. package/dist/wizard-abort-BBkiUxfS.js.map +1 -0
  115. package/dist/wizard-abort-BU4aLyvh.js +3 -0
  116. package/dist/{wizard-session-FSJCkTcP.js → wizard-session-2w4Ru-Wz.js} +12 -16
  117. package/dist/wizard-session-2w4Ru-Wz.js.map +1 -0
  118. package/dist/wizard-session-DGaUHOF3.js +2 -0
  119. package/dist/wizard-ui-DoyOZxK8.js +16 -0
  120. package/dist/wizard-ui-DoyOZxK8.js.map +1 -0
  121. package/dist/{yara-hooks-BaPKsm-B.js → yara-hooks-DCeMDd1o.js} +19 -68
  122. package/dist/yara-hooks-DCeMDd1o.js.map +1 -0
  123. package/dist/yara-hooks-DSGuCU9A.js +2 -0
  124. package/package.json +8 -1
  125. package/dist/add-mcp-server-to-clients-4yHaRvOo.js.map +0 -1
  126. package/dist/agent-interface-DPaPdIjS.js.map +0 -1
  127. package/dist/agent-prompt-loader-BlhabNM2.js.map +0 -1
  128. package/dist/agent-runner-JFwQQj2k.js +0 -6100
  129. package/dist/agent-runner-JFwQQj2k.js.map +0 -1
  130. package/dist/analytics-CcHoyhE_.js +0 -2
  131. package/dist/analytics-DSVyjIVF.js.map +0 -1
  132. package/dist/api-Ci0dZWLR.js.map +0 -1
  133. package/dist/bounded-fs-FbZJ_vJ_.js.map +0 -1
  134. package/dist/ci-install-CEVCqahf.js.map +0 -1
  135. package/dist/debug-DWYDVp0B.js +0 -750
  136. package/dist/debug-DWYDVp0B.js.map +0 -1
  137. package/dist/defaults-DulzMJpN.js.map +0 -1
  138. package/dist/env-api-key-DwmkB3fm.js.map +0 -1
  139. package/dist/environment-1wA7uwAS.js.map +0 -1
  140. package/dist/errors--OqLxmWR.js.map +0 -1
  141. package/dist/gateway-session-OqzCMpZ9.js.map +0 -1
  142. package/dist/gateway-session-s1xr8b48.js +0 -2
  143. package/dist/headless-ui-DRGWDg9Z.js.map +0 -1
  144. package/dist/local-dev-DPZiIPCK.js.map +0 -1
  145. package/dist/mcp-BprhJJ2c.js +0 -64
  146. package/dist/mcp-BprhJJ2c.js.map +0 -1
  147. package/dist/mcp-prompt-streaming-E1d8DJcX.js.map +0 -1
  148. package/dist/mint-failure-C82j0RMC.js.map +0 -1
  149. package/dist/non-interactive-DGT2H_n4.js.map +0 -1
  150. package/dist/orchestrator-tools-BBBNV1z5.js.map +0 -1
  151. package/dist/package-json-xt3eeyBI.js.map +0 -1
  152. package/dist/package-manager-DU3aVif4.js +0 -290
  153. package/dist/package-manager-DU3aVif4.js.map +0 -1
  154. package/dist/pi-fG5fT50Y.js.map +0 -1
  155. package/dist/playground-UFSHP-Yn.js.map +0 -1
  156. package/dist/posthog-O9kKcnda.js.map +0 -1
  157. package/dist/provisioning-B-tzjG4r.js.map +0 -1
  158. package/dist/queue-tools-7Oso-fpt.js.map +0 -1
  159. package/dist/registry-D1L5e-WQ.js.map +0 -1
  160. package/dist/security-n3-xdINN.js.map +0 -1
  161. package/dist/setup-utils-Bj0gejEf.js.map +0 -1
  162. package/dist/start-tui-BowrTPXm.js.map +0 -1
  163. package/dist/store-CVkJKlny.js.map +0 -1
  164. package/dist/subagent-SxmvfDfp.js.map +0 -1
  165. package/dist/task-nF7Ry8ff.js.map +0 -1
  166. package/dist/task-stream-C9BLiAhz.js.map +0 -1
  167. package/dist/tasks-BEEVIBcT.js.map +0 -1
  168. package/dist/telemetry-PD7bhcda.js.map +0 -1
  169. package/dist/terminal-NhNl-BIA.js.map +0 -1
  170. package/dist/tools-BBdpgcIf.js.map +0 -1
  171. package/dist/wizard-abort-D3YA1hXX.js +0 -2
  172. package/dist/wizard-abort-hqHF-9xD.js.map +0 -1
  173. package/dist/wizard-session-CYvyYnti.js +0 -2
  174. package/dist/wizard-session-FSJCkTcP.js.map +0 -1
  175. package/dist/yara-hooks-BaPKsm-B.js.map +0 -1
  176. package/dist/yara-hooks-CwfQuEl3.js +0 -2
@@ -1,9 +1,9 @@
1
- import { s as logToFile } from "./debug-DWYDVp0B.js";
2
- import { n as analytics } from "./analytics-DSVyjIVF.js";
1
+ import { s as logToFile } from "./debug-Ch4BDOtD.js";
2
+ import { n as analytics } from "./analytics-CHCZ_qUR.js";
3
3
  import fs from "fs";
4
4
  import path from "path";
5
5
  import fg from "fast-glob";
6
- //#region src/utils/bounded-fs.ts
6
+ //#region src/shared/utils/bounded-fs.ts
7
7
  /**
8
8
  * Bounded filesystem primitives for scanning USER project trees. Every
9
9
  * detection-time glob, walk, and project-file read goes through here so the
@@ -239,4 +239,4 @@ function readFileHead(filePath, bytes) {
239
239
  //#endregion
240
240
  export { safeReadFile as a, readProjectFile as i, boundedGlob as n, walkProjectFiles as o, readFileHead as r, IGNORED_DIRS as t };
241
241
 
242
- //# sourceMappingURL=bounded-fs-FbZJ_vJ_.js.map
242
+ //# sourceMappingURL=bounded-fs-Bx9zTe6m.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bounded-fs-Bx9zTe6m.js","names":[],"sources":["../src/shared/utils/bounded-fs.ts"],"sourcesContent":["/**\n * Bounded filesystem primitives for scanning USER project trees. Every\n * detection-time glob, walk, and project-file read goes through here so the\n * worst case is a constant, never a function of the user's repo.\n */\nimport path from 'path';\nimport fs from 'fs';\nimport type { Dirent } from 'fs';\nimport fg from 'fast-glob';\nimport { analytics } from './analytics';\nimport { logToFile } from './debug';\nimport type { WizardRunOptions } from './types';\n\n/**\n * Errno codes that are expected while walking an arbitrary tree and mean\n * \"skip this entry\", not \"something is broken\". Scanning from a broad dir\n * (e.g. `~`) routinely hits OS-protected paths (macOS `Library/Group\n * Containers/group.com.apple.*`) that throw EPERM/EACCES per entry — capturing\n * each as an exception buried real errors under thousands of noise events.\n */\nconst BENIGN_FS_ERROR_CODES = new Set<string>([\n 'EACCES', // permission denied\n 'EPERM', // operation not permitted (macOS-protected dirs)\n 'ENOENT', // entry vanished mid-walk\n 'ENOTDIR', // path component isn't a directory\n 'ELOOP', // symlink loop\n 'ENAMETOOLONG', // path too long\n 'EMFILE', // too many open files (environmental, not a wizard bug)\n 'ENFILE',\n]);\n\n/**\n * Report a swallowed filesystem error. Traversal stays best-effort — the caller\n * still skips the failing entry. Expected errno codes (permission denied, entry\n * vanished, symlink loops…) are logged to the debug file only; anything else is\n * genuinely unexpected and gets captured to error tracking. Preserves the\n * original Error (and its `code`, e.g. EACCES / ENOENT) when available.\n */\nfunction reportFsError(step: string, filePath: string, error: unknown): void {\n const code = (error as NodeJS.ErrnoException | null)?.code;\n if (code && BENIGN_FS_ERROR_CODES.has(code)) {\n logToFile(`[bounded-fs] skipped ${step} (${code}): ${filePath}`);\n return;\n }\n analytics.captureException(\n error instanceof Error ? error : new Error(String(error)),\n { step, path: filePath },\n );\n}\n\nexport function getDotGitignore({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>) {\n const gitignorePath = path.join(installDir, '.gitignore');\n const gitignoreExists = fs.existsSync(gitignorePath);\n\n if (gitignoreExists) {\n return gitignorePath;\n }\n\n return undefined;\n}\n\n/**\n * Directory names to skip when scanning a project tree — dependency\n * directories, build output, virtual environments, vendored trees.\n * Used verbatim by walkProjectFiles and as glob patterns by boundedGlob.\n */\nexport const IGNORED_DIRS = new Set<string>([\n 'node_modules',\n '.git',\n '.next',\n '.nuxt',\n '.svelte-kit',\n '.turbo',\n '.cache',\n '.parcel-cache',\n 'dist',\n 'build',\n 'out',\n 'coverage',\n '.coverage',\n 'venv',\n '.venv',\n '__pycache__',\n '.pytest_cache',\n 'vendor',\n 'target',\n '.gradle',\n '.idea',\n '.vscode',\n 'site-packages',\n 'DerivedData',\n 'Pods',\n]);\n\n/** IGNORED_DIRS as fast-glob ignore patterns. */\nexport const PROJECT_IGNORE_GLOBS: readonly string[] = [...IGNORED_DIRS].map(\n (dir) => `**/${dir}/**`,\n);\n\n// Files larger than this are skipped, never materialized.\nexport const MAX_PROJECT_FILE_BYTES = 2 * 1024 * 1024;\n\n// A glob returns at most this many entries.\nexport const MAX_GLOB_MATCHES = 500;\n\n// A glob's traversal is destroyed after this long, even when abandoned.\nexport const GLOB_DEADLINE_MS = 8_000;\n\n// A directory contributes at most this many entries to a walk.\nexport const MAX_DIR_ENTRIES = 10_000;\n\n// A walk fires at most this many onFile callbacks.\nexport const MAX_WALK_FILES = 100_000;\n\nexport interface BoundedGlobOptions {\n cwd: string;\n /** Appended to PROJECT_IGNORE_GLOBS. */\n extraIgnore?: readonly string[];\n /** Stop after this many matches. Defaults to MAX_GLOB_MATCHES. */\n limit?: number;\n /** Match dotfiles. Traversal of dot-DIRECTORIES stays blocked by the ignore set. */\n dot?: boolean;\n /** fast-glob `deep` — maximum directory depth. */\n deep?: number;\n}\n\n/**\n * Streams matches, stops at `limit`, destroys the crawl at GLOB_DEADLINE_MS.\n * Returns paths relative to `cwd`, possibly truncated.\n */\nexport async function boundedGlob(\n patterns: string | string[],\n options: BoundedGlobOptions,\n): Promise<string[]> {\n const limit = options.limit ?? MAX_GLOB_MATCHES;\n const stream = fg.stream(patterns, {\n cwd: options.cwd,\n dot: options.dot ?? false,\n onlyFiles: true,\n deep: options.deep,\n ignore: [...PROJECT_IGNORE_GLOBS, ...(options.extraIgnore ?? [])],\n suppressErrors: true,\n followSymbolicLinks: false,\n }) as NodeJS.ReadableStream & { destroy(): void };\n\n const matches: string[] = [];\n return new Promise((resolve) => {\n let settled = false;\n const finish = (): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(matches);\n };\n const timer = setTimeout(() => {\n stream.destroy();\n finish();\n }, GLOB_DEADLINE_MS);\n stream.on('data', (entry: string | Buffer) => {\n matches.push(String(entry));\n if (matches.length >= limit) {\n stream.destroy();\n finish();\n }\n });\n stream.once('error', finish);\n stream.once('end', finish);\n stream.once('close', finish);\n });\n}\n\n/**\n * Walk a project tree, invoking `onFile(name, fullPath)` for every regular\n * file — including dotfiles like `.env` (the caller decides what it cares\n * about). Skips `IGNORED_DIRS` and hidden directories, follows symlinked\n * directories with realpath-based loop protection, descends at most\n * `maxDepth` levels below `rootDir`, and stops at the per-directory and\n * whole-walk caps. Filesystem errors are reported and skipped (best-effort).\n */\nexport function walkProjectFiles(\n rootDir: string,\n onFile: (name: string, fullPath: string) => void,\n maxDepth = 3,\n): void {\n const visited = new Set<string>();\n let filesSeen = 0;\n // Explicit stack — no call-stack recursion.\n const stack: Array<{ dir: string; depth: number }> = [\n { dir: rootDir, depth: 0 },\n ];\n\n while (stack.length > 0 && filesSeen < MAX_WALK_FILES) {\n const { dir, depth } = stack.pop()!;\n\n // realpath both resolves symlinked dirs and gives us a stable key to\n // detect loops (symlink cycles, e.g. a -> ../a).\n let realDir: string;\n try {\n realDir = fs.realpathSync(dir);\n } catch (error) {\n reportFsError('walkProjectFiles.realpath', dir, error);\n continue;\n }\n if (visited.has(realDir)) continue;\n visited.add(realDir);\n\n let handle: fs.Dir;\n try {\n handle = fs.opendirSync(dir);\n } catch (error) {\n reportFsError('walkProjectFiles.opendir', dir, error);\n continue;\n }\n try {\n let entriesRead = 0;\n let entry: Dirent | null;\n while ((entry = handle.readSync()) !== null) {\n if (++entriesRead > MAX_DIR_ENTRIES || filesSeen >= MAX_WALK_FILES) {\n logToFile(\n `[bounded-fs] walk capped in ${dir} (entries=${entriesRead}, files=${filesSeen})`,\n );\n break;\n }\n if (IGNORED_DIRS.has(entry.name)) continue;\n\n const fullPath = path.join(dir, entry.name);\n\n // Symlinks report isDirectory()/isFile() as false under withFileTypes,\n // so resolve the target before deciding how to handle the entry.\n let isDir = entry.isDirectory();\n let isFile = entry.isFile();\n if (entry.isSymbolicLink()) {\n try {\n const st = fs.statSync(fullPath);\n isDir = st.isDirectory();\n isFile = st.isFile();\n } catch (error) {\n reportFsError('walkProjectFiles.stat', fullPath, error);\n continue;\n }\n }\n\n if (isDir) {\n if (entry.name.startsWith('.')) continue; // skip hidden directories\n if (depth < maxDepth) stack.push({ dir: fullPath, depth: depth + 1 });\n } else if (isFile) {\n filesSeen += 1;\n onFile(entry.name, fullPath);\n }\n }\n } finally {\n try {\n handle.closeSync();\n } catch {\n /* already closed */\n }\n }\n }\n}\n\n/**\n * Read a project file as UTF-8, or null when missing, unreadable, or over\n * `maxBytes` (stat-gated: an oversized file is never materialized).\n */\nexport function readProjectFile(\n filePath: string,\n maxBytes = MAX_PROJECT_FILE_BYTES,\n): string | null {\n try {\n if (fs.statSync(filePath).size > maxBytes) return null;\n return fs.readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * `readProjectFile` that also reports unexpected errors to error tracking.\n * For walk callbacks where a failing read is worth a telemetry breadcrumb.\n */\nexport function safeReadFile(fullPath: string): string | null {\n try {\n if (fs.statSync(fullPath).size > MAX_PROJECT_FILE_BYTES) {\n logToFile(`[bounded-fs] skipped oversized file: ${fullPath}`);\n return null;\n }\n return fs.readFileSync(fullPath, 'utf-8');\n } catch (error) {\n reportFsError('safeReadFile', fullPath, error);\n return null;\n }\n}\n\n/**\n * The first `bytes` of a file without materializing the rest.\n */\nexport function readFileHead(filePath: string, bytes: number): string | null {\n try {\n const fd = fs.openSync(filePath, 'r');\n try {\n const buffer = Buffer.alloc(bytes);\n const read = fs.readSync(fd, buffer, 0, bytes, 0);\n return buffer.toString('utf-8', 0, read);\n } finally {\n fs.closeSync(fd);\n }\n } catch {\n return null;\n }\n}\n"],"mappings":"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"}
@@ -15,7 +15,7 @@ import { ProgressList } from '@ui/tui/primitives/ProgressList';
15
15
  import { ManagedSettingsScreen } from '@ui/tui/screens/ManagedSettingsScreen';
16
16
  import { SettingsOverrideScreen } from '@ui/tui/screens/SettingsOverrideScreen';
17
17
  import { WizardAskScreen } from '@ui/tui/screens/WizardAskScreen';
18
- import type { SettingsConflict } from '@lib/agent/agent-interface';
18
+ import type { SettingsConflict } from '@agent/agent-interface';
19
19
 
20
20
  function fakeStore(session: Record<string, unknown>): any {
21
21
  return {
@@ -1,7 +1,8 @@
1
- import { d as ErrorCodes, u as emitWizardError } from "./errors--OqLxmWR.js";
2
- import { h as LoggingUI, m as setUI, p as getUI } from "./debug-DWYDVp0B.js";
3
- import { n as provisionNewAccount } from "./provisioning-B-tzjG4r.js";
4
- import { X as posthogIntegrationConfig } from "./mint-failure-C82j0RMC.js";
1
+ import { d as ErrorCodes, u as emitWizardError } from "./errors-CQ9kttJD.js";
2
+ import { t as LoggingUI } from "./logging-ui-_TwoMNbG.js";
3
+ import { n as setUI, t as getUI } from "./ui-BBVuTM1v.js";
4
+ import { n as provisionNewAccount } from "./provisioning-B8uSqRZk.js";
5
+ import { X as posthogIntegrationConfig } from "./mint-failure-D4nd2XmZ.js";
5
6
  import { c as runWizardHeadless, l as runWizardCI, u as API_KEY_HINT } from "./bin.js";
6
7
  //#region src/commands/basic-integration/ci-install.ts
7
8
  /**
@@ -116,4 +117,4 @@ async function provisionForSignup(options) {
116
117
  //#endregion
117
118
  export { runCIInstall, runHeadlessInstall };
118
119
 
119
- //# sourceMappingURL=ci-install-CEVCqahf.js.map
120
+ //# sourceMappingURL=ci-install-CDdQYsPe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci-install-CDdQYsPe.js","names":[],"sources":["../src/commands/basic-integration/ci-install.ts"],"sourcesContent":["import type { Arguments } from 'yargs';\nimport { getUI, setUI } from '@ui';\nimport { LoggingUI } from '@ui/logging-ui';\nimport { API_KEY_HINT, runWizardCI, runWizardHeadless } from '@lib/runners';\nimport type { NonInteractiveMode } from '@lib/runners';\nimport { provisionNewAccount } from '@utils/provisioning';\nimport { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index';\nimport { ErrorCodes, type ErrorCode } from '@shared/errors';\nimport { emitWizardError } from '@shared/errors';\n\ntype Options = Arguments & {\n region?: string;\n baseUrl?: string;\n installDir?: string;\n apiKey?: string;\n signup?: boolean;\n email?: string;\n name?: string;\n projectId?: string;\n};\n\n/**\n * CI-mode install entry point (`--ci`, dev/test builds). Thin shell over the\n * shared non-interactive install — see `runNonInteractiveInstall`.\n */\nexport function runCIInstall(argv: Arguments): void {\n runNonInteractiveInstall(argv, 'ci');\n}\n\n/**\n * Headless install entry point (the experimental published-build run path; see\n * @lib/headless-mode). Thin shell over the shared non-interactive install.\n * Today it behaves exactly like `runCIInstall`; it is a separate function so\n * headless can diverge later (auth, prompts, …) without touching the CI path.\n */\nexport function runHeadlessInstall(argv: Arguments): void {\n runNonInteractiveInstall(argv, 'headless');\n}\n\n/**\n * Non-interactive install shared by CI and headless. Validates signup flags,\n * optionally provisions an account, then installs. `mode` only changes\n * user-facing labels and which runner is invoked; the accepted keys and the\n * install itself are identical (see runNonInteractive).\n */\nfunction runNonInteractiveInstall(\n argv: Arguments,\n mode: NonInteractiveMode,\n): void {\n const options = { ...argv } as Options;\n const headless = mode === 'headless';\n const label = headless ? 'Headless' : 'CI';\n const runWizard = headless ? runWizardHeadless : runWizardCI;\n\n // Base validation (region/install-dir/api-key) is owned by the runner.\n // This layer only adds the signup branch on top.\n if (!options.apiKey && !options.signup) {\n return failCI(\n `${label} mode requires --api-key (${API_KEY_HINT}). ` +\n 'To create a new account instead, use --signup --email you@example.com.',\n ErrorCodes.ArgsMissingApiKey,\n );\n }\n if (!options.apiKey && options.signup && !options.email) {\n return failCI(\n `${label} --signup requires --email to create a new account.`,\n ErrorCodes.ArgsMissingEmail,\n );\n }\n warnOnUnexpectedKeyPrefix(options.apiKey);\n\n void (async () => {\n if (!options.apiKey && options.signup) {\n // Fail before the irreversible provisioning step rather than after it.\n if (!options.installDir) {\n return failCI(\n `${label} mode requires --install-dir (directory to install in)`,\n ErrorCodes.ArgsMissingInstallDir,\n );\n }\n const provisioned = await provisionForSignup(options);\n options.apiKey = provisioned.personalApiKey;\n if (options.projectId == null) options.projectId = provisioned.projectId;\n }\n runWizard(posthogIntegrationConfig, options);\n })().catch((error: unknown) => {\n emitWizardError({\n code: ErrorCodes.ArgsSignupProvisionFailed,\n message: error instanceof Error ? error.message : String(error),\n });\n process.exit(1);\n });\n}\n\nfunction failCI(message: string, code?: ErrorCode): void {\n setUI(new LoggingUI());\n getUI().intro('PostHog Wizard');\n getUI().log.error(message);\n if (code) emitWizardError({ code, message });\n process.exit(1);\n}\n\n/**\n * Decide whether to warn about an unexpected `--api-key` prefix, and with what\n * message. Returns `null` when the key is acceptable.\n *\n * CI and headless accept the same two credentials: a personal API key (`phx_`)\n * and a `pha_` OAuth access token minted under the wizard's own OAuth\n * application (cloud runs, and the CI bot). Both authenticate the mint the\n * same way. Anything else is unexpected and warns.\n *\n * Extracted as a pure predicate so it can be unit-tested without a UI.\n */\nexport function keyPrefixWarning(apiKey: string | undefined): string | null {\n if (!apiKey || apiKey.startsWith('phx_') || apiKey.startsWith('pha_')) {\n return null;\n }\n const hint = apiKey.startsWith('phc_')\n ? ' (phc_ is a project/client key; expected a personal API key or a wizard-app token)'\n : '';\n return `--api-key does not start with \"phx_\" or \"pha_\"${hint}. Continuing anyway, but the LLM Gateway may reject it with a 401.`;\n}\n\nfunction warnOnUnexpectedKeyPrefix(apiKey: string | undefined): void {\n const message = keyPrefixWarning(apiKey);\n if (!message) return;\n setUI(new LoggingUI());\n getUI().intro('PostHog Wizard');\n getUI().log.warn(message);\n}\n\n/**\n * Provision a new account and return its credentials. Throws on any failure\n * (after logging a user-facing message); the caller's `.catch` turns that\n * into a non-zero exit. The return type carries no failure sentinel.\n */\nasync function provisionForSignup(\n options: Options,\n): Promise<{ personalApiKey: string; projectId: string }> {\n setUI(new LoggingUI());\n getUI().intro('PostHog Wizard');\n const signupRegion = ((options.region as string) || 'us').toUpperCase() as\n | 'US'\n | 'EU';\n getUI().log.info(\n `Provisioning new PostHog account for ${String(\n options.email,\n )} in ${signupRegion}...`,\n );\n\n let result;\n try {\n result = await provisionNewAccount(\n options.email as string,\n options.name ?? '',\n signupRegion,\n { baseUrl: options.baseUrl },\n );\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n getUI().log.error(`Provisioning failed: ${msg}`);\n throw error;\n }\n\n if (!result.personalApiKey) {\n getUI().log.error(\n 'Provisioning succeeded but no personal API key was returned — cannot continue install.',\n );\n throw new Error('provisioning returned no personal API key');\n }\n\n getUI().log.success('Account ready.');\n getUI().log.info(` Project API Key: ${result.projectApiKey}`);\n getUI().log.info(` Personal API Key: ${result.personalApiKey}`);\n getUI().log.info(` Host: ${result.host}`);\n return {\n personalApiKey: result.personalApiKey,\n projectId: result.projectId,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,260 @@
1
+ import "./debug-Ch4BDOtD.js";
2
+ import { t as VERSION } from "./version-aXxpgRKx.js";
3
+ import { a as getLocalDev, t as CONTEXT_MILL_LOCAL_URL } from "./local-dev-McsurOC-.js";
4
+ //#region src/shared/constants.ts
5
+ /**
6
+ * Shared constants for the PostHog wizard.
7
+ */
8
+ /** Next sonnet generation (a `MODEL_FLAG_VARIANTS` key in the switchboard). */
9
+ const SONNET_5_MODEL = "claude-sonnet-5";
10
+ /**
11
+ * Default model for agent runs. Bare model IDs (no `anthropic/` prefix) so the
12
+ * LLM gateway's Bedrock fallback can match map_to_bedrock_model().
13
+ */
14
+ const DEFAULT_AGENT_MODEL = SONNET_5_MODEL;
15
+ /** Undated haiku, for scan triage. The alias tracks the current 4.5 release rather than pinning one. */
16
+ const HAIKU_TRIAGE_MODEL = "claude-haiku-4-5";
17
+ /**
18
+ * Cheaper, faster model for mechanical agent work (e.g. repo classification
19
+ * during source-map detection). Passed via AgentConfig.modelOverride.
20
+ */
21
+ const HAIKU_MODEL = HAIKU_TRIAGE_MODEL;
22
+ const GPT5_6_LUNA_MODEL = "openai/gpt-5.6-luna";
23
+ const GPT5_6_TERRA_MODEL = "openai/gpt-5.6-terra";
24
+ const GPT5_6_SOL_MODEL = "openai/gpt-5.6-sol";
25
+ /**
26
+ * The two agent runner routing axes: **harness** (which agent SDK drives the LLM)
27
+ * and **sequence** (which pipeline shape orchestrates the work). Single source
28
+ * of truth for yargs `choices`, session fields, the runner registry, and tests
29
+ * — `Object.values(Harness)` gives an iterable of the values when an array is
30
+ * needed. Adding a member is enough to pick it up everywhere.
31
+ *
32
+ * Naming matches the directory layout — see `src/agent/runner/harness/`
33
+ * and `src/agent/runner/sequence/`.
34
+ */
35
+ let Harness = /* @__PURE__ */ function(Harness) {
36
+ Harness["anthropic"] = "anthropic";
37
+ Harness["pi"] = "pi";
38
+ return Harness;
39
+ }({});
40
+ let Sequence = /* @__PURE__ */ function(Sequence) {
41
+ Sequence["linear"] = "linear";
42
+ Sequence["orchestrator"] = "orchestrator";
43
+ return Sequence;
44
+ }({});
45
+ /**
46
+ * Detection order matters: put framework-specific integrations BEFORE basic language fallbacks.
47
+ */
48
+ let Integration = /* @__PURE__ */ function(Integration) {
49
+ Integration["nextjs"] = "nextjs";
50
+ Integration["nuxt"] = "nuxt";
51
+ Integration["vue"] = "vue";
52
+ Integration["reactRouter"] = "react-router";
53
+ Integration["tanstackStart"] = "tanstack-start";
54
+ Integration["tanstackRouter"] = "tanstack-router";
55
+ Integration["reactNative"] = "react-native";
56
+ Integration["angular"] = "angular";
57
+ Integration["astro"] = "astro";
58
+ Integration["django"] = "django";
59
+ Integration["flask"] = "flask";
60
+ Integration["fastapi"] = "fastapi";
61
+ Integration["laravel"] = "laravel";
62
+ Integration["sveltekit"] = "sveltekit";
63
+ Integration["flutter"] = "flutter";
64
+ Integration["kmp"] = "kmp";
65
+ Integration["swift"] = "swift";
66
+ Integration["android"] = "android";
67
+ Integration["rails"] = "rails";
68
+ Integration["elixir"] = "elixir";
69
+ Integration["go"] = "go";
70
+ Integration["rust"] = "rust";
71
+ Integration["java"] = "java";
72
+ Integration["python"] = "python";
73
+ Integration["ruby"] = "ruby";
74
+ Integration["javascript_web"] = "javascript_web";
75
+ Integration["javascriptNode"] = "javascript_node";
76
+ return Integration;
77
+ }({});
78
+ /** The events-audit report. */
79
+ const EVENTS_AUDIT_REPORT_FILE = "posthog-events-audit-report.md";
80
+ const EVENT_INVENTORY_FILE = ".posthog-events-inventory.json";
81
+ /** Per-part filename pattern emitted by events-audit subagents (e.g. `.posthog-events-inventory.part-3.json`). */
82
+ const EVENT_INVENTORY_PART_PATTERN = /^\.posthog-events-inventory\.part-\d+\.json$/;
83
+ /** The integration program's event plan. */
84
+ const EVENT_PLAN_FILE = ".posthog-events.json";
85
+ /**
86
+ * Region-agnostic PostHog app URL. Resolves to us.posthog.com or
87
+ * eu.posthog.com server-side based on the signed-in user's profile.
88
+ * Use this for share-with-user links (e.g. settings pages) so they
89
+ * land on the right region without us needing to know it client-side.
90
+ */
91
+ const POSTHOG_APP_URL = "https://app.posthog.com";
92
+ const ISSUES_URL = "https://github.com/posthog/wizard/issues";
93
+ /** Public status page, linked from transient-failure guidance (e.g. OAuth server_error). */
94
+ const POSTHOG_STATUS_PAGE_URL = "https://www.posthogstatus.com";
95
+ const CONTEXT_MILL_URL = "https://github.com/PostHog/context-mill";
96
+ /**
97
+ * Latest context-mill release page — the BYOAI download link shown in
98
+ * the privacy panel. Deliberately the release PAGE, not a direct asset
99
+ * URL: asset URLs are ~89 chars and hard-wrap inside the 64-col panel,
100
+ * which corrupts terminal copy/paste with a mid-URL line break. This
101
+ * stays under one line; the panel names the exact asset to grab.
102
+ */
103
+ const CONTEXT_MILL_RELEASES_URL = "https://github.com/PostHog/context-mill/releases/latest";
104
+ const POSTHOG_DOCS_URL = "https://posthog.com/docs";
105
+ const POSTHOG_TERMS_URL = "https://posthog.com/terms";
106
+ const POSTHOG_PRIVACY_URL = "https://posthog.com/privacy";
107
+ const POSTHOG_ORG_AI_SETTINGS_URL = "https://app.posthog.com/settings/organization-details#setting=organization-ai-consent";
108
+ const WIZARD_CONTACT_EMAIL = "wizard@posthog.com";
109
+ /**
110
+ * Two origins for the same release, same filenames. Interchangeable bases, so
111
+ * making AWS primary is a `getSkillsBaseUrl` change, not a code change.
112
+ */
113
+ const GITHUB_SKILLS_BASE_URL = "https://github.com/PostHog/context-mill/releases/latest/download";
114
+ const AWS_SKILLS_BASE_URL = "https://context-mill.posthog.com/latest";
115
+ /** Alias of `@lib/local-dev`'s constant, kept for existing importers. */
116
+ const LOCAL_SKILLS_BASE_URL = CONTEXT_MILL_LOCAL_URL;
117
+ /**
118
+ * Driven by `--local-context-mill`, NOT `--local-mcp` (which used to select
119
+ * both). Takes no argument on purpose: callers can't pass the wrong flag.
120
+ */
121
+ function getSkillsBaseUrl() {
122
+ return getLocalDev().localContextMill ? LOCAL_SKILLS_BASE_URL : GITHUB_SKILLS_BASE_URL;
123
+ }
124
+ const ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY = "sTMFPsFhdP1Ssg";
125
+ const ANALYTICS_HOST_URL = "https://internal-j.posthog.com";
126
+ const ANALYTICS_TEAM_TAG = "docs-and-wizard";
127
+ const OAUTH_PORTS = [
128
+ 8239,
129
+ 8238,
130
+ 8240,
131
+ 8237,
132
+ 8236,
133
+ 8235
134
+ ];
135
+ const POSTHOG_US_CLIENT_ID = "c4Rdw8DIxgtQfA80IiSnGKlNX8QN00cFWF00QQhM";
136
+ const POSTHOG_EU_CLIENT_ID = "bx2C5sZRN03TkdjraCcetvQFPGH6N2Y9vRLkcKEy";
137
+ const POSTHOG_DEV_CLIENT_ID = "DC5uRLVbGI02YQ82grxgnK6Qn12SXWpCqdPb60oZ";
138
+ const POSTHOG_PROXY_CLIENT_ID = POSTHOG_US_CLIENT_ID;
139
+ const DUMMY_PROJECT_API_KEY = "_YOUR_POSTHOG_PROJECT_TOKEN_";
140
+ /**
141
+ * Scopes the wizard requests during the agentic provisioning signup flow.
142
+ *
143
+ * Each entry is justified by what the wizard's agent step does after signup:
144
+ * - user:read identify the user for analytics + agent context
145
+ * - project:read look up the freshly-provisioned project
146
+ * - llm_gateway:read authenticate to gateway.{us,eu}.posthog.com/wizard
147
+ * (the agent's LLM calls — without this scope, every
148
+ * agent message returns 401)
149
+ * - query:read run HogQL queries when the agent needs data
150
+ * - dashboard:write create the onboarding dashboard during setup
151
+ * - insight:write create the onboarding insights during setup
152
+ * - notebook:write upload the events-audit report as a PostHog notebook
153
+ * in step 6 of the events-audit skill (notebooks-create
154
+ * MCP tool requires this scope)
155
+ * - event_definition:write
156
+ * create event definitions from the completed wizard
157
+ * session's event plan
158
+ *
159
+ * Must be a subset of `ALLOWED_PROVISIONING_SCOPES` in
160
+ * `ee/api/agentic_provisioning/views.py` on the backend.
161
+ */
162
+ const WIZARD_PROVISIONING_SCOPES = [
163
+ "user:read",
164
+ "project:read",
165
+ "llm_gateway:read",
166
+ "dashboard:write",
167
+ "insight:write",
168
+ "query:read",
169
+ "notebook:write",
170
+ "event_definition:write"
171
+ ];
172
+ /**
173
+ * Scopes the wizard requests during the OAuth login flow. Superset of
174
+ * `WIZARD_PROVISIONING_SCOPES` with scopes that only apply to the login
175
+ * path and are not in the provisioning allowlist:
176
+ * - health_issue:read used by `wizard doctor`
177
+ * - wizard_session:read list / retrieve / stream sessions
178
+ * - wizard_session:write stream run state to /api/projects/{id}/wizard/sessions/
179
+ * - event_definition:write
180
+ * create event definitions when a session completes
181
+ * - organization:read read `organization.is_ai_data_processing_approved`
182
+ * from /api/users/@me/ for the AI opt-in gate
183
+ *
184
+ * NOTE: every scope here must be within the wizard OAuth application's
185
+ * server-side scope ceiling (`OAuthApplication.scopes` in posthog, set
186
+ * via Django admin on BOTH prod regions). A scope outside the ceiling
187
+ * does NOT fail the authorize request — the server silently clamps the
188
+ * request to the ceiling (`clamp_scopes_to_ceiling` in posthog) and the
189
+ * token comes back without it. Separately, the consent screen lets the
190
+ * user deselect any scope the app doesn't mark required. Both paths
191
+ * yield a granted `scope` narrower than requested, with no error, so
192
+ * never assume the token carries this list — the token response's
193
+ * `scope` field is the truth, and `missingOAuthScopes` (utils/oauth.ts)
194
+ * diffs it at login. Ceiling procedure: the "scope-ceiling-invalid-scope"
195
+ * runbook in PostHog/runbooks. Keep its worked example in sync when this
196
+ * list changes.
197
+ */
198
+ const WIZARD_OAUTH_SCOPES = [
199
+ ...WIZARD_PROVISIONING_SCOPES,
200
+ "health_issue:read",
201
+ "wizard_session:read",
202
+ "wizard_session:write",
203
+ "wizard_run:write",
204
+ "organization:read"
205
+ ];
206
+ const WIZARD_INTERACTION_EVENT_NAME = "wizard interaction";
207
+ const WIZARD_REMARK_EVENT_NAME = "wizard remark";
208
+ /** Multivariate flag: `wizard-run` publishes to WizardRun, anything else to WizardSession. */
209
+ const WIZARD_RUN_SYNC_FLAG_KEY = "wizard-run-sync";
210
+ /** Boolean feature flag that routes a run to the experimental orchestrator runner. */
211
+ const WIZARD_ORCHESTRATOR_FLAG_KEY = "wizard-orchestrator";
212
+ /** Multivariate flag: per-stage orchestrator overrides ride each variant's JSON payload (`{stage: {model?, effort?}}`). */
213
+ const WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY = "wizard-orchestrator-override";
214
+ /** Boolean flag: on → pi for self-driving. Payload carries `{model, effort?, harness?, sequence?}` (model = a `MODEL_FLAG_VARIANTS` key); missing/invalid payload keeps the non-flagged default. */
215
+ const WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY = "wizard-self-driving-use-pi-harness";
216
+ /** Boolean flag: agentic project scoping for non-interactive basic-integration runs. */
217
+ const WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY = "wizard-basic-integration-agentic-detection";
218
+ /** Boolean flag: the orchestrator queues the program's runner-seeded tasks (the warehouse step). Off, no task is queued and the run is byte-identical to a no-sources project. */
219
+ const WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY = "wizard-orchestrator-seeded-tasks";
220
+ /** Kill switch over a shipped default: ONLY an explicit 'false' excludes the AI Observability and Logs tasks from default integration runs — absent or fetch-failed means include, so the default never vanishes on a network hiccup. */
221
+ const WIZARD_DEFAULT_AIO_LOGS_FLAG_KEY = "wizard-default-aio-logs";
222
+ const WIZARD_FLAG_KEYS = [
223
+ WIZARD_RUN_SYNC_FLAG_KEY,
224
+ WIZARD_ORCHESTRATOR_FLAG_KEY,
225
+ WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY,
226
+ WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY,
227
+ WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY,
228
+ WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY,
229
+ WIZARD_DEFAULT_AIO_LOGS_FLAG_KEY
230
+ ];
231
+ /** User-Agent for wizard HTTP requests and MCP server identification. */
232
+ const WIZARD_USER_AGENT = `posthog/wizard; version: ${VERSION}`;
233
+ /**
234
+ * User-Agent for a specific program's MCP calls, tagged with `program: <id>` so the
235
+ * backend can attribute work per program (e.g. the `self-driving` program's warehouse
236
+ * sources are recorded as `created_via=self_driving` rather than plain `wizard`). The
237
+ * base `posthog/wizard` token is preserved, so anything keying only on that still matches.
238
+ */
239
+ function wizardUserAgentForProgram(programId) {
240
+ return programId ? `${WIZARD_USER_AGENT}; program: ${programId}` : WIZARD_USER_AGENT;
241
+ }
242
+ /** Timeout for framework / project detection probes (ms). */
243
+ const DETECTION_TIMEOUT_MS = 1e4;
244
+ /** Timeout for the agentic project scan (ms); past it the run falls back to root detection. */
245
+ const AGENTIC_DETECTION_FIRST_ATTEMPT_TIMEOUT_MS = 6e4;
246
+ const AGENTIC_DETECTION_RETRY_TIMEOUT_MS = 9e4;
247
+ /**
248
+ * Timeout for the OAuth authorization flow (ms).
249
+ *
250
+ * How long the user has to complete the browser login. The authorization
251
+ * code is minted at approval and exchanged immediately on callback, so the
252
+ * server-side code expiry (`AUTHORIZATION_CODE_EXPIRE_SECONDS`, 5 minutes)
253
+ * bounds only the approval→exchange gap — manual-paste users have 5 minutes
254
+ * from approval to submit the code — not how long this window may stay open.
255
+ */
256
+ const OAUTH_TIMEOUT_MS = 18e5;
257
+ //#endregion
258
+ export { getSkillsBaseUrl as $, POSTHOG_EU_CLIENT_ID as A, WIZARD_CONTACT_EMAIL as B, ISSUES_URL as C, POSTHOG_APP_URL as D, OAUTH_TIMEOUT_MS as E, POSTHOG_TERMS_URL as F, WIZARD_ORCHESTRATOR_FLAG_KEY as G, WIZARD_FLAG_KEYS as H, POSTHOG_US_CLIENT_ID as I, WIZARD_PROVISIONING_SCOPES as J, WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY as K, SONNET_5_MODEL as L, POSTHOG_PRIVACY_URL as M, POSTHOG_PROXY_CLIENT_ID as N, POSTHOG_DEV_CLIENT_ID as O, POSTHOG_STATUS_PAGE_URL as P, WIZARD_USER_AGENT as Q, Sequence as R, Harness as S, OAUTH_PORTS as T, WIZARD_INTERACTION_EVENT_NAME as U, WIZARD_DEFAULT_AIO_LOGS_FLAG_KEY as V, WIZARD_OAUTH_SCOPES as W, WIZARD_RUN_SYNC_FLAG_KEY as X, WIZARD_REMARK_EVENT_NAME as Y, WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY as Z, GPT5_6_LUNA_MODEL as _, ANALYTICS_TEAM_TAG as a, HAIKU_MODEL as b, CONTEXT_MILL_URL as c, DUMMY_PROJECT_API_KEY as d, wizardUserAgentForProgram as et, EVENTS_AUDIT_REPORT_FILE as f, GITHUB_SKILLS_BASE_URL as g, EVENT_PLAN_FILE as h, ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY as i, POSTHOG_ORG_AI_SETTINGS_URL as j, POSTHOG_DOCS_URL as k, DEFAULT_AGENT_MODEL as l, EVENT_INVENTORY_PART_PATTERN as m, AGENTIC_DETECTION_RETRY_TIMEOUT_MS as n, AWS_SKILLS_BASE_URL as o, EVENT_INVENTORY_FILE as p, WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY as q, ANALYTICS_HOST_URL as r, CONTEXT_MILL_RELEASES_URL as s, AGENTIC_DETECTION_FIRST_ATTEMPT_TIMEOUT_MS as t, DETECTION_TIMEOUT_MS as u, GPT5_6_SOL_MODEL as v, Integration as w, HAIKU_TRIAGE_MODEL as x, GPT5_6_TERRA_MODEL as y, WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY as z };
259
+
260
+ //# sourceMappingURL=constants-jFI2SaE1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants-jFI2SaE1.js","names":[],"sources":["../src/shared/constants.ts"],"sourcesContent":["/**\n * Shared constants for the PostHog wizard.\n */\n\nimport { VERSION } from './version';\n\n// ── Models ──────────────────────────────────────────────────────────\n// Coordinate IDs/efforts with the mint allowlists and gateway transport/required prompt policy; see agent/runner/README.md.\n\n/** Next sonnet generation (a `MODEL_FLAG_VARIANTS` key in the switchboard). */\nexport const SONNET_5_MODEL = 'claude-sonnet-5';\n\n/**\n * Default model for agent runs. Bare model IDs (no `anthropic/` prefix) so the\n * LLM gateway's Bedrock fallback can match map_to_bedrock_model().\n */\nexport const DEFAULT_AGENT_MODEL = SONNET_5_MODEL;\n\n/** Undated haiku, for scan triage. The alias tracks the current 4.5 release rather than pinning one. */\nexport const HAIKU_TRIAGE_MODEL = 'claude-haiku-4-5';\n\n/**\n * Cheaper, faster model for mechanical agent work (e.g. repo classification\n * during source-map detection). Passed via AgentConfig.modelOverride.\n */\nexport const HAIKU_MODEL = HAIKU_TRIAGE_MODEL;\n\n// Locally supported OpenAI models; constants alone do not authorize gateway use.\nexport const GPT5_6_LUNA_MODEL = 'openai/gpt-5.6-luna';\nexport const GPT5_6_TERRA_MODEL = 'openai/gpt-5.6-terra';\nexport const GPT5_6_SOL_MODEL = 'openai/gpt-5.6-sol';\n\n// ── Agent runner routing axes ────────────────────────────────────────\n\n/**\n * The two agent runner routing axes: **harness** (which agent SDK drives the LLM)\n * and **sequence** (which pipeline shape orchestrates the work). Single source\n * of truth for yargs `choices`, session fields, the runner registry, and tests\n * — `Object.values(Harness)` gives an iterable of the values when an array is\n * needed. Adding a member is enough to pick it up everywhere.\n *\n * Naming matches the directory layout — see `src/agent/runner/harness/`\n * and `src/agent/runner/sequence/`.\n */\nexport enum Harness {\n anthropic = 'anthropic',\n pi = 'pi',\n}\n\nexport enum Sequence {\n linear = 'linear',\n orchestrator = 'orchestrator',\n}\n\n/**\n * What kind of call produced a gateway generation — the `call_type` trace tag.\n * Splits a program's LLM spend by workload. Every member is sent explicitly so\n * an absent value means \"old build\", not \"agent\".\n */\nexport enum CallType {\n /** The agent doing the work the user asked for. */\n agent = 'agent',\n /** Warlock's classifier deciding whether a YARA match is a true positive. */\n yaraTriage = 'yara-triage',\n /** The cheap repo scan that classifies which projects a program acts on. */\n detection = 'detection',\n}\n\n// ── Integration / CLI ───────────────────────────────────────────────\n\n/**\n * Detection order matters: put framework-specific integrations BEFORE basic language fallbacks.\n */\nexport enum Integration {\n // Frameworks\n nextjs = 'nextjs',\n nuxt = 'nuxt',\n vue = 'vue',\n reactRouter = 'react-router',\n tanstackStart = 'tanstack-start',\n tanstackRouter = 'tanstack-router',\n reactNative = 'react-native',\n angular = 'angular',\n astro = 'astro',\n django = 'django',\n flask = 'flask',\n fastapi = 'fastapi',\n laravel = 'laravel',\n sveltekit = 'sveltekit',\n flutter = 'flutter',\n kmp = 'kmp',\n swift = 'swift',\n android = 'android',\n rails = 'rails',\n elixir = 'elixir',\n go = 'go',\n rust = 'rust',\n // Must stay after kmp/swift/android: those claim gradle projects first.\n java = 'java',\n\n // Language fallbacks. Keep javascriptNode last: it matches any package.json.\n python = 'python',\n ruby = 'ruby',\n javascript_web = 'javascript_web',\n javascriptNode = 'javascript_node',\n}\n\n// ── Documents the wizard's programs write into the user's project ────\n// Named here so the scanner's documentation allowlist can list them without\n// importing a program; each program re-exports its own.\n/** The events-audit report. */\nexport const EVENTS_AUDIT_REPORT_FILE = 'posthog-events-audit-report.md';\nexport const EVENT_INVENTORY_FILE = '.posthog-events-inventory.json';\n/** Per-part filename pattern emitted by events-audit subagents (e.g. `.posthog-events-inventory.part-3.json`). */\nexport const EVENT_INVENTORY_PART_PATTERN =\n /^\\.posthog-events-inventory\\.part-\\d+\\.json$/;\n/** The integration program's event plan. */\nexport const EVENT_PLAN_FILE = '.posthog-events.json';\n\nexport interface Args {\n debug: boolean;\n integration: Integration;\n}\n\n// ── Environment ──────────────────────────────────────────────────────\n\nimport { IS_DEV } from '@env';\nimport {\n CONTEXT_MILL_LOCAL_URL,\n getLocalDev,\n POSTHOG_LOCAL_URL,\n} from './local-dev';\nexport { IS_DEV };\nexport const DEBUG = false;\n\n// ── URLs ─────────────────────────────────────────────────────────────\n\nexport const DEFAULT_URL = IS_DEV\n ? POSTHOG_LOCAL_URL\n : 'https://us.posthog.com';\n/**\n * Region-agnostic PostHog app URL. Resolves to us.posthog.com or\n * eu.posthog.com server-side based on the signed-in user's profile.\n * Use this for share-with-user links (e.g. settings pages) so they\n * land on the right region without us needing to know it client-side.\n */\nexport const POSTHOG_APP_URL = IS_DEV\n ? POSTHOG_LOCAL_URL\n : 'https://app.posthog.com';\nexport const DEFAULT_HOST_URL = IS_DEV\n ? POSTHOG_LOCAL_URL\n : 'https://us.i.posthog.com';\nexport const ISSUES_URL = 'https://github.com/posthog/wizard/issues';\n/** Public status page, linked from transient-failure guidance (e.g. OAuth server_error). */\nexport const POSTHOG_STATUS_PAGE_URL = 'https://www.posthogstatus.com';\nexport const CONTEXT_MILL_URL = 'https://github.com/PostHog/context-mill';\n/**\n * Latest context-mill release page — the BYOAI download link shown in\n * the privacy panel. Deliberately the release PAGE, not a direct asset\n * URL: asset URLs are ~89 chars and hard-wrap inside the 64-col panel,\n * which corrupts terminal copy/paste with a mid-URL line break. This\n * stays under one line; the panel names the exact asset to grab.\n */\nexport const CONTEXT_MILL_RELEASES_URL =\n 'https://github.com/PostHog/context-mill/releases/latest';\nexport const POSTHOG_DOCS_URL = 'https://posthog.com/docs';\nexport const POSTHOG_WIZARD_REPO_URL = 'https://github.com/PostHog/wizard';\nexport const POSTHOG_TERMS_URL = 'https://posthog.com/terms';\nexport const POSTHOG_PRIVACY_URL = 'https://posthog.com/privacy';\nexport const POSTHOG_ORG_AI_SETTINGS_URL =\n 'https://app.posthog.com/settings/organization-details#setting=organization-ai-consent';\nexport const WIZARD_CONTACT_EMAIL = 'wizard@posthog.com';\n\n/**\n * Two origins for the same release, same filenames. Interchangeable bases, so\n * making AWS primary is a `getSkillsBaseUrl` change, not a code change.\n */\nexport const GITHUB_SKILLS_BASE_URL =\n 'https://github.com/PostHog/context-mill/releases/latest/download';\nexport const AWS_SKILLS_BASE_URL = 'https://context-mill.posthog.com/latest';\n/** Alias of `@lib/local-dev`'s constant, kept for existing importers. */\nexport const LOCAL_SKILLS_BASE_URL = CONTEXT_MILL_LOCAL_URL;\n\n/**\n * Driven by `--local-context-mill`, NOT `--local-mcp` (which used to select\n * both). Takes no argument on purpose: callers can't pass the wrong flag.\n */\nexport function getSkillsBaseUrl(): string {\n return getLocalDev().localContextMill\n ? LOCAL_SKILLS_BASE_URL\n : GITHUB_SKILLS_BASE_URL;\n}\n\n// ── Analytics (internal) ──────────────────────────────────────────────\n\nexport const ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY = 'sTMFPsFhdP1Ssg';\nexport const ANALYTICS_HOST_URL = 'https://internal-j.posthog.com';\nexport const ANALYTICS_TEAM_TAG = 'docs-and-wizard';\n\n// ── OAuth / Auth ────────────────────────────────────────────────────\n\nexport const OAUTH_PORTS = [8239, 8238, 8240, 8237, 8236, 8235] as const;\nexport const POSTHOG_US_CLIENT_ID = 'c4Rdw8DIxgtQfA80IiSnGKlNX8QN00cFWF00QQhM';\nexport const POSTHOG_EU_CLIENT_ID = 'bx2C5sZRN03TkdjraCcetvQFPGH6N2Y9vRLkcKEy';\nexport const POSTHOG_DEV_CLIENT_ID = 'DC5uRLVbGI02YQ82grxgnK6Qn12SXWpCqdPb60oZ';\nexport const POSTHOG_PROXY_CLIENT_ID = POSTHOG_US_CLIENT_ID;\nexport const DUMMY_PROJECT_API_KEY = '_YOUR_POSTHOG_PROJECT_TOKEN_';\n\n/**\n * Scopes the wizard requests during the agentic provisioning signup flow.\n *\n * Each entry is justified by what the wizard's agent step does after signup:\n * - user:read identify the user for analytics + agent context\n * - project:read look up the freshly-provisioned project\n * - llm_gateway:read authenticate to gateway.{us,eu}.posthog.com/wizard\n * (the agent's LLM calls — without this scope, every\n * agent message returns 401)\n * - query:read run HogQL queries when the agent needs data\n * - dashboard:write create the onboarding dashboard during setup\n * - insight:write create the onboarding insights during setup\n * - notebook:write upload the events-audit report as a PostHog notebook\n * in step 6 of the events-audit skill (notebooks-create\n * MCP tool requires this scope)\n * - event_definition:write\n * create event definitions from the completed wizard\n * session's event plan\n *\n * Must be a subset of `ALLOWED_PROVISIONING_SCOPES` in\n * `ee/api/agentic_provisioning/views.py` on the backend.\n */\nexport const WIZARD_PROVISIONING_SCOPES = [\n 'user:read',\n 'project:read',\n 'llm_gateway:read',\n 'dashboard:write',\n 'insight:write',\n 'query:read',\n 'notebook:write',\n 'event_definition:write',\n] as const;\n\n/**\n * Scopes the wizard requests during the OAuth login flow. Superset of\n * `WIZARD_PROVISIONING_SCOPES` with scopes that only apply to the login\n * path and are not in the provisioning allowlist:\n * - health_issue:read used by `wizard doctor`\n * - wizard_session:read list / retrieve / stream sessions\n * - wizard_session:write stream run state to /api/projects/{id}/wizard/sessions/\n * - event_definition:write\n * create event definitions when a session completes\n * - organization:read read `organization.is_ai_data_processing_approved`\n * from /api/users/@me/ for the AI opt-in gate\n *\n * NOTE: every scope here must be within the wizard OAuth application's\n * server-side scope ceiling (`OAuthApplication.scopes` in posthog, set\n * via Django admin on BOTH prod regions). A scope outside the ceiling\n * does NOT fail the authorize request — the server silently clamps the\n * request to the ceiling (`clamp_scopes_to_ceiling` in posthog) and the\n * token comes back without it. Separately, the consent screen lets the\n * user deselect any scope the app doesn't mark required. Both paths\n * yield a granted `scope` narrower than requested, with no error, so\n * never assume the token carries this list — the token response's\n * `scope` field is the truth, and `missingOAuthScopes` (utils/oauth.ts)\n * diffs it at login. Ceiling procedure: the \"scope-ceiling-invalid-scope\"\n * runbook in PostHog/runbooks. Keep its worked example in sync when this\n * list changes.\n */\nexport const WIZARD_OAUTH_SCOPES = [\n ...WIZARD_PROVISIONING_SCOPES,\n 'health_issue:read',\n 'wizard_session:read',\n 'wizard_session:write',\n 'wizard_run:write',\n 'organization:read',\n] as const;\n\n// ── Wizard run / variants ───────────────────────────────────────────\n\nexport const WIZARD_INTERACTION_EVENT_NAME = 'wizard interaction';\nexport const WIZARD_REMARK_EVENT_NAME = 'wizard remark';\n/** Multivariate flag: `wizard-run` publishes to WizardRun, anything else to WizardSession. */\nexport const WIZARD_RUN_SYNC_FLAG_KEY = 'wizard-run-sync';\n/** Boolean feature flag that routes a run to the experimental orchestrator runner. */\nexport const WIZARD_ORCHESTRATOR_FLAG_KEY = 'wizard-orchestrator';\n/** Multivariate flag: per-stage orchestrator overrides ride each variant's JSON payload (`{stage: {model?, effort?}}`). */\nexport const WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY =\n 'wizard-orchestrator-override';\n/** Boolean flag: on → pi for self-driving. Payload carries `{model, effort?, harness?, sequence?}` (model = a `MODEL_FLAG_VARIANTS` key); missing/invalid payload keeps the non-flagged default. */\nexport const WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY =\n 'wizard-self-driving-use-pi-harness';\n/** Boolean flag: agentic project scoping for non-interactive basic-integration runs. */\nexport const WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY =\n 'wizard-basic-integration-agentic-detection';\n/** Boolean flag: the orchestrator queues the program's runner-seeded tasks (the warehouse step). Off, no task is queued and the run is byte-identical to a no-sources project. */\nexport const WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY =\n 'wizard-orchestrator-seeded-tasks';\n/** Kill switch over a shipped default: ONLY an explicit 'false' excludes the AI Observability and Logs tasks from default integration runs — absent or fetch-failed means include, so the default never vanishes on a network hiccup. */\nexport const WIZARD_DEFAULT_AIO_LOGS_FLAG_KEY = 'wizard-default-aio-logs';\n// Reading a flag enters this run into that flag's experiment, so a closed set — not a\n// `wizard-` prefix anyone can name into — decides what a run evaluates. Test-pinned exhaustive.\nexport const WIZARD_FLAG_KEYS = [\n WIZARD_RUN_SYNC_FLAG_KEY,\n WIZARD_ORCHESTRATOR_FLAG_KEY,\n WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY,\n WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY,\n WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY,\n WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY,\n WIZARD_DEFAULT_AIO_LOGS_FLAG_KEY,\n] as const;\n/** User-Agent for wizard HTTP requests and MCP server identification. */\nexport const WIZARD_USER_AGENT = `posthog/wizard; version: ${VERSION}`;\n\n/**\n * User-Agent for a specific program's MCP calls, tagged with `program: <id>` so the\n * backend can attribute work per program (e.g. the `self-driving` program's warehouse\n * sources are recorded as `created_via=self_driving` rather than plain `wizard`). The\n * base `posthog/wizard` token is preserved, so anything keying only on that still matches.\n */\nexport function wizardUserAgentForProgram(programId?: string): string {\n return programId\n ? `${WIZARD_USER_AGENT}; program: ${programId}`\n : WIZARD_USER_AGENT;\n}\n\n// ── Timeouts ─────────────────────────────────────────────────────────\n\n/** Timeout for framework / project detection probes (ms). */\nexport const DETECTION_TIMEOUT_MS = 10_000;\n\n/** Timeout for the agentic project scan (ms); past it the run falls back to root detection. */\nexport const AGENTIC_DETECTION_FIRST_ATTEMPT_TIMEOUT_MS = 60_000;\nexport const AGENTIC_DETECTION_RETRY_TIMEOUT_MS = 90_000;\n\n/**\n * Timeout for the OAuth authorization flow (ms).\n *\n * How long the user has to complete the browser login. The authorization\n * code is minted at approval and exchanged immediately on callback, so the\n * server-side code expiry (`AUTHORIZATION_CODE_EXPIRE_SECONDS`, 5 minutes)\n * bounds only the approval→exchange gap — manual-paste users have 5 minutes\n * from approval to submit the code — not how long this window may stay open.\n */\nexport const OAUTH_TIMEOUT_MS = 1_800_000;\n"],"mappings":";;;;;;;;AAUA,MAAa,iBAAiB;;;;;AAM9B,MAAa,sBAAsB;;AAGnC,MAAa,qBAAqB;;;;;AAMlC,MAAa,cAAc;AAG3B,MAAa,oBAAoB;AACjC,MAAa,qBAAqB;AAClC,MAAa,mBAAmB;;;;;;;;;;;AAchC,IAAY,UAAL,yBAAA,SAAA;AACL,SAAA,eAAA;AACA,SAAA,QAAA;;KACD;AAED,IAAY,WAAL,yBAAA,UAAA;AACL,UAAA,YAAA;AACA,UAAA,kBAAA;;KACD;;;;AAqBD,IAAY,cAAL,yBAAA,aAAA;AAEL,aAAA,YAAA;AACA,aAAA,UAAA;AACA,aAAA,SAAA;AACA,aAAA,iBAAA;AACA,aAAA,mBAAA;AACA,aAAA,oBAAA;AACA,aAAA,iBAAA;AACA,aAAA,aAAA;AACA,aAAA,WAAA;AACA,aAAA,YAAA;AACA,aAAA,WAAA;AACA,aAAA,aAAA;AACA,aAAA,aAAA;AACA,aAAA,eAAA;AACA,aAAA,aAAA;AACA,aAAA,SAAA;AACA,aAAA,WAAA;AACA,aAAA,aAAA;AACA,aAAA,WAAA;AACA,aAAA,YAAA;AACA,aAAA,QAAA;AACA,aAAA,UAAA;AAEA,aAAA,UAAA;AAGA,aAAA,YAAA;AACA,aAAA,UAAA;AACA,aAAA,oBAAA;AACA,aAAA,oBAAA;;KACD;;AAMD,MAAa,2BAA2B;AACxC,MAAa,uBAAuB;;AAEpC,MAAa,+BACX;;AAEF,MAAa,kBAAkB;;;;;;;AA6B/B,MAAa,kBAET;AAIJ,MAAa,aAAa;;AAE1B,MAAa,0BAA0B;AACvC,MAAa,mBAAmB;;;;;;;;AAQhC,MAAa,4BACX;AACF,MAAa,mBAAmB;AAEhC,MAAa,oBAAoB;AACjC,MAAa,sBAAsB;AACnC,MAAa,8BACX;AACF,MAAa,uBAAuB;;;;;AAMpC,MAAa,yBACX;AACF,MAAa,sBAAsB;;AAEnC,MAAa,wBAAwB;;;;;AAMrC,SAAgB,mBAA2B;AACzC,QAAO,aAAa,CAAC,mBACjB,wBACA;;AAKN,MAAa,6CAA6C;AAC1D,MAAa,qBAAqB;AAClC,MAAa,qBAAqB;AAIlC,MAAa,cAAc;CAAC;CAAM;CAAM;CAAM;CAAM;CAAM;CAAK;AAC/D,MAAa,uBAAuB;AACpC,MAAa,uBAAuB;AACpC,MAAa,wBAAwB;AACrC,MAAa,0BAA0B;AACvC,MAAa,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;AAwBrC,MAAa,6BAA6B;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BD,MAAa,sBAAsB;CACjC,GAAG;CACH;CACA;CACA;CACA;CACA;CACD;AAID,MAAa,gCAAgC;AAC7C,MAAa,2BAA2B;;AAExC,MAAa,2BAA2B;;AAExC,MAAa,+BAA+B;;AAE5C,MAAa,wCACX;;AAEF,MAAa,8CACX;;AAEF,MAAa,sDACX;;AAEF,MAAa,4CACX;;AAEF,MAAa,mCAAmC;AAGhD,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAED,MAAa,oBAAoB,4BAA4B;;;;;;;AAQ7D,SAAgB,0BAA0B,WAA4B;AACpE,QAAO,YACH,GAAG,kBAAkB,aAAa,cAClC;;;AAMN,MAAa,uBAAuB;;AAGpC,MAAa,6CAA6C;AAC1D,MAAa,qCAAqC;;;;;;;;;;AAWlD,MAAa,mBAAmB"}
@@ -0,0 +1,171 @@
1
+ import { appendFileSync, mkdirSync } from "fs";
2
+ import path from "path";
3
+ import { inspect } from "node:util";
4
+ import { tmpdir } from "node:os";
5
+ import { join as join$1, sep as sep$1 } from "node:path";
6
+ //#region src/lib/headless-mode.ts
7
+ /**
8
+ * The on-CLI flag name. Intentionally ugly + undocumented; do not surface it in
9
+ * `--help`, the README, or user-facing error messages.
10
+ */
11
+ const HEADLESS_FLAG = "headless-DONOTUSE-EXPERIMENTAL";
12
+ /**
13
+ * The yargs option declaration for the headless flag. Commands opt in so that
14
+ * unsupported commands reject headless execution instead of starting it.
15
+ */
16
+ const headlessOption = { [HEADLESS_FLAG]: {
17
+ default: false,
18
+ describe: "EXPERIMENTAL — do not use. Unstable, subject to breaking changes.",
19
+ type: "boolean",
20
+ hidden: true
21
+ } };
22
+ /**
23
+ * Read the headless signal off a parsed argv / options bag. yargs always sets
24
+ * the value under the declared key (`HEADLESS_FLAG`), so reading that key is
25
+ * reliable regardless of camel-case expansion.
26
+ */
27
+ function isHeadless(options) {
28
+ return options[HEADLESS_FLAG] === true;
29
+ }
30
+ const regionOption = { region: {
31
+ describe: "PostHog cloud region\nenv: POSTHOG_WIZARD_REGION",
32
+ choices: ["us", "eu"],
33
+ type: "string",
34
+ hidden: true
35
+ } };
36
+ //#endregion
37
+ //#region src/env.ts
38
+ /**
39
+ * Central environment variable access for the PostHog wizard.
40
+ *
41
+ * ── Build-time constants ────────────────────────────────────────────
42
+ * Inlined by tsdown's `env` option at compile time. After build, the
43
+ * runtime value of these env vars has zero effect on the wizard.
44
+ *
45
+ * ── Runtime variables ───────────────────────────────────────────────
46
+ * Read through `runtimeEnv()` with a typed allowlist. This makes every
47
+ * runtime dependency on the environment explicit and grep-able.
48
+ *
49
+ * ── Direct process.env access ───────────────────────────────────────
50
+ * Reserved for subprocess environment configuration (writes) and
51
+ * vendored code. Production source outside those cases should use
52
+ * this module instead.
53
+ */
54
+ const NODE_ENV = "production";
55
+ /** 'cloud' when launched with the experimental headless flag, else 'local' — resolved once from argv at launch. */
56
+ const RUN_SURFACE = process.argv.some((a) => a === `--headless-DONOTUSE-EXPERIMENTAL` || a.startsWith(`--headless-DONOTUSE-EXPERIMENTAL=`)) ? "cloud" : "local";
57
+ /** Read a runtime environment variable. Only allowlisted keys compile. */
58
+ function runtimeEnv(key) {
59
+ return process.env[key];
60
+ }
61
+ /**
62
+ * The PostHog task run that launched this wizard, when one did. A cloud run's
63
+ * sandbox exports both ids into the wizard's environment; every local run
64
+ * leaves them undefined. Resolved once at launch, like RUN_SURFACE above.
65
+ */
66
+ const TASK_RUN_ID = runtimeEnv("POSTHOG_TASK_RUN_ID") || void 0;
67
+ const TASK_ID = runtimeEnv("POSTHOG_TASK_ID") || void 0;
68
+ //#endregion
69
+ //#region src/shared/utils/paths.ts
70
+ const TMP = process.platform === "win32" ? tmpdir() : "/tmp";
71
+ const WIZARD_LOG_FILE = join$1(TMP, "posthog-wizard.log");
72
+ const WIZARD_BENCHMARK_FILE = join$1(TMP, "posthog-wizard-benchmark.json");
73
+ /** Default target of `--task-stream-log`. Dev builds only. */
74
+ const WIZARD_TASK_STREAM_FILE = join$1(TMP, "posthog-wizard-task-stream.jsonl");
75
+ const WIZARD_YARA_REPORT_FILE = join$1(TMP, "posthog-wizard-yara-report.json");
76
+ /**
77
+ * Strip an absolute installDir prefix off a project file path so the UI
78
+ * renders `index.js:12` instead of `/Users/.../index.js:12`. Defends
79
+ * against false matches like `/Users/foo` ⊂ `/Users/foobar/x.js` by
80
+ * normalizing to a trailing path separator before the prefix check.
81
+ */
82
+ function relativeToInstallDir(file, installDir) {
83
+ const prefix = installDir.endsWith(sep$1) ? installDir : installDir + sep$1;
84
+ return file.startsWith(prefix) ? file.slice(prefix.length) : file;
85
+ }
86
+ //#endregion
87
+ //#region src/shared/utils/debug.ts
88
+ let logFilePath = WIZARD_LOG_FILE;
89
+ let fileLoggingEnabled = true;
90
+ let consoleLoggingEnabled = false;
91
+ function stringify(value) {
92
+ if (typeof value === "string") return value;
93
+ if (value instanceof Error) return value.stack ?? String(value);
94
+ try {
95
+ return JSON.stringify(value, null, 2) ?? inspect(value, { depth: 3 });
96
+ } catch {
97
+ return inspect(value, { depth: 3 });
98
+ }
99
+ }
100
+ function renderLine(args) {
101
+ return args.map(stringify).join(" ");
102
+ }
103
+ function getLogFilePath() {
104
+ return logFilePath;
105
+ }
106
+ function configureLogFile(opts) {
107
+ if (opts.path !== void 0) {
108
+ logFilePath = opts.path;
109
+ ensuredLogDir = false;
110
+ }
111
+ if (opts.enabled !== void 0) fileLoggingEnabled = opts.enabled;
112
+ }
113
+ let ensuredLogDir = false;
114
+ let reportedLogFailure = false;
115
+ function reportLogFailureOnce(err) {
116
+ if (reportedLogFailure) return;
117
+ reportedLogFailure = true;
118
+ import("./analytics-BcV-WCM4.js").then(({ analytics }) => analytics.captureException(err instanceof Error ? err : new Error(String(err)), {
119
+ source: "log-file-write",
120
+ log_path: logFilePath,
121
+ platform: process.platform
122
+ })).catch(() => {});
123
+ }
124
+ function appendLine(text) {
125
+ try {
126
+ appendFileSync(logFilePath, text);
127
+ } catch (err) {
128
+ if (ensuredLogDir) {
129
+ reportLogFailureOnce(err);
130
+ return;
131
+ }
132
+ ensuredLogDir = true;
133
+ try {
134
+ mkdirSync(path.dirname(logFilePath), { recursive: true });
135
+ appendFileSync(logFilePath, text);
136
+ } catch (retryErr) {
137
+ reportLogFailureOnce(retryErr);
138
+ }
139
+ }
140
+ }
141
+ function configureLogFileFromEnvironment() {
142
+ const dir = runtimeEnv("POSTHOG_WIZARD_LOG_DIR");
143
+ if (dir) configureLogFile({ path: path.join(dir, "posthog-wizard.log") });
144
+ }
145
+ function initLogFile() {
146
+ if (!fileLoggingEnabled) return;
147
+ const divider = "=".repeat(60);
148
+ appendLine(`\n${divider}\nPostHog Wizard Run: ${(/* @__PURE__ */ new Date()).toISOString()}\n${divider}\n`);
149
+ }
150
+ function logToFile(...args) {
151
+ if (!fileLoggingEnabled) return;
152
+ appendLine(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${renderLine(args)}\n`);
153
+ }
154
+ let debugSink = (line) => process.stdout.write(`${line}\n`);
155
+ /** Replace the console sink; returns the previous one so callers can restore it. */
156
+ function setDebugSink(sink) {
157
+ const previous = debugSink;
158
+ debugSink = sink;
159
+ return previous;
160
+ }
161
+ function debug(...args) {
162
+ if (!consoleLoggingEnabled) return;
163
+ debugSink(renderLine(args));
164
+ }
165
+ function enableDebugLogs() {
166
+ consoleLoggingEnabled = true;
167
+ }
168
+ //#endregion
169
+ export { TASK_RUN_ID as _, getLogFilePath as a, isHeadless as b, setDebugSink as c, WIZARD_TASK_STREAM_FILE as d, WIZARD_YARA_REPORT_FILE as f, TASK_ID as g, RUN_SURFACE as h, enableDebugLogs as i, WIZARD_BENCHMARK_FILE as l, NODE_ENV as m, configureLogFileFromEnvironment as n, initLogFile as o, relativeToInstallDir as p, debug as r, logToFile as s, configureLogFile as t, WIZARD_LOG_FILE as u, runtimeEnv as v, regionOption as x, headlessOption as y };
170
+
171
+ //# sourceMappingURL=debug-Ch4BDOtD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-Ch4BDOtD.js","names":["join","sep"],"sources":["../src/lib/headless-mode.ts","../src/env.ts","../src/shared/utils/paths.ts","../src/shared/utils/debug.ts"],"sourcesContent":["/**\n * Headless mode — the published-build, non-interactive run path.\n *\n * The headless flag and `--ci` both drive a non-interactive install\n * (session.ci === true), but through dedicated entry points so they can\n * diverge: runHeadlessInstall → runWizardHeadless for headless,\n * runCIInstall → runWizardCI for `--ci`. Both delegate to one shared pipeline\n * (runNonInteractive) today; the only forks are the api-key prefixes accepted\n * (ci-install) and the analytics build tag (the mode passed to the runner).\n *\n * The flag is deliberately named `--headless-DONOTUSE-EXPERIMENTAL` and hidden\n * from `--help`: the contract is still unstable and subject to breaking\n * changes, so it must not be advertised or relied on by external callers. This\n * module is the single source of truth for the flag's name and detection — keep\n * the scary name out of every other file so a future rename is one edit here.\n */\n\nimport type { Options } from 'yargs';\n\n/**\n * The on-CLI flag name. Intentionally ugly + undocumented; do not surface it in\n * `--help`, the README, or user-facing error messages.\n */\nexport const HEADLESS_FLAG = 'headless-DONOTUSE-EXPERIMENTAL';\n\n/**\n * The yargs option declaration for the headless flag. Commands opt in so that\n * unsupported commands reject headless execution instead of starting it.\n */\nexport const headlessOption: Record<string, Options> = {\n [HEADLESS_FLAG]: {\n default: false,\n // EXPERIMENTAL + UNSTABLE: the non-interactive published-build run path.\n // Declared unconditionally (unlike --ci) so it works in the shipped\n // package, but hidden and intentionally ugly-named — the contract may\n // break without notice, so it must not be advertised.\n describe:\n 'EXPERIMENTAL — do not use. Unstable, subject to breaking changes.',\n type: 'boolean',\n hidden: true,\n },\n};\n\n/**\n * Read the headless signal off a parsed argv / options bag. yargs always sets\n * the value under the declared key (`HEADLESS_FLAG`), so reading that key is\n * reliable regardless of camel-case expansion.\n */\nexport function isHeadless(options: Record<string, unknown>): boolean {\n return options[HEADLESS_FLAG] === true;\n}\n\n// `--region` only means something non-interactively (API-key auth has no OAuth\n// token response to read `posthog_region` from), so only headless-capable\n// commands declare it.\nexport const regionOption: Record<string, Options> = {\n region: {\n describe: 'PostHog cloud region\\nenv: POSTHOG_WIZARD_REGION',\n choices: ['us', 'eu'],\n type: 'string',\n hidden: true,\n },\n};\n","/**\n * Central environment variable access for the PostHog wizard.\n *\n * ── Build-time constants ────────────────────────────────────────────\n * Inlined by tsdown's `env` option at compile time. After build, the\n * runtime value of these env vars has zero effect on the wizard.\n *\n * ── Runtime variables ───────────────────────────────────────────────\n * Read through `runtimeEnv()` with a typed allowlist. This makes every\n * runtime dependency on the environment explicit and grep-able.\n *\n * ── Direct process.env access ───────────────────────────────────────\n * Reserved for subprocess environment configuration (writes) and\n * vendored code. Production source outside those cases should use\n * this module instead.\n */\n\nimport { HEADLESS_FLAG } from '@lib/headless-mode';\n\n// ── Build-time constants ─────────────────────────────────────────────\n// tsdown replaces `process.env.NODE_ENV` with a string literal.\n// After build these are just `\"production\"`, `false`, etc.\n\nexport const NODE_ENV = process.env.NODE_ENV as string;\nexport const IS_DEV =\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test';\n\n/**\n * True only in published/production builds. tsdown inlines\n * `process.env.NODE_ENV` as the literal `\"production\"` at build time, so this\n * collapses to `true` in `dist/` and stays `false` for `tsx`/dev/test runs\n * (where NODE_ENV is unset, `development`, or `test`). Used to gate features\n * that aren't supported in the shipped package — e.g. `--ci` mode.\n */\nexport const IS_PRODUCTION_BUILD = process.env.NODE_ENV === 'production';\n\n/** 'cloud' when launched with the experimental headless flag, else 'local' — resolved once from argv at launch. */\nexport const RUN_SURFACE: 'cloud' | 'local' = process.argv.some(\n (a) => a === `--${HEADLESS_FLAG}` || a.startsWith(`--${HEADLESS_FLAG}=`),\n)\n ? 'cloud'\n : 'local';\n\n// ── Runtime environment ──────────────────────────────────────────────\n\n/**\n * Exhaustive allowlist of env vars the wizard reads at runtime.\n * Add new keys here when a new runtime dependency is needed.\n */\ntype RuntimeEnvKey =\n // CI-build-only flag overrides (see utils/ci-flag-overrides.ts).\n // Deliberately NOT POSTHOG_WIZARD_-prefixed: yargs .env('POSTHOG_WIZARD')\n // would claim it as an unknown CLI option and strict-reject the run.\n | 'WIZARD_CI_FLAG_OVERRIDES'\n | 'WIZARD_CI_EXCLUDE_TASKS'\n | 'WIZARD_CI_GATEWAY_TOKEN_FILE'\n | 'WIZARD_CI_GATEWAY_URL'\n // Wizard CLI configuration (yargs POSTHOG_WIZARD_ prefix)\n | 'POSTHOG_WIZARD_BENCHMARK_CONFIG'\n | 'POSTHOG_WIZARD_BENCHMARK_FILE'\n | 'POSTHOG_WIZARD_LOG_DIR'\n | 'POSTHOG_WIZARD_DEBUG'\n // Identity of the PostHog task run whose sandbox launched this wizard. Set by\n // the sandbox for every run it starts, agent or wizard. Deliberately NOT\n // POSTHOG_WIZARD_-prefixed, for the same reason as the two keys above:\n // yargs .env('POSTHOG_WIZARD') would claim them as CLI options and\n // .strictOptions() would reject the run unless the wizard also declared them,\n // which would tie every sandbox deploy to an npm release of this package.\n | 'POSTHOG_WIZARD_RUN_ID'\n | 'POSTHOG_TASK_RUN_ID'\n | 'POSTHOG_TASK_ID'\n | 'POSTHOG_HANDOFF_OUTPUT_PATH'\n // Local/CI escape hatch to disable Warlock scanning without the PostHog flag.\n | 'POSTHOG_WIZARD_WARLOCK_DISABLED'\n | 'DEBUG'\n // Agent / MCP\n | 'MCP_URL'\n | 'POSTHOG_API_KEY'\n // Platform: terminal detection\n | 'TERM'\n | 'TERM_PROGRAM'\n | 'TERMINAL_EMULATOR'\n | 'CI'\n | 'WT_SESSION'\n | 'TERMINUS_SUBLIME'\n | 'ConEmuTask'\n // Platform: paths\n | 'APPDATA'\n | 'OPENCODE_CONFIG_DIR'\n | 'XDG_CONFIG_HOME';\n\n/** Read a runtime environment variable. Only allowlisted keys compile. */\nexport function runtimeEnv(key: RuntimeEnvKey): string | undefined {\n return process.env[key];\n}\n\n/**\n * The PostHog task run that launched this wizard, when one did. A cloud run's\n * sandbox exports both ids into the wizard's environment; every local run\n * leaves them undefined. Resolved once at launch, like RUN_SURFACE above.\n */\nexport const TASK_RUN_ID: string | undefined =\n runtimeEnv('POSTHOG_TASK_RUN_ID') || undefined;\nexport const TASK_ID: string | undefined =\n runtimeEnv('POSTHOG_TASK_ID') || undefined;\n","import { tmpdir } from 'node:os';\nimport { join, sep } from 'node:path';\n\n// /tmp is stable and discoverable on macOS/Linux; Windows needs os.tmpdir()\nconst TMP = process.platform === 'win32' ? tmpdir() : '/tmp';\n\nexport const WIZARD_LOG_FILE = join(TMP, 'posthog-wizard.log');\nexport const WIZARD_BENCHMARK_FILE = join(TMP, 'posthog-wizard-benchmark.json');\n/** Default target of `--task-stream-log`. Dev builds only. */\nexport const WIZARD_TASK_STREAM_FILE = join(\n TMP,\n 'posthog-wizard-task-stream.jsonl',\n);\nexport const WIZARD_YARA_REPORT_FILE = join(\n TMP,\n 'posthog-wizard-yara-report.json',\n);\n/**\n * Strip an absolute installDir prefix off a project file path so the UI\n * renders `index.js:12` instead of `/Users/.../index.js:12`. Defends\n * against false matches like `/Users/foo` ⊂ `/Users/foobar/x.js` by\n * normalizing to a trailing path separator before the prefix check.\n */\nexport function relativeToInstallDir(file: string, installDir: string): string {\n const prefix = installDir.endsWith(sep) ? installDir : installDir + sep;\n return file.startsWith(prefix) ? file.slice(prefix.length) : file;\n}\n","import { appendFileSync, mkdirSync } from 'fs';\nimport path from 'path';\nimport { inspect } from 'node:util';\nimport { IS_DEV, runtimeEnv } from '@env';\nimport { WIZARD_LOG_FILE } from './paths';\n\n// Dev builds may redirect the log so concurrent runs don't interleave one file.\nlet logFilePath =\n (IS_DEV && process.env.POSTHOG_WIZARD_LOG_FILE) || WIZARD_LOG_FILE;\nlet fileLoggingEnabled = true;\nlet consoleLoggingEnabled = false;\n\nfunction stringify(value: unknown): string {\n if (typeof value === 'string') return value;\n if (value instanceof Error) return value.stack ?? String(value);\n try {\n // JSON.stringify throws on cycles and skips some values — fall back to\n // inspect so a crash log line is never dropped.\n return JSON.stringify(value, null, 2) ?? inspect(value, { depth: 3 });\n } catch {\n return inspect(value, { depth: 3 });\n }\n}\n\nfunction renderLine(args: readonly unknown[]): string {\n return args.map(stringify).join(' ');\n}\n\nexport function getLogFilePath(): string {\n return logFilePath;\n}\n\nexport function configureLogFile(opts: {\n path?: string;\n enabled?: boolean;\n}): void {\n if (opts.path !== undefined) {\n logFilePath = opts.path;\n ensuredLogDir = false;\n }\n if (opts.enabled !== undefined) fileLoggingEnabled = opts.enabled;\n}\n\nlet ensuredLogDir = false;\nlet reportedLogFailure = false;\n\n// Failed log writes go to error tracking, once per process. Dynamic import:\n// analytics logs through this module, so a static import would be a cycle.\nfunction reportLogFailureOnce(err: unknown): void {\n if (reportedLogFailure) return;\n reportedLogFailure = true;\n void import('./analytics')\n .then(({ analytics }) =>\n analytics.captureException(\n err instanceof Error ? err : new Error(String(err)),\n {\n source: 'log-file-write',\n log_path: logFilePath,\n platform: process.platform,\n },\n ),\n )\n .catch(() => {\n // Reporting must never crash the wizard either.\n });\n}\n\n// The log's directory isn't guaranteed to exist (Windows %TEMP%,\n// POSTHOG_WIZARD_LOG_DIR) — create it on first failure.\nfunction appendLine(text: string): void {\n try {\n appendFileSync(logFilePath, text);\n } catch (err) {\n if (ensuredLogDir) {\n reportLogFailureOnce(err);\n return;\n }\n ensuredLogDir = true;\n try {\n mkdirSync(path.dirname(logFilePath), { recursive: true });\n appendFileSync(logFilePath, text);\n } catch (retryErr) {\n reportLogFailureOnce(retryErr);\n }\n }\n}\n\nexport function configureLogFileFromEnvironment(): void {\n const dir = runtimeEnv('POSTHOG_WIZARD_LOG_DIR');\n if (dir) {\n configureLogFile({ path: path.join(dir, 'posthog-wizard.log') });\n }\n}\n\nexport function initLogFile(): void {\n if (!fileLoggingEnabled) return;\n const divider = '='.repeat(60);\n appendLine(\n `\\n${divider}\\nPostHog Wizard Run: ${new Date().toISOString()}\\n${divider}\\n`,\n );\n}\n\nexport function logToFile(...args: unknown[]): void {\n if (!fileLoggingEnabled) return;\n const ts = new Date().toISOString();\n appendLine(`[${ts}] ${renderLine(args)}\\n`);\n}\n\n/** Where `debug()` lines go. The UI module installs the current UI's info log at load; until then they go to stdout. */\nexport type DebugSink = (line: string) => void;\n\nlet debugSink: DebugSink = (line) => process.stdout.write(`${line}\\n`);\n\n/** Replace the console sink; returns the previous one so callers can restore it. */\nexport function setDebugSink(sink: DebugSink): DebugSink {\n const previous = debugSink;\n debugSink = sink;\n return previous;\n}\n\nexport function debug(...args: unknown[]): void {\n if (!consoleLoggingEnabled) return;\n debugSink(renderLine(args));\n}\n\nexport function enableDebugLogs(): void {\n consoleLoggingEnabled = true;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { n as configureLogFileFromEnvironment, s as logToFile } from "./debug-DWYDVp0B.js";
1
+ import { n as configureLogFileFromEnvironment, s as logToFile } from "./debug-Ch4BDOtD.js";
2
2
  export { configureLogFileFromEnvironment, logToFile };