@posthog/wizard 2.65.0 → 2.67.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 (119) hide show
  1. package/dist/{add-mcp-server-to-clients-ArtlMX9-.js → add-mcp-server-to-clients-DHTRbyJX.js} +228 -64
  2. package/dist/add-mcp-server-to-clients-DHTRbyJX.js.map +1 -0
  3. package/dist/{agent-interface-ORzGEFNM.js → agent-interface-tM_b0l__.js} +458 -76
  4. package/dist/agent-interface-tM_b0l__.js.map +1 -0
  5. package/dist/{agent-prompt-loader-D3w6sc34.js → agent-prompt-loader-BSMh5bfD.js} +5 -5
  6. package/dist/{agent-prompt-loader-D3w6sc34.js.map → agent-prompt-loader-BSMh5bfD.js.map} +1 -1
  7. package/dist/{agent-runner-Ca-e2TOQ.js → agent-runner-DD65OMkB.js} +153 -71
  8. package/dist/agent-runner-DD65OMkB.js.map +1 -0
  9. package/dist/analytics-B4Igh5nv.js +2 -0
  10. package/dist/{analytics-zBrIVjMV.js → analytics-CtIYzkK4.js} +2 -2
  11. package/dist/{analytics-zBrIVjMV.js.map → analytics-CtIYzkK4.js.map} +1 -1
  12. package/dist/{api-Wgb7AhrP.js → api-BJft9v6K.js} +3 -3
  13. package/dist/{api-Wgb7AhrP.js.map → api-BJft9v6K.js.map} +1 -1
  14. package/dist/bin.js +245 -102
  15. package/dist/bin.js.map +1 -1
  16. package/dist/{bounded-fs-DqsVmh4r.js → bounded-fs-BWqoFQvQ.js} +3 -3
  17. package/dist/{bounded-fs-DqsVmh4r.js.map → bounded-fs-BWqoFQvQ.js.map} +1 -1
  18. package/dist/{ci-install-D1QqmJIc.js → ci-install-BXGnVI7T.js} +18 -9
  19. package/dist/ci-install-BXGnVI7T.js.map +1 -0
  20. package/dist/{debug-Cm1hvkVy.js → debug-BsHD83Vy.js} +4 -4
  21. package/dist/debug-BsHD83Vy.js.map +1 -0
  22. package/dist/{debug-CtQ13sCW.js → debug-mO3yg4Z7.js} +1 -1
  23. package/dist/{defaults-BHhXrX9F.js → defaults-DI642M3n.js} +1 -1
  24. package/dist/{defaults-BHhXrX9F.js.map → defaults-DI642M3n.js.map} +1 -1
  25. package/dist/{env-api-key-CdI2XZIz.js → env-api-key-DS0ghlcO.js} +2 -2
  26. package/dist/{env-api-key-CdI2XZIz.js.map → env-api-key-DS0ghlcO.js.map} +1 -1
  27. package/dist/{environment-BhFvfkQg.js → environment-C7CKGIOE.js} +4 -4
  28. package/dist/{environment-BhFvfkQg.js.map → environment-C7CKGIOE.js.map} +1 -1
  29. package/dist/errors-BHervYGs.js +156 -0
  30. package/dist/errors-BHervYGs.js.map +1 -0
  31. package/dist/{file-watcher-Dciz09Rr.js → file-watcher-D1bdo9mq.js} +2 -2
  32. package/dist/{file-watcher-Dciz09Rr.js.map → file-watcher-D1bdo9mq.js.map} +1 -1
  33. package/dist/{headless-ui-B4FnKm11.js → headless-ui-6QuByWZ_.js} +2 -2
  34. package/dist/{headless-ui-B4FnKm11.js.map → headless-ui-6QuByWZ_.js.map} +1 -1
  35. package/dist/{interactive-DxHFVYr2.js → interactive-DUpW84WU.js} +2 -2
  36. package/dist/{interactive-DxHFVYr2.js.map → interactive-DUpW84WU.js.map} +1 -1
  37. package/dist/{local-dev-BN6NKQ0B.js → local-dev-DPZiIPCK.js} +1 -1
  38. package/dist/{local-dev-BN6NKQ0B.js.map → local-dev-DPZiIPCK.js.map} +1 -1
  39. package/dist/{mcp-t0UxAPur.js → mcp-CHo9h-WV.js} +2 -2
  40. package/dist/{mcp-t0UxAPur.js.map → mcp-CHo9h-WV.js.map} +1 -1
  41. package/dist/mcp-install-smoke-test.ts +477 -0
  42. package/dist/{mcp-prompt-streaming-ro98iUDc.js → mcp-prompt-streaming-CHRPxxd0.js} +4 -4
  43. package/dist/{mcp-prompt-streaming-ro98iUDc.js.map → mcp-prompt-streaming-CHRPxxd0.js.map} +1 -1
  44. package/dist/{non-interactive-BA2L_jDT.js → non-interactive-Cr-chffe.js} +7 -2
  45. package/dist/non-interactive-Cr-chffe.js.map +1 -0
  46. package/dist/{orchestrator-tools-vZmNsHy9.js → orchestrator-tools-Tx18_TMb.js} +3 -3
  47. package/dist/{orchestrator-tools-vZmNsHy9.js.map → orchestrator-tools-Tx18_TMb.js.map} +1 -1
  48. package/dist/{package-json-D0DCWpe5.js → package-json-GEU2VZlS.js} +1 -1
  49. package/dist/{package-json-D0DCWpe5.js.map → package-json-GEU2VZlS.js.map} +1 -1
  50. package/dist/{package-manager-DgqJdAQk.js → package-manager-CLfc31yf.js} +4 -4
  51. package/dist/package-manager-CLfc31yf.js.map +1 -0
  52. package/dist/{pi-nwrCARRp.js → pi-RlnYUHdb.js} +12 -11
  53. package/dist/{pi-nwrCARRp.js.map → pi-RlnYUHdb.js.map} +1 -1
  54. package/dist/{playground-xkEke_h0.js → playground-DQ633rje.js} +7 -7
  55. package/dist/{playground-xkEke_h0.js.map → playground-DQ633rje.js.map} +1 -1
  56. package/dist/{posthog-9To56cSd.js → posthog-DSn9bIZc.js} +2 -2
  57. package/dist/{posthog-9To56cSd.js.map → posthog-DSn9bIZc.js.map} +1 -1
  58. package/dist/{posthog-integration-CoPvN6YZ.js → posthog-integration-DFfBRGOC.js} +667 -37
  59. package/dist/posthog-integration-DFfBRGOC.js.map +1 -0
  60. package/dist/{provisioning-BYFSHSHY.js → provisioning-Cvy_vQHV.js} +3 -3
  61. package/dist/{provisioning-BYFSHSHY.js.map → provisioning-Cvy_vQHV.js.map} +1 -1
  62. package/dist/{queue-tools-BREbgGSC.js → queue-tools-BC9HxOV6.js} +33 -7
  63. package/dist/queue-tools-BC9HxOV6.js.map +1 -0
  64. package/dist/{registry-DGJQ_8QI.js → registry-DCAElOyj.js} +81 -81
  65. package/dist/{registry-DGJQ_8QI.js.map → registry-DCAElOyj.js.map} +1 -1
  66. package/dist/{security-wc-naGq5.js → security-CuSX3XVo.js} +21 -9
  67. package/dist/security-CuSX3XVo.js.map +1 -0
  68. package/dist/{setup-utils-Cz0wPLsQ.js → setup-utils-D1tv0v_R.js} +13 -13
  69. package/dist/{setup-utils-Cz0wPLsQ.js.map → setup-utils-D1tv0v_R.js.map} +1 -1
  70. package/dist/{start-tui-DDW9uVnD.js → start-tui-B5YfmqNr.js} +57 -25
  71. package/dist/start-tui-B5YfmqNr.js.map +1 -0
  72. package/dist/{steps-CZI0B24_.js → steps-CLaSMwfR.js} +7 -7
  73. package/dist/{steps-CZI0B24_.js.map → steps-CLaSMwfR.js.map} +1 -1
  74. package/dist/{store-xMkU8xAa.js → store-DzEgsAPN.js} +7 -6
  75. package/dist/{store-xMkU8xAa.js.map → store-DzEgsAPN.js.map} +1 -1
  76. package/dist/{subagent-BztacyoV.js → subagent-BUV6aD7p.js} +2 -2
  77. package/dist/{subagent-BztacyoV.js.map → subagent-BUV6aD7p.js.map} +1 -1
  78. package/dist/{task-CJ7x3McC.js → task-GnWId75q.js} +13 -12
  79. package/dist/{task-CJ7x3McC.js.map → task-GnWId75q.js.map} +1 -1
  80. package/dist/{task-stream-BK7JQ27G.js → task-stream-DSzvwJrD.js} +16 -9
  81. package/dist/task-stream-DSzvwJrD.js.map +1 -0
  82. package/dist/{tasks-FGzp_zBd.js → tasks-BO0W8ocx.js} +2 -2
  83. package/dist/{tasks-FGzp_zBd.js.map → tasks-BO0W8ocx.js.map} +1 -1
  84. package/dist/{telemetry-By56gAtF.js → telemetry-Vi9dWddJ.js} +3 -3
  85. package/dist/{telemetry-By56gAtF.js.map → telemetry-Vi9dWddJ.js.map} +1 -1
  86. package/dist/{terminal-C_rmkaku.js → terminal-B5wZK7aS.js} +73 -80
  87. package/dist/terminal-B5wZK7aS.js.map +1 -0
  88. package/dist/{tools-BpCJgMez.js → tools-C9cNluqc.js} +54 -47
  89. package/dist/tools-C9cNluqc.js.map +1 -0
  90. package/dist/{wizard-abort-BlDla_Jd.js → wizard-abort-BsNbguJt.js} +1 -1
  91. package/dist/wizard-abort-CGv3lVxw.js +71 -0
  92. package/dist/wizard-abort-CGv3lVxw.js.map +1 -0
  93. package/dist/{wizard-session-Bn6dO1gE.js → wizard-session-Cex1BiXs.js} +3 -2
  94. package/dist/wizard-session-Cex1BiXs.js.map +1 -0
  95. package/dist/{wizard-session-UxA_A0cA.js → wizard-session-DHbUcjI7.js} +1 -1
  96. package/dist/yara-hooks-C3Vm2Gow.js +2 -0
  97. package/dist/{yara-hooks-BrisBebM.js → yara-hooks-DZIVzhA6.js} +57 -8
  98. package/dist/yara-hooks-DZIVzhA6.js.map +1 -0
  99. package/package.json +2 -1
  100. package/dist/add-mcp-server-to-clients-ArtlMX9-.js.map +0 -1
  101. package/dist/agent-interface-ORzGEFNM.js.map +0 -1
  102. package/dist/agent-runner-Ca-e2TOQ.js.map +0 -1
  103. package/dist/analytics-C4j6grao.js +0 -2
  104. package/dist/ci-install-D1QqmJIc.js.map +0 -1
  105. package/dist/debug-Cm1hvkVy.js.map +0 -1
  106. package/dist/non-interactive-BA2L_jDT.js.map +0 -1
  107. package/dist/package-manager-DgqJdAQk.js.map +0 -1
  108. package/dist/posthog-integration-CoPvN6YZ.js.map +0 -1
  109. package/dist/queue-tools-BREbgGSC.js.map +0 -1
  110. package/dist/security-wc-naGq5.js.map +0 -1
  111. package/dist/start-tui-DDW9uVnD.js.map +0 -1
  112. package/dist/task-stream-BK7JQ27G.js.map +0 -1
  113. package/dist/terminal-C_rmkaku.js.map +0 -1
  114. package/dist/tools-BpCJgMez.js.map +0 -1
  115. package/dist/wizard-abort-CzwID162.js +0 -49
  116. package/dist/wizard-abort-CzwID162.js.map +0 -1
  117. package/dist/wizard-session-Bn6dO1gE.js.map +0 -1
  118. package/dist/yara-hooks-BrisBebM.js.map +0 -1
  119. package/dist/yara-hooks-D2B7Fd9G.js +0 -2
