@raindrop-ai/wizard 0.0.11 → 0.0.13

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 (34) hide show
  1. package/dist/src/docs/opencode.mdx +75 -0
  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/mcp.js +13 -11
  17. package/dist/src/lib/mcp.js.map +1 -1
  18. package/dist/src/lib/sdk-messages.d.ts +41 -2
  19. package/dist/src/lib/sdk-messages.js +89 -41
  20. package/dist/src/lib/sdk-messages.js.map +1 -1
  21. package/dist/src/lib/wizard.js +1 -1
  22. package/dist/src/lib/wizard.js.map +1 -1
  23. package/dist/src/ui/components/ToolCallDisplay.js +30 -0
  24. package/dist/src/ui/components/ToolCallDisplay.js.map +1 -1
  25. package/dist/src/ui/contexts/WizardContext.d.ts +0 -11
  26. package/dist/src/ui/contexts/WizardContext.js +2 -19
  27. package/dist/src/ui/contexts/WizardContext.js.map +1 -1
  28. package/dist/src/utils/__mocks__/ui.d.ts +10 -0
  29. package/dist/src/utils/__mocks__/ui.js +7 -0
  30. package/dist/src/utils/__mocks__/ui.js.map +1 -0
  31. package/dist/src/utils/session.d.ts +22 -0
  32. package/dist/src/utils/session.js +67 -1
  33. package/dist/src/utils/session.js.map +1 -1
  34. package/package.json +16 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-messages.test.js","sourceRoot":"","sources":["../../../../src/lib/__tests__/sdk-messages.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,sBAAsB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAEzC,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC;IACvC,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,SAAS,EAAE,GAAG,EAAE,GAAE,CAAC;CACpB,CAAC,CAAC,CAAC;AACJ,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE,CAAC,CAAC;IACzC,kBAAkB,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,sBAAsB,CAAC,GAAG,IAAI,CAAC;CAC5E,CAAC,CAAC,CAAC;AACJ,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC;IAClC,qBAAqB,EAAE,CAAC,IAAa,EAAE,EAAE,CACvC,IAAI;QACF,CAAC,CAAC,0BAA0B,IAAI,qGAAqG;QACrI,CAAC,CAAC,4HAA4H;IAClI,mBAAmB,EAAE,IAAI,GAAG,EAAU;IACtC,eAAe,EAAE,OAAO;CACzB,CAAC,CAAC,CAAC;AACJ,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAGxC,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACnC,MAAM,WAAW,GAAG,EAAE,CAAC,OAAoB,CAAC;AAE5C,MAAM,mBAAmB,GAAG;IAC1B,eAAe,EAAE,UAAU;IAC3B,WAAW,EAAE,OAAO;IACpB,KAAK,EAAE,OAAO;IACd,gBAAgB,EAAE,cAAc;CACjC,CAAC;AACF,MAAM,WAAW,GAAG;IAClB,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE;IACxB,kBAAkB,EAAE,SAAS;IAC7B,OAAO,EAAE,mBAAmB;CAC7B,CAAC;AACF,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,KAAK;IACZ,YAAY,EAAE,KAAK;IACnB,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,cAAc;IACzB,aAAa,EAAE,EAAE;CAClB,CAAC;AACF,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA2B,CAAC;AAE5D,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,IAAI,GAAG,yBAAyB,CAAC,YAAY,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,IAAI,GAAG,yBAAyB,CAAC,gBAAgB,CAAC,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,IAAI,GAAG,yBAAyB,CAAC,sBAAsB,CAAC,CAAC;QAC/D,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,IAAI,GAAG,yBAAyB,CAAC,EAAE,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QACzD,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QACzD,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACzE,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC3E,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnE,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,CACzD,iBAAiB,CAClB,CAAC;QACF,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,CACJ,oBAAoB,CAClB,MAAM,EACN,IAAI,EACJ;YACE,UAAU,EAAE,MAAM;YAClB,UAAU,EAAE,SAAS;SACtB,CACF,CACF,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACvB,MAAM,CACJ,oBAAoB,CAClB,MAAM,EACN,IAAI,EACJ;YACE,UAAU,EAAE,GAAG;YACf,UAAU,EAAE,GAAG;SAChB,CACF,CACF,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CACJ,oBAAoB,CAClB,OAAO,EACP,IAAI,EACJ,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,qBAAqB,EAAE,CACxD,CACF,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAClC,MAAM,CACJ,oBAAoB,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CACnE,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,oBAAoB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CACJ,oBAAoB,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAC7D,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,UAAU,CAAC,GAAG,EAAE;QACd,sBAAsB,CAAC,SAAS,EAAE,CAAC;QACnC,WAAW,CAAC,SAAS,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uDAAuD,EAAE,GAAG,EAAE;QACrE,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;YACjF,MAAM,MAAM,GAAG,iBAAiB,CAC9B;gBACE,IAAI,EAAE,WAAW;gBACjB,UAAU,EAAE,QAAQ;gBACpB,OAAO,EAAE;oBACP,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;iBAC3C;aACF,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,WAAW,CACZ,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mFAAmF,EAAE,GAAG,EAAE;YAC3F,MAAM,MAAM,GAAG,iBAAiB,CAC9B;gBACE,IAAI,EAAE,WAAW;gBACjB,UAAU,EAAE,QAAQ;gBACpB,OAAO,EAAE;oBACP,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,UAAU;4BAChB,QAAQ,EAAE,0BAA0B;yBACrC;qBACF;iBACF;aACF,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,WAAW,CACZ,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,8BAA8B,EAAE,KAAK,EAAE,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mFAAmF,EAAE,GAAG,EAAE;YAC3F,MAAM,MAAM,GAAG,iBAAiB,CAC9B;gBACE,IAAI,EAAE,WAAW;gBACjB,UAAU,EAAE,QAAQ;gBACpB,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;aACzB,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,WAAW,CACZ,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,8BAA8B,EAAE,KAAK,EAAE,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,wGAAwG,EAAE,GAAG,EAAE;YAChH,iBAAiB,CACf;gBACE,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,SAAS;gBAChB,UAAU,EAAE,UAAU;gBACtB,OAAO,EAAE;oBACP,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;iBAChD;aACF,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,WAAW,CACZ,CAAC;YAEF,MAAM,CAAC,sBAAsB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACxD,MAAM,CAAC,sBAAsB,CAAC,CAAC,oBAAoB,CACjD,YAAY,EACZ,UAAU,EACV,mBAAmB,CACpB,CAAC;YACF,MAAM,CAAC,WAAW,CAAC,CAAC,oBAAoB,CAAC;gBACvC,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC;aACrC,CAAC,CAAC;YACH,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CACjD,kCAAkC,CACnC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;YACrF,iBAAiB,CACf;gBACE,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,EAAE;gBACT,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE;aAC7D,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,WAAW,CACZ,CAAC;YACF,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACtD,MAAM,CAAC,WAAW,CAAC,CAAC,oBAAoB,CAAC;gBACvC,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC;aACrC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,mHAAmH,EAAE,GAAG,EAAE;YAC3H,iBAAiB,CACf;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,OAAO;gBAChB,UAAU,EAAE,UAAU;gBACtB,MAAM,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;aACrC,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,WAAW,CACZ,CAAC;YAEF,MAAM,CAAC,sBAAsB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACxD,MAAM,CAAC,sBAAsB,CAAC,CAAC,oBAAoB,CACjD,0BAA0B,EAC1B,UAAU,EACV,mBAAmB,CACpB,CAAC;YACF,MAAM,CAAC,WAAW,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YAC7C,MAAM,CAAC,WAAW,CAAC,CAAC,oBAAoB,CAAC;gBACvC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC;aACrC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kFAAkF,EAAE,GAAG,EAAE;YAC1F,iBAAiB,CACf;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,OAAO;gBAChB,UAAU,EAAE,UAAU;gBACtB,MAAM,EAAE,CAAC,YAAY,CAAC;aACvB,EACD,WAAW,EACX,gBAAgB,EAChB,IAAI,EACJ,WAAW,CACZ,CAAC;YAEF,MAAM,CAAC,sBAAsB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACxD,MAAM,CAAC,sBAAsB,CAAC,CAAC,oBAAoB,CACjD,YAAY,EACZ,UAAU,EACV,mBAAmB,CACpB,CAAC;YACF,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAC9C,CAAC,CAAY,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC,CAAC,CAAsB,CAAC,IAAI,KAAK,OAAO,CACtE,CAAC;YACF,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2EAA2E,EAAE,GAAG,EAAE;YACnF,iBAAiB,CACf;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,OAAO;gBAChB,UAAU,EAAE,QAAQ;gBACpB,MAAM,EAAE,CAAC,iBAAiB,EAAE,qBAAqB,EAAE,YAAY,CAAC;aACjE,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,WAAW,CACZ,CAAC;YAEF,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACtD,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAC9C,CAAC,CAAY,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC,CAAC,CAAsB,CAAC,IAAI,KAAK,OAAO,CACtE,CAAC;YACF,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iEAAiE,EAAE,GAAG,EAAE;QAC/E,EAAE,CAAC,mGAAmG,EAAE,GAAG,EAAE;YAC3G,MAAM,uBAAuB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;YAC1C,iBAAiB,CACf;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,SAAS;gBAClB,UAAU,EAAE,cAAc;aAC3B,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL;gBACE,GAAG,WAAW;gBACd,8BAA8B,EAAE,KAAK;gBACrC,mBAAmB,EAAE,uBAAuB;aAC7C,CACF,CAAC;YAEF,MAAM,CAAC,sBAAsB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACxD,MAAM,CAAC,sBAAsB,CAAC,CAAC,oBAAoB,CACjD,sDAAsD,EACtD,cAAc,EACd,mBAAmB,CACpB,CAAC;YACF,MAAM,CAAC,uBAAuB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACzD,MAAM,CAAC,uBAAuB,CAAC,CAAC,oBAAoB,CAClD,oBAAoB,CACrB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;YAC9E,MAAM,uBAAuB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;YAC1C,iBAAiB,CACf;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,SAAS;gBAClB,UAAU,EAAE,SAAS;aACtB,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL;gBACE,GAAG,WAAW;gBACd,8BAA8B,EAAE,IAAI;gBACpC,mBAAmB,EAAE,uBAAuB;aAC7C,CACF,CAAC;YAEF,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACtD,MAAM,CAAC,uBAAuB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oGAAoG,EAAE,GAAG,EAAE;YAC5G,MAAM,uBAAuB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;YAC1C,iBAAiB,CACf;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,SAAS;gBAClB,UAAU,EAAE,SAAS;aACtB,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,EAAE,GAAG,WAAW,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,CACjE,CAAC;YAEF,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACtD,MAAM,CAAC,uBAAuB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC9D,MAAM,uBAAuB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;YAC1C,iBAAiB,CACf;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,SAAS;gBAClB,UAAU,EAAE,cAAc;aAC3B,EACD,WAAW,EACX,gBAAgB,EAChB,IAAI,EACJ;gBACE,GAAG,WAAW;gBACd,8BAA8B,EAAE,KAAK;gBACrC,mBAAmB,EAAE,uBAAuB;aAC7C,CACF,CAAC;YAEF,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACtD,MAAM,CAAC,uBAAuB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;YAChF,MAAM,uBAAuB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;YAC1C,iBAAiB,CACf;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,SAAS;gBAClB,UAAU,EAAE,SAAS;aACtB,EACD,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL;gBACE,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE;gBACxB,kBAAkB,EAAE,SAAS;gBAC7B,8BAA8B,EAAE,KAAK;gBACrC,mBAAmB,EAAE,uBAAuB;aAC7C,CACF,CAAC;YAEF,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACtD,MAAM,CAAC,uBAAuB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACzD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/**\n * Tests for SDK message processing utilities\n */\n\nconst reportSessionErrorMock = jest.fn();\n\njest.mock('../../utils/debug.js', () => ({\n debug: () => {},\n logToFile: () => {},\n}));\njest.mock('../../utils/session.js', () => ({\n reportSessionError: (...args: unknown[]) => reportSessionErrorMock(...args),\n}));\njest.mock('../constants.js', () => ({\n ERROR_DISPLAY_MESSAGE: (code?: string) =>\n code\n ? `Sorry, I encountered a ${code} error. Send another message to continue. If the issue persists, please contact support@raindrop.ai`\n : `Sorry, I encountered an error. Send another message to continue. If the issue persists, please contact support@raindrop.ai`,\n INTERNAL_TOOL_NAMES: new Set<string>(),\n MCP_TOOL_PREFIX: 'mcp__',\n}));\njest.mock('../handlers.js', () => ({}));\n\nimport type { PendingToolCall } from '../handlers.js';\nimport {\n extractResultSummary,\n getCannedErrorDisplayText,\n processSDKMessage,\n} from '../sdk-messages.js';\nimport ui from '../../utils/ui.js';\nconst addItemMock = ui.addItem as jest.Mock;\n\nconst sessionErrorContext = {\n wizardSessionId: 'wizard-1',\n accessToken: 'token',\n orgId: 'org-1',\n workingDirectory: '/tmp/project',\n};\nconst baseContext = {\n updateSpinner: jest.fn(),\n baseSpinnerMessage: 'Working',\n onError: sessionErrorContext,\n};\nconst baseOptions = {\n debug: false,\n forceInstall: false,\n installDir: '/tmp',\n default: false,\n sessionId: 'test-session',\n compiledSetup: '',\n};\nconst pendingToolCalls = new Map<string, PendingToolCall>();\n\ndescribe('getCannedErrorDisplayText', () => {\n it('extracts code from \"Error: 504\" and returns canned message with code', () => {\n const text = getCannedErrorDisplayText('Error: 504');\n expect(text).toContain('504');\n expect(text).toContain('Sorry, I encountered');\n expect(text).toContain('Send another message to continue');\n });\n\n it('extracts code from \"API Error: 429\"', () => {\n const text = getCannedErrorDisplayText('API Error: 429');\n expect(text).toContain('429');\n expect(text).toContain('Sorry, I encountered');\n });\n\n it('returns generic message when no code match', () => {\n const text = getCannedErrorDisplayText('Something went wrong');\n expect(text).not.toMatch(/\\d+ error/);\n expect(text).toContain('Sorry, I encountered an error');\n expect(text).toContain('Send another message to continue');\n });\n\n it('returns generic message for empty string', () => {\n const text = getCannedErrorDisplayText('');\n expect(text).toContain('Sorry, I encountered an error');\n });\n});\n\ndescribe('extractResultSummary', () => {\n it('returns undefined for empty content', () => {\n expect(extractResultSummary('Glob', '')).toBeUndefined();\n expect(extractResultSummary('Read', '')).toBeUndefined();\n expect(extractResultSummary('Grep', undefined)).toBeUndefined();\n });\n\n it('Glob: counts non-empty lines as files', () => {\n expect(extractResultSummary('Glob', '/a\\n/b\\n/c')).toBe('Found 3 files');\n expect(extractResultSummary('Glob', ' \\n/a\\n \\n')).toBe('Found 1 files');\n expect(extractResultSummary('Glob', '\\n\\n')).toBe('Found 0 files');\n });\n\n it('Read: returns line count', () => {\n expect(extractResultSummary('Read', 'line1')).toBe('Read 1 lines');\n expect(extractResultSummary('Read', 'a\\nb\\nc')).toBe('Read 3 lines');\n });\n\n it('Grep: counts non-empty match lines', () => {\n expect(extractResultSummary('Grep', 'match1\\nmatch2')).toBe(\n 'Found 2 matches',\n );\n expect(extractResultSummary('Grep', ' \\n')).toBe('Found 0 matches');\n });\n\n it('Edit: returns summary from input when input provided', () => {\n expect(\n extractResultSummary(\n 'Edit',\n 'ok',\n {\n old_string: 'a\\nb',\n new_string: 'a\\nb\\nc',\n },\n ),\n ).toBe('Added 1 line');\n expect(\n extractResultSummary(\n 'Edit',\n 'ok',\n {\n old_string: 'x',\n new_string: 'y',\n },\n ),\n ).toBe('Updated 1 line');\n });\n\n it('Edit: returns undefined when input not provided', () => {\n expect(extractResultSummary('Edit', 'content')).toBeUndefined();\n });\n\n it('Write: returns summary from input when input provided', () => {\n expect(\n extractResultSummary(\n 'Write',\n 'ok',\n { path: '/foo/bar.ts', content: 'line1\\nline2\\nline3' },\n ),\n ).toBe('Wrote 3 lines to bar.ts');\n expect(\n extractResultSummary('Write', 'ok', { path: 'file', content: '' }),\n ).toBe('Wrote 0 lines to file');\n });\n\n it('Write: returns undefined when input not provided', () => {\n expect(extractResultSummary('Write', 'content')).toBeUndefined();\n });\n\n it('handles array result content (e.g. multi-block)', () => {\n expect(\n extractResultSummary('Read', [{ text: 'a' }, { text: 'b' }]),\n ).toBe('Read 2 lines');\n });\n\n it('returns undefined for unknown tool', () => {\n expect(extractResultSummary('UnknownTool', 'content')).toBeUndefined();\n });\n});\n\ndescribe('processSDKMessage', () => {\n beforeEach(() => {\n reportSessionErrorMock.mockClear();\n addItemMock.mockClear();\n });\n\n describe('assistant return value lastAssistantHadVisibleContent', () => {\n it('returns lastAssistantHadVisibleContent true when message has text block', () => {\n const result = processSDKMessage(\n {\n type: 'assistant',\n session_id: 'conv-1',\n message: {\n content: [{ type: 'text', text: 'Hello' }],\n },\n },\n baseOptions,\n pendingToolCalls,\n false,\n baseContext,\n );\n expect(result).toEqual({ lastAssistantHadVisibleContent: true });\n });\n\n it('returns lastAssistantHadVisibleContent false when message has only thinking block', () => {\n const result = processSDKMessage(\n {\n type: 'assistant',\n session_id: 'conv-2',\n message: {\n content: [\n {\n type: 'thinking',\n thinking: 'Some internal reasoning.',\n },\n ],\n },\n },\n baseOptions,\n pendingToolCalls,\n false,\n baseContext,\n );\n expect(result).toEqual({ lastAssistantHadVisibleContent: false });\n });\n\n it('returns lastAssistantHadVisibleContent false when message has empty or no content', () => {\n const result = processSDKMessage(\n {\n type: 'assistant',\n session_id: 'conv-3',\n message: { content: [] },\n },\n baseOptions,\n pendingToolCalls,\n false,\n baseContext,\n );\n expect(result).toEqual({ lastAssistantHadVisibleContent: false });\n });\n });\n\n describe('assistant with error', () => {\n it('reports to session/error and shows canned message in UI when message.error is \"unknown\" and error text', () => {\n processSDKMessage(\n {\n type: 'assistant',\n error: 'unknown',\n session_id: 'conv-123',\n message: {\n content: [{ type: 'text', text: 'Error: 504' }],\n },\n },\n baseOptions,\n pendingToolCalls,\n false,\n baseContext,\n );\n\n expect(reportSessionErrorMock).toHaveBeenCalledTimes(1);\n expect(reportSessionErrorMock).toHaveBeenCalledWith(\n 'Error: 504',\n 'conv-123',\n sessionErrorContext,\n );\n expect(addItemMock).toHaveBeenCalledWith({\n type: 'agent-message',\n text: expect.stringContaining('504'),\n });\n expect(addItemMock.mock.calls[0][0].text).toContain(\n 'Send another message to continue',\n );\n });\n\n it('does not call reportSessionError when context.onError or session_id missing', () => {\n processSDKMessage(\n {\n type: 'assistant',\n error: {},\n session_id: undefined,\n message: { content: [{ type: 'text', text: 'Error: 504' }] },\n },\n baseOptions,\n pendingToolCalls,\n false,\n baseContext,\n );\n expect(reportSessionErrorMock).not.toHaveBeenCalled();\n expect(addItemMock).toHaveBeenCalledWith({\n type: 'agent-message',\n text: expect.stringContaining('504'),\n });\n });\n });\n\n describe('result with errors', () => {\n it('reports combined non-interrupt errors to session/error and shows first canned message in UI when not interrupting', () => {\n processSDKMessage(\n {\n type: 'result',\n subtype: 'error',\n session_id: 'conv-456',\n errors: ['Error: 503', 'Error: 504'],\n },\n baseOptions,\n pendingToolCalls,\n false,\n baseContext,\n );\n\n expect(reportSessionErrorMock).toHaveBeenCalledTimes(1);\n expect(reportSessionErrorMock).toHaveBeenCalledWith(\n 'Error: 503\\n\\nError: 504',\n 'conv-456',\n sessionErrorContext,\n );\n expect(addItemMock).toHaveBeenCalledTimes(1);\n expect(addItemMock).toHaveBeenCalledWith({\n type: 'error',\n text: expect.stringContaining('503'),\n });\n });\n\n it('when isInterrupting: still reports to session/error but does not add error to UI', () => {\n processSDKMessage(\n {\n type: 'result',\n subtype: 'error',\n session_id: 'conv-789',\n errors: ['Error: 500'],\n },\n baseOptions,\n pendingToolCalls,\n true,\n baseContext,\n );\n\n expect(reportSessionErrorMock).toHaveBeenCalledTimes(1);\n expect(reportSessionErrorMock).toHaveBeenCalledWith(\n 'Error: 500',\n 'conv-789',\n sessionErrorContext,\n );\n const errorCalls = addItemMock.mock.calls.filter(\n (c: unknown[]) => c[0] && (c[0] as { type: string }).type === 'error',\n );\n expect(errorCalls).toHaveLength(0);\n });\n\n it('does not report or show interrupt-like errors (aborted, interrupted, 403)', () => {\n processSDKMessage(\n {\n type: 'result',\n subtype: 'error',\n session_id: 'conv-x',\n errors: ['request aborted', 'interrupted by user', 'Error: 403'],\n },\n baseOptions,\n pendingToolCalls,\n false,\n baseContext,\n );\n\n expect(reportSessionErrorMock).not.toHaveBeenCalled();\n const errorCalls = addItemMock.mock.calls.filter(\n (c: unknown[]) => c[0] && (c[0] as { type: string }).type === 'error',\n );\n expect(errorCalls).toHaveLength(0);\n });\n });\n\n describe('result success with last assistant having only thinking content', () => {\n it('reports to session/error and queues follow-up prompt when lastAssistantHadVisibleContent is false', () => {\n const queueFollowUpPromptMock = jest.fn();\n processSDKMessage(\n {\n type: 'result',\n subtype: 'success',\n session_id: 'conv-no-text',\n },\n baseOptions,\n pendingToolCalls,\n false,\n {\n ...baseContext,\n lastAssistantHadVisibleContent: false,\n queueFollowUpPrompt: queueFollowUpPromptMock,\n },\n );\n\n expect(reportSessionErrorMock).toHaveBeenCalledTimes(1);\n expect(reportSessionErrorMock).toHaveBeenCalledWith(\n 'Last assistant message did not have a text response.',\n 'conv-no-text',\n sessionErrorContext,\n );\n expect(queueFollowUpPromptMock).toHaveBeenCalledTimes(1);\n expect(queueFollowUpPromptMock).toHaveBeenCalledWith(\n '[Wizard] Continue.',\n );\n });\n\n it('does not report or queue when lastAssistantHadVisibleContent is true', () => {\n const queueFollowUpPromptMock = jest.fn();\n processSDKMessage(\n {\n type: 'result',\n subtype: 'success',\n session_id: 'conv-ok',\n },\n baseOptions,\n pendingToolCalls,\n false,\n {\n ...baseContext,\n lastAssistantHadVisibleContent: true,\n queueFollowUpPrompt: queueFollowUpPromptMock,\n },\n );\n\n expect(reportSessionErrorMock).not.toHaveBeenCalled();\n expect(queueFollowUpPromptMock).not.toHaveBeenCalled();\n });\n\n it('does not report or queue when lastAssistantHadVisibleContent is undefined (treated as had visible)', () => {\n const queueFollowUpPromptMock = jest.fn();\n processSDKMessage(\n {\n type: 'result',\n subtype: 'success',\n session_id: 'conv-ok',\n },\n baseOptions,\n pendingToolCalls,\n false,\n { ...baseContext, queueFollowUpPrompt: queueFollowUpPromptMock },\n );\n\n expect(reportSessionErrorMock).not.toHaveBeenCalled();\n expect(queueFollowUpPromptMock).not.toHaveBeenCalled();\n });\n\n it('does not report or queue when isInterrupting is true', () => {\n const queueFollowUpPromptMock = jest.fn();\n processSDKMessage(\n {\n type: 'result',\n subtype: 'success',\n session_id: 'conv-no-text',\n },\n baseOptions,\n pendingToolCalls,\n true,\n {\n ...baseContext,\n lastAssistantHadVisibleContent: false,\n queueFollowUpPrompt: queueFollowUpPromptMock,\n },\n );\n\n expect(reportSessionErrorMock).not.toHaveBeenCalled();\n expect(queueFollowUpPromptMock).not.toHaveBeenCalled();\n });\n\n it('does not report or queue when context.onError or session_id is missing', () => {\n const queueFollowUpPromptMock = jest.fn();\n processSDKMessage(\n {\n type: 'result',\n subtype: 'success',\n session_id: undefined,\n },\n baseOptions,\n pendingToolCalls,\n false,\n {\n updateSpinner: jest.fn(),\n baseSpinnerMessage: 'Working',\n lastAssistantHadVisibleContent: false,\n queueFollowUpPrompt: queueFollowUpPromptMock,\n },\n );\n\n expect(reportSessionErrorMock).not.toHaveBeenCalled();\n expect(queueFollowUpPromptMock).not.toHaveBeenCalled();\n });\n });\n});\n"]}
