@raindrop-ai/wizard 0.0.10 → 0.0.12

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 (32) hide show
  1. package/dist/src/docs/claude-agent-sdk.mdx +2 -2
  2. package/dist/src/docs/python.mdx +6 -0
  3. package/dist/src/docs/typescript.mdx +125 -28
  4. package/dist/src/lib/__tests__/sdk-messages.test.d.ts +4 -0
  5. package/dist/src/lib/__tests__/sdk-messages.test.js +296 -0
  6. package/dist/src/lib/__tests__/sdk-messages.test.js.map +1 -0
  7. package/dist/src/lib/agent-interface.js +40 -14
  8. package/dist/src/lib/agent-interface.js.map +1 -1
  9. package/dist/src/lib/agent-prompts.js +4 -1
  10. package/dist/src/lib/agent-prompts.js.map +1 -1
  11. package/dist/src/lib/constants.d.ts +7 -0
  12. package/dist/src/lib/constants.js +15 -0
  13. package/dist/src/lib/constants.js.map +1 -1
  14. package/dist/src/lib/handlers.js +21 -18
  15. package/dist/src/lib/handlers.js.map +1 -1
  16. package/dist/src/lib/sdk-messages.d.ts +41 -2
  17. package/dist/src/lib/sdk-messages.js +89 -41
  18. package/dist/src/lib/sdk-messages.js.map +1 -1
  19. package/dist/src/lib/wizard.js +1 -1
  20. package/dist/src/lib/wizard.js.map +1 -1
  21. package/dist/src/ui/components/ToolCallDisplay.js +30 -0
  22. package/dist/src/ui/components/ToolCallDisplay.js.map +1 -1
  23. package/dist/src/ui/contexts/WizardContext.d.ts +0 -11
  24. package/dist/src/ui/contexts/WizardContext.js +2 -19
  25. package/dist/src/ui/contexts/WizardContext.js.map +1 -1
  26. package/dist/src/utils/__mocks__/ui.d.ts +10 -0
  27. package/dist/src/utils/__mocks__/ui.js +7 -0
  28. package/dist/src/utils/__mocks__/ui.js.map +1 -0
  29. package/dist/src/utils/session.d.ts +22 -0
  30. package/dist/src/utils/session.js +67 -1
  31. package/dist/src/utils/session.js.map +1 -1
  32. package/package.json +16 -1
@@ -1 +1 @@
1
- {"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../../src/lib/wizard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EACL,iBAAiB,EACjB,iCAAiC,GAClC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,0DAA0D;AAC1D,MAAM,KAAK,GAAG,KAAY,CAAC;AAE3B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAsB;IACpD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,eAAe,EAAE,CAAC;IACpB,CAAC;IAED,kIAAkI;IAClI,MAAM,iCAAiC,CAAC,OAAO,CAAC,CAAC;IAEjD,MAAM,KAAK,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAExC,gDAAgD;IAChD,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,KAAK,CAAC,KAAK,CAAC;IAE/C,MAAM,eAAe,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IACrC,eAAe,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAE/D,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjD,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAe,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QACrD,EAAE,CAAC,OAAO,CAAC;YACT,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SACzE,CAAC,CAAC;QACH,MAAM,KAAK,CAAC;IACd,CAAC;IAED,eAAe,CAAC,IAAI,EAAE,CAAC;IAEvB,iDAAiD;IACjD,EAAE,CAAC,OAAO,CAAC;QACT,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,QAAQ;KACT,CAAC,CAAC;IAEH,gDAAgD;IAChD,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,cAAc,CAAC;QAC7C,OAAO,EAAE,uCAAuC,KAAK,CAAC,IAAI,CACxD,oBAAoB,CACrB,GAAG;QACJ,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE;YAC1C,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE;YAC7C,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;SACzC;QACD,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IAEH,iEAAiE;IACjE,IAAI,aAAiC,CAAC;IAEtC,IAAI,cAAc,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,IAAI,cAAc,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACvC,IAAI,CAAC;gBACH,MAAM,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;gBACtD,aAAa,GAAG,eAAe,CAAC;YAClC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,EAAE,CAAC,OAAO,CAAC;oBACT,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,oCACJ,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE;iBACH,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,IAAI,cAAc,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,KAAK,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;gBACzD,aAAa,GAAG,qBAAqB,CAAC;YACxC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,EAAE,CAAC,OAAO,CAAC;oBACT,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,gCACJ,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE;iBACH,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,kDAAkD;IACpD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,KAAK,CAAC,KAAK,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,qBAAqB,OAAO,CAAC,SAAS,EAAE,CAAC;IAEhF,mBAAmB;IACnB,MAAM,KAAK,GAAG,eAAe,CAC3B;QACE,gBAAgB,EAAE,OAAO,CAAC,UAAU;KACrC,EACD,OAAO,CACR,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,YAAY,CACpC,KAAK,EACL,6BAA6B,OAAO,CAAC,SAAS,0BAA0B,EACxE,OAAO,EACP;QACE,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,KAAK,CAAC,KAAK;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE;QAC7B,qBAAqB,EAAE,KAAK,IAAI,EAAE;YAChC,0DAA0D;YAC1D,EAAE,CAAC,mBAAmB,EAAE,CAAC;YACzB,OAAO,eAAe,CACpB,OAAO,EACP,QAAQ,EACR,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CACvB,CAAC;QACJ,CAAC;KACF,CACF,CAAC;IAEF,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACzB,EAAE,CAAC,OAAO,CAAC;gBACT,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,sFAAsF;aAC7F,CAAC,CAAC;QACL,CAAC;QACD,OAAO;IACT,CAAC;IAED,sBAAsB;IACtB,MAAM,SAAS,GAAG;QAChB,gEAAgE;QAChE,0CAA0C;KAC3C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,MAAM,YAAY,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC;;EAEvE,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC;EAC3B,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;cAEnC,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC;EACtD,KAAK,CAAC,GAAG,CACT,iHAAiH,CAClH,EAAE,CAAC;IAEF,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;AACtD,CAAC","sourcesContent":["import Chalk from 'chalk';\nimport clipboardy from 'clipboardy';\nimport {\n askForWizardLogin,\n confirmContinueIfNoOrDirtyGitRepo,\n} from '../utils/clack-utils.js';\nimport { enableDebugLogs } from '../utils/debug.js';\nimport { saveWriteKeyToEnv } from '../utils/environment.js';\nimport { getOrgWriteKey } from '../utils/oauth.js';\nimport type { WizardOptions } from '../utils/types.js';\nimport ui from '../utils/ui.js';\nimport { initializeAgent, runAgentLoop } from './agent-interface.js';\nimport { ANTHROPIC_BASE_URL, SPINNER_MESSAGE } from './constants.js';\nimport { testIntegration } from './integration-testing.js';\n\n// chalk v2 types don't work well with ESM default imports\nconst chalk = Chalk as any;\n\n/**\n * Unified wizard powered by the universal agent runner.\n * The agent will detect the integration type and load appropriate documentation.\n */\nexport async function runWizard(options: WizardOptions): Promise<void> {\n if (options.debug) {\n enableDebugLogs();\n }\n\n // Check if the current directory is a git repository and has uncommitted or untracked changes; prompt the user to continue if so.\n await confirmContinueIfNoOrDirtyGitRepo(options);\n\n const token = await askForWizardLogin();\n\n // Set the wizard JWT in process.env for the SDK\n process.env.ANTHROPIC_AUTH_TOKEN = token.token;\n\n const writeKeySpinner = ui.spinner();\n writeKeySpinner.start('Retrieving your Raindrop write key...');\n\n let writeKey: string;\n try {\n const result = await getOrgWriteKey(token.token);\n writeKey = result.writeKey;\n } catch (error) {\n writeKeySpinner.stop('Failed to retrieve write key');\n ui.addItem({\n type: 'error',\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n });\n throw error;\n }\n\n writeKeySpinner.stop();\n\n // Show org info and write key in a beautiful box\n ui.addItem({\n type: 'org-info',\n text: 'Organization info',\n orgName: token.orgName,\n writeKey,\n });\n\n // Prompt user for what to do with the write key\n const writeKeyAction = await ui.feedbackSelect({\n message: `What would you like to do with your ${chalk.cyan(\n 'RAINDROP_WRITE_KEY',\n )}?`,\n options: [\n { value: 'add-env', label: 'Add to .env' },\n { value: 'copy', label: 'Copy to clipboard' },\n { value: 'continue', label: 'Continue' },\n ],\n skipHistory: true,\n });\n\n // Determine the label for the history item based on action taken\n let writeKeyLabel: string | undefined;\n\n if (writeKeyAction.type === 'option') {\n if (writeKeyAction.value === 'add-env') {\n try {\n await saveWriteKeyToEnv(writeKey, options.installDir);\n writeKeyLabel = 'saved to .env';\n } catch (error) {\n ui.addItem({\n type: 'error',\n text: `Failed to add write key to .env: ${\n error instanceof Error ? error.message : String(error)\n }`,\n });\n }\n } else if (writeKeyAction.value === 'copy') {\n try {\n await clipboardy.write(`RAINDROP_WRITE_KEY=${writeKey}`);\n writeKeyLabel = 'copied to clipboard';\n } catch (error) {\n ui.addItem({\n type: 'error',\n text: `Failed to copy to clipboard: ${\n error instanceof Error ? error.message : String(error)\n }`,\n });\n }\n }\n // For 'continue', writeKeyLabel remains undefined\n }\n\n process.env.ANTHROPIC_BASE_URL = ANTHROPIC_BASE_URL;\n process.env.ANTHROPIC_AUTH_TOKEN = token.token;\n process.env.ANTHROPIC_CUSTOM_HEADERS = `x-wizard-session: ${options.sessionId}`;\n\n // Initialize agent\n const agent = initializeAgent(\n {\n workingDirectory: options.installDir,\n },\n options,\n );\n\n const agentResult = await runAgentLoop(\n agent,\n `Your WIZARD SESSION ID is ${options.sessionId}. Begin the integration.`,\n options,\n {\n spinnerMessage: SPINNER_MESSAGE,\n accessToken: token.token,\n orgId: token.orgId.toString(),\n onCompleteIntegration: async () => {\n // Ensure persistent input is stopped before testing phase\n ui.stopPersistentInput();\n return testIntegration(\n options,\n writeKey,\n token.token,\n token.orgId.toString(),\n );\n },\n },\n );\n\n if (!agentResult.completed) {\n if (!agentResult.support) {\n ui.addItem({\n type: 'warning',\n text: 'Integration session ended before confirmation. You can rerun the wizard to continue.',\n });\n }\n return;\n }\n\n // Build outro message\n const nextSteps = [\n 'Configure your API key in environment variables for deployment',\n 'Start using Raindrop in your application',\n ].filter(Boolean);\n\n const outroMessage = `${chalk.white('Raindrop successfully integrated')}\n\n${chalk.yellow('Next steps:')}\n${nextSteps.map((step) => `• ${step}`).join('\\n')}\n\nLearn more: ${chalk.cyan('https://www.raindrop.ai/docs')}\n${chalk.dim(\n 'Note: The Raindrop wizard uses an LLM agent to analyze and modify your project. Please review the changes made.',\n)}`;\n\n ui.addItem({ type: 'success', text: outroMessage });\n}\n"]}
1
+ {"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../../src/lib/wizard.ts"],"names":[],"mappings":"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","sourcesContent":["import Chalk from 'chalk';\nimport clipboardy from 'clipboardy';\nimport {\n askForWizardLogin,\n confirmContinueIfNoOrDirtyGitRepo,\n} from '../utils/clack-utils.js';\nimport { enableDebugLogs } from '../utils/debug.js';\nimport { saveWriteKeyToEnv } from '../utils/environment.js';\nimport { getOrgWriteKey } from '../utils/oauth.js';\nimport type { WizardOptions } from '../utils/types.js';\nimport ui from '../utils/ui.js';\nimport { initializeAgent, runAgentLoop } from './agent-interface.js';\nimport { ANTHROPIC_BASE_URL, SPINNER_MESSAGE } from './constants.js';\nimport { testIntegration } from './integration-testing.js';\n\n// chalk v2 types don't work well with ESM default imports\nconst chalk = Chalk as any;\n\n/**\n * Unified wizard powered by the universal agent runner.\n * The agent will detect the integration type and load appropriate documentation.\n */\nexport async function runWizard(options: WizardOptions): Promise<void> {\n if (options.debug) {\n enableDebugLogs();\n }\n\n // Check if the current directory is a git repository and has uncommitted or untracked changes; prompt the user to continue if so.\n await confirmContinueIfNoOrDirtyGitRepo(options);\n\n const token = await askForWizardLogin();\n\n // Set the wizard JWT in process.env for the SDK\n process.env.ANTHROPIC_AUTH_TOKEN = token.token;\n\n const writeKeySpinner = ui.spinner();\n writeKeySpinner.start('Retrieving your Raindrop write key...');\n\n let writeKey: string;\n try {\n const result = await getOrgWriteKey(token.token);\n writeKey = result.writeKey;\n } catch (error) {\n writeKeySpinner.stop('Failed to retrieve write key');\n ui.addItem({\n type: 'error',\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n });\n throw error;\n }\n\n writeKeySpinner.stop();\n\n // Show org info and write key in a beautiful box\n ui.addItem({\n type: 'org-info',\n text: 'Organization info',\n orgName: token.orgName,\n writeKey,\n });\n\n // Prompt user for what to do with the write key\n const writeKeyAction = await ui.feedbackSelect({\n message: `What would you like to do with your ${chalk.cyan(\n 'RAINDROP_WRITE_KEY',\n )}?`,\n options: [\n { value: 'add-env', label: 'Add to .env' },\n { value: 'copy', label: 'Copy to clipboard' },\n { value: 'continue', label: 'Continue' },\n ],\n skipHistory: true,\n });\n\n // Determine the label for the history item based on action taken\n let writeKeyLabel: string | undefined;\n\n if (writeKeyAction.type === 'option') {\n if (writeKeyAction.value === 'add-env') {\n try {\n await saveWriteKeyToEnv(writeKey, options.installDir);\n writeKeyLabel = 'saved to .env';\n } catch (error) {\n ui.addItem({\n type: 'error',\n text: `Failed to add write key to .env: ${\n error instanceof Error ? error.message : String(error)\n }`,\n });\n }\n } else if (writeKeyAction.value === 'copy') {\n try {\n await clipboardy.write(`RAINDROP_WRITE_KEY=${writeKey}`);\n writeKeyLabel = 'copied to clipboard';\n } catch (error) {\n ui.addItem({\n type: 'error',\n text: `Failed to copy to clipboard: ${\n error instanceof Error ? error.message : String(error)\n }`,\n });\n }\n }\n // For 'continue', writeKeyLabel remains undefined\n }\n\n process.env.ANTHROPIC_BASE_URL = ANTHROPIC_BASE_URL;\n process.env.ANTHROPIC_AUTH_TOKEN = token.token;\n process.env.ANTHROPIC_CUSTOM_HEADERS = `x-wizard-session: ${options.sessionId}`;\n\n // Initialize agent\n const agent = initializeAgent(\n {\n workingDirectory: options.installDir,\n },\n options,\n );\n\n const agentResult = await runAgentLoop(\n agent,\n `[Wizard] Your WIZARD SESSION ID is ${options.sessionId}. Begin the integration.`,\n options,\n {\n spinnerMessage: SPINNER_MESSAGE,\n accessToken: token.token,\n orgId: token.orgId.toString(),\n onCompleteIntegration: async () => {\n // Ensure persistent input is stopped before testing phase\n ui.stopPersistentInput();\n return testIntegration(\n options,\n writeKey,\n token.token,\n token.orgId.toString(),\n );\n },\n },\n );\n\n if (!agentResult.completed) {\n if (!agentResult.support) {\n ui.addItem({\n type: 'warning',\n text: 'Integration session ended before confirmation. You can rerun the wizard to continue.',\n });\n }\n return;\n }\n\n // Build outro message\n const nextSteps = [\n 'Configure your API key in environment variables for deployment',\n 'Start using Raindrop in your application',\n ].filter(Boolean);\n\n const outroMessage = `${chalk.white('Raindrop successfully integrated')}\n\n${chalk.yellow('Next steps:')}\n${nextSteps.map((step) => `• ${step}`).join('\\n')}\n\nLearn more: ${chalk.cyan('https://www.raindrop.ai/docs')}\n${chalk.dim(\n 'Note: The Raindrop wizard uses an LLM agent to analyze and modify your project. Please review the changes made.',\n)}`;\n\n ui.addItem({ type: 'success', text: outroMessage });\n}\n"]}
@@ -34,6 +34,24 @@ function getRelativePath(fullPath) {
34
34
  return fullPath;
35
35
  return parts.slice(-2).join('/');
36
36
  }