@@ -0,0 +1,156 @@
1
+ //#region src/lib/errors/codes.ts
2
+ const ErrorCodes = {
3
+ CliNodeVersion: "PHW_CLI_NODE_VERSION",
4
+ CliBadArgs: "PHW_CLI_BAD_ARGS",
5
+ CliFlagUnavailable: "PHW_CLI_FLAG_UNAVAILABLE",
6
+ CliInteractiveRequired: "PHW_CLI_INTERACTIVE_REQUIRED",
7
+ ArgsMissingApiKey: "PHW_ARGS_MISSING_API_KEY",
8
+ ArgsMissingInstallDir: "PHW_ARGS_MISSING_INSTALL_DIR",
9
+ ArgsMissingEmail: "PHW_ARGS_MISSING_EMAIL",
10
+ ArgsSignupProvisionFailed: "PHW_ARGS_SIGNUP_PROVISION_FAILED",
11
+ AuthKeyType: "PHW_AUTH_KEY_TYPE",
12
+ AuthMissingScope: "PHW_AUTH_MISSING_SCOPE",
13
+ AuthRegionMismatch: "PHW_AUTH_REGION_MISMATCH",
14
+ AuthInvalidOrExpired: "PHW_AUTH_INVALID_OR_EXPIRED",
15
+ AuthSettingsConflict: "PHW_AUTH_SETTINGS_CONFLICT",
16
+ AuthStoredLoginConflict: "PHW_AUTH_STORED_LOGIN_CONFLICT",
17
+ AuthProjectFetchFailed: "PHW_AUTH_PROJECT_FETCH_FAILED",
18
+ EnvLocalServicesDown: "PHW_ENV_LOCAL_SERVICES_DOWN",
19
+ EnvServiceOutage: "PHW_ENV_SERVICE_OUTAGE",
20
+ DetectBadDirectory: "PHW_DETECT_BAD_DIRECTORY",
21
+ DetectNoFramework: "PHW_DETECT_NO_FRAMEWORK",
22
+ DetectUnsupportedVersion: "PHW_DETECT_UNSUPPORTED_VERSION",
23
+ DetectUnsupportedPlatform: "PHW_DETECT_UNSUPPORTED_PLATFORM",
24
+ DetectNoPosthogSdk: "PHW_DETECT_NO_POSTHOG_SDK",
25
+ DetectNoProjectFiles: "PHW_DETECT_NO_PROJECT_FILES",
26
+ DetectNoSources: "PHW_DETECT_NO_SOURCES",
27
+ DetectNoPackageJson: "PHW_DETECT_NO_PACKAGE_JSON",
28
+ DetectNoSdks: "PHW_DETECT_NO_SDKS",
29
+ DetectMissingStripe: "PHW_DETECT_MISSING_STRIPE",
30
+ DetectUnclassified: "PHW_DETECT_UNCLASSIFIED",
31
+ SkillMenuFetchFailed: "PHW_SKILL_MENU_FETCH_FAILED",
32
+ SkillNotFound: "PHW_SKILL_NOT_FOUND",
33
+ SkillDownloadFailed: "PHW_SKILL_DOWNLOAD_FAILED",
34
+ AgentAbort: "PHW_AGENT_ABORT",
35
+ AgentMcpMissing: "PHW_AGENT_MCP_MISSING",
36
+ AgentResourceMissing: "PHW_AGENT_RESOURCE_MISSING",
37
+ AgentRateLimit: "PHW_AGENT_RATE_LIMIT",
38
+ AgentApiError: "PHW_AGENT_API_ERROR",
39
+ AgentYaraViolation: "PHW_AGENT_YARA_VIOLATION",
40
+ AgentNoProgress: "PHW_AGENT_NO_PROGRESS",
41
+ AgentIncompleteTasks: "PHW_AGENT_INCOMPLETE_TASKS",
42
+ AgentOrchestratorSkillVariantMissing: "PHW_AGENT_ORCHESTRATOR_SKILL_VARIANT_MISSING",
43
+ AgentOrchestratorTasksFailed: "PHW_AGENT_ORCHESTRATOR_TASKS_FAILED",
44
+ AgentOrchestratorSinkInvariant: "PHW_AGENT_ORCHESTRATOR_SINK_INVARIANT",
45
+ SettingsUnfixableConflict: "PHW_SETTINGS_UNFIXABLE_CONFLICT",
46
+ InternalUnhandled: "PHW_INTERNAL_UNHANDLED"
47
+ };
48
+ //#endregion
49
+ //#region src/lib/errors/emit.ts
50
+ const PHW_ERROR_PREFIX = "phw-error:";
51
+ function formatWizardErrorLine(line) {
52
+ return `${PHW_ERROR_PREFIX} ${JSON.stringify(line)}`;
53
+ }
54
+ function emitWizardError(line) {
55
+ process.stderr.write(`${formatWizardErrorLine(line)}\n`);
56
+ }
57
+ ErrorCodes.CliNodeVersion, ErrorCodes.CliBadArgs, ErrorCodes.CliFlagUnavailable, ErrorCodes.CliInteractiveRequired, ErrorCodes.ArgsMissingApiKey, ErrorCodes.ArgsMissingInstallDir, ErrorCodes.ArgsMissingEmail, ErrorCodes.ArgsSignupProvisionFailed, ErrorCodes.AuthKeyType, ErrorCodes.AuthInvalidOrExpired, ErrorCodes.AuthMissingScope, ErrorCodes.AuthRegionMismatch, ErrorCodes.AuthSettingsConflict, ErrorCodes.AuthStoredLoginConflict, ErrorCodes.AuthProjectFetchFailed, ErrorCodes.EnvLocalServicesDown, ErrorCodes.EnvServiceOutage, ErrorCodes.DetectBadDirectory, ErrorCodes.DetectNoFramework, ErrorCodes.DetectUnsupportedVersion, ErrorCodes.DetectUnsupportedPlatform, ErrorCodes.DetectNoPosthogSdk, ErrorCodes.DetectNoProjectFiles, ErrorCodes.DetectNoSources, ErrorCodes.DetectNoPackageJson, ErrorCodes.DetectNoSdks, ErrorCodes.DetectMissingStripe, ErrorCodes.DetectUnclassified, ErrorCodes.SkillMenuFetchFailed, ErrorCodes.SkillNotFound, ErrorCodes.SkillDownloadFailed, ErrorCodes.AgentAbort, ErrorCodes.AgentMcpMissing, ErrorCodes.AgentResourceMissing, ErrorCodes.AgentRateLimit, ErrorCodes.AgentApiError, ErrorCodes.AgentYaraViolation, ErrorCodes.AgentNoProgress, ErrorCodes.AgentIncompleteTasks, ErrorCodes.AgentOrchestratorSkillVariantMissing, ErrorCodes.AgentOrchestratorTasksFailed, ErrorCodes.AgentOrchestratorSinkInvariant, ErrorCodes.SettingsUnfixableConflict, ErrorCodes.InternalUnhandled;
58
+ //#endregion
59
+ //#region src/lib/errors/auth.ts
60
+ function classifyAuthFailure(input) {
61
+ if (input.usingManagedLogin) return ErrorCodes.AuthStoredLoginConflict;
62
+ if (input.hasSettingsConflict) return ErrorCodes.AuthSettingsConflict;
63
+ if (input.apiKey && !input.apiKey.startsWith("phx_") && !input.apiKey.startsWith("pha_")) return ErrorCodes.AuthKeyType;
64
+ if (input.missingScopes && input.missingScopes.length > 0) return ErrorCodes.AuthMissingScope;
65
+ if (input.gatewayRegion && input.sessionRegion && input.gatewayRegion !== "local" && input.gatewayRegion !== input.sessionRegion) return ErrorCodes.AuthRegionMismatch;
66
+ return ErrorCodes.AuthInvalidOrExpired;
67
+ }
68
+ //#endregion
69
+ //#region src/lib/agent/signals.ts
70
+ /**
71
+ * Agent signal vocabulary — the marker strings the agent emits and the error
72
+ * taxonomy the runner returns. Kept as a dependency-free leaf module so both
73
+ * `agent-interface.ts` and `output-signals.ts` can import it without a cycle.
74
+ */
75
+ const AgentSignals = {
76
+ STATUS: "[STATUS]",
77
+ ERROR_MCP_MISSING: "[ERROR-MCP-MISSING]",
78
+ ERROR_RESOURCE_MISSING: "[ERROR-RESOURCE-MISSING]",
79
+ SKILL_INSTALL_FAILED: "[SKILL-INSTALL-FAILED]",
80
+ ABORT: "[ABORT]",
81
+ WIZARD_REMARK: "[WIZARD-REMARK]",
82
+ BENCHMARK: "[BENCHMARK]",
83
+ DASHBOARD_URL: "[DASHBOARD_URL]",
84
+ NOTEBOOK_URL: "[NOTEBOOK_URL]"
85
+ };
86
+ /**
87
+ * End-of-run reflection ask, shared by both harnesses so remarks are
88
+ * comparable. The format clause comes FIRST and nothing trails the marker —
89
+ * literal models (gpt-5-mini) echo whatever text follows it. The parser also
90
+ * drops remarks that quote this instruction (see AgentOutputSignals.remark).
91
+ */
92
+ const REMARK_INSTRUCTION = `Reply with a single line that starts with ${AgentSignals.WIZARD_REMARK} and no other lines. In that line, state briefly what information or guidance would have been useful to have in the integration prompt or documentation for this run — specifically anything that would have prevented tool failures, erroneous edits, or other wasted turns.`;
93
+ //#endregion
94
+ //#region src/lib/errors/agent-map.ts
95
+ const AGENT_ERROR_CODE = {
96
+ ["WIZARD_MCP_MISSING"]: ErrorCodes.AgentMcpMissing,
97
+ ["WIZARD_RESOURCE_MISSING"]: ErrorCodes.AgentResourceMissing,
98
+ ["WIZARD_RATE_LIMIT"]: ErrorCodes.AgentRateLimit,
99
+ ["WIZARD_API_ERROR"]: ErrorCodes.AgentApiError,
100
+ ["WIZARD_YARA_VIOLATION"]: ErrorCodes.AgentYaraViolation,
101
+ ["WIZARD_ABORT"]: ErrorCodes.AgentAbort,
102
+ ["WIZARD_NO_PROGRESS"]: ErrorCodes.AgentNoProgress,
103
+ ["WIZARD_INCOMPLETE_TASKS"]: ErrorCodes.AgentIncompleteTasks
104
+ };
105
+ //#endregion
106
+ //#region src/lib/errors/detect-map.ts
107
+ const DETECT_CODES = {
108
+ "bad-directory": ErrorCodes.DetectBadDirectory,
109
+ "unsupported-platform": ErrorCodes.DetectUnsupportedPlatform,
110
+ "no-project-files": ErrorCodes.DetectNoProjectFiles,
111
+ "no-sources": ErrorCodes.DetectNoSources,
112
+ "no-package-json": ErrorCodes.DetectNoPackageJson,
113
+ "no-sdks": ErrorCodes.DetectNoSdks,
114
+ "missing-stripe": ErrorCodes.DetectMissingStripe,
115
+ "no-posthog-sdk": ErrorCodes.DetectNoPosthogSdk,
116
+ "no-posthog": ErrorCodes.DetectNoPosthogSdk,
117
+ "missing-posthog": ErrorCodes.DetectNoPosthogSdk
118
+ };
119
+ /**
120
+ * `kind` arrives as a bare string — `frameworkContext.detectError` is untyped
121
+ * storage — so the lookup can still miss. It falls back to a detect-group code
122
+ * with `retry: 'no'`, never to `InternalUnhandled`: an unrecognized precondition
123
+ * failure is still a precondition failure, and telling a sandbox to retry one
124
+ * costs it the whole budget.
125
+ */
126
+ function detectErrorCode(kind) {
127
+ return DETECT_CODES[kind] ?? ErrorCodes.DetectUnclassified;
128
+ }
129
+ //#endregion
130
+ //#region src/lib/errors/skill-map.ts
131
+ const SKILL_CODES = {
132
+ "menu-fetch-failed": ErrorCodes.SkillMenuFetchFailed,
133
+ "skill-not-found": ErrorCodes.SkillNotFound,
134
+ "download-failed": ErrorCodes.SkillDownloadFailed
135
+ };
136
+ function skillErrorCode(result) {
137
+ if (result.kind === "ok") return null;
138
+ return SKILL_CODES[result.kind];
139
+ }
140
+ //#endregion
141
+ //#region src/lib/errors/sanitize.ts
142
+ const DETAIL_ALLOWLIST = [
143
+ "reason",
144
+ "detected",
145
+ "platform"
146
+ ];
147
+ function sanitizeErrorDetail(detail) {
148
+ if (!detail) return void 0;
149
+ const safe = {};
150
+ for (const key of DETAIL_ALLOWLIST) if (detail[key] !== void 0) safe[key] = detail[key];
151
+ return Object.keys(safe).length > 0 ? safe : void 0;
152
+ }
153
+ //#endregion
154
+ export { AgentSignals as a, emitWizardError as c, AGENT_ERROR_CODE as i, ErrorCodes as l, skillErrorCode as n, REMARK_INSTRUCTION as o, detectErrorCode as r, classifyAuthFailure as s, sanitizeErrorDetail as t };
155
+
156
+ //# sourceMappingURL=errors-BHervYGs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-BHervYGs.js","names":[],"sources":["../src/lib/errors/codes.ts","../src/lib/errors/emit.ts","../src/lib/errors/catalog.ts","../src/lib/errors/auth.ts","../src/lib/agent/signals.ts","../src/lib/errors/agent-map.ts","../src/lib/errors/detect-map.ts","../src/lib/errors/skill-map.ts","../src/lib/errors/sanitize.ts"],"sourcesContent":["export const ErrorCodes = {\n CliNodeVersion: 'PHW_CLI_NODE_VERSION',\n CliBadArgs: 'PHW_CLI_BAD_ARGS',\n CliFlagUnavailable: 'PHW_CLI_FLAG_UNAVAILABLE',\n CliInteractiveRequired: 'PHW_CLI_INTERACTIVE_REQUIRED',\n ArgsMissingApiKey: 'PHW_ARGS_MISSING_API_KEY',\n ArgsMissingInstallDir: 'PHW_ARGS_MISSING_INSTALL_DIR',\n ArgsMissingEmail: 'PHW_ARGS_MISSING_EMAIL',\n ArgsSignupProvisionFailed: 'PHW_ARGS_SIGNUP_PROVISION_FAILED',\n AuthKeyType: 'PHW_AUTH_KEY_TYPE',\n AuthMissingScope: 'PHW_AUTH_MISSING_SCOPE',\n AuthRegionMismatch: 'PHW_AUTH_REGION_MISMATCH',\n AuthInvalidOrExpired: 'PHW_AUTH_INVALID_OR_EXPIRED',\n AuthSettingsConflict: 'PHW_AUTH_SETTINGS_CONFLICT',\n AuthStoredLoginConflict: 'PHW_AUTH_STORED_LOGIN_CONFLICT',\n AuthProjectFetchFailed: 'PHW_AUTH_PROJECT_FETCH_FAILED',\n EnvLocalServicesDown: 'PHW_ENV_LOCAL_SERVICES_DOWN',\n EnvServiceOutage: 'PHW_ENV_SERVICE_OUTAGE',\n DetectBadDirectory: 'PHW_DETECT_BAD_DIRECTORY',\n DetectNoFramework: 'PHW_DETECT_NO_FRAMEWORK',\n DetectUnsupportedVersion: 'PHW_DETECT_UNSUPPORTED_VERSION',\n DetectUnsupportedPlatform: 'PHW_DETECT_UNSUPPORTED_PLATFORM',\n DetectNoPosthogSdk: 'PHW_DETECT_NO_POSTHOG_SDK',\n DetectNoProjectFiles: 'PHW_DETECT_NO_PROJECT_FILES',\n DetectNoSources: 'PHW_DETECT_NO_SOURCES',\n DetectNoPackageJson: 'PHW_DETECT_NO_PACKAGE_JSON',\n DetectNoSdks: 'PHW_DETECT_NO_SDKS',\n DetectMissingStripe: 'PHW_DETECT_MISSING_STRIPE',\n DetectUnclassified: 'PHW_DETECT_UNCLASSIFIED',\n SkillMenuFetchFailed: 'PHW_SKILL_MENU_FETCH_FAILED',\n SkillNotFound: 'PHW_SKILL_NOT_FOUND',\n SkillDownloadFailed: 'PHW_SKILL_DOWNLOAD_FAILED',\n AgentAbort: 'PHW_AGENT_ABORT',\n AgentMcpMissing: 'PHW_AGENT_MCP_MISSING',\n AgentResourceMissing: 'PHW_AGENT_RESOURCE_MISSING',\n AgentRateLimit: 'PHW_AGENT_RATE_LIMIT',\n AgentApiError: 'PHW_AGENT_API_ERROR',\n AgentYaraViolation: 'PHW_AGENT_YARA_VIOLATION',\n AgentNoProgress: 'PHW_AGENT_NO_PROGRESS',\n AgentIncompleteTasks: 'PHW_AGENT_INCOMPLETE_TASKS',\n AgentOrchestratorSkillVariantMissing:\n 'PHW_AGENT_ORCHESTRATOR_SKILL_VARIANT_MISSING',\n AgentOrchestratorTasksFailed: 'PHW_AGENT_ORCHESTRATOR_TASKS_FAILED',\n AgentOrchestratorSinkInvariant: 'PHW_AGENT_ORCHESTRATOR_SINK_INVARIANT',\n SettingsUnfixableConflict: 'PHW_SETTINGS_UNFIXABLE_CONFLICT',\n InternalUnhandled: 'PHW_INTERNAL_UNHANDLED',\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\nexport const ERROR_CODE_PATTERN = /^PHW_[A-Z][A-Z0-9_]*$/;\n\nexport function isErrorCode(value: string): value is ErrorCode {\n return (Object.values(ErrorCodes) as string[]).includes(value);\n}\n","import type { ErrorCode } from './codes';\n\nexport const PHW_ERROR_PREFIX = 'phw-error:';\n\nexport interface WizardErrorLine {\n code: ErrorCode;\n message: string;\n detail?: Record<string, unknown>;\n}\n\nexport function formatWizardErrorLine(line: WizardErrorLine): string {\n return `${PHW_ERROR_PREFIX} ${JSON.stringify(line)}`;\n}\n\nexport function emitWizardError(line: WizardErrorLine): void {\n process.stderr.write(`${formatWizardErrorLine(line)}\\n`);\n}\n","import { ErrorCodes, type ErrorCode } from './codes';\nimport type { ErrorCatalogEntry } from './types';\n\nexport const ERROR_CATALOG: Record<ErrorCode, ErrorCatalogEntry> = {\n [ErrorCodes.CliNodeVersion]: {\n group: 'cli',\n retry: 'no',\n description: 'Node.js runtime is older than the required range.',\n },\n [ErrorCodes.CliBadArgs]: {\n group: 'cli',\n retry: 'no',\n description: 'Unrecognized command or option.',\n },\n [ErrorCodes.CliFlagUnavailable]: {\n group: 'cli',\n retry: 'no',\n description: 'A dev-only flag or env var was passed to a published build.',\n },\n [ErrorCodes.CliInteractiveRequired]: {\n group: 'cli',\n retry: 'no',\n description:\n 'The command requires an interactive terminal and has no non-interactive fallback.',\n },\n [ErrorCodes.ArgsMissingApiKey]: {\n group: 'args',\n retry: 'no',\n description: 'Non-interactive run without --api-key.',\n },\n [ErrorCodes.ArgsMissingInstallDir]: {\n group: 'args',\n retry: 'no',\n description: 'Non-interactive run without --install-dir.',\n },\n [ErrorCodes.ArgsMissingEmail]: {\n group: 'args',\n retry: 'no',\n description: 'Signup run without --email.',\n },\n [ErrorCodes.ArgsSignupProvisionFailed]: {\n group: 'args',\n retry: 'yes',\n description: 'Account provisioning for --signup failed.',\n },\n [ErrorCodes.AuthKeyType]: {\n group: 'auth',\n retry: 'no',\n description: 'The API key has the wrong type or prefix for this mode.',\n },\n [ErrorCodes.AuthInvalidOrExpired]: {\n group: 'auth',\n retry: 'no',\n description: 'The credential was rejected by the LLM gateway or API.',\n },\n [ErrorCodes.AuthMissingScope]: {\n group: 'auth',\n retry: 'no',\n description: 'The personal API key lacks a scope the run requires.',\n },\n [ErrorCodes.AuthRegionMismatch]: {\n group: 'auth',\n retry: 'no',\n description: 'The resolved region does not match the credential.',\n },\n [ErrorCodes.AuthSettingsConflict]: {\n group: 'auth',\n retry: 'no',\n description: 'A Claude settings file overrides the gateway credential.',\n },\n [ErrorCodes.AuthStoredLoginConflict]: {\n group: 'auth',\n retry: 'no',\n description:\n 'The agent SDK used a stored Claude login instead of the gateway token.',\n },\n [ErrorCodes.AuthProjectFetchFailed]: {\n group: 'auth',\n retry: 'yes',\n description: 'Fetching user or project data from the PostHog API failed.',\n },\n [ErrorCodes.EnvLocalServicesDown]: {\n group: 'env',\n retry: 'yes',\n description: 'A local dev target service is not running.',\n },\n [ErrorCodes.EnvServiceOutage]: {\n group: 'env',\n retry: 'yes',\n description: 'Blocking external services are down.',\n },\n [ErrorCodes.DetectBadDirectory]: {\n group: 'detect',\n retry: 'no',\n description:\n 'The install directory is missing, not a directory, or unreadable.',\n },\n [ErrorCodes.DetectNoFramework]: {\n group: 'detect',\n retry: 'no',\n description: 'Framework auto-detection found no supported framework.',\n },\n [ErrorCodes.DetectUnsupportedVersion]: {\n group: 'detect',\n retry: 'no',\n description:\n 'The detected framework version is below the supported minimum.',\n },\n [ErrorCodes.DetectUnsupportedPlatform]: {\n group: 'detect',\n retry: 'no',\n description: 'The project platform has no matching skill variant.',\n },\n [ErrorCodes.DetectNoPosthogSdk]: {\n group: 'detect',\n retry: 'no',\n description:\n 'The program requires an installed PostHog SDK and none was found.',\n },\n [ErrorCodes.DetectNoProjectFiles]: {\n group: 'detect',\n retry: 'no',\n description: 'The project has no files for the program to work on.',\n },\n [ErrorCodes.DetectNoSources]: {\n group: 'detect',\n retry: 'no',\n description: 'No data warehouse sources were found.',\n },\n [ErrorCodes.DetectNoPackageJson]: {\n group: 'detect',\n retry: 'no',\n description: 'The project has no package.json for the program to scan.',\n },\n [ErrorCodes.DetectNoSdks]: {\n group: 'detect',\n retry: 'no',\n description: 'None of the SDKs the program needs are installed.',\n },\n [ErrorCodes.DetectMissingStripe]: {\n group: 'detect',\n retry: 'no',\n description: 'Revenue analytics requires a Stripe SDK and none was found.',\n },\n [ErrorCodes.DetectUnclassified]: {\n group: 'detect',\n // A detect step reported a precondition failure we have no code for yet.\n // Every known cause is a property of the user's project, so retrying can\n // only burn budget — fail closed rather than inheriting `internal`'s 'yes'.\n retry: 'no',\n description: 'A detect step failed with a kind absent from the catalog.',\n },\n [ErrorCodes.SkillMenuFetchFailed]: {\n group: 'skill',\n retry: 'yes',\n description: 'The context-mill skill menu could not be fetched.',\n },\n [ErrorCodes.SkillNotFound]: {\n group: 'skill',\n retry: 'no',\n description: 'The skill id is absent from the context-mill menu.',\n },\n [ErrorCodes.SkillDownloadFailed]: {\n group: 'skill',\n retry: 'yes',\n description: 'The skill download or extraction failed.',\n },\n [ErrorCodes.AgentAbort]: {\n group: 'agent',\n retry: 'case-by-case',\n description: 'The agent emitted an [ABORT] signal with a reason.',\n },\n [ErrorCodes.AgentMcpMissing]: {\n group: 'agent',\n retry: 'yes',\n description: 'The agent could not reach the PostHog MCP server.',\n },\n [ErrorCodes.AgentResourceMissing]: {\n group: 'agent',\n retry: 'yes',\n description: 'The agent could not access a setup resource.',\n },\n [ErrorCodes.AgentRateLimit]: {\n group: 'agent',\n retry: 'yes',\n description: 'The LLM gateway rate-limited the run.',\n },\n [ErrorCodes.AgentApiError]: {\n group: 'agent',\n retry: 'yes',\n description: 'The agent hit an API error other than a rate limit.',\n },\n [ErrorCodes.AgentYaraViolation]: {\n group: 'agent',\n retry: 'no',\n description: 'The security scanner terminated the run.',\n },\n [ErrorCodes.AgentNoProgress]: {\n group: 'agent',\n retry: 'case-by-case',\n description: 'The agent ended without a single tool call.',\n },\n [ErrorCodes.AgentIncompleteTasks]: {\n group: 'agent',\n retry: 'case-by-case',\n description: 'The agent stopped with planned tasks still open.',\n },\n [ErrorCodes.AgentOrchestratorSkillVariantMissing]: {\n group: 'agent',\n retry: 'yes',\n description: 'The orchestrator could not download a needed skill variant.',\n },\n [ErrorCodes.AgentOrchestratorTasksFailed]: {\n group: 'agent',\n retry: 'case-by-case',\n description: 'The orchestrator queue drained with failed or blocked tasks.',\n },\n [ErrorCodes.AgentOrchestratorSinkInvariant]: {\n group: 'agent',\n retry: 'no',\n description: 'The orchestrator plan failed the sink coverage invariant.',\n },\n [ErrorCodes.SettingsUnfixableConflict]: {\n group: 'settings',\n retry: 'no',\n description:\n 'A Claude settings conflict cannot be neutralized automatically.',\n },\n [ErrorCodes.InternalUnhandled]: {\n group: 'internal',\n retry: 'yes',\n description: 'An unexpected error escaped the pipeline.',\n },\n};\n","import { ErrorCodes, type ErrorCode } from './codes';\n\nexport interface AuthFailureInput {\n hasSettingsConflict?: boolean;\n usingManagedLogin?: boolean;\n apiKey?: string;\n missingScopes?: readonly string[];\n gatewayRegion?: 'us' | 'eu' | 'local';\n sessionRegion?: 'us' | 'eu';\n}\n\nexport function classifyAuthFailure(input: AuthFailureInput): ErrorCode {\n if (input.usingManagedLogin) return ErrorCodes.AuthStoredLoginConflict;\n if (input.hasSettingsConflict) return ErrorCodes.AuthSettingsConflict;\n if (\n input.apiKey &&\n !input.apiKey.startsWith('phx_') &&\n !input.apiKey.startsWith('pha_')\n ) {\n return ErrorCodes.AuthKeyType;\n }\n if (input.missingScopes && input.missingScopes.length > 0) {\n return ErrorCodes.AuthMissingScope;\n }\n if (\n input.gatewayRegion &&\n input.sessionRegion &&\n input.gatewayRegion !== 'local' &&\n input.gatewayRegion !== input.sessionRegion\n ) {\n return ErrorCodes.AuthRegionMismatch;\n }\n return ErrorCodes.AuthInvalidOrExpired;\n}\n","/**\n * Agent signal vocabulary — the marker strings the agent emits and the error\n * taxonomy the runner returns. Kept as a dependency-free leaf module so both\n * `agent-interface.ts` and `output-signals.ts` can import it without a cycle.\n */\n\nexport const AgentSignals = {\n /** Signal emitted when the agent reports progress to the user */\n STATUS: '[STATUS]',\n /** Signal emitted when the agent cannot access the PostHog MCP server */\n ERROR_MCP_MISSING: '[ERROR-MCP-MISSING]',\n /** Signal emitted when the agent cannot access the setup resource */\n ERROR_RESOURCE_MISSING: '[ERROR-RESOURCE-MISSING]',\n /**\n * Signal emitted when `install_skill` failed and the agent is continuing\n * the integration WITHOUT the skill (best-effort from its own knowledge).\n * Format: \"[SKILL-INSTALL-FAILED] <skill id — reason>\". Non-fatal by\n * design: a freestyled integration beats an outright failure, but the run\n * must be measurable — the runner captures it as an analytics event.\n */\n SKILL_INSTALL_FAILED: '[SKILL-INSTALL-FAILED]',\n /**\n * Signal emitted when the agent cannot complete the program and is\n * aborting intentionally (distinct from errors). Format: \"[ABORT] <reason>\".\n * Programs can declare an onAbort handler to render a custom screen.\n */\n ABORT: '[ABORT]',\n /** Signal emitted when the agent provides a remark about its run */\n WIZARD_REMARK: '[WIZARD-REMARK]',\n /** Signal prefix for benchmark logging */\n BENCHMARK: '[BENCHMARK]',\n /**\n * Signal emitted when the agent has created a PostHog dashboard for the\n * user. Format: `[DASHBOARD_URL] <full https url>`. The URL is captured\n * onto `session.dashboardUrl` and surfaced by programs in their outro.\n */\n DASHBOARD_URL: '[DASHBOARD_URL]',\n /**\n * Signal emitted when the agent has uploaded a report to a PostHog\n * notebook. Format: `[NOTEBOOK_URL] <full https url>`. The URL is captured\n * onto `session.notebookUrl` and surfaced by programs in their outro.\n */\n NOTEBOOK_URL: '[NOTEBOOK_URL]',\n} as const;\n\nexport type AgentSignal = (typeof AgentSignals)[keyof typeof AgentSignals];\n\n/**\n * End-of-run reflection ask, shared by both harnesses so remarks are\n * comparable. The format clause comes FIRST and nothing trails the marker —\n * literal models (gpt-5-mini) echo whatever text follows it. The parser also\n * drops remarks that quote this instruction (see AgentOutputSignals.remark).\n */\nexport const REMARK_INSTRUCTION = `Reply with a single line that starts with ${AgentSignals.WIZARD_REMARK} and no other lines. In that line, state briefly what information or guidance would have been useful to have in the integration prompt or documentation for this run — specifically anything that would have prevented tool failures, erroneous edits, or other wasted turns.`;\n\n/**\n * Error types that can be returned from agent execution.\n * These correspond to the error signals that the agent emits.\n */\nexport enum AgentErrorType {\n /** Agent could not access the PostHog MCP server */\n MCP_MISSING = 'WIZARD_MCP_MISSING',\n /** Agent could not access the setup resource */\n RESOURCE_MISSING = 'WIZARD_RESOURCE_MISSING',\n /** API rate limit exceeded */\n RATE_LIMIT = 'WIZARD_RATE_LIMIT',\n /** Generic API error */\n API_ERROR = 'WIZARD_API_ERROR',\n /** YARA scanner detected a security violation */\n YARA_VIOLATION = 'WIZARD_YARA_VIOLATION',\n /** Agent intentionally aborted the program (emitted [ABORT] <reason>) */\n ABORT = 'WIZARD_ABORT',\n /** Agent ended without making a single tool call — a no-op run that did no work */\n NO_PROGRESS = 'WIZARD_NO_PROGRESS',\n /** Agent acted but stopped short — planned tasks left open and/or no skill installed */\n INCOMPLETE_TASKS = 'WIZARD_INCOMPLETE_TASKS',\n}\n","import { AgentErrorType } from '../agent/signals';\nimport { ErrorCodes, type ErrorCode } from './codes';\n\nexport const AGENT_ERROR_CODE: Record<AgentErrorType, ErrorCode> = {\n [AgentErrorType.MCP_MISSING]: ErrorCodes.AgentMcpMissing,\n [AgentErrorType.RESOURCE_MISSING]: ErrorCodes.AgentResourceMissing,\n [AgentErrorType.RATE_LIMIT]: ErrorCodes.AgentRateLimit,\n [AgentErrorType.API_ERROR]: ErrorCodes.AgentApiError,\n [AgentErrorType.YARA_VIOLATION]: ErrorCodes.AgentYaraViolation,\n [AgentErrorType.ABORT]: ErrorCodes.AgentAbort,\n [AgentErrorType.NO_PROGRESS]: ErrorCodes.AgentNoProgress,\n [AgentErrorType.INCOMPLETE_TASKS]: ErrorCodes.AgentIncompleteTasks,\n};\n","import { ErrorCodes, type ErrorCode } from './codes';\nimport type { RevenueDetectError } from '@lib/programs/revenue-analytics/detect';\nimport type { SelfDrivingDetectError } from '@lib/programs/self-driving/detect';\nimport type { SourceMapsDetectError } from '@lib/programs/error-tracking-upload-source-maps/detect';\nimport type { WarehouseDetectError } from '@lib/programs/warehouse-source/detect';\nimport type { WebAnalyticsDetectError } from '@lib/programs/web-analytics-doctor/detect';\n\n/**\n * Every `kind` a program detect step can write into\n * `frameworkContext.detectError`, assembled from the programs' own unions.\n * Type-only imports, so this adds no runtime edge from the catalog to the\n * programs (same shape as `skill-map.ts` keying on `InstallSkillResult`).\n *\n * The point is the compile error: add a kind to any program's `DetectError`\n * and `DETECT_CODES` stops type-checking until it gets a code.\n */\nexport type DetectErrorKind =\n | RevenueDetectError['kind']\n | SelfDrivingDetectError['kind']\n | SourceMapsDetectError['kind']\n | WarehouseDetectError['kind']\n | WebAnalyticsDetectError['kind'];\n\nconst DETECT_CODES: Record<DetectErrorKind, ErrorCode> = {\n 'bad-directory': ErrorCodes.DetectBadDirectory,\n 'unsupported-platform': ErrorCodes.DetectUnsupportedPlatform,\n 'no-project-files': ErrorCodes.DetectNoProjectFiles,\n 'no-sources': ErrorCodes.DetectNoSources,\n 'no-package-json': ErrorCodes.DetectNoPackageJson,\n 'no-sdks': ErrorCodes.DetectNoSdks,\n 'missing-stripe': ErrorCodes.DetectMissingStripe,\n // Three kinds, one failure class: the program needs a PostHog SDK and the\n // project has none. Hosts that care which program asked read `detail.kind`.\n 'no-posthog-sdk': ErrorCodes.DetectNoPosthogSdk,\n 'no-posthog': ErrorCodes.DetectNoPosthogSdk,\n 'missing-posthog': ErrorCodes.DetectNoPosthogSdk,\n};\n\n/**\n * `kind` arrives as a bare string — `frameworkContext.detectError` is untyped\n * storage — so the lookup can still miss. It falls back to a detect-group code\n * with `retry: 'no'`, never to `InternalUnhandled`: an unrecognized precondition\n * failure is still a precondition failure, and telling a sandbox to retry one\n * costs it the whole budget.\n */\nexport function detectErrorCode(kind: string): ErrorCode {\n return DETECT_CODES[kind as DetectErrorKind] ?? ErrorCodes.DetectUnclassified;\n}\n","import { ErrorCodes, type ErrorCode } from './codes';\nimport type { InstallSkillResult } from '@lib/wizard-tools';\n\nconst SKILL_CODES: Record<\n Exclude<InstallSkillResult['kind'], 'ok'>,\n ErrorCode\n> = {\n 'menu-fetch-failed': ErrorCodes.SkillMenuFetchFailed,\n 'skill-not-found': ErrorCodes.SkillNotFound,\n 'download-failed': ErrorCodes.SkillDownloadFailed,\n};\n\nexport function skillErrorCode(result: InstallSkillResult): ErrorCode | null {\n if (result.kind === 'ok') return null;\n return SKILL_CODES[result.kind];\n}\n","const DETAIL_ALLOWLIST = ['reason', 'detected', 'platform'] as const;\n\nexport function sanitizeErrorDetail(\n detail: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!detail) return undefined;\n const safe: Record<string, unknown> = {};\n for (const key of DETAIL_ALLOWLIST) {\n if (detail[key] !== undefined) safe[key] = detail[key];\n }\n return Object.keys(safe).length > 0 ? safe : undefined;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { s as logToFile } from "./debug-Cm1hvkVy.js";
1
+ import { s as logToFile } from "./debug-BsHD83Vy.js";
2
2
  import * as fs$1 from "fs";