@@ -104,11 +104,11 @@ export function initializeAgent(config, options) {
104
104
  ensureClaudeConfigFileExists();
105
105
  process.env.MAX_THINKING_TOKENS = '10000';
106
106
  process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';
107
- // Set default subagent model to Sonnet
108
- process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-sonnet-4-5-20250929';
107
+ // Set default subagent model to Opus
108
+ process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-opus-4-6';
109
109
  const agentRunConfig = {
110
110
  workingDirectory: config.workingDirectory,
111
- model: 'sonnet',
111
+ model: 'opus',
112
112
  };
113
113
  logToFile('Agent config:', {
114
114
  workingDirectory: agentRunConfig.workingDirectory,
@@ -152,7 +152,6 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
152
152
  const inputQueue = new UserMessageQueue();
153
153
  inputQueue.push(prompt);
154
154
  const approvedFilesCache = new Set();
155
- const collectedText = [];
156
155
  const pendingToolCalls = new Map();
157
156
  const hasCompletedWorkRef = { value: false };
158
157
  const isInterruptingRef = { value: false };
@@ -194,14 +193,12 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
194
193
  spinner.start(spinnerMessage);
195
194
  isSpinnerRunning = true;
196
195
  }
197
- ui.setAgentState({ isRunning: true });
198
196
  return;
199
197
  }
200
198
  if (isSpinnerRunning) {
201
199
  spinner.stop();
202
200
  isSpinnerRunning = false;
203
201
  }
204
- ui.setAgentState({ isRunning: false });
205
202
  };