37
+ function truncateLabel(value, max = 80) {
38
+ if (value.length <= max)
39
+ return value;
40
+ return `${value.slice(0, max - 3)}...`;
41
+ }
42
+ function extractDomain(urlValue) {
43
+ if (typeof urlValue !== 'string' || !urlValue.trim()) {
44
+ return null;
45
+ }
46
+ try {
47
+ return new URL(urlValue).hostname;
48
+ }
49
+ catch {
50
+ const withoutProtocol = urlValue.replace(/^[a-z]+:\/\//i, '');
51
+ const domain = withoutProtocol.split('/')[0];
52
+ return domain || null;
53
+ }
54
+ }
37
55
  /**
38
56
  * Format tool display name and parameters separately
39
57
  */
@@ -59,6 +77,18 @@ function formatToolDisplay(toolName, input) {
59
77
  const filePath = getRelativePath(input?.file_path ?? input?.path);
60
78
  return { name: 'Write', params: `(${filePath})` };
61
79
  }
80
+ case 'WebSearch': {
81
+ const searchTerm = typeof input?.query === 'string'
82
+ ? input.query
83
+ : typeof input?.search_term === 'string'
84
+ ? input.search_term
85
+ : '...';
86
+ return { name: 'WebSearch', params: `(${truncateLabel(searchTerm)})` };
87
+ }
88
+ case 'WebFetch': {
89
+ const domain = extractDomain(input?.url);
90
+ return { name: 'WebFetch', params: `(${truncateLabel(domain ?? '...')})` };
91
+ }
62
92
  default:
63
93
  return { name: toolName, params: null };
64
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ToolCallDisplay.js","sourceRoot":"","sources":["../../../../src/ui/components/ToolCallDisplay.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool call display component for history items.\n * Shows tool execution status, name, and optional details.\n */\n\nimport React from 'react';\nimport { Box, Text } from 'ink';\nimport type { ToolCallInfo, ToolCallStatus } from '../types.js';\nimport { DiffDisplay } from './DiffDisplay.js';\n\ninterface ToolCallDisplayProps {\n toolCall: ToolCallInfo;\n}\n\n/**\n * Get status indicator based on tool call status\n */\nfunction getStatusIndicator(status: ToolCallStatus): {\n symbol: string;\n color: string;\n} {\n switch (status) {\n case 'pending':\n return { symbol: '○', color: 'gray' };\n case 'executing':\n return { symbol: '◐', color: 'yellow' };\n case 'success':\n return { symbol: '●', color: 'green' };\n case 'error':\n return { symbol: '●', color: 'red' };\n case 'denied':\n return { symbol: '○', color: 'red' };\n case 'interrupted':\n return { symbol: '●', color: 'red' };\n default:\n return { symbol: '○', color: 'gray' };\n }\n}\n\n/**\n * Get relative path by extracting filename or last path segments\n */\nfunction getRelativePath(fullPath: unknown): string {\n if (typeof fullPath !== 'string') return '...';\n // Get the last 2-3 path segments for context\n const parts = fullPath.split('/').filter(Boolean);\n if (parts.length <= 2) return fullPath;\n return parts.slice(-2).join('/');\n}\n\n/**\n * Format tool display name and parameters separately\n */\nfunction formatToolDisplay(\n toolName: string,\n input?: Record<string, unknown>,\n): { name: string; params: string | null } {\n switch (toolName) {\n case 'Glob': {\n const pattern = input?.glob_pattern ?? input?.pattern ?? '*';\n return { name: 'Search', params: `(pattern: \"${pattern}\")` };\n }\n case 'Grep': {\n const pattern = input?.pattern ?? input?.regex ?? '...';\n return { name: 'Search', params: `(pattern: \"${pattern}\")` };\n }\n case 'Read': {\n const filePath = getRelativePath(input?.file_path ?? input?.path);\n return { name: 'Read', params: `(${filePath})` };\n }\n case 'Edit': {\n const filePath = getRelativePath(input?.file_path ?? input?.path);\n return { name: 'Update', params: `(${filePath})` };\n }\n case 'Write': {\n const filePath = getRelativePath(input?.file_path ?? input?.path);\n return { name: 'Write', params: `(${filePath})` };\n }\n default:\n return { name: toolName, params: null };\n }\n}\n\n/**\n * Display a tool call in the history\n */\nexport function ToolCallDisplay({\n toolCall,\n}: ToolCallDisplayProps): React.ReactElement {\n const { toolName, status, result, error, input, diffContent } = toolCall;\n const { symbol, color } = getStatusIndicator(status);\n const { name, params } = formatToolDisplay(toolName, input);\n\n // For Bash, show the command instead of description\n const subtitle = toolName === 'Bash' \n ? (typeof input?.command === 'string' ? input.command : null)\n : null;\n\n // Check if this is an Edit or Write tool that should show diff\n // Don't show diff for Edit/Write since user already saw it in the approval prompt\n const shouldShowDiff = false;\n\n return (\n <Box flexDirection=\"column\">\n {/* Main line with status and tool name */}\n <Box>\n <Text color={color}>{symbol}</Text>\n <Text> </Text>\n <Text bold>{name}</Text>\n {params && <Text>{params}</Text>}\n </Box>\n\n {/* For Bash, show the command */}\n {subtitle && (\n <Box marginLeft={2}>\n <Text dimColor>{subtitle}</Text>\n </Box>\n )}\n\n {/* Result summary (e.g., \"Added 1 line, removed 1 line\") */}\n {status === 'success' && result && (\n <Box marginLeft={2}>\n <Text dimColor>└─ </Text>\n <Text color=\"green\">{result}</Text>\n </Box>\n )}\n\n {/* Diff content for Edit/Write tools */}\n {shouldShowDiff && diffContent && (\n <Box marginLeft={2} marginTop={1}>\n <DiffDisplay diffContent={diffContent} maxHeight={15} />\n </Box>\n )}\n\n {status === 'error' && error && (\n <Box marginLeft={2}>\n <Text dimColor>└─ </Text>\n <Text color=\"red\">{error}</Text>\n </Box>\n )}\n\n {status === 'denied' && (\n <Box marginLeft={2}>\n <Text dimColor>└─ </Text>\n <Text color=\"yellow\">Denied by user</Text>\n </Box>\n )}\n\n {status === 'interrupted' && (\n <Box marginLeft={2}>\n <Text dimColor>└─ </Text>\n <Text color=\"red\">Interrupted</Text>\n </Box>\n )}\n </Box>\n );\n}\n\nexport default ToolCallDisplay;\n"]}
1
+ {"version":3,"file":"ToolCallDisplay.js","sourceRoot":"","sources":["../../../../src/ui/components/ToolCallDisplay.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool call display component for history items.\n * Shows tool execution status, name, and optional details.\n */\n\nimport React from 'react';\nimport { Box, Text } from 'ink';\nimport type { ToolCallInfo, ToolCallStatus } from '../types.js';\nimport { DiffDisplay } from './DiffDisplay.js';\n\ninterface ToolCallDisplayProps {\n toolCall: ToolCallInfo;\n}\n\n/**\n * Get status indicator based on tool call status\n */\nfunction getStatusIndicator(status: ToolCallStatus): {\n symbol: string;\n color: string;\n} {\n switch (status) {\n case 'pending':\n return { symbol: '○', color: 'gray' };\n case 'executing':\n return { symbol: '◐', color: 'yellow' };\n case 'success':\n return { symbol: '●', color: 'green' };\n case 'error':\n return { symbol: '●', color: 'red' };\n case 'denied':\n return { symbol: '○', color: 'red' };\n case 'interrupted':\n return { symbol: '●', color: 'red' };\n default:\n return { symbol: '○', color: 'gray' };\n }\n}\n\n/**\n * Get relative path by extracting filename or last path segments\n */\nfunction getRelativePath(fullPath: unknown): string {\n if (typeof fullPath !== 'string') return '...';\n // Get the last 2-3 path segments for context\n const parts = fullPath.split('/').filter(Boolean);\n if (parts.length <= 2) return fullPath;\n return parts.slice(-2).join('/');\n}\n\nfunction truncateLabel(value: string, max = 80): string {\n if (value.length <= max) return value;\n return `${value.slice(0, max - 3)}...`;\n}\n\nfunction extractDomain(urlValue: unknown): string | null {\n if (typeof urlValue !== 'string' || !urlValue.trim()) {\n return null;\n }\n\n try {\n return new URL(urlValue).hostname;\n } catch {\n const withoutProtocol = urlValue.replace(/^[a-z]+:\\/\\//i, '');\n const domain = withoutProtocol.split('/')[0];\n return domain || null;\n }\n}\n\n/**\n * Format tool display name and parameters separately\n */\nfunction formatToolDisplay(\n toolName: string,\n input?: Record<string, unknown>,\n): { name: string; params: string | null } {\n switch (toolName) {\n case 'Glob': {\n const pattern = input?.glob_pattern ?? input?.pattern ?? '*';\n return { name: 'Search', params: `(pattern: \"${pattern}\")` };\n }\n case 'Grep': {\n const pattern = input?.pattern ?? input?.regex ?? '...';\n return { name: 'Search', params: `(pattern: \"${pattern}\")` };\n }\n case 'Read': {\n const filePath = getRelativePath(input?.file_path ?? input?.path);\n return { name: 'Read', params: `(${filePath})` };\n }\n case 'Edit': {\n const filePath = getRelativePath(input?.file_path ?? input?.path);\n return { name: 'Update', params: `(${filePath})` };\n }\n case 'Write': {\n const filePath = getRelativePath(input?.file_path ?? input?.path);\n return { name: 'Write', params: `(${filePath})` };\n }\n case 'WebSearch': {\n const searchTerm =\n typeof input?.query === 'string'\n ? input.query\n : typeof input?.search_term === 'string'\n ? input.search_term\n : '...';\n return { name: 'WebSearch', params: `(${truncateLabel(searchTerm)})` };\n }\n case 'WebFetch': {\n const domain = extractDomain(input?.url);\n return { name: 'WebFetch', params: `(${truncateLabel(domain ?? '...')})` };\n }\n default:\n return { name: toolName, params: null };\n }\n}\n\n/**\n * Display a tool call in the history\n */\nexport function ToolCallDisplay({\n toolCall,\n}: ToolCallDisplayProps): React.ReactElement {\n const { toolName, status, result, error, input, diffContent } = toolCall;\n const { symbol, color } = getStatusIndicator(status);\n const { name, params } = formatToolDisplay(toolName, input);\n\n // For Bash, show the command instead of description\n const subtitle = toolName === 'Bash' \n ? (typeof input?.command === 'string' ? input.command : null)\n : null;\n\n // Check if this is an Edit or Write tool that should show diff\n // Don't show diff for Edit/Write since user already saw it in the approval prompt\n const shouldShowDiff = false;\n\n return (\n <Box flexDirection=\"column\">\n {/* Main line with status and tool name */}\n <Box>\n <Text color={color}>{symbol}</Text>\n <Text> </Text>\n <Text bold>{name}</Text>\n {params && <Text>{params}</Text>}\n </Box>\n\n {/* For Bash, show the command */}\n {subtitle && (\n <Box marginLeft={2}>\n <Text dimColor>{subtitle}</Text>\n </Box>\n )}\n\n {/* Result summary (e.g., \"Added 1 line, removed 1 line\") */}\n {status === 'success' && result && (\n <Box marginLeft={2}>\n <Text dimColor>└─ </Text>\n <Text color=\"green\">{result}</Text>\n </Box>\n )}\n\n {/* Diff content for Edit/Write tools */}\n {shouldShowDiff && diffContent && (\n <Box marginLeft={2} marginTop={1}>\n <DiffDisplay diffContent={diffContent} maxHeight={15} />\n </Box>\n )}\n\n {status === 'error' && error && (\n <Box marginLeft={2}>\n <Text dimColor>└─ </Text>\n <Text color=\"red\">{error}</Text>\n </Box>\n )}\n\n {status === 'denied' && (\n <Box marginLeft={2}>\n <Text dimColor>└─ </Text>\n <Text color=\"yellow\">Denied by user</Text>\n </Box>\n )}\n\n {status === 'interrupted' && (\n <Box marginLeft={2}>\n <Text dimColor>└─ </Text>\n <Text color=\"red\">Interrupted</Text>\n </Box>\n )}\n </Box>\n );\n}\n\nexport default ToolCallDisplay;\n"]}
@@ -84,17 +84,8 @@ export interface PendingItem {
84
84
  * Agent execution state
85
85
  */
86
86
  export interface AgentState {
87
- /** Whether an agent is currently running */
88
- isRunning: boolean;
89
- /** Session ID for resuming */
90
- sessionId?: string;
91
87
  /** Handle to control the running agent */
92
88
  queryHandle?: AgentQueryHandle;
93
- /** Callbacks to restore persistent input after approval prompts */
94
- persistentInputCallbacks?: {
95
- onSubmit: (message: string) => void;
96
- onInterrupt: () => void;
97
- };
98
89
  }
99
90
  /**
100
91
  * Wizard state that's exposed via context
@@ -104,8 +95,6 @@ export interface WizardState {
104
95
  history: HistoryItem[];
105
96
  /** Currently active prompt (rendered as pending) */
106
97
  pendingItem: PendingItem | null;
107
- /** Whether the app is ready to exit */
108
- shouldExit: boolean;
109
98
  /** Agent execution state */
110
99
  agentState: AgentState;
111
100
  /** Active spinner message (separate from pendingItem so both can be visible) */
@@ -41,10 +41,7 @@ export function WizardProvider({ children, onExit, }) {
41
41
  // This allows multiple tool approvals to be queued without losing earlier ones
42
42
  // Note: persistent-input is NOT stored in queue, it's a fallback shown when queue is empty
43
43
  const [pendingQueue, setPendingQueue] = useState([]);
44
- const [shouldExit, setShouldExit] = useState(false);
45
- const [agentState, setAgentStateInternal] = useState({
46
- isRunning: false,
47
- });
44
+ const [agentState, setAgentStateInternal] = useState({});
48
45
  // Spinner state - separate from pendingItem so both can be visible
49
46
  const [activeSpinner, setActiveSpinner] = useState(null);
50
47
  // Terminal size state for responsive rendering
@@ -240,7 +237,6 @@ export function WizardProvider({ children, onExit, }) {
240
237
  }, [addItem]);
241
238
  // Exit the app
242
239
  const exit = useCallback(() => {
243
- setShouldExit(true);
244
240
  onExit?.();
245
241
  }, [onExit]);
246
242
  // ========================================================================
@@ -313,14 +309,6 @@ export function WizardProvider({ children, onExit, }) {
313
309
  // Store config - persistent input will automatically show when queue is empty.
314
310
  // The live input text is preserved separately in persistentInputValueRef.
315
311
  setPersistentInputConfig(config);
316
- // Also store callbacks in agent state for external access if needed
317
- setAgentStateInternal((current) => ({
318
- ...current,
319
- persistentInputCallbacks: {
320
- onSubmit: config.onSubmit,
321
- onInterrupt: config.onInterrupt,
322
- },
323
- }));
324
312
  }, []);
325
313
  // Stop persistent input mode - clears config so it no longer shows
326
314
  const stopPersistentInput = useCallback(() => {
@@ -329,10 +317,6 @@ export function WizardProvider({ children, onExit, }) {
329
317
  // Also clear the refs to prevent the input from lingering
330
318
  persistentInputItemRef.current = null;
331
319
  lastValidPendingItemRef.current = null;
332
- setAgentStateInternal((current) => ({
333
- ...current,
334
- persistentInputCallbacks: undefined,
335
- }));
336
320
  }, []);
337
321
  // Update persistent input value - allows PersistentTextInput to save its state
338
322
  const updatePersistentInputValue = useCallback((value) => {
@@ -389,11 +373,10 @@ export function WizardProvider({ children, onExit, }) {
389
373
  const state = useMemo(() => ({
390
374
  history,
391
375
  pendingItem,
392
- shouldExit,
393
376
  agentState,
394
377
  activeSpinner,
395
378
  terminalSize,
396
- }), [history, pendingItem, shouldExit, agentState, activeSpinner, terminalSize]);
379
+ }), [history, pendingItem, agentState, activeSpinner, terminalSize]);
397
380
  // Context value
398
381
  const contextValue = useMemo(() => ({ state, actions }), [state, actions]);
399
382
  return (_jsx(WizardContext.Provider, { value: contextValue, children: children }));
@@ -1 +1 @@
1
- {"version":3,"file":"WizardContext.js","sourceRoot":"","sources":["../../../../src/ui/contexts/WizardContext.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Central state management for the unified Ink wizard app.\n * Uses React Context to share state between all UI components.\n */\n\nimport React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useRef,\n useMemo,\n useEffect,\n type ReactNode,\n} from 'react';\nimport { useStdout } from 'ink';\nimport type {\n SelectOptions,\n TextOptions,\n SpinnerInstance,\n ToolApprovalProps,\n ToolApprovalResult,\n ClarifyingQuestionsProps,\n ClarifyingQuestionsResult,\n PlanApprovalProps,\n PlanApprovalResult,\n PersistentInputProps,\n ToolCallInfo,\n AgentQueryHandle,\n FeedbackSelectOptions,\n FeedbackSelectResult,\n ContinuePromptOptions,\n} from '../types.js';\nimport { SPINNER_MESSAGE } from '../../lib/constants.js';\n\n/**\n * Types of items that can appear in history\n */\nexport type HistoryItemType =\n | 'logo'\n | 'outro'\n | 'note'\n | 'cancel'\n | 'response'\n | 'warning'\n | 'error'\n | 'success'\n | 'step'\n | 'phase'\n | 'select-result'\n | 'text-result'\n | 'spinner-result'\n | 'tool-call'\n | 'agent-message'\n | 'user-message'\n | 'clarifying-questions-result'\n | 'declined-questions'\n | 'received-event'\n | 'plan-review'\n | 'plan-approved'\n | 'plan-rejected'\n | 'write-key'\n | 'org-info';\n\n/**\n * Data for received-event history items\n */\nexport interface ReceivedEventData {\n id: string;\n eventName: string;\n timestamp?: string;\n model?: string;\n userId?: string;\n input?: string;\n output?: string;\n toolCallNames?: string[];\n}\n\n/**\n * A completed item that goes into history\n */\nexport interface HistoryItem {\n id: number;\n type: HistoryItemType;\n text: string;\n /** Optional secondary content (e.g., selected option label) */\n label?: string;\n /** Optional hint/description */\n hint?: string;\n /** Title for note items */\n title?: string;\n /** For tool-call items, the tool call info */\n toolCall?: ToolCallInfo;\n /** For clarifying-questions-result items, the Q&A pairs */\n questionsAndAnswers?: Array<{ question: string; answer: string }>;\n /** For received-event items, the event data */\n receivedEvent?: ReceivedEventData;\n /** For plan-approved and plan-rejected items, the plan content */\n planContent?: string;\n /** For write-key items, the write key and install directory */\n writeKey?: string;\n installDir?: string;\n /** For write-key items, whether the component should be interactive */\n isActive?: boolean;\n /** For org-info items, the organization name */\n orgName?: string;\n}\n\n/**\n * Input type for adding history items (without id)\n */\nexport type HistoryItemInput = Omit<HistoryItem, 'id'>;\n\n/**\n * Types of pending prompts that can be active\n */\nexport type PendingItemType =\n | 'select'\n | 'text'\n | 'spinner'\n | 'tool-approval'\n | 'clarifying-questions'\n | 'plan-approval'\n | 'persistent-input'\n | 'feedback-select'\n | 'continue';\n\n/**\n * Spinner-specific props\n */\nexport interface SpinnerProps {\n message: string;\n}\n\n/**\n * All possible pending item props\n */\nexport type PendingItemProps =\n | SelectOptions<unknown>\n | TextOptions\n | SpinnerProps\n | ToolApprovalProps\n | ClarifyingQuestionsProps\n | PlanApprovalProps\n | PersistentInputProps\n | FeedbackSelectOptions<unknown>\n | ContinuePromptOptions;\n\n/**\n * A pending item represents an active prompt or spinner\n */\nexport interface PendingItem {\n type: PendingItemType;\n props: PendingItemProps;\n resolve: (value: unknown) => void;\n reject?: (error: Error) => void;\n}\n\n/**\n * Agent execution state\n */\nexport interface AgentState {\n /** Whether an agent is currently running */\n isRunning: boolean;\n /** Session ID for resuming */\n sessionId?: string;\n /** Handle to control the running agent */\n queryHandle?: AgentQueryHandle;\n /** Callbacks to restore persistent input after approval prompts */\n persistentInputCallbacks?: {\n onSubmit: (message: string) => void;\n onInterrupt: () => void;\n };\n}\n\n/**\n * Wizard state that's exposed via context\n */\nexport interface WizardState {\n /** Completed history items */\n history: HistoryItem[];\n /** Currently active prompt (rendered as pending) */\n pendingItem: PendingItem | null;\n /** Whether the app is ready to exit */\n shouldExit: boolean;\n /** Agent execution state */\n agentState: AgentState;\n /** Active spinner message (separate from pendingItem so both can be visible) */\n activeSpinner: string | null;\n /** Terminal dimensions for responsive rendering */\n terminalSize: { width: number; height: number };\n}\n\n/**\n * Actions to modify wizard state\n */\nexport interface WizardActions {\n /** Add an item to history, returns the assigned item ID */\n addItem: (item: HistoryItemInput) => number;\n\n /** Update an existing history item by ID */\n updateItem: (id: number, updates: Partial<HistoryItemInput>) => void;\n\n /** Deactivate all write-key items in history */\n deactivateWriteKeys: () => void;\n\n /** Display a select prompt and return the selected value */\n select: <T>(options: SelectOptions<T>) => Promise<T | symbol>;\n\n /** Display a text input prompt and return the entered value */\n text: (options: TextOptions) => Promise<string | symbol>;\n\n /** Display a continue button prompt and wait for user to press Enter */\n continue: (options: ContinuePromptOptions) => Promise<boolean | symbol>;\n\n /** Display a spinner and return control methods */\n spinner: () => SpinnerInstance;\n\n /** Resolve the current pending item with a value */\n resolvePending: (value: unknown) => void;\n\n /** Mark the app as ready to exit */\n exit: () => void;\n\n // ========================================================================\n // Agent-related actions\n // ========================================================================\n\n /**\n * Show tool approval prompt (replaces persistent-input, restores after)\n * Used by canUseTool handler for tools that need user approval\n */\n toolApproval: (props: ToolApprovalProps) => Promise<ToolApprovalResult>;\n\n /**\n * Show clarifying questions prompt (replaces persistent-input, restores after)\n * Used by canUseTool handler for AskUserQuestion tool\n */\n clarifyingQuestions: (\n props: ClarifyingQuestionsProps,\n ) => Promise<ClarifyingQuestionsResult>;\n\n /**\n * Show plan approval prompt (replaces persistent-input, restores after)\n * Used by canUseTool handler for ExitPlanMode tool\n */\n planApproval: (props: PlanApprovalProps) => Promise<PlanApprovalResult>;\n\n /**\n * Show feedback select prompt (select with inline text input option)\n * Used for \"yes/no with feedback\" patterns\n */\n feedbackSelect: <T>(\n options: FeedbackSelectOptions<T>,\n ) => Promise<FeedbackSelectResult<T>>;\n\n /**\n * Start persistent input mode during agent execution\n * Sets pendingItem to persistent-input type\n */\n startPersistentInput: (config: {\n onSubmit: (message: string) => void;\n onInterrupt: () => void;\n onCtrlC?: () => void;\n message?: string;\n placeholder?: string;\n }) => void;\n\n /**\n * Stop persistent input mode\n * Clears pendingItem if it's persistent-input type\n */\n stopPersistentInput: () => void;\n\n /**\n * Update persistent input value\n * Allows PersistentTextInput to preserve its state across unmount/remount\n */\n updatePersistentInputValue: (value: string) => void;\n\n /**\n * Update agent state\n */\n setAgentState: (state: Partial<AgentState>) => void;\n}\n\n/**\n * Combined context type\n */\nexport interface WizardContextType {\n state: WizardState;\n actions: WizardActions;\n}\n\n// Create the context with a null default (must be used within provider)\nconst WizardContext = createContext<WizardContextType | null>(null);\n\n/**\n * Hook to access wizard state and actions\n */\nexport function useWizard(): WizardContextType {\n const context = useContext(WizardContext);\n if (!context) {\n throw new Error('useWizard must be used within a WizardProvider');\n }\n return context;\n}\n\n/**\n * Hook to access just the wizard state\n */\nexport function useWizardState(): WizardState {\n return useWizard().state;\n}\n\n/**\n * Hook to access just the wizard actions\n */\nexport function useWizardActions(): WizardActions {\n return useWizard().actions;\n}\n\n/**\n * Props for the WizardProvider\n */\ninterface WizardProviderProps {\n children: ReactNode;\n onExit?: () => void;\n}\n\n/**\n * Provider component that manages all wizard state\n */\nexport function WizardProvider({\n children,\n onExit,\n}: WizardProviderProps): React.ReactElement {\n const { stdout } = useStdout();\n\n // State\n const [history, setHistory] = useState<HistoryItem[]>([]);\n // Queue of pending items - processes one at a time, FIFO order\n // This allows multiple tool approvals to be queued without losing earlier ones\n // Note: persistent-input is NOT stored in queue, it's a fallback shown when queue is empty\n const [pendingQueue, setPendingQueue] = useState<PendingItem[]>([]);\n const [shouldExit, setShouldExit] = useState(false);\n const [agentState, setAgentStateInternal] = useState<AgentState>({\n isRunning: false,\n });\n // Spinner state - separate from pendingItem so both can be visible\n const [activeSpinner, setActiveSpinner] = useState<string | null>(null);\n // Terminal size state for responsive rendering\n const [terminalSize, setTerminalSize] = useState({\n width: Math.max(1, stdout?.columns || 80),\n height: Math.max(1, stdout?.rows || 24),\n });\n\n // Persistent input config - stored separately, shown as fallback when queue is empty\n const [persistentInputConfig, setPersistentInputConfig] = useState<{\n onSubmit: (message: string) => void;\n onInterrupt: () => void;\n onCtrlC?: () => void;\n message?: string;\n placeholder?: string;\n } | null>(null);\n\n // Ref to store persistent input pending item - reuse same object to prevent re-renders\n const persistentInputItemRef = useRef<PendingItem | null>(null);\n // Ref to preserve in-progress persistent input text without triggering re-renders\n const persistentInputValueRef = useRef('');\n\n // Ref to store the last valid pending item to prevent flickering\n const lastValidPendingItemRef = useRef<PendingItem | null>(null);\n\n // Listen for terminal resize events\n useEffect(() => {\n const handleResize = () => {\n const nextWidth = Math.max(1, stdout?.columns || 80);\n const nextHeight = Math.max(1, stdout?.rows || 24);\n\n setTerminalSize((current) => {\n if (current.width === nextWidth && current.height === nextHeight) {\n return current;\n }\n\n return {\n width: nextWidth,\n height: nextHeight,\n };\n });\n };\n\n // Update terminal size on mount and when stdout changes\n handleResize();\n\n // Listen for resize events\n if (stdout) {\n stdout.on('resize', handleResize);\n return () => {\n stdout.off('resize', handleResize);\n };\n }\n }, [stdout]);\n\n // Derive current pending item:\n // 1. If queue has items → show first item in queue\n // 2. If queue is empty AND persistent input is active → show persistent input\n // 3. Otherwise → keep showing the last valid item to prevent flickering\n const pendingItem: PendingItem | null = useMemo(() => {\n let newPendingItem: PendingItem | null = null;\n\n // Priority 1: Items in queue\n if (pendingQueue.length > 0) {\n newPendingItem = pendingQueue[0];\n }\n // Priority 2: Persistent input (fallback when queue is empty)\n else if (persistentInputConfig) {\n // Reuse the same pending item object if the config hasn't changed\n // This prevents unnecessary re-renders when switching back to persistent input\n const currentRef = persistentInputItemRef.current;\n const propsMatch =\n currentRef &&\n (currentRef.props as PersistentInputProps).onSubmit ===\n persistentInputConfig.onSubmit &&\n (currentRef.props as PersistentInputProps).onInterrupt ===\n persistentInputConfig.onInterrupt &&\n (currentRef.props as PersistentInputProps).onCtrlC ===\n persistentInputConfig.onCtrlC &&\n (currentRef.props as PersistentInputProps).message ===\n persistentInputConfig.message &&\n (currentRef.props as PersistentInputProps).placeholder ===\n (persistentInputConfig.placeholder ??\n 'Type a message or press Esc to interrupt...');\n\n if (!propsMatch) {\n // Config changed, create new pending item\n persistentInputItemRef.current = {\n type: 'persistent-input',\n props: {\n onSubmit: persistentInputConfig.onSubmit,\n onInterrupt: persistentInputConfig.onInterrupt,\n onCtrlC: persistentInputConfig.onCtrlC,\n placeholder:\n persistentInputConfig.placeholder ??\n 'Type a message or press Esc to interrupt...',\n message: persistentInputConfig.message,\n defaultValue: persistentInputValueRef.current,\n } as PersistentInputProps,\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n resolve: () => {},\n };\n }\n newPendingItem = persistentInputItemRef.current;\n }\n\n // If we have a valid new pending item, update the ref and return it\n if (newPendingItem) {\n lastValidPendingItemRef.current = newPendingItem;\n return newPendingItem;\n }\n\n // If no new pending item but we have a last valid one, keep showing it to prevent flickering\n // This handles intermediate render states where pendingQueue might be temporarily empty\n if (lastValidPendingItemRef.current) {\n return lastValidPendingItemRef.current;\n }\n\n // No pending items at all\n persistentInputItemRef.current = null;\n lastValidPendingItemRef.current = null;\n return null;\n }, [pendingQueue, persistentInputConfig]);\n\n // Counter for unique IDs\n const idCounter = useRef(0);\n\n // Get next unique ID\n const getNextId = useCallback(() => {\n return ++idCounter.current;\n }, []);\n\n // Add item to history (direct, like gemini-cli). Returns the assigned ID.\n const addItem = useCallback(\n (item: HistoryItemInput): number => {\n const id = getNextId();\n setHistory((prev) => [...prev, { ...item, id }]);\n return id;\n },\n [getNextId],\n );\n\n // Update an existing history item by ID\n const updateItem = useCallback(\n (id: number, updates: Partial<HistoryItemInput>) => {\n setHistory((prev) =>\n prev.map((item) => (item.id === id ? { ...item, ...updates } : item)),\n );\n },\n [],\n );\n\n // Deactivate all write-key items in history\n const deactivateWriteKeys = useCallback(() => {\n setHistory((prev) =>\n prev.map((item) =>\n item.type === 'write-key' && item.isActive\n ? { ...item, isActive: false }\n : item,\n ),\n );\n }, []);\n\n // Resolve current pending item and advance the queue\n const resolvePending = useCallback((value: unknown) => {\n // Clear the last valid pending item ref to prevent flickering/repeating the old question\n lastValidPendingItemRef.current = null;\n\n setPendingQueue((queue) => {\n if (queue.length > 0) {\n // Resolve the first item in the queue\n queue[0].resolve(value);\n // Return the queue without the first item (shift)\n return queue.slice(1);\n }\n return queue;\n });\n }, []);\n\n // Show select prompt - adds to queue\n const select = useCallback(\n <T,>(options: SelectOptions<T>): Promise<T | symbol> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'select',\n props: options as SelectOptions<unknown>,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [],\n );\n\n // Show text prompt - adds to queue\n const text = useCallback((options: TextOptions): Promise<string | symbol> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'text',\n props: options,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n }, []);\n\n // Show continue button prompt - adds to queue\n const continuePrompt = useCallback(\n (options: ContinuePromptOptions): Promise<boolean | symbol> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'continue',\n props: options,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [],\n );\n\n // Show spinner - uses separate activeSpinner state so it can be visible alongside pendingItem\n const spinner = useCallback((): SpinnerInstance => {\n return {\n start: (msg = '') => {\n setActiveSpinner(msg || SPINNER_MESSAGE);\n },\n stop: (msg = '') => {\n if (msg) {\n addItem({ type: 'spinner-result', text: msg });\n }\n setActiveSpinner(null);\n },\n message: (msg: string) => {\n setActiveSpinner((prev) => (prev !== null ? msg : null));\n },\n };\n }, [addItem]);\n\n // Exit the app\n const exit = useCallback(() => {\n setShouldExit(true);\n onExit?.();\n }, [onExit]);\n\n // ========================================================================\n // Agent-related actions\n // ========================================================================\n\n // Show tool approval prompt - adds to queue\n // Persistent input automatically shows when queue becomes empty (it's a fallback, not in queue)\n const toolApproval = useCallback(\n (props: ToolApprovalProps): Promise<ToolApprovalResult> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'tool-approval',\n props,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [],\n );\n\n // Show clarifying questions prompt - adds to queue\n // Persistent input automatically shows when queue becomes empty\n const clarifyingQuestions = useCallback(\n (props: ClarifyingQuestionsProps): Promise<ClarifyingQuestionsResult> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'clarifying-questions',\n props,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [],\n );\n\n // Show plan approval prompt - adds plan to history first (static), then adds selection to queue\n // Persistent input automatically shows when queue becomes empty\n const planApproval = useCallback(\n (props: PlanApprovalProps): Promise<PlanApprovalResult> => {\n // First, add the plan content to history so it's static and doesn't re-render\n addItem({\n type: 'plan-review',\n text: 'Ready to execute the plan?',\n planContent: props.planContent,\n });\n\n // Then show just the selection prompt as pending item\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'plan-approval',\n props,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [addItem],\n );\n\n // Show feedback select prompt - adds to queue\n const feedbackSelect = useCallback(\n <T,>(\n options: FeedbackSelectOptions<T>,\n ): Promise<FeedbackSelectResult<T>> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'feedback-select',\n props: options as FeedbackSelectOptions<unknown>,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [],\n );\n\n // Start persistent input mode - sets config so it shows as fallback when queue is empty\n const startPersistentInput = useCallback(\n (config: {\n onSubmit: (message: string) => void;\n onInterrupt: () => void;\n onCtrlC?: () => void;\n message?: string;\n placeholder?: string;\n }) => {\n // Store config - persistent input will automatically show when queue is empty.\n // The live input text is preserved separately in persistentInputValueRef.\n setPersistentInputConfig(config);\n\n // Also store callbacks in agent state for external access if needed\n setAgentStateInternal((current) => ({\n ...current,\n persistentInputCallbacks: {\n onSubmit: config.onSubmit,\n onInterrupt: config.onInterrupt,\n },\n }));\n },\n [],\n );\n\n // Stop persistent input mode - clears config so it no longer shows\n const stopPersistentInput = useCallback(() => {\n setPersistentInputConfig(null);\n persistentInputValueRef.current = '';\n // Also clear the refs to prevent the input from lingering\n persistentInputItemRef.current = null;\n lastValidPendingItemRef.current = null;\n\n setAgentStateInternal((current) => ({\n ...current,\n persistentInputCallbacks: undefined,\n }));\n }, []);\n\n // Update persistent input value - allows PersistentTextInput to save its state\n const updatePersistentInputValue = useCallback((value: string) => {\n persistentInputValueRef.current = value;\n\n const currentPersistentItem = persistentInputItemRef.current;\n if (currentPersistentItem?.type === 'persistent-input') {\n // Keep the ref-backed pending item up to date for future remounts.\n (currentPersistentItem.props as PersistentInputProps).defaultValue = value;\n }\n }, []);\n\n // Update agent state\n const setAgentState = useCallback((state: Partial<AgentState>) => {\n setAgentStateInternal((current) => ({ ...current, ...state }));\n }, []);\n\n // Combine actions\n const actions = useMemo<WizardActions>(\n () => ({\n addItem,\n updateItem,\n deactivateWriteKeys,\n select,\n text,\n continue: continuePrompt,\n spinner,\n resolvePending,\n exit,\n toolApproval,\n clarifyingQuestions,\n planApproval,\n feedbackSelect,\n startPersistentInput,\n stopPersistentInput,\n updatePersistentInputValue,\n setAgentState,\n }),\n [\n addItem,\n updateItem,\n deactivateWriteKeys,\n select,\n text,\n continuePrompt,\n spinner,\n resolvePending,\n exit,\n toolApproval,\n clarifyingQuestions,\n planApproval,\n feedbackSelect,\n startPersistentInput,\n stopPersistentInput,\n updatePersistentInputValue,\n setAgentState,\n ],\n );\n\n // Combine state\n const state = useMemo<WizardState>(\n () => ({\n history,\n pendingItem,\n shouldExit,\n agentState,\n activeSpinner,\n terminalSize,\n }),\n [history, pendingItem, shouldExit, agentState, activeSpinner, terminalSize],\n );\n\n // Context value\n const contextValue = useMemo<WizardContextType>(\n () => ({ state, actions }),\n [state, actions],\n );\n\n return (\n <WizardContext.Provider value={contextValue}>\n {children}\n </WizardContext.Provider>\n );\n}\n\nexport { WizardContext };\n"]}
1
+ {"version":3,"file":"WizardContext.js","sourceRoot":"","sources":["../../../../src/ui/contexts/WizardContext.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Central state management for the unified Ink wizard app.\n * Uses React Context to share state between all UI components.\n */\n\nimport React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useRef,\n useMemo,\n useEffect,\n type ReactNode,\n} from 'react';\nimport { useStdout } from 'ink';\nimport type {\n SelectOptions,\n TextOptions,\n SpinnerInstance,\n ToolApprovalProps,\n ToolApprovalResult,\n ClarifyingQuestionsProps,\n ClarifyingQuestionsResult,\n PlanApprovalProps,\n PlanApprovalResult,\n PersistentInputProps,\n ToolCallInfo,\n AgentQueryHandle,\n FeedbackSelectOptions,\n FeedbackSelectResult,\n ContinuePromptOptions,\n} from '../types.js';\nimport { SPINNER_MESSAGE } from '../../lib/constants.js';\n\n/**\n * Types of items that can appear in history\n */\nexport type HistoryItemType =\n | 'logo'\n | 'outro'\n | 'note'\n | 'cancel'\n | 'response'\n | 'warning'\n | 'error'\n | 'success'\n | 'step'\n | 'phase'\n | 'select-result'\n | 'text-result'\n | 'spinner-result'\n | 'tool-call'\n | 'agent-message'\n | 'user-message'\n | 'clarifying-questions-result'\n | 'declined-questions'\n | 'received-event'\n | 'plan-review'\n | 'plan-approved'\n | 'plan-rejected'\n | 'write-key'\n | 'org-info';\n\n/**\n * Data for received-event history items\n */\nexport interface ReceivedEventData {\n id: string;\n eventName: string;\n timestamp?: string;\n model?: string;\n userId?: string;\n input?: string;\n output?: string;\n toolCallNames?: string[];\n}\n\n/**\n * A completed item that goes into history\n */\nexport interface HistoryItem {\n id: number;\n type: HistoryItemType;\n text: string;\n /** Optional secondary content (e.g., selected option label) */\n label?: string;\n /** Optional hint/description */\n hint?: string;\n /** Title for note items */\n title?: string;\n /** For tool-call items, the tool call info */\n toolCall?: ToolCallInfo;\n /** For clarifying-questions-result items, the Q&A pairs */\n questionsAndAnswers?: Array<{ question: string; answer: string }>;\n /** For received-event items, the event data */\n receivedEvent?: ReceivedEventData;\n /** For plan-approved and plan-rejected items, the plan content */\n planContent?: string;\n /** For write-key items, the write key and install directory */\n writeKey?: string;\n installDir?: string;\n /** For write-key items, whether the component should be interactive */\n isActive?: boolean;\n /** For org-info items, the organization name */\n orgName?: string;\n}\n\n/**\n * Input type for adding history items (without id)\n */\nexport type HistoryItemInput = Omit<HistoryItem, 'id'>;\n\n/**\n * Types of pending prompts that can be active\n */\nexport type PendingItemType =\n | 'select'\n | 'text'\n | 'spinner'\n | 'tool-approval'\n | 'clarifying-questions'\n | 'plan-approval'\n | 'persistent-input'\n | 'feedback-select'\n | 'continue';\n\n/**\n * Spinner-specific props\n */\nexport interface SpinnerProps {\n message: string;\n}\n\n/**\n * All possible pending item props\n */\nexport type PendingItemProps =\n | SelectOptions<unknown>\n | TextOptions\n | SpinnerProps\n | ToolApprovalProps\n | ClarifyingQuestionsProps\n | PlanApprovalProps\n | PersistentInputProps\n | FeedbackSelectOptions<unknown>\n | ContinuePromptOptions;\n\n/**\n * A pending item represents an active prompt or spinner\n */\nexport interface PendingItem {\n type: PendingItemType;\n props: PendingItemProps;\n resolve: (value: unknown) => void;\n reject?: (error: Error) => void;\n}\n\n/**\n * Agent execution state\n */\nexport interface AgentState {\n /** Handle to control the running agent */\n queryHandle?: AgentQueryHandle;\n}\n\n/**\n * Wizard state that's exposed via context\n */\nexport interface WizardState {\n /** Completed history items */\n history: HistoryItem[];\n /** Currently active prompt (rendered as pending) */\n pendingItem: PendingItem | null;\n /** Agent execution state */\n agentState: AgentState;\n /** Active spinner message (separate from pendingItem so both can be visible) */\n activeSpinner: string | null;\n /** Terminal dimensions for responsive rendering */\n terminalSize: { width: number; height: number };\n}\n\n/**\n * Actions to modify wizard state\n */\nexport interface WizardActions {\n /** Add an item to history, returns the assigned item ID */\n addItem: (item: HistoryItemInput) => number;\n\n /** Update an existing history item by ID */\n updateItem: (id: number, updates: Partial<HistoryItemInput>) => void;\n\n /** Deactivate all write-key items in history */\n deactivateWriteKeys: () => void;\n\n /** Display a select prompt and return the selected value */\n select: <T>(options: SelectOptions<T>) => Promise<T | symbol>;\n\n /** Display a text input prompt and return the entered value */\n text: (options: TextOptions) => Promise<string | symbol>;\n\n /** Display a continue button prompt and wait for user to press Enter */\n continue: (options: ContinuePromptOptions) => Promise<boolean | symbol>;\n\n /** Display a spinner and return control methods */\n spinner: () => SpinnerInstance;\n\n /** Resolve the current pending item with a value */\n resolvePending: (value: unknown) => void;\n\n /** Mark the app as ready to exit */\n exit: () => void;\n\n // ========================================================================\n // Agent-related actions\n // ========================================================================\n\n /**\n * Show tool approval prompt (replaces persistent-input, restores after)\n * Used by canUseTool handler for tools that need user approval\n */\n toolApproval: (props: ToolApprovalProps) => Promise<ToolApprovalResult>;\n\n /**\n * Show clarifying questions prompt (replaces persistent-input, restores after)\n * Used by canUseTool handler for AskUserQuestion tool\n */\n clarifyingQuestions: (\n props: ClarifyingQuestionsProps,\n ) => Promise<ClarifyingQuestionsResult>;\n\n /**\n * Show plan approval prompt (replaces persistent-input, restores after)\n * Used by canUseTool handler for ExitPlanMode tool\n */\n planApproval: (props: PlanApprovalProps) => Promise<PlanApprovalResult>;\n\n /**\n * Show feedback select prompt (select with inline text input option)\n * Used for \"yes/no with feedback\" patterns\n */\n feedbackSelect: <T>(\n options: FeedbackSelectOptions<T>,\n ) => Promise<FeedbackSelectResult<T>>;\n\n /**\n * Start persistent input mode during agent execution\n * Sets pendingItem to persistent-input type\n */\n startPersistentInput: (config: {\n onSubmit: (message: string) => void;\n onInterrupt: () => void;\n onCtrlC?: () => void;\n message?: string;\n placeholder?: string;\n }) => void;\n\n /**\n * Stop persistent input mode\n * Clears pendingItem if it's persistent-input type\n */\n stopPersistentInput: () => void;\n\n /**\n * Update persistent input value\n * Allows PersistentTextInput to preserve its state across unmount/remount\n */\n updatePersistentInputValue: (value: string) => void;\n\n /**\n * Update agent state\n */\n setAgentState: (state: Partial<AgentState>) => void;\n}\n\n/**\n * Combined context type\n */\nexport interface WizardContextType {\n state: WizardState;\n actions: WizardActions;\n}\n\n// Create the context with a null default (must be used within provider)\nconst WizardContext = createContext<WizardContextType | null>(null);\n\n/**\n * Hook to access wizard state and actions\n */\nexport function useWizard(): WizardContextType {\n const context = useContext(WizardContext);\n if (!context) {\n throw new Error('useWizard must be used within a WizardProvider');\n }\n return context;\n}\n\n/**\n * Hook to access just the wizard state\n */\nexport function useWizardState(): WizardState {\n return useWizard().state;\n}\n\n/**\n * Hook to access just the wizard actions\n */\nexport function useWizardActions(): WizardActions {\n return useWizard().actions;\n}\n\n/**\n * Props for the WizardProvider\n */\ninterface WizardProviderProps {\n children: ReactNode;\n onExit?: () => void;\n}\n\n/**\n * Provider component that manages all wizard state\n */\nexport function WizardProvider({\n children,\n onExit,\n}: WizardProviderProps): React.ReactElement {\n const { stdout } = useStdout();\n\n // State\n const [history, setHistory] = useState<HistoryItem[]>([]);\n // Queue of pending items - processes one at a time, FIFO order\n // This allows multiple tool approvals to be queued without losing earlier ones\n // Note: persistent-input is NOT stored in queue, it's a fallback shown when queue is empty\n const [pendingQueue, setPendingQueue] = useState<PendingItem[]>([]);\n const [agentState, setAgentStateInternal] = useState<AgentState>({});\n // Spinner state - separate from pendingItem so both can be visible\n const [activeSpinner, setActiveSpinner] = useState<string | null>(null);\n // Terminal size state for responsive rendering\n const [terminalSize, setTerminalSize] = useState({\n width: Math.max(1, stdout?.columns || 80),\n height: Math.max(1, stdout?.rows || 24),\n });\n\n // Persistent input config - stored separately, shown as fallback when queue is empty\n const [persistentInputConfig, setPersistentInputConfig] = useState<{\n onSubmit: (message: string) => void;\n onInterrupt: () => void;\n onCtrlC?: () => void;\n message?: string;\n placeholder?: string;\n } | null>(null);\n\n // Ref to store persistent input pending item - reuse same object to prevent re-renders\n const persistentInputItemRef = useRef<PendingItem | null>(null);\n // Ref to preserve in-progress persistent input text without triggering re-renders\n const persistentInputValueRef = useRef('');\n\n // Ref to store the last valid pending item to prevent flickering\n const lastValidPendingItemRef = useRef<PendingItem | null>(null);\n\n // Listen for terminal resize events\n useEffect(() => {\n const handleResize = () => {\n const nextWidth = Math.max(1, stdout?.columns || 80);\n const nextHeight = Math.max(1, stdout?.rows || 24);\n\n setTerminalSize((current) => {\n if (current.width === nextWidth && current.height === nextHeight) {\n return current;\n }\n\n return {\n width: nextWidth,\n height: nextHeight,\n };\n });\n };\n\n // Update terminal size on mount and when stdout changes\n handleResize();\n\n // Listen for resize events\n if (stdout) {\n stdout.on('resize', handleResize);\n return () => {\n stdout.off('resize', handleResize);\n };\n }\n }, [stdout]);\n\n // Derive current pending item:\n // 1. If queue has items → show first item in queue\n // 2. If queue is empty AND persistent input is active → show persistent input\n // 3. Otherwise → keep showing the last valid item to prevent flickering\n const pendingItem: PendingItem | null = useMemo(() => {\n let newPendingItem: PendingItem | null = null;\n\n // Priority 1: Items in queue\n if (pendingQueue.length > 0) {\n newPendingItem = pendingQueue[0];\n }\n // Priority 2: Persistent input (fallback when queue is empty)\n else if (persistentInputConfig) {\n // Reuse the same pending item object if the config hasn't changed\n // This prevents unnecessary re-renders when switching back to persistent input\n const currentRef = persistentInputItemRef.current;\n const propsMatch =\n currentRef &&\n (currentRef.props as PersistentInputProps).onSubmit ===\n persistentInputConfig.onSubmit &&\n (currentRef.props as PersistentInputProps).onInterrupt ===\n persistentInputConfig.onInterrupt &&\n (currentRef.props as PersistentInputProps).onCtrlC ===\n persistentInputConfig.onCtrlC &&\n (currentRef.props as PersistentInputProps).message ===\n persistentInputConfig.message &&\n (currentRef.props as PersistentInputProps).placeholder ===\n (persistentInputConfig.placeholder ??\n 'Type a message or press Esc to interrupt...');\n\n if (!propsMatch) {\n // Config changed, create new pending item\n persistentInputItemRef.current = {\n type: 'persistent-input',\n props: {\n onSubmit: persistentInputConfig.onSubmit,\n onInterrupt: persistentInputConfig.onInterrupt,\n onCtrlC: persistentInputConfig.onCtrlC,\n placeholder:\n persistentInputConfig.placeholder ??\n 'Type a message or press Esc to interrupt...',\n message: persistentInputConfig.message,\n defaultValue: persistentInputValueRef.current,\n } as PersistentInputProps,\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n resolve: () => {},\n };\n }\n newPendingItem = persistentInputItemRef.current;\n }\n\n // If we have a valid new pending item, update the ref and return it\n if (newPendingItem) {\n lastValidPendingItemRef.current = newPendingItem;\n return newPendingItem;\n }\n\n // If no new pending item but we have a last valid one, keep showing it to prevent flickering\n // This handles intermediate render states where pendingQueue might be temporarily empty\n if (lastValidPendingItemRef.current) {\n return lastValidPendingItemRef.current;\n }\n\n // No pending items at all\n persistentInputItemRef.current = null;\n lastValidPendingItemRef.current = null;\n return null;\n }, [pendingQueue, persistentInputConfig]);\n\n // Counter for unique IDs\n const idCounter = useRef(0);\n\n // Get next unique ID\n const getNextId = useCallback(() => {\n return ++idCounter.current;\n }, []);\n\n // Add item to history (direct, like gemini-cli). Returns the assigned ID.\n const addItem = useCallback(\n (item: HistoryItemInput): number => {\n const id = getNextId();\n setHistory((prev) => [...prev, { ...item, id }]);\n return id;\n },\n [getNextId],\n );\n\n // Update an existing history item by ID\n const updateItem = useCallback(\n (id: number, updates: Partial<HistoryItemInput>) => {\n setHistory((prev) =>\n prev.map((item) => (item.id === id ? { ...item, ...updates } : item)),\n );\n },\n [],\n );\n\n // Deactivate all write-key items in history\n const deactivateWriteKeys = useCallback(() => {\n setHistory((prev) =>\n prev.map((item) =>\n item.type === 'write-key' && item.isActive\n ? { ...item, isActive: false }\n : item,\n ),\n );\n }, []);\n\n // Resolve current pending item and advance the queue\n const resolvePending = useCallback((value: unknown) => {\n // Clear the last valid pending item ref to prevent flickering/repeating the old question\n lastValidPendingItemRef.current = null;\n\n setPendingQueue((queue) => {\n if (queue.length > 0) {\n // Resolve the first item in the queue\n queue[0].resolve(value);\n // Return the queue without the first item (shift)\n return queue.slice(1);\n }\n return queue;\n });\n }, []);\n\n // Show select prompt - adds to queue\n const select = useCallback(\n <T,>(options: SelectOptions<T>): Promise<T | symbol> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'select',\n props: options as SelectOptions<unknown>,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [],\n );\n\n // Show text prompt - adds to queue\n const text = useCallback((options: TextOptions): Promise<string | symbol> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'text',\n props: options,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n }, []);\n\n // Show continue button prompt - adds to queue\n const continuePrompt = useCallback(\n (options: ContinuePromptOptions): Promise<boolean | symbol> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'continue',\n props: options,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [],\n );\n\n // Show spinner - uses separate activeSpinner state so it can be visible alongside pendingItem\n const spinner = useCallback((): SpinnerInstance => {\n return {\n start: (msg = '') => {\n setActiveSpinner(msg || SPINNER_MESSAGE);\n },\n stop: (msg = '') => {\n if (msg) {\n addItem({ type: 'spinner-result', text: msg });\n }\n setActiveSpinner(null);\n },\n message: (msg: string) => {\n setActiveSpinner((prev) => (prev !== null ? msg : null));\n },\n };\n }, [addItem]);\n\n // Exit the app\n const exit = useCallback(() => {\n onExit?.();\n }, [onExit]);\n\n // ========================================================================\n // Agent-related actions\n // ========================================================================\n\n // Show tool approval prompt - adds to queue\n // Persistent input automatically shows when queue becomes empty (it's a fallback, not in queue)\n const toolApproval = useCallback(\n (props: ToolApprovalProps): Promise<ToolApprovalResult> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'tool-approval',\n props,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [],\n );\n\n // Show clarifying questions prompt - adds to queue\n // Persistent input automatically shows when queue becomes empty\n const clarifyingQuestions = useCallback(\n (props: ClarifyingQuestionsProps): Promise<ClarifyingQuestionsResult> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'clarifying-questions',\n props,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [],\n );\n\n // Show plan approval prompt - adds plan to history first (static), then adds selection to queue\n // Persistent input automatically shows when queue becomes empty\n const planApproval = useCallback(\n (props: PlanApprovalProps): Promise<PlanApprovalResult> => {\n // First, add the plan content to history so it's static and doesn't re-render\n addItem({\n type: 'plan-review',\n text: 'Ready to execute the plan?',\n planContent: props.planContent,\n });\n\n // Then show just the selection prompt as pending item\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'plan-approval',\n props,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [addItem],\n );\n\n // Show feedback select prompt - adds to queue\n const feedbackSelect = useCallback(\n <T,>(\n options: FeedbackSelectOptions<T>,\n ): Promise<FeedbackSelectResult<T>> => {\n return new Promise((resolve) => {\n setPendingQueue((queue) => [\n ...queue,\n {\n type: 'feedback-select',\n props: options as FeedbackSelectOptions<unknown>,\n resolve: resolve as (value: unknown) => void,\n },\n ]);\n });\n },\n [],\n );\n\n // Start persistent input mode - sets config so it shows as fallback when queue is empty\n const startPersistentInput = useCallback(\n (config: {\n onSubmit: (message: string) => void;\n onInterrupt: () => void;\n onCtrlC?: () => void;\n message?: string;\n placeholder?: string;\n }) => {\n // Store config - persistent input will automatically show when queue is empty.\n // The live input text is preserved separately in persistentInputValueRef.\n setPersistentInputConfig(config);\n },\n [],\n );\n\n // Stop persistent input mode - clears config so it no longer shows\n const stopPersistentInput = useCallback(() => {\n setPersistentInputConfig(null);\n persistentInputValueRef.current = '';\n // Also clear the refs to prevent the input from lingering\n persistentInputItemRef.current = null;\n lastValidPendingItemRef.current = null;\n }, []);\n\n // Update persistent input value - allows PersistentTextInput to save its state\n const updatePersistentInputValue = useCallback((value: string) => {\n persistentInputValueRef.current = value;\n\n const currentPersistentItem = persistentInputItemRef.current;\n if (currentPersistentItem?.type === 'persistent-input') {\n // Keep the ref-backed pending item up to date for future remounts.\n (currentPersistentItem.props as PersistentInputProps).defaultValue = value;\n }\n }, []);\n\n // Update agent state\n const setAgentState = useCallback((state: Partial<AgentState>) => {\n setAgentStateInternal((current) => ({ ...current, ...state }));\n }, []);\n\n // Combine actions\n const actions = useMemo<WizardActions>(\n () => ({\n addItem,\n updateItem,\n deactivateWriteKeys,\n select,\n text,\n continue: continuePrompt,\n spinner,\n resolvePending,\n exit,\n toolApproval,\n clarifyingQuestions,\n planApproval,\n feedbackSelect,\n startPersistentInput,\n stopPersistentInput,\n updatePersistentInputValue,\n setAgentState,\n }),\n [\n addItem,\n updateItem,\n deactivateWriteKeys,\n select,\n text,\n continuePrompt,\n spinner,\n resolvePending,\n exit,\n toolApproval,\n clarifyingQuestions,\n planApproval,\n feedbackSelect,\n startPersistentInput,\n stopPersistentInput,\n updatePersistentInputValue,\n setAgentState,\n ],\n );\n\n // Combine state\n const state = useMemo<WizardState>(\n () => ({\n history,\n pendingItem,\n agentState,\n activeSpinner,\n terminalSize,\n }),\n [history, pendingItem, agentState, activeSpinner, terminalSize],\n );\n\n // Context value\n const contextValue = useMemo<WizardContextType>(\n () => ({ state, actions }),\n [state, actions],\n );\n\n return (\n <WizardContext.Provider value={contextValue}>\n {children}\n </WizardContext.Provider>\n );\n}\n\nexport { WizardContext };\n"]}
@@ -0,0 +1,10 @@
1
+ /// <reference types="jest" />
2
+ /**
3
+ * Manual mock for ui used in sdk-messages tests.
4
+ * Export addItemMock so tests can assert on calls.
5
+ */
6
+ export declare const addItemMock: jest.Mock<any, any, any>;
7
+ declare const _default: {
8
+ addItem: jest.Mock<any, any, any>;
9
+ };
10
+ export default _default;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Manual mock for ui used in sdk-messages tests.
3
+ * Export addItemMock so tests can assert on calls.
4
+ */
5
+ export const addItemMock = jest.fn();
6
+ export default { addItem: addItemMock };
7
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../../src/utils/__mocks__/ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AACrC,eAAe,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC","sourcesContent":["/**\n * Manual mock for ui used in sdk-messages tests.\n * Export addItemMock so tests can assert on calls.\n */\nexport const addItemMock = jest.fn();\nexport default { addItem: addItemMock };\n"]}
@@ -1,3 +1,25 @@
1
+ /** Context required to report an agent error (wizard session + project path for log lookup). */
2
+ export interface SessionErrorContext {
3
+ wizardSessionId: string;
4
+ accessToken: string;
5
+ orgId: string;
6
+ /** Resolved absolute project path (e.g. /Users/.../project). */
7
+ workingDirectory: string;
8
+ }
9
+ /**
10
+ * Report an agent error to the session error endpoint (Slack) with agent log path and content.
11
+ * Uses workingDirectory and agentConvoId to locate the agent log file under ~/.claude/projects/.
12
+ */
13
+ export declare function reportSessionError(errorMessage: string, agentConvoId: string, onError: SessionErrorContext): void;
1
14
  export declare function sendSessionInit(sessionId: string, setupDetails: string, accessToken: string, orgId: string): void;
2
15
  export declare function sendSessionUpdate(sessionId: string, plan: string, accessToken: string, orgId: string): void;
16
+ export interface SendSessionErrorOptions {
17
+ /** Original error message (e.g. API response body) to append to the thread. */
18
+ errorMessage?: string;
19
+ /** Claude Agent SDK convo/session id (used in log path and for Slack). */
20
+ agentConvoId?: string;
21
+ /** Contents of the agent .jsonl log file (attached to Slack like setup.txt / plan.txt). */
22
+ agentLogContent?: string;
23
+ }
24
+ export declare function sendSessionError(wizardSessionId: string, agentLogPath: string, accessToken: string, orgId: string, options?: SendSessionErrorOptions): void;
3
25
  export declare function sendSessionComplete(sessionId: string, status: 'success' | 'failure' | 'support', accessToken: string, orgId: string, feedback?: string): Promise<void>;
@@ -1,5 +1,25 @@
1
- import { SESSION_START_ENDPOINT, SESSION_UPDATE_ENDPOINT, SESSION_COMPLETE_ENDPOINT, } from '../lib/constants.js';
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { SESSION_START_ENDPOINT, SESSION_UPDATE_ENDPOINT, SESSION_COMPLETE_ENDPOINT, SESSION_ERROR_ENDPOINT, } from '../lib/constants.js';
2
5
  import { logToFile, debug } from './debug.js';
6
+ /**
7
+ * Report an agent error to the session error endpoint (Slack) with agent log path and content.
8
+ * Uses workingDirectory and agentConvoId to locate the agent log file under ~/.claude/projects/.
9
+ */
10
+ export function reportSessionError(errorMessage, agentConvoId, onError) {
11
+ const segment = '-' +
12
+ onError.workingDirectory.replace(/^\//, '').replace(/\//g, '-');
13
+ const agentLogPath = path.join(os.homedir(), '.claude', 'projects', segment, `${agentConvoId}.jsonl`);
14
+ let agentLogContent;
15
+ try {
16
+ agentLogContent = fs.readFileSync(agentLogPath, 'utf-8');
17
+ }
18
+ catch {
19
+ agentLogContent = undefined;
20
+ }
21
+ sendSessionError(onError.wizardSessionId, agentLogPath, onError.accessToken, onError.orgId, { errorMessage, agentConvoId, agentLogContent });
22
+ }
3
23
  export function sendSessionInit(sessionId, setupDetails, accessToken, orgId) {
4
24
  debug('→ Sending session init notification');
5
25
  const makeRequest = async () => {
@@ -84,6 +104,52 @@ export function sendSessionUpdate(sessionId, plan, accessToken, orgId) {
84
104
  // Silently fail - this is a non-critical update
85
105
  });
86
106
  }
107
+ export function sendSessionError(wizardSessionId, agentLogPath, accessToken, orgId, options) {
108
+ const { errorMessage, agentConvoId, agentLogContent } = options ?? {};
109
+ debug('→ Sending session error notification');
110
+ const makeRequest = async () => {
111
+ logToFile('Sending session error:', {
112
+ endpoint: SESSION_ERROR_ENDPOINT,
113
+ wizardSessionId,
114
+ orgId,
115
+ agentLogPath,
116
+ agentConvoId,
117
+ hasErrorMessage: !!errorMessage,
118
+ hasAgentLogContent: !!agentLogContent,
119
+ hasAccessToken: !!accessToken,
120
+ });
121
+ const response = await fetch(SESSION_ERROR_ENDPOINT, {
122
+ method: 'POST',
123
+ headers: {
124
+ Authorization: `Bearer ${accessToken}`,
125
+ 'Content-Type': 'application/json',
126
+ 'x-wizard-session': wizardSessionId,
127
+ 'x-org-id': orgId,
128
+ },
129
+ body: JSON.stringify({
130
+ errorMessage,
131
+ agentConvoId,
132
+ agentLogContent,
133
+ }),
134
+ });
135
+ logToFile('Session error response:', {
136
+ status: response.status,
137
+ statusText: response.statusText,
138
+ });
139
+ if (!response.ok) {
140
+ const errorText = await response.text().catch(() => 'Unable to read error');
141
+ logToFile('Session error failed:', errorText);
142
+ debug(`✗ Session error failed: ${response.status}`);
143
+ }
144
+ else {
145
+ debug('✓ Session error notification sent');
146
+ }
147
+ return response;
148
+ };
149
+ void makeRequest().catch((error) => {
150
+ logToFile('Session error request error:', error);
151
+ });
152
+ }
87
153
  export async function sendSessionComplete(sessionId, status, accessToken, orgId, feedback) {
88
154
  debug('→ Sending session complete notification');
89
155
  const makeRequest = async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/utils/session.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SESSION_START_ENDPOINT,\n SESSION_UPDATE_ENDPOINT,\n SESSION_COMPLETE_ENDPOINT,\n} from '../lib/constants.js';\nimport { logToFile, debug } from './debug.js';\n\nexport function sendSessionInit(\n sessionId: string,\n setupDetails: string,\n accessToken: string,\n orgId: string,\n): void {\n debug('→ Sending session init notification');\n\n const makeRequest = async () => {\n logToFile('Sending session init:', {\n endpoint: SESSION_START_ENDPOINT,\n sessionId,\n orgId,\n setupDetailsLength: setupDetails?.length || 0,\n hasAccessToken: !!accessToken,\n });\n\n const response = await fetch(SESSION_START_ENDPOINT, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'x-wizard-session': sessionId,\n 'x-org-id': orgId,\n },\n body: JSON.stringify({\n setupDetails,\n }),\n });\n\n logToFile('Session init response:', {\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unable to read error');\n logToFile('Session init failed:', errorText);\n debug(`✗ Session init failed: ${response.status}`);\n } else {\n debug('✓ Session init notification sent');\n }\n\n return response;\n };\n\n // Fire and forget - don't await\n void makeRequest().catch((error) => {\n logToFile('Session init error:', error);\n // Silently fail - this is a non-critical notification\n });\n}\n\nexport function sendSessionUpdate(\n sessionId: string,\n plan: string,\n accessToken: string,\n orgId: string,\n): void {\n debug('→ Sending session update notification');\n\n const makeRequest = async () => {\n logToFile('Sending session update:', {\n endpoint: SESSION_UPDATE_ENDPOINT,\n sessionId,\n orgId,\n planLength: plan?.length || 0,\n hasAccessToken: !!accessToken,\n });\n\n const response = await fetch(SESSION_UPDATE_ENDPOINT, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'x-wizard-session': sessionId,\n 'x-org-id': orgId,\n },\n body: JSON.stringify({\n plan,\n }),\n });\n\n logToFile('Session update response:', {\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unable to read error');\n logToFile('Session update failed:', errorText);\n debug(`✗ Session update failed: ${response.status}`);\n } else {\n debug('✓ Session update notification sent');\n }\n\n return response;\n };\n\n // Fire and forget - don't await\n void makeRequest().catch((error) => {\n logToFile('Session update error:', error);\n // Silently fail - this is a non-critical update\n });\n}\n\nexport async function sendSessionComplete(\n sessionId: string,\n status: 'success' | 'failure' | 'support',\n accessToken: string,\n orgId: string,\n feedback?: string,\n): Promise<void> {\n debug('→ Sending session complete notification');\n\n const makeRequest = async () => {\n logToFile('Sending session complete:', {\n endpoint: SESSION_COMPLETE_ENDPOINT,\n sessionId,\n orgId,\n status,\n hasFeedback: !!feedback,\n });\n\n const response = await fetch(SESSION_COMPLETE_ENDPOINT, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'x-wizard-session': sessionId,\n 'x-org-id': orgId,\n },\n body: JSON.stringify({ status, feedback }),\n });\n\n logToFile('Session complete response:', {\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unable to read error');\n logToFile('Session complete failed:', errorText);\n debug(`✗ Session complete failed: ${response.status}`);\n } else {\n debug('✓ Session complete notification sent');\n }\n\n return response;\n };\n\n await makeRequest().catch((error) => {\n logToFile('Session complete error:', error);\n // Silently fail - this is a non-critical notification\n });\n}\n"]}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/utils/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAW9C;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAAoB,EACpB,YAAoB,EACpB,OAA4B;IAE5B,MAAM,OAAO,GACX,GAAG;QACH,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAClE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAC5B,EAAE,CAAC,OAAO,EAAE,EACZ,SAAS,EACT,UAAU,EACV,OAAO,EACP,GAAG,YAAY,QAAQ,CACxB,CAAC;IACF,IAAI,eAAmC,CAAC;IACxC,IAAI,CAAC;QACH,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,eAAe,GAAG,SAAS,CAAC;IAC9B,CAAC;IACD,gBAAgB,CACd,OAAO,CAAC,eAAe,EACvB,YAAY,EACZ,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,KAAK,EACb,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,CAChD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,SAAiB,EACjB,YAAoB,EACpB,WAAmB,EACnB,KAAa;IAEb,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAE7C,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;QAC7B,SAAS,CAAC,uBAAuB,EAAE;YACjC,QAAQ,EAAE,sBAAsB;YAChC,SAAS;YACT,KAAK;YACL,kBAAkB,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;YAC7C,cAAc,EAAE,CAAC,CAAC,WAAW;SAC9B,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,sBAAsB,EAAE;YACnD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,WAAW,EAAE;gBACtC,cAAc,EAAE,kBAAkB;gBAClC,kBAAkB,EAAE,SAAS;gBAC7B,UAAU,EAAE,KAAK;aAClB;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,YAAY;aACb,CAAC;SACH,CAAC,CAAC;QAEH,SAAS,CAAC,wBAAwB,EAAE;YAClC,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,CAAC;YAC5E,SAAS,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC;YAC7C,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEF,gCAAgC;IAChC,KAAK,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACjC,SAAS,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;QACxC,sDAAsD;IACxD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,SAAiB,EACjB,IAAY,EACZ,WAAmB,EACnB,KAAa;IAEb,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAE/C,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;QAC7B,SAAS,CAAC,yBAAyB,EAAE;YACnC,QAAQ,EAAE,uBAAuB;YACjC,SAAS;YACT,KAAK;YACL,UAAU,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;YAC7B,cAAc,EAAE,CAAC,CAAC,WAAW;SAC9B,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,uBAAuB,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,WAAW,EAAE;gBACtC,cAAc,EAAE,kBAAkB;gBAClC,kBAAkB,EAAE,SAAS;gBAC7B,UAAU,EAAE,KAAK;aAClB;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,IAAI;aACL,CAAC;SACH,CAAC,CAAC;QAEH,SAAS,CAAC,0BAA0B,EAAE;YACpC,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,CAAC;YAC5E,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;YAC/C,KAAK,CAAC,4BAA4B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEF,gCAAgC;IAChC,KAAK,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACjC,SAAS,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QAC1C,gDAAgD;IAClD,CAAC,CAAC,CAAC;AACL,CAAC;AAWD,MAAM,UAAU,gBAAgB,CAC9B,eAAuB,EACvB,YAAoB,EACpB,WAAmB,EACnB,KAAa,EACb,OAAiC;IAEjC,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IACtE,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAE9C,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;QAC7B,SAAS,CAAC,wBAAwB,EAAE;YAClC,QAAQ,EAAE,sBAAsB;YAChC,eAAe;YACf,KAAK;YACL,YAAY;YACZ,YAAY;YACZ,eAAe,EAAE,CAAC,CAAC,YAAY;YAC/B,kBAAkB,EAAE,CAAC,CAAC,eAAe;YACrC,cAAc,EAAE,CAAC,CAAC,WAAW;SAC9B,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,sBAAsB,EAAE;YACnD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,WAAW,EAAE;gBACtC,cAAc,EAAE,kBAAkB;gBAClC,kBAAkB,EAAE,eAAe;gBACnC,UAAU,EAAE,KAAK;aAClB;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,YAAY;gBACZ,YAAY;gBACZ,eAAe;aAChB,CAAC;SACH,CAAC,CAAC;QAEH,SAAS,CAAC,yBAAyB,EAAE;YACnC,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,CAAC;YAC5E,SAAS,CAAC,uBAAuB,EAAE,SAAS,CAAC,CAAC;YAC9C,KAAK,CAAC,2BAA2B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEF,KAAK,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACjC,SAAS,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAiB,EACjB,MAAyC,EACzC,WAAmB,EACnB,KAAa,EACb,QAAiB;IAEjB,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAEjD,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;QAC7B,SAAS,CAAC,2BAA2B,EAAE;YACrC,QAAQ,EAAE,yBAAyB;YACnC,SAAS;YACT,KAAK;YACL,MAAM;YACN,WAAW,EAAE,CAAC,CAAC,QAAQ;SACxB,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,yBAAyB,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,WAAW,EAAE;gBACtC,cAAc,EAAE,kBAAkB;gBAClC,kBAAkB,EAAE,SAAS;gBAC7B,UAAU,EAAE,KAAK;aAClB;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;SAC3C,CAAC,CAAC;QAEH,SAAS,CAAC,4BAA4B,EAAE;YACtC,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,CAAC;YAC5E,SAAS,CAAC,0BAA0B,EAAE,SAAS,CAAC,CAAC;YACjD,KAAK,CAAC,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAChD,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEF,MAAM,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QAClC,SAAS,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;QAC5C,sDAAsD;IACxD,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport {\n SESSION_START_ENDPOINT,\n SESSION_UPDATE_ENDPOINT,\n SESSION_COMPLETE_ENDPOINT,\n SESSION_ERROR_ENDPOINT,\n} from '../lib/constants.js';\nimport { logToFile, debug } from './debug.js';\n\n/** Context required to report an agent error (wizard session + project path for log lookup). */\nexport interface SessionErrorContext {\n wizardSessionId: string;\n accessToken: string;\n orgId: string;\n /** Resolved absolute project path (e.g. /Users/.../project). */\n workingDirectory: string;\n}\n\n/**\n * Report an agent error to the session error endpoint (Slack) with agent log path and content.\n * Uses workingDirectory and agentConvoId to locate the agent log file under ~/.claude/projects/.\n */\nexport function reportSessionError(\n errorMessage: string,\n agentConvoId: string,\n onError: SessionErrorContext,\n): void {\n const segment =\n '-' +\n onError.workingDirectory.replace(/^\\//, '').replace(/\\//g, '-');\n const agentLogPath = path.join(\n os.homedir(),\n '.claude',\n 'projects',\n segment,\n `${agentConvoId}.jsonl`,\n );\n let agentLogContent: string | undefined;\n try {\n agentLogContent = fs.readFileSync(agentLogPath, 'utf-8');\n } catch {\n agentLogContent = undefined;\n }\n sendSessionError(\n onError.wizardSessionId,\n agentLogPath,\n onError.accessToken,\n onError.orgId,\n { errorMessage, agentConvoId, agentLogContent },\n );\n}\n\nexport function sendSessionInit(\n sessionId: string,\n setupDetails: string,\n accessToken: string,\n orgId: string,\n): void {\n debug('→ Sending session init notification');\n\n const makeRequest = async () => {\n logToFile('Sending session init:', {\n endpoint: SESSION_START_ENDPOINT,\n sessionId,\n orgId,\n setupDetailsLength: setupDetails?.length || 0,\n hasAccessToken: !!accessToken,\n });\n\n const response = await fetch(SESSION_START_ENDPOINT, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'x-wizard-session': sessionId,\n 'x-org-id': orgId,\n },\n body: JSON.stringify({\n setupDetails,\n }),\n });\n\n logToFile('Session init response:', {\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unable to read error');\n logToFile('Session init failed:', errorText);\n debug(`✗ Session init failed: ${response.status}`);\n } else {\n debug('✓ Session init notification sent');\n }\n\n return response;\n };\n\n // Fire and forget - don't await\n void makeRequest().catch((error) => {\n logToFile('Session init error:', error);\n // Silently fail - this is a non-critical notification\n });\n}\n\nexport function sendSessionUpdate(\n sessionId: string,\n plan: string,\n accessToken: string,\n orgId: string,\n): void {\n debug('→ Sending session update notification');\n\n const makeRequest = async () => {\n logToFile('Sending session update:', {\n endpoint: SESSION_UPDATE_ENDPOINT,\n sessionId,\n orgId,\n planLength: plan?.length || 0,\n hasAccessToken: !!accessToken,\n });\n\n const response = await fetch(SESSION_UPDATE_ENDPOINT, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'x-wizard-session': sessionId,\n 'x-org-id': orgId,\n },\n body: JSON.stringify({\n plan,\n }),\n });\n\n logToFile('Session update response:', {\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unable to read error');\n logToFile('Session update failed:', errorText);\n debug(`✗ Session update failed: ${response.status}`);\n } else {\n debug('✓ Session update notification sent');\n }\n\n return response;\n };\n\n // Fire and forget - don't await\n void makeRequest().catch((error) => {\n logToFile('Session update error:', error);\n // Silently fail - this is a non-critical update\n });\n}\n\nexport interface SendSessionErrorOptions {\n /** Original error message (e.g. API response body) to append to the thread. */\n errorMessage?: string;\n /** Claude Agent SDK convo/session id (used in log path and for Slack). */\n agentConvoId?: string;\n /** Contents of the agent .jsonl log file (attached to Slack like setup.txt / plan.txt). */\n agentLogContent?: string;\n}\n\nexport function sendSessionError(\n wizardSessionId: string,\n agentLogPath: string,\n accessToken: string,\n orgId: string,\n options?: SendSessionErrorOptions,\n): void {\n const { errorMessage, agentConvoId, agentLogContent } = options ?? {};\n debug('→ Sending session error notification');\n\n const makeRequest = async () => {\n logToFile('Sending session error:', {\n endpoint: SESSION_ERROR_ENDPOINT,\n wizardSessionId,\n orgId,\n agentLogPath,\n agentConvoId,\n hasErrorMessage: !!errorMessage,\n hasAgentLogContent: !!agentLogContent,\n hasAccessToken: !!accessToken,\n });\n\n const response = await fetch(SESSION_ERROR_ENDPOINT, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'x-wizard-session': wizardSessionId,\n 'x-org-id': orgId,\n },\n body: JSON.stringify({\n errorMessage,\n agentConvoId,\n agentLogContent,\n }),\n });\n\n logToFile('Session error response:', {\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unable to read error');\n logToFile('Session error failed:', errorText);\n debug(`✗ Session error failed: ${response.status}`);\n } else {\n debug('✓ Session error notification sent');\n }\n\n return response;\n };\n\n void makeRequest().catch((error) => {\n logToFile('Session error request error:', error);\n });\n}\n\nexport async function sendSessionComplete(\n sessionId: string,\n status: 'success' | 'failure' | 'support',\n accessToken: string,\n orgId: string,\n feedback?: string,\n): Promise<void> {\n debug('→ Sending session complete notification');\n\n const makeRequest = async () => {\n logToFile('Sending session complete:', {\n endpoint: SESSION_COMPLETE_ENDPOINT,\n sessionId,\n orgId,\n status,\n hasFeedback: !!feedback,\n });\n\n const response = await fetch(SESSION_COMPLETE_ENDPOINT, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'x-wizard-session': sessionId,\n 'x-org-id': orgId,\n },\n body: JSON.stringify({ status, feedback }),\n });\n\n logToFile('Session complete response:', {\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unable to read error');\n logToFile('Session complete failed:', errorText);\n debug(`✗ Session complete failed: ${response.status}`);\n } else {\n debug('✓ Session complete notification sent');\n }\n\n return response;\n };\n\n await makeRequest().catch((error) => {\n logToFile('Session complete error:', error);\n // Silently fail - this is a non-critical notification\n });\n}\n"]}