3
3
  import { basename, dirname } from "node:path";
4
4
  //#region src/lib/file-watcher.ts
@@ -120,4 +120,4 @@ function startFileWatcher(path, onUpdate, options = {}) {
120
120
  //#endregion
121
121
  export { startFileWatcher as t };
122
122
 
123
- //# sourceMappingURL=file-watcher-Dciz09Rr.js.map
123
+ //# sourceMappingURL=file-watcher-D1bdo9mq.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-watcher-Dciz09Rr.js","names":["fs"],"sources":["../src/lib/file-watcher.ts"],"sourcesContent":["/**\n * JSON file watcher shared by runner and UI machinery.\n *\n * `fs.watch` alone is unreliable for atomic-rename writes, so the watcher\n * pairs it with a continuous mtime-polled re-read. The poll catches missed\n * events; the watch keeps latency low when it does fire.\n */\n\nimport * as fs from 'fs';\nimport { basename, dirname } from 'node:path';\nimport { logToFile } from '@utils/debug';\n\nconst DEFAULT_POLL_INTERVAL_MS = 5000;\nconst DEFAULT_ATTACH_RETRY_INTERVAL_MS = 1000;\nconst DEFAULT_WATCH_DEBOUNCE_MS = 25;\n\nexport interface FileWatcherHandle {\n refresh(): void;\n stop(): void;\n}\n\nexport interface FileWatcherOptions {\n /** ms between mtime checks once the file exists. */\n pollIntervalMs?: number;\n /** ms between attach attempts while waiting for the file to appear. */\n attachRetryIntervalMs?: number;\n /** ms to coalesce duplicate filesystem events. */\n watchDebounceMs?: number;\n /** Ignore the file that exists when the watcher starts until it changes. */\n ignoreInitialFile?: boolean;\n /** Refuse to read files larger than this many bytes. */\n maxFileSizeBytes?: number;\n}\n\n/** Watch `path` for JSON updates and call `onUpdate(parsed)` whenever the\n * file's mtime changes and the contents are valid JSON. Caller must invoke\n * `handle.stop()` to release the watcher. */\nexport function startFileWatcher(\n path: string,\n onUpdate: (parsed: unknown) => void,\n options: FileWatcherOptions = {},\n): FileWatcherHandle {\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const attachRetryIntervalMs =\n options.attachRetryIntervalMs ?? DEFAULT_ATTACH_RETRY_INTERVAL_MS;\n const watchDebounceMs = options.watchDebounceMs ?? DEFAULT_WATCH_DEBOUNCE_MS;\n\n const watchers: fs.FSWatcher[] = [];\n const intervals: Array<ReturnType<typeof setInterval>> = [];\n const targetDir = dirname(path);\n const targetName = basename(path);\n let lastMtimeMs = 0;\n let ignoredInitialSignature: string | null = null;\n let watchDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n let lastReadErrorSignature: string | null = null;\n let stopped = false;\n\n const signature = (stat: fs.Stats): string =>\n `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}:${stat.ctimeMs}`;\n\n if (options.ignoreInitialFile) {\n try {\n const stat = fs.lstatSync(path);\n if (stat.isFile() && !stat.isSymbolicLink()) {\n ignoredInitialSignature = signature(stat);\n }\n } catch {\n // No initial file to ignore.\n }\n }\n\n const logReadError = (errorSignature: string, message: string) => {\n if (lastReadErrorSignature === errorSignature) return;\n lastReadErrorSignature = errorSignature;\n logToFile(`[file-watcher] ${message}: ${path}`);\n };\n\n const read = (force = false) => {\n let stat: fs.Stats;\n try {\n stat = fs.lstatSync(path);\n } catch {\n return;\n }\n\n if (!stat.isFile() || stat.isSymbolicLink()) return;\n const fileSignature = signature(stat);\n\n try {\n if (ignoredInitialSignature) {\n if (fileSignature === ignoredInitialSignature) return;\n ignoredInitialSignature = null;\n }\n if (\n options.maxFileSizeBytes !== undefined &&\n stat.size > options.maxFileSizeBytes\n ) {\n logReadError(\n `oversized:${fileSignature}`,\n `refusing oversized JSON file (${stat.size} bytes, limit ${options.maxFileSizeBytes} bytes)`,\n );\n return;\n }\n if (!force && stat.mtimeMs === lastMtimeMs) return;\n lastMtimeMs = stat.mtimeMs;\n const parsed: unknown = JSON.parse(fs.readFileSync(path, 'utf-8'));\n lastReadErrorSignature = null;\n onUpdate(parsed);\n } catch (error) {\n logReadError(\n `invalid:${fileSignature}:${String(error)}`,\n `could not read valid JSON (${String(error)})`,\n );\n }\n };\n\n const scheduleRead = () => {\n if (stopped) return;\n if (watchDebounceTimer) clearTimeout(watchDebounceTimer);\n watchDebounceTimer = setTimeout(() => {\n watchDebounceTimer = null;\n read(true);\n }, watchDebounceMs);\n };\n\n const attachWatch = () => {\n watchers.push(\n fs.watch(targetDir, (_eventType, filename) => {\n if (filename == null || filename.toString() === targetName) {\n scheduleRead();\n }\n }),\n );\n };\n\n intervals.push(setInterval(() => read(), pollIntervalMs));\n\n try {\n attachWatch();\n // Defer the initial callback until the caller has received the handle, so\n // callbacks that stop their watcher cannot race handle assignment.\n queueMicrotask(() => {\n if (!stopped) read(true);\n });\n } catch {\n // Parent directory does not exist yet. Polling still covers a later file;\n // retry attaching the low-latency directory watcher until it appears.\n const attachInterval = setInterval(() => {\n try {\n fs.accessSync(targetDir);\n clearInterval(attachInterval);\n const idx = intervals.indexOf(attachInterval);\n if (idx >= 0) intervals.splice(idx, 1);\n attachWatch();\n read(true);\n } catch {\n // Still waiting.\n }\n }, attachRetryIntervalMs);\n intervals.push(attachInterval);\n }\n\n return {\n refresh() {\n if (stopped) return;\n if (watchDebounceTimer) {\n clearTimeout(watchDebounceTimer);\n watchDebounceTimer = null;\n }\n read(true);\n },\n stop() {\n stopped = true;\n if (watchDebounceTimer) {\n clearTimeout(watchDebounceTimer);\n watchDebounceTimer = null;\n }\n for (const watcher of watchers) watcher.close();\n for (const interval of intervals) clearInterval(interval);\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"file-watcher-D1bdo9mq.js","names":["fs"],"sources":["../src/lib/file-watcher.ts"],"sourcesContent":["/**\n * JSON file watcher shared by runner and UI machinery.\n *\n * `fs.watch` alone is unreliable for atomic-rename writes, so the watcher\n * pairs it with a continuous mtime-polled re-read. The poll catches missed\n * events; the watch keeps latency low when it does fire.\n */\n\nimport * as fs from 'fs';\nimport { basename, dirname } from 'node:path';\nimport { logToFile } from '@utils/debug';\n\nconst DEFAULT_POLL_INTERVAL_MS = 5000;\nconst DEFAULT_ATTACH_RETRY_INTERVAL_MS = 1000;\nconst DEFAULT_WATCH_DEBOUNCE_MS = 25;\n\nexport interface FileWatcherHandle {\n refresh(): void;\n stop(): void;\n}\n\nexport interface FileWatcherOptions {\n /** ms between mtime checks once the file exists. */\n pollIntervalMs?: number;\n /** ms between attach attempts while waiting for the file to appear. */\n attachRetryIntervalMs?: number;\n /** ms to coalesce duplicate filesystem events. */\n watchDebounceMs?: number;\n /** Ignore the file that exists when the watcher starts until it changes. */\n ignoreInitialFile?: boolean;\n /** Refuse to read files larger than this many bytes. */\n maxFileSizeBytes?: number;\n}\n\n/** Watch `path` for JSON updates and call `onUpdate(parsed)` whenever the\n * file's mtime changes and the contents are valid JSON. Caller must invoke\n * `handle.stop()` to release the watcher. */\nexport function startFileWatcher(\n path: string,\n onUpdate: (parsed: unknown) => void,\n options: FileWatcherOptions = {},\n): FileWatcherHandle {\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const attachRetryIntervalMs =\n options.attachRetryIntervalMs ?? DEFAULT_ATTACH_RETRY_INTERVAL_MS;\n const watchDebounceMs = options.watchDebounceMs ?? DEFAULT_WATCH_DEBOUNCE_MS;\n\n const watchers: fs.FSWatcher[] = [];\n const intervals: Array<ReturnType<typeof setInterval>> = [];\n const targetDir = dirname(path);\n const targetName = basename(path);\n let lastMtimeMs = 0;\n let ignoredInitialSignature: string | null = null;\n let watchDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n let lastReadErrorSignature: string | null = null;\n let stopped = false;\n\n const signature = (stat: fs.Stats): string =>\n `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}:${stat.ctimeMs}`;\n\n if (options.ignoreInitialFile) {\n try {\n const stat = fs.lstatSync(path);\n if (stat.isFile() && !stat.isSymbolicLink()) {\n ignoredInitialSignature = signature(stat);\n }\n } catch {\n // No initial file to ignore.\n }\n }\n\n const logReadError = (errorSignature: string, message: string) => {\n if (lastReadErrorSignature === errorSignature) return;\n lastReadErrorSignature = errorSignature;\n logToFile(`[file-watcher] ${message}: ${path}`);\n };\n\n const read = (force = false) => {\n let stat: fs.Stats;\n try {\n stat = fs.lstatSync(path);\n } catch {\n return;\n }\n\n if (!stat.isFile() || stat.isSymbolicLink()) return;\n const fileSignature = signature(stat);\n\n try {\n if (ignoredInitialSignature) {\n if (fileSignature === ignoredInitialSignature) return;\n ignoredInitialSignature = null;\n }\n if (\n options.maxFileSizeBytes !== undefined &&\n stat.size > options.maxFileSizeBytes\n ) {\n logReadError(\n `oversized:${fileSignature}`,\n `refusing oversized JSON file (${stat.size} bytes, limit ${options.maxFileSizeBytes} bytes)`,\n );\n return;\n }\n if (!force && stat.mtimeMs === lastMtimeMs) return;\n lastMtimeMs = stat.mtimeMs;\n const parsed: unknown = JSON.parse(fs.readFileSync(path, 'utf-8'));\n lastReadErrorSignature = null;\n onUpdate(parsed);\n } catch (error) {\n logReadError(\n `invalid:${fileSignature}:${String(error)}`,\n `could not read valid JSON (${String(error)})`,\n );\n }\n };\n\n const scheduleRead = () => {\n if (stopped) return;\n if (watchDebounceTimer) clearTimeout(watchDebounceTimer);\n watchDebounceTimer = setTimeout(() => {\n watchDebounceTimer = null;\n read(true);\n }, watchDebounceMs);\n };\n\n const attachWatch = () => {\n watchers.push(\n fs.watch(targetDir, (_eventType, filename) => {\n if (filename == null || filename.toString() === targetName) {\n scheduleRead();\n }\n }),\n );\n };\n\n intervals.push(setInterval(() => read(), pollIntervalMs));\n\n try {\n attachWatch();\n // Defer the initial callback until the caller has received the handle, so\n // callbacks that stop their watcher cannot race handle assignment.\n queueMicrotask(() => {\n if (!stopped) read(true);\n });\n } catch {\n // Parent directory does not exist yet. Polling still covers a later file;\n // retry attaching the low-latency directory watcher until it appears.\n const attachInterval = setInterval(() => {\n try {\n fs.accessSync(targetDir);\n clearInterval(attachInterval);\n const idx = intervals.indexOf(attachInterval);\n if (idx >= 0) intervals.splice(idx, 1);\n attachWatch();\n read(true);\n } catch {\n // Still waiting.\n }\n }, attachRetryIntervalMs);\n intervals.push(attachInterval);\n }\n\n return {\n refresh() {\n if (stopped) return;\n if (watchDebounceTimer) {\n clearTimeout(watchDebounceTimer);\n watchDebounceTimer = null;\n }\n read(true);\n },\n stop() {\n stopped = true;\n if (watchDebounceTimer) {\n clearTimeout(watchDebounceTimer);\n watchDebounceTimer = null;\n }\n for (const watcher of watchers) watcher.close();\n for (const interval of intervals) clearInterval(interval);\n },\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { m as LoggingUI } from "./debug-Cm1hvkVy.js";
1
+ import { m as LoggingUI } from "./debug-BsHD83Vy.js";
2
2
  //#region src/ui/headless-ui.ts
3
3
  /**
4
4
  * `LoggingUI` plus it feeds run state into a `WizardStore` so the background
@@ -25,4 +25,4 @@ var HeadlessUI = class extends LoggingUI {
25
25
  //#endregion
26
26
  export { HeadlessUI };
27
27
 
28
- //# sourceMappingURL=headless-ui-B4FnKm11.js.map
28
+ //# sourceMappingURL=headless-ui-6QuByWZ_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"headless-ui-B4FnKm11.js","names":[],"sources":["../src/ui/headless-ui.ts"],"sourcesContent":["import { LoggingUI } from './logging-ui';\nimport type { WizardStore } from './tui/store';\n\n/**\n * `LoggingUI` plus it feeds run state into a `WizardStore` so the background\n * wizard-session sync (`TaskStreamPush`) can observe a headless run. We extend\n * `LoggingUI` (not `InkUI`) because its blocking/gate methods would wait on a\n * TUI that never renders; the runner drives phase transitions on the store\n * directly, so only UI-originated per-run updates tee through here. Runner\n * machinery loads agent-authored artifacts such as the event plan directly\n * into the store.\n */\nexport class HeadlessUI extends LoggingUI {\n constructor(private readonly store: WizardStore) {\n super();\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n super.syncTodos(todos);\n this.store.syncTodos(todos);\n }\n\n setHandoffText(text: string): void {\n this.store.setHandoffText(text);\n }\n}\n"],"mappings":";;;;;;;;;;;AAYA,IAAa,aAAb,cAAgC,UAAU;CACxC,YAAY,OAAqC;AAC/C,SAAO;AADoB,OAAA,QAAA;;CAI7B,UACE,OACM;AACN,QAAM,UAAU,MAAM;AACtB,OAAK,MAAM,UAAU,MAAM;;CAG7B,eAAe,MAAoB;AACjC,OAAK,MAAM,eAAe,KAAK"}
1
+ {"version":3,"file":"headless-ui-6QuByWZ_.js","names":[],"sources":["../src/ui/headless-ui.ts"],"sourcesContent":["import { LoggingUI } from './logging-ui';\nimport type { WizardStore } from './tui/store';\n\n/**\n * `LoggingUI` plus it feeds run state into a `WizardStore` so the background\n * wizard-session sync (`TaskStreamPush`) can observe a headless run. We extend\n * `LoggingUI` (not `InkUI`) because its blocking/gate methods would wait on a\n * TUI that never renders; the runner drives phase transitions on the store\n * directly, so only UI-originated per-run updates tee through here. Runner\n * machinery loads agent-authored artifacts such as the event plan directly\n * into the store.\n */\nexport class HeadlessUI extends LoggingUI {\n constructor(private readonly store: WizardStore) {\n super();\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n super.syncTodos(todos);\n this.store.syncTodos(todos);\n }\n\n setHandoffText(text: string): void {\n this.store.setHandoffText(text);\n }\n}\n"],"mappings":";;;;;;;;;;;AAYA,IAAa,aAAb,cAAgC,UAAU;CACxC,YAAY,OAAqC;AAC/C,SAAO;AADoB,OAAA,QAAA;;CAI7B,UACE,OACM;AACN,QAAM,UAAU,MAAM;AACtB,OAAK,MAAM,UAAU,MAAM;;CAG7B,eAAe,MAAoB;AACjC,OAAK,MAAM,eAAe,KAAK"}
@@ -1,4 +1,4 @@
1
- import { r as posthogIntegrationConfig } from "./posthog-integration-CoPvN6YZ.js";
1
+ import { r as posthogIntegrationConfig } from "./posthog-integration-DFfBRGOC.js";
2
2
  import { u as runWizard } from "./bin.js";
3
3
  //#region src/commands/basic-integration/interactive.ts
4
4
  /** Default flow: run the posthog-integration program through the TUI. */
@@ -8,4 +8,4 @@ function runInteractive(argv) {
8
8
  //#endregion
9
9
  export { runInteractive };
10
10
 
11
- //# sourceMappingURL=interactive-DxHFVYr2.js.map
11
+ //# sourceMappingURL=interactive-DUpW84WU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-DxHFVYr2.js","names":[],"sources":["../src/commands/basic-integration/interactive.ts"],"sourcesContent":["import type { Arguments } from 'yargs';\nimport { runWizard } from '@lib/runners';\nimport { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index';\n\n/** Default flow: run the posthog-integration program through the TUI. */\nexport function runInteractive(argv: Arguments): void {\n runWizard(posthogIntegrationConfig, argv);\n}\n"],"mappings":";;;;AAKA,SAAgB,eAAe,MAAuB;AACpD,WAAU,0BAA0B,KAAK"}
1
+ {"version":3,"file":"interactive-DUpW84WU.js","names":[],"sources":["../src/commands/basic-integration/interactive.ts"],"sourcesContent":["import type { Arguments } from 'yargs';\nimport { runWizard } from '@lib/runners';\nimport { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index';\n\n/** Default flow: run the posthog-integration program through the TUI. */\nexport function runInteractive(argv: Arguments): void {\n runWizard(posthogIntegrationConfig, argv);\n}\n"],"mappings":";;;;AAKA,SAAgB,eAAe,MAAuB;AACpD,WAAU,0BAA0B,KAAK"}
@@ -132,4 +132,4 @@ function localMcpSkillsNotice(flags) {
132
132
  //#endregion
133
133
  export { getLocalDev as a, resolveLocalDev as c, checkLocalServices as i, MCP_LOCAL_URL as n, initLocalDev as o, POSTHOG_LOCAL_URL as r, localMcpSkillsNotice as s, CONTEXT_MILL_LOCAL_URL as t };
134
134
 
135
- //# sourceMappingURL=local-dev-BN6NKQ0B.js.map
135
+ //# sourceMappingURL=local-dev-DPZiIPCK.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-dev-BN6NKQ0B.js","names":[],"sources":["../src/lib/local-dev.ts"],"sourcesContent":["/**\n * Local development targets: context-mill (skills), MCP, and PostHog. Each is\n * independently switchable — CI runs local skills against the *production* MCP\n * — with `--local-dev` as a shorthand for all three.\n *\n * `wizard mcp add --local` is unrelated: it writes a `posthog-local` entry into\n * the user's editor config rather than retargeting this run. Hence no\n * `--local` here.\n */\n\nexport const CONTEXT_MILL_LOCAL_URL = 'http://localhost:8765';\nexport const MCP_LOCAL_URL = 'http://localhost:8787/mcp';\n/** Pins the API, app, OAuth, and the LLM gateway derived from them. */\nexport const POSTHOG_LOCAL_URL = 'http://localhost:8010';\n\n/**\n * Raw yargs values. The three specific flags are declared without a `default`\n * so they stay `undefined` when absent — see `resolveLocalDev`.\n */\nexport type LocalDevFlags = {\n localDev?: boolean;\n localMcp?: boolean;\n localContextMill?: boolean;\n localPosthog?: boolean;\n};\n\nexport type ResolvedLocalDev = {\n localMcp: boolean;\n localContextMill: boolean;\n localPosthog: boolean;\n};\n\n/**\n * A specific flag beats `--local-dev` in both directions. `??` is load-bearing:\n * it falls through only on `undefined`, so giving the specific flags a yargs\n * `default: false` would silently break both the umbrella and `--no-local-mcp`.\n */\nexport function resolveLocalDev(flags: LocalDevFlags): ResolvedLocalDev {\n const umbrella = flags.localDev ?? false;\n return {\n localMcp: flags.localMcp ?? umbrella,\n localContextMill: flags.localContextMill ?? umbrella,\n localPosthog: flags.localPosthog ?? umbrella,\n };\n}\n\n/** yargs populates both spellings, so read either. */\nexport function localDevFromArgv(\n argv: Record<string, unknown>,\n): ResolvedLocalDev {\n const read = (kebab: string, camel: string): boolean | undefined => {\n const value = argv[camel] ?? argv[kebab];\n return typeof value === 'boolean' ? value : undefined;\n };\n return resolveLocalDev({\n localDev: read('local-dev', 'localDev'),\n localMcp: read('local-mcp', 'localMcp'),\n localContextMill: read('local-context-mill', 'localContextMill'),\n localPosthog: read('local-posthog', 'localPosthog'),\n });\n}\n\nconst PRODUCTION_TARGETS: ResolvedLocalDev = {\n localMcp: false,\n localContextMill: false,\n localPosthog: false,\n};\n\nlet resolved: ResolvedLocalDev | null = null;\n\n/**\n * Resolve this process's targets. Called once from the yargs middleware, which\n * covers every command and the env-var spellings alike.\n */\nexport function initLocalDev(argv: Record<string, unknown>): ResolvedLocalDev {\n resolved = localDevFromArgv(argv);\n return resolved;\n}\n\n/**\n * Where this run points. Resolved once because the flags are parsed at startup\n * and never change; threading them through state let call sites read whichever\n * field they happened to have, which is how the intro screens ended up asking\n * the MCP flag where to fetch skills.\n *\n * Uninitialized means no CLI parse ran (a direct-call test) — production.\n */\nexport function getLocalDev(): ResolvedLocalDev {\n return resolved ?? PRODUCTION_TARGETS;\n}\n\n/** Tests only. */\nexport function resetLocalDev(): void {\n resolved = null;\n}\n\ntype LocalService = {\n key: keyof ResolvedLocalDev;\n label: string;\n flag: string;\n /** Probed for reachability — any HTTP reply proves the port is bound. */\n url: string;\n startHint: string;\n};\n\nconst LOCAL_SERVICES: readonly LocalService[] = [\n {\n key: 'localContextMill',\n label: 'context-mill',\n flag: '--local-context-mill',\n url: `${CONTEXT_MILL_LOCAL_URL}/skill-menu.json`,\n startHint: 'npm run dev (in the context-mill repo)',\n },\n {\n key: 'localMcp',\n label: 'MCP server',\n flag: '--local-mcp',\n url: MCP_LOCAL_URL,\n startHint:\n 'hogli start (or pnpm dev:local-resources in posthog/services/mcp)',\n },\n {\n key: 'localPosthog',\n label: 'PostHog',\n flag: '--local-posthog',\n url: POSTHOG_LOCAL_URL,\n startHint: './bin/start (in the posthog repo)',\n },\n] as const;\n\n// Retries because this gate gates `fetchWithRetry` (see fetch-retry.ts) — a\n// blip it would ride out must not abort the run instead. A missing server\n// refuses instantly, so the retries only cost time when one is slow to answer,\n// which is exactly when they're worth paying for.\nconst PROBE_TIMEOUT_MS = 2_000;\nconst PROBE_ATTEMPTS = 3;\nconst PROBE_BACKOFF_MS = 250;\n\nasync function isReachable(url: string): Promise<boolean> {\n for (let attempt = 1; attempt <= PROBE_ATTEMPTS; attempt++) {\n try {\n // Any reply — including 404 or 405 — proves something is listening, which\n // is the only question here. Deliberately not `fetchWithRetry`: that\n // treats a non-ok status as failure, and here it is a pass.\n await fetch(url, { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });\n return true;\n } catch {\n if (attempt < PROBE_ATTEMPTS) {\n await new Promise((r) =>\n setTimeout(r, PROBE_BACKOFF_MS * 2 ** (attempt - 1)),\n );\n }\n }\n }\n return false;\n}\n\n/**\n * Probe every service the flags asked to be local. Returns one message naming\n * each unreachable one, or undefined if all are up (or none were requested).\n *\n * Without this a dead local server surfaces late and badly: a missing\n * context-mill looks like a registry outage, a missing MCP fails mid-run after\n * the agent has already edited files.\n */\nexport async function checkLocalServices(\n resolved: ResolvedLocalDev,\n): Promise<string | undefined> {\n const requested = LOCAL_SERVICES.filter((s) => resolved[s.key]);\n if (requested.length === 0) return undefined;\n\n const reachable = await Promise.all(requested.map((s) => isReachable(s.url)));\n const dead = requested.filter((_, i) => !reachable[i]);\n if (dead.length === 0) return undefined;\n\n return [\n `Local ${dead.length === 1 ? 'service is' : 'services are'} not running:`,\n '',\n ...dead.map(\n (s) =>\n ` ${s.label} — nothing listening at ${new URL(s.url).origin}\\n` +\n ` requested by ${s.flag}\\n` +\n ` start it with: ${s.startHint}`,\n ),\n '',\n 'Start the missing services, or drop the flag to use production.',\n ].join('\\n');\n}\n\n/**\n * `--local-mcp` used to select local skills too; anyone still relying on that\n * would silently get production skills. Temporary — drop after a release or two.\n */\nexport function localMcpSkillsNotice(flags: LocalDevFlags): string | undefined {\n if (flags.localMcp !== true) return undefined;\n if (flags.localContextMill !== undefined || flags.localDev === true) {\n return undefined;\n }\n return (\n '--local-mcp now points only at the local MCP server. ' +\n 'For local skills, add --local-context-mill (or use --local-dev for both).'\n );\n}\n"],"mappings":";;;;;;;;;;AAUA,MAAa,yBAAyB;AACtC,MAAa,gBAAgB;;AAE7B,MAAa,oBAAoB;;;;;;AAwBjC,SAAgB,gBAAgB,OAAwC;CACtE,MAAM,WAAW,MAAM,YAAY;AACnC,QAAO;EACL,UAAU,MAAM,YAAY;EAC5B,kBAAkB,MAAM,oBAAoB;EAC5C,cAAc,MAAM,gBAAgB;EACrC;;;AAIH,SAAgB,iBACd,MACkB;CAClB,MAAM,QAAQ,OAAe,UAAuC;EAClE,MAAM,QAAQ,KAAK,UAAU,KAAK;AAClC,SAAO,OAAO,UAAU,YAAY,QAAQ,KAAA;;AAE9C,QAAO,gBAAgB;EACrB,UAAU,KAAK,aAAa,WAAW;EACvC,UAAU,KAAK,aAAa,WAAW;EACvC,kBAAkB,KAAK,sBAAsB,mBAAmB;EAChE,cAAc,KAAK,iBAAiB,eAAe;EACpD,CAAC;;AAGJ,MAAM,qBAAuC;CAC3C,UAAU;CACV,kBAAkB;CAClB,cAAc;CACf;AAED,IAAI,WAAoC;;;;;AAMxC,SAAgB,aAAa,MAAiD;AAC5E,YAAW,iBAAiB,KAAK;AACjC,QAAO;;;;;;;;;;AAWT,SAAgB,cAAgC;AAC9C,QAAO,YAAY;;AAiBrB,MAAM,iBAA0C;CAC9C;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,KAAK,GAAG,uBAAuB;EAC/B,WAAW;EACZ;CACD;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,KAAK;EACL,WACE;EACH;CACD;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,KAAK;EACL,WAAW;EACZ;CACF;AAMD,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,mBAAmB;AAEzB,eAAe,YAAY,KAA+B;AACxD,MAAK,IAAI,UAAU,GAAG,WAAW,gBAAgB,UAC/C,KAAI;AAIF,QAAM,MAAM,KAAK,EAAE,QAAQ,YAAY,QAAQ,iBAAiB,EAAE,CAAC;AACnE,SAAO;SACD;AACN,MAAI,UAAU,eACZ,OAAM,IAAI,SAAS,MACjB,WAAW,GAAG,mBAAmB,MAAM,UAAU,GAAG,CACrD;;AAIP,QAAO;;;;;;;;;;AAWT,eAAsB,mBACpB,UAC6B;CAC7B,MAAM,YAAY,eAAe,QAAQ,MAAM,SAAS,EAAE,KAAK;AAC/D,KAAI,UAAU,WAAW,EAAG,QAAO,KAAA;CAEnC,MAAM,YAAY,MAAM,QAAQ,IAAI,UAAU,KAAK,MAAM,YAAY,EAAE,IAAI,CAAC,CAAC;CAC7E,MAAM,OAAO,UAAU,QAAQ,GAAG,MAAM,CAAC,UAAU,GAAG;AACtD,KAAI,KAAK,WAAW,EAAG,QAAO,KAAA;AAE9B,QAAO;EACL,SAAS,KAAK,WAAW,IAAI,eAAe,eAAe;EAC3D;EACA,GAAG,KAAK,KACL,MACC,KAAK,EAAE,MAAM,0BAA0B,IAAI,IAAI,EAAE,IAAI,CAAC,OAAO,qBACzC,EAAE,KAAK,uBACL,EAAE,YAC3B;EACD;EACA;EACD,CAAC,KAAK,KAAK;;;;;;AAOd,SAAgB,qBAAqB,OAA0C;AAC7E,KAAI,MAAM,aAAa,KAAM,QAAO,KAAA;AACpC,KAAI,MAAM,qBAAqB,KAAA,KAAa,MAAM,aAAa,KAC7D;AAEF,QACE"}
1
+ {"version":3,"file":"local-dev-DPZiIPCK.js","names":[],"sources":["../src/lib/local-dev.ts"],"sourcesContent":["/**\n * Local development targets: context-mill (skills), MCP, and PostHog. Each is\n * independently switchable — CI runs local skills against the *production* MCP\n * — with `--local-dev` as a shorthand for all three.\n *\n * `wizard mcp add --local` is unrelated: it writes a `posthog-local` entry into\n * the user's editor config rather than retargeting this run. Hence no\n * `--local` here.\n */\n\nexport const CONTEXT_MILL_LOCAL_URL = 'http://localhost:8765';\nexport const MCP_LOCAL_URL = 'http://localhost:8787/mcp';\n/** Pins the API, app, OAuth, and the LLM gateway derived from them. */\nexport const POSTHOG_LOCAL_URL = 'http://localhost:8010';\n\n/**\n * Raw yargs values. The three specific flags are declared without a `default`\n * so they stay `undefined` when absent — see `resolveLocalDev`.\n */\nexport type LocalDevFlags = {\n localDev?: boolean;\n localMcp?: boolean;\n localContextMill?: boolean;\n localPosthog?: boolean;\n};\n\nexport type ResolvedLocalDev = {\n localMcp: boolean;\n localContextMill: boolean;\n localPosthog: boolean;\n};\n\n/**\n * A specific flag beats `--local-dev` in both directions. `??` is load-bearing:\n * it falls through only on `undefined`, so giving the specific flags a yargs\n * `default: false` would silently break both the umbrella and `--no-local-mcp`.\n */\nexport function resolveLocalDev(flags: LocalDevFlags): ResolvedLocalDev {\n const umbrella = flags.localDev ?? false;\n return {\n localMcp: flags.localMcp ?? umbrella,\n localContextMill: flags.localContextMill ?? umbrella,\n localPosthog: flags.localPosthog ?? umbrella,\n };\n}\n\n/** yargs populates both spellings, so read either. */\nexport function localDevFromArgv(\n argv: Record<string, unknown>,\n): ResolvedLocalDev {\n const read = (kebab: string, camel: string): boolean | undefined => {\n const value = argv[camel] ?? argv[kebab];\n return typeof value === 'boolean' ? value : undefined;\n };\n return resolveLocalDev({\n localDev: read('local-dev', 'localDev'),\n localMcp: read('local-mcp', 'localMcp'),\n localContextMill: read('local-context-mill', 'localContextMill'),\n localPosthog: read('local-posthog', 'localPosthog'),\n });\n}\n\nconst PRODUCTION_TARGETS: ResolvedLocalDev = {\n localMcp: false,\n localContextMill: false,\n localPosthog: false,\n};\n\nlet resolved: ResolvedLocalDev | null = null;\n\n/**\n * Resolve this process's targets. Called once from the yargs middleware, which\n * covers every command and the env-var spellings alike.\n */\nexport function initLocalDev(argv: Record<string, unknown>): ResolvedLocalDev {\n resolved = localDevFromArgv(argv);\n return resolved;\n}\n\n/**\n * Where this run points. Resolved once because the flags are parsed at startup\n * and never change; threading them through state let call sites read whichever\n * field they happened to have, which is how the intro screens ended up asking\n * the MCP flag where to fetch skills.\n *\n * Uninitialized means no CLI parse ran (a direct-call test) — production.\n */\nexport function getLocalDev(): ResolvedLocalDev {\n return resolved ?? PRODUCTION_TARGETS;\n}\n\n/** Tests only. */\nexport function resetLocalDev(): void {\n resolved = null;\n}\n\ntype LocalService = {\n key: keyof ResolvedLocalDev;\n label: string;\n flag: string;\n /** Probed for reachability — any HTTP reply proves the port is bound. */\n url: string;\n startHint: string;\n};\n\nconst LOCAL_SERVICES: readonly LocalService[] = [\n {\n key: 'localContextMill',\n label: 'context-mill',\n flag: '--local-context-mill',\n url: `${CONTEXT_MILL_LOCAL_URL}/skill-menu.json`,\n startHint: 'npm run dev (in the context-mill repo)',\n },\n {\n key: 'localMcp',\n label: 'MCP server',\n flag: '--local-mcp',\n url: MCP_LOCAL_URL,\n startHint:\n 'hogli start (or pnpm dev:local-resources in posthog/services/mcp)',\n },\n {\n key: 'localPosthog',\n label: 'PostHog',\n flag: '--local-posthog',\n url: POSTHOG_LOCAL_URL,\n startHint: './bin/start (in the posthog repo)',\n },\n] as const;\n\n// Retries because this gate gates `fetchWithRetry` (see fetch-retry.ts) — a\n// blip it would ride out must not abort the run instead. A missing server\n// refuses instantly, so the retries only cost time when one is slow to answer,\n// which is exactly when they're worth paying for.\nconst PROBE_TIMEOUT_MS = 2_000;\nconst PROBE_ATTEMPTS = 3;\nconst PROBE_BACKOFF_MS = 250;\n\nasync function isReachable(url: string): Promise<boolean> {\n for (let attempt = 1; attempt <= PROBE_ATTEMPTS; attempt++) {\n try {\n // Any reply — including 404 or 405 — proves something is listening, which\n // is the only question here. Deliberately not `fetchWithRetry`: that\n // treats a non-ok status as failure, and here it is a pass.\n await fetch(url, { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });\n return true;\n } catch {\n if (attempt < PROBE_ATTEMPTS) {\n await new Promise((r) =>\n setTimeout(r, PROBE_BACKOFF_MS * 2 ** (attempt - 1)),\n );\n }\n }\n }\n return false;\n}\n\n/**\n * Probe every service the flags asked to be local. Returns one message naming\n * each unreachable one, or undefined if all are up (or none were requested).\n *\n * Without this a dead local server surfaces late and badly: a missing\n * context-mill looks like a registry outage, a missing MCP fails mid-run after\n * the agent has already edited files.\n */\nexport async function checkLocalServices(\n resolved: ResolvedLocalDev,\n): Promise<string | undefined> {\n const requested = LOCAL_SERVICES.filter((s) => resolved[s.key]);\n if (requested.length === 0) return undefined;\n\n const reachable = await Promise.all(requested.map((s) => isReachable(s.url)));\n const dead = requested.filter((_, i) => !reachable[i]);\n if (dead.length === 0) return undefined;\n\n return [\n `Local ${dead.length === 1 ? 'service is' : 'services are'} not running:`,\n '',\n ...dead.map(\n (s) =>\n ` ${s.label} — nothing listening at ${new URL(s.url).origin}\\n` +\n ` requested by ${s.flag}\\n` +\n ` start it with: ${s.startHint}`,\n ),\n '',\n 'Start the missing services, or drop the flag to use production.',\n ].join('\\n');\n}\n\n/**\n * `--local-mcp` used to select local skills too; anyone still relying on that\n * would silently get production skills. Temporary — drop after a release or two.\n */\nexport function localMcpSkillsNotice(flags: LocalDevFlags): string | undefined {\n if (flags.localMcp !== true) return undefined;\n if (flags.localContextMill !== undefined || flags.localDev === true) {\n return undefined;\n }\n return (\n '--local-mcp now points only at the local MCP server. ' +\n 'For local skills, add --local-context-mill (or use --local-dev for both).'\n );\n}\n"],"mappings":";;;;;;;;;;AAUA,MAAa,yBAAyB;AACtC,MAAa,gBAAgB;;AAE7B,MAAa,oBAAoB;;;;;;AAwBjC,SAAgB,gBAAgB,OAAwC;CACtE,MAAM,WAAW,MAAM,YAAY;AACnC,QAAO;EACL,UAAU,MAAM,YAAY;EAC5B,kBAAkB,MAAM,oBAAoB;EAC5C,cAAc,MAAM,gBAAgB;EACrC;;;AAIH,SAAgB,iBACd,MACkB;CAClB,MAAM,QAAQ,OAAe,UAAuC;EAClE,MAAM,QAAQ,KAAK,UAAU,KAAK;AAClC,SAAO,OAAO,UAAU,YAAY,QAAQ,KAAA;;AAE9C,QAAO,gBAAgB;EACrB,UAAU,KAAK,aAAa,WAAW;EACvC,UAAU,KAAK,aAAa,WAAW;EACvC,kBAAkB,KAAK,sBAAsB,mBAAmB;EAChE,cAAc,KAAK,iBAAiB,eAAe;EACpD,CAAC;;AAGJ,MAAM,qBAAuC;CAC3C,UAAU;CACV,kBAAkB;CAClB,cAAc;CACf;AAED,IAAI,WAAoC;;;;;AAMxC,SAAgB,aAAa,MAAiD;AAC5E,YAAW,iBAAiB,KAAK;AACjC,QAAO;;;;;;;;;;AAWT,SAAgB,cAAgC;AAC9C,QAAO,YAAY;;AAiBrB,MAAM,iBAA0C;CAC9C;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,KAAK,GAAG,uBAAuB;EAC/B,WAAW;EACZ;CACD;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,KAAK;EACL,WACE;EACH;CACD;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,KAAK;EACL,WAAW;EACZ;CACF;AAMD,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,mBAAmB;AAEzB,eAAe,YAAY,KAA+B;AACxD,MAAK,IAAI,UAAU,GAAG,WAAW,gBAAgB,UAC/C,KAAI;AAIF,QAAM,MAAM,KAAK,EAAE,QAAQ,YAAY,QAAQ,iBAAiB,EAAE,CAAC;AACnE,SAAO;SACD;AACN,MAAI,UAAU,eACZ,OAAM,IAAI,SAAS,MACjB,WAAW,GAAG,mBAAmB,MAAM,UAAU,GAAG,CACrD;;AAIP,QAAO;;;;;;;;;;AAWT,eAAsB,mBACpB,UAC6B;CAC7B,MAAM,YAAY,eAAe,QAAQ,MAAM,SAAS,EAAE,KAAK;AAC/D,KAAI,UAAU,WAAW,EAAG,QAAO,KAAA;CAEnC,MAAM,YAAY,MAAM,QAAQ,IAAI,UAAU,KAAK,MAAM,YAAY,EAAE,IAAI,CAAC,CAAC;CAC7E,MAAM,OAAO,UAAU,QAAQ,GAAG,MAAM,CAAC,UAAU,GAAG;AACtD,KAAI,KAAK,WAAW,EAAG,QAAO,KAAA;AAE9B,QAAO;EACL,SAAS,KAAK,WAAW,IAAI,eAAe,eAAe;EAC3D;EACA,GAAG,KAAK,KACL,MACC,KAAK,EAAE,MAAM,0BAA0B,IAAI,IAAI,EAAE,IAAI,CAAC,OAAO,qBACzC,EAAE,KAAK,uBACL,EAAE,YAC3B;EACD;EACA;EACD,CAAC,KAAK,KAAK;;;;;;AAOd,SAAgB,qBAAqB,OAA0C;AAC7E,KAAI,MAAM,aAAa,KAAM,QAAO,KAAA;AACpC,KAAI,MAAM,qBAAqB,KAAA,KAAa,MAAM,aAAa,KAC7D;AAEF,QACE"}
@@ -1,4 +1,4 @@
1
- import { gt as VERSION, s as logToFile } from "./debug-Cm1hvkVy.js";
1
+ import { gt as VERSION, s as logToFile } from "./debug-BsHD83Vy.js";
2
2
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
3
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4
4
  import { createJiti } from "jiti";
@@ -61,4 +61,4 @@ async function setupPostHogMcp(opts) {
61
61
  //#endregion
62
62
  export { fetchInstructions, setupPostHogMcp };
63
63
 
64
- //# sourceMappingURL=mcp-t0UxAPur.js.map
64
+ //# sourceMappingURL=mcp-CHo9h-WV.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-t0UxAPur.js","names":[],"sources":["../src/lib/agent/runner/harness/pi/mcp.ts"],"sourcesContent":["/**\n * pi has no built-in MCP; `pi-mcp-adapter` — pi's own MCP extension, built here\n * with its supported `createMcpAdapter` embedding API — bridges the same hosted\n * MCP the anthropic path uses into the agent.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { createJiti } from 'jiti';\nimport { VERSION } from '@lib/version';\nimport { logToFile } from '@utils/debug';\n\nconst MCP_TOKEN_ENV = 'POSTHOG_MCP_TOKEN';\n\nexport interface PostHogMcpSetup {\n /** pi ExtensionFactory to add to the resource loader's `extensionFactories`. */\n extensionFactory: (pi: unknown) => void;\n /** Drop the token env var. Call after the run. */\n cleanup: () => void;\n}\n\n/** Server `instructions` for the system prompt — the adapter exposes no accessor, so one standard-SDK handshake; best-effort. */\nexport async function fetchInstructions(\n mcpUrl: string,\n accessToken: string,\n userAgent: string,\n): Promise<string | undefined> {\n const client = new Client({ name: 'posthog-wizard', version: VERSION });\n try {\n const transport = new StreamableHTTPClientTransport(new URL(mcpUrl), {\n requestInit: {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': userAgent,\n },\n },\n });\n await client.connect(transport);\n const instructions = client.getInstructions() || undefined;\n logToFile(`[pi-mcp] instructions ${instructions?.length ?? 0} chars`);\n return instructions;\n } catch (err) {\n logToFile(`[pi-mcp] instructions fetch skipped: ${String(err)}`);\n return undefined;\n } finally {\n await client.close().catch(() => undefined);\n }\n}\n\nexport async function setupPostHogMcp(opts: {\n mcpUrl: string;\n accessToken: string;\n userAgent: string;\n}): Promise<PostHogMcpSetup> {\n const { mcpUrl, accessToken, userAgent } = opts;\n\n // By env NAME: the token stays in this process, off disk, and never reaches pi's env-scrubbed tool subprocesses.\n process.env[MCP_TOKEN_ENV] = accessToken;\n\n // The adapter ships raw TypeScript; loading through jiti is its documented requirement.\n const jiti = createJiti(import.meta.url);\n const mod = await jiti.import('pi-mcp-adapter');\n const extensionFactory = mod.createMcpAdapter({\n config: {\n mcpServers: {\n posthog: {\n url: mcpUrl,\n auth: 'bearer',\n bearerTokenEnv: MCP_TOKEN_ENV,\n headers: { 'User-Agent': userAgent },\n // Connect at extension load — direct tools register without a session_start.\n lifecycle: 'eager',\n // Register only `exec`: `directTools: true` also mints a `posthog_get_<name>` tool per MCP resource, whose sentence-length names overflow Anthropic's 128-char tool-name limit and 400 the whole request.\n directTools: ['exec'],\n exposeResources: false,\n },\n },\n // Disable the proxy `mcp` tool (its search indirection pollutes context); the adapter re-enables it only if no direct tools resolve.\n settings: { disableProxyTool: true, toolPrefix: 'posthog' },\n },\n });\n logToFile(`[pi-mcp] adapter loaded; posthog MCP at ${mcpUrl}`);\n\n const cleanup = (): void => {\n delete process.env[MCP_TOKEN_ENV];\n };\n\n return { extensionFactory, cleanup };\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAM,gBAAgB;;AAUtB,eAAsB,kBACpB,QACA,aACA,WAC6B;CAC7B,MAAM,SAAS,IAAI,OAAO;EAAE,MAAM;EAAkB,SAAS;EAAS,CAAC;AACvE,KAAI;EACF,MAAM,YAAY,IAAI,8BAA8B,IAAI,IAAI,OAAO,EAAE,EACnE,aAAa,EACX,SAAS;GACP,eAAe,UAAU;GACzB,cAAc;GACf,EACF,EACF,CAAC;AACF,QAAM,OAAO,QAAQ,UAAU;EAC/B,MAAM,eAAe,OAAO,iBAAiB,IAAI,KAAA;AACjD,YAAU,yBAAyB,cAAc,UAAU,EAAE,QAAQ;AACrE,SAAO;UACA,KAAK;AACZ,YAAU,wCAAwC,OAAO,IAAI,GAAG;AAChE;WACQ;AACR,QAAM,OAAO,OAAO,CAAC,YAAY,KAAA,EAAU;;;AAI/C,eAAsB,gBAAgB,MAIT;CAC3B,MAAM,EAAE,QAAQ,aAAa,cAAc;AAG3C,SAAQ,IAAI,iBAAiB;CAK7B,MAAM,oBADM,MADC,WAAW,OAAO,KAAK,IAAI,CACjB,OAAO,iBAAiB,EAClB,iBAAiB,EAC5C,QAAQ;EACN,YAAY,EACV,SAAS;GACP,KAAK;GACL,MAAM;GACN,gBAAgB;GAChB,SAAS,EAAE,cAAc,WAAW;GAEpC,WAAW;GAEX,aAAa,CAAC,OAAO;GACrB,iBAAiB;GAClB,EACF;EAED,UAAU;GAAE,kBAAkB;GAAM,YAAY;GAAW;EAC5D,EACF,CAAC;AACF,WAAU,2CAA2C,SAAS;CAE9D,MAAM,gBAAsB;AAC1B,SAAO,QAAQ,IAAI;;AAGrB,QAAO;EAAE;EAAkB;EAAS"}
1
+ {"version":3,"file":"mcp-CHo9h-WV.js","names":[],"sources":["../src/lib/agent/runner/harness/pi/mcp.ts"],"sourcesContent":["/**\n * pi has no built-in MCP; `pi-mcp-adapter` — pi's own MCP extension, built here\n * with its supported `createMcpAdapter` embedding API — bridges the same hosted\n * MCP the anthropic path uses into the agent.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { createJiti } from 'jiti';\nimport { VERSION } from '@lib/version';\nimport { logToFile } from '@utils/debug';\n\nconst MCP_TOKEN_ENV = 'POSTHOG_MCP_TOKEN';\n\nexport interface PostHogMcpSetup {\n /** pi ExtensionFactory to add to the resource loader's `extensionFactories`. */\n extensionFactory: (pi: unknown) => void;\n /** Drop the token env var. Call after the run. */\n cleanup: () => void;\n}\n\n/** Server `instructions` for the system prompt — the adapter exposes no accessor, so one standard-SDK handshake; best-effort. */\nexport async function fetchInstructions(\n mcpUrl: string,\n accessToken: string,\n userAgent: string,\n): Promise<string | undefined> {\n const client = new Client({ name: 'posthog-wizard', version: VERSION });\n try {\n const transport = new StreamableHTTPClientTransport(new URL(mcpUrl), {\n requestInit: {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': userAgent,\n },\n },\n });\n await client.connect(transport);\n const instructions = client.getInstructions() || undefined;\n logToFile(`[pi-mcp] instructions ${instructions?.length ?? 0} chars`);\n return instructions;\n } catch (err) {\n logToFile(`[pi-mcp] instructions fetch skipped: ${String(err)}`);\n return undefined;\n } finally {\n await client.close().catch(() => undefined);\n }\n}\n\nexport async function setupPostHogMcp(opts: {\n mcpUrl: string;\n accessToken: string;\n userAgent: string;\n}): Promise<PostHogMcpSetup> {\n const { mcpUrl, accessToken, userAgent } = opts;\n\n // By env NAME: the token stays in this process, off disk, and never reaches pi's env-scrubbed tool subprocesses.\n process.env[MCP_TOKEN_ENV] = accessToken;\n\n // The adapter ships raw TypeScript; loading through jiti is its documented requirement.\n const jiti = createJiti(import.meta.url);\n const mod = await jiti.import('pi-mcp-adapter');\n const extensionFactory = mod.createMcpAdapter({\n config: {\n mcpServers: {\n posthog: {\n url: mcpUrl,\n auth: 'bearer',\n bearerTokenEnv: MCP_TOKEN_ENV,\n headers: { 'User-Agent': userAgent },\n // Connect at extension load — direct tools register without a session_start.\n lifecycle: 'eager',\n // Register only `exec`: `directTools: true` also mints a `posthog_get_<name>` tool per MCP resource, whose sentence-length names overflow Anthropic's 128-char tool-name limit and 400 the whole request.\n directTools: ['exec'],\n exposeResources: false,\n },\n },\n // Disable the proxy `mcp` tool (its search indirection pollutes context); the adapter re-enables it only if no direct tools resolve.\n settings: { disableProxyTool: true, toolPrefix: 'posthog' },\n },\n });\n logToFile(`[pi-mcp] adapter loaded; posthog MCP at ${mcpUrl}`);\n\n const cleanup = (): void => {\n delete process.env[MCP_TOKEN_ENV];\n };\n\n return { extensionFactory, cleanup };\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAM,gBAAgB;;AAUtB,eAAsB,kBACpB,QACA,aACA,WAC6B;CAC7B,MAAM,SAAS,IAAI,OAAO;EAAE,MAAM;EAAkB,SAAS;EAAS,CAAC;AACvE,KAAI;EACF,MAAM,YAAY,IAAI,8BAA8B,IAAI,IAAI,OAAO,EAAE,EACnE,aAAa,EACX,SAAS;GACP,eAAe,UAAU;GACzB,cAAc;GACf,EACF,EACF,CAAC;AACF,QAAM,OAAO,QAAQ,UAAU;EAC/B,MAAM,eAAe,OAAO,iBAAiB,IAAI,KAAA;AACjD,YAAU,yBAAyB,cAAc,UAAU,EAAE,QAAQ;AACrE,SAAO;UACA,KAAK;AACZ,YAAU,wCAAwC,OAAO,IAAI,GAAG;AAChE;WACQ;AACR,QAAM,OAAO,OAAO,CAAC,YAAY,KAAA,EAAU;;;AAI/C,eAAsB,gBAAgB,MAIT;CAC3B,MAAM,EAAE,QAAQ,aAAa,cAAc;AAG3C,SAAQ,IAAI,iBAAiB;CAK7B,MAAM,oBADM,MADC,WAAW,OAAO,KAAK,IAAI,CACjB,OAAO,iBAAiB,EAClB,iBAAiB,EAC5C,QAAQ;EACN,YAAY,EACV,SAAS;GACP,KAAK;GACL,MAAM;GACN,gBAAgB;GAChB,SAAS,EAAE,cAAc,WAAW;GAEpC,WAAW;GAEX,aAAa,CAAC,OAAO;GACrB,iBAAiB;GAClB,EACF;EAED,UAAU;GAAE,kBAAkB;GAAM,YAAY;GAAW;EAC5D,EACF,CAAC;AACF,WAAU,2CAA2C,SAAS;CAE9D,MAAM,gBAAsB;AAC1B,SAAO,QAAQ,IAAI;;AAGrB,QAAO;EAAE;EAAkB;EAAS"}