206
203
  // Create MCP server with CompleteIntegration tool
207
204
  const toolsMcpServer = createMcpServer(hasCompletedWorkRef, {
@@ -249,6 +246,7 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
249
246
  waitingForUserInputRef.value = false;
250
247
  isInterruptingRef.value = false;
251
248
  setAgentRunning(true);
249
+ updateSpinner(currentSpinnerMsg);
252
250
  return;
253
251
  }
254
252
  if (!isInterruptingRef.value) {
@@ -288,6 +286,7 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
288
286
  };
289
287
  startPersistentInput();
290
288
  setAgentRunning(true);
289
+ updateSpinner(currentSpinnerMsg);
291
290
  // Create Raindrop client and wrap the Claude Agent SDK for observability
292
291
  const raindrop = createRaindropClaudeAgentSDK({
293
292
  writeKey: accessToken,
@@ -299,6 +298,14 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
299
298
  },
300
299
  selfDiagnostics: {
301
300
  signals: {
301
+ learnings: {
302
+ description: 'The agent learned something new that it did not know before.',
303
+ sentiment: 'NEGATIVE',
304
+ },
305
+ misleading_docs: {
306
+ description: 'The agent followed the documentation and then realised later that it was not the correct approach.',
307
+ sentiment: 'NEGATIVE',
308
+ },
302
309
  code_dumping: {
303
310
  description: 'The user pasted code or console logs to the agent.',
304
311
  sentiment: 'NEGATIVE',
@@ -332,7 +339,11 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
332
339
  mcpServers: {
333
340
  'raindrop-wizard': toolsMcpServer,
334
341
  },
335
- systemPrompt: '{WIZARD_SYSTEM_PROMPT}',
342
+ systemPrompt: {
343
+ type: 'preset',
344
+ preset: 'claude_code',
345
+ append: '{WIZARD_SYSTEM_PROMPT}',
346
+ },
336
347
  env: { ...process.env },
337
348
  canUseTool: createCanUseToolHandler(approvedFilesCache),
338
349
  hooks: {
@@ -347,19 +358,16 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
347
358
  },
348
359
  });
349
360
  // Update agent state
350
- ui.setAgentState({
351
- isRunning: true,
352
- queryHandle: handle,
353
- });
361
+ ui.setAgentState({ queryHandle: handle });
354
362
  try {
355
363
  if (!queryObject) {
356
364
  throw new Error('queryObject was not initialized');
357
365
  }
366
+ let lastAssistantHadVisibleContent = true;
358
367
  for await (const message of queryObject) {
359
368
  // Capture session_id from any message
360
369
  if (message.session_id && !sessionId) {
361
370
  sessionId = message.session_id;
362
- ui.setAgentState({ sessionId });
363
371
  }
364
372
  // If we were waiting for user input but got a new message,
365
373
  // the queued message has started processing.
@@ -369,8 +377,25 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
369
377
  waitingForUserInputRef.value = false;
370
378
  isInterruptingRef.value = false;
371
379
  setAgentRunning(true);
380
+ updateSpinner(currentSpinnerMsg);
381
+ }
382
+ const sdkResult = processSDKMessage(message, options, pendingToolCalls, isInterruptingRef.value, {
383
+ updateSpinner,
384
+ baseSpinnerMessage: spinnerMessage,
385
+ lastAssistantHadVisibleContent,
386
+ queueFollowUpPrompt: (prompt) => inputQueue.push(prompt),
387
+ hasCompletedWork: hasCompletedWorkRef.value,
388
+ onError: {
389
+ wizardSessionId: options.sessionId,
390
+ accessToken,
391
+ orgId,
392
+ workingDirectory: path.resolve(agentConfig.workingDirectory),
393
+ },
394
+ });
395
+ if (sdkResult?.lastAssistantHadVisibleContent !== undefined) {
396
+ lastAssistantHadVisibleContent =
397
+ sdkResult.lastAssistantHadVisibleContent;
372
398
  }
373
- processSDKMessage(message, options, collectedText, pendingToolCalls, isInterruptingRef.value, { updateSpinner, baseSpinnerMessage: spinnerMessage });
374
399
  if (message.type !== 'result') {
375
400
  continue;
376
401
  }
@@ -404,6 +429,7 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
404
429
  handle.sendMessage(feedbackPrompt);
405
430
  startPersistentInput();
406
431
  setAgentRunning(true);
432
+ updateSpinner(currentSpinnerMsg);
407
433
  continue;
408
434
  }
409
435
  completed = completionDecision;
@@ -421,6 +447,7 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
421
447
  else {
422
448
  waitingForUserInputRef.value = false;
423
449
  setAgentRunning(true);
450
+ updateSpinner(currentSpinnerMsg);
424
451
  }
425
452
  }
426
453
  }
@@ -438,7 +465,6 @@ export async function runAgentLoop(agentConfig, prompt, options, config) {
438
465
  completed = true;
439
466
  }
440
467
  ui.stopPersistentInput();
441
- ui.setAgentState({ isRunning: false });
442
468
  if (completed || isSpinnerRunning) {
443
469
  spinner.stop();
444
470
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent-interface.js","sourceRoot":"","sources":["../../../src/lib/agent-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared agent interface for wizards\n * Uses Claude Agent SDK directly with streaming input support\n */\n\nimport type { SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';\nimport * as claudeAgentSDK from '@anthropic-ai/claude-agent-sdk';\nimport { createRaindropClaudeAgentSDK } from '@raindrop-ai/claude-agent-sdk';\nimport { existsSync, writeFileSync } from 'fs';\nimport { createRequire } from 'module';\nimport os from 'os';\nimport path from 'path';\nimport type { AgentQueryHandle } from '../ui/types.js';\nimport {\n debug,\n initLogFile,\n LOG_FILE_PATH,\n logToFile,\n} from '../utils/debug.js';\nimport type { WizardOptions } from '../utils/types.js';\nimport ui from '../utils/ui.js';\nimport { RAINDROP_ENDPOINT } from './constants.js';\nimport {\n createAgentQueryHandle,\n createCanUseToolHandler,\n createPreToolUseHook,\n type PendingToolCall,\n type SessionInfo,\n} from './handlers.js';\nimport { createMcpServer } from './mcp.js';\nimport { processSDKMessage } from './sdk-messages.js';\n\n// Create a require function for ESM compatibility\nconst require = createRequire(import.meta.url);\n\n/**\n * Get the path to the bundled Claude Code CLI from the SDK package.\n * This ensures we use the SDK's bundled version rather than the user's installed Claude Code.\n */\nfunction getClaudeCodeExecutablePath(): string {\n // require.resolve finds the package's main entry, then we get cli.js from same dir\n const sdkPackagePath = require.resolve('@anthropic-ai/claude-agent-sdk');\n return path.join(path.dirname(sdkPackagePath), 'cli.js');\n}\n\n/**\n * Ensure Claude CLI has a config file to read during startup.\n * Some SDK/CLI versions error if ~/.claude.json is missing.\n */\nfunction ensureClaudeConfigFileExists(): void {\n const claudeConfigPath = path.join(os.homedir(), '.claude.json');\n if (existsSync(claudeConfigPath)) {\n return;\n }\n\n writeFileSync(claudeConfigPath, '{}\\n', { encoding: 'utf-8' });\n logToFile('Created missing Claude config file:', claudeConfigPath);\n}\n\n// Re-export AgentQueryHandle for external use\nexport type { AgentQueryHandle };\n\nexport type AgentConfig = {\n workingDirectory: string;\n};\n\n/**\n * Result from runAgentLoop including session ID and query handle\n */\nexport interface AgentRunResult {\n sessionId?: string;\n handle: AgentQueryHandle;\n completed: boolean;\n support?: boolean;\n}\n\n/**\n * Internal configuration object returned by initializeAgent\n */\nexport type AgentRunConfig = {\n workingDirectory: string;\n model: string;\n};\n\ntype QueuedUserMessage = {\n type: 'user';\n message: {\n role: 'user';\n content: string;\n };\n};\n\ntype QueryMessage = {\n type?: string;\n session_id?: string;\n [key: string]: unknown;\n};\n\ntype QueryObject = AsyncIterable<QueryMessage> & {\n interrupt?: () => Promise<void>;\n};\n\n/**\n * Async queue for user messages.\n * Messages are pushed by UI callbacks and consumed by the SDK as an async iterable.\n */\nclass UserMessageQueue implements AsyncIterable<QueuedUserMessage> {\n private messages: QueuedUserMessage[] = [];\n\n private waitingResolver:\n | ((message: QueuedUserMessage | null) => void)\n | null = null;\n\n private closed = false;\n\n push(content: string): void {\n if (this.closed) {\n return;\n }\n\n const message: QueuedUserMessage = {\n type: 'user',\n message: {\n role: 'user',\n content,\n },\n };\n\n if (this.waitingResolver) {\n this.waitingResolver(message);\n this.waitingResolver = null;\n return;\n }\n\n this.messages.push(message);\n }\n\n hasPending(): boolean {\n return this.messages.length > 0;\n }\n\n close(): void {\n this.closed = true;\n if (this.waitingResolver) {\n this.waitingResolver(null);\n this.waitingResolver = null;\n }\n }\n\n async *[Symbol.asyncIterator](): AsyncIterableIterator<QueuedUserMessage> {\n while (!this.closed) {\n if (this.messages.length > 0) {\n const nextMessage = this.messages.shift();\n if (nextMessage) {\n yield nextMessage;\n }\n continue;\n }\n\n const nextMessage = await new Promise<QueuedUserMessage | null>(\n (resolve) => {\n this.waitingResolver = resolve;\n },\n );\n\n if (!nextMessage) {\n return;\n }\n\n yield nextMessage;\n }\n }\n}\n\n/**\n * Initialize agent configuration for the Claude agent\n */\nexport function initializeAgent(\n config: AgentConfig,\n options: WizardOptions,\n): AgentRunConfig {\n // Initialize log file for this run\n initLogFile();\n logToFile('Agent initialization starting');\n logToFile('Install directory:', options.installDir);\n\n try {\n ensureClaudeConfigFileExists();\n process.env.MAX_THINKING_TOKENS = '10000';\n process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';\n // Set default subagent model to Sonnet\n process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-sonnet-4-5-20250929';\n\n const agentRunConfig: AgentRunConfig = {\n workingDirectory: config.workingDirectory,\n model: 'sonnet',\n };\n\n logToFile('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n\n if (options.debug) {\n debug('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n }\n\n ui.addItem({\n type: 'step',\n text: `I'll keep verbose logs for this session at: ${LOG_FILE_PATH}`,\n });\n return agentRunConfig;\n } catch (error) {\n ui.addItem({\n type: 'error',\n text: `Failed to initialize agent: ${(error as Error).message}`,\n });\n logToFile('Agent initialization error:', error);\n debug('Agent initialization error:', error);\n throw error;\n }\n}\n\n/**\n * Configuration for runAgentLoop\n */\nexport interface RunAgentConfig {\n spinnerMessage?: string;\n accessToken: string;\n orgId: string;\n onCompleteIntegration?: () => Promise<boolean | string>;\n}\n\n/**\n * Execute an agent with the provided prompt and options.\n * Supports streaming input for user interruption and follow-up messages.\n * Uses a single long-lived SDK query fed by an async message queue.\n *\n * @returns Session ID and query handle for controlling the agent\n */\nexport async function runAgentLoop(\n agentConfig: AgentRunConfig,\n prompt: string,\n options: WizardOptions,\n config: RunAgentConfig,\n): Promise<AgentRunResult> {\n const {\n spinnerMessage = 'Raindrop wizard is working...',\n accessToken,\n orgId,\n onCompleteIntegration,\n } = config;\n\n // Add header to indicate start of interactive agent phase\n ui.addItem({ type: 'phase', text: '─── Agent ───' });\n\n const cliPath = getClaudeCodeExecutablePath();\n logToFile('Starting agent run');\n logToFile('Claude Code executable:', cliPath);\n\n const startTime = Date.now();\n const inputQueue = new UserMessageQueue();\n inputQueue.push(prompt);\n\n const approvedFilesCache = new Set<string>();\n const collectedText: string[] = [];\n const pendingToolCalls = new Map<string, PendingToolCall>();\n\n const hasCompletedWorkRef = { value: false };\n const isInterruptingRef = { value: false };\n const waitingForUserInputRef = { value: false };\n const exitHintShownRef = { value: false };\n\n let sessionId: string | undefined;\n let queryObject: QueryObject | null = null;\n let isSpinnerRunning = false;\n let completed = false;\n let shouldEndSession = false;\n let supportRequested = false;\n\n const spinner = ui.spinner();\n\n // Track current spinner base message and when it last changed.\n let currentSpinnerMsg = spinnerMessage;\n let lastActivityTime = Date.now();\n\n const updateSpinner = (msg: string) => {\n if (!isSpinnerRunning) return;\n currentSpinnerMsg = msg;\n lastActivityTime = Date.now();\n spinner.message(msg);\n };\n\n // Every second, if the agent has been silent for >= 10s, append a counting thinking indicator.\n // Pure JS interval — Ink only re-renders when the string actually changes.\n const thinkingTimer = setInterval(() => {\n if (!isSpinnerRunning) return;\n const idleS = Math.floor((Date.now() - lastActivityTime) / 1000);\n if (idleS >= 20) {\n const mins = Math.floor(idleS / 60);\n const secs = idleS % 60;\n const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;\n spinner.message(`${currentSpinnerMsg} (thinking · ${timeStr})`);\n }\n }, 1000);\n\n const setAgentRunning = (isRunning: boolean) => {\n if (isRunning) {\n if (!isSpinnerRunning) {\n spinner.start(spinnerMessage);\n isSpinnerRunning = true;\n }\n ui.setAgentState({ isRunning: true });\n return;\n }\n\n if (isSpinnerRunning) {\n spinner.stop();\n isSpinnerRunning = false;\n }\n ui.setAgentState({ isRunning: false });\n };\n\n // Create MCP server with CompleteIntegration tool\n const toolsMcpServer = createMcpServer(hasCompletedWorkRef, {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n installDir: agentConfig.workingDirectory,\n });\n\n // Session info for notifications\n const sessionInfo: SessionInfo = {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n };\n\n const handle = createAgentQueryHandle({\n isInterruptingRef,\n waitingForUserInputRef,\n pendingToolCalls,\n getQueryObject: () => queryObject,\n sendMessage: (message: string) => {\n inputQueue.push(message);\n },\n });\n\n const startPersistentInput = (placeholder?: string) => {\n ui.startPersistentInput({\n onSubmit: handlePersistentSubmit,\n onInterrupt: handlePersistentInterrupt,\n onCtrlC: handlePersistentCtrlC,\n placeholder,\n });\n };\n\n // Define callbacks for persistent input\n const handlePersistentSubmit = (message: string) => {\n const trimmedMessage = message.trim();\n if (!trimmedMessage) {\n return;\n }\n\n exitHintShownRef.value = false;\n\n ui.addItem({\n type: 'user-message',\n text: trimmedMessage,\n });\n\n handle.sendMessage(trimmedMessage);\n\n if (waitingForUserInputRef.value) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n return;\n }\n\n if (!isInterruptingRef.value) {\n logToFile(\n 'User submitted message while agent is running - interrupting current turn',\n );\n void handle.interrupt(true);\n }\n };\n\n const handlePersistentInterrupt = () => {\n logToFile('User requested interrupt (Esc)');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n const handlePersistentCtrlC = () => {\n logToFile('User pressed Ctrl+C');\n\n // If already interrupted and exit hint was shown, exit immediately\n if (\n (isInterruptingRef.value || waitingForUserInputRef.value) &&\n exitHintShownRef.value\n ) {\n logToFile('Second Ctrl+C - exiting');\n ui.stopPersistentInput();\n ui.exit();\n // Small delay to allow UI to clean up before exit\n setTimeout(() => process.exit(130), 100);\n return;\n }\n\n // If already interrupted but hint not shown yet, show hint and clear input\n if (isInterruptingRef.value || waitingForUserInputRef.value) {\n logToFile('First Ctrl+C while interrupted - showing exit hint');\n exitHintShownRef.value = true;\n ui.stopPersistentInput();\n startPersistentInput('Press Ctrl+C again to exit');\n return;\n }\n\n // Not interrupted yet - treat as normal interrupt\n logToFile('First Ctrl+C - triggering interrupt');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n startPersistentInput();\n setAgentRunning(true);\n\n // Create Raindrop client and wrap the Claude Agent SDK for observability\n const raindrop = createRaindropClaudeAgentSDK({\n writeKey: accessToken,\n endpoint: RAINDROP_ENDPOINT,\n });\n const wrappedSDK = raindrop.wrap(claudeAgentSDK, {\n context: {\n userId: orgId,\n },\n selfDiagnostics: {\n signals: {\n code_dumping: {\n description: 'The user pasted code or console logs to the agent.',\n sentiment: 'NEGATIVE',\n },\n user_wake_up: {\n description:\n 'The user is waking up the agent e.g. \"hello\", \"continue\", etc.',\n sentiment: 'NEGATIVE',\n },\n user_correction: {\n description:\n \"The user is correcting the agent's original plan or approach.\",\n sentiment: 'NEGATIVE',\n },\n tool_failure: {\n description:\n 'A tool call returned an error, timed out, or produced unusable output.',\n sentiment: 'NEGATIVE',\n },\n stuck_in_loop: {\n description:\n 'The same approach has been attempted multiple times without progress.',\n sentiment: 'NEGATIVE',\n },\n },\n },\n });\n\n queryObject = wrappedSDK.query({\n prompt: inputQueue as unknown as AsyncIterable<SDKUserMessage>,\n options: {\n model: agentConfig.model,\n cwd: agentConfig.workingDirectory,\n permissionMode: 'default',\n disallowedTools: ['Skill'],\n mcpServers: {\n 'raindrop-wizard': toolsMcpServer,\n },\n systemPrompt: '{WIZARD_SYSTEM_PROMPT}',\n env: { ...process.env },\n canUseTool: createCanUseToolHandler(approvedFilesCache),\n hooks: {\n PreToolUse: [{ hooks: [createPreToolUseHook(sessionInfo)] }],\n },\n stderr: (data: string) => {\n logToFile('CLI stderr:', data);\n if (options.debug) {\n debug('CLI stderr:', data);\n }\n },\n },\n });\n\n // Update agent state\n ui.setAgentState({\n isRunning: true,\n queryHandle: handle,\n });\n\n try {\n if (!queryObject) {\n throw new Error('queryObject was not initialized');\n }\n for await (const message of queryObject) {\n // Capture session_id from any message\n if (message.session_id && !sessionId) {\n sessionId = message.session_id;\n ui.setAgentState({ sessionId });\n }\n\n // If we were waiting for user input but got a new message,\n // the queued message has started processing.\n if (\n waitingForUserInputRef.value &&\n !isInterruptingRef.value &&\n message.type !== 'result'\n ) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n }\n\n processSDKMessage(\n message,\n options,\n collectedText,\n pendingToolCalls,\n isInterruptingRef.value,\n { updateSpinner, baseSpinnerMessage: spinnerMessage },\n );\n\n if (message.type !== 'result') {\n continue;\n }\n\n if (hasCompletedWorkRef.value) {\n setAgentRunning(false);\n ui.stopPersistentInput();\n\n const completionDecision = onCompleteIntegration\n ? await onCompleteIntegration()\n : true;\n\n if (completionDecision === 'support') {\n logToFile('User requested support - ending session');\n completed = false;\n supportRequested = true;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n if (typeof completionDecision === 'string') {\n const feedbackPrompt = completionDecision.trim();\n if (!feedbackPrompt) {\n logToFile('Received empty feedback prompt - ending session');\n completed = false;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n logToFile('Received testing feedback - queueing feedback prompt');\n hasCompletedWorkRef.value = false;\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n handle.sendMessage(feedbackPrompt);\n startPersistentInput();\n setAgentRunning(true);\n continue;\n }\n\n completed = completionDecision;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n // Turn ended without completion. If there are no queued messages,\n // we are waiting for the user to submit the next one.\n isInterruptingRef.value = false;\n\n if (!inputQueue.hasPending()) {\n waitingForUserInputRef.value = true;\n setAgentRunning(false);\n } else {\n waitingForUserInputRef.value = false;\n setAgentRunning(true);\n }\n }\n } finally {\n inputQueue.close();\n clearInterval(thinkingTimer);\n await raindrop.flush();\n }\n\n const durationMs = Date.now() - startTime;\n logToFile(`Agent session completed in ${Math.round(durationMs / 1000)}s`);\n logToFile('Session ID:', sessionId);\n logToFile('Completion status:', hasCompletedWorkRef.value);\n\n if (!shouldEndSession && hasCompletedWorkRef.value) {\n // Fallback: if stream ended after completion, mark as completed.\n completed = true;\n }\n\n ui.stopPersistentInput();\n ui.setAgentState({ isRunning: false });\n\n if (completed || isSpinnerRunning) {\n spinner.stop();\n }\n\n return { sessionId, handle, completed, support: supportRequested };\n}\n"]}
1
+ {"version":3,"file":"agent-interface.js","sourceRoot":"","sources":["../../../src/lib/agent-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared agent interface for wizards\n * Uses Claude Agent SDK directly with streaming input support\n */\n\nimport type { SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';\nimport * as claudeAgentSDK from '@anthropic-ai/claude-agent-sdk';\nimport { createRaindropClaudeAgentSDK } from '@raindrop-ai/claude-agent-sdk';\nimport { existsSync, writeFileSync } from 'fs';\nimport { createRequire } from 'module';\nimport os from 'os';\nimport path from 'path';\nimport type { AgentQueryHandle } from '../ui/types.js';\nimport {\n debug,\n initLogFile,\n LOG_FILE_PATH,\n logToFile,\n} from '../utils/debug.js';\nimport type { WizardOptions } from '../utils/types.js';\nimport ui from '../utils/ui.js';\nimport { RAINDROP_ENDPOINT } from './constants.js';\nimport {\n createAgentQueryHandle,\n createCanUseToolHandler,\n createPreToolUseHook,\n type PendingToolCall,\n type SessionInfo,\n} from './handlers.js';\nimport { createMcpServer } from './mcp.js';\nimport { processSDKMessage } from './sdk-messages.js';\n\n// Create a require function for ESM compatibility\nconst require = createRequire(import.meta.url);\n\n/**\n * Get the path to the bundled Claude Code CLI from the SDK package.\n * This ensures we use the SDK's bundled version rather than the user's installed Claude Code.\n */\nfunction getClaudeCodeExecutablePath(): string {\n // require.resolve finds the package's main entry, then we get cli.js from same dir\n const sdkPackagePath = require.resolve('@anthropic-ai/claude-agent-sdk');\n return path.join(path.dirname(sdkPackagePath), 'cli.js');\n}\n\n/**\n * Ensure Claude CLI has a config file to read during startup.\n * Some SDK/CLI versions error if ~/.claude.json is missing.\n */\nfunction ensureClaudeConfigFileExists(): void {\n const claudeConfigPath = path.join(os.homedir(), '.claude.json');\n if (existsSync(claudeConfigPath)) {\n return;\n }\n\n writeFileSync(claudeConfigPath, '{}\\n', { encoding: 'utf-8' });\n logToFile('Created missing Claude config file:', claudeConfigPath);\n}\n\n// Re-export AgentQueryHandle for external use\nexport type { AgentQueryHandle };\n\nexport type AgentConfig = {\n workingDirectory: string;\n};\n\n/**\n * Result from runAgentLoop including session ID and query handle\n */\nexport interface AgentRunResult {\n sessionId?: string;\n handle: AgentQueryHandle;\n completed: boolean;\n support?: boolean;\n}\n\n/**\n * Internal configuration object returned by initializeAgent\n */\nexport type AgentRunConfig = {\n workingDirectory: string;\n model: string;\n};\n\ntype QueuedUserMessage = {\n type: 'user';\n message: {\n role: 'user';\n content: string;\n };\n};\n\ntype QueryMessage = {\n type?: string;\n session_id?: string;\n [key: string]: unknown;\n};\n\ntype QueryObject = AsyncIterable<QueryMessage> & {\n interrupt?: () => Promise<void>;\n};\n\n/**\n * Async queue for user messages.\n * Messages are pushed by UI callbacks and consumed by the SDK as an async iterable.\n */\nclass UserMessageQueue implements AsyncIterable<QueuedUserMessage> {\n private messages: QueuedUserMessage[] = [];\n\n private waitingResolver:\n | ((message: QueuedUserMessage | null) => void)\n | null = null;\n\n private closed = false;\n\n push(content: string): void {\n if (this.closed) {\n return;\n }\n\n const message: QueuedUserMessage = {\n type: 'user',\n message: {\n role: 'user',\n content,\n },\n };\n\n if (this.waitingResolver) {\n this.waitingResolver(message);\n this.waitingResolver = null;\n return;\n }\n\n this.messages.push(message);\n }\n\n hasPending(): boolean {\n return this.messages.length > 0;\n }\n\n close(): void {\n this.closed = true;\n if (this.waitingResolver) {\n this.waitingResolver(null);\n this.waitingResolver = null;\n }\n }\n\n async *[Symbol.asyncIterator](): AsyncIterableIterator<QueuedUserMessage> {\n while (!this.closed) {\n if (this.messages.length > 0) {\n const nextMessage = this.messages.shift();\n if (nextMessage) {\n yield nextMessage;\n }\n continue;\n }\n\n const nextMessage = await new Promise<QueuedUserMessage | null>(\n (resolve) => {\n this.waitingResolver = resolve;\n },\n );\n\n if (!nextMessage) {\n return;\n }\n\n yield nextMessage;\n }\n }\n}\n\n/**\n * Initialize agent configuration for the Claude agent\n */\nexport function initializeAgent(\n config: AgentConfig,\n options: WizardOptions,\n): AgentRunConfig {\n // Initialize log file for this run\n initLogFile();\n logToFile('Agent initialization starting');\n logToFile('Install directory:', options.installDir);\n\n try {\n ensureClaudeConfigFileExists();\n process.env.MAX_THINKING_TOKENS = '10000';\n process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';\n // Set default subagent model to Opus\n process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-opus-4-6';\n\n const agentRunConfig: AgentRunConfig = {\n workingDirectory: config.workingDirectory,\n model: 'opus',\n };\n\n logToFile('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n\n if (options.debug) {\n debug('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n }\n\n ui.addItem({\n type: 'step',\n text: `I'll keep verbose logs for this session at: ${LOG_FILE_PATH}`,\n });\n return agentRunConfig;\n } catch (error) {\n ui.addItem({\n type: 'error',\n text: `Failed to initialize agent: ${(error as Error).message}`,\n });\n logToFile('Agent initialization error:', error);\n debug('Agent initialization error:', error);\n throw error;\n }\n}\n\n/**\n * Configuration for runAgentLoop\n */\nexport interface RunAgentConfig {\n spinnerMessage?: string;\n accessToken: string;\n orgId: string;\n onCompleteIntegration?: () => Promise<boolean | string>;\n}\n\n/**\n * Execute an agent with the provided prompt and options.\n * Supports streaming input for user interruption and follow-up messages.\n * Uses a single long-lived SDK query fed by an async message queue.\n *\n * @returns Session ID and query handle for controlling the agent\n */\nexport async function runAgentLoop(\n agentConfig: AgentRunConfig,\n prompt: string,\n options: WizardOptions,\n config: RunAgentConfig,\n): Promise<AgentRunResult> {\n const {\n spinnerMessage = 'Raindrop wizard is working...',\n accessToken,\n orgId,\n onCompleteIntegration,\n } = config;\n\n // Add header to indicate start of interactive agent phase\n ui.addItem({ type: 'phase', text: '─── Agent ───' });\n\n const cliPath = getClaudeCodeExecutablePath();\n logToFile('Starting agent run');\n logToFile('Claude Code executable:', cliPath);\n\n const startTime = Date.now();\n const inputQueue = new UserMessageQueue();\n inputQueue.push(prompt);\n\n const approvedFilesCache = new Set<string>();\n const pendingToolCalls = new Map<string, PendingToolCall>();\n\n const hasCompletedWorkRef = { value: false };\n const isInterruptingRef = { value: false };\n const waitingForUserInputRef = { value: false };\n const exitHintShownRef = { value: false };\n\n let sessionId: string | undefined;\n let queryObject: QueryObject | null = null;\n let isSpinnerRunning = false;\n let completed = false;\n let shouldEndSession = false;\n let supportRequested = false;\n\n const spinner = ui.spinner();\n\n // Track current spinner base message and when it last changed.\n let currentSpinnerMsg = spinnerMessage;\n let lastActivityTime = Date.now();\n\n const updateSpinner = (msg: string) => {\n if (!isSpinnerRunning) return;\n currentSpinnerMsg = msg;\n lastActivityTime = Date.now();\n spinner.message(msg);\n };\n\n // Every second, if the agent has been silent for >= 10s, append a counting thinking indicator.\n // Pure JS interval — Ink only re-renders when the string actually changes.\n const thinkingTimer = setInterval(() => {\n if (!isSpinnerRunning) return;\n const idleS = Math.floor((Date.now() - lastActivityTime) / 1000);\n if (idleS >= 20) {\n const mins = Math.floor(idleS / 60);\n const secs = idleS % 60;\n const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;\n spinner.message(`${currentSpinnerMsg} (thinking · ${timeStr})`);\n }\n }, 1000);\n\n const setAgentRunning = (isRunning: boolean) => {\n if (isRunning) {\n if (!isSpinnerRunning) {\n spinner.start(spinnerMessage);\n isSpinnerRunning = true;\n }\n return;\n }\n\n if (isSpinnerRunning) {\n spinner.stop();\n isSpinnerRunning = false;\n }\n };\n\n // Create MCP server with CompleteIntegration tool\n const toolsMcpServer = createMcpServer(hasCompletedWorkRef, {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n installDir: agentConfig.workingDirectory,\n });\n\n // Session info for notifications\n const sessionInfo: SessionInfo = {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n };\n\n const handle = createAgentQueryHandle({\n isInterruptingRef,\n waitingForUserInputRef,\n pendingToolCalls,\n getQueryObject: () => queryObject,\n sendMessage: (message: string) => {\n inputQueue.push(message);\n },\n });\n\n const startPersistentInput = (placeholder?: string) => {\n ui.startPersistentInput({\n onSubmit: handlePersistentSubmit,\n onInterrupt: handlePersistentInterrupt,\n onCtrlC: handlePersistentCtrlC,\n placeholder,\n });\n };\n\n // Define callbacks for persistent input\n const handlePersistentSubmit = (message: string) => {\n const trimmedMessage = message.trim();\n if (!trimmedMessage) {\n return;\n }\n\n exitHintShownRef.value = false;\n\n ui.addItem({\n type: 'user-message',\n text: trimmedMessage,\n });\n\n handle.sendMessage(trimmedMessage);\n\n if (waitingForUserInputRef.value) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n updateSpinner(currentSpinnerMsg);\n return;\n }\n\n if (!isInterruptingRef.value) {\n logToFile(\n 'User submitted message while agent is running - interrupting current turn',\n );\n void handle.interrupt(true);\n }\n };\n\n const handlePersistentInterrupt = () => {\n logToFile('User requested interrupt (Esc)');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n const handlePersistentCtrlC = () => {\n logToFile('User pressed Ctrl+C');\n\n // If already interrupted and exit hint was shown, exit immediately\n if (\n (isInterruptingRef.value || waitingForUserInputRef.value) &&\n exitHintShownRef.value\n ) {\n logToFile('Second Ctrl+C - exiting');\n ui.stopPersistentInput();\n ui.exit();\n // Small delay to allow UI to clean up before exit\n setTimeout(() => process.exit(130), 100);\n return;\n }\n\n // If already interrupted but hint not shown yet, show hint and clear input\n if (isInterruptingRef.value || waitingForUserInputRef.value) {\n logToFile('First Ctrl+C while interrupted - showing exit hint');\n exitHintShownRef.value = true;\n ui.stopPersistentInput();\n startPersistentInput('Press Ctrl+C again to exit');\n return;\n }\n\n // Not interrupted yet - treat as normal interrupt\n logToFile('First Ctrl+C - triggering interrupt');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n startPersistentInput();\n setAgentRunning(true);\n updateSpinner(currentSpinnerMsg);\n\n // Create Raindrop client and wrap the Claude Agent SDK for observability\n const raindrop = createRaindropClaudeAgentSDK({\n writeKey: accessToken,\n endpoint: RAINDROP_ENDPOINT,\n });\n const wrappedSDK = raindrop.wrap(claudeAgentSDK, {\n context: {\n userId: orgId,\n },\n selfDiagnostics: {\n signals: {\n learnings: {\n description:\n 'The agent learned something new that it did not know before.',\n sentiment: 'NEGATIVE',\n },\n misleading_docs: {\n description:\n 'The agent followed the documentation and then realised later that it was not the correct approach.',\n sentiment: 'NEGATIVE',\n },\n code_dumping: {\n description: 'The user pasted code or console logs to the agent.',\n sentiment: 'NEGATIVE',\n },\n user_wake_up: {\n description:\n 'The user is waking up the agent e.g. \"hello\", \"continue\", etc.',\n sentiment: 'NEGATIVE',\n },\n user_correction: {\n description:\n \"The user is correcting the agent's original plan or approach.\",\n sentiment: 'NEGATIVE',\n },\n tool_failure: {\n description:\n 'A tool call returned an error, timed out, or produced unusable output.',\n sentiment: 'NEGATIVE',\n },\n stuck_in_loop: {\n description:\n 'The same approach has been attempted multiple times without progress.',\n sentiment: 'NEGATIVE',\n },\n },\n },\n });\n\n queryObject = wrappedSDK.query({\n prompt: inputQueue as unknown as AsyncIterable<SDKUserMessage>,\n options: {\n model: agentConfig.model,\n cwd: agentConfig.workingDirectory,\n permissionMode: 'default',\n disallowedTools: ['Skill'],\n mcpServers: {\n 'raindrop-wizard': toolsMcpServer,\n },\n systemPrompt: {\n type: 'preset',\n preset: 'claude_code',\n append: '{WIZARD_SYSTEM_PROMPT}',\n },\n env: { ...process.env },\n canUseTool: createCanUseToolHandler(approvedFilesCache),\n hooks: {\n PreToolUse: [{ hooks: [createPreToolUseHook(sessionInfo)] }],\n },\n stderr: (data: string) => {\n logToFile('CLI stderr:', data);\n if (options.debug) {\n debug('CLI stderr:', data);\n }\n },\n },\n });\n\n // Update agent state\n ui.setAgentState({ queryHandle: handle });\n\n try {\n if (!queryObject) {\n throw new Error('queryObject was not initialized');\n }\n let lastAssistantHadVisibleContent = true;\n for await (const message of queryObject) {\n // Capture session_id from any message\n if (message.session_id && !sessionId) {\n sessionId = message.session_id;\n }\n\n // If we were waiting for user input but got a new message,\n // the queued message has started processing.\n if (\n waitingForUserInputRef.value &&\n !isInterruptingRef.value &&\n message.type !== 'result'\n ) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n updateSpinner(currentSpinnerMsg);\n }\n\n const sdkResult = processSDKMessage(\n message,\n options,\n pendingToolCalls,\n isInterruptingRef.value,\n {\n updateSpinner,\n baseSpinnerMessage: spinnerMessage,\n lastAssistantHadVisibleContent,\n queueFollowUpPrompt: (prompt: string) => inputQueue.push(prompt),\n hasCompletedWork: hasCompletedWorkRef.value,\n onError: {\n wizardSessionId: options.sessionId,\n accessToken,\n orgId,\n workingDirectory: path.resolve(agentConfig.workingDirectory),\n },\n },\n );\n if (sdkResult?.lastAssistantHadVisibleContent !== undefined) {\n lastAssistantHadVisibleContent =\n sdkResult.lastAssistantHadVisibleContent;\n }\n\n if (message.type !== 'result') {\n continue;\n }\n\n if (hasCompletedWorkRef.value) {\n setAgentRunning(false);\n ui.stopPersistentInput();\n\n const completionDecision = onCompleteIntegration\n ? await onCompleteIntegration()\n : true;\n\n if (completionDecision === 'support') {\n logToFile('User requested support - ending session');\n completed = false;\n supportRequested = true;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n if (typeof completionDecision === 'string') {\n const feedbackPrompt = completionDecision.trim();\n if (!feedbackPrompt) {\n logToFile('Received empty feedback prompt - ending session');\n completed = false;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n logToFile('Received testing feedback - queueing feedback prompt');\n hasCompletedWorkRef.value = false;\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n handle.sendMessage(feedbackPrompt);\n startPersistentInput();\n setAgentRunning(true);\n updateSpinner(currentSpinnerMsg);\n continue;\n }\n\n completed = completionDecision;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n // Turn ended without completion. If there are no queued messages,\n // we are waiting for the user to submit the next one.\n isInterruptingRef.value = false;\n\n if (!inputQueue.hasPending()) {\n waitingForUserInputRef.value = true;\n setAgentRunning(false);\n } else {\n waitingForUserInputRef.value = false;\n setAgentRunning(true);\n updateSpinner(currentSpinnerMsg);\n }\n }\n } finally {\n inputQueue.close();\n clearInterval(thinkingTimer);\n await raindrop.flush();\n }\n\n const durationMs = Date.now() - startTime;\n logToFile(`Agent session completed in ${Math.round(durationMs / 1000)}s`);\n logToFile('Session ID:', sessionId);\n logToFile('Completion status:', hasCompletedWorkRef.value);\n\n if (!shouldEndSession && hasCompletedWorkRef.value) {\n // Fallback: if stream ended after completion, mark as completed.\n completed = true;\n }\n\n ui.stopPersistentInput();\n\n if (completed || isSpinnerRunning) {\n spinner.stop();\n }\n\n return { sessionId, handle, completed, support: supportRequested };\n}\n"]}
@@ -22,7 +22,10 @@ Analyze the events and user feedback, then fix the code to address any issues:
22
22
  2. Identify what's missing or incorrect
23
23
  3. Update the integration code to fix the problems
24
24
  4. Verify the build still succeeds after your fixes
25
- 5. Call CompleteIntegration when done. Do not announce that you are calling the tool.`;
25
+ 5. Call CompleteIntegration when done. Do not announce that you are calling the tool.
26
+
27
+ ## Fix
28
+ Begin the integration by immediately announcing that you will analyse the events and user feedback and then fix the code to address any issues.`;
26
29
  }
27
30
  // =============================================================================
28
31
  // Helper Functions
@@ -1 +1 @@
1
- {"version":3,"file":"agent-prompts.js","sourceRoot":"","sources":["../../../src/lib/agent-prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAyC,EACzC,YAAoB;IAEpB,OAAO;;;;EAIP,kBAAkB,CAAC,MAAM,CAAC;;;;GAIzB,YAAY;;;;;;;;;sFASuE,CAAC;AACvF,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;GAEG;AACH,SAAS,kBAAkB,CAAC,MAAyC;IACnE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QAClB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9D,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC;QAEtD,OAAO,UAAU,GAAG,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG;UACpC,MAAM;EACd,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;QACpC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IACvC,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC","sourcesContent":["/**\n * Agent prompt templates for Raindrop integration wizard\n */\n\n/**\n * Build test feedback message for agent\n */\nexport function buildTestFeedbackMessage(\n events: Array<{ url: string; data: any }>,\n userFeedback: string,\n): string {\n return `# Integration Test Results\n\n## Events Collected\n\n${formatEventSummary(events)}\n\n## User Feedback\n\n\"${userFeedback}\"\n\n## Your Task\n\nAnalyze the events and user feedback, then fix the code to address any issues:\n1. Review the event data structure and user's comments\n2. Identify what's missing or incorrect\n3. Update the integration code to fix the problems\n4. Verify the build still succeeds after your fixes\n5. Call CompleteIntegration when done. Do not announce that you are calling the tool.`;\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Format event summary for test feedback\n */\nfunction formatEventSummary(events: Array<{ url: string; data: any }>): string {\n if (events.length === 0) {\n return 'No events received.';\n }\n\n return events\n .map((event, idx) => {\n const format = event.data.format === 'otel' ? 'OTEL' : 'JSON';\n const spanCount = event.data.spans?.length || 0;\n const aiAttrs = event.data.aiAttributes || event.data;\n\n return `Event #${idx + 1} at ${event.url}:\nFormat: ${format}\n${spanCount > 0 ? `Spans: ${spanCount}` : ''}\nData: ${JSON.stringify(aiAttrs, null, 2)}`;\n })\n .join('\\n\\n');\n}\n"]}
1
+ {"version":3,"file":"agent-prompts.js","sourceRoot":"","sources":["../../../src/lib/agent-prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAyC,EACzC,YAAoB;IAEpB,OAAO;;;;EAIP,kBAAkB,CAAC,MAAM,CAAC;;;;GAIzB,YAAY;;;;;;;;;;;;gJAYiI,CAAC;AACjJ,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;GAEG;AACH,SAAS,kBAAkB,CAAC,MAAyC;IACnE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QAClB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9D,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC;QAEtD,OAAO,UAAU,GAAG,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG;UACpC,MAAM;EACd,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;QACpC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IACvC,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC","sourcesContent":["/**\n * Agent prompt templates for Raindrop integration wizard\n */\n\n/**\n * Build test feedback message for agent\n */\nexport function buildTestFeedbackMessage(\n events: Array<{ url: string; data: any }>,\n userFeedback: string,\n): string {\n return `# Integration Test Results\n\n## Events Collected\n\n${formatEventSummary(events)}\n\n## User Feedback\n\n\"${userFeedback}\"\n\n## Your Task\n\nAnalyze the events and user feedback, then fix the code to address any issues:\n1. Review the event data structure and user's comments\n2. Identify what's missing or incorrect\n3. Update the integration code to fix the problems\n4. Verify the build still succeeds after your fixes\n5. Call CompleteIntegration when done. Do not announce that you are calling the tool.\n\n## Fix\nBegin the integration by immediately announcing that you will analyse the events and user feedback and then fix the code to address any issues.`;\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Format event summary for test feedback\n */\nfunction formatEventSummary(events: Array<{ url: string; data: any }>): string {\n if (events.length === 0) {\n return 'No events received.';\n }\n\n return events\n .map((event, idx) => {\n const format = event.data.format === 'otel' ? 'OTEL' : 'JSON';\n const spanCount = event.data.spans?.length || 0;\n const aiAttrs = event.data.aiAttributes || event.data;\n\n return `Event #${idx + 1} at ${event.url}:\nFormat: ${format}\n${spanCount > 0 ? `Spans: ${spanCount}` : ''}\nData: ${JSON.stringify(aiAttrs, null, 2)}`;\n })\n .join('\\n\\n');\n}\n"]}
@@ -15,12 +15,19 @@ export declare const ANTHROPIC_BASE_URL: string;
15
15
  export declare const SESSION_START_ENDPOINT: string;
16
16
  export declare const SESSION_UPDATE_ENDPOINT: string;
17
17
  export declare const SESSION_COMPLETE_ENDPOINT: string;
18
+ export declare const SESSION_ERROR_ENDPOINT: string;
18
19
  export declare const SUPPORT_ENDPOINT: string;
19
20
  export declare const RAINDROP_ENDPOINT: string;
20
21
  /**
21
22
  * Spinner message shown during wizard execution
22
23
  */
23
24
  export declare const SPINNER_MESSAGE = "Raindrop wizard is working...";
25
+ /** Prefix for MCP tools (e.g. mcp__server__tool). Shared by handlers and SDK message processing. */
26
+ export declare const MCP_TOOL_PREFIX = "mcp__";
27
+ /** Tool names that are internal to the wizard and not shown in the UI (e.g. Task, EnterPlanMode). */
28
+ export declare const INTERNAL_TOOL_NAMES: Set<string>;
29
+ /** Canned message when assistant content is an error (message.error set). Optional code e.g. "504". */
30
+ export declare const ERROR_DISPLAY_MESSAGE: (code?: string) => string;
24
31
  /**
25
32
  * Safe bash command patterns that can be auto-approved without user confirmation.
26
33
  * Uses simple prefix matching with optional * wildcard at the end.
@@ -32,12 +32,27 @@ export const ANTHROPIC_BASE_URL = `${RAINDROP_API_URL}/api/cli`;
32
32
  export const SESSION_START_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/init`;
33
33
  export const SESSION_UPDATE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/update`;
34
34
  export const SESSION_COMPLETE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/complete`;
35
+ export const SESSION_ERROR_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/error`;
35
36
  export const SUPPORT_ENDPOINT = `${RAINDROP_API_URL}/api/cli/support`;
36
37
  export const RAINDROP_ENDPOINT = `${RAINDROP_API_URL}/api/cli/raindrop`;
37
38
  /**
38
39
  * Spinner message shown during wizard execution
39
40
  */
40
41
  export const SPINNER_MESSAGE = 'Raindrop wizard is working...';
42
+ /** Prefix for MCP tools (e.g. mcp__server__tool). Shared by handlers and SDK message processing. */
43
+ export const MCP_TOOL_PREFIX = 'mcp__';
44
+ /** Tool names that are internal to the wizard and not shown in the UI (e.g. Task, EnterPlanMode). */
45
+ export const INTERNAL_TOOL_NAMES = new Set([
46
+ 'Task',
47
+ 'AskUserQuestion',
48
+ 'TodoWrite',
49
+ 'EnterPlanMode',
50
+ 'ExitPlanMode',
51
+ ]);
52
+ /** Canned message when assistant content is an error (message.error set). Optional code e.g. "504". */
53
+ export const ERROR_DISPLAY_MESSAGE = (code) => code
54
+ ? `Sorry, I encountered a ${code} error. Send another message to continue. If the issue persists, please contact support@raindrop.ai`
55
+ : `Sorry, I encountered an error. Send another message to continue. If the issue persists, please contact support@raindrop.ai`;
41
56
  /**
42
57
  * Safe bash command patterns that can be auto-approved without user confirmation.
43
58
  * Uses simple prefix matching with optional * wildcard at the end.
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/lib/constants.ts"],"names":[],"mappings":"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","sourcesContent":["export enum Integration {\n python = 'python',\n typescript = 'typescript',\n vercelAiSdk = 'vercel-ai-sdk',\n}\n\nexport function getIntegrationDescription(type: string): string {\n switch (type) {\n case Integration.python:\n return 'a Python SDK';\n case Integration.typescript:\n return 'a TypeScript SDK';\n case Integration.vercelAiSdk:\n return 'the Vercel AI SDK';\n default:\n throw new Error(`Unknown integration ${type}`);\n }\n}\n\nexport const IS_DEV = ['test', 'development'].includes(\n process.env.NODE_ENV ?? '',\n);\n\nexport const ISSUES_URL = 'https://github.com/raindrop/wizard/issues';\n\nexport const CALLBACK_PORT = 8259;\nconst useLocalUrls = ['1', 'true'].includes(\n (process.env.RAINDROP_USE_LOCAL ?? '').toLowerCase(),\n);\n\nexport const APP_URL = useLocalUrls\n ? 'http://localhost:5173'\n : 'https://app.raindrop.ai';\nexport const RAINDROP_API_URL = useLocalUrls\n ? 'http://localhost:3000'\n : 'https://api.dawnai.com';\nexport const WRITE_KEY_ENDPOINT = `${RAINDROP_API_URL}/api/cli/users/key`;\nexport const EVENTS_LIST_ENDPOINT = `${RAINDROP_API_URL}/api/cli/events/list`;\nexport const ANTHROPIC_BASE_URL = `${RAINDROP_API_URL}/api/cli`;\nexport const SESSION_START_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/init`;\nexport const SESSION_UPDATE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/update`;\nexport const SESSION_COMPLETE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/complete`;\nexport const SUPPORT_ENDPOINT = `${RAINDROP_API_URL}/api/cli/support`;\nexport const RAINDROP_ENDPOINT = `${RAINDROP_API_URL}/api/cli/raindrop`;\n\n/**\n * Spinner message shown during wizard execution\n */\nexport const SPINNER_MESSAGE = 'Raindrop wizard is working...';\n\n/**\n * Safe bash command patterns that can be auto-approved without user confirmation.\n * Uses simple prefix matching with optional * wildcard at the end.\n *\n * NOTE: Package manager install/build/run commands are NOT auto-approved and require user confirmation.\n */\nexport const SAFE_BASH_PATTERNS: string[] = [\n // === Package Managers - Read-only commands ===\n 'npm ls*',\n 'npm outdated*',\n 'npm audit*',\n\n 'pip list*',\n 'pip show*',\n 'pip freeze*',\n\n 'poetry show*',\n\n 'uv pip list*',\n\n 'cargo check*',\n 'cargo clippy*',\n 'cargo fmt*',\n\n 'go fmt*',\n\n // === Type Checking / Linting / Formatting ===\n 'tsc*',\n 'eslint *',\n 'prettier *',\n 'biome *',\n 'mypy *',\n 'python -m mypy*',\n 'ruff *',\n 'black *',\n 'flake8 *',\n 'pylint *',\n 'pyright*',\n 'rubocop*',\n 'rustfmt*',\n 'gofmt*',\n 'swiftlint*',\n 'ktlint*',\n\n // === Build Tools ===\n 'make',\n 'make build*',\n 'make test*',\n 'make lint*',\n 'make check*',\n 'cmake *',\n 'gradle build*',\n 'gradle test*',\n './gradlew build*',\n './gradlew test*',\n 'mvn compile*',\n 'mvn test*',\n 'mvn package*',\n\n // === Testing ===\n 'jest*',\n 'vitest*',\n 'mocha*',\n 'pytest*',\n 'python -m pytest*',\n 'npx playwright test*',\n 'npx cypress run*',\n 'npx jest*',\n 'npx vitest*',\n\n // === Git (read-only operations) ===\n 'git status*',\n 'git diff*',\n 'git log*',\n 'git show*',\n 'git branch*',\n 'git fetch*',\n 'git remote -v*',\n 'git ls-files*',\n 'git rev-parse*',\n\n // === File/Directory Info (read-only) ===\n 'ls *',\n 'ls',\n 'cat *',\n 'head *',\n 'tail *',\n 'less *',\n 'find *',\n 'grep *',\n 'rg *',\n 'ag *',\n 'tree*',\n 'pwd',\n 'wc *',\n 'file *',\n 'stat *',\n 'du *',\n 'df *',\n\n // === Environment/System Info ===\n 'which *',\n 'whereis *',\n 'type *',\n 'command -v *',\n 'node --version*',\n 'node -v*',\n 'npm --version*',\n 'npm -v*',\n 'python --version*',\n 'python -V*',\n 'python3 --version*',\n '*--version',\n '*-v',\n '*-V',\n 'env',\n 'printenv*',\n 'echo *',\n 'uname*',\n 'hostname',\n 'whoami',\n 'date',\n 'uptime',\n\n // === Docker (read-only / safe) ===\n 'docker ps*',\n 'docker images*',\n 'docker logs*',\n 'docker inspect*',\n 'docker-compose ps*',\n 'docker-compose logs*',\n 'docker build*',\n 'docker compose build*',\n 'docker compose up*',\n\n // === Directory Navigation ===\n 'cd *',\n 'pushd *',\n 'popd',\n];\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,gCAAiB,CAAA;IACjB,wCAAyB,CAAA;IACzB,4CAA6B,CAAA;AAC/B,CAAC,EAJW,WAAW,KAAX,WAAW,QAItB;AAED,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW,CAAC,MAAM;YACrB,OAAO,cAAc,CAAC;QACxB,KAAK,WAAW,CAAC,UAAU;YACzB,OAAO,kBAAkB,CAAC;QAC5B,KAAK,WAAW,CAAC,WAAW;YAC1B,OAAO,mBAAmB,CAAC;QAC7B;YACE,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,QAAQ,CACpD,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,2CAA2C,CAAC;AAEtE,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAClC,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,QAAQ,CACzC,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CACrD,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,YAAY;IACjC,CAAC,CAAC,uBAAuB;IACzB,CAAC,CAAC,yBAAyB,CAAC;AAC9B,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY;IAC1C,CAAC,CAAC,uBAAuB;IACzB,CAAC,CAAC,wBAAwB,CAAC;AAC7B,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,gBAAgB,oBAAoB,CAAC;AAC1E,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,gBAAgB,sBAAsB,CAAC;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,gBAAgB,UAAU,CAAC;AAChE,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,gBAAgB,uBAAuB,CAAC;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,gBAAgB,yBAAyB,CAAC;AACpF,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,gBAAgB,2BAA2B,CAAC;AACxF,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,gBAAgB,wBAAwB,CAAC;AAClF,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,gBAAgB,kBAAkB,CAAC;AACtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,gBAAgB,mBAAmB,CAAC;AAExE;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,+BAA+B,CAAC;AAE/D,oGAAoG;AACpG,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AAEvC,qGAAqG;AACrG,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IACzC,MAAM;IACN,iBAAiB;IACjB,WAAW;IACX,eAAe;IACf,cAAc;CACf,CAAC,CAAC;AAEH,uGAAuG;AACvG,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAa,EAAE,EAAE,CACrD,IAAI;IACF,CAAC,CAAC,0BAA0B,IAAI,qGAAqG;IACrI,CAAC,CAAC,4HAA4H,CAAC;AAEnI;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAa;IAC1C,gDAAgD;IAChD,SAAS;IACT,eAAe;IACf,YAAY;IAEZ,WAAW;IACX,WAAW;IACX,aAAa;IAEb,cAAc;IAEd,cAAc;IAEd,cAAc;IACd,eAAe;IACf,YAAY;IAEZ,SAAS;IAET,+CAA+C;IAC/C,MAAM;IACN,UAAU;IACV,YAAY;IACZ,SAAS;IACT,QAAQ;IACR,iBAAiB;IACjB,QAAQ;IACR,SAAS;IACT,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,QAAQ;IACR,YAAY;IACZ,SAAS;IAET,sBAAsB;IACtB,MAAM;IACN,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,aAAa;IACb,SAAS;IACT,eAAe;IACf,cAAc;IACd,kBAAkB;IAClB,iBAAiB;IACjB,cAAc;IACd,WAAW;IACX,cAAc;IAEd,kBAAkB;IAClB,OAAO;IACP,SAAS;IACT,QAAQ;IACR,SAAS;IACT,mBAAmB;IACnB,sBAAsB;IACtB,kBAAkB;IAClB,WAAW;IACX,aAAa;IAEb,qCAAqC;IACrC,aAAa;IACb,WAAW;IACX,UAAU;IACV,WAAW;IACX,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAEhB,0CAA0C;IAC1C,MAAM;IACN,IAAI;IACJ,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,MAAM;IACN,OAAO;IACP,KAAK;IACL,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,MAAM;IAEN,kCAAkC;IAClC,SAAS;IACT,WAAW;IACX,QAAQ;IACR,cAAc;IACd,iBAAiB;IACjB,UAAU;IACV,gBAAgB;IAChB,SAAS;IACT,mBAAmB;IACnB,YAAY;IACZ,oBAAoB;IACpB,YAAY;IACZ,KAAK;IACL,KAAK;IACL,KAAK;IACL,WAAW;IACX,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,MAAM;IACN,QAAQ;IAER,oCAAoC;IACpC,YAAY;IACZ,gBAAgB;IAChB,cAAc;IACd,iBAAiB;IACjB,oBAAoB;IACpB,sBAAsB;IACtB,eAAe;IACf,uBAAuB;IACvB,oBAAoB;IAEpB,+BAA+B;IAC/B,MAAM;IACN,SAAS;IACT,MAAM;CACP,CAAC","sourcesContent":["export enum Integration {\n python = 'python',\n typescript = 'typescript',\n vercelAiSdk = 'vercel-ai-sdk',\n}\n\nexport function getIntegrationDescription(type: string): string {\n switch (type) {\n case Integration.python:\n return 'a Python SDK';\n case Integration.typescript:\n return 'a TypeScript SDK';\n case Integration.vercelAiSdk:\n return 'the Vercel AI SDK';\n default:\n throw new Error(`Unknown integration ${type}`);\n }\n}\n\nexport const IS_DEV = ['test', 'development'].includes(\n process.env.NODE_ENV ?? '',\n);\n\nexport const ISSUES_URL = 'https://github.com/raindrop/wizard/issues';\n\nexport const CALLBACK_PORT = 8259;\nconst useLocalUrls = ['1', 'true'].includes(\n (process.env.RAINDROP_USE_LOCAL ?? '').toLowerCase(),\n);\n\nexport const APP_URL = useLocalUrls\n ? 'http://localhost:5173'\n : 'https://app.raindrop.ai';\nexport const RAINDROP_API_URL = useLocalUrls\n ? 'http://localhost:3000'\n : 'https://api.dawnai.com';\nexport const WRITE_KEY_ENDPOINT = `${RAINDROP_API_URL}/api/cli/users/key`;\nexport const EVENTS_LIST_ENDPOINT = `${RAINDROP_API_URL}/api/cli/events/list`;\nexport const ANTHROPIC_BASE_URL = `${RAINDROP_API_URL}/api/cli`;\nexport const SESSION_START_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/init`;\nexport const SESSION_UPDATE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/update`;\nexport const SESSION_COMPLETE_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/complete`;\nexport const SESSION_ERROR_ENDPOINT = `${RAINDROP_API_URL}/api/cli/session/error`;\nexport const SUPPORT_ENDPOINT = `${RAINDROP_API_URL}/api/cli/support`;\nexport const RAINDROP_ENDPOINT = `${RAINDROP_API_URL}/api/cli/raindrop`;\n\n/**\n * Spinner message shown during wizard execution\n */\nexport const SPINNER_MESSAGE = 'Raindrop wizard is working...';\n\n/** Prefix for MCP tools (e.g. mcp__server__tool). Shared by handlers and SDK message processing. */\nexport const MCP_TOOL_PREFIX = 'mcp__';\n\n/** Tool names that are internal to the wizard and not shown in the UI (e.g. Task, EnterPlanMode). */\nexport const INTERNAL_TOOL_NAMES = new Set([\n 'Task',\n 'AskUserQuestion',\n 'TodoWrite',\n 'EnterPlanMode',\n 'ExitPlanMode',\n]);\n\n/** Canned message when assistant content is an error (message.error set). Optional code e.g. \"504\". */\nexport const ERROR_DISPLAY_MESSAGE = (code?: string) =>\n code\n ? `Sorry, I encountered a ${code} error. Send another message to continue. If the issue persists, please contact support@raindrop.ai`\n : `Sorry, I encountered an error. Send another message to continue. If the issue persists, please contact support@raindrop.ai`;\n\n/**\n * Safe bash command patterns that can be auto-approved without user confirmation.\n * Uses simple prefix matching with optional * wildcard at the end.\n *\n * NOTE: Package manager install/build/run commands are NOT auto-approved and require user confirmation.\n */\nexport const SAFE_BASH_PATTERNS: string[] = [\n // === Package Managers - Read-only commands ===\n 'npm ls*',\n 'npm outdated*',\n 'npm audit*',\n\n 'pip list*',\n 'pip show*',\n 'pip freeze*',\n\n 'poetry show*',\n\n 'uv pip list*',\n\n 'cargo check*',\n 'cargo clippy*',\n 'cargo fmt*',\n\n 'go fmt*',\n\n // === Type Checking / Linting / Formatting ===\n 'tsc*',\n 'eslint *',\n 'prettier *',\n 'biome *',\n 'mypy *',\n 'python -m mypy*',\n 'ruff *',\n 'black *',\n 'flake8 *',\n 'pylint *',\n 'pyright*',\n 'rubocop*',\n 'rustfmt*',\n 'gofmt*',\n 'swiftlint*',\n 'ktlint*',\n\n // === Build Tools ===\n 'make',\n 'make build*',\n 'make test*',\n 'make lint*',\n 'make check*',\n 'cmake *',\n 'gradle build*',\n 'gradle test*',\n './gradlew build*',\n './gradlew test*',\n 'mvn compile*',\n 'mvn test*',\n 'mvn package*',\n\n // === Testing ===\n 'jest*',\n 'vitest*',\n 'mocha*',\n 'pytest*',\n 'python -m pytest*',\n 'npx playwright test*',\n 'npx cypress run*',\n 'npx jest*',\n 'npx vitest*',\n\n // === Git (read-only operations) ===\n 'git status*',\n 'git diff*',\n 'git log*',\n 'git show*',\n 'git branch*',\n 'git fetch*',\n 'git remote -v*',\n 'git ls-files*',\n 'git rev-parse*',\n\n // === File/Directory Info (read-only) ===\n 'ls *',\n 'ls',\n 'cat *',\n 'head *',\n 'tail *',\n 'less *',\n 'find *',\n 'grep *',\n 'rg *',\n 'ag *',\n 'tree*',\n 'pwd',\n 'wc *',\n 'file *',\n 'stat *',\n 'du *',\n 'df *',\n\n // === Environment/System Info ===\n 'which *',\n 'whereis *',\n 'type *',\n 'command -v *',\n 'node --version*',\n 'node -v*',\n 'npm --version*',\n 'npm -v*',\n 'python --version*',\n 'python -V*',\n 'python3 --version*',\n '*--version',\n '*-v',\n '*-V',\n 'env',\n 'printenv*',\n 'echo *',\n 'uname*',\n 'hostname',\n 'whoami',\n 'date',\n 'uptime',\n\n // === Docker (read-only / safe) ===\n 'docker ps*',\n 'docker images*',\n 'docker logs*',\n 'docker inspect*',\n 'docker-compose ps*',\n 'docker-compose logs*',\n 'docker build*',\n 'docker compose build*',\n 'docker compose up*',\n\n // === Directory Navigation ===\n 'cd *',\n 'pushd *',\n 'popd',\n];\n"]}
@@ -6,7 +6,7 @@ import { createTwoFilesPatch } from 'diff';
6
6
  import { logToFile } from '../utils/debug.js';
7
7
  import { sendSessionUpdate } from '../utils/session.js';
8
8
  import ui from '../utils/ui.js';
9
- import { SAFE_BASH_PATTERNS } from './constants.js';
9
+ import { MCP_TOOL_PREFIX, SAFE_BASH_PATTERNS } from './constants.js';
10
10
  // ============================================================================
11
11
  // Session-wide Approval Tracking
12
12
  // ============================================================================
@@ -301,13 +301,14 @@ async function handlePlanApproval(input, sessionInfo) {
301
301
  updatedInput: input,
302
302
  };
303
303
  }
304
- /** Prefix for MCP tools (e.g. mcp__server__tool or mcp____server____tool). All are auto-approved and not shown in approval UI. */
305
- const MCP_TOOL_PREFIX = 'mcp__';
306
304
  /**
307
305
  * Tools that are automatically approved without user confirmation.
308
306
  * MCP tools (name starts with mcp__) are approved via wildcard in PreToolUse.
309
307
  */
310
- const AUTO_APPROVED_TOOLS = new Set(['EnterPlanMode']);
308
+ const AUTO_APPROVED_TOOLS = new Set([
309
+ 'EnterPlanMode',
310
+ 'WebFetch',
311
+ ]);
311
312
  /**
312
313
  * Patterns indicating a file path or glob likely targets secret/credential files.
313
314
  * Used to auto-deny Read/Glob/Grep operations on sensitive files.
@@ -409,7 +410,22 @@ export function createPreToolUseHook(sessionInfo) {
409
410
  },
410
411
  };
411
412
  }
412
- // Auto-approve all MCP tools (mcp__*) and EnterPlanMode — no approval UI
413
+ // Auto-approve WebSearch with domain restriction applied via updatedInput.
414
+ // Keep this before the generic AUTO_APPROVED_TOOLS branch so WebSearch
415
+ // still receives input hardening.
416
+ if (tool_name === 'WebSearch') {
417
+ return {
418
+ hookSpecificOutput: {
419
+ hookEventName: 'PreToolUse',
420
+ permissionDecision: 'allow',
421
+ updatedInput: {
422
+ ...inp,
423
+ allowed_domains: ['raindrop.ai/docs', 'ai-sdk.dev/docs/'],
424
+ },
425
+ },
426
+ };
427
+ }
428
+ // Auto-approve all MCP tools (mcp__*) and core auto-approved tools — no approval UI
413
429
  if (tool_name.startsWith(MCP_TOOL_PREFIX) ||
414
430
  AUTO_APPROVED_TOOLS.has(tool_name)) {
415
431
  return {
@@ -441,19 +457,6 @@ export function createPreToolUseHook(sessionInfo) {
441
457
  };
442
458
  }
443
459
  }
444
- // Auto-approve WebSearch with domain restriction applied via updatedInput
445
- if (tool_name === 'WebSearch') {
446
- return {
447
- hookSpecificOutput: {
448
- hookEventName: 'PreToolUse',
449
- permissionDecision: 'allow',
450
- updatedInput: {
451
- ...inp,
452
- allowed_domains: ['raindrop.ai/docs', 'ai-sdk.dev/docs/'],
453
- },
454
- },
455
- };
456
- }
457
460
  // Auto-approve ExitPlanMode and fire session update
458
461
  if (tool_name === 'ExitPlanMode') {
459
462
  const planContent = typeof inp.plan === 'string' ? inp.plan : '';