@circuitwall/jarela 0.7.2 → 0.7.3

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 (91) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +2 -2
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  5. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  15. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  16. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  17. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  19. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  22. package/.next/standalone/.next/server/app/api/v1/agents/[id]/compact/route.js +51 -35
  23. package/.next/standalone/.next/server/app/api/v1/agents/[id]/compact/route.js.map +1 -1
  24. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js +2 -2
  25. package/.next/standalone/.next/server/app/index.html +2 -2
  26. package/.next/standalone/.next/server/app/index.rsc +3 -3
  27. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  28. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  29. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  30. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  31. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  32. package/.next/standalone/.next/server/app/page.js +515 -104
  33. package/.next/standalone/.next/server/app/page.js.map +1 -1
  34. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/setup.html +1 -1
  37. package/.next/standalone/.next/server/app/setup.rsc +2 -2
  38. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +2 -2
  39. package/.next/standalone/.next/server/app/setup.segments/_head.segment.rsc +1 -1
  40. package/.next/standalone/.next/server/app/setup.segments/_index.segment.rsc +2 -2
  41. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  42. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +1 -1
  43. package/.next/standalone/.next/server/app/setup.segments/setup.segment.rsc +1 -1
  44. package/.next/standalone/.next/server/chunks/1683.js +26 -16
  45. package/.next/standalone/.next/server/chunks/1683.js.map +1 -1
  46. package/.next/standalone/.next/server/chunks/{317.js → 5432.js} +11100 -10858
  47. package/.next/standalone/.next/server/chunks/5432.js.map +1 -0
  48. package/.next/standalone/.next/server/chunks/7885.js +606 -353
  49. package/.next/standalone/.next/server/chunks/7885.js.map +1 -1
  50. package/.next/standalone/.next/server/chunks/8135.js +59 -16
  51. package/.next/standalone/.next/server/chunks/8135.js.map +1 -1
  52. package/.next/standalone/.next/server/chunks/9032.js +3 -3
  53. package/.next/standalone/.next/server/chunks/9032.js.map +1 -1
  54. package/.next/standalone/.next/server/instrumentation.js +3 -3
  55. package/.next/standalone/.next/server/instrumentation.js.map +1 -1
  56. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  57. package/.next/standalone/.next/server/pages/404.html +2 -2
  58. package/.next/standalone/.next/server/pages/500.html +1 -1
  59. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  60. package/.next/standalone/.next/static/chunks/app/{page-a20902703c0a4f10.js → page-9fb006074fb13526.js} +582 -171
  61. package/.next/standalone/.next/static/chunks/app/page-9fb006074fb13526.js.map +1 -0
  62. package/.next/standalone/.next/static/css/5507dbe1cdc6c599.css +5 -0
  63. package/.next/standalone/.next/static/css/5507dbe1cdc6c599.css.map +1 -0
  64. package/.next/standalone/package.json +1 -1
  65. package/CHANGELOG.md +11 -0
  66. package/README.md +83 -1
  67. package/api/types.ts +7 -0
  68. package/app/api/v1/agents/[id]/compact/route.ts +2 -40
  69. package/components/bridges/BridgeEditor.tsx +8 -0
  70. package/components/chat/MessageBubble.tsx +3 -36
  71. package/components/models/ModelEditor.tsx +141 -0
  72. package/components/scheduled-tasks/ScheduledTasksPanel.tsx +5 -0
  73. package/components/scheduled-tasks/WatchersSection.tsx +5 -0
  74. package/lib/agents/context-budget.test.ts +128 -0
  75. package/lib/agents/context-budget.ts +128 -0
  76. package/lib/agents/conversation-summary.test.ts +68 -0
  77. package/lib/agents/conversation-summary.ts +51 -0
  78. package/lib/agents/run-thread.ts +112 -2
  79. package/lib/bridges/dispatcher.test.ts +134 -0
  80. package/lib/bridges/dispatcher.ts +34 -16
  81. package/lib/bridges/message-role.test.ts +83 -0
  82. package/lib/bridges/message-role.ts +46 -0
  83. package/lib/triggers/handlers/watcher.test.ts +23 -4
  84. package/lib/triggers/handlers/watcher.ts +56 -8
  85. package/package.json +1 -1
  86. package/.next/standalone/.next/server/chunks/317.js.map +0 -1
  87. package/.next/standalone/.next/static/chunks/app/page-a20902703c0a4f10.js.map +0 -1
  88. package/.next/standalone/.next/static/css/cc66c456aba91258.css +0 -5
  89. package/.next/standalone/.next/static/css/cc66c456aba91258.css.map +0 -1
  90. /package/.next/standalone/.next/static/{IauO0rNZkUVPX834k-SBa → AbCOWpaxP4v4lUSeFWWYz}/_buildManifest.js +0 -0
  91. /package/.next/standalone/.next/static/{IauO0rNZkUVPX834k-SBa → AbCOWpaxP4v4lUSeFWWYz}/_ssgManifest.js +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"317.js","mappings":"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HACA;IACA;IACA;IACA,gGACA;IACA,yHACA,gJACA,gIACA;IACA,kHACA;IACA,2HACA;IACA,qGACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAAC1T,IAAI,CAAC;AAEP,MAAM2T,oBAAoB;IACxB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAAC3T,IAAI,CAAC;AAEP,MAAM4T,gBAAgB;IACpB;IACA;IACA;IACA;IACA;IACA,CAAC,kCAAkC,EAAEL,SAAS,wDAAwD,CAAC;IACvG;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,CAAC,wBAAwB,EAAEA,SAAS,kXAAkX,CAAC;IACvZ;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAACvT,IAAI,CAAC;AAEA,MAAM6T,yBAAiBA,GAAc;IAC1C;QACElX,IAAIiW,wBAAkBA;QACtBpY,MAAM;QACNU,aACE;QACF4Y,SAAS;QACTC,UAAU;YACRhB,cAAc;gBAAEiB,SAAS;gBAAMC,MAAMT;YAAkB;YACvDN,YAAY;gBAAEc,SAAS;gBAAMC,MAAMR;YAAgB;YACnDN,cAAc;gBAAEa,SAAS;gBAAMC,MAAMN;YAAkB;YACvDP,UAAU;gBAAEY,SAAS;gBAAMC,MAAML;YAAc;YAC/CP,aAAa;gBAAEW,SAAS;gBAAMC,MAAMP;YAAiB;QACvD;IACF;CACD,CAAC;AAEK,SAASQ,kBAAkBvX,EAAU;IAC1C,OAAOkX,yBAAiBA,CAAChI,IAAI,CAAC,CAACsI,IAAMA,EAAExX,EAAE,KAAKA;AAChD;;;ACrNyC;AACR;AASG;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A;QACJ;KACD;AACH,EAAE;;;AC1EK,MAAMC,iBAAsC;IACjDn/C,IAAI;IACJnC,MAAM;IACNm/B,SACE,2FACA,0FACA;IACFpc,UAAU;IACV+9B,eAAe;QACb;YACEC,OAAO;YACPC,QACE,oFACA;QACJ;QACA;YACED,OAAO;YACPC,QACE,8FACA;YACFC,UAAU;QACZ;KACD;IACDC,OAAO;QACL;YACE/+C,IAAI;YACJqW,OAAO;YACP9X,aACE,+FACA,sGACA,sGACA;YACFugD,UAAU;QACZ;QACA;YACE9+C,IAAI;YACJqW,OAAO;YACP9X,aACE;YACFygD,UAAU;QACZ;KACD;IACDC,iBAAiB;QACf;YACEhmB,MAAM;YACNimB,KACE,mFACA;QACJ;QACA;YACEjmB,MAAM;YACNimB,KACE,uGACA;QACJ;QACA;YACEjmB,MAAM;YACNimB,KACE,yGACA,0GACA;QACJ;QACA;YACEjmB,MAAM;YACNimB,KACE,8FACA;QACJ;KACD;AACH,EAAE;;;ACrEK,MAAME,gBAAqC;IAChDp/C,IAAI;IACJnC,MAAM;IACNm/B,SACE,iFACA,qFACA;IACFpc,UAAU;IACV+9B,eAAe;QACb;YACEC,OAAO;YACPC,QACE,gFACA,gFACA;YACFC,UAAU;QACZ;QACA;YACEF,OAAO;YACPC,QACE,sFACA;QACJ;KACD;IACDE,OAAO;QACL;YACE/+C,IAAI;YACJqW,OAAO;YACP9X,aACE,oFACA;YACFugD,UAAU;QACZ;QACA;YACE9+C,IAAI;YACJqW,OAAO;YACP9X,aACE,mGACA;QACJ;QACA;YACEyB,IAAI;YACJqW,OAAO;YACP9X,aACE,6FACA;YACFugD,UAAU;QACZ;QACA;YACE9+C,IAAI;YACJqW,OAAO;YACP9X,aACE,uFACA;YACFygD,UAAU;QACZ;QACA;YACEh/C,IAAI;YACJqW,OAAO;YACP9X,aACE,2FACA,0FACA;YACFygD,UAAU;YACVK,QAAQ;gBAAE7kC,MAAM;YAAoB;QACtC;KACD;IACDykC,iBAAiB;QACf;YACEhmB,MAAM;YACNimB,KACE,uFACA,gGACA;QACJ;QACA;YACEjmB,MAAM;YACNimB,KACE,kGACA;QACJ;QACA;YACEjmB,MAAM;YACNimB,KACE,iGACA;QACJ;QACA;YACEjmB,MAAM;YACNimB,KACE,mGACA;QACJ;KACD;AACH,EAAE;;;AC9FK,MAAMI,iBAAsC;IACjDt/C,IAAI;IACJnC,MAAM;IACNm/B,SACE,2EACA;IACFpc,UAAU;IACV+9B,eAAe;QACb;YACEC,OAAO;YACPC,QACE,uEACA;YACFC,UAAU;QACZ;KACD;IACDC,OAAO;QACL;YACE/+C,IAAI;YACJqW,OAAO;YACP9X,aACE,qEACA;YACFugD,UAAU;QACZ;QACA;YACE9+C,IAAI;YACJqW,OAAO;YACP9X,aACE,4EACA;YACFygD,UAAU;QACZ;KACD;IACDC,iBAAiB;QACf;YACEhmB,MAAM;YACNimB,KACE,6EACA;QACJ;QACA;YACEjmB,MAAM;YACNimB,KACE,uFACA;QACJ;KACD;AACH,EAAE;;;AChDK,MAAMK,kBAAuC;IAClDv/C,IAAI;IACJnC,MAAM;IACNm/B,SACE,wFACA,wFACA;IACFpc,UAAU;IACV+9B,eAAe;QACb;YACEC,OAAO;YACPC,QACE,mFACA,qFACA;YACFC,UAAU;QACZ;QACA;YACEF,OAAO;YACPC,QACE,6FACA;QACJ;KACD;IACDE,OAAO;QACL;YACE/+C,IAAI;YACJqW,OAAO;YACP9X,aACE,wFACA,+GACA;YACFugD,UAAU;QACZ;QACA;YACE9+C,IAAI;YACJqW,OAAO;YACP9X,aACE,oGACA;QACJ;QACA;YACEyB,IAAI;YACJqW,OAAO;YACP9X,aACE,mFACA,yEACA;QACJ;QACA;YACEyB,IAAI;YACJqW,OAAO;YACP9X,aACE,4GACA;YACFygD,UAAU;QACZ;QACA;YACEh/C,IAAI;YACJqW,OAAO;YACP9X,aACE,oGACA;YACFygD,UAAU;YACVK,QAAQ;gBAAE7kC,MAAM;YAAuB;QACzC;KACD;IACDykC,iBAAiB;QACf;YACEhmB,MAAM;YACNimB,KACE,kGACA;QACJ;QACA;YACEjmB,MAAM;YACNimB,KACE,oGACA;QACJ;QAC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","sources":["webpack://@circuitwall/jarela/./lib/providers/jarela-chat-model.ts","webpack://@circuitwall/jarela/./lib/stores/langgraph-store.ts","webpack://@circuitwall/jarela/./lib/agents/sqlite-checkpoint-saver.ts","webpack://@circuitwall/jarela/./lib/agents/checkpointer.ts","webpack://@circuitwall/jarela/./lib/agents/llm.ts","webpack://@circuitwall/jarela/./lib/stores/tool-stats.ts","webpack://@circuitwall/jarela/./lib/agents/adaptive-persona.ts","webpack://@circuitwall/jarela/./lib/agents/harness/types.ts","webpack://@circuitwall/jarela/./lib/agents/harness/presets.ts","webpack://@circuitwall/jarela/./lib/stores/harnesses.ts","webpack://@circuitwall/jarela/./lib/agents/harness/resolve.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/claim-detector.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/citation-parser.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/validator.ts","webpack://@circuitwall/jarela/./lib/agents/output-validator/index.ts","webpack://@circuitwall/jarela/./lib/agents/run-thread.ts","webpack://@circuitwall/jarela/./lib/stores/watchers.ts","webpack://@circuitwall/jarela/./lib/utils/json.ts","webpack://@circuitwall/jarela/./lib/tools/registry.ts","webpack://@circuitwall/jarela/./lib/integrations/gmail-oauth.ts","webpack://@circuitwall/jarela/./lib/tools/github.ts","webpack://@circuitwall/jarela/./lib/stores/document-sources.ts","webpack://@circuitwall/jarela/./lib/stores/scheduled-tasks.ts","webpack://@circuitwall/jarela/./lib/utils/oauth-flow-store.ts","webpack://@circuitwall/jarela/./lib/documents/remote/flatten.ts","webpack://@circuitwall/jarela/./lib/documents/remote/upsert.ts","webpack://@circuitwall/jarela/./lib/documents/remote/confluence.ts","webpack://@circuitwall/jarela/./lib/documents/remote/mail.ts","webpack://@circuitwall/jarela/./lib/documents/remote/jira.ts","webpack://@circuitwall/jarela/./lib/documents/remote/github.ts","webpack://@circuitwall/jarela/./lib/documents/remote/index.ts","webpack://@circuitwall/jarela/./lib/notifications/bus.ts","webpack://@circuitwall/jarela/./lib/integrations/microsoft-oauth.ts","webpack://@circuitwall/jarela/./lib/stores/threads.ts","webpack://@circuitwall/jarela/./lib/stores/user-profile.ts","webpack://@circuitwall/jarela/./lib/scheduler/index.ts","webpack://@circuitwall/jarela/./lib/env/app-config.ts","webpack://@circuitwall/jarela/./lib/env/config.ts","webpack://@circuitwall/jarela/./lib/tools/memory.ts","webpack://@circuitwall/jarela/./lib/documents/search.ts","webpack://@circuitwall/jarela/./lib/tools/documents.ts","webpack://@circuitwall/jarela/./lib/tools/exec.ts","webpack://@circuitwall/jarela/./lib/tools/files.ts","webpack://@circuitwall/jarela/./lib/tools/search.ts","webpack://@circuitwall/jarela/./lib/utils/private-ip.ts","webpack://@circuitwall/jarela/./lib/tools/fetch.ts","webpack://@circuitwall/jarela/./lib/tools/location.ts","webpack://@circuitwall/jarela/./lib/files.ts","webpack://@circuitwall/jarela/./lib/utils/google-api.ts","webpack://@circuitwall/jarela/./lib/tools/generate_image.ts","webpack://@circuitwall/jarela/./lib/voice/constants.ts","webpack://@circuitwall/jarela/./lib/voice/gemini.ts","webpack://@circuitwall/jarela/./lib/tools/generate_voice.ts","webpack://@circuitwall/jarela/./lib/tools/schedule.ts","webpack://@circuitwall/jarela/./lib/tools/watcher.ts","webpack://@circuitwall/jarela/./lib/stores/pending-actions.ts","webpack://@circuitwall/jarela/./lib/tools/propose.ts","webpack://@circuitwall/jarela/./lib/integrations/atlassian/manifest.ts","webpack://@circuitwall/jarela/./lib/integrations/github/manifest.ts","webpack://@circuitwall/jarela/./lib/integrations/gmail/manifest.ts","webpack://@circuitwall/jarela/./lib/integrations/google/manifest.ts","webpack://@circuitwall/jarela/./lib/integrations/outlook/manifest.ts","webpack://@circuitwall/jarela/./lib/integrations/manifest.ts","webpack://@circuitwall/jarela/./lib/integrations/registry.ts","webpack://@circuitwall/jarela/./lib/tools/integrations.ts","webpack://@circuitwall/jarela/./lib/tools/jira-align.ts","webpack://@circuitwall/jarela/./lib/tools/gmail.ts","webpack://@circuitwall/jarela/./lib/tools/calendar.ts","webpack://@circuitwall/jarela/./lib/tools/outlook.ts","webpack://@circuitwall/jarela/./lib/tools/outlook-calendar.ts","webpack://@circuitwall/jarela/./lib/tools/builtins.ts","webpack://@circuitwall/jarela/./lib/stores/mcp-servers.ts","webpack://@circuitwall/jarela/./lib/mcp/client.ts","webpack://@circuitwall/jarela/./lib/stores/tool-secrets.ts","webpack://@circuitwall/jarela/./lib/tools/external.ts","webpack://@circuitwall/jarela/./lib/stores/builtin-tools.ts","webpack://@circuitwall/jarela/./lib/tools/index.ts","webpack://@circuitwall/jarela/./lib/stores/agent-configs.ts","webpack://@circuitwall/jarela/./lib/utils/text.ts","webpack://@circuitwall/jarela/./lib/tools/atlassian.ts","webpack://@circuitwall/jarela/./lib/stores/reaction-shared.ts","webpack://@circuitwall/jarela/./lib/documents/chunker.ts","webpack://@circuitwall/jarela/./lib/documents/indexer.ts","webpack://@circuitwall/jarela/./lib/triggers/registry.ts","webpack://@circuitwall/jarela/./lib/agents/stream-collector.ts","webpack://@circuitwall/jarela/./lib/triggers/runner.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/scheduled-task.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/watcher.ts","webpack://@circuitwall/jarela/./lib/documents/reindex-local-file.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/fs-watch.ts","webpack://@circuitwall/jarela/./lib/triggers/handlers/document-fast-sweep.ts","webpack://@circuitwall/jarela/./lib/triggers/reactions/notify.ts","webpack://@circuitwall/jarela/./lib/triggers/index.ts","webpack://@circuitwall/jarela/./lib/utils/html.ts","webpack://@circuitwall/jarela/./lib/triggers/scripts.ts"],"sourcesContent":["import { BaseChatModel, type BaseChatModelCallOptions } from \"@langchain/core/language_models/chat_models\";\nimport {\n AIMessage,\n AIMessageChunk,\n type BaseMessage,\n isAIMessage,\n isHumanMessage,\n isSystemMessage,\n isToolMessage,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatGeneration, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { convertToOpenAITool } from \"@langchain/core/utils/function_calling\";\nimport type { Runnable } from \"@langchain/core/runnables\";\nimport type { ModelProvider, ProviderParams } from \"@/lib/providers/types\";\nimport type { ContentPart, InvokeMessage, OpenAITool, ToolParamSchema } from \"@/lib/tools/types\";\n\ninterface Fields {\n provider: ModelProvider;\n modelId: string;\n params: ProviderParams;\n boundTools?: StructuredToolInterface[];\n}\n\nexport class JarelaChatModel extends BaseChatModel {\n lc_namespace = [\"jarela\", \"chat_models\"];\n lc_serializable = false;\n\n private _provider: ModelProvider;\n private _modelId: string;\n private _params: ProviderParams;\n private _boundTools: StructuredToolInterface[];\n\n constructor(fields: Fields) {\n super({});\n this._provider = fields.provider;\n this._modelId = fields.modelId;\n this._params = fields.params;\n this._boundTools = fields.boundTools ?? [];\n }\n\n _llmType(): string {\n return `jarela_${this._provider?.name ?? \"chat\"}`;\n }\n\n // createReactAgent calls bindTools() to attach the tool list before streaming.\n bindTools(tools: StructuredToolInterface[], _kwargs?: Partial<BaseChatModelCallOptions>): Runnable {\n return new JarelaChatModel({\n provider: this._provider,\n modelId: this._modelId,\n params: this._params,\n boundTools: tools,\n });\n }\n\n private _convertedTools(): OpenAITool[] {\n return this._boundTools.flatMap((t) => {\n try {\n const oai = convertToOpenAITool(t) as { function?: { name?: string; description?: string; parameters: unknown } };\n if (!oai?.function?.name) return [];\n return [{\n type: \"function\" as const,\n function: {\n name: oai.function.name,\n description: oai.function.description ?? \"\",\n parameters: oai.function.parameters as ToolParamSchema,\n },\n }];\n } catch {\n return [];\n }\n });\n }\n\n async _generate(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun,\n ): Promise<ChatResult> {\n const invokeMessages = toInvokeMessages(messages);\n const openaiTools = this._convertedTools();\n\n // Streaming path — assemble chunks into a final message.\n if (this._provider.streamInvoke && openaiTools.length > 0) {\n const finalChunk = await this._streamToFinalChunk(invokeMessages, openaiTools, runManager);\n const gen: ChatGeneration = {\n message: aiMessageFromChunk(finalChunk.message as AIMessageChunk),\n text: typeof finalChunk.message.content === \"string\" ? finalChunk.message.content : \"\",\n };\n return { generations: [gen] };\n }\n\n if (this._provider.invoke && openaiTools.length > 0) {\n const result = await this._provider.invoke(this._modelId, invokeMessages, this._params, openaiTools);\n const aiMsg = new AIMessage({\n content: result.text ?? \"\",\n tool_calls: result.tool_calls.map((tc) => ({\n id: tc.id,\n name: tc.name,\n args: tc.arguments,\n type: \"tool_call\" as const,\n })),\n });\n const gen: ChatGeneration = { message: aiMsg, text: result.text ?? \"\" };\n return { generations: [gen] };\n }\n\n const providerMessages = invokeMessages\n .filter((m) => m.role !== \"tool\")\n .map((m) => ({ role: m.role as \"user\" | \"assistant\" | \"system\", content: m.content }));\n const { stream } = await this._provider.chat(this._modelId, providerMessages, this._params);\n let text = \"\";\n for await (const chunk of stream) { text += chunk; }\n const gen: ChatGeneration = { message: new AIMessage(text), text };\n return { generations: [gen] };\n }\n\n private async _streamToFinalChunk(\n invokeMessages: InvokeMessage[],\n openaiTools: OpenAITool[],\n runManager?: CallbackManagerForLLMRun,\n ): Promise<ChatGenerationChunk> {\n let acc: ChatGenerationChunk | null = null;\n for await (const chunk of this._streamFromProvider(invokeMessages, openaiTools, runManager)) {\n acc = acc ? acc.concat(chunk) : chunk;\n }\n return acc ?? new ChatGenerationChunk({ message: new AIMessageChunk({ content: \"\" }), text: \"\" });\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun,\n ): AsyncGenerator<ChatGenerationChunk> {\n const invokeMessages = toInvokeMessages(messages);\n const openaiTools = this._convertedTools();\n\n if (!this._provider.streamInvoke) {\n const result = await this._generate(messages, _options, runManager);\n const msg = result.generations[0].message as AIMessage;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: msg.content,\n tool_call_chunks: msg.tool_calls?.map((tc, i) => ({\n index: i,\n id: tc.id,\n name: tc.name,\n args: JSON.stringify(tc.args),\n type: \"tool_call_chunk\" as const,\n })) ?? [],\n }),\n text: typeof msg.content === \"string\" ? msg.content : \"\",\n });\n return;\n }\n\n yield* this._streamFromProvider(invokeMessages, openaiTools, runManager);\n }\n\n private async *_streamFromProvider(\n invokeMessages: InvokeMessage[],\n openaiTools: OpenAITool[],\n runManager?: CallbackManagerForLLMRun,\n ): AsyncGenerator<ChatGenerationChunk> {\n if (!this._provider.streamInvoke) return;\n let emittedAny = false;\n let stopReason: \"stop\" | \"tool_use\" | \"length\" | undefined;\n for await (const event of this._provider.streamInvoke(this._modelId, invokeMessages, this._params, openaiTools)) {\n if (event.type === \"text\") {\n emittedAny = true;\n await runManager?.handleLLMNewToken(event.delta);\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({ content: event.delta }),\n text: event.delta,\n });\n } else if (event.type === \"thinking\") {\n emittedAny = true;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n additional_kwargs: { reasoning_content: event.delta },\n }),\n text: \"\",\n });\n } else if (event.type === \"tool_call_chunk\") {\n emittedAny = true;\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n tool_call_chunks: [{\n index: event.index,\n id: event.id,\n name: event.name,\n args: event.args_delta,\n type: \"tool_call_chunk\" as const,\n }],\n }),\n text: \"\",\n });\n } else if (event.type === \"stop\") {\n stopReason = event.reason;\n }\n }\n // Provider ended the stream without emitting any text, thinking, or tool\n // call chunks. Without this guard, LangChain's BaseChatModel consumer sees\n // zero ChatGenerationChunks and throws \"Received empty response from chat\n // model call.\" — opaque to users. Translate the underlying stop reason\n // into something actionable.\n if (!emittedAny) {\n if (stopReason === \"length\") {\n throw new Error(\n \"Model returned no content before hitting max_tokens. \" +\n \"Reasoning likely consumed the entire token budget — raise max_tokens \" +\n \"(or the thinking budget) in the model config and retry.\",\n );\n }\n // stopReason \"stop\" with no content can mean a content-filter refusal\n // (OpenAI/Azure map content_filter -> \"stop\" in our type), or a model\n // that legitimately decided to emit nothing on this turn. Yield one\n // empty chunk so LangChain has something to aggregate; the agent loop\n // will record an empty AIMessage and the UI will fall through to `done`.\n console.warn(\n `[jarela-chat-model] Provider ${this._provider.name} ended stream with no content (stopReason=${stopReason ?? \"<none>\"}).`,\n );\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n additional_kwargs: stopReason ? { empty_stream_reason: stopReason } : {},\n }),\n text: \"\",\n });\n return;\n }\n // Mid-stream truncation: provider produced content then stopped because of\n // max_tokens (or a length-equivalent). The aggregated message is partial\n // (e.g. a table cut off mid-row). Tag the final chunk with stop_reason so\n // the agent layer can surface a \"your output was truncated\" warning to\n // the user — otherwise they see a cut-off response with no explanation.\n if (stopReason === \"length\") {\n yield new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: \"\",\n additional_kwargs: { stop_reason: \"length\" },\n }),\n text: \"\",\n });\n }\n }\n}\n\nfunction aiMessageFromChunk(chunk: AIMessageChunk): AIMessage {\n return new AIMessage({\n content: chunk.content,\n tool_calls: chunk.tool_calls,\n invalid_tool_calls: chunk.invalid_tool_calls,\n additional_kwargs: chunk.additional_kwargs,\n });\n}\n\n// LangChain's BaseMessage.content can be a string or a content-block array\n// (text, image_url, etc. — used for multi-modal input). Preserve it through\n// to InvokeMessage so the provider routes can translate properly. Stringifying\n// destroys image attachments — `String([{...}, {...}])` becomes \"[object Object],...\"\nfunction lcContentToInvoke(content: BaseMessage[\"content\"]): string | ContentPart[] {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n const parts: ContentPart[] = [];\n for (const block of content) {\n if (typeof block === \"string\") {\n parts.push({ type: \"text\", text: block });\n continue;\n }\n if (!block || typeof block !== \"object\") continue;\n const b = block as Record<string, unknown>;\n if (b.type === \"text\" && typeof b.text === \"string\") {\n parts.push({ type: \"text\", text: b.text });\n } else if (b.type === \"image_url\") {\n // OpenAI-style: { type: \"image_url\", image_url: { url: \"data:image/png;base64,...\" } }\n const url = (b.image_url as { url?: string } | string | undefined);\n const dataUrl = typeof url === \"string\" ? url : url?.url;\n if (dataUrl?.startsWith(\"data:\")) {\n const m = /^data:([^;]+);base64,(.+)$/.exec(dataUrl);\n if (m) parts.push({ type: \"image\", media_type: m[1], data: m[2] });\n }\n } else if (b.type === \"image\") {\n // Anthropic-style: { type: \"image\", source: { type: \"base64\", media_type, data } }\n const src = b.source as { media_type?: string; data?: string } | undefined;\n if (src?.media_type && src.data) {\n parts.push({ type: \"image\", media_type: src.media_type, data: src.data });\n }\n }\n }\n // If we ended up with only text blocks, collapse to a string so providers\n // that don't need multi-modal handling don't have to special-case.\n if (parts.every((p) => p.type === \"text\")) {\n return parts.map((p) => (p as { text: string }).text).join(\"\\n\");\n }\n return parts;\n}\n\nfunction toInvokeMessages(messages: BaseMessage[]): InvokeMessage[] {\n return messages.map((m): InvokeMessage => {\n if (isHumanMessage(m)) {\n return { role: \"user\", content: lcContentToInvoke(m.content) };\n }\n if (isSystemMessage(m)) {\n return { role: \"system\", content: lcContentToInvoke(m.content) };\n }\n if (isAIMessage(m)) {\n const ai = m as AIMessage;\n const invokeMsg: InvokeMessage = {\n role: \"assistant\",\n content: typeof m.content === \"string\" ? m.content : lcContentToInvoke(m.content),\n };\n if (ai.tool_calls?.length) {\n invokeMsg.tool_calls = ai.tool_calls.map((tc) => ({\n id: tc.id ?? \"\",\n type: \"function\" as const,\n function: { name: tc.name, arguments: JSON.stringify(tc.args) },\n }));\n }\n // DeepSeek thinking-mode: propagate the reasoning trace back so the\n // provider can echo it on follow-up turns (required by their API).\n const reasoning = ai.additional_kwargs?.reasoning_content;\n if (typeof reasoning === \"string\" && reasoning) {\n invokeMsg.reasoning_content = reasoning;\n }\n return invokeMsg;\n }\n if (isToolMessage(m)) {\n return {\n role: \"tool\",\n content: typeof m.content === \"string\" ? m.content : lcContentToInvoke(m.content),\n tool_call_id: m.tool_call_id,\n };\n }\n return { role: \"user\", content: lcContentToInvoke(m.content) };\n });\n}\n","import { BaseStore } from \"@langchain/langgraph-checkpoint\";\nimport type { Operation, OperationResults, Item } from \"@langchain/langgraph-checkpoint\";\nimport { getMemory, putMemory, deleteMemory, listMemory } from \"@/lib/stores/memory\";\n\nexport class SqliteMemoryStore extends BaseStore {\n async batch<Op extends Operation[]>(operations: Op): Promise<OperationResults<Op>> {\n const results = await Promise.all(\n operations.map(async (op): Promise<Item | null | Item[] | void> => {\n // GetOperation: { namespace, key } — no \"value\" or \"namespacePrefix\"\n if (\"key\" in op && \"namespace\" in op && !(\"value\" in op) && !(\"namespacePrefix\" in op)) {\n const ns = op.namespace.join(\"/\");\n const row = getMemory(ns, op.key);\n if (!row) return null;\n let value: Record<string, unknown>;\n try {\n value = JSON.parse(row.value) as Record<string, unknown>;\n } catch {\n value = { _raw: row.value };\n }\n return {\n namespace: op.namespace,\n key: op.key,\n value,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n };\n }\n\n // PutOperation: { namespace, key, value }\n if (\"value\" in op && \"namespace\" in op && \"key\" in op) {\n const ns = op.namespace.join(\"/\");\n if (op.value === null) {\n deleteMemory(ns, op.key);\n } else {\n putMemory(ns, op.key, op.value);\n }\n return undefined;\n }\n\n // SearchOperation: { namespacePrefix, ... }\n if (\"namespacePrefix\" in op) {\n const prefix = (op.namespacePrefix as string[]).join(\"/\");\n const limit = \"limit\" in op && typeof op.limit === \"number\" ? op.limit : 10;\n const rows = listMemory(prefix || undefined, undefined, limit);\n return rows.map((r) => {\n let value: Record<string, unknown>;\n try {\n value = JSON.parse(r.value) as Record<string, unknown>;\n } catch {\n value = { _raw: r.value };\n }\n return {\n namespace: r.namespace.split(\"/\"),\n key: r.key,\n value,\n createdAt: new Date(r.created_at),\n updatedAt: new Date(r.updated_at),\n };\n });\n }\n\n return undefined;\n }),\n );\n return results as unknown as OperationResults<Op>;\n }\n}\n","import { DatabaseSync, type StatementSync } from \"node:sqlite\";\nimport { type RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n BaseCheckpointSaver,\n TASKS,\n copyCheckpoint,\n maxChannelVersion,\n type Checkpoint,\n type CheckpointListOptions,\n type CheckpointMetadata,\n type CheckpointTuple,\n type PendingWrite,\n type SerializerProtocol,\n} from \"@langchain/langgraph-checkpoint\";\n\n// In-tree LangGraph checkpoint saver backed by node:sqlite.\n//\n// Schema-compatible drop-in replacement for SqliteSaver from\n// @langchain/langgraph-checkpoint-sqlite. The DDL is byte-identical so an\n// existing checkpoints.db keeps working without migration.\n\nconst VALID_FILTER_KEYS: readonly string[] = [\"source\", \"step\", \"parents\"];\n\ntype Row = Record<string, unknown>;\n\nfunction buildLatestSelect(includeCheckpointId: boolean): string {\n return `\n SELECT\n thread_id,\n checkpoint_ns,\n checkpoint_id,\n parent_checkpoint_id,\n type,\n checkpoint,\n metadata,\n (\n SELECT\n json_group_array(\n json_object(\n 'task_id', pw.task_id,\n 'channel', pw.channel,\n 'type', pw.type,\n 'value', CAST(pw.value AS TEXT)\n )\n )\n FROM writes as pw\n WHERE pw.thread_id = checkpoints.thread_id\n AND pw.checkpoint_ns = checkpoints.checkpoint_ns\n AND pw.checkpoint_id = checkpoints.checkpoint_id\n ) as pending_writes,\n (\n SELECT\n json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n )\n FROM writes as ps\n WHERE ps.thread_id = checkpoints.thread_id\n AND ps.checkpoint_ns = checkpoints.checkpoint_ns\n AND ps.checkpoint_id = checkpoints.parent_checkpoint_id\n AND ps.channel = '${TASKS}'\n ORDER BY ps.idx\n ) as pending_sends\n FROM checkpoints\n WHERE thread_id = ? AND checkpoint_ns = ? ${\n includeCheckpointId\n ? \"AND checkpoint_id = ?\"\n : \"ORDER BY checkpoint_id DESC LIMIT 1\"\n }`;\n}\n\n// node:sqlite rejects `undefined` parameter binds; coerce to null.\nfunction nv<T>(v: T | undefined | null): T | null {\n return v === undefined ? null : (v as T | null);\n}\n\nexport class NodeSqliteSaver extends BaseCheckpointSaver {\n db: DatabaseSync;\n\n protected isSetup = false;\n protected withoutCheckpoint!: StatementSync;\n protected withCheckpoint!: StatementSync;\n\n constructor(db: DatabaseSync, serde?: SerializerProtocol) {\n super(serde);\n this.db = db;\n }\n\n static fromConnString(connStringOrLocalPath: string): NodeSqliteSaver {\n return new NodeSqliteSaver(new DatabaseSync(connStringOrLocalPath));\n }\n\n protected setup(): void {\n if (this.isSetup) return;\n this.db.exec(\"PRAGMA journal_mode=WAL\");\n this.db.exec(`\nCREATE TABLE IF NOT EXISTS checkpoints (\n thread_id TEXT NOT NULL,\n checkpoint_ns TEXT NOT NULL DEFAULT '',\n checkpoint_id TEXT NOT NULL,\n parent_checkpoint_id TEXT,\n type TEXT,\n checkpoint BLOB,\n metadata BLOB,\n PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id)\n);`);\n this.db.exec(`\nCREATE TABLE IF NOT EXISTS writes (\n thread_id TEXT NOT NULL,\n checkpoint_ns TEXT NOT NULL DEFAULT '',\n checkpoint_id TEXT NOT NULL,\n task_id TEXT NOT NULL,\n idx INTEGER NOT NULL,\n channel TEXT NOT NULL,\n type TEXT,\n value BLOB,\n PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id, task_id, idx)\n);`);\n this.withoutCheckpoint = this.db.prepare(buildLatestSelect(false));\n this.withCheckpoint = this.db.prepare(buildLatestSelect(true));\n this.isSetup = true;\n }\n\n protected txn<T>(fn: () => T): T {\n this.db.exec(\"BEGIN\");\n try {\n const result = fn();\n this.db.exec(\"COMMIT\");\n return result;\n } catch (err) {\n try {\n this.db.exec(\"ROLLBACK\");\n } catch {\n // ignore rollback failure; surface the original error\n }\n throw err;\n }\n }\n\n private async decodeRowState(row: Row): Promise<{\n pendingWrites: [string, string, unknown][];\n checkpoint: Checkpoint;\n metadata: CheckpointMetadata;\n }> {\n const pendingWrites = await Promise.all(\n JSON.parse(String(row.pending_writes ?? \"[]\")).map(\n async (write: { task_id: string; channel: string; type?: string; value?: string }) => {\n return [\n write.task_id,\n write.channel,\n await this.serde.loadsTyped(write.type ?? \"json\", write.value ?? \"\"),\n ] as [string, string, unknown];\n },\n ),\n );\n\n const checkpoint = (await this.serde.loadsTyped(\n (row.type as string | null) ?? \"json\",\n row.checkpoint as Uint8Array | string,\n )) as Checkpoint;\n\n if (checkpoint.v < 4 && row.parent_checkpoint_id != null) {\n await this.migratePendingSends(\n checkpoint,\n row.thread_id as string,\n row.parent_checkpoint_id as string,\n );\n }\n\n const metadata = (await this.serde.loadsTyped(\n (row.type as string | null) ?? \"json\",\n row.metadata as Uint8Array | string,\n )) as CheckpointMetadata;\n\n return { pendingWrites, checkpoint, metadata };\n }\n\n async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {\n this.setup();\n const { thread_id, checkpoint_ns = \"\", checkpoint_id } =\n config.configurable ?? {};\n const args: unknown[] = [nv(thread_id), checkpoint_ns];\n if (checkpoint_id) args.push(checkpoint_id);\n const stmt = checkpoint_id ? this.withCheckpoint : this.withoutCheckpoint;\n const row = stmt.get(...(args as never[])) as Row | undefined;\n if (row === undefined) return undefined;\n\n let finalConfig = config;\n if (!checkpoint_id) {\n finalConfig = {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns,\n checkpoint_id: row.checkpoint_id,\n },\n };\n }\n if (\n finalConfig.configurable?.thread_id === undefined ||\n finalConfig.configurable?.checkpoint_id === undefined\n ) {\n throw new Error(\"Missing thread_id or checkpoint_id\");\n }\n\n const { pendingWrites, checkpoint, metadata } = await this.decodeRowState(row);\n\n return {\n checkpoint,\n config: finalConfig,\n metadata,\n parentConfig: row.parent_checkpoint_id\n ? {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns,\n checkpoint_id: row.parent_checkpoint_id,\n },\n }\n : undefined,\n pendingWrites,\n };\n }\n\n async *list(\n config: RunnableConfig,\n options?: CheckpointListOptions,\n ): AsyncGenerator<CheckpointTuple> {\n const { limit, before, filter } = options ?? {};\n this.setup();\n const thread_id = config.configurable?.thread_id;\n const checkpoint_ns = config.configurable?.checkpoint_ns;\n\n let sql = `\n SELECT\n thread_id,\n checkpoint_ns,\n checkpoint_id,\n parent_checkpoint_id,\n type,\n checkpoint,\n metadata,\n (\n SELECT\n json_group_array(\n json_object(\n 'task_id', pw.task_id,\n 'channel', pw.channel,\n 'type', pw.type,\n 'value', CAST(pw.value AS TEXT)\n )\n )\n FROM writes as pw\n WHERE pw.thread_id = checkpoints.thread_id\n AND pw.checkpoint_ns = checkpoints.checkpoint_ns\n AND pw.checkpoint_id = checkpoints.checkpoint_id\n ) as pending_writes,\n (\n SELECT\n json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n )\n FROM writes as ps\n WHERE ps.thread_id = checkpoints.thread_id\n AND ps.checkpoint_ns = checkpoints.checkpoint_ns\n AND ps.checkpoint_id = checkpoints.parent_checkpoint_id\n AND ps.channel = '${TASKS}'\n ORDER BY ps.idx\n ) as pending_sends\n FROM checkpoints\\n`;\n\n const whereClause: string[] = [];\n if (thread_id) whereClause.push(\"thread_id = ?\");\n if (checkpoint_ns !== undefined && checkpoint_ns !== null) {\n whereClause.push(\"checkpoint_ns = ?\");\n }\n if (before?.configurable?.checkpoint_id !== undefined) {\n whereClause.push(\"checkpoint_id < ?\");\n }\n\n const sanitizedFilter = Object.fromEntries(\n Object.entries(filter ?? {}).filter(\n ([key, value]) => value !== undefined && VALID_FILTER_KEYS.includes(key),\n ),\n );\n whereClause.push(\n ...Object.entries(sanitizedFilter).map(\n ([key]) => `jsonb(CAST(metadata AS TEXT))->'$.${key}' = ?`,\n ),\n );\n if (whereClause.length > 0) sql += `WHERE\\n ${whereClause.join(\" AND\\n \")}\\n`;\n sql += \"\\nORDER BY checkpoint_id DESC\";\n if (limit) sql += ` LIMIT ${parseInt(String(limit), 10)}`;\n\n const args: unknown[] = [\n thread_id,\n checkpoint_ns,\n before?.configurable?.checkpoint_id,\n ...Object.values(sanitizedFilter).map((value) => JSON.stringify(value)),\n ].filter((value) => value !== undefined && value !== null);\n\n const rows = this.db.prepare(sql).all(...(args as never[])) as Row[];\n for (const row of rows) {\n const { pendingWrites, checkpoint, metadata } = await this.decodeRowState(row);\n yield {\n config: {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns: row.checkpoint_ns,\n checkpoint_id: row.checkpoint_id,\n },\n },\n checkpoint,\n metadata,\n parentConfig: row.parent_checkpoint_id\n ? {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns: row.checkpoint_ns,\n checkpoint_id: row.parent_checkpoint_id,\n },\n }\n : undefined,\n pendingWrites,\n };\n }\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata,\n ): Promise<RunnableConfig> {\n this.setup();\n if (!config.configurable) throw new Error(\"Empty configuration supplied.\");\n const thread_id = config.configurable?.thread_id as string | undefined;\n const checkpoint_ns = (config.configurable?.checkpoint_ns ?? \"\") as string;\n const parent_checkpoint_id = config.configurable?.checkpoint_id as\n | string\n | undefined;\n if (!thread_id) {\n throw new Error(`Missing \"thread_id\" field in passed \"config.configurable\".`);\n }\n const preparedCheckpoint = copyCheckpoint(checkpoint);\n const [\n [type1, serializedCheckpoint],\n [type2, serializedMetadata],\n ] = await Promise.all([\n this.serde.dumpsTyped(preparedCheckpoint),\n this.serde.dumpsTyped(metadata),\n ]);\n if (type1 !== type2) {\n throw new Error(\n \"Failed to serialized checkpoint and metadata to the same type.\",\n );\n }\n this.db\n .prepare(\n `INSERT OR REPLACE INTO checkpoints (thread_id, checkpoint_ns, checkpoint_id, parent_checkpoint_id, type, checkpoint, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n thread_id,\n checkpoint_ns,\n checkpoint.id,\n nv(parent_checkpoint_id),\n type1,\n serializedCheckpoint as never,\n serializedMetadata as never,\n );\n return {\n configurable: {\n thread_id,\n checkpoint_ns,\n checkpoint_id: checkpoint.id,\n },\n };\n }\n\n async putWrites(\n config: RunnableConfig,\n writes: PendingWrite[],\n taskId: string,\n ): Promise<void> {\n this.setup();\n if (!config.configurable) throw new Error(\"Empty configuration supplied.\");\n if (!config.configurable?.thread_id) {\n throw new Error(\"Missing thread_id field in config.configurable.\");\n }\n if (!config.configurable?.checkpoint_id) {\n throw new Error(\"Missing checkpoint_id field in config.configurable.\");\n }\n const stmt = this.db.prepare(`\n INSERT OR REPLACE INTO writes\n (thread_id, checkpoint_ns, checkpoint_id, task_id, idx, channel, type, value)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `);\n const rows = await Promise.all(\n writes.map(async (write, idx) => {\n const [type, serializedWrite] = await this.serde.dumpsTyped(write[1]);\n return [\n config.configurable?.thread_id as string,\n (config.configurable?.checkpoint_ns ?? \"\") as string,\n config.configurable?.checkpoint_id as string,\n taskId,\n idx,\n write[0],\n type,\n serializedWrite,\n ] as const;\n }),\n );\n this.txn(() => {\n for (const row of rows) stmt.run(...(row as unknown as never[]));\n });\n }\n\n async deleteThread(threadId: string): Promise<void> {\n this.setup();\n this.txn(() => {\n this.db\n .prepare(`DELETE FROM checkpoints WHERE thread_id = ?`)\n .run(threadId);\n this.db.prepare(`DELETE FROM writes WHERE thread_id = ?`).run(threadId);\n });\n }\n\n protected async migratePendingSends(\n checkpoint: Checkpoint,\n threadId: string,\n parentCheckpointId: string,\n ): Promise<void> {\n const row = this.db\n .prepare(\n `\n SELECT\n checkpoint_id,\n json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n ) as pending_sends\n FROM writes as ps\n WHERE ps.thread_id = ?\n AND ps.checkpoint_id = ?\n AND ps.channel = '${TASKS}'\n ORDER BY ps.idx\n `,\n )\n .get(threadId, parentCheckpointId) as Row | undefined;\n const pendingSendsJson = String(row?.pending_sends ?? \"[]\");\n const mutable = checkpoint as Checkpoint & {\n channel_values?: Record<string, unknown>;\n channel_versions: Record<string, unknown>;\n };\n mutable.channel_values ??= {};\n mutable.channel_values[TASKS] = await Promise.all(\n JSON.parse(pendingSendsJson).map(\n ({ type, value }: { type?: string; value?: string }) =>\n this.serde.loadsTyped(type ?? \"json\", value ?? \"\"),\n ),\n );\n mutable.channel_versions[TASKS] =\n Object.keys(checkpoint.channel_versions).length > 0\n ? maxChannelVersion(...Object.values(checkpoint.channel_versions))\n : this.getNextVersion(undefined);\n }\n}\n","import { join } from \"node:path\";\nimport { getDataDir } from \"@/lib/db/data-dir\";\nimport { NodeSqliteSaver } from \"./sqlite-checkpoint-saver\";\n\n// Persistent graph state per thread_id. Multi-step plans, scratchpad messages,\n// and any pending tool-call sequence survive process restarts and resume on\n// the next agent.stream() with the same thread_id.\n//\n// Stored in a separate DB file (~/.jarela/checkpoints.db) so LangGraph\n// manages its own schema independently of our own migrations under\n// lib/db/. Both files use WAL mode via the same node:sqlite driver.\n\nconst CHECKPOINT_PATH = join(getDataDir(), \"checkpoints.db\");\n\nlet _saver: NodeSqliteSaver | null = null;\n\nexport function getCheckpointer(): NodeSqliteSaver {\n if (!_saver) {\n _saver = NodeSqliteSaver.fromConnString(CHECKPOINT_PATH);\n }\n return _saver;\n}\n","import { createReactAgent } from \"@langchain/langgraph/prebuilt\";\nimport {\n AIMessage,\n AIMessageChunk,\n HumanMessage,\n SystemMessage,\n ToolMessage,\n} from \"@langchain/core/messages\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport { getProvider } from \"@/lib/providers\";\nimport { getModelConfig, getDefaultModelConfig } from \"@/lib/stores/model-config\";\nimport { getAllToolsAsync } from \"@/lib/tools\";\nimport { JarelaChatModel } from \"@/lib/providers/jarela-chat-model\";\nimport { SqliteMemoryStore } from \"@/lib/stores/langgraph-store\";\nimport { getCheckpointer } from \"@/lib/agents/checkpointer\";\nimport type { ContentPart } from \"@/lib/tools/types\";\nimport type { StreamChunk, StreamOptions } from \"./base\";\nimport type { ProviderParams } from \"@/lib/providers/types\";\nimport { getConfig } from \"@/lib/env/config\";\n\nfunction toBaseMessages(\n messages: Array<{ role: \"user\" | \"assistant\"; content: string | ContentPart[] }>,\n systemPrompt?: string,\n): BaseMessage[] {\n const base: BaseMessage[] = systemPrompt ? [new SystemMessage(systemPrompt)] : [];\n return [\n ...base,\n ...messages.map((m) => {\n // Plain text path — fast & most common.\n if (typeof m.content === \"string\") {\n return m.role === \"user\" ? new HumanMessage(m.content) : new AIMessage(m.content);\n }\n // Multi-modal path — translate our ContentPart[] into LangChain's\n // standard content-block array. Images become OpenAI-style\n // `image_url` blocks (the LangChain idiom that all major providers\n // accept on input). File attachments fall back to text so they\n // still reach text-only models. Assistant messages currently never\n // contain attachments in our flow, so we just flatten to text.\n if (m.role === \"assistant\") {\n const text = m.content\n .filter((p): p is ContentPart & { type: \"text\" } => p.type === \"text\")\n .map((p) => p.text).join(\"\\n\");\n return new AIMessage(text);\n }\n const blocks: Array<Record<string, unknown>> = [];\n for (const part of m.content) {\n if (part.type === \"text\") {\n if (part.text) blocks.push({ type: \"text\", text: part.text });\n } else if (part.type === \"image\") {\n blocks.push({\n type: \"image_url\",\n image_url: { url: `data:${part.media_type};base64,${part.data}` },\n });\n } else if (part.type === \"file\") {\n if (part.media_type.startsWith(\"text/\") || part.media_type === \"application/json\") {\n blocks.push({ type: \"text\", text: `[Attached file: ${part.name}]\\n${part.data}` });\n } else {\n blocks.push({ type: \"text\", text: `[Attached file: ${part.name} (${part.media_type})]` });\n }\n }\n }\n // Cast through unknown — LangChain's strict block-union type rejects our\n // dynamic shape, but at runtime BaseMessage stores content as-is and\n // ChatModels consume whatever the provider's API expects (image_url for\n // OpenAI, image for Anthropic, etc.).\n return new HumanMessage({ content: blocks as unknown as string });\n }),\n ];\n}\n\nexport async function* streamWithConfig(\n threadId: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string | ContentPart[] }>,\n options?: StreamOptions,\n signal?: AbortSignal,\n): AsyncIterable<StreamChunk> {\n const runCfg = options?.agent_run_config;\n\n const cfgName = runCfg?.model_config_name ?? null;\n const cfg = cfgName ? getModelConfig(cfgName) : getDefaultModelConfig();\n\n if (!cfg) {\n yield { type: \"error\", data: { message: \"No model configured. Add a model in the Models panel.\", code: \"no_model\" } };\n return;\n }\n\n let params: ProviderParams;\n try {\n params = JSON.parse(cfg.params) as ProviderParams;\n } catch {\n yield { type: \"error\", data: { message: `Model config \"${cfg.name}\" has invalid JSON params.`, code: \"config_parse_error\" } };\n return;\n }\n\n const provider = getProvider(cfg.provider);\n\n const toolPolicy = runCfg?.allowed_tools?.length\n ? { allow: runCfg.allowed_tools }\n : options?.tool_policy;\n const tools = await getAllToolsAsync(toolPolicy);\n\n const model = new JarelaChatModel({ provider, modelId: cfg.model_id, params });\n const store = new SqliteMemoryStore();\n const checkpointer = getCheckpointer();\n\n // Wipe prior checkpoint state for this thread BEFORE invoking the agent.\n // Every turn we rebuild the message history from jarela.db.messages (the\n // source of truth), so the checkpointer's only job is to buffer in-flight\n // tool-call state within the current turn. Without this delete, LangGraph's\n // default messages-state reducer keeps appending — every prior turn's tool\n // results (plus any inline image data URIs) stay in state forever and get\n // replayed to the LLM, eventually blowing past the model's context window.\n // See: thread fb35423b grew to 893 MB / 238 checkpoints because a single\n // image-attached HumanMessage (~1.2 MB base64) was replayed on every retry.\n try {\n await checkpointer.deleteThread(threadId);\n } catch (err) {\n // SqliteSaver creates the `checkpoints` table lazily on first write.\n // If we get here before any checkpoint has ever been persisted (fresh\n // DB, first turn of the process), deleteThread raises\n // `SQLITE_ERROR: no such table: checkpoints` — which is a no-op for us,\n // not an error. Swallow it; surface anything else.\n const msg = err instanceof Error ? err.message : String(err);\n if (!/no such table:\\s*checkpoints/i.test(msg)) {\n console.error(\"[llm] checkpoint reset failed for thread\", threadId, err);\n }\n }\n\n const agent = createReactAgent({ llm: model, tools, store, checkpointer });\n\n // Track which AIMessageChunk-tool-call-chunks we've already announced (by id).\n // We emit a tool_call event once per id when both id+name are known and\n // the assistant turn ends, so callers see structured tool calls (not partial ones).\n const announcedToolIds = new Set<string>();\n let pendingAIChunk: AIMessageChunk | null = null;\n let totalOutputTokens = 0;\n // Tracks whether the model hit max_tokens mid-stream. JarelaChatModel tags\n // the final chunk with additional_kwargs.stop_reason=\"length\" when this\n // happens; we surface a non-fatal warning before `done` so the user knows\n // their (visibly truncated) response was cut off — and can ask to continue.\n let truncatedByLength = false;\n // Tracks whether the previous emitted chunk was a tool result. When the next\n // AI message starts producing text, we prepend a paragraph break so the\n // pre-tool plan acknowledgment and the post-tool reply don't visually merge.\n let needsParagraphBreak = false;\n let textEmittedSinceLastBreak = false;\n\n const flushPendingToolCalls = function* (): Iterable<StreamChunk> {\n if (!pendingAIChunk) return;\n const calls = pendingAIChunk.tool_calls ?? [];\n for (const tc of calls) {\n if (!tc.id || announcedToolIds.has(tc.id)) continue;\n announcedToolIds.add(tc.id);\n yield { type: \"tool_call\", data: { id: tc.id, name: tc.name ?? \"\", arguments: tc.args ?? {} } };\n }\n pendingAIChunk = null;\n };\n\n try {\n const agentStream = await agent.stream(\n { messages: toBaseMessages(messages, runCfg?.system_prompt) },\n {\n streamMode: [\"messages\", \"updates\"],\n configurable: { thread_id: threadId },\n // LangGraph counts EACH node visit (model call + each tool call) as a\n // step. File-organization, multi-search-and-fetch, and any task that\n // pairs every action with a verify call (file_move + file_stat, etc.)\n // burns through 50 fast — 25 file moves and you're done. 200 leaves\n // generous headroom for legitimate multi-step work while still\n // bounding obvious runaway loops. Configurable via env per deployment.\n recursionLimit: getConfig().recursionLimit,\n // Cancellation: when the user hits Stop (or the last client\n // disconnects), the route aborts this signal and the LangGraph\n // pregel loop unwinds, throwing a friendly aborted error below.\n signal,\n },\n );\n\n for await (const [mode, payload] of agentStream as AsyncIterable<[string, unknown]>) {\n if (mode === \"messages\") {\n const [chunk] = payload as [BaseMessage, unknown];\n if (chunk instanceof AIMessageChunk) {\n if (typeof chunk.content === \"string\" && chunk.content) {\n // After a tool result, the next AI text starts a new conceptual\n // turn. Insert a paragraph break so the pre-tool plan and the\n // post-tool reply don't visually merge into one run-on sentence.\n let delta = chunk.content;\n if (needsParagraphBreak && textEmittedSinceLastBreak) {\n delta = \"\\n\\n\" + delta;\n }\n needsParagraphBreak = false;\n textEmittedSinceLastBreak = true;\n totalOutputTokens += 1;\n yield { type: \"text_delta\", data: { delta } };\n }\n const reasoning = chunk.additional_kwargs?.reasoning_content;\n if (typeof reasoning === \"string\" && reasoning) {\n yield { type: \"thinking_delta\", data: { delta: reasoning } };\n }\n if (chunk.additional_kwargs?.stop_reason === \"length\") {\n truncatedByLength = true;\n }\n pendingAIChunk = pendingAIChunk ? pendingAIChunk.concat(chunk) : chunk;\n } else if (chunk instanceof ToolMessage) {\n yield* flushPendingToolCalls();\n let result: unknown = chunk.content;\n if (typeof result === \"string\") {\n try { result = JSON.parse(result); } catch { /* keep string */ }\n }\n yield {\n type: \"tool_result\",\n data: { id: chunk.tool_call_id, name: chunk.name ?? \"\", result },\n };\n // Next AI text should be visually separated from the pre-tool prose.\n needsParagraphBreak = true;\n }\n } else if (mode === \"updates\") {\n // End of an agent step — flush any unflushed tool calls (e.g. final assistant message\n // with no follow-up tool execution).\n yield* flushPendingToolCalls();\n }\n }\n\n // Final flush in case stream ended without an \"updates\" tick.\n yield* flushPendingToolCalls();\n } catch (err) {\n const name = err instanceof Error ? err.name : \"\";\n const baseMsg = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error && err.stack ? err.stack : \"\";\n // undici surfaces network failures as a bare \"fetch failed\" with the\n // real reason (ECONNREFUSED, EAI_AGAIN, UND_ERR_SOCKET, cert issues,\n // proxy CONNECT rejects, …) hidden under err.cause. Walk the chain so\n // operators get a useful log line and the UI shows something actionable.\n const causeChain: string[] = [];\n let cur: unknown = err;\n let depth = 0;\n while (cur && typeof cur === \"object\" && \"cause\" in cur && depth < 4) {\n const c = (cur as { cause?: unknown }).cause;\n if (!c) break;\n const cMsg = c instanceof Error ? `${c.name}: ${c.message}` : String(c);\n const cCode = c && typeof c === \"object\" && \"code\" in c ? ` [${(c as { code?: string }).code}]` : \"\";\n causeChain.push(`${cMsg}${cCode}`);\n cur = c;\n depth += 1;\n }\n const rawMsg = causeChain.length > 0\n ? `${baseMsg} (cause: ${causeChain.join(\" → \")})`\n : baseMsg;\n\n // User-initiated abort (Stop button / client disconnect): emit a\n // short error chunk and let the route fall through to `done` so the\n // queued-message drain in the UI fires normally.\n if (signal?.aborted || name === \"AbortError\" || /aborted/i.test(rawMsg)) {\n yield { type: \"error\", data: { message: \"Run interrupted by user.\", code: \"aborted\" } };\n yield {\n type: \"done\",\n data: {\n message_id: `llm-${threadId}-${Date.now()}`,\n usage: { input_tokens: 0, output_tokens: totalOutputTokens },\n aborted: true,\n },\n };\n return;\n }\n\n console.error(\"[agent_error]\", stack || rawMsg);\n\n // Translate LangGraph's recursion limit into a friendly explanation —\n // the raw stack mentions internal Pregel paths users can't act on. They\n // CAN act on knowing the agent loop didn't converge (likely chasing tool\n // results in a loop or a genuinely deep multi-step task).\n let friendly = rawMsg;\n let code = \"agent_error\";\n if (name === \"GraphRecursionError\" || /recursion limit/i.test(rawMsg)) {\n const limit = getConfig().recursionLimit;\n friendly =\n `The agent took too many tool-calling steps without finishing (hit the ${limit}-step limit). ` +\n `If the task is legitimately deep, raise JARELA_RECURSION_LIMIT in the env. ` +\n `If the agent looked stuck in a loop (calling the same tool repeatedly), simplify the prompt or ` +\n `try /new to start fresh — long histories of tool results sometimes make the model re-attempt the same step.`;\n code = \"recursion_limit\";\n } else if (/Received empty response from chat model call/i.test(rawMsg)) {\n // Defense in depth: JarelaChatModel._streamFromProvider already guards\n // against this by emitting a sentinel empty chunk, but if a future\n // provider bypasses that path we still want a useful message instead of\n // the raw LangChain stack.\n friendly =\n \"The model returned an empty response. This usually means a content filter triggered, \" +\n \"max_tokens was too low for a reasoning model, or the connection dropped mid-stream. \" +\n \"Check the model config and retry.\";\n code = \"empty_response\";\n } else if (/max_tokens/i.test(rawMsg) && /no content|before hitting/i.test(rawMsg)) {\n code = \"max_tokens_exhausted\";\n }\n // Pull out the FIRST in-app frame from the stack so the user sees what\n // module triggered it, without dumping the full Pregel/webpack trace.\n const firstAppFrame = stack.split(\"\\n\").find((l) => /\\(rsc\\)\\.\\/lib\\//.test(l));\n const trimmed = firstAppFrame ? `\\n${firstAppFrame.trim()}` : \"\";\n yield { type: \"error\", data: { message: `${friendly}${trimmed}`, code } };\n return;\n }\n\n if (truncatedByLength) {\n yield {\n type: \"error\",\n data: {\n message:\n \"Response truncated — the model hit its max_tokens limit before finishing. \" +\n \"Raise max_tokens in the model config (Anthropic defaults to 4096) and ask me to continue.\",\n code: \"max_tokens_truncated\",\n },\n };\n }\n\n yield {\n type: \"done\",\n data: {\n message_id: `llm-${threadId}-${Date.now()}`,\n usage: { input_tokens: 0, output_tokens: totalOutputTokens },\n },\n };\n}\n","import type { PersistedToolEvent } from \"@/lib/stores/threads\";\nimport { getDb } from \"@/lib/db\";\n\nconst now = () => new Date().toISOString();\n\nexport interface ToolStatsRow {\n tool_name: string;\n call_count: number;\n success_count: number;\n error_count: number;\n used_count: number;\n last_called_at: string | null;\n updated_at: string;\n}\n\nexport interface ToolUsefulnessStats {\n call_count: number;\n success_count: number;\n error_count: number;\n used_count: number;\n success_rate: number;\n usefulness_rate: number;\n score: number;\n never_used: boolean;\n last_called_at: string | null;\n}\n\ninterface ToolUsageDelta {\n name: string;\n calls: number;\n successes: number;\n errors: number;\n used: number;\n}\n\nconst UPSERT_SQL = `\n INSERT INTO tool_stats\n (tool_name, call_count, success_count, error_count, used_count, last_called_at, updated_at)\n VALUES\n (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(tool_name) DO UPDATE SET\n call_count = tool_stats.call_count + excluded.call_count,\n success_count = tool_stats.success_count + excluded.success_count,\n error_count = tool_stats.error_count + excluded.error_count,\n used_count = tool_stats.used_count + excluded.used_count,\n last_called_at = COALESCE(excluded.last_called_at, tool_stats.last_called_at),\n updated_at = excluded.updated_at\n`;\n\nexport function recordToolUsage(\n toolEvents: readonly PersistedToolEvent[],\n assistantContent: string,\n): void {\n const deltas = summarizeToolUsage(toolEvents, assistantContent);\n if (deltas.length === 0) return;\n\n const db = getDb();\n const stamp = now();\n const stmt = db.prepare(UPSERT_SQL);\n db.exec(\"BEGIN\");\n try {\n for (const row of deltas) {\n stmt.run(\n row.name,\n row.calls,\n row.successes,\n row.errors,\n row.used,\n row.calls > 0 ? stamp : null,\n stamp,\n );\n }\n db.exec(\"COMMIT\");\n } catch (err) {\n try { db.exec(\"ROLLBACK\"); } catch { /* ignore rollback failure */ }\n throw err;\n }\n}\n\nexport function listToolStats(): ToolStatsRow[] {\n return getDb()\n .prepare(\n `SELECT tool_name, call_count, success_count, error_count, used_count, last_called_at, updated_at\n FROM tool_stats`,\n )\n .all() as unknown as ToolStatsRow[];\n}\n\nexport function getToolStatsMap(names?: readonly string[]): Map<string, ToolUsefulnessStats> {\n const rows = names && names.length > 0\n ? getDb()\n .prepare(\n `SELECT tool_name, call_count, success_count, error_count, used_count, last_called_at, updated_at\n FROM tool_stats\n WHERE tool_name IN (${names.map(() => \"?\").join(\",\")})`,\n )\n .all(...names) as unknown as ToolStatsRow[]\n : listToolStats();\n\n const out = new Map<string, ToolUsefulnessStats>();\n for (const row of rows) out.set(row.tool_name, toStats(row));\n return out;\n}\n\nexport function defaultToolStats(): ToolUsefulnessStats {\n return {\n call_count: 0,\n success_count: 0,\n error_count: 0,\n used_count: 0,\n success_rate: 1,\n usefulness_rate: 1,\n score: 1,\n never_used: true,\n last_called_at: null,\n };\n}\n\nexport function toStats(row: ToolStatsRow): ToolUsefulnessStats {\n const calls = Math.max(0, row.call_count);\n if (calls === 0) return defaultToolStats();\n\n const successRate = clamp01(row.success_count / calls);\n const usefulnessRate = clamp01(row.used_count / calls);\n const score = clamp01((successRate * 0.65) + (usefulnessRate * 0.35));\n\n return {\n call_count: calls,\n success_count: row.success_count,\n error_count: row.error_count,\n used_count: row.used_count,\n success_rate: successRate,\n usefulness_rate: usefulnessRate,\n score,\n never_used: false,\n last_called_at: row.last_called_at,\n };\n}\n\nexport function summarizeToolUsage(\n toolEvents: readonly PersistedToolEvent[],\n assistantContent: string,\n): ToolUsageDelta[] {\n const byId = new Map<string, { name: string; successful: boolean; used: boolean }>();\n const assistantTerms = normalizeText(assistantContent);\n\n for (const ev of toolEvents) {\n if (!ev.name) continue;\n const key = ev.id || `${ev.phase}:${ev.name}`;\n const existing = byId.get(key) ?? { name: ev.name, successful: false, used: false };\n\n if (ev.phase === \"call\") {\n existing.name = ev.name;\n } else if (ev.phase === \"result\") {\n const successful = !isErrorPayload(ev.payload);\n existing.successful = successful;\n existing.used = successful && payloadLooksUsed(ev.payload, assistantTerms);\n }\n\n byId.set(key, existing);\n }\n\n const totals = new Map<string, ToolUsageDelta>();\n for (const ev of toolEvents) {\n if (ev.phase !== \"call\" || !ev.name) continue;\n const key = ev.id || `${ev.phase}:${ev.name}`;\n const outcome = byId.get(key);\n const next = totals.get(ev.name) ?? {\n name: ev.name,\n calls: 0,\n successes: 0,\n errors: 0,\n used: 0,\n };\n next.calls += 1;\n if (outcome?.successful) next.successes += 1;\n else next.errors += 1;\n if (outcome?.used) next.used += 1;\n totals.set(ev.name, next);\n }\n\n return [...totals.values()];\n}\n\nfunction payloadLooksUsed(payload: unknown, assistantTerms: Set<string>): boolean {\n if (assistantTerms.size === 0) return false;\n const candidates = extractPayloadTerms(payload);\n if (candidates.length === 0) return false;\n\n let matched = 0;\n for (const term of candidates) {\n if (assistantTerms.has(term)) matched += 1;\n if (matched >= 2) return true;\n }\n return false;\n}\n\nfunction extractPayloadTerms(payload: unknown): string[] {\n const raw = stringifyPayload(payload);\n if (!raw) return [];\n const unique = new Set<string>();\n for (const token of raw.toLowerCase().split(/[^a-z0-9_./:-]+/)) {\n if (token.length < 4) continue;\n if (/^\\d+$/.test(token) && token.length < 6) continue;\n unique.add(token);\n if (unique.size >= 24) break;\n }\n return [...unique];\n}\n\nfunction stringifyPayload(payload: unknown): string {\n if (typeof payload === \"string\") return payload;\n try {\n return JSON.stringify(payload);\n } catch {\n return \"\";\n }\n}\n\nfunction normalizeText(text: string): Set<string> {\n const out = new Set<string>();\n for (const token of text.toLowerCase().split(/[^a-z0-9_./:-]+/)) {\n if (token.length < 4) continue;\n out.add(token);\n }\n return out;\n}\n\nfunction isErrorPayload(payload: unknown): boolean {\n if (typeof payload === \"string\") return /\\berror\\b|\\bfailed\\b|\\bexception\\b/i.test(payload);\n if (!payload || typeof payload !== \"object\") return false;\n if (\"error\" in payload || \"errors\" in payload) return true;\n const status = \"status\" in payload ? (payload as { status?: unknown }).status : undefined;\n if (typeof status === \"string\" && /error|failed/i.test(status)) return true;\n return false;\n}\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}","import type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\nimport { MBTI_PRESETS, type MbtiType } from \"@/lib/agents/adaptive-persona-presets\";\n\ninterface SignalSnapshot {\n mood: \"frustrated\" | \"rushed\" | \"positive\" | \"neutral\";\n urgency: number;\n frustration: number;\n positivity: number;\n}\n\n/**\n * Build a compact runtime persona section from per-agent adaptive settings and\n * the current user message. This keeps adaptation deterministic and auditable.\n */\nexport function buildAdaptivePersonaContext(agent: AgentConfigRow, userMessage: string): string {\n if (!agent.adaptive_persona_enabled) return \"\";\n\n const mbti = toMbti(agent.adaptive_mbti) ?? \"INTJ\";\n const mbtiLabel = MBTI_PRESETS[mbti].label;\n\n const strength = clampPercent(agent.adaptive_persona_strength);\n const empathy = clampPercent(agent.adaptive_empathy);\n const expressiveness = clampPercent(agent.adaptive_expressiveness);\n const verbosity = clampPercent(agent.adaptive_verbosity);\n\n const signal = detectSignals(userMessage);\n const intensity = strength / 100;\n\n const targetEmpathy = clampPercent(\n empathy + Math.round((signal.frustration * 30 + signal.urgency * 10 - signal.positivity * 6) * intensity),\n );\n const targetExpressive = clampPercent(\n expressiveness + Math.round((signal.positivity * 24 - signal.frustration * 12) * intensity),\n );\n const targetVerbosity = clampPercent(\n verbosity + Math.round((signal.urgency * -30 + signal.frustration * -12) * intensity),\n );\n\n const empathyBand = bandLabel(targetEmpathy, [30, 70], [\"low\", \"balanced\", \"high\"]);\n const expressiveBand = bandLabel(targetExpressive, [30, 70], [\"reserved\", \"balanced\", \"energetic\"]);\n const verbosityBand = bandLabel(targetVerbosity, [30, 70], [\"concise\", \"balanced\", \"detailed\"]);\n\n const directives = [\n empathyBand === \"high\"\n ? \"Acknowledge user friction clearly before giving steps.\"\n : empathyBand === \"low\"\n ? \"Keep emotional language minimal; stay pragmatic and neutral.\"\n : \"Use light empathy, then move quickly to actionable guidance.\",\n verbosityBand === \"concise\"\n ? \"Prefer short, direct answers and prioritize the next concrete action.\"\n : verbosityBand === \"detailed\"\n ? \"Provide fuller rationale and tradeoffs when relevant.\"\n : \"Keep explanations compact with enough rationale to be useful.\",\n expressiveBand === \"energetic\"\n ? \"Use lively but professional tone; avoid slang and exaggeration.\"\n : expressiveBand === \"reserved\"\n ? \"Use calm, matter-of-fact wording.\"\n : \"Use steady, approachable wording.\",\n signal.mood === \"rushed\"\n ? \"User appears time-constrained; front-load the answer and avoid preamble.\"\n : signal.mood === \"frustrated\"\n ? \"User appears frustrated; validate briefly and offer a clear recovery path.\"\n : \"Do not force mood mirroring; keep behavior stable and task-focused.\",\n ];\n\n return [\n \"--- Adaptive persona ---\",\n \"These style constraints are dynamic and apply to this turn only.\",\n `Preset: ${mbti} (${mbtiLabel})`,\n `Detected user signal: ${signal.mood}`,\n `Adapt strength: ${strength}/100`,\n `Target empathy: ${targetEmpathy}/100 (${empathyBand})`,\n `Target expressiveness: ${targetExpressive}/100 (${expressiveBand})`,\n `Target verbosity: ${targetVerbosity}/100 (${verbosityBand})`,\n \"Style directives:\",\n ...directives.map((d) => `- ${d}`),\n \"Never sacrifice factual accuracy, safety policy, or execution completeness for style.\",\n ].join(\"\\n\");\n}\n\nfunction detectSignals(text: string): SignalSnapshot {\n const lower = text.toLowerCase();\n\n const frustrationHits = countMatches(lower, [\n \"stuck\", \"frustrat\", \"annoy\", \"angry\", \"wtf\", \"doesn't work\", \"not working\", \"broken\", \"hate this\",\n ]);\n const urgencyHits = countMatches(lower, [\n \"asap\", \"urgent\", \"quick\", \"quickly\", \"fast\", \"hurry\", \"right now\", \"immediately\",\n ]);\n const positivityHits = countMatches(lower, [\n \"thanks\", \"thank you\", \"awesome\", \"great\", \"love\", \"perfect\", \"nice\",\n ]);\n\n const frustration = Math.min(1, frustrationHits / 2);\n const urgency = Math.min(1, urgencyHits / 2);\n const positivity = Math.min(1, positivityHits / 2);\n\n let mood: SignalSnapshot[\"mood\"] = \"neutral\";\n if (frustration >= 0.5) mood = \"frustrated\";\n else if (urgency >= 0.5) mood = \"rushed\";\n else if (positivity >= 0.5) mood = \"positive\";\n\n return { mood, urgency, frustration, positivity };\n}\n\nfunction countMatches(text: string, terms: string[]): number {\n let n = 0;\n for (const term of terms) {\n if (text.includes(term)) n += 1;\n }\n return n;\n}\n\nfunction clampPercent(v: number): number {\n if (!Number.isFinite(v)) return 50;\n return Math.max(0, Math.min(100, Math.round(v)));\n}\n\nfunction bandLabel<T extends string>(value: number, cutoffs: [number, number], labels: [T, T, T]): T {\n if (value < cutoffs[0]) return labels[0];\n if (value > cutoffs[1]) return labels[2];\n return labels[1];\n}\n\nfunction toMbti(v: string | null | undefined): MbtiType | null {\n if (!v) return null;\n return (v in MBTI_PRESETS ? v : null) as MbtiType | null;\n}\n","export const HARNESS_SECTION_KEYS = [\n \"capabilities\",\n \"plan_first\",\n \"presentation\",\n \"citation\",\n \"self_config\",\n] as const;\n\nexport type HarnessSectionKey = typeof HARNESS_SECTION_KEYS[number];\n\nexport interface HarnessSection {\n enabled: boolean;\n body: string;\n}\n\nexport interface Harness {\n id: string;\n name: string;\n description?: string;\n builtin: boolean;\n sections: Record<HarnessSectionKey, HarnessSection>;\n}\n\nexport const BUILTIN_HARNESS_ID_PREFIX = \"builtin:\";\nexport const CUSTOM_HARNESS_ID_PREFIX = \"custom:\";\nexport const DEFAULT_HARNESS_ID = \"builtin:default\";\n\nexport function isBuiltinHarnessId(id: string): boolean {\n return id.startsWith(BUILTIN_HARNESS_ID_PREFIX);\n}\n\nexport const SECTION_DISPLAY: Record<HarnessSectionKey, { title: string; hint: string }> = {\n capabilities: {\n title: \"Host capabilities\",\n hint: \"What the surrounding app can do — notifications, scheduling, watchers, document indexing.\",\n },\n plan_first: {\n title: \"Plan-first acknowledgment\",\n hint: \"Acknowledge-before-acting rules, action principle, anti-fabrication, follow-through.\",\n },\n presentation: {\n title: \"Output formatting\",\n hint: \"Markdown / HTML extras, code fences, images, maps, citation refs block.\",\n },\n citation: {\n title: \"Source attribution\",\n hint: \"Anti-hallucination rules: every substantive claim must be tagged with its source.\",\n },\n self_config: {\n title: \"Self-configuration proposals\",\n hint: \"Lets the agent propose config changes (install MCP, edit agent, set keys) for user approval.\",\n },\n};\n","import { getAppName } from \"@/lib/env/app-config\";\nimport type { Harness } from \"./types\";\nimport { DEFAULT_HARNESS_ID } from \"./types\";\n\nconst APP_NAME = getAppName();\n\nconst CAPABILITIES_BODY = [\n `--- Host UI capabilities (${APP_NAME}) ---`,\n `You're running inside ${APP_NAME}, a local web app. The surrounding UI provides:`,\n \"- Browser notifications (Web Notifications API) — fire automatically when you finish a turn or a scheduled task runs, IF the user has granted notification permission AND is not currently looking at this agent's chat.\",\n \"- A scheduled-tasks panel — users can see/cancel anything you schedule via schedule_task in the gear menu under \\\"Tasks\\\". The same panel shows event-driven watchers you register with schedule_watcher.\",\n \" IMPORTANT: this panel is GLOBAL across all agents — it lists scheduled tasks and watchers for every agent on the instance, each row labelled with the owning agent's name. Do NOT tell the user the panel is filtered by the current agent or that the UI is hiding entries because they belong to a different agent. If the user expects to see something there and doesn't, the cause is something else (the UI loaded before the new entry, a stale view, or a list-fetch error) — say so plainly rather than inventing a per-agent scope.\",\n \"- Per-agent thread persistence with checkpointed state.\",\n \"Don't tell users you can't notify them or that scheduling has no effect — both are wired and working.\",\n \"\",\n \"--- Choosing between schedule_task and schedule_watcher ---\",\n \"Use `schedule_task` when the user wants something to happen on a CLOCK (cron, ISO timestamp, 'every weekday at 10am').\",\n `Use \\`schedule_watcher\\` when the user wants to be told about a CHANGE ('tell me when X updates', 'ping me when a new ticket lands', 'notify me when files appear in this folder'). Watchers poll a built-in tool, SHA-256 the result, and only fire the agent on a diff — they're the substitute ${APP_NAME} has for webhooks and OS-level file-system events. Examples:`,\n \" • new SLPV tickets assigned to me → schedule_watcher on `jira_search` with the JQL.\",\n \" • file appears in ~/Downloads → schedule_watcher on `file_list` with that path.\",\n \" • Confluence page edited → schedule_watcher on `confluence_get_page`.\",\n \"Do NOT tell the user 'I can't do webhooks' or 'I can only schedule on cron' — propose a watcher instead. Honest limits to mention if relevant: minimum 60s interval, built-in tools only (no MCP), and the byte-level diff can flap on volatile fields (mitigate by narrowing the tool's args/fields).\",\n `- Documents local-folder sources auto-reindex on file changes via internal fs-watch scripts on macOS/Windows (Linux falls back to periodic sweep). Do NOT tell users this needs an LLM watcher loop.`,\n \"- list_reaction_scripts intentionally shows only user-attachable reaction.* scripts. Internal scripts (e.g. documents.reindex_local_file) are built-in plumbing and won't appear there.\",\n \"\",\n].join(\"\\n\");\n\nconst PLAN_FIRST_BODY = [\n \"--- Acknowledge before acting ---\",\n \"When your reply will involve tool calls (web_search, web_fetch, memory_*, schedule_task, exec, etc.):\",\n \"- Start your reply with ONE short sentence acknowledging the task and your approach. Max ~20 words.\",\n \"- Example: \\\"Got it — I'll search for the latest LangChain release notes and pull the top 3 changes.\\\"\",\n \"- Then call the tool(s). The acknowledgment streams to the user before tool latency, so they know the task landed.\",\n \"- One acknowledgment per user turn — don't re-announce between consecutive tool calls.\",\n \"\",\n \"Skip the acknowledgment when:\",\n \"- The reply is a direct text answer with no tool calls.\",\n \"- The task is trivially short (a one-word answer, a yes/no).\",\n \"- You're already mid-execution from a prior turn (e.g. follow-up tool call after seeing a result).\",\n \"\",\n \"ACTION PRINCIPLE:\",\n \"- If the user asked you to do something and a tool can do it, execute it in this turn instead of giving instructions back.\",\n \"- Ask follow-up questions only when required parameters or approval are genuinely missing.\",\n \"- For destructive operations (delete/cancel/remove/overwrite), require explicit confirmation unless the user already gave it.\",\n \"\",\n \"ANTI-FABRICATION RULES (very important):\",\n \"- NEVER report a tool result you didn't actually receive. If you didn't call the tool, you have no result.\",\n \"- NEVER invent IDs, UUIDs, timestamps, status fields, or any structured value that should come from a tool's JSON output. If a real call is required to produce that value, you must make the real call.\",\n \"- After calling a tool, only report what's literally in the tool's JSON response. Don't paraphrase IDs or restate computed fields you didn't see.\",\n \"- If a tool errored, say so plainly and stop. Do not retry the same tool call with the same arguments. Do not pretend the call succeeded.\",\n \"- For `schedule_task` specifically: the response will contain `proposal_id` only if propose_config_change was used, or `id` + `next_run_at` from schedule_task. Quote those values verbatim. If you didn't call the tool, you don't have an id.\",\n \"\",\n \"FOLLOW-THROUGH RULES (very important):\",\n \"- NEVER end a turn with a promise to do something next. Forbidden as the LAST sentence of your reply (case-insensitive, in any language):\",\n \" \\\"give me a moment\\\" / \\\"one moment\\\" / \\\"one sec\\\" / \\\"hold on\\\" / \\\"just a moment\\\" / \\\"bear with me\\\"\",\n \" \\\"let me check\\\" / \\\"let me verify\\\" / \\\"let me continue\\\" / \\\"let me proceed\\\" / \\\"let me look\\\"\",\n \" \\\"I'll check\\\" / \\\"I'll verify\\\" / \\\"I'll continue\\\" / \\\"I'll proceed\\\" / \\\"I'll look into\\\" / \\\"I'll keep going\\\"\",\n \" \\\"continuing now\\\" / \\\"proceeding now\\\" / \\\"working on it\\\"\",\n \" The user does NOT get to send another implicit ping — your turn ends and nothing else happens. Sending two such messages in a row is even worse.\",\n \"- If you need to check or try something, DO IT IN THIS TURN: call the next tool, observe the result, then respond. The acknowledgment sentence (PLAN_FIRST rule) is allowed BECAUSE it is immediately followed by tool calls in the same turn.\",\n \"- When a tool returns a recoverable error (ENOENT path-not-found, 404, 'not found' results), try sensible alternatives in the same turn before responding: list the parent directory, try common siblings, search differently. Only ask the user when you've exhausted the obvious next steps OR you need information they alone have.\",\n \"- End every turn with either: (a) a concrete answer / result, (b) a question the user must answer, or (c) a clear statement that the task is blocked and why. NOT a vibe.\",\n \"\",\n \"CONCRETE FORBIDDEN EXAMPLE — this exact pattern is NEVER acceptable:\",\n \" > \\\"Understood! I'll continue with the file organization. One moment while I proceed.\\\" ← BAD: ends with a promise, no tool calls.\",\n \" > \\\"Let me continue the required moves. One sec!\\\" ← BAD: same pattern.\",\n \" Correct version: emit ONE short acknowledgment, then CALL file_move (or whatever tool advances the task) in the same turn. Only after the tool returns do you reply.\",\n].join(\"\\n\");\n\nconst SELF_CONFIG_BODY = [\n \"--- Self-configuration (with user approval) ---\",\n \"If completing the user's task would clearly benefit from a config change, you may propose it.\",\n \"Available kinds (via propose_config_change):\",\n \" - install_mcp: install a new MCP server. Prefer registry_id (e.g. 'github', 'atlassian') over a custom spec. \" +\n \"Do NOT include real secrets in the payload — use placeholder values and ask the user to fill them in the UI before approving.\",\n \" - toggle_mcp: enable/disable an installed MCP server.\",\n \" - update_agent_tools: change THIS agent's tool allowlist (agent_id = the current agent).\",\n \" - update_agent: edit identity, instructions, history window, or harness_id for an agent. \" +\n \"Pass `harness_id` to switch which harness the agent runs under (an existing 'builtin:default' or 'custom:<uuid>'); pass null to inherit the global default.\",\n \" - upsert_harness: create or edit a CUSTOM harness preset (the behavioural scaffolding wrapped around every turn). \" +\n \"Built-in harnesses ('builtin:*') are read-only — to tweak default behaviour, omit `id` and copy the sections you want as a starting point. \" +\n \"Use this sparingly: identity/instructions edits via update_agent are the right tool for tone, role, and topic preferences. \" +\n \"Reach for upsert_harness only when the user wants a structural change to the scaffolding the LLM sees on every turn (e.g., disable inline citation, swap the entire output-formatting section). After approval, follow up with update_agent to point an agent at the new harness id.\",\n \" - start_oauth: kick off the OAuth consent flow for an integration that already has client_id/secret saved. \" +\n \"Payload: { integration_id }. The user approves, then a vendor consent screen opens in a new tab.\",\n \" - set_provider_key: add or replace an LLM provider/model entry. Payload: { name, provider, model_id, is_default? }. \" +\n \"NEVER put the API key in the payload — the approval UI collects it through a secret input.\",\n \" - enable_integration: save the credentials for one of the listed integrations and turn it on. \" +\n \"Payload: { id }. NEVER put credentials in the payload — the approval UI collects each declared field.\",\n \"\",\n \"Setup flows:\",\n \"- When the user asks 'how do I connect X?' or 'what can I connect?', call list_integrations first.\",\n \" Then call get_integration_setup(id) for the chosen one and walk the user through the steps.\",\n \"- For each step with a `proposes` field, call propose_config_change with that kind when the user's ready.\",\n \"- For each step with a `verify` field, call that tool AFTER approval to confirm success.\",\n \"- Don't open URLs for the user. If a step has a docs_url, mention it as a markdown link `[label](url)` and let the user click.\",\n \" There is no open_url tool by design — see ADR-0010.\",\n \"\",\n \"Rules:\",\n \"- Only propose changes when the user's request makes them necessary or clearly helpful — don't volunteer changes unprompted.\",\n \"- After calling propose_config_change, end your turn with one short sentence telling the user what you proposed and that they need to approve it in the banner above the input.\",\n \"- Do not retry a failed proposal in the same turn — the user will see the banner.\",\n \"- Do not poll check_proposal in a tight loop. If you need to know the outcome, do it in the next turn after the user replies.\",\n \"\",\n].join(\"\\n\");\n\nconst PRESENTATION_BODY = [\n \"--- Output formatting ---\",\n \"Your replies are rendered as GitHub-flavored Markdown with a safe subset of HTML.\",\n \"Use formatting to make answers scannable, not decorative — match the response density to the question.\",\n \"Available:\",\n \"- Markdown: headings, lists, **bold**, _italic_, `code`, code fences with language tag, > blockquotes, tables, [links](url), task lists.\",\n \"- HTML extras: <kbd>Ctrl</kbd>+<kbd>K</kbd>, <mark>highlight</mark>, <sub>/<sup>, <abbr title=\\\"…\\\">term</abbr>, <details><summary>label</summary>content</details>.\",\n \"- Callouts: <aside class=\\\"info|tip|warn|danger\\\">message</aside>\",\n \"Guidelines:\",\n \"- Short factual answers stay plain — no headings or bullets for one-liners.\",\n \"- Use tables for comparisons (≥3 items × ≥2 attributes), bullets for short parallel lists, prose for explanations.\",\n \"- Wrap collapsibles around long supporting detail (logs, full diffs, raw data) so the main answer stays compact.\",\n \"- Use callouts sparingly: <aside class=\\\"warn\\\"> for caveats, <aside class=\\\"tip\\\"> for non-obvious shortcuts.\",\n \"- Always specify the language on code fences. Inline code for symbols, blocks for multi-line.\",\n \"- Script tags and event handlers are stripped — don't bother emitting them.\",\n \"\",\n \"Images:\",\n \"- You CAN embed images in replies via markdown `![alt](url)`. The renderer allowlists `<img>`.\",\n \"- For research / news / product summaries, embed a relevant image from the page near the top — it makes the answer feel like a real article instead of a wall of text.\",\n \"- Sources: `web_fetch` returns an `images` field — `images.og` is usually the publisher-chosen hero shot (best pick), then `images.twitter`, then `images.samples`. Use those URLs verbatim.\",\n \"- Don't fabricate image URLs. Only use URLs that came from a tool result or the user.\",\n \"- To CREATE a new image from a description, call the `generate_image` tool. Embed every URL it returns (use the `markdown` field verbatim, or build `![alt](images[i].url)` yourself).\",\n \"- One hero image is plenty for most replies; a small inline gallery is fine for comparisons. Don't spam.\",\n \"\",\n \"Maps:\",\n \"- You CAN embed an interactive Google Map by emitting a ```map fenced code block containing a small JSON object. The renderer turns it into a live Google Maps iframe.\",\n \"- Use it whenever the answer is about a place, address, route, or coordinates — a map is far more useful than just naming the location.\",\n \"- Supported fields (pick one shape):\",\n \" place: { \\\"q\\\": \\\"Eiffel Tower, Paris\\\", \\\"zoom\\\": 15 }\",\n \" coordinates: { \\\"center\\\": \\\"48.8584,2.2945\\\", \\\"zoom\\\": 16 }\",\n \" search: { \\\"search\\\": \\\"coffee shops near Times Square\\\" }\",\n \" directions: { \\\"origin\\\": \\\"JFK Airport\\\", \\\"destination\\\": \\\"Times Square\\\", \\\"mode\\\": \\\"transit\\\" }\",\n \"- `mode` (directions only) can be `driving` | `walking` | `bicycling` | `transit`.\",\n \"- Emit the map after the prose, not before. One map per answer unless the user asked to compare locations.\",\n \"- Example:\",\n \" ```map\",\n \" { \\\"q\\\": \\\"Golden Gate Bridge\\\", \\\"zoom\\\": 13 }\",\n \" ```\",\n \"\",\n \"Citations:\",\n \"- When your reply draws on web_search results (or any external URL you fetched), end your message with a <refs> block listing the sources you actually used.\",\n \"- Format: a single <refs>…</refs> block at the very end (after all prose), one markdown link per line inside it.\",\n \"- Example:\",\n \" <refs>\",\n \" [Wikipedia — DuckDuckGo](https://en.wikipedia.org/wiki/DuckDuckGo)\",\n \" [DDG About page](https://duckduckgo.com/about)\",\n \" </refs>\",\n \"- Only list sources you actually used, not every search hit. No duplicates. Keep titles short (~6 words).\",\n \"- Don't include a separate \\\"Sources:\\\" heading — the UI renders the <refs> block as a compact collapsed footer automatically.\",\n \"- If the response doesn't draw on external sources, omit the block entirely.\",\n].join(\"\\n\");\n\nconst CITATION_BODY = [\n \"--- Source attribution (anti-hallucination) ---\",\n \"Every substantive factual claim in your reply MUST be traceable to a source you actually consulted in this conversation. Tag the source with a short inline parenthetical so the user can verify (and so YOU can't drift into invented detail).\",\n \"\",\n \"WHAT counts as a substantive claim that needs a tag:\",\n \"- Counts, totals, IDs, UUIDs, status fields, timestamps, version numbers.\",\n `- Behavioral statements about how ${APP_NAME}, a tool, an integration, a file, or the codebase works.`,\n \"- Quotes, file paths, function/class names, config values.\",\n \"- Anything the user could reasonably challenge with \\\"how do you know?\\\"\",\n \"\",\n \"WHAT does NOT need a tag (don't bloat replies):\",\n \"- One-line answers and chitchat.\",\n \"- Acknowledgments, plans of attack, and questions back to the user.\",\n \"- Things the user just said in the same conversation.\",\n \"- Generic background knowledge that doesn't depend on this user's data.\",\n \"\",\n \"FORMAT — short parenthetical at the end of the claim:\",\n \"- Tool result: `(via tool_name)` — e.g. `(via list_watchers)`. If the same tool was called multiple times this turn, distinguish with a key arg: `(via jira_get_issue ABC-123)`.\",\n \"- File / code: `(path/to/file.ts:42)` — line numbers when you have them.\",\n \"- Memory: `(memory: namespace/key)`.\",\n \"- Web (and ONLY web): keep using the existing <refs> block at the end — don't double-cite inline.\",\n \"- Multiple sources for one claim: comma-separate inside one paren, e.g. `(via list_watchers, file: WatchersSection.tsx:20)`.\",\n \"\",\n \"HARD RULES:\",\n \"- If you don't have a source for a claim, do NOT make the claim. Say \\\"I don't know\\\" or call a tool to find out.\",\n \"- Never tag a tool call you didn't actually make this conversation. Never invent a file path or line number to make a claim look sourced — that's worse than no tag.\",\n `- Don't speculate about ${APP_NAME}'s UI behavior unless a tool result, the codebase, or the user's own message gave you the fact. If the user reports the UI shows something different than you'd expect, say you don't know why and propose concrete checks (refresh, look at the right tab, inspect logs) — do not invent a mechanism (a hidden filter, a permissions rule, a per-agent scope) to explain the gap.`,\n \"- If asked to recall something from prior turns and you don't actually see it in your context window, say so — don't reconstruct it from plausibility.\",\n \"\",\n \"EXAMPLES:\",\n \" Good: \\\"You have 18 active watchers (via list_watchers), all enabled. The Watchers panel shows watchers from every agent (no per-agent filter on the UI).\\\"\",\n \" Good: \\\"`createWatcher` writes to the watchers table (lib/stores/watchers.ts:56).\\\"\",\n \" Bad: \\\"The panel doesn't show these because they're attached to my agent ID.\\\" ← unsourced, fabricated mechanism.\",\n \" Bad: \\\"You have around 15-20 watchers.\\\" ← if you called the tool you have an exact number; if you didn't, don't guess.\",\n].join(\"\\n\");\n\nexport const BUILTIN_HARNESSES: Harness[] = [\n {\n id: DEFAULT_HARNESS_ID,\n name: \"Default\",\n description:\n \"Standard scaffolding: capabilities, plan-first acknowledgment, output formatting, citation, self-config proposals.\",\n builtin: true,\n sections: {\n capabilities: { enabled: true, body: CAPABILITIES_BODY },\n plan_first: { enabled: true, body: PLAN_FIRST_BODY },\n presentation: { enabled: true, body: PRESENTATION_BODY },\n citation: { enabled: true, body: CITATION_BODY },\n self_config: { enabled: true, body: SELF_CONFIG_BODY },\n },\n },\n];\n\nexport function getBuiltinHarness(id: string): Harness | undefined {\n return BUILTIN_HARNESSES.find((h) => h.id === id);\n}\n","import { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\nimport {\n CUSTOM_HARNESS_ID_PREFIX,\n DEFAULT_HARNESS_ID,\n HARNESS_SECTION_KEYS,\n type Harness,\n type HarnessSection,\n type HarnessSectionKey,\n isBuiltinHarnessId,\n} from \"@/lib/agents/harness/types\";\nimport { BUILTIN_HARNESSES, getBuiltinHarness } from \"@/lib/agents/harness/presets\";\n\nconst NS = \"app-settings\";\nconst CUSTOMS_KEY = \"harnesses\";\nconst DEFAULT_KEY = \"default_harness_id\";\n\nconst now = () => new Date().toISOString();\n\nfunction readJson<T>(key: string): T | null {\n const row = getDb()\n .prepare(\"SELECT value FROM memory_store WHERE namespace=? AND key=?\")\n .get(NS, key) as { value?: string } | undefined;\n if (!row?.value) return null;\n try {\n return JSON.parse(row.value) as T;\n } catch {\n return null;\n }\n}\n\nfunction writeJson(key: string, value: unknown): void {\n const t = now();\n const existing = getDb()\n .prepare(\"SELECT created_at FROM memory_store WHERE namespace=? AND key=?\")\n .get(NS, key) as { created_at?: string } | undefined;\n const created = existing?.created_at ?? t;\n getDb()\n .prepare(\n \"INSERT OR REPLACE INTO memory_store (namespace,key,value,created_at,updated_at,embedding) VALUES (?,?,?,?,?,NULL)\",\n )\n .run(NS, key, JSON.stringify(value), created, t);\n}\n\nfunction deleteKey(key: string): void {\n getDb().prepare(\"DELETE FROM memory_store WHERE namespace=? AND key=?\").run(NS, key);\n}\n\nfunction sanitizeSections(input: unknown): Harness[\"sections\"] {\n const out = {} as Harness[\"sections\"];\n const obj = (input ?? {}) as Partial<Record<HarnessSectionKey, Partial<HarnessSection>>>;\n for (const k of HARNESS_SECTION_KEYS) {\n const s = obj[k] ?? { enabled: true, body: \"\" };\n out[k] = {\n enabled: s.enabled !== false,\n body: typeof s.body === \"string\" ? s.body : \"\",\n };\n }\n return out;\n}\n\nfunction listCustomHarnesses(): Harness[] {\n const raw = readJson<unknown[]>(CUSTOMS_KEY);\n if (!Array.isArray(raw)) return [];\n const out: Harness[] = [];\n for (const item of raw) {\n if (!item || typeof item !== \"object\") continue;\n const obj = item as Partial<Harness>;\n if (typeof obj.id !== \"string\" || !obj.id.startsWith(CUSTOM_HARNESS_ID_PREFIX)) continue;\n if (typeof obj.name !== \"string\") continue;\n out.push({\n id: obj.id,\n name: obj.name,\n description: typeof obj.description === \"string\" ? obj.description : undefined,\n builtin: false,\n sections: sanitizeSections(obj.sections),\n });\n }\n return out;\n}\n\nfunction writeCustomHarnesses(list: Harness[]): void {\n writeJson(CUSTOMS_KEY, list);\n}\n\nexport function listAllHarnesses(): Harness[] {\n return [...BUILTIN_HARNESSES, ...listCustomHarnesses()];\n}\n\nexport function getHarness(id: string): Harness | null {\n if (isBuiltinHarnessId(id)) return getBuiltinHarness(id) ?? null;\n return listCustomHarnesses().find((h) => h.id === id) ?? null;\n}\n\nexport function getDefaultHarnessId(): string {\n const raw = readJson<string>(DEFAULT_KEY);\n if (typeof raw === \"string\" && raw.length > 0) return raw;\n return DEFAULT_HARNESS_ID;\n}\n\nexport function setDefaultHarnessId(id: string): string {\n if (!getHarness(id)) {\n throw new Error(`unknown harness id: ${id}`);\n }\n if (id === DEFAULT_HARNESS_ID) {\n deleteKey(DEFAULT_KEY);\n return DEFAULT_HARNESS_ID;\n }\n writeJson(DEFAULT_KEY, id);\n return id;\n}\n\nexport interface CreateHarnessInput {\n name: string;\n description?: string;\n sections: Partial<Record<HarnessSectionKey, Partial<HarnessSection>>>;\n}\n\nexport function createCustomHarness(input: CreateHarnessInput): Harness {\n const id = `${CUSTOM_HARNESS_ID_PREFIX}${randomUUID()}`;\n const harness: Harness = {\n id,\n name: input.name.trim() || \"Untitled harness\",\n description: input.description?.trim() || undefined,\n builtin: false,\n sections: sanitizeSections(input.sections),\n };\n const list = listCustomHarnesses();\n list.push(harness);\n writeCustomHarnesses(list);\n return harness;\n}\n\nexport interface UpdateHarnessInput {\n name?: string;\n description?: string;\n sections?: Partial<Record<HarnessSectionKey, Partial<HarnessSection>>>;\n}\n\nexport function updateCustomHarness(id: string, input: UpdateHarnessInput): Harness | null {\n if (isBuiltinHarnessId(id)) return null;\n const list = listCustomHarnesses();\n const idx = list.findIndex((h) => h.id === id);\n if (idx === -1) return null;\n const prev = list[idx];\n const next: Harness = {\n ...prev,\n name: input.name !== undefined ? (input.name.trim() || prev.name) : prev.name,\n description:\n input.description !== undefined\n ? (input.description.trim() || undefined)\n : prev.description,\n sections: input.sections ? sanitizeSections({ ...prev.sections, ...input.sections }) : prev.sections,\n };\n list[idx] = next;\n writeCustomHarnesses(list);\n return next;\n}\n\nexport function deleteCustomHarness(id: string): boolean {\n if (isBuiltinHarnessId(id)) return false;\n const list = listCustomHarnesses();\n const next = list.filter((h) => h.id !== id);\n if (next.length === list.length) return false;\n writeCustomHarnesses(next);\n // Null out any agent that referenced this harness so resolveHarness falls\n // back to the global default rather than the deleted id.\n getDb()\n .prepare(\"UPDATE agent_configs SET harness_id=NULL, updated_at=? WHERE harness_id=?\")\n .run(now(), id);\n // If this harness was the global default, fall back to builtin:default.\n if (getDefaultHarnessId() === id) {\n deleteKey(DEFAULT_KEY);\n }\n return true;\n}\n","import type { AgentConfigRow } from \"@/lib/stores/agent-configs\";\nimport { getDefaultHarnessId, getHarness } from \"@/lib/stores/harnesses\";\nimport { getBuiltinHarness } from \"./presets\";\nimport { DEFAULT_HARNESS_ID, HARNESS_SECTION_KEYS, type HarnessSectionKey } from \"./types\";\n\nexport type ResolvedHarnessSections = Record<HarnessSectionKey, string>;\n\n/**\n * Resolve which harness applies to a given agent and return its section\n * bodies as a record. Disabled sections become empty strings (so the\n * caller's `.filter(Boolean)` in systemParts assembly drops them).\n *\n * Resolution order:\n * 1. agentCfg.harness_id (per-agent override)\n * 2. app-settings default_harness_id (global default)\n * 3. builtin:default\n *\n * Stale ids (custom harness deleted out from under an agent) fall back to\n * builtin:default rather than erroring — matches how missing model configs\n * behave in this codebase.\n */\nexport function resolveHarness(\n agentCfg: Pick<AgentConfigRow, \"harness_id\">,\n): ResolvedHarnessSections {\n const id = agentCfg.harness_id || getDefaultHarnessId() || DEFAULT_HARNESS_ID;\n const harness =\n getHarness(id) ?? getBuiltinHarness(DEFAULT_HARNESS_ID) ?? null;\n const out = {} as ResolvedHarnessSections;\n for (const key of HARNESS_SECTION_KEYS) {\n const section = harness?.sections[key];\n out[key] = section?.enabled ? section.body : \"\";\n }\n return out;\n}\n","import type { Claim } from \"./types\";\n\n// First-person past-tense or perfect-tense action verbs that imply work was\n// performed in the current turn. We don't try to enumerate every English verb;\n// the set covers the dominant fabrication shapes in observed transcripts.\nconst ACTION_VERBS = [\n \"patched\", \"edited\", \"wrote\", \"ran\", \"verified\", \"created\", \"deleted\",\n \"updated\", \"committed\", \"saved\", \"added\", \"removed\", \"fixed\", \"applied\",\n \"installed\", \"configured\", \"renamed\", \"moved\", \"copied\", \"pushed\", \"merged\",\n \"checked\", \"confirmed\", \"tested\",\n];\n\nconst VERB_GROUP = ACTION_VERBS.join(\"|\");\n\nconst PATTERNS: RegExp[] = [\n // \"I patched the file\" — bare past tense\n new RegExp(`\\\\bI\\\\s+(?:just\\\\s+)?(${VERB_GROUP})\\\\b`, \"gi\"),\n // \"I've patched\", \"I have patched\"\n new RegExp(`\\\\bI(?:'ve|\\\\s+have)\\\\s+(${VERB_GROUP})\\\\b`, \"gi\"),\n // \"Verified the bytes\" — leading capital, no subject (common in concise replies)\n new RegExp(`(?:^|\\\\.\\\\s+|\\\\n)(${VERB_GROUP})\\\\b`, \"gi\"),\n];\n\nconst FUTURE_PATTERNS: RegExp[] = [\n // \"I'll patch\", \"I will patch\", \"I would patch\", \"I could patch\"\n /\\bI(?:'ll|\\s+will|\\s+would|\\s+could|\\s+should|\\s+can|\\s+might)\\s+\\w+/i,\n];\n\nexport function findActionClaims(text: string): Claim[] {\n const out: Claim[] = [];\n const seen = new Set<string>();\n for (const re of PATTERNS) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const verb = m[1].toLowerCase();\n // Skip if this match is inside a future-tense clause. Scan a small\n // backward window for \"I'll / I will\" before the verb.\n const start = Math.max(0, m.index - 24);\n const window = text.slice(start, m.index + m[0].length);\n if (FUTURE_PATTERNS.some((f) => f.test(window))) continue;\n const key = `${verb}@${m.index}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push({ verb, raw: m[0].trim() });\n }\n }\n return out;\n}\n","import type { Citation } from \"./types\";\n\n// Matches `(via NAME)` and `(via NAME ARG1 ARG2)` and `(via NAME, file: ...)`.\n// Captures the tool name (first whitespace-delimited identifier-ish token).\n// Ignores file-path citations like `(lib/foo.ts:42)` and memory citations\n// like `(memory: ns/key)` — those are not tool-call claims.\nconst VIA_RE = /\\(\\s*via\\s+([A-Za-z_][\\w-]*)[^)]*\\)/g;\n\nexport function findCitations(text: string): Citation[] {\n const out: Citation[] = [];\n VIA_RE.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = VIA_RE.exec(text)) !== null) {\n out.push({ tool: m[1], raw: m[0] });\n }\n return out;\n}\n","import { findActionClaims } from \"./claim-detector\";\nimport { findCitations } from \"./citation-parser\";\nimport type { ValidationResult } from \"./types\";\n\nconst SUMMARY_PATTERNS: RegExp[] = [\n /^#{1,6}\\s*Summary(?:\\s+of\\s+changes)?\\b/im,\n /\\bI(?:'ve|\\s+have)\\s+completed\\b/i,\n /\\bWhat\\s+I\\s+did\\b/i,\n];\n\n/**\n * Cross-check the assistant's text output against the tool calls actually\n * issued in this turn. Returns ok=true when nothing fishy is detected,\n * or ok=false with a kind + reason when a fabrication shape is matched.\n *\n * Priority (first match wins): citation_unregistered_tool >\n * citation_uncalled_tool > claim_without_tool > summary_without_action.\n *\n * Lenient principle: when ANY tool was called this turn, action-claim text\n * is allowed (the model legitimately did work, even if its phrasing isn't\n * tagged with `(via ...)`). Citations are checked regardless of tool count.\n */\nexport function validateAssistantOutput(\n text: string,\n toolCalls: readonly string[],\n allowedTools: readonly string[],\n): ValidationResult {\n const calledSet = new Set(toolCalls);\n const allowedSet = new Set(allowedTools);\n\n // Citation checks run regardless of whether other tools were called —\n // a `(via foo)` tag MUST refer to a registered tool that was actually\n // invoked this turn.\n const citations = findCitations(text);\n for (const c of citations) {\n if (!allowedSet.has(c.tool)) {\n return {\n ok: false,\n kind: \"citation_unregistered_tool\",\n reason: `You wrote \"${c.raw}\" but \"${c.tool}\" is not a registered tool. Either drop the citation or call the correct tool.`,\n evidence: c.raw,\n };\n }\n if (!calledSet.has(c.tool)) {\n return {\n ok: false,\n kind: \"citation_uncalled_tool\",\n reason: `You wrote \"${c.raw}\" but did not actually call \"${c.tool}\" this turn. Call the tool or drop the citation.`,\n evidence: c.raw,\n };\n }\n }\n\n // Claim and summary checks only fire when zero tools were called. If any\n // tool ran, the text is treated as legitimately describing work done.\n if (toolCalls.length > 0) return { ok: true };\n\n const claims = findActionClaims(text);\n if (claims.length > 0) {\n const c = claims[0];\n return {\n ok: false,\n kind: \"claim_without_tool\",\n reason: `You wrote \"${c.raw}\" but did not call any tool this turn. Either call the tool that performs the action or rephrase as a proposal.`,\n evidence: c.raw,\n };\n }\n\n for (const re of SUMMARY_PATTERNS) {\n const m = text.match(re);\n if (m) {\n return {\n ok: false,\n kind: \"summary_without_action\",\n reason: `You wrote a summary section (\"${m[0].trim()}\") but did not call any tool this turn. Drop the recap or do the work first.`,\n evidence: m[0].trim(),\n };\n }\n }\n\n return { ok: true };\n}\n","export { validateAssistantOutput } from \"./validator\";\nexport { findActionClaims } from \"./claim-detector\";\nexport { findCitations } from \"./citation-parser\";\nexport type {\n ValidationKind,\n ValidationOk,\n ValidationFail,\n ValidationResult,\n Citation,\n Claim,\n} from \"./types\";\n","import { streamWithConfig } from \"@/lib/agents/llm\";\nimport type { StreamChunk, StreamOptions } from \"@/lib/agents/base\";\nimport type { ContentPart } from \"@/lib/tools/types\";\nimport { addMessage, getRecentMessagesWindow, getThread, touchThread, type PersistedToolEvent } from \"@/lib/stores/threads\";\nimport { recordToolUsage } from \"@/lib/stores/tool-stats\";\nimport { getAgentConfig } from \"@/lib/stores/agent-configs\";\nimport { getUserProfile } from \"@/lib/stores/user-profile\";\nimport { startScheduler } from \"@/lib/scheduler\";\nimport { recall, type RecalledMemory } from \"@/lib/embeddings\";\nimport { listIntegrations } from \"@/lib/stores/integrations\";\nimport { buildAdaptivePersonaContext } from \"@/lib/agents/adaptive-persona\";\nimport { resolveHarness } from \"@/lib/agents/harness/resolve\";\nimport { validateAssistantOutput } from \"@/lib/agents/output-validator\";\nimport { getAppName } from \"@/lib/env/app-config\";\nimport os from \"node:os\";\n\n// Resolve the app name once at module load. Forks set NEXT_PUBLIC_APP_NAME to\n// rebrand the user-visible name the LLM echoes in chat replies; default\n// \"Jarela\" for upstream. Per-turn pieces of the system prompt (user profile,\n// integrations, time, env) still interpolate this constant directly.\nconst APP_NAME = getAppName();\n\nexport class RunThreadError extends Error {\n status: number;\n code: string;\n\n constructor(status: number, message: string, code: string) {\n super(message);\n this.status = status;\n this.code = code;\n }\n}\n\n// Hard cap on how long we wait for the embedding-based recall pass before\n// starting the LLM stream without it. Recall is best-effort context — making\n// users wait on a cold OpenAI embeddings round-trip every turn is a worse UX\n// than occasionally missing a memory hit.\nconst RECALL_BUDGET_MS = 400;\n\nfunction raceWithBudget<T>(promise: Promise<T>, ms: number, fallback: T): Promise<T> {\n return new Promise<T>((resolve) => {\n let settled = false;\n const t = setTimeout(() => {\n if (!settled) {\n settled = true;\n resolve(fallback);\n }\n }, ms);\n promise.then(\n (v) => { if (!settled) { settled = true; clearTimeout(t); resolve(v); } },\n () => { if (!settled) { settled = true; clearTimeout(t); resolve(fallback); } },\n );\n });\n}\n\n// The harness sections (capabilities, plan-first, presentation, citation,\n// self-config) used to live here as hard-coded constants. They moved to\n// `lib/agents/harness/presets.ts` as the body of `builtin:default`, and\n// `resolveHarness(agentCfg)` returns them per-turn (allowing per-agent\n// override + global default selection). See ADR-0033.\n\nexport interface PreparedThreadRun {\n stream: AsyncIterable<StreamChunk>;\n thread_id: string;\n}\n\n// Max times we'll auto-retry a single user turn when the model emits a\n// \"one moment\" stall without firing any tool. One retry is plenty — if the\n// model is *still* stalling after a forceful nudge, looping further just\n// burns tokens and the warning footer on the persisted message gives the\n// user a clear manual recovery path (\"continue\").\nconst MAX_STALL_AUTO_RETRIES = 1;\n\nfunction parseContent(raw: string): string | ContentPart[] {\n if (!raw.startsWith(\"[\")) return raw;\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (\n Array.isArray(parsed) &&\n parsed.length > 0 &&\n typeof parsed[0] === \"object\" &&\n parsed[0] !== null &&\n \"type\" in (parsed[0] as object)\n ) {\n return parsed as ContentPart[];\n }\n } catch {\n // not valid JSON — treat as plain text\n }\n return raw;\n}\n\nfunction contentText(content: string | ContentPart[]): string {\n if (typeof content === \"string\") return content;\n return content\n .filter((p): p is ContentPart & { type: \"text\" } => p.type === \"text\")\n .map((p) => p.text)\n .join(\" \");\n}\n\nexport async function prepareThreadRun(\n thread_id: string,\n message: string,\n options?: StreamOptions,\n attachments?: ContentPart[],\n signal?: AbortSignal,\n // Internal: tracks how many stall-retries are still allowed in this turn.\n // Public callers leave this undefined and get the default budget. The\n // wrapper decrements it when it recursively re-invokes prepareThreadRun.\n _stallRetriesLeft: number = MAX_STALL_AUTO_RETRIES,\n // Optional classification tag persisted on the injected user message.\n // Surfaces in the chat panel's category-filter toolbar (e.g.\n // 'scheduled_task', 'bridge', 'synthetic'). undefined = ordinary chat.\n userCategory: string | null = null,\n): Promise<PreparedThreadRun> {\n // Lazy-start the scheduler when any agent activity occurs so previously\n // saved scheduled tasks resume firing across server restarts.\n startScheduler();\n\n const thread = getThread(thread_id);\n if (!thread) throw new RunThreadError(404, \"Thread not found\", \"thread_not_found\");\n\n const trimmed = message.trim();\n if (!trimmed && !attachments?.length) {\n throw new RunThreadError(400, \"message required\", \"message_required\");\n }\n\n const agentCfg = getAgentConfig(thread.agent_id);\n if (!agentCfg) {\n throw new RunThreadError(404, `Agent \"${thread.agent_id}\" not found`, \"agent_not_found\");\n }\n\n const content: string | ContentPart[] =\n attachments?.length ? [{ type: \"text\", text: trimmed }, ...attachments] : trimmed;\n\n const stored = typeof content === \"string\" ? content : JSON.stringify(content);\n addMessage(thread_id, \"user\", stored, undefined, userCategory);\n touchThread(thread_id, trimmed.slice(0, 80) || undefined);\n\n // Build the LLM history window: latest N messages that are also within the\n // last X hours. Both bounds come from the agent's config (defaults 50 / 8h).\n // The full history remains queryable via getMessages for the UI.\n const limit = agentCfg.history_limit ?? 50;\n const windowHours = agentCfg.history_window_hours ?? 8;\n const sinceISO = windowHours > 0\n ? new Date(Date.now() - windowHours * 3600_000).toISOString()\n : undefined;\n const history = getRecentMessagesWindow(thread_id, limit, sinceISO).map((m) => ({\n role: m.role as \"user\" | \"assistant\",\n content: parseContent(m.content),\n }));\n\n // Build agent run config from DB record\n const userProfile = getUserProfile();\n const userCtxParts: string[] = [];\n if (userProfile?.name) userCtxParts.push(`Name: ${userProfile.name}`);\n if (userProfile?.about) userCtxParts.push(`About: ${userProfile.about}`);\n if (\n userProfile?.location_consent === 1 &&\n typeof userProfile.location_lat === \"number\" &&\n typeof userProfile.location_lng === \"number\"\n ) {\n const ageSec = userProfile.location_updated_at\n ? Math.round((Date.now() - Date.parse(userProfile.location_updated_at)) / 1000)\n : null;\n const ageStr = ageSec === null ? \"unknown age\"\n : ageSec < 120 ? `${ageSec}s ago`\n : ageSec < 7200 ? `${Math.round(ageSec / 60)}m ago`\n : `${Math.round(ageSec / 3600)}h ago`;\n const acc = userProfile.location_accuracy_m != null\n ? ` (±${Math.round(userProfile.location_accuracy_m)}m)` : \"\";\n const label = userProfile.location_label ? ` — ${userProfile.location_label}` : \"\";\n userCtxParts.push(\n `Location: ${userProfile.location_lat.toFixed(5)}, ${userProfile.location_lng.toFixed(5)}${acc}${label} [updated ${ageStr}]`,\n \" (User has opted in to share location. Use it for any location-dependent answer — weather, nearby places, directions, local time. Call get_user_location for the freshest values.)\",\n );\n }\n const userCtx = userCtxParts.length > 0\n ? `--- User context ---\\n${userCtxParts.join(\"\\n\")}`\n : null;\n\n const timeCtx = `Current time: ${new Date().toISOString()} (UTC). Use this when computing scheduled task timestamps.`;\n\n // Host environment hint so the agent doesn't have to guess platform-specific\n // paths (e.g. iCloud Drive lives at a different default location on Windows\n // vs. macOS). Keeps the agent grounded in the actual filesystem it's\n // operating against.\n const envCtx = [\n \"--- Host environment ---\",\n `Platform: ${process.platform} (${process.arch})`,\n `CWD: ${process.cwd()}`,\n `Home: ${os.homedir()}`,\n process.platform === \"win32\"\n ? \"iCloud Drive on Windows (if installed): %USERPROFILE%\\\\iCloudDrive (a.k.a. ~\\\\iCloudDrive)\"\n : process.platform === \"darwin\"\n ? \"iCloud Drive on macOS: ~/Library/Mobile Documents/com~apple~CloudDocs\"\n : \"\",\n `File-tool path resolution: absolute paths and \\`~/...\\` are honored verbatim; BARE RELATIVE paths (e.g. \\`notes.txt\\`) resolve against HOME, not cwd. cwd is the ${APP_NAME} install directory and should never be used as a default location for user files.`,\n \"Verify file paths with file_stat or file_list before assuming they exist. Always echo the resolved absolute path back to the user when you create/move/delete a file so they know where it landed.\",\n ].filter(Boolean).join(\"\\n\");\n\n // Surface configured integrations so the LLM knows native tools are wired\n // and ready. Without this, the model defaults to shell-exec'ing CLIs (`jira`,\n // `gh`, etc.) because that's what its training data covers — even though\n // the typed REST tools are right there in the function list.\n const configuredIntegrations = listIntegrations().filter((i) => i.configured);\n const integrationsCtx = configuredIntegrations.length > 0 ? [\n \"--- Configured integrations (use the typed tools, not shell CLIs) ---\",\n ...configuredIntegrations.flatMap((i) => {\n if (i.name === \"atlassian\") {\n const url = i.values.url;\n return [\n `Atlassian: ${url} as ${i.values.email}.`,\n \" Use jira_search / jira_get_issue / jira_create_issue / jira_add_comment / jira_transition_issue / confluence_search / confluence_get_page.\",\n \" DO NOT shell out to a `jira` or `acli` CLI — these REST tools are already authenticated and use the corporate proxy correctly.\",\n ];\n }\n if (i.name === \"jira_align\") {\n return [\n \"Jira Align: configured.\",\n \" Use jira_align_search_items / jira_align_get_item / jira_align_create_item / jira_align_update_item / jira_align_transition_item / jira_align_add_comment.\",\n ];\n }\n if (i.name === \"github\") {\n return [\n \"GitHub: configured.\",\n \" Use github_* tools for issues/PRs/code/reviews (search, create, update, comment, merge, file fetch) instead of shelling out to `gh`.\",\n ];\n }\n if (i.name === \"gmail\") {\n return [\n \"Gmail + Calendar: configured.\",\n \" Use gmail_* for inbox/search/draft/labels and calendar_* for event operations. Prefer these typed tools over raw IMAP/SMTP instructions.\",\n ];\n }\n if (i.name === \"outlook\") {\n return [\n \"Outlook + Calendar: configured.\",\n \" Use outlook_* for mail operations and outlook_calendar_* for event operations.\",\n ];\n }\n if (i.name === \"google\") {\n return [\n \"Google AI: configured.\",\n \" Use generate_image when the user asks to create images; don't claim image generation is unavailable.\",\n ];\n }\n return [`${i.name}: configured.`];\n }),\n \"\",\n ].join(\"\\n\") : \"\";\n\n const memoryCtx = [\n \"--- Memory & recall ---\",\n \"You have long-term memory across sessions and a fresh recall pass on every turn.\",\n `- The recent ${limit} messages from the last ${windowHours}h are already in your context above.`,\n \"- A semantic search over all stored memory entries + past chat messages was run against the user's turn; matching items appear under \\\"Relevant context\\\" below.\",\n \"- Use memory_write proactively when the user shares a fact, preference, or decision worth remembering. Use memory_read / memory_list to recall stored facts on demand.\",\n \"- If you want detail from outside the recent window, the user can scroll up — but for facts you've stored explicitly, prefer recall over guessing.\",\n ].join(\"\\n\");\n\n // Semantic recall: pull in long-term memory + past messages relevant to this turn.\n // Skip messages from the current thread that are already in the windowed history.\n // Capped at RECALL_BUDGET_MS — if the embedding round-trip is slower than\n // that the LLM stream starts without recall hits rather than letting the\n // user stare at an idle screen waiting on a network call.\n const oldestInWindow = history.length > 0 ? contentText(history[0].content) : null;\n const recallCtx = await raceWithBudget(\n buildRecallContext(thread_id, trimmed, oldestInWindow),\n RECALL_BUDGET_MS,\n \"\",\n );\n const adaptivePersonaCtx = buildAdaptivePersonaContext(agentCfg, trimmed);\n const harnessParts = resolveHarness(agentCfg);\n\n const systemParts = [\n agentCfg.identity,\n agentCfg.instructions,\n adaptivePersonaCtx,\n userCtx,\n integrationsCtx,\n harnessParts.capabilities,\n harnessParts.plan_first,\n harnessParts.presentation,\n harnessParts.citation,\n timeCtx,\n envCtx,\n harnessParts.self_config,\n memoryCtx,\n recallCtx,\n ].filter(Boolean);\n let allowedTools: string[] = [];\n try {\n allowedTools = JSON.parse(agentCfg.tools) as string[];\n } catch { /* keep empty */ }\n\n const streamOpts: StreamOptions = {\n ...options,\n agent_run_config: {\n system_prompt: systemParts.join(\"\\n\\n\"),\n allowed_tools: allowedTools,\n model_config_name: agentCfg.model_config_name ?? null,\n },\n };\n\n const rawStream = streamWithConfig(thread_id, history, streamOpts, signal);\n return {\n stream: stallRetryStream(rawStream, thread_id, options, signal, _stallRetriesLeft, allowedTools),\n thread_id,\n };\n}\n\n// Wraps the raw agent stream with stall-retry logic. Chunks pass through\n// LIVE to the consumer (so the chat UI sees deltas as they arrive); we only\n// hold the terminal `done` chunk so we can decide whether to retry. If the\n// completed turn produced no tool calls AND the assistant text matches a\n// \"one moment\"-style stall pattern, we inject a forceful nudge as a\n// synthetic user message and forward the retry stream's chunks too. The\n// stalled prose stays visible (already streamed) and a \"↻\" separator marks\n// the boundary; the consumer's text/tool accumulator naturally captures\n// both halves into a single combined assistant message.\nasync function* stallRetryStream(\n inner: AsyncIterable<StreamChunk>,\n thread_id: string,\n options: StreamOptions | undefined,\n signal: AbortSignal | undefined,\n retriesLeft: number,\n allowedTools: readonly string[],\n): AsyncGenerator<StreamChunk> {\n // If no retry budget, just forward everything unchanged. The downstream\n // persistAssistantMessage will still tag a stall or fabrication with a\n // warning footer.\n if (retriesLeft <= 0) {\n for await (const chunk of inner) yield chunk;\n return;\n }\n\n let textBuf = \"\";\n const toolNames: string[] = [];\n let doneChunk: StreamChunk | null = null;\n let sawError = false;\n\n for await (const chunk of inner) {\n if (chunk.type === \"text_delta\") {\n const d = (chunk.data as { delta?: unknown } | undefined)?.delta;\n if (typeof d === \"string\") textBuf += d;\n yield chunk;\n } else if (chunk.type === \"tool_call\") {\n const name = (chunk.data as { name?: unknown } | undefined)?.name;\n if (typeof name === \"string\" && name) toolNames.push(name);\n yield chunk;\n } else if (chunk.type === \"done\") {\n // Hold the terminal marker — if we retry, the retry's `done` closes\n // the turn instead.\n doneChunk = chunk;\n break;\n } else if (chunk.type === \"error\") {\n sawError = true;\n yield chunk;\n return;\n } else {\n yield chunk;\n }\n }\n\n const stalled =\n !sawError &&\n toolNames.length === 0 &&\n textBuf.trim().length > 0 &&\n looksLikeStall(textBuf.trim());\n\n // Fabrication check (ADR-0037): only run when the stall path didn't claim\n // this turn — stall-retry already handles zero-tool stall-prose turns.\n const fabrication = !sawError && !stalled\n ? validateAssistantOutput(textBuf, toolNames, allowedTools)\n : ({ ok: true } as const);\n\n if (!stalled && fabrication.ok) {\n if (doneChunk) yield doneChunk;\n return;\n }\n\n // Visible separator between the stalled prose and the retry continuation,\n // so the user can see something is being re-attempted.\n yield { type: \"text_delta\", data: { delta: \"\\n\\n↻ \" } };\n\n // Inject a forceful nudge as a synthetic user message so the model sees\n // its own flagged reply + an instruction to continue. Stall and fabrication\n // get distinct, reason-aware nudges.\n const nudge = stalled\n ? \"\\u21bb Auto-retry: your previous reply ended with a 'one moment' style promise but you didn't call any tool, which ends the turn with nothing happening. Continue the original task NOW by invoking the appropriate tool. Do not acknowledge, do not apologize \\u2014 just call the tool.\"\n : `\\u21bb Auto-retry: output validator flagged your reply. ${\"reason\" in fabrication ? fabrication.reason : \"\"} Redo this turn without the false claim \\u2014 either call the actual tool, or rephrase as a proposal/question.`;\n\n const retry = await prepareThreadRun(\n thread_id,\n nudge,\n options,\n undefined,\n signal,\n retriesLeft - 1,\n );\n for await (const chunk of retry.stream) yield chunk;\n}\n\nexport function persistAssistantMessage(\n thread_id: string,\n content: string,\n usedTools?: readonly string[],\n toolEvents?: readonly PersistedToolEvent[],\n category: string | null = null,\n): void {\n const trimmed = content.trim();\n // Append a small, persistent footer listing which tools actually ran this\n // turn. Without this, tool_call events are live-only UI — after the stream\n // ends (or on page reload, or if a mobile client missed the brief render)\n // the assistant text remains saying \"I scheduled X\" with no proof a tool\n // ran, which reads as a hallucination even when the tool did execute.\n let final = trimmed;\n const toolList = usedTools ? Array.from(new Set(usedTools.filter(Boolean))) : [];\n // Stall detector: model ended its turn with a \"one moment\" / \"let me check\"\n // promise but invoked no tool. The system prompt forbids this, but models\n // occasionally do it anyway. Marking the message inline gives the user a\n // concrete next-step (\"type continue\") instead of staring at silence.\n if (toolList.length === 0 && trimmed && looksLikeStall(trimmed)) {\n final = `${trimmed}\\n\\n*⚠️ Agent stalled — promised a next step but did not invoke any tool. Reply \"continue\" to retry.*`;\n } else if (toolList.length > 0) {\n final = `${trimmed}\\n\\n*— used: ${toolList.join(\", \")}*`;\n }\n // Fabrication footer (ADR-0037): runs after the retry budget is exhausted\n // and a flagged reply still made it through. Look up allowed tools from\n // the agent config so callers don't have to thread it through.\n if (trimmed && !final.includes(\"*⚠️ Agent stalled\")) {\n const allowedTools = lookupAllowedToolsForThread(thread_id);\n const v = validateAssistantOutput(trimmed, toolList, allowedTools);\n if (!v.ok) {\n final = `${final}\\n\\n*⚠️ Output validator flagged: ${v.reason}*`;\n }\n }\n // Cap individual tool payloads so a single 64KB file_read result doesn't\n // make every reload of this thread re-download a giant blob. Keep the\n // first ~8KB — enough to be useful, small enough to be cheap.\n const sanitizedEvents = toolEvents && toolEvents.length > 0\n ? toolEvents.map(capToolEventPayload)\n : null;\n // Strip the `?autoplay=1` hint that generate_voice embeds in /api/v1/files\n // URLs before persistence. Autoplay is a transient signal for the live\n // streaming client only — reloading the thread, scrolling back, or opening\n // the conversation from another browser must not replay TTS clips the user\n // has already heard.\n const persisted = stripAutoplayHints(final);\n if (persisted || (sanitizedEvents && sanitizedEvents.length > 0)) {\n addMessage(thread_id, \"assistant\", persisted, sanitizedEvents, category);\n if (sanitizedEvents && sanitizedEvents.length > 0) {\n recordToolUsage(sanitizedEvents, persisted);\n }\n }\n}\n\n// Removes `autoplay=1` from /api/v1/files/*.{wav,mp3,...} URLs that appear in\n// the assistant text. Handles it as the sole query param (`?autoplay=1`) or\n// combined with others (`?foo=bar&autoplay=1`, `?autoplay=1&foo=bar`).\nfunction stripAutoplayHints(text: string): string {\n if (!text || !text.includes(\"autoplay=1\")) return text;\n return text.replace(\n /(\\/api\\/v1\\/files\\/[^\\s)\"']+?\\.(?:wav|mp3|ogg|webm|m4a))(\\?[^\\s)\"']*)/gi,\n (_full, base: string, query: string) => {\n const cleaned = query\n .replace(/[?&]autoplay=1\\b/g, \"\")\n .replace(/^&/, \"?\");\n return cleaned === \"?\" || cleaned === \"\" ? base : `${base}${cleaned}`;\n },\n );\n}\n\nconst MAX_PERSISTED_PAYLOAD_BYTES = 8_000;\n\nfunction capToolEventPayload(ev: PersistedToolEvent): PersistedToolEvent {\n try {\n const serialized = JSON.stringify(ev.payload);\n if (serialized.length <= MAX_PERSISTED_PAYLOAD_BYTES) return ev;\n return {\n ...ev,\n payload: {\n __truncated: true,\n preview: serialized.slice(0, MAX_PERSISTED_PAYLOAD_BYTES),\n original_bytes: serialized.length,\n },\n };\n } catch {\n return { ...ev, payload: { __truncated: true, error: \"unserializable\" } };\n }\n}\n\nconst STALL_PATTERNS: RegExp[] = [\n /\\bone (moment|sec(?:ond)?)\\b/i,\n /\\bgive me (a|just a) (moment|sec(?:ond)?|minute)\\b/i,\n /\\bhold on\\b/i,\n /\\bjust a (moment|sec(?:ond)?|minute)\\b/i,\n /\\bbear with me\\b/i,\n /\\blet me (check|verify|continue|proceed|look|try|do (?:that|this|it))\\b/i,\n /\\bi['’]?ll (check|verify|continue|proceed|look|try|do (?:that|this|it)|keep going|get (?:on|right) (?:on|to))/i,\n /\\b(continuing|proceeding|working on it|moving on)\\b.*[!.]?\\s*$/i,\n];\n\n// Resolve the agent's allowed_tools list from a thread id. Best-effort: empty\n// list if the thread or agent config has gone away (the validator then\n// flags any `(via foo)` citation as unregistered, which is the safe default).\nfunction lookupAllowedToolsForThread(thread_id: string): string[] {\n try {\n const thread = getThread(thread_id);\n if (!thread) return [];\n const agentCfg = getAgentConfig(thread.agent_id);\n if (!agentCfg) return [];\n const parsed = JSON.parse(agentCfg.tools) as unknown;\n return Array.isArray(parsed) ? parsed.filter((t): t is string => typeof t === \"string\") : [];\n } catch {\n return [];\n }\n}\n\nexport function looksLikeStall(text: string): boolean {\n // Inspect the last paragraph / sentence \\u2014 earlier acknowledgment\n // language is fine when followed by real work. The stall signal is when\n // the message ends on a promise.\n const tail = text.split(/\\n{2,}|(?<=[.!?])\\s+/).filter(Boolean).slice(-2).join(\" \");\n return STALL_PATTERNS.some((re) => re.test(tail));\n}\n\n// Run semantic recall on the user's turn, format the top hits as a system-prompt\n// block. Empty string when no embeddings configured or no good matches.\nasync function buildRecallContext(\n current_thread_id: string,\n query: string,\n windowOldestContent: string | null,\n): Promise<string> {\n if (!query.trim()) return \"\";\n let hits: RecalledMemory[];\n try {\n hits = await recall(query, 6);\n } catch {\n return \"\";\n }\n if (hits.length === 0) return \"\";\n\n // Drop matches that already live in the in-prompt history window.\n const filtered = hits.filter((h) => {\n if (h.source === \"message\" && h.thread_id === current_thread_id) {\n // crude but cheap: skip if it's the same content as anything in the window\n return windowOldestContent !== h.content;\n }\n return true;\n });\n if (filtered.length === 0) return \"\";\n\n const lines = [\n \"--- Your retrieved memory for this turn ---\",\n \"These entries were pulled from YOUR own memory store (not user-supplied just now).\",\n \"Treat them as facts you previously committed to remember. Cite them confidently when relevant.\",\n \"\",\n ];\n for (const h of filtered) {\n const stamp = h.created_at.slice(0, 10);\n if (h.source === \"memory\") {\n lines.push(`• [memory ${h.namespace}/${h.key}, ${stamp}] ${truncate(h.content, 280)}`);\n } else {\n const tag = h.thread_id === current_thread_id ? \"earlier this thread\" : \"past chat\";\n lines.push(`• [${tag} · ${h.role}, ${stamp}] ${truncate(h.content, 280)}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction truncate(s: string, max: number): string {\n const flat = s.replace(/\\s+/g, \" \").trim();\n return flat.length > max ? flat.slice(0, max) + \"…\" : flat;\n}\n\nexport function shouldEmitChunk(\n chunkType: StreamChunk[\"type\"],\n options?: StreamOptions,\n): boolean {\n const includeTools = options?.filters?.include_tools ?? true;\n const includeThinking = options?.filters?.include_thinking ?? true;\n if (!includeTools && (chunkType === \"tool_call\" || chunkType === \"tool_result\")) return false;\n if (!includeThinking && chunkType === \"thinking_delta\") return false;\n return true;\n}\n\nexport { contentText };\n","// Watcher store (ADR-0027). Sibling to lib/stores/scheduled-tasks.ts;\n// shape mirrors it so the UI + trigger plumbing can treat them as\n// near-equivalents apart from the diff-aware fields.\nimport { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\nimport {\n normaliseReactionPrompt,\n normaliseReactionScriptArgs,\n resolveReaction,\n validateReactionScript,\n type ReactionKind,\n type ResolvedReaction,\n} from \"./reaction-shared\";\n\n// Re-export so existing imports of these helpers from `@/lib/stores/watchers`\n// keep working (back-compat for tests + any historical call site).\nexport {\n normaliseReactionPrompt,\n normaliseReactionScriptArgs,\n validateReactionScript,\n type ReactionKind,\n};\n\nexport interface WatcherRow {\n id: string;\n agent_id: string;\n label: string;\n tool_name: string;\n tool_args: string; // JSON-encoded record passed to the tool\n interval_seconds: number;\n last_fingerprint: string | null;\n last_result: string | null; // stringified previous tool output, for the diff prompt\n last_run_at: string | null; // ISO — most recent poll, regardless of whether it fired\n last_fired_at: string | null; // ISO — most recent firing (i.e. fingerprint changed)\n last_error: string | null;\n next_run_at: string; // ISO\n enabled: number; // 0 | 1\n silent: number; // 0 | 1\n reaction_prompt: string | null; // ADR-0030: user-supplied directive; NULL = default\n reaction_kind: ReactionKind; // ADR-0031\n reaction_script: string | null; // ADR-0031: registry key when reaction_kind='script'\n reaction_script_args: string | null; // ADR-0031: JSON-encoded args bag\n created_at: string;\n updated_at: string;\n}\n\nconst MIN_INTERVAL_SECONDS = 60;\nconst now = () => new Date().toISOString();\n\nexport function clampInterval(seconds: number): number {\n if (!Number.isFinite(seconds)) throw new Error(\"interval_seconds must be a finite number\");\n const n = Math.floor(seconds);\n if (n < MIN_INTERVAL_SECONDS) {\n throw new Error(`interval_seconds must be >= ${MIN_INTERVAL_SECONDS}`);\n }\n return n;\n}\n\nexport interface CreateWatcherInput {\n agent_id: string;\n label: string;\n tool_name: string;\n tool_args?: Record<string, unknown>;\n interval_seconds: number;\n silent?: boolean;\n // ADR-0030 / ADR-0031: only one reaction is active per watcher.\n // - kind 'agent_prompt' (default): reaction_prompt is the optional directive.\n // - kind 'script': reaction_script + reaction_script_args drive a script firing.\n reaction_kind?: ReactionKind;\n reaction_prompt?: string | null;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\nexport function createWatcher(input: CreateWatcherInput): WatcherRow {\n const id = randomUUID();\n const t = now();\n const interval = clampInterval(input.interval_seconds);\n // Schedule the very first poll for `interval` seconds from now. The\n // agent-facing tool description tells the agent to call list_watchers\n // or wait one cycle; we don't fire immediately to avoid stampedes\n // when an agent registers a watcher.\n const next = new Date(Date.now() + interval * 1000).toISOString();\n const argsJson = JSON.stringify(input.tool_args ?? {});\n const silent = input.silent ? 1 : 0;\n const reaction = resolveReaction(input);\n getDb()\n .prepare(\n `INSERT INTO watchers\n (id, agent_id, label, tool_name, tool_args, interval_seconds,\n last_fingerprint, last_result, last_run_at, last_fired_at, last_error,\n next_run_at, enabled, silent, reaction_prompt,\n reaction_kind, reaction_script, reaction_script_args,\n created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, NULL, NULL, NULL, NULL, NULL, ?, 1, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n id, input.agent_id, input.label, input.tool_name, argsJson, interval, next, silent,\n reaction.prompt, reaction.kind, reaction.script, reaction.scriptArgs, t, t,\n );\n return {\n id,\n agent_id: input.agent_id,\n label: input.label,\n tool_name: input.tool_name,\n tool_args: argsJson,\n interval_seconds: interval,\n last_fingerprint: null,\n last_result: null,\n last_run_at: null,\n last_fired_at: null,\n last_error: null,\n next_run_at: next,\n enabled: 1,\n silent,\n reaction_prompt: reaction.prompt,\n reaction_kind: reaction.kind,\n reaction_script: reaction.script,\n reaction_script_args: reaction.scriptArgs,\n created_at: t,\n updated_at: t,\n };\n}\n\nexport function listWatchers(agentId?: string): WatcherRow[] {\n const db = getDb();\n const rows = agentId\n ? db.prepare(\"SELECT * FROM watchers WHERE agent_id=? ORDER BY next_run_at ASC\").all(agentId)\n : db.prepare(\"SELECT * FROM watchers ORDER BY next_run_at ASC\").all();\n return rows as unknown as WatcherRow[];\n}\n\nexport function getWatcher(id: string): WatcherRow | null {\n const row = getDb().prepare(\"SELECT * FROM watchers WHERE id=?\").get(id);\n return (row as WatcherRow | undefined) ?? null;\n}\n\nexport function getDueWatchers(asOf: Date = new Date()): WatcherRow[] {\n return getDb()\n .prepare(\"SELECT * FROM watchers WHERE enabled=1 AND next_run_at <= ? ORDER BY next_run_at ASC\")\n .all(asOf.toISOString()) as unknown as WatcherRow[];\n}\n\nexport function deleteWatcher(id: string): boolean {\n const r = getDb().prepare(\"DELETE FROM watchers WHERE id=?\").run(id);\n return r.changes > 0;\n}\n\nexport interface UpdateWatcherInput {\n label?: string;\n interval_seconds?: number;\n enabled?: boolean;\n silent?: boolean;\n // ADR-0030 / ADR-0031: a PATCH may swap the reaction kind. The semantics\n // mirror the create input — if reaction_kind is provided, the reaction is\n // fully replaced (the other branch's fields are forced NULL). If\n // reaction_kind is absent, only the matching field for the EXISTING kind\n // can be updated. undefined leaves a field alone; null clears it.\n reaction_kind?: ReactionKind;\n reaction_prompt?: string | null;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\nexport function updateWatcher(id: string, patch: UpdateWatcherInput): WatcherRow | null {\n const existing = getWatcher(id);\n if (!existing) return null;\n const t = now();\n const interval = patch.interval_seconds !== undefined\n ? clampInterval(patch.interval_seconds)\n : existing.interval_seconds;\n // Only recompute next_run_at when the interval changed; otherwise keep\n // the existing schedule so a label edit doesn't reset the cycle.\n const nextRunAt = patch.interval_seconds !== undefined\n ? new Date(Date.now() + interval * 1000).toISOString()\n : existing.next_run_at;\n\n // Compute the reaction columns. Two cases:\n // 1. patch.reaction_kind is set → fully resolve the patch as a new reaction.\n // 2. patch.reaction_kind is absent → keep the existing kind, but allow the\n // matching branch's field to be patched (e.g. update reaction_prompt\n // while staying in 'agent_prompt' kind).\n let reaction: ResolvedReaction;\n if (patch.reaction_kind !== undefined) {\n reaction = resolveReaction({\n reaction_kind: patch.reaction_kind,\n reaction_prompt: patch.reaction_prompt,\n reaction_script: patch.reaction_script,\n reaction_script_args: patch.reaction_script_args,\n });\n } else if (existing.reaction_kind === \"script\") {\n const script = patch.reaction_script === undefined\n ? existing.reaction_script\n : (patch.reaction_script === null ? null : validateReactionScript(patch.reaction_script));\n if (!script) {\n throw new Error(\n \"reaction_script cannot be cleared while reaction_kind='script' — switch reaction_kind to 'agent_prompt' instead\",\n );\n }\n const scriptArgs = patch.reaction_script_args === undefined\n ? existing.reaction_script_args\n : normaliseReactionScriptArgs(patch.reaction_script_args);\n reaction = { kind: \"script\", prompt: null, script, scriptArgs };\n } else {\n const prompt = patch.reaction_prompt === undefined\n ? existing.reaction_prompt\n : normaliseReactionPrompt(patch.reaction_prompt);\n reaction = { kind: \"agent_prompt\", prompt, script: null, scriptArgs: null };\n }\n\n getDb()\n .prepare(\n `UPDATE watchers\n SET label=?, interval_seconds=?, next_run_at=?, enabled=?, silent=?,\n reaction_prompt=?, reaction_kind=?, reaction_script=?, reaction_script_args=?,\n updated_at=?\n WHERE id=?`,\n )\n .run(\n patch.label ?? existing.label,\n interval,\n nextRunAt,\n patch.enabled === undefined ? existing.enabled : (patch.enabled ? 1 : 0),\n patch.silent === undefined ? existing.silent : (patch.silent ? 1 : 0),\n reaction.prompt,\n reaction.kind,\n reaction.script,\n reaction.scriptArgs,\n t,\n id,\n );\n return getWatcher(id);\n}\n\n// Bookkeeping after a poll. Always advances next_run_at. `fired`\n// indicates the fingerprint changed; when false we still update\n// last_run_at + last_fingerprint (first run, or unchanged).\nexport function recordWatcherPoll(input: {\n id: string;\n fingerprint: string;\n result: string;\n fired: boolean;\n error?: string;\n}): void {\n const existing = getWatcher(input.id);\n if (!existing) return;\n const t = now();\n const nextRunAt = new Date(Date.now() + existing.interval_seconds * 1000).toISOString();\n getDb()\n .prepare(\n `UPDATE watchers\n SET last_fingerprint=?, last_result=?, last_run_at=?,\n last_fired_at=COALESCE(?, last_fired_at),\n last_error=?, next_run_at=?, updated_at=?\n WHERE id=?`,\n )\n .run(\n input.fingerprint,\n input.result,\n t,\n input.fired ? t : null,\n input.error ?? null,\n nextRunAt,\n t,\n input.id,\n );\n}\n\nexport function recordWatcherPollError(id: string, error: string): void {\n const existing = getWatcher(id);\n if (!existing) return;\n const t = now();\n const nextRunAt = new Date(Date.now() + existing.interval_seconds * 1000).toISOString();\n getDb()\n .prepare(\n `UPDATE watchers SET last_run_at=?, last_error=?, next_run_at=?, updated_at=? WHERE id=?`,\n )\n .run(t, error, nextRunAt, t, id);\n}\n","// JSON.parse with a fallback value when the input is malformed (or empty).\n// Used everywhere we read responses from external APIs — they're contractually\n// JSON but a transient 502 / proxy interstitial occasionally returns HTML.\nexport function parseJsonSafe<T>(text: string, fallback: T): T;\nexport function parseJsonSafe<T>(text: string): T | undefined;\nexport function parseJsonSafe<T>(text: string, fallback?: T): T | undefined {\n try {\n return JSON.parse(text) as T;\n } catch {\n return fallback;\n }\n}\n","// Tool registry.\n//\n// Each built-in tool module registers its own tools + category at module\n// load. lib/tools/index.ts only needs to side-effect-import the modules\n// (see ./builtins.ts) — there is no central map listing every tool by\n// name. Adding a new built-in tool now requires touching exactly two\n// files: the tool file itself, and an `import \"./<name>\";` line in\n// builtins.ts.\n//\n// External tools (loaded from JARELA_TOOLS_DIR at runtime) use the same\n// category vocabulary but are not stored in this registry — see\n// ./external.ts. MCP tools default to category \"MCP\".\n\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\n\nexport type ToolCategory =\n | \"Memory\" | \"Documents\" | \"Files\" | \"Shell\" | \"Web\" | \"Images\" | \"Voice\"\n | \"Schedule\" | \"Atlassian\" | \"JiraAlign\" | \"GitHub\" | \"Mail\" | \"Calendar\" | \"Config\" | \"MCP\";\n\n// Optional parent grouping for the Agent editor sidebar.\nexport type ToolGroup = \"Work\" | null;\n\n// Category → group mapping. \"Work\" collapses corporate-auth tools under\n// one header in the Agent editor; everything else is a top-level category.\nconst CATEGORY_GROUPS: Record<Exclude<ToolCategory, \"MCP\">, ToolGroup> = {\n Memory: null, Documents: null, Files: null, Shell: null, Web: null, Images: null, Voice: null,\n Schedule: null, Config: null, Mail: null, Calendar: null,\n Atlassian: \"Work\", JiraAlign: \"Work\", GitHub: \"Work\",\n};\n\nexport type BuiltinCategory = Exclude<ToolCategory, \"MCP\">;\n\ninterface RegistryEntry {\n tool: StructuredToolInterface;\n category: BuiltinCategory;\n group: ToolGroup;\n}\n\nconst REGISTRY = new Map<string, RegistryEntry>();\n\n/**\n * Register one or more tools under a category. Call this at the bottom of\n * each tool file (after the tools are defined). Throws on duplicate names\n * — collisions are bugs, not warnings.\n */\nexport function registerTools<T extends StructuredToolInterface>(\n category: BuiltinCategory,\n tools: readonly T[],\n): readonly T[] {\n const group = CATEGORY_GROUPS[category];\n for (const t of tools) {\n if (REGISTRY.has(t.name)) {\n throw new Error(`[tools] duplicate built-in tool registration: ${t.name}`);\n }\n REGISTRY.set(t.name, { tool: t, category, group });\n }\n return tools;\n}\n\n/** All registered built-in tools, in registration order. */\nexport function registeredTools(): StructuredToolInterface[] {\n return Array.from(REGISTRY.values(), (e) => e.tool);\n}\n\n/** Names of all registered built-in tools — used for collision checks. */\nexport function registeredNames(): ReadonlySet<string> {\n return new Set(REGISTRY.keys());\n}\n\nexport function registeredCategory(name: string): BuiltinCategory | undefined {\n return REGISTRY.get(name)?.category;\n}\n\nexport function registeredGroup(name: string): ToolGroup | undefined {\n return REGISTRY.get(name)?.group;\n}\n\n/** Test-only: clear the registry between cases. */\nexport function _resetRegistry(): void {\n REGISTRY.clear();\n}\n","// Ephemeral state store for the in-app Gmail OAuth flow.\n//\n// The user types client_id + client_secret in the Integrations panel and clicks\n// \"Connect Gmail\". We POST those to /oauth/start, which stashes them here keyed\n// by a random `state` token and returns the Google authorize URL. The browser\n// opens that URL; Google bounces back to /oauth/callback with `?code&state`,\n// which exchanges the code for a refresh_token and persists the integration.\n// Meanwhile the panel polls /oauth/status to know when to refresh.\n//\n// Pinned to globalThis so HMR in dev doesn't lose pending flows.\n\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { createOAuthFlowStore, type OAuthFlow } from \"@/lib/utils/oauth-flow-store\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\n\nexport type { OAuthFlow };\n\nconst flowStore = createOAuthFlowStore({ globalKey: \"__ggOauthFlows\" });\n\nexport const createFlow = flowStore.create;\nexport const getFlow = flowStore.get;\nexport const updateFlow = flowStore.update;\nexport const deleteFlow = flowStore.delete;\n\nexport const GMAIL_SCOPES = [\n \"https://www.googleapis.com/auth/gmail.modify\",\n \"https://www.googleapis.com/auth/gmail.compose\",\n // Calendar: read/write events on the user's existing calendars. Narrow\n // scope on purpose — doesn't grant create/delete of entire calendars\n // (matches the principle-of-least-privilege the Gmail scopes follow).\n \"https://www.googleapis.com/auth/calendar.events\",\n // Read-only metadata of the user's calendar list. Required for the\n // calendarList.list endpoint that powers calendarListCalendarsTool —\n // calendar.events alone returns 403 there.\n \"https://www.googleapis.com/auth/calendar.readonly\",\n];\n\nexport function buildAuthorizeUrl(opts: {\n clientId: string;\n redirectUri: string;\n state: string;\n}): string {\n const p = new URLSearchParams({\n client_id: opts.clientId,\n redirect_uri: opts.redirectUri,\n response_type: \"code\",\n scope: GMAIL_SCOPES.join(\" \"),\n access_type: \"offline\",\n prompt: \"consent\",\n include_granted_scopes: \"true\",\n state: opts.state,\n });\n return `https://accounts.google.com/o/oauth2/v2/auth?${p.toString()}`;\n}\n\nexport async function exchangeCode(opts: {\n code: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n}): Promise<{ refresh_token?: string; access_token?: string; expires_in?: number; scope?: string }> {\n const body = new URLSearchParams({\n code: opts.code,\n client_id: opts.clientId,\n client_secret: opts.clientSecret,\n redirect_uri: opts.redirectUri,\n grant_type: \"authorization_code\",\n });\n const res = await fetch(\"https://oauth2.googleapis.com/token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n const parsed = parseJsonSafe<Record<string, unknown>>(text, {});\n if (!res.ok) {\n const err = (parsed[\"error_description\"] || parsed[\"error\"] || text || `HTTP ${res.status}`) as string;\n throw new Error(err);\n }\n return parsed as { refresh_token?: string; access_token?: string; expires_in?: number; scope?: string };\n}\n\n// ---------------------------------------------------------------------------\n// Shared Google API auth (Gmail + Calendar + any future Google scope)\n// ---------------------------------------------------------------------------\n//\n// The same OAuth client (stored under integration name \"gmail\" for back-compat)\n// grants every Google scope we ask for. Tools across `lib/tools/` share these\n// helpers so a burst of mixed Gmail+Calendar calls hits Google's token\n// endpoint once per refresh, not once per file.\n\nexport interface GoogleAuth {\n client_id: string;\n client_secret: string;\n refresh_token: string;\n}\n\nexport function resolveGoogleAuth(): GoogleAuth | { error: string } {\n const envId = process.env.GMAIL_CLIENT_ID;\n const envSecret = process.env.GMAIL_CLIENT_SECRET;\n const envRefresh = process.env.GMAIL_REFRESH_TOKEN;\n if (envId && envSecret && envRefresh) {\n return { client_id: envId, client_secret: envSecret, refresh_token: envRefresh };\n }\n const saved = getIntegrationRaw(\"gmail\");\n if (saved?.client_id && saved.client_secret && saved.refresh_token) {\n return {\n client_id: saved.client_id,\n client_secret: saved.client_secret,\n refresh_token: saved.refresh_token,\n };\n }\n return {\n error:\n \"Google account not connected. Open the gear menu → Integrations tab → \" +\n \"Gmail card and click Connect Gmail to authorize Gmail + Calendar access.\",\n };\n}\n\ninterface CachedAccessToken { token: string; expires_at: number }\nconst accessTokenCache = new Map<string, CachedAccessToken>();\n\nexport async function getGoogleAccessToken(\n auth: GoogleAuth,\n): Promise<string | { error: string }> {\n const key = auth.refresh_token.slice(0, 20);\n const cached = accessTokenCache.get(key);\n if (cached && cached.expires_at > Date.now() + 60_000) return cached.token;\n\n const body = new URLSearchParams({\n client_id: auth.client_id,\n client_secret: auth.client_secret,\n refresh_token: auth.refresh_token,\n grant_type: \"refresh_token\",\n });\n try {\n const res = await fetch(\"https://oauth2.googleapis.com/token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n if (!res.ok) {\n // Drop any stale cached token so a reconnected (broader-scope) refresh\n // re-exchanges cleanly on the next call.\n accessTokenCache.delete(key);\n return { error: `OAuth token refresh failed (${res.status}): ${text.slice(0, 300)}` };\n }\n const parsed = JSON.parse(text) as { access_token?: string; expires_in?: number };\n if (!parsed.access_token) return { error: \"OAuth response missing access_token\" };\n const expires_at = Date.now() + (parsed.expires_in ?? 3000) * 1000;\n accessTokenCache.set(key, { token: parsed.access_token, expires_at });\n return parsed.access_token;\n } catch (err) {\n return { error: `OAuth token refresh threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n\n/**\n * Shared bearer-auth fetch for Google REST APIs (Gmail, Calendar, ...).\n *\n * Behaviour:\n * - Resolves access token from `auth`; if that fails, the error object is\n * surfaced unchanged so callers can pass it back to the agent.\n * - 204 No Content → `{ ok: true }` (used by DELETE endpoints).\n * - Non-2xx response → `{ error: \"<service> <status>: <body slice>\", url }`.\n * - 2xx with body → parsed JSON if possible, raw text otherwise.\n * - Fetch throws (DNS, abort, timeout) → `{ error: \"<service> fetch threw: ...\" }`.\n *\n * @param service Short tag used in error messages, e.g. \"Gmail\" or \"Calendar\".\n * @param baseUrl Base for relative `path` (e.g. `https://gmail.googleapis.com/gmail/v1/users/me`).\n * @param path Either a full URL (starts with `http`) or path appended to baseUrl.\n */\nexport async function googleFetch(\n auth: GoogleAuth,\n service: string,\n baseUrl: string,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const token = await getGoogleAccessToken(auth);\n if (typeof token !== \"string\") return token;\n const url = path.startsWith(\"http\") ? path : `${baseUrl}${path}`;\n try {\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n signal: AbortSignal.timeout(30_000),\n });\n if (res.status === 204) return { ok: true };\n const text = await res.text();\n if (!res.ok) {\n return { error: `${service} ${res.status}: ${text.slice(0, 500)}`, url };\n }\n try { return JSON.parse(text); } catch { return text; }\n } catch (err) {\n return { error: `${service} fetch threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n","/**\n * Native GitHub tools — direct REST API calls, no MCP, no `gh` CLI.\n *\n * Mirrors the Atlassian tool (lib/tools/atlassian.ts) in shape: the agent\n * never shells out, every call goes through the same `fetch` global that\n * already honours the in-app HTTP proxy + custom CA bundle (ADR-0009,\n * ADR-0012). That means these tools work on a corp laptop with the MCP\n * install path blocked, which was the whole point of building them native.\n *\n * Auth resolution (priority order):\n * 1. Env: GITHUB_TOKEN, then GH_TOKEN (matches gh CLI's fallback chain).\n * 2. Memory store: namespace=\"integrations\", key=\"github\", value={ token }.\n *\n * The agent populates option 2 via the propose_config_change /\n * enable_integration flow (ADR-0010); env wins because deployment-level\n * config should beat per-user secrets stored in the local DB.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\nimport { isLikelyBinary } from \"@/lib/documents/indexer\";\nimport { registerTools } from \"./registry\";\n\nexport interface GitHubAuth {\n token: string;\n}\n\n// Exposed so the integrations test endpoint can probe the live API after save.\nexport function _resolveGithubAuth(): GitHubAuth | { error: string } {\n return resolveAuth();\n}\n\nfunction resolveAuth(): GitHubAuth | { error: string } {\n const env = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;\n if (env && env.trim()) return { token: env.trim() };\n const saved = getIntegrationRaw(\"github\");\n if (saved?.token) return { token: saved.token };\n return {\n error:\n \"GitHub not configured. Open the gear menu → Integrations and add a Personal Access Token. \" +\n \"Create one at github.com/settings/tokens with scopes: repo, read:org. \" +\n \"(Or set GITHUB_TOKEN / GH_TOKEN as an env var.)\",\n };\n}\n\nconst API = \"https://api.github.com\";\n\nasync function ghFetch(\n auth: GitHubAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const url = path.startsWith(\"http\") ? path : `${API}${path}`;\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${auth.token}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n \"User-Agent\": \"Jarela\",\n ...(init?.headers ?? {}),\n },\n });\n const text = await res.text();\n if (!res.ok) {\n return { error: `GitHub ${res.status}: ${text.slice(0, 500)}`, url };\n }\n if (!text) return {};\n return parseJsonSafe<unknown>(text, text);\n}\n\n// Exposed for sibling modules that need the same auth/proxy/CA-bundle\n// behaviour without duplicating the wrapper (currently:\n// `lib/documents/remote/github.ts`, ADR-0029). Mirrors `_atlassianFetch`.\nexport async function _ghFetch(\n auth: GitHubAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n return ghFetch(auth, path, init);\n}\n\n// ── Shared helpers ─────────────────────────────────────────────────────────\n\nconst BODY_CAP = 20_000;\nconst COMMENT_CAP = 8_000;\nconst PATCH_CAP = 8_000;\nconst SNIPPET_CAP = 400;\n\n// Pure-fn body cap. Returns the same `body` field shape as the existing\n// inline ternaries in github_get_issue / github_get_pull (str + truncated\n// flag) so the agent doesn't need to handle two shapes.\nexport function truncate(text: string, cap: number): { text: string; truncated: boolean } {\n if (text.length <= cap) return { text, truncated: false };\n return { text: text.slice(0, cap), truncated: true };\n}\n\n// `/repos/.../contents/{path}` returns a base64-encoded blob; the API also\n// returns the same response shape for directories (as an array). Decode +\n// detect binary so the agent gets useful output for text and a clear\n// not-text signal for everything else.\nexport interface DecodedBlob {\n binary: boolean;\n text?: string;\n size_bytes: number;\n}\nexport function decodeContentsBlob(content: string, encoding: string | undefined): DecodedBlob {\n if (!content) return { binary: false, text: \"\", size_bytes: 0 };\n const b64 = encoding === \"base64\" ? content.replace(/\\s+/g, \"\") : \"\";\n const buf = b64 ? Buffer.from(b64, \"base64\") : Buffer.from(content, \"utf8\");\n if (isLikelyBinary(buf)) return { binary: true, size_bytes: buf.length };\n return { binary: false, text: buf.toString(\"utf8\"), size_bytes: buf.length };\n}\n\n// Trim repo URLs on issue/PR responses to user-facing html_urls (the API\n// returns api.github.com/repos/... which is useless for a human).\ntype GhUser = { login?: string } | null;\ntype GhLabel = { name?: string };\n\nfunction liteUser(u: unknown): string | null {\n return (u as GhUser)?.login ?? null;\n}\nfunction liteLabels(labels: unknown): string[] {\n return (labels as GhLabel[] | undefined ?? []).map((l) => l.name).filter(Boolean) as string[];\n}\n\ntype GhIssueLite = {\n number?: number;\n title?: string;\n state?: string;\n html_url?: string;\n user?: GhUser;\n labels?: GhLabel[];\n pull_request?: unknown; // presence means \"this issue is actually a PR\"\n updated_at?: string;\n comments?: number;\n};\n\n// ── Issue tools ────────────────────────────────────────────────────────────\n\nexport const githubSearchIssuesTool = tool(\n async ({ q, repo, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n // `repo:owner/name` is the dominant filter — accept it as a separate\n // parameter so the agent doesn't have to remember GitHub's search syntax\n // for the common case. Anything else goes in `q`.\n const query = repo ? `repo:${repo} ${q}` : q;\n const data = await ghFetch(\n auth,\n `/search/issues?q=${encodeURIComponent(query)}&per_page=${limit}`,\n ) as { items?: GhIssueLite[]; total_count?: number; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total_count ?? 0,\n items: (data.items ?? []).map((i) => ({\n number: i.number,\n title: i.title,\n state: i.state,\n is_pr: !!i.pull_request,\n url: i.html_url,\n user: liteUser(i.user),\n labels: liteLabels(i.labels),\n updated_at: i.updated_at,\n comments: i.comments ?? 0,\n })),\n });\n },\n {\n name: \"github_search_issues\",\n description:\n \"Search GitHub issues AND pull requests with the same query syntax as the github.com search bar. \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** Pass `repo` (\\\"owner/name\\\") to scope the search \" +\n \"to a single repo — the tool prepends `repo:owner/name ` automatically. The `q` body accepts the \" +\n \"full GitHub search vocabulary: 'is:issue is:open assignee:@me', 'is:pr review-requested:@me', \" +\n \"'label:bug created:>2026-01-01', etc. `is_pr` in the response distinguishes PRs from issues.\",\n schema: z.object({\n q: z.string().describe(\"GitHub search query (e.g. 'is:open is:issue label:bug')\"),\n repo: z.string().optional().describe(\"Optional 'owner/name' shortcut; prepended as repo: filter\"),\n max_results: z.number().optional().describe(\"Max items (default 25, max 100)\"),\n }),\n },\n);\n\nexport const githubGetIssueTool = tool(\n async ({ owner, repo, number }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const assignees = (data.assignees as Array<{ login?: string }> | undefined ?? [])\n .map((a) => a.login).filter(Boolean);\n const cap = truncate(typeof data.body === \"string\" ? data.body : \"\", BODY_CAP);\n return JSON.stringify({\n number: data.number,\n title: data.title,\n state: data.state,\n is_pr: !!data.pull_request,\n url: data.html_url,\n author: liteUser(data.user),\n labels: liteLabels(data.labels),\n assignees,\n created_at: data.created_at,\n updated_at: data.updated_at,\n closed_at: data.closed_at,\n comments: data.comments,\n body: cap.text,\n truncated: cap.truncated,\n });\n },\n {\n name: \"github_get_issue\",\n description:\n \"Fetch a single issue (or PR — same endpoint) by number. Returns body capped at 20KB, plus labels, \" +\n \"assignees, and timestamps. **PREFER THIS over shell-exec'ing the `gh` CLI.**\",\n schema: z.object({\n owner: z.string().describe(\"Repository owner (user or org)\"),\n repo: z.string().describe(\"Repository name\"),\n number: z.number().int().positive().describe(\"Issue or PR number\"),\n }),\n },\n);\n\nexport const githubCreateIssueTool = tool(\n async ({ owner, repo, title, body, labels, assignees }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = { title };\n if (body) payload.body = body;\n if (labels?.length) payload.labels = labels;\n if (assignees?.length) payload.assignees = assignees;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, number: data.number, url: data.html_url });\n },\n {\n name: \"github_create_issue\",\n description:\n \"Open a new issue in a repository. **PREFER THIS over shell-exec'ing the `gh` CLI.** Labels and \" +\n \"assignees must already exist on the repo — invalid values produce a 422.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n title: z.string().describe(\"Issue title\"),\n body: z.string().optional().describe(\"Markdown body\"),\n labels: z.array(z.string()).optional().describe(\"Existing label names\"),\n assignees: z.array(z.string()).optional().describe(\"GitHub usernames with access\"),\n }),\n },\n);\n\nexport const githubAddCommentTool = tool(\n async ({ owner, repo, number, body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Same endpoint for issues AND PRs — GitHub treats PR comments as issue\n // comments (the line-level review comments are a different surface).\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}/comments`,\n { method: \"POST\", body: JSON.stringify({ body }) },\n ) as { id?: number; html_url?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, comment_id: data.id, url: data.html_url });\n },\n {\n name: \"github_add_comment\",\n description:\n \"Post a comment on an issue or pull request (GitHub treats both the same). \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** Body is rendered as GitHub-flavored Markdown.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n body: z.string().describe(\"Comment body (GitHub-flavored Markdown)\"),\n }),\n },\n);\n\n// ── Pull-request tools ─────────────────────────────────────────────────────\n\nexport const githubListPullsTool = tool(\n async ({ owner, repo, state, head, base, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const params = new URLSearchParams({ per_page: String(limit) });\n if (state) params.set(\"state\", state);\n if (head) params.set(\"head\", head);\n if (base) params.set(\"base\", base);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls?${params.toString()}`,\n ) as Array<Record<string, unknown>> | { error?: string; message?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n pulls: data.map((p) => ({\n number: p.number,\n title: p.title,\n state: p.state,\n draft: p.draft,\n url: p.html_url,\n user: liteUser(p.user),\n head: (p.head as { ref?: string } | null)?.ref ?? null,\n base: (p.base as { ref?: string } | null)?.ref ?? null,\n created_at: p.created_at,\n updated_at: p.updated_at,\n })),\n });\n },\n {\n name: \"github_list_pulls\",\n description:\n \"List pull requests for a repository, optionally filtered by state / head branch / base branch. \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** For richer detail on a single PR (mergeable, \" +\n \"review state, file count) call github_get_pull.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n state: z.enum([\"open\", \"closed\", \"all\"]).optional().describe(\"Default: open\"),\n head: z.string().optional().describe(\"Filter by head: 'user:branch' or 'org:branch'\"),\n base: z.string().optional().describe(\"Filter by base branch (e.g. 'main')\"),\n max_results: z.number().optional().describe(\"Max PRs (default 25, max 100)\"),\n }),\n },\n);\n\nexport const githubGetPullTool = tool(\n async ({ owner, repo, number }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const head = data.head as { ref?: string; sha?: string; repo?: { full_name?: string } } | null;\n const base = data.base as { ref?: string; sha?: string } | null;\n const cap = truncate(typeof data.body === \"string\" ? data.body : \"\", BODY_CAP);\n return JSON.stringify({\n number: data.number,\n title: data.title,\n state: data.state,\n draft: data.draft,\n merged: data.merged,\n mergeable: data.mergeable, // null = GitHub still computing\n mergeable_state: data.mergeable_state,\n url: data.html_url,\n author: liteUser(data.user),\n head: head ? { ref: head.ref, sha: head.sha, repo: head.repo?.full_name } : null,\n base: base ? { ref: base.ref, sha: base.sha } : null,\n changed_files: data.changed_files,\n additions: data.additions,\n deletions: data.deletions,\n review_comments: data.review_comments,\n comments: data.comments,\n created_at: data.created_at,\n updated_at: data.updated_at,\n merged_at: data.merged_at,\n body: cap.text,\n truncated: cap.truncated,\n });\n },\n {\n name: \"github_get_pull\",\n description:\n \"Fetch detail on a single pull request — head/base SHAs, mergeable state, additions/deletions, \" +\n \"changed files count, review comment count. **PREFER THIS over shell-exec'ing the `gh` CLI.** \" +\n \"Note: `mergeable` may be null on a freshly-pushed PR; GitHub computes it asynchronously.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n }),\n },\n);\n\n// ── Repo info ───────────────────────────────────────────────────────────────\n\nexport const githubGetRepoTool = tool(\n async ({ owner, repo }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n full_name: data.full_name,\n url: data.html_url,\n description: data.description,\n visibility: data.visibility ?? (data.private ? \"private\" : \"public\"),\n default_branch: data.default_branch,\n topics: data.topics ?? [],\n language: data.language,\n stars: data.stargazers_count,\n forks: data.forks_count,\n open_issues: data.open_issues_count,\n archived: data.archived,\n pushed_at: data.pushed_at,\n });\n },\n {\n name: \"github_get_repo\",\n description:\n \"Fetch repo summary (default branch, visibility, description, topics, star/fork counts, \" +\n \"open-issue count). **PREFER THIS over shell-exec'ing the `gh` CLI.** Useful before opening \" +\n \"an issue (to confirm the repo exists / pick the right default branch).\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n }),\n },\n);\n\n// ── Issue write / read (cont'd) ────────────────────────────────────────────\n\nexport const githubUpdateIssueTool = tool(\n async ({ owner, repo, number, title, body, state, state_reason, labels, assignees }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = {};\n if (title !== undefined) payload.title = title;\n if (body !== undefined) payload.body = body;\n if (state !== undefined) payload.state = state;\n if (state_reason !== undefined) payload.state_reason = state_reason;\n if (labels !== undefined) payload.labels = labels;\n if (assignees !== undefined) payload.assignees = assignees;\n if (Object.keys(payload).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of title/body/state/labels/assignees\" });\n }\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}`,\n { method: \"PATCH\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; state?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n number: data.number,\n state: data.state,\n url: data.html_url,\n updated_fields: Object.keys(payload),\n });\n },\n {\n name: \"github_update_issue\",\n description:\n \"Edit an issue or PR (same endpoint): change title, body, labels, assignees, or close/reopen via \" +\n \"`state`. **PREFER THIS over shell-exec'ing the `gh` CLI.** Pass `state: \\\"closed\\\"` with \" +\n \"`state_reason: \\\"completed\\\"` for done-as-intended, or `\\\"not_planned\\\"` for won't-fix.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n title: z.string().optional(),\n body: z.string().optional().describe(\"New issue body (Markdown). Replaces, doesn't append.\"),\n state: z.enum([\"open\", \"closed\"]).optional(),\n state_reason: z.enum([\"completed\", \"not_planned\", \"reopened\"]).optional(),\n labels: z.array(z.string()).optional().describe(\"Replaces the label set entirely.\"),\n assignees: z.array(z.string()).optional().describe(\"Replaces the assignee set entirely.\"),\n }),\n },\n);\n\nexport const githubListIssueCommentsTool = tool(\n async ({ owner, repo, number, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}/comments?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n comments: data.map((c) => {\n const cap = truncate(typeof c.body === \"string\" ? c.body : \"\", COMMENT_CAP);\n return {\n id: c.id,\n user: liteUser(c.user),\n created_at: c.created_at,\n updated_at: c.updated_at,\n url: c.html_url,\n body: cap.text,\n truncated: cap.truncated,\n };\n }),\n });\n },\n {\n name: \"github_list_issue_comments\",\n description:\n \"List comments on an issue or PR. **PREFER THIS over shell-exec'ing the `gh` CLI.** Each comment \" +\n \"body is capped at 8 KB; `truncated: true` flags ones that hit the cap.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n max_results: z.number().optional().describe(\"Max comments (default 25, max 100)\"),\n }),\n },\n);\n\n// ── Pull-request write ─────────────────────────────────────────────────────\n\nexport const githubCreatePullTool = tool(\n async ({ owner, repo, title, head, base, body, draft, maintainer_can_modify }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = { title, head, base };\n if (body !== undefined) payload.body = body;\n if (draft !== undefined) payload.draft = draft;\n if (maintainer_can_modify !== undefined) payload.maintainer_can_modify = maintainer_can_modify;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; draft?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, number: data.number, draft: data.draft, url: data.html_url });\n },\n {\n name: \"github_create_pull\",\n description:\n \"Open a pull request. **PREFER THIS over shell-exec'ing the `gh` CLI.** `head` is the branch with \" +\n \"your changes (use `user:branch` for cross-fork PRs); `base` is the branch you want to merge into. \" +\n \"Returns 422 if the head/base pair has no diff or if the branches don't exist.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n title: z.string(),\n head: z.string().describe(\"Source branch ('feature/x' for same-repo, 'user:branch' for fork PRs)\"),\n base: z.string().describe(\"Target branch (typically 'main')\"),\n body: z.string().optional().describe(\"PR description (Markdown)\"),\n draft: z.boolean().optional().describe(\"Open as draft (default false)\"),\n maintainer_can_modify: z.boolean().optional()\n .describe(\"Allow upstream maintainers to push to your fork branch (default true)\"),\n }),\n },\n);\n\nexport const githubUpdatePullTool = tool(\n async ({ owner, repo, number, title, body, state, base, maintainer_can_modify }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = {};\n if (title !== undefined) payload.title = title;\n if (body !== undefined) payload.body = body;\n if (state !== undefined) payload.state = state;\n if (base !== undefined) payload.base = base;\n if (maintainer_can_modify !== undefined) payload.maintainer_can_modify = maintainer_can_modify;\n if (Object.keys(payload).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of title/body/state/base\" });\n }\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}`,\n { method: \"PATCH\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; state?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n number: data.number,\n state: data.state,\n url: data.html_url,\n updated_fields: Object.keys(payload),\n });\n },\n {\n name: \"github_update_pull\",\n description:\n \"Edit a pull request: title, body, base branch, or close/reopen. **PREFER THIS over shell-exec'ing \" +\n \"the `gh` CLI.** To MERGE a PR use github_merge_pull — `state` here only opens / closes.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n title: z.string().optional(),\n body: z.string().optional(),\n state: z.enum([\"open\", \"closed\"]).optional()\n .describe(\"`closed` here means 'close without merging'. Use github_merge_pull to merge.\"),\n base: z.string().optional().describe(\"Re-target the PR at a different base branch.\"),\n maintainer_can_modify: z.boolean().optional(),\n }),\n },\n);\n\nexport const githubMergePullTool = tool(\n async ({ owner, repo, number, method, commit_title, commit_message, sha }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = {};\n if (commit_title !== undefined) payload.commit_title = commit_title;\n if (commit_message !== undefined) payload.commit_message = commit_message;\n if (method !== undefined) payload.merge_method = method;\n if (sha !== undefined) payload.sha = sha;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/merge`,\n { method: \"PUT\", body: JSON.stringify(payload) },\n ) as { merged?: boolean; sha?: string; message?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: !!data.merged,\n merged_sha: data.sha ?? null,\n message: data.message ?? null,\n });\n },\n {\n name: \"github_merge_pull\",\n description:\n \"Merge a pull request. **PREFER THIS over shell-exec'ing the `gh` CLI.** `method` selects the \" +\n \"merge strategy (default `merge`); pass `sha` to refuse the merge if the PR head has been \" +\n \"force-pushed since you last looked. 405 means the PR isn't mergeable yet (still in CI / has \" +\n \"conflicts / needs review); 409 means the `sha` guard tripped.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n method: z.enum([\"merge\", \"squash\", \"rebase\"]).optional(),\n commit_title: z.string().optional()\n .describe(\"Title for the merge commit (or squash commit). Default: GitHub's auto-generated title.\"),\n commit_message: z.string().optional(),\n sha: z.string().optional()\n .describe(\"Refuse to merge unless the PR head still matches this SHA — guards against TOCTOU.\"),\n }),\n },\n);\n\nexport const githubRequestReviewersTool = tool(\n async ({ owner, repo, number, reviewers, team_reviewers }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!reviewers?.length && !team_reviewers?.length) {\n return JSON.stringify({ error: \"pass at least one of reviewers or team_reviewers\" });\n }\n const payload: Record<string, unknown> = {};\n if (reviewers?.length) payload.reviewers = reviewers;\n if (team_reviewers?.length) payload.team_reviewers = team_reviewers;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/requested_reviewers`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as {\n requested_reviewers?: Array<{ login?: string }>;\n requested_teams?: Array<{ slug?: string }>;\n html_url?: string;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n requested_users: (data.requested_reviewers ?? []).map((u) => u.login).filter(Boolean),\n requested_teams: (data.requested_teams ?? []).map((t) => t.slug).filter(Boolean),\n url: data.html_url,\n });\n },\n {\n name: \"github_request_reviewers\",\n description:\n \"Request review on a pull request from one or more users and/or teams. **PREFER THIS over \" +\n \"shell-exec'ing the `gh` CLI.** GitHub silently drops invalid usernames / team slugs — check the \" +\n \"returned `requested_users` / `requested_teams` to see who actually got a notification.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n reviewers: z.array(z.string()).optional().describe(\"GitHub usernames\"),\n team_reviewers: z.array(z.string()).optional().describe(\"Team slugs (org-scoped)\"),\n }),\n },\n);\n\nexport const githubCreateReviewTool = tool(\n async ({ owner, repo, number, event, body, commit_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (event === \"REQUEST_CHANGES\" && !body?.trim()) {\n return JSON.stringify({ error: \"REQUEST_CHANGES requires a non-empty body explaining what to change\" });\n }\n const payload: Record<string, unknown> = { event };\n if (body !== undefined) payload.body = body;\n if (commit_id !== undefined) payload.commit_id = commit_id;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/reviews`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { id?: number; state?: string; html_url?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, review_id: data.id, state: data.state, url: data.html_url });\n },\n {\n name: \"github_create_review\",\n description:\n \"Submit a pull-request review (approve / request changes / leave a comment). **PREFER THIS over \" +\n \"shell-exec'ing the `gh` CLI.** `event=APPROVE` doesn't require a body. `event=REQUEST_CHANGES` \" +\n \"requires a body. Line-level inline review comments aren't supported by this tool yet — use the \" +\n \"GitHub UI for those.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n event: z.enum([\"APPROVE\", \"REQUEST_CHANGES\", \"COMMENT\"]),\n body: z.string().optional().describe(\"Review summary (Markdown). Required for REQUEST_CHANGES.\"),\n commit_id: z.string().optional().describe(\"Pin the review to a specific commit SHA.\"),\n }),\n },\n);\n\n// ── Pull-request read (cont'd) ─────────────────────────────────────────────\n\nexport const githubListPullFilesTool = tool(\n async ({ owner, repo, number, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 30, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/files?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n files: data.map((f) => {\n const patch = typeof f.patch === \"string\" ? truncate(f.patch, PATCH_CAP) : null;\n return {\n filename: f.filename,\n status: f.status, // added | modified | removed | renamed | …\n additions: f.additions,\n deletions: f.deletions,\n changes: f.changes,\n previous_filename: f.previous_filename,\n sha: f.sha,\n patch: patch?.text,\n patch_truncated: patch?.truncated ?? false,\n };\n }),\n });\n },\n {\n name: \"github_list_pull_files\",\n description:\n \"List files changed in a pull request, with per-file additions/deletions and (capped) patch text. \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** Each patch caps at 8 KB; `patch_truncated: true` \" +\n \"means the diff was longer than that. GitHub itself caps the response at 3000 files.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n max_results: z.number().optional().describe(\"Max files (default 30, max 100)\"),\n }),\n },\n);\n\nexport const githubListPullReviewsTool = tool(\n async ({ owner, repo, number, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 30, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/reviews?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n reviews: data.map((r) => {\n const cap = truncate(typeof r.body === \"string\" ? r.body : \"\", COMMENT_CAP);\n return {\n id: r.id,\n user: liteUser(r.user),\n state: r.state, // APPROVED | CHANGES_REQUESTED | COMMENTED | DISMISSED | PENDING\n submitted_at: r.submitted_at,\n commit_id: r.commit_id,\n url: r.html_url,\n body: cap.text,\n truncated: cap.truncated,\n };\n }),\n });\n },\n {\n name: \"github_list_pull_reviews\",\n description:\n \"List reviews submitted on a pull request (approvals, change-requests, comment-only). **PREFER THIS \" +\n \"over shell-exec'ing the `gh` CLI.** Use this to check whether a PR is approved before calling \" +\n \"github_merge_pull.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n max_results: z.number().optional().describe(\"Max reviews (default 30, max 100)\"),\n }),\n },\n);\n\n// ── Repo content ───────────────────────────────────────────────────────────\n\nexport const githubListBranchesTool = tool(\n async ({ owner, repo, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 30, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/branches?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n branches: data.map((b) => ({\n name: b.name,\n commit_sha: (b.commit as { sha?: string } | null)?.sha ?? null,\n protected: b.protected,\n })),\n });\n },\n {\n name: \"github_list_branches\",\n description:\n \"List branches in a repository with their head SHAs and protection state. **PREFER THIS over \" +\n \"shell-exec'ing the `gh` CLI.** Useful before opening a PR (confirm the head branch exists \" +\n \"and is the SHA you expect).\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n max_results: z.number().optional().describe(\"Max branches (default 30, max 100)\"),\n }),\n },\n);\n\nexport const githubGetFileTool = tool(\n async ({ owner, repo, path, ref }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const url = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/contents/${path\n .split(\"/\").map(encodeURIComponent).join(\"/\")}` + (ref ? `?ref=${encodeURIComponent(ref)}` : \"\");\n const data = await ghFetch(auth, url) as Record<string, unknown> | Array<unknown> | { error?: string };\n if (!Array.isArray(data) && (data as { error?: string }).error) {\n return JSON.stringify(data);\n }\n if (Array.isArray(data) || (data as { type?: string }).type === \"dir\") {\n return JSON.stringify({\n error: `'${path}' is a directory; this tool only reads single files. Pass a path to a file.`,\n });\n }\n const f = data as { type?: string; encoding?: string; content?: string; sha?: string;\n size?: number; html_url?: string; path?: string };\n if (f.type !== \"file\") {\n return JSON.stringify({ error: `unsupported content type '${f.type ?? \"?\"}' at ${path}` });\n }\n const decoded = decodeContentsBlob(f.content ?? \"\", f.encoding);\n if (decoded.binary) {\n return JSON.stringify({\n path: f.path, sha: f.sha, url: f.html_url,\n binary: true, size_bytes: decoded.size_bytes,\n });\n }\n const cap = truncate(decoded.text ?? \"\", BODY_CAP);\n return JSON.stringify({\n path: f.path, sha: f.sha, url: f.html_url,\n binary: false, size_bytes: decoded.size_bytes,\n content: cap.text, truncated: cap.truncated,\n });\n },\n {\n name: \"github_get_file\",\n description:\n \"Read a file's contents from a repo at an optional ref (branch / tag / commit SHA). **PREFER THIS \" +\n \"over shell-exec'ing the `gh` CLI.** Returns up to 20 KB of UTF-8 text; longer files are truncated \" +\n \"with `truncated: true`. Binary files return `binary: true` and `size_bytes` instead of `content`. \" +\n \"GitHub itself rejects files larger than ~1 MB on this endpoint.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n path: z.string().describe(\"Path within the repo (e.g. 'src/lib/index.ts'). Slashes preserved.\"),\n ref: z.string().optional().describe(\"Branch, tag, or commit SHA. Default: repo's default branch.\"),\n }),\n },\n);\n\nexport const githubSearchCodeTool = tool(\n async ({ q, repo, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const query = repo ? `repo:${repo} ${q}` : q;\n const data = await ghFetch(\n auth,\n `/search/code?q=${encodeURIComponent(query)}&per_page=${limit}`,\n { headers: { Accept: \"application/vnd.github.text-match+json\" } },\n ) as {\n items?: Array<{\n name?: string; path?: string; sha?: string; html_url?: string;\n repository?: { full_name?: string };\n text_matches?: Array<{ fragment?: string }>;\n }>;\n total_count?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total_count ?? 0,\n items: (data.items ?? []).map((i) => {\n const fragment = i.text_matches?.[0]?.fragment ?? \"\";\n const snip = truncate(fragment, SNIPPET_CAP);\n return {\n name: i.name,\n path: i.path,\n repo: i.repository?.full_name,\n url: i.html_url,\n sha: i.sha,\n snippet: snip.text,\n snippet_truncated: snip.truncated,\n };\n }),\n });\n },\n {\n name: \"github_search_code\",\n description:\n \"Search file contents across GitHub. **PREFER THIS over shell-exec'ing the `gh` CLI.** Pass `repo` \" +\n \"(\\\"owner/name\\\") to scope to one repo; the tool prepends `repo:owner/name `. The `q` body accepts \" +\n \"GitHub's full code-search syntax: 'language:ts symbolName', 'extension:py path:tests assert', etc. \" +\n \"Each hit returns a 400-char snippet around the match. Note: GitHub code search has stricter rate \" +\n \"limits than other endpoints (10/min for unauthenticated, 30/min for authenticated).\",\n schema: z.object({\n q: z.string().describe(\"Code search query (e.g. 'language:ts isLikelyBinary')\"),\n repo: z.string().optional().describe(\"Optional 'owner/name' shortcut; prepended as repo: filter\"),\n max_results: z.number().optional().describe(\"Max items (default 25, max 100)\"),\n }),\n },\n);\n\nregisterTools(\"GitHub\", [\n // Issues\n githubSearchIssuesTool, githubGetIssueTool, githubCreateIssueTool,\n githubUpdateIssueTool, githubAddCommentTool, githubListIssueCommentsTool,\n // Pull requests\n githubListPullsTool, githubGetPullTool,\n githubCreatePullTool, githubUpdatePullTool, githubMergePullTool,\n githubRequestReviewersTool, githubCreateReviewTool,\n githubListPullFilesTool, githubListPullReviewsTool,\n // Repo content\n githubGetRepoTool, githubListBranchesTool, githubGetFileTool, githubSearchCodeTool,\n]);\n","// CRUD for the `document_sources` table (ADR-0024). A source is a folder\n// the user has asked Jarela to index for semantic search.\n\nimport { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\n\n// ADR-0026 — `kind` discriminates local-folder sources from remote ones\n// (Jira projects, Confluence spaces, saved JQL/CQL, on-demand URL). `config`\n// is a JSON-encoded per-kind blob. `last_cursor` is a per-source incremental\n// watermark (used by remote indexers to do incremental syncs).\n// ADR-0029 added `github_pulls` (PRs of one repo) and `github_repo` (text\n// files on one branch of one repo).\nexport type DocumentSourceKind =\n | \"local_folder\"\n | \"confluence_space\"\n | \"confluence_cql\"\n | \"jira_project\"\n | \"jira_jql\"\n | \"github_pulls\"\n | \"github_repo\"\n | \"gmail_mail\"\n | \"outlook_mail\"\n | \"on_demand_url\";\n\nexport interface DocumentSourceRow {\n id: string;\n path: string;\n label: string | null;\n enabled: number;\n last_scan_at: string | null;\n last_error: string | null;\n created_at: string;\n updated_at: string;\n kind: DocumentSourceKind;\n config: string | null; // JSON; null for local_folder\n last_cursor: string | null; // incremental watermark; null for local_folder\n}\n\nconst now = () => new Date().toISOString();\n\nexport function listDocumentSources(): DocumentSourceRow[] {\n return getDb()\n .prepare(\"SELECT * FROM document_sources ORDER BY created_at ASC\")\n .all() as unknown as DocumentSourceRow[];\n}\n\nexport function listEnabledDocumentSources(): DocumentSourceRow[] {\n return getDb()\n .prepare(\"SELECT * FROM document_sources WHERE enabled=1 ORDER BY created_at ASC\")\n .all() as unknown as DocumentSourceRow[];\n}\n\nexport function getDocumentSource(id: string): DocumentSourceRow | null {\n const row = getDb().prepare(\"SELECT * FROM document_sources WHERE id=?\").get(id);\n return (row as DocumentSourceRow | undefined) ?? null;\n}\n\nexport function getDocumentSourceByPath(path: string): DocumentSourceRow | null {\n const row = getDb().prepare(\"SELECT * FROM document_sources WHERE path=?\").get(path);\n return (row as DocumentSourceRow | undefined) ?? null;\n}\n\nexport function createDocumentSource(input: {\n path: string;\n label?: string | null;\n kind?: DocumentSourceKind;\n config?: Record<string, unknown> | null;\n}): DocumentSourceRow {\n const id = randomUUID();\n const t = now();\n const kind = input.kind ?? \"local_folder\";\n const config = input.config ? JSON.stringify(input.config) : null;\n getDb()\n .prepare(\n `INSERT INTO document_sources\n (id, path, label, enabled, last_scan_at, last_error, created_at, updated_at, kind, config, last_cursor)\n VALUES (?, ?, ?, 1, NULL, NULL, ?, ?, ?, ?, NULL)`,\n )\n .run(id, input.path, input.label ?? null, t, t, kind, config);\n return {\n id,\n path: input.path,\n label: input.label ?? null,\n enabled: 1,\n last_scan_at: null,\n last_error: null,\n created_at: t,\n updated_at: t,\n kind,\n config,\n last_cursor: null,\n };\n}\n\n// Parsed-config accessor — JSON.parse on every call would be fine at our\n// scale but this helper keeps call sites tidy.\nexport function parseSourceConfig<T = Record<string, unknown>>(\n row: DocumentSourceRow,\n): T | null {\n if (!row.config) return null;\n try { return JSON.parse(row.config) as T; } catch { return null; }\n}\n\nexport function updateDocumentSourceCursor(id: string, cursor: string | null): void {\n getDb()\n .prepare(\"UPDATE document_sources SET last_cursor=?, updated_at=? WHERE id=?\")\n .run(cursor, now(), id);\n}\n\nexport function updateDocumentSource(\n id: string,\n patch: { label?: string | null; enabled?: boolean },\n): DocumentSourceRow | null {\n const existing = getDocumentSource(id);\n if (!existing) return null;\n const t = now();\n getDb()\n .prepare(\n `UPDATE document_sources SET label=?, enabled=?, updated_at=? WHERE id=?`,\n )\n .run(\n patch.label === undefined ? existing.label : patch.label,\n patch.enabled === undefined ? existing.enabled : patch.enabled ? 1 : 0,\n t,\n id,\n );\n return getDocumentSource(id);\n}\n\nexport function deleteDocumentSource(id: string): boolean {\n // ON DELETE CASCADE handles documents + chunks.\n return (\n (getDb()\n .prepare(\"DELETE FROM document_sources WHERE id=?\")\n .run(id) as { changes: number }).changes > 0\n );\n}\n\nexport function markSourceScanned(\n id: string,\n error?: string | null,\n): void {\n getDb()\n .prepare(\n \"UPDATE document_sources SET last_scan_at=?, last_error=?, updated_at=? WHERE id=?\",\n )\n .run(now(), error ?? null, now(), id);\n}\n\nexport interface DocumentSourceStats {\n source_id: string;\n document_count: number;\n chunk_count: number;\n embedded_chunk_count: number;\n}\n\nexport function getDocumentSourceStats(sourceId: string): DocumentSourceStats {\n const db = getDb();\n const docs = db\n .prepare(\"SELECT COUNT(*) AS n FROM documents WHERE source_id=?\")\n .get(sourceId) as { n: number };\n const chunks = db\n .prepare(\n `SELECT COUNT(*) AS n\n FROM document_chunks dc JOIN documents d ON dc.document_id = d.id\n WHERE d.source_id=?`,\n )\n .get(sourceId) as { n: number };\n const embedded = db\n .prepare(\n `SELECT COUNT(*) AS n\n FROM document_chunks dc JOIN documents d ON dc.document_id = d.id\n WHERE d.source_id=? AND dc.embedding IS NOT NULL`,\n )\n .get(sourceId) as { n: number };\n return {\n source_id: sourceId,\n document_count: docs.n,\n chunk_count: chunks.n,\n embedded_chunk_count: embedded.n,\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport { CronExpressionParser } from \"cron-parser\";\nimport { getDb } from \"@/lib/db\";\nimport {\n resolveReaction,\n validateReactionScript,\n normaliseReactionScriptArgs,\n type ReactionKind,\n type ResolvedReaction,\n} from \"./reaction-shared\";\n\nexport type ScheduleKind = \"once\" | \"cron\";\n\nexport interface ScheduledTaskRow {\n id: string;\n agent_id: string;\n prompt: string;\n description: string | null;\n kind: ScheduleKind;\n schedule: string; // ISO timestamp for \"once\", cron expression for \"cron\"\n next_run_at: string; // ISO\n last_run_at: string | null;\n last_error: string | null;\n enabled: number; // 0 | 1\n // When 1 the scheduler wraps the prompt with a \"reply only if material\"\n // directive and a NO_REPLY sentinel; NO_REPLY/empty assistant turns are\n // dropped. Visibility is handled at the UI layer via the chat-panel\n // category-filter toolbar (firings are tagged `scheduled_task`).\n silent: number; // 0 | 1\n // ADR-0032 — discriminated reaction. 'agent_prompt' (default) runs the\n // agent with `prompt`; 'script' runs a registered reaction.* script\n // with no LLM round-trip. The other branch's columns are forced NULL\n // by the store layer (see resolveReaction in reaction-shared.ts).\n reaction_kind: ReactionKind;\n reaction_script: string | null;\n reaction_script_args: string | null; // JSON-encoded record\n created_at: string;\n updated_at: string;\n}\n\nconst now = () => new Date().toISOString();\n\nexport function computeNextRun(kind: ScheduleKind, schedule: string, after: Date = new Date()): Date {\n if (kind === \"once\") {\n const ts = new Date(schedule);\n if (Number.isNaN(ts.getTime())) throw new Error(`Invalid ISO timestamp: ${schedule}`);\n return ts;\n }\n const it = CronExpressionParser.parse(schedule, { currentDate: after });\n return it.next().toDate();\n}\n\nexport interface CreateScheduledTaskInput {\n agent_id: string;\n // Required for kind='agent_prompt'; ignored (stored as \"\") for kind='script'.\n prompt?: string;\n description?: string;\n kind: ScheduleKind;\n schedule: string;\n silent?: boolean;\n // ADR-0032 — discriminated reaction. Same shape as the watcher store.\n reaction_kind?: ReactionKind;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\nexport function createScheduledTask(input: CreateScheduledTaskInput): ScheduledTaskRow {\n const id = randomUUID();\n const t = now();\n const next = computeNextRun(input.kind, input.schedule).toISOString();\n const silent = input.silent ? 1 : 0;\n const reaction = resolveReaction({\n reaction_kind: input.reaction_kind,\n // Scheduled tasks don't carry a reaction_prompt override — the firing\n // prompt is `input.prompt` itself when kind='agent_prompt'. Pass null\n // so resolveReaction normalises it consistently.\n reaction_prompt: null,\n reaction_script: input.reaction_script,\n reaction_script_args: input.reaction_script_args,\n });\n if (reaction.kind === \"agent_prompt\" && !input.prompt) {\n throw new Error(\"prompt is required when reaction_kind='agent_prompt'\");\n }\n // For kind='script' we still need a non-NULL value in the prompt column\n // (NOT NULL constraint stays). Empty string is the agreed sentinel; the\n // discriminator decides whether prompt is read.\n const prompt = reaction.kind === \"script\" ? (input.prompt ?? \"\") : input.prompt!;\n getDb()\n .prepare(\n `INSERT INTO scheduled_tasks\n (id, agent_id, prompt, description, kind, schedule, next_run_at, last_run_at, last_error, enabled, silent,\n reaction_kind, reaction_script, reaction_script_args, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, NULL, NULL, 1, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n id, input.agent_id, prompt, input.description ?? null, input.kind, input.schedule, next, silent,\n reaction.kind, reaction.script, reaction.scriptArgs, t, t,\n );\n return {\n id,\n agent_id: input.agent_id,\n prompt,\n description: input.description ?? null,\n kind: input.kind,\n schedule: input.schedule,\n next_run_at: next,\n last_run_at: null,\n last_error: null,\n enabled: 1,\n silent,\n reaction_kind: reaction.kind,\n reaction_script: reaction.script,\n reaction_script_args: reaction.scriptArgs,\n created_at: t,\n updated_at: t,\n };\n}\n\nexport function listScheduledTasks(agentId?: string): ScheduledTaskRow[] {\n const db = getDb();\n const rows = agentId\n ? db.prepare(\"SELECT * FROM scheduled_tasks WHERE agent_id=? ORDER BY next_run_at ASC\").all(agentId)\n : db.prepare(\"SELECT * FROM scheduled_tasks ORDER BY next_run_at ASC\").all();\n return rows as unknown as ScheduledTaskRow[];\n}\n\nexport function getScheduledTask(id: string): ScheduledTaskRow | null {\n const row = getDb().prepare(\"SELECT * FROM scheduled_tasks WHERE id=?\").get(id);\n return (row as ScheduledTaskRow | undefined) ?? null;\n}\n\nexport function getDueTasks(asOf: Date = new Date()): ScheduledTaskRow[] {\n return getDb()\n .prepare(\"SELECT * FROM scheduled_tasks WHERE enabled=1 AND next_run_at <= ? ORDER BY next_run_at ASC\")\n .all(asOf.toISOString()) as unknown as ScheduledTaskRow[];\n}\n\nexport function deleteScheduledTask(id: string): boolean {\n const r = getDb().prepare(\"DELETE FROM scheduled_tasks WHERE id=?\").run(id);\n return r.changes > 0;\n}\n\nexport interface UpdateScheduledTaskInput {\n prompt?: string;\n description?: string | null;\n kind?: ScheduleKind;\n schedule?: string;\n enabled?: boolean;\n silent?: boolean;\n // ADR-0032 — same discriminated-union semantics as updateWatcher:\n // explicit reaction_kind does a full replace; absent kind allows\n // kind-preserving patch of the matching branch's fields.\n reaction_kind?: ReactionKind;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}\n\n// Patch an existing task. Only the supplied fields are touched; the rest\n// stay as-is. Changing `kind` or `schedule` recomputes `next_run_at`\n// against the new value so the scheduler picks the right next firing.\nexport function updateScheduledTask(id: string, patch: UpdateScheduledTaskInput): ScheduledTaskRow | null {\n const existing = getScheduledTask(id);\n if (!existing) return null;\n const nextKind = patch.kind ?? existing.kind;\n const nextSchedule = patch.schedule ?? existing.schedule;\n const t = now();\n // If the schedule (kind or expression) changed, validate + recompute. If\n // it didn't change we keep the existing next_run_at so a simple prompt\n // edit doesn't accidentally re-arm an already-overdue task.\n let nextRunAt = existing.next_run_at;\n if (patch.kind !== undefined || patch.schedule !== undefined) {\n nextRunAt = computeNextRun(nextKind, nextSchedule, new Date(t)).toISOString();\n }\n\n // Compute the reaction columns. Two cases mirroring updateWatcher:\n // 1. patch.reaction_kind is set → fully resolve as a new reaction.\n // 2. patch.reaction_kind is absent → keep existing kind, allow the\n // matching branch's field to be patched.\n let reaction: ResolvedReaction;\n if (patch.reaction_kind !== undefined) {\n reaction = resolveReaction({\n reaction_kind: patch.reaction_kind,\n reaction_prompt: null,\n reaction_script: patch.reaction_script,\n reaction_script_args: patch.reaction_script_args,\n });\n } else if (existing.reaction_kind === \"script\") {\n const script = patch.reaction_script === undefined\n ? existing.reaction_script\n : (patch.reaction_script === null ? null : validateReactionScript(patch.reaction_script));\n if (!script) {\n throw new Error(\n \"reaction_script cannot be cleared while reaction_kind='script' — switch reaction_kind to 'agent_prompt' instead\",\n );\n }\n const scriptArgs = patch.reaction_script_args === undefined\n ? existing.reaction_script_args\n : normaliseReactionScriptArgs(patch.reaction_script_args);\n reaction = { kind: \"script\", prompt: null, script, scriptArgs };\n } else {\n reaction = { kind: \"agent_prompt\", prompt: null, script: null, scriptArgs: null };\n }\n\n // Prompt column constraint: must be non-NULL. For kind='script' we keep\n // whatever was there (or \"\" if switching from script with empty existing).\n const nextPrompt = patch.prompt !== undefined\n ? patch.prompt\n : (reaction.kind === \"agent_prompt\" && existing.reaction_kind === \"script\"\n ? (existing.prompt || \"\")\n : existing.prompt);\n\n getDb()\n .prepare(\n `UPDATE scheduled_tasks SET\n prompt=?, description=?, kind=?, schedule=?, next_run_at=?, enabled=?, silent=?, last_error=?,\n reaction_kind=?, reaction_script=?, reaction_script_args=?, updated_at=?\n WHERE id=?`,\n )\n .run(\n nextPrompt,\n patch.description === undefined ? existing.description : patch.description,\n nextKind,\n nextSchedule,\n nextRunAt,\n patch.enabled === undefined ? existing.enabled : (patch.enabled ? 1 : 0),\n patch.silent === undefined ? existing.silent : (patch.silent ? 1 : 0),\n // Clear the last error whenever the user touches the task — they've\n // presumably fixed whatever caused it.\n null,\n reaction.kind,\n reaction.script,\n reaction.scriptArgs,\n t,\n id,\n );\n return getScheduledTask(id);\n}\n\nexport function markTaskRan(id: string, kind: ScheduleKind, schedule: string, error?: string): void {\n const t = now();\n if (kind === \"once\") {\n // One-shot tasks delete themselves after firing.\n getDb().prepare(\"DELETE FROM scheduled_tasks WHERE id=?\").run(id);\n return;\n }\n let nextRun: string;\n try {\n nextRun = computeNextRun(kind, schedule, new Date(t)).toISOString();\n } catch (e) {\n // Invalid cron — disable the task to avoid a tight error loop.\n getDb()\n .prepare(\"UPDATE scheduled_tasks SET enabled=0, last_run_at=?, last_error=?, updated_at=? WHERE id=?\")\n .run(t, `Cron parse failed: ${e instanceof Error ? e.message : String(e)}`, t, id);\n return;\n }\n getDb()\n .prepare(\"UPDATE scheduled_tasks SET last_run_at=?, last_error=?, next_run_at=?, updated_at=? WHERE id=?\")\n .run(t, error ?? null, nextRun, t, id);\n}\n","// Ephemeral state store for in-app OAuth flows (Gmail, Microsoft, ...).\n//\n// Why this exists: the user types client_id + client_secret in the\n// Integrations panel, we POST to /oauth/start, stash them here keyed by a\n// random `state`, and return the provider's authorize URL. The browser\n// bounces back to /oauth/callback with `?code&state`, we exchange, and\n// persist the integration. Meanwhile the panel polls /oauth/status.\n//\n// Pinned to globalThis so HMR in dev doesn't lose pending flows.\n//\n// Same shape used by both gmail-oauth.ts and microsoft-oauth.ts — pass a\n// unique `globalKey` per provider so they don't share a Map.\n\nimport { randomBytes } from \"node:crypto\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\n\nexport interface OAuthFlow {\n createdAt: number;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n status: \"pending\" | \"done\" | \"error\";\n error?: string;\n}\n\nexport interface OAuthFlowStore {\n create(input: { clientId: string; clientSecret: string; redirectUri: string }): {\n state: string;\n flow: OAuthFlow;\n };\n get(state: string): OAuthFlow | undefined;\n update(state: string, patch: Partial<OAuthFlow>): void;\n delete(state: string): void;\n}\n\nconst DEFAULT_TTL_MS = 10 * 60 * 1000;\nconst DEFAULT_MAX_FLOWS = 32;\n\nexport function createOAuthFlowStore(opts: {\n globalKey: string;\n ttlMs?: number;\n maxFlows?: number;\n}): OAuthFlowStore {\n const ttlMs = opts.ttlMs ?? DEFAULT_TTL_MS;\n const maxFlows = opts.maxFlows ?? DEFAULT_MAX_FLOWS;\n const flows = getOrCreateGlobal<Map<string, OAuthFlow>>(opts.globalKey, () => new Map());\n\n function gc(): void {\n const now = Date.now();\n for (const [k, v] of flows) {\n if (now - v.createdAt > ttlMs) flows.delete(k);\n }\n // Hard cap so a stuck UI can't grow this unbounded.\n if (flows.size > maxFlows) {\n const oldest = [...flows.entries()].sort((a, b) => a[1].createdAt - b[1].createdAt);\n for (let i = 0; i < oldest.length - maxFlows; i++) flows.delete(oldest[i][0]);\n }\n }\n\n return {\n create(input) {\n gc();\n const state = randomBytes(16).toString(\"hex\");\n const flow: OAuthFlow = { createdAt: Date.now(), status: \"pending\", ...input };\n flows.set(state, flow);\n return { state, flow };\n },\n get(state) {\n gc();\n return flows.get(state);\n },\n update(state, patch) {\n const f = flows.get(state);\n if (f) Object.assign(f, patch);\n },\n delete(state) {\n flows.delete(state);\n },\n };\n}\n","// Plain-text flatteners for remote document RAG (ADR-0026).\n//\n// Jira issue bodies and comments arrive as Atlassian Document Format\n// (ADF) — a JSON tree of typed nodes. Confluence page bodies arrive as\n// HTML (the `storage` representation). Both have to be flattened to plain\n// text before being chunked by `lib/documents/chunker.ts`, which assumes\n// paragraph-delimited text.\n//\n// These flatteners are intentionally lossy: they keep textual content\n// and paragraph structure, drop markup, links, attachments, embeds.\n// \"Good enough for retrieval\" is the bar — not \"round-trips to source\".\n\ninterface AdfNode {\n type?: string;\n text?: string;\n content?: AdfNode[];\n}\n\n/** Flatten an ADF JSON tree into paragraph-separated plain text. */\nexport function adfToText(adf: unknown): string {\n if (!adf || typeof adf !== \"object\") return \"\";\n const parts: string[] = [];\n function walk(node: AdfNode, depth = 0): void {\n if (!node) return;\n if (typeof node.text === \"string\") {\n parts.push(node.text);\n return;\n }\n const block = node.type && /paragraph|heading|listItem|codeBlock|blockquote|panel/.test(node.type);\n if (Array.isArray(node.content)) {\n for (const c of node.content) walk(c, depth + 1);\n }\n if (block) parts.push(\"\\n\\n\");\n }\n walk(adf as AdfNode);\n // Collapse runs of >2 newlines and trim.\n return parts.join(\"\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\n}\n\n/** Strip Confluence storage-format HTML to plain text. */\nexport function htmlToText(html: string): string {\n if (!html) return \"\";\n let s = html;\n // Drop script / style blocks entirely.\n s = s.replace(/<(script|style)[^>]*>[\\s\\S]*?<\\/\\1>/gi, \"\");\n // Confluence macros sometimes embed CDATA — keep the inner text.\n s = s.replace(/<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>/g, \"$1\");\n // Block-level closes → newline.\n s = s.replace(/<\\/(p|div|h[1-6]|li|tr|br|hr|blockquote|pre)\\s*>/gi, \"\\n\");\n // Self-closing <br>.\n s = s.replace(/<br\\s*\\/?>/gi, \"\\n\");\n // Drop all remaining tags.\n s = s.replace(/<[^>]+>/g, \"\");\n // Decode the handful of entities Atlassian actually emits.\n s = s\n .replace(/&nbsp;/g, \" \")\n .replace(/&amp;/g, \"&\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/&apos;/g, \"'\");\n // Collapse runs of >2 newlines and trim trailing space per line.\n return s.replace(/[ \\t]+\\n/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\n}\n","// Shared upsert path for remote document sources (ADR-0026).\n//\n// Remote sources (Jira issues, Confluence pages) don't have an mtime or a\n// stable filesystem path — the upstream `updated` timestamp plays the same\n// role as mtime, and we synthesize a stable `path` per item (`jira://KEY`\n// or `confluence://pageId`). The rest of the indexed shape matches local\n// folder documents so retrieval through searchDocuments works unchanged.\n\nimport { randomUUID, createHash } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\nimport { chunkAndEmbedDocument } from \"../indexer\";\n\nexport interface RemoteDocInput {\n /** Stable synthetic path, e.g. \"jira://ABC-123\" or \"confluence://12345\". */\n path: string;\n /** Human-readable title shown in retrieval results (Jira key+summary,\n * Confluence page title). Stored in `rel_path` so the existing search\n * UI shows it without schema changes. */\n title: string;\n /** ISO timestamp of the upstream `updated` field. Drives change detection\n * via the same column the local indexer uses for filesystem mtime\n * (re-purposed: we hash this string into mtime_ms). */\n externalUpdatedAt: string;\n /** Plain-text body to chunk + embed. Already flattened (ADF→text,\n * HTML→text) by the caller. */\n text: string;\n}\n\ninterface IndexedRow {\n id: string;\n mtime_ms: number;\n content_hash: string;\n}\n\nfunction findExisting(sourceId: string, path: string): IndexedRow | null {\n const row = getDb()\n .prepare(\"SELECT id, mtime_ms, content_hash FROM documents WHERE source_id=? AND path=?\")\n .get(sourceId, path) as IndexedRow | undefined;\n return row ?? null;\n}\n\n// Map an ISO string to a stable integer so we can store it in the existing\n// `mtime_ms` column without a schema change. Hashing keeps the column\n// useful for \"did the upstream record change?\" checks even though ms\n// resolution is meaningless for remote sources.\nfunction isoToMtime(iso: string): number {\n const t = Date.parse(iso);\n if (Number.isFinite(t)) return t;\n // Fall back to a deterministic hash so duplicate calls with the same\n // string still produce the same value.\n const h = createHash(\"sha1\").update(iso).digest();\n return h.readUInt32BE(0);\n}\n\nfunction hashContent(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\nexport interface UpsertResult {\n status: \"unchanged\" | \"added\" | \"updated\";\n /** Total chunks produced for this document (0 when unchanged). */\n chunks: number;\n /** Chunks that successfully got an embedding vector. */\n embedded: number;\n /** First embed error seen for this document, if any. */\n embedError: string | null;\n}\n\n/**\n * Insert-or-update a single remote document. Returns whether anything\n * actually changed so the caller can update incremental-sync counters.\n * Re-chunks + re-embeds when content changed; otherwise just touches\n * the indexed-at timestamp.\n */\nexport async function upsertRemoteDocument(\n sourceId: string,\n input: RemoteDocInput,\n): Promise<UpsertResult> {\n const db = getDb();\n const t = new Date().toISOString();\n const hash = hashContent(input.text);\n const mtime = isoToMtime(input.externalUpdatedAt);\n const existing = findExisting(sourceId, input.path);\n\n if (existing && existing.content_hash === hash) {\n db.prepare(\"UPDATE documents SET mtime_ms=?, last_indexed_at=? WHERE id=?\")\n .run(mtime, t, existing.id);\n return { status: \"unchanged\", chunks: 0, embedded: 0, embedError: null };\n }\n\n const docId = existing?.id ?? randomUUID();\n const size = Buffer.byteLength(input.text, \"utf8\");\n\n if (existing) {\n db.prepare(\n `UPDATE documents\n SET path=?, rel_path=?, mtime_ms=?, size_bytes=?, content_hash=?, last_indexed_at=?\n WHERE id=?`,\n ).run(input.path, input.title, mtime, size, hash, t, existing.id);\n db.prepare(\"DELETE FROM document_chunks WHERE document_id=?\").run(existing.id);\n } else {\n db.prepare(\n `INSERT INTO documents\n (id, source_id, path, rel_path, mtime_ms, size_bytes, content_hash, last_indexed_at, chunk_count)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)`,\n ).run(docId, sourceId, input.path, input.title, mtime, size, hash, t);\n }\n\n const r = await chunkAndEmbedDocument(docId, input.text, input.path);\n return {\n status: existing ? \"updated\" : \"added\",\n chunks: r.chunks,\n embedded: r.embedded,\n embedError: r.embedError,\n };\n}\n\n/**\n * Drop every indexed document for `sourceId` whose `path` isn't in the\n * keep-set. Returns the count removed. Remote indexers use this only for\n * \"full re-sync\" semantics — incremental syncs don't call it (an upstream\n * item disappearing doesn't necessarily mean it should be evicted; we'd\n * rather keep stale-but-useful content than punch holes silently).\n */\nexport function evictMissing(sourceId: string, keepPaths: Set<string>): number {\n const db = getDb();\n const rows = db.prepare(\"SELECT id, path FROM documents WHERE source_id=?\")\n .all(sourceId) as Array<{ id: string; path: string }>;\n let removed = 0;\n const del = db.prepare(\"DELETE FROM documents WHERE id=?\");\n for (const r of rows) {\n if (!keepPaths.has(r.path)) {\n del.run(r.id);\n removed++;\n }\n }\n return removed;\n}\n","// Confluence remote indexer (ADR-0026).\n//\n// Source kinds handled:\n// - confluence_space → CQL `space = \"<key>\" AND type = page`\n// - confluence_cql → user-supplied CQL (still scoped to `type = page`)\n//\n// Incremental: uses `last_cursor` to avoid re-fetching pages whose\n// `lastmodified` is older than the previous run's high-water mark.\n\nimport {\n _atlassianFetch,\n _resolveAtlassianAuth,\n type AtlassianAuth,\n} from \"@/lib/tools/atlassian\";\nimport {\n parseSourceConfig,\n updateDocumentSourceCursor,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { htmlToText } from \"./flatten\";\nimport { upsertRemoteDocument, type UpsertResult } from \"./upsert\";\n\nconst PAGE_LIMIT = 25;\nconst MAX_PAGES_PER_RUN = 200;\n\ninterface ConfluencePage {\n id: string;\n title: string;\n version?: { when?: string };\n history?: { lastUpdated?: { when?: string }; createdDate?: string };\n body?: { storage?: { value?: string } };\n _links?: { webui?: string };\n}\ninterface ConfluenceSearchResp {\n results?: ConfluencePage[];\n start?: number;\n size?: number;\n limit?: number;\n}\n\nfunction buildCql(source: DocumentSourceRow, since: string | null): string {\n const cfg = parseSourceConfig<{ space_key?: string; cql?: string; recency_days?: number }>(source) ?? {};\n const clauses: string[] = [\"type = page\"];\n if (source.kind === \"confluence_space\") {\n if (!cfg.space_key) throw new Error(\"confluence_space requires config.space_key\");\n clauses.push(`space = \"${cfg.space_key}\"`);\n } else if (source.kind === \"confluence_cql\") {\n if (!cfg.cql) throw new Error(\"confluence_cql requires config.cql\");\n clauses.push(`(${cfg.cql})`);\n }\n if (since) clauses.push(`lastmodified > \"${since.slice(0, 10)}\"`);\n if (cfg.recency_days && cfg.recency_days > 0) {\n clauses.push(`lastmodified > now(\"-${cfg.recency_days}d\")`);\n }\n return clauses.join(\" AND \");\n}\n\nfunction pageUpdatedAt(p: ConfluencePage): string {\n return (\n p.version?.when ??\n p.history?.lastUpdated?.when ??\n p.history?.createdDate ??\n new Date().toISOString()\n );\n}\n\nasync function fetchPage(auth: AtlassianAuth, pageId: string): Promise<ConfluencePage | null> {\n const data = await _atlassianFetch(\n auth,\n `/wiki/rest/api/content/${encodeURIComponent(pageId)}?expand=body.storage,version,history.lastUpdated`,\n ) as ConfluencePage & { error?: string };\n if (!data || (data as { error?: string }).error) return null;\n return data;\n}\n\nexport interface ConfluenceIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n cursor: string | null;\n embedFailed: number;\n embedError: string | null;\n}\n\nexport async function runConfluenceIndexer(source: DocumentSourceRow): Promise<ConfluenceIndexStats> {\n const stats: ConfluenceIndexStats = {\n scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0,\n cursor: source.last_cursor,\n embedFailed: 0, embedError: null,\n };\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const cql = buildCql(source, source.last_cursor);\n let start = 0;\n let highWater = source.last_cursor;\n\n while (stats.scanned < MAX_PAGES_PER_RUN) {\n const url = `/wiki/rest/api/content/search?cql=${encodeURIComponent(cql)}` +\n `&expand=body.storage,version,history.lastUpdated&limit=${PAGE_LIMIT}&start=${start}`;\n const data = await _atlassianFetch(auth, url) as ConfluenceSearchResp & { error?: string };\n if ((data as { error?: string }).error) throw new Error((data as { error?: string }).error);\n const results = data.results ?? [];\n if (results.length === 0) break;\n\n for (const page of results) {\n stats.scanned++;\n try {\n const text = `${page.title}\\n\\n${htmlToText(page.body?.storage?.value ?? \"\")}`.trim();\n const updatedAt = pageUpdatedAt(page);\n const res: UpsertResult = await upsertRemoteDocument(source.id, {\n path: `confluence://${page.id}`,\n title: page.title,\n externalUpdatedAt: updatedAt,\n text,\n });\n if (res.status === \"added\") stats.added++;\n else if (res.status === \"updated\") stats.updated++;\n else stats.unchanged++;\n stats.embedFailed += res.chunks - res.embedded;\n if (res.embedError && !stats.embedError) stats.embedError = res.embedError;\n if (!highWater || updatedAt > highWater) highWater = updatedAt;\n } catch {\n stats.errors++;\n }\n }\n start += results.length;\n if (results.length < PAGE_LIMIT) break;\n }\n\n if (highWater && highWater !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, highWater);\n stats.cursor = highWater;\n }\n return stats;\n}\n\n/**\n * On-demand: fetch a single Confluence page by id and index it under the\n * shared \"on_demand_url\" source row. Used by the `documents_index_url` tool\n * for \"just pull THIS one page\".\n */\nexport async function indexConfluencePageById(\n sourceId: string,\n pageId: string,\n): Promise<UpsertResult> {\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const page = await fetchPage(auth, pageId);\n if (!page) throw new Error(`confluence page ${pageId} not found`);\n const text = `${page.title}\\n\\n${htmlToText(page.body?.storage?.value ?? \"\")}`.trim();\n return upsertRemoteDocument(sourceId, {\n path: `confluence://${page.id}`,\n title: page.title,\n externalUpdatedAt: pageUpdatedAt(page),\n text,\n });\n}\n","// Remote mail indexing for Gmail and Outlook.\n//\n// These sources let the user index a filtered slice of mailbox content as\n// searchable documents. The query field is intentionally provider-native:\n// Gmail uses Gmail query syntax, Outlook uses KQL.\n\nimport { stripHtml } from \"@/lib/utils/html\";\nimport { truncateBytes } from \"@/lib/utils/text\";\nimport { googleFetch, resolveGoogleAuth } from \"@/lib/integrations/gmail-oauth\";\nimport { graphFetch, resolveMicrosoftAuth } from \"@/lib/integrations/microsoft-oauth\";\nimport { parseSourceConfig, type DocumentSourceRow } from \"@/lib/stores/document-sources\";\nimport { evictMissing, upsertRemoteDocument } from \"./upsert\";\n\nimport type { RemoteIndexStats } from \"./index\";\n\nconst BODY_CAP = 40_000;\nconst DEFAULT_MAX_RESULTS = 250;\nconst DEFAULT_PAGE_SIZE = 100;\nconst MAX_RESULTS_CAP = 5_000;\n\ninterface Header {\n name?: string;\n value?: string;\n}\n\ninterface GmailMessageList {\n messages?: Array<{ id: string; threadId?: string }>;\n nextPageToken?: string;\n resultSizeEstimate?: number;\n error?: string;\n}\n\ninterface GmailMessage {\n id?: string;\n threadId?: string;\n internalDate?: string;\n snippet?: string;\n labelIds?: string[];\n payload?: {\n headers?: Header[];\n mimeType?: string;\n filename?: string;\n body?: { data?: string };\n parts?: GmailMessage[\"payload\"][];\n };\n error?: string;\n}\n\ninterface GraphEmailAddress {\n name?: string;\n address?: string;\n}\n\ninterface GraphRecipient {\n emailAddress?: GraphEmailAddress;\n}\n\ninterface GraphMessage {\n id?: string;\n conversationId?: string;\n subject?: string;\n bodyPreview?: string;\n body?: { contentType?: \"html\" | \"text\"; content?: string };\n from?: GraphRecipient;\n toRecipients?: GraphRecipient[];\n ccRecipients?: GraphRecipient[];\n receivedDateTime?: string;\n lastModifiedDateTime?: string;\n isRead?: boolean;\n isDraft?: boolean;\n hasAttachments?: boolean;\n categories?: string[];\n parentFolderId?: string;\n webLink?: string;\n}\n\nfunction header(headers: Header[] | undefined, name: string): string | null {\n const hit = (headers ?? []).find((h) => (h.name ?? \"\").toLowerCase() === name.toLowerCase());\n return hit?.value ?? null;\n}\n\nfunction decodeBase64Url(s: string): string {\n try {\n return Buffer.from(s, \"base64url\").toString(\"utf8\");\n } catch {\n return \"\";\n }\n}\n\nfunction findPart(part: { mimeType?: string; filename?: string; body?: { data?: string }; parts?: Array<unknown> } | undefined, mime: string): { mimeType?: string; filename?: string; body?: { data?: string }; parts?: Array<unknown> } | null {\n if (!part) return null;\n if (part.mimeType === mime && !part.filename && part.body?.data) return part;\n for (const child of part.parts ?? []) {\n const hit = findPart(child as Parameters<typeof findPart>[0], mime);\n if (hit) return hit;\n }\n return null;\n}\n\nfunction extractGmailBody(payload: GmailMessage[\"payload\"] | undefined): string {\n if (!payload) return \"\";\n const plain = findPart(payload, \"text/plain\") as { body?: { data?: string } } | null;\n if (plain?.body?.data) return decodeBase64Url(plain.body.data);\n const html = findPart(payload, \"text/html\") as { body?: { data?: string } } | null;\n if (html?.body?.data) {\n return stripHtml(decodeBase64Url(html.body.data), { preserveParagraphs: true });\n }\n return \"\";\n}\n\nfunction recipientToStr(r?: GraphRecipient): string | null {\n const addr = r?.emailAddress?.address;\n if (!addr) return null;\n const name = r?.emailAddress?.name;\n return name && name !== addr ? `${name} <${addr}>` : addr;\n}\n\nfunction summarizeGraphMessage(m: GraphMessage): { title: string; text: string; updatedAt: string } {\n const from = recipientToStr(m.from) ?? \"\";\n const to = (m.toRecipients ?? []).map(recipientToStr).filter(Boolean).join(\", \");\n const cc = (m.ccRecipients ?? []).map(recipientToStr).filter(Boolean).join(\", \");\n const body = m.body?.content ?? m.bodyPreview ?? \"\";\n const plain = m.body?.contentType === \"html\"\n ? stripHtml(body, { preserveParagraphs: true })\n : body;\n const { text: capped } = truncateBytes(plain, BODY_CAP);\n const text = [\n `From: ${from}`,\n to ? `To: ${to}` : null,\n cc ? `Cc: ${cc}` : null,\n m.subject ? `Subject: ${m.subject}` : null,\n m.receivedDateTime ? `Date: ${m.receivedDateTime}` : null,\n \"\",\n capped,\n ].filter((line): line is string => line !== null).join(\"\\n\");\n return {\n title: m.subject?.trim() || m.id || \"(no subject)\",\n text,\n updatedAt: m.lastModifiedDateTime ?? m.receivedDateTime ?? new Date().toISOString(),\n };\n}\n\nfunction gmailSourceConfig(row: DocumentSourceRow): { query: string; max_results: number; page_size: number } {\n const cfg = parseSourceConfig<{ query?: string; max_results?: number; page_size?: number }>(row) ?? {};\n const query = String(cfg.query ?? \"\").trim();\n if (!query) throw new Error(\"gmail_mail source config.query is required\");\n const max_results = Math.min(Math.max(Number(cfg.max_results ?? DEFAULT_MAX_RESULTS), 1), MAX_RESULTS_CAP);\n const page_size = Math.min(Math.max(Number(cfg.page_size ?? DEFAULT_PAGE_SIZE), 1), 100);\n return { query, max_results, page_size };\n}\n\nfunction outlookSourceConfig(row: DocumentSourceRow): { query: string; max_results: number; page_size: number } {\n const cfg = parseSourceConfig<{ query?: string; max_results?: number; page_size?: number }>(row) ?? {};\n const query = String(cfg.query ?? \"\").trim();\n if (!query) throw new Error(\"outlook_mail source config.query is required\");\n const max_results = Math.min(Math.max(Number(cfg.max_results ?? DEFAULT_MAX_RESULTS), 1), MAX_RESULTS_CAP);\n const page_size = Math.min(Math.max(Number(cfg.page_size ?? DEFAULT_PAGE_SIZE), 1), 100);\n return { query, max_results, page_size };\n}\n\nasync function indexGmailMail(row: DocumentSourceRow): Promise<RemoteIndexStats> {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const { query, max_results, page_size } = gmailSourceConfig(row);\n\n const stats: RemoteIndexStats = { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0 };\n const keep = new Set<string>();\n let pageToken: string | undefined;\n\n while (stats.scanned < max_results) {\n const limit = Math.min(page_size, max_results - stats.scanned);\n const qs = new URLSearchParams({ q: query, maxResults: String(limit) });\n if (pageToken) qs.set(\"pageToken\", pageToken);\n const list = await googleFetch(\n auth,\n \"Gmail\",\n \"https://gmail.googleapis.com/gmail/v1/users/me\",\n `/messages?${qs.toString()}`,\n ) as GmailMessageList;\n if (list.error) throw new Error(list.error);\n\n const batch = list.messages ?? [];\n if (batch.length === 0) break;\n\n const results = await Promise.all(batch.slice(0, limit).map(async (entry) => {\n const msg = await googleFetch(\n auth,\n \"Gmail\",\n \"https://gmail.googleapis.com/gmail/v1/users/me\",\n `/messages/${encodeURIComponent(entry.id)}?format=full`,\n ) as GmailMessage;\n if (msg.error) throw new Error(msg.error);\n const title = msg.payload ? header(msg.payload.headers, \"Subject\") ?? entry.id : entry.id;\n const body = extractGmailBody(msg.payload);\n const text = [\n `From: ${header(msg.payload?.headers, \"From\") ?? \"\"}`,\n `To: ${header(msg.payload?.headers, \"To\") ?? \"\"}`,\n `Subject: ${title}`,\n `Date: ${header(msg.payload?.headers, \"Date\") ?? \"\"}`,\n msg.snippet ? `Snippet: ${msg.snippet}` : null,\n \"\",\n body,\n ].filter((line): line is string => line !== null).join(\"\\n\");\n const updatedAt = msg.internalDate\n ? new Date(Number(msg.internalDate)).toISOString()\n : header(msg.payload?.headers, \"Date\") ?? new Date().toISOString();\n return upsertRemoteDocument(row.id, {\n path: `gmail://${entry.id}`,\n title,\n externalUpdatedAt: updatedAt,\n text,\n });\n }));\n\n for (const [index, item] of results.entries()) {\n const id = batch[index]?.id ?? \"\";\n if (id) keep.add(`gmail://${id}`);\n stats.scanned++;\n stats.added += item.status === \"added\" ? 1 : 0;\n stats.updated += item.status === \"updated\" ? 1 : 0;\n stats.unchanged += item.status === \"unchanged\" ? 1 : 0;\n stats.errors += item.embedError ? 1 : 0;\n stats.embedFailed = (stats.embedFailed ?? 0) + Math.max(item.chunks - item.embedded, 0);\n if (item.embedError && !stats.embedError) stats.embedError = item.embedError;\n }\n\n pageToken = list.nextPageToken;\n if (!pageToken || batch.length < limit) break;\n }\n\n stats.removed = evictMissing(row.id, keep);\n return stats;\n}\n\nasync function indexOutlookMail(row: DocumentSourceRow): Promise<RemoteIndexStats> {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const { query, max_results, page_size } = outlookSourceConfig(row);\n\n const stats: RemoteIndexStats = { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0 };\n const keep = new Set<string>();\n let nextLink: string | null = null;\n\n while (stats.scanned < max_results) {\n const limit = Math.min(page_size, max_results - stats.scanned);\n const data = nextLink\n ? await graphFetch(auth, nextLink, { headers: { ConsistencyLevel: \"eventual\" } })\n : await graphFetch(\n auth,\n `/me/messages?$top=${limit}&$count=true&$select=id,subject,bodyPreview,from,toRecipients,ccRecipients,receivedDateTime,lastModifiedDateTime,isRead,isDraft,hasAttachments,categories,parentFolderId,webLink&$search=${encodeURIComponent(`\"${query.replace(/\"/g, '\\\\\"')}\"`)}`,\n { headers: { ConsistencyLevel: \"eventual\" } },\n );\n const payload = data as { value?: GraphMessage[]; \"@odata.nextLink\"?: string; error?: string };\n if (payload.error) throw new Error(payload.error);\n\n const batch = payload.value ?? [];\n if (batch.length === 0) break;\n\n const results = await Promise.all(batch.slice(0, limit).map(async (entry) => {\n const msg = await graphFetch(auth, `/me/messages/${encodeURIComponent(entry.id ?? \"\")}`) as GraphMessage & { error?: string };\n if (msg.error) throw new Error(msg.error);\n const summary = summarizeGraphMessage(msg);\n return upsertRemoteDocument(row.id, {\n path: `outlook://${msg.id ?? entry.id}`,\n title: summary.title,\n externalUpdatedAt: summary.updatedAt,\n text: summary.text,\n });\n }));\n\n for (const [index, item] of results.entries()) {\n const id = batch[index]?.id ?? \"\";\n if (id) keep.add(`outlook://${id}`);\n stats.scanned++;\n stats.added += item.status === \"added\" ? 1 : 0;\n stats.updated += item.status === \"updated\" ? 1 : 0;\n stats.unchanged += item.status === \"unchanged\" ? 1 : 0;\n stats.errors += item.embedError ? 1 : 0;\n stats.embedFailed = (stats.embedFailed ?? 0) + Math.max(item.chunks - item.embedded, 0);\n if (item.embedError && !stats.embedError) stats.embedError = item.embedError;\n }\n\n nextLink = payload[\"@odata.nextLink\"] ?? null;\n if (!nextLink || batch.length < limit) break;\n }\n\n stats.removed = evictMissing(row.id, keep);\n return stats;\n}\n\nexport async function runMailIndexer(source: DocumentSourceRow): Promise<RemoteIndexStats> {\n switch (source.kind) {\n case \"gmail_mail\":\n return indexGmailMail(source);\n case \"outlook_mail\":\n return indexOutlookMail(source);\n default:\n throw new Error(`unsupported mail source kind: ${source.kind}`);\n }\n}\n","// Jira remote indexer (ADR-0026).\n//\n// Source kinds handled:\n// - jira_project → JQL `project = \"<key>\"`\n// - jira_jql → user-supplied JQL\n//\n// Each indexed \"document\" is one issue, with its summary, description and\n// comments flattened into one text body. Comments live on the same chunk\n// graph as the issue body so the same retrieval query can surface either.\n\nimport {\n _atlassianFetch,\n _resolveAtlassianAuth,\n type AtlassianAuth,\n} from \"@/lib/tools/atlassian\";\nimport {\n parseSourceConfig,\n updateDocumentSourceCursor,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { adfToText } from \"./flatten\";\nimport { upsertRemoteDocument, type UpsertResult } from \"./upsert\";\n\nconst PAGE_LIMIT = 50;\nconst MAX_ISSUES_PER_RUN = 500;\n\ninterface JiraComment {\n author?: { displayName?: string };\n created?: string;\n body?: unknown; // ADF\n}\ninterface JiraIssueFields {\n summary?: string;\n description?: unknown; // ADF\n updated?: string;\n comment?: { comments?: JiraComment[]; total?: number };\n}\ninterface JiraIssue {\n key: string;\n fields?: JiraIssueFields;\n}\ninterface JiraSearchResp {\n issues?: JiraIssue[];\n nextPageToken?: string;\n}\n\nfunction buildJql(source: DocumentSourceRow, since: string | null): string {\n const cfg = parseSourceConfig<{ project_key?: string; jql?: string; recency_days?: number }>(source) ?? {};\n const clauses: string[] = [];\n if (source.kind === \"jira_project\") {\n if (!cfg.project_key) throw new Error(\"jira_project requires config.project_key\");\n clauses.push(`project = \"${cfg.project_key}\"`);\n } else if (source.kind === \"jira_jql\") {\n if (!cfg.jql) throw new Error(\"jira_jql requires config.jql\");\n clauses.push(`(${cfg.jql})`);\n }\n if (cfg.recency_days && cfg.recency_days > 0) {\n clauses.push(`updated >= -${cfg.recency_days}d`);\n }\n if (since) clauses.push(`updated > \"${formatJqlDate(since)}\"`);\n // Monotonic order keeps incremental cursors well-defined even on partial runs.\n return `${clauses.join(\" AND \")} ORDER BY updated ASC`;\n}\n\nfunction formatJqlDate(iso: string): string {\n // JQL `updated > \"yyyy/MM/dd HH:mm\"` — minute resolution is enough.\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getUTCFullYear()}/${pad(d.getUTCMonth() + 1)}/${pad(d.getUTCDate())} ` +\n `${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}`;\n}\n\nfunction flattenIssue(issue: JiraIssue, baseUrl: string): { text: string; updatedAt: string } {\n const f = issue.fields ?? {};\n const parts: string[] = [];\n parts.push(`${issue.key} — ${f.summary ?? \"\"}`.trim());\n parts.push(`${baseUrl}/browse/${issue.key}`);\n const desc = adfToText(f.description);\n if (desc) parts.push(desc);\n for (const c of f.comment?.comments ?? []) {\n const body = adfToText(c.body);\n if (!body.trim()) continue;\n const author = c.author?.displayName ?? \"unknown\";\n const ts = c.created ? ` (${c.created.slice(0, 10)})` : \"\";\n parts.push(`Comment by ${author}${ts}:\\n${body}`);\n }\n return {\n text: parts.join(\"\\n\\n\"),\n updatedAt: f.updated ?? new Date().toISOString(),\n };\n}\n\nasync function fetchIssue(auth: AtlassianAuth, key: string): Promise<JiraIssue | null> {\n const data = await _atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(key)}?fields=summary,description,updated,comment`,\n ) as JiraIssue & { error?: string };\n if (!data || (data as { error?: string }).error) return null;\n return data;\n}\n\nexport interface JiraIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n cursor: string | null;\n embedFailed: number;\n embedError: string | null;\n}\n\nexport async function runJiraIndexer(source: DocumentSourceRow): Promise<JiraIndexStats> {\n const stats: JiraIndexStats = {\n scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0,\n cursor: source.last_cursor,\n embedFailed: 0, embedError: null,\n };\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const jql = buildJql(source, source.last_cursor);\n let nextPageToken: string | undefined;\n let highWater = source.last_cursor;\n\n while (stats.scanned < MAX_ISSUES_PER_RUN) {\n const data = await _atlassianFetch(auth, \"/rest/api/3/search/jql\", {\n method: \"POST\",\n body: JSON.stringify({\n jql,\n fields: [\"summary\", \"description\", \"updated\", \"comment\"],\n maxResults: PAGE_LIMIT,\n nextPageToken,\n }),\n }) as JiraSearchResp & { error?: string };\n if ((data as { error?: string }).error) throw new Error((data as { error?: string }).error);\n const issues = data.issues ?? [];\n if (issues.length === 0) break;\n\n for (const issue of issues) {\n stats.scanned++;\n try {\n const { text, updatedAt } = flattenIssue(issue, auth.url);\n const res = await upsertRemoteDocument(source.id, {\n path: `jira://${issue.key}`,\n title: `${issue.key}: ${issue.fields?.summary ?? \"\"}`.trim(),\n externalUpdatedAt: updatedAt,\n text,\n });\n if (res.status === \"added\") stats.added++;\n else if (res.status === \"updated\") stats.updated++;\n else stats.unchanged++;\n stats.embedFailed += res.chunks - res.embedded;\n if (res.embedError && !stats.embedError) stats.embedError = res.embedError;\n if (!highWater || updatedAt > highWater) highWater = updatedAt;\n } catch {\n stats.errors++;\n }\n }\n nextPageToken = data.nextPageToken;\n if (!nextPageToken) break;\n }\n\n if (highWater && highWater !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, highWater);\n stats.cursor = highWater;\n }\n return stats;\n}\n\n/** On-demand: fetch & index a single issue by key under the shared\n * on_demand_url source row. */\nexport async function indexJiraIssueByKey(\n sourceId: string,\n key: string,\n): Promise<UpsertResult> {\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const issue = await fetchIssue(auth, key);\n if (!issue) throw new Error(`jira issue ${key} not found`);\n const { text, updatedAt } = flattenIssue(issue, auth.url);\n return upsertRemoteDocument(sourceId, {\n path: `jira://${issue.key}`,\n title: `${issue.key}: ${issue.fields?.summary ?? \"\"}`.trim(),\n externalUpdatedAt: updatedAt,\n text,\n });\n}\n","// GitHub remote indexer (ADR-0029).\n//\n// Source kinds handled:\n// - github_pulls → all PRs of one repo + their issue comments + review\n// bodies, flattened to one document per PR.\n// - github_repo → text files on one branch of one repo (default branch\n// by default), walked via the Git Trees API. Filtered\n// by the same extension allowlist + binary heuristic\n// as the local-folder walker so the two surfaces stay\n// in sync.\n//\n// On-demand helpers (called via lib/documents/remote/index.ts'\n// indexOnDemand) cover one-shot indexing of a PR / issue / file URL\n// under the shared `on_demand_url` source row.\n\nimport {\n _ghFetch,\n _resolveGithubAuth,\n type GitHubAuth,\n} from \"@/lib/tools/github\";\nimport {\n parseSourceConfig,\n updateDocumentSourceCursor,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { ALLOWED_EXT, isLikelyBinary, lowerExt } from \"../indexer\";\nimport { upsertRemoteDocument, type UpsertResult } from \"./upsert\";\n\nconst PR_PAGE_LIMIT = 50;\nconst MAX_PRS_PER_RUN = 200;\nconst MAX_FILES_PER_RUN = 500;\nconst MAX_FILE_BYTES = 2 * 1024 * 1024; // matches local indexer\n\ninterface GhUserLite { login?: string }\ninterface GhPull {\n number: number;\n title?: string;\n state?: string;\n body?: string;\n updated_at?: string;\n html_url?: string;\n user?: GhUserLite;\n draft?: boolean;\n}\ninterface GhIssueComment {\n user?: GhUserLite;\n created_at?: string;\n body?: string;\n}\ninterface GhReview {\n user?: GhUserLite;\n state?: string;\n submitted_at?: string;\n body?: string;\n}\ninterface GhIssue {\n number: number;\n title?: string;\n body?: string;\n updated_at?: string;\n state?: string;\n html_url?: string;\n user?: GhUserLite;\n}\ninterface GhTreeEntry {\n path: string;\n type: \"blob\" | \"tree\" | \"commit\";\n size?: number;\n sha?: string;\n}\ninterface GhTreeResp {\n sha?: string;\n tree?: GhTreeEntry[];\n truncated?: boolean;\n}\ninterface GhRepo {\n default_branch?: string;\n}\ninterface GhContents {\n type?: \"file\" | \"dir\" | \"symlink\" | \"submodule\";\n encoding?: string;\n content?: string;\n size?: number;\n sha?: string;\n}\n\nfunction ghError(data: unknown): string | null {\n return (data as { error?: string })?.error ?? null;\n}\n\nfunction liteAuthor(u: GhUserLite | undefined): string {\n return u?.login ?? \"unknown\";\n}\n\n// One-document-per-PR text body. Mirrors the Jira flattener: title +\n// URL on the first lines so retrieval results read sensibly even when\n// only the leading chunk surfaces.\nfunction flattenPull(\n pr: GhPull,\n comments: GhIssueComment[],\n reviews: GhReview[],\n): string {\n const parts: string[] = [];\n parts.push(`PR #${pr.number}: ${pr.title ?? \"\"}`.trim());\n if (pr.html_url) parts.push(pr.html_url);\n parts.push(`State: ${pr.state ?? \"unknown\"}${pr.draft ? \" (draft)\" : \"\"} · author: ${liteAuthor(pr.user)}`);\n if (pr.body && pr.body.trim()) parts.push(pr.body.trim());\n for (const c of comments) {\n if (!c.body?.trim()) continue;\n const ts = c.created_at ? ` (${c.created_at.slice(0, 10)})` : \"\";\n parts.push(`Comment by ${liteAuthor(c.user)}${ts}:\\n${c.body.trim()}`);\n }\n for (const r of reviews) {\n if (!r.body?.trim()) continue;\n const ts = r.submitted_at ? ` (${r.submitted_at.slice(0, 10)})` : \"\";\n parts.push(`Review by ${liteAuthor(r.user)} — ${r.state ?? \"\"}${ts}:\\n${r.body.trim()}`);\n }\n return parts.join(\"\\n\\n\");\n}\n\nfunction flattenIssue(issue: GhIssue, comments: GhIssueComment[]): string {\n const parts: string[] = [];\n parts.push(`Issue #${issue.number}: ${issue.title ?? \"\"}`.trim());\n if (issue.html_url) parts.push(issue.html_url);\n parts.push(`State: ${issue.state ?? \"unknown\"} · author: ${liteAuthor(issue.user)}`);\n if (issue.body && issue.body.trim()) parts.push(issue.body.trim());\n for (const c of comments) {\n if (!c.body?.trim()) continue;\n const ts = c.created_at ? ` (${c.created_at.slice(0, 10)})` : \"\";\n parts.push(`Comment by ${liteAuthor(c.user)}${ts}:\\n${c.body.trim()}`);\n }\n return parts.join(\"\\n\\n\");\n}\n\nasync function listIssueComments(auth: GitHubAuth, owner: string, repo: string, n: number): Promise<GhIssueComment[]> {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${n}/comments?per_page=100`,\n );\n return Array.isArray(data) ? (data as GhIssueComment[]) : [];\n}\n\nasync function listReviews(auth: GitHubAuth, owner: string, repo: string, n: number): Promise<GhReview[]> {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${n}/reviews?per_page=100`,\n );\n return Array.isArray(data) ? (data as GhReview[]) : [];\n}\n\nexport interface GithubIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n cursor: string | null;\n embedFailed: number;\n embedError: string | null;\n}\n\nfunction emptyStats(cursor: string | null): GithubIndexStats {\n return { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0, cursor, embedFailed: 0, embedError: null };\n}\n\nfunction applyUpsert(stats: GithubIndexStats, res: UpsertResult): void {\n if (res.status === \"added\") stats.added++;\n else if (res.status === \"updated\") stats.updated++;\n else stats.unchanged++;\n stats.embedFailed += res.chunks - res.embedded;\n if (res.embedError && !stats.embedError) stats.embedError = res.embedError;\n}\n\n// ── github_pulls ──────────────────────────────────────────────────────────\n\ninterface PullsConfig {\n owner?: string;\n repo?: string;\n recency_days?: number;\n state?: \"open\" | \"closed\" | \"all\";\n}\n\nasync function runGithubPullsIndexer(source: DocumentSourceRow): Promise<GithubIndexStats> {\n const cfg = parseSourceConfig<PullsConfig>(source) ?? {};\n if (!cfg.owner || !cfg.repo) throw new Error(\"github_pulls requires config.owner and config.repo\");\n const stats = emptyStats(source.last_cursor);\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const cutoffMs = cfg.recency_days && cfg.recency_days > 0\n ? Date.now() - cfg.recency_days * 86_400_000\n : null;\n const sinceMs = source.last_cursor ? Date.parse(source.last_cursor) : NaN;\n const state = cfg.state ?? \"all\";\n let highWater = source.last_cursor;\n\n // Sorted by `updated desc` so we can stop early as soon as we drop\n // below the watermark or the recency cutoff.\n let page = 1;\n outer: while (stats.scanned < MAX_PRS_PER_RUN) {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(cfg.owner)}/${encodeURIComponent(cfg.repo)}/pulls` +\n `?state=${state}&sort=updated&direction=desc&per_page=${PR_PAGE_LIMIT}&page=${page}`,\n );\n const err = ghError(data);\n if (err) throw new Error(err);\n const pulls = Array.isArray(data) ? (data as GhPull[]) : [];\n if (pulls.length === 0) break;\n\n for (const pr of pulls) {\n stats.scanned++;\n const updated = pr.updated_at ?? \"\";\n const updatedMs = Date.parse(updated);\n if (cutoffMs !== null && Number.isFinite(updatedMs) && updatedMs < cutoffMs) break outer;\n if (Number.isFinite(sinceMs) && Number.isFinite(updatedMs) && updatedMs <= sinceMs) break outer;\n\n try {\n const [comments, reviews] = await Promise.all([\n listIssueComments(auth, cfg.owner, cfg.repo, pr.number),\n listReviews(auth, cfg.owner, cfg.repo, pr.number),\n ]);\n const text = flattenPull(pr, comments, reviews);\n const res = await upsertRemoteDocument(source.id, {\n path: `github-pull://${cfg.owner}/${cfg.repo}/${pr.number}`,\n title: `PR #${pr.number}: ${pr.title ?? \"\"}`.trim(),\n externalUpdatedAt: updated || new Date().toISOString(),\n text,\n });\n applyUpsert(stats, res);\n if (updated && (!highWater || updated > highWater)) highWater = updated;\n } catch {\n stats.errors++;\n }\n }\n if (pulls.length < PR_PAGE_LIMIT) break;\n page++;\n }\n\n if (highWater && highWater !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, highWater);\n stats.cursor = highWater;\n }\n return stats;\n}\n\n// ── github_repo ───────────────────────────────────────────────────────────\n\ninterface RepoConfig {\n owner?: string;\n repo?: string;\n ref?: string;\n path_prefix?: string;\n}\n\nasync function resolveDefaultBranch(auth: GitHubAuth, owner: string, repo: string): Promise<string> {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`,\n ) as GhRepo & { error?: string };\n if (data.error) throw new Error(data.error);\n if (!data.default_branch) throw new Error(`could not resolve default branch for ${owner}/${repo}`);\n return data.default_branch;\n}\n\nasync function runGithubRepoIndexer(source: DocumentSourceRow): Promise<GithubIndexStats> {\n const cfg = parseSourceConfig<RepoConfig>(source) ?? {};\n if (!cfg.owner || !cfg.repo) throw new Error(\"github_repo requires config.owner and config.repo\");\n const stats = emptyStats(source.last_cursor);\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const ref = cfg.ref ?? await resolveDefaultBranch(auth, cfg.owner, cfg.repo);\n const tree = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(cfg.owner)}/${encodeURIComponent(cfg.repo)}/git/trees/${encodeURIComponent(ref)}?recursive=1`,\n ) as GhTreeResp & { error?: string };\n if (tree.error) throw new Error(tree.error);\n const treeSha = tree.sha ?? null;\n\n // Cheap no-op: if the branch head hasn't moved since last walk, skip\n // the whole thing. Saves a contents fetch per file on quiet repos.\n if (treeSha && source.last_cursor === treeSha) {\n stats.cursor = treeSha;\n return stats;\n }\n\n const prefix = (cfg.path_prefix ?? \"\").replace(/^\\/+|\\/+$/g, \"\");\n const blobs = (tree.tree ?? []).filter((e) => {\n if (e.type !== \"blob\") return false;\n if (typeof e.size === \"number\" && e.size > MAX_FILE_BYTES) return false;\n if (!ALLOWED_EXT.has(lowerExt(e.path))) return false;\n if (prefix && !(e.path === prefix || e.path.startsWith(prefix + \"/\"))) return false;\n return true;\n });\n\n for (const entry of blobs) {\n if (stats.scanned >= MAX_FILES_PER_RUN) break;\n stats.scanned++;\n try {\n const contents = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(cfg.owner)}/${encodeURIComponent(cfg.repo)}/contents/${entry.path\n .split(\"/\").map(encodeURIComponent).join(\"/\")}?ref=${encodeURIComponent(ref)}`,\n ) as GhContents & { error?: string };\n if (contents.error) { stats.errors++; continue; }\n if (contents.type !== \"file\" || !contents.content) continue;\n const buf = Buffer.from(contents.content.replace(/\\s+/g, \"\"), contents.encoding === \"base64\" ? \"base64\" : \"utf8\");\n if (isLikelyBinary(buf)) continue;\n const text = buf.toString(\"utf8\");\n const res = await upsertRemoteDocument(source.id, {\n path: `github-file://${cfg.owner}/${cfg.repo}@${ref}/${entry.path}`,\n title: entry.path,\n externalUpdatedAt: new Date().toISOString(), // tree SHA carries the cursor; per-file mtime would need a commits API call we'd rather skip\n text,\n });\n applyUpsert(stats, res);\n } catch {\n stats.errors++;\n }\n }\n\n if (treeSha && treeSha !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, treeSha);\n stats.cursor = treeSha;\n }\n return stats;\n}\n\n// ── Dispatcher entry-point used by lib/documents/remote/index.ts ──────────\n\nexport async function runGithubIndexer(source: DocumentSourceRow): Promise<GithubIndexStats> {\n if (source.kind === \"github_pulls\") return runGithubPullsIndexer(source);\n if (source.kind === \"github_repo\") return runGithubRepoIndexer(source);\n throw new Error(`runGithubIndexer called with unsupported kind: ${source.kind}`);\n}\n\n// ── On-demand helpers (called from indexOnDemand) ─────────────────────────\n\nexport async function indexGithubPullByUrl(\n sourceId: string,\n owner: string,\n repo: string,\n number: number,\n): Promise<UpsertResult> {\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const pr = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}`,\n ) as GhPull & { error?: string };\n if (pr.error) throw new Error(pr.error);\n const [comments, reviews] = await Promise.all([\n listIssueComments(auth, owner, repo, number),\n listReviews(auth, owner, repo, number),\n ]);\n const text = flattenPull(pr, comments, reviews);\n return upsertRemoteDocument(sourceId, {\n path: `github-pull://${owner}/${repo}/${number}`,\n title: `PR #${number}: ${pr.title ?? \"\"}`.trim(),\n externalUpdatedAt: pr.updated_at ?? new Date().toISOString(),\n text,\n });\n}\n\nexport async function indexGithubIssueByUrl(\n sourceId: string,\n owner: string,\n repo: string,\n number: number,\n): Promise<UpsertResult> {\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const issue = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}`,\n ) as GhIssue & { error?: string };\n if (issue.error) throw new Error(issue.error);\n const comments = await listIssueComments(auth, owner, repo, number);\n const text = flattenIssue(issue, comments);\n return upsertRemoteDocument(sourceId, {\n path: `github-issue://${owner}/${repo}/${number}`,\n title: `Issue #${number}: ${issue.title ?? \"\"}`.trim(),\n externalUpdatedAt: issue.updated_at ?? new Date().toISOString(),\n text,\n });\n}\n\nexport async function indexGithubFileByUrl(\n sourceId: string,\n owner: string,\n repo: string,\n ref: string,\n path: string,\n): Promise<UpsertResult> {\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const contents = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/contents/${path\n .split(\"/\").map(encodeURIComponent).join(\"/\")}?ref=${encodeURIComponent(ref)}`,\n ) as GhContents & { error?: string };\n if (contents.error) throw new Error(contents.error);\n if (contents.type !== \"file\" || !contents.content) {\n throw new Error(`github contents at ${path} is not a file`);\n }\n const buf = Buffer.from(contents.content.replace(/\\s+/g, \"\"), contents.encoding === \"base64\" ? \"base64\" : \"utf8\");\n if (isLikelyBinary(buf)) throw new Error(`github file ${path} appears to be binary`);\n return upsertRemoteDocument(sourceId, {\n path: `github-file://${owner}/${repo}@${ref}/${path}`,\n title: path,\n externalUpdatedAt: new Date().toISOString(),\n text: buf.toString(\"utf8\"),\n });\n}\n","// Remote document-source dispatcher (ADR-0026).\n//\n// `lib/documents/indexer.ts` walks local folders. For non-local kinds it\n// delegates to one of these per-kind handlers. Keeping the dispatcher tiny\n// (just a switch) keeps the local-folder happy path untouched.\n\nimport {\n createDocumentSource,\n getDocumentSourceByPath,\n markSourceScanned,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { runConfluenceIndexer, indexConfluencePageById } from \"./confluence\";\nimport { runMailIndexer } from \"./mail\";\nimport { runJiraIndexer, indexJiraIssueByKey } from \"./jira\";\nimport {\n runGithubIndexer,\n indexGithubPullByUrl,\n indexGithubIssueByUrl,\n indexGithubFileByUrl,\n} from \"./github\";\nimport type { UpsertResult } from \"./upsert\";\n\nexport interface RemoteIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n removed?: number;\n /** Total chunks across this run that didn't get an embedding vector. */\n embedFailed?: number;\n /** First embed error message seen, if any. */\n embedError?: string | null;\n}\n\n/** Returns true if `kind` is anything other than `local_folder`. */\nexport function isRemoteKind(kind: string): boolean {\n return kind !== \"local_folder\";\n}\n\nexport async function runRemoteSource(source: DocumentSourceRow): Promise<RemoteIndexStats> {\n let lastError: string | null = null;\n let stats: RemoteIndexStats = { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0 };\n try {\n switch (source.kind) {\n case \"confluence_space\":\n case \"confluence_cql\": {\n const s = await runConfluenceIndexer(source);\n stats = s;\n break;\n }\n case \"jira_project\":\n case \"jira_jql\": {\n const s = await runJiraIndexer(source);\n stats = s;\n break;\n }\n case \"github_pulls\":\n case \"github_repo\": {\n const s = await runGithubIndexer(source);\n stats = s;\n break;\n }\n case \"gmail_mail\":\n case \"outlook_mail\": {\n const s = await runMailIndexer(source);\n stats = s;\n break;\n }\n case \"on_demand_url\":\n // No background sweep — items are added one-at-a-time via\n // indexOnDemand() from the tool / API surface.\n break;\n default:\n throw new Error(`unsupported remote source kind: ${source.kind}`);\n }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n // Mirror the local indexer's surfacing rule: a fetch error wins; otherwise\n // bubble up an embed-failure summary so the operator sees that semantic\n // search is degraded for this source without grepping logs.\n const embedFailed = stats.embedFailed ?? 0;\n const composite = lastError\n ? lastError\n : embedFailed > 0\n ? `${embedFailed} chunk${embedFailed === 1 ? \"\" : \"s\"} failed to embed${stats.embedError ? \": \" + stats.embedError : \"\"}`\n : null;\n markSourceScanned(source.id, composite);\n return stats;\n}\n\n/** Singleton \"on-demand URLs\" source row. Lazily created on first use. */\nconst ON_DEMAND_PATH = \"on-demand://urls\";\nexport function getOrCreateOnDemandSource(): DocumentSourceRow {\n const existing = getDocumentSourceByPath(ON_DEMAND_PATH);\n if (existing) return existing;\n return createDocumentSource({\n path: ON_DEMAND_PATH,\n label: \"On-demand URLs\",\n kind: \"on_demand_url\",\n config: null,\n });\n}\n\n/**\n * Resolve a free-form input (Jira issue key, Jira browse URL, Confluence\n * page URL, GitHub PR/issue/blob URL) to \"fetch this one thing and index\n * it under the on-demand source\". Surfaced via the `documents_index_url`\n * tool + HTTP API. ADR-0029 added the GitHub matchers.\n */\nexport async function indexOnDemand(input: string): Promise<{\n kind: \"jira\" | \"confluence\" | \"github\";\n identifier: string;\n result: UpsertResult;\n source_id: string;\n}> {\n const trimmed = input.trim();\n if (!trimmed) throw new Error(\"input is required\");\n const source = getOrCreateOnDemandSource();\n\n // Bare Jira key.\n const bareKey = /^[A-Z][A-Z0-9_]+-\\d+$/;\n if (bareKey.test(trimmed)) {\n const result = await indexJiraIssueByKey(source.id, trimmed);\n return { kind: \"jira\", identifier: trimmed, result, source_id: source.id };\n }\n // Jira /browse/<KEY>\n const browse = trimmed.match(/\\/browse\\/([A-Z][A-Z0-9_]+-\\d+)/);\n if (browse) {\n const result = await indexJiraIssueByKey(source.id, browse[1]);\n return { kind: \"jira\", identifier: browse[1], result, source_id: source.id };\n }\n // Confluence /wiki/spaces/.../pages/<id>\n const pages = trimmed.match(/\\/wiki\\/spaces\\/[^/]+\\/pages\\/(\\d+)/);\n if (pages) {\n const result = await indexConfluencePageById(source.id, pages[1]);\n return { kind: \"confluence\", identifier: pages[1], result, source_id: source.id };\n }\n // Confluence ?pageId=<id>\n const pageId = trimmed.match(/[?&]pageId=(\\d+)/);\n if (pageId) {\n const result = await indexConfluencePageById(source.id, pageId[1]);\n return { kind: \"confluence\", identifier: pageId[1], result, source_id: source.id };\n }\n // GitHub PR /pull/<n>\n const ghPull = trimmed.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/pull\\/(\\d+)/);\n if (ghPull) {\n const [, owner, repo, n] = ghPull;\n const result = await indexGithubPullByUrl(source.id, owner, repo, Number(n));\n return { kind: \"github\", identifier: `${owner}/${repo}#${n}`, result, source_id: source.id };\n }\n // GitHub issue /issues/<n>\n const ghIssue = trimmed.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/issues\\/(\\d+)/);\n if (ghIssue) {\n const [, owner, repo, n] = ghIssue;\n const result = await indexGithubIssueByUrl(source.id, owner, repo, Number(n));\n return { kind: \"github\", identifier: `${owner}/${repo}#${n}`, result, source_id: source.id };\n }\n // GitHub file /blob/<ref>/<path>\n const ghBlob = trimmed.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/blob\\/([^/]+)\\/(.+)$/);\n if (ghBlob) {\n const [, owner, repo, ref, path] = ghBlob;\n const cleanPath = path.split(\"?\")[0].split(\"#\")[0];\n const result = await indexGithubFileByUrl(source.id, owner, repo, ref, cleanPath);\n return { kind: \"github\", identifier: `${owner}/${repo}@${ref}/${cleanPath}`, result, source_id: source.id };\n }\n\n throw new Error(\n \"could not recognise input — expected a Jira issue key (ABC-123), a /browse/<KEY> URL, \" +\n \"a Confluence /wiki/spaces/.../pages/<id> URL, or a GitHub /pull/<n>, /issues/<n>, or \" +\n \"/blob/<ref>/<path> URL.\",\n );\n}\n","// Tiny in-process pub/sub for app-level events the UI wants to surface as\n// browser notifications. Run completions and scheduled-task firings both\n// publish here; the frontend subscribes via a single SSE endpoint.\n\nexport type NotificationEvent =\n | {\n type: \"run_completed\";\n thread_id: string;\n agent_id: string | null;\n status: \"done\" | \"error\";\n preview: string; // first ~100 chars of assistant reply\n ts: number;\n }\n | {\n type: \"task_completed\";\n task_id: string;\n agent_id: string;\n prompt: string;\n thread_id: string;\n // \"skipped\" is emitted when a silent scheduled task ran but the agent\n // chose not to surface a reply (NO_REPLY sentinel or empty). The chat\n // already stays quiet via messages.hidden; downstream notification\n // sinks can drop the ping too.\n status: \"done\" | \"error\" | \"skipped\";\n preview: string;\n error?: string;\n ts: number;\n }\n | {\n // Bridge replied to an inbound message on a configured route.\n type: \"bridge_message_received\";\n bridge_id: string;\n remote_jid: string;\n push_name: string | null;\n is_group: boolean;\n thread_id: string;\n agent_id: string;\n preview: string; // first ~120 chars of assistant reply\n ts: number;\n }\n | {\n // Bridge received a message from a chat that has no route configured.\n // Advisory only — surfaced in the UI as a \"Add route\" hint so the user\n // can copy the JID into a new route. The message itself is dropped.\n type: \"bridge_unrouted\";\n bridge_id: string;\n remote_jid: string;\n push_name: string | null;\n is_group: boolean;\n preview: string;\n ts: number;\n }\n | {\n // Bridge connection lifecycle: disconnected | pairing | connected | error.\n // Lets the UI flip status pills and surface QR data URLs live without\n // polling.\n type: \"bridge_status\";\n bridge_id: string;\n status: \"disconnected\" | \"pairing\" | \"connected\" | \"error\";\n error: string | null;\n paired_id: string | null;\n ts: number;\n }\n | {\n // A new message landed in a thread without an active LLM run firing —\n // currently published by the browser-extension page-capture route so\n // the open chat view re-fetches without waiting for the next run.\n type: \"thread_message_added\";\n thread_id: string;\n agent_id: string;\n source: \"page_capture\";\n ts: number;\n };\n\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\n\ntype Listener = (ev: NotificationEvent) => void;\nconst RECENT_LIMIT = 50;\n\ninterface BusState {\n listeners: Set<Listener>;\n recent: NotificationEvent[];\n}\nconst busState = getOrCreateGlobal<BusState>(\"__jarela_notif_bus\", () => ({\n listeners: new Set<Listener>(),\n recent: [],\n}));\nconst listeners = busState.listeners;\nconst recent = busState.recent;\n\nexport function publish(ev: NotificationEvent): void {\n recent.push(ev);\n if (recent.length > RECENT_LIMIT) recent.shift();\n for (const l of listeners) {\n try { l(ev); } catch { /* listener errored, ignore */ }\n }\n}\n\nexport function subscribe(fn: Listener): () => void {\n listeners.add(fn);\n return () => { listeners.delete(fn); };\n}\n\n// Replay events newer than `sinceTs` (used when a client reconnects).\nexport function recentSince(sinceTs: number): NotificationEvent[] {\n return recent.filter((e) => e.ts > sinceTs);\n}\n","// Ephemeral state store + shared auth helpers for the in-app Microsoft OAuth\n// flow. Mirrors lib/integrations/gmail-oauth.ts but targets the Microsoft\n// identity platform (v2.0 endpoint, common tenant by default) and Microsoft\n// Graph as the downstream API surface (Outlook Mail + Calendar in v1).\n//\n// The user types client_id + client_secret in the Integrations panel and\n// clicks \"Connect Outlook\". We POST those to /oauth/start, which stashes\n// them here keyed by a random `state` token and returns the Microsoft\n// authorize URL. The browser opens that URL; MS bounces back to\n// /oauth/callback with `?code&state`, which exchanges the code for a\n// refresh_token (granted because we asked for `offline_access`) and\n// persists the integration. The panel polls /oauth/status separately.\n//\n// Pinned to globalThis so HMR in dev doesn't lose pending flows.\n\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { createOAuthFlowStore, type OAuthFlow } from \"@/lib/utils/oauth-flow-store\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\n\nexport type { OAuthFlow };\n\nconst flowStore = createOAuthFlowStore({ globalKey: \"__msOauthFlows\" });\n\nexport const createFlow = flowStore.create;\nexport const getFlow = flowStore.get;\nexport const updateFlow = flowStore.update;\nexport const deleteFlow = flowStore.delete;\n\n// Tenant selector. `common` accepts both personal Microsoft accounts\n// (@outlook.com, @hotmail.com, @live.com) and work/school M365 accounts.\n// Switch to `consumers` to lock to personal only, or `organizations` for\n// work/school only. We expose this as an env override for power users but\n// don't surface it in the UI yet.\nconst TENANT = process.env.OUTLOOK_TENANT?.trim() || \"common\";\n\n// Delegated Graph scopes the agent needs. Keep narrow:\n// - offline_access → required for a refresh_token (MS counterpart of\n// Google's access_type=offline).\n// - User.Read → used by the test endpoint to call /me.\n// - Mail.ReadWrite → search/read mail, create drafts, mark read,\n// move to folders (incl. DeletedItems). Does NOT\n// grant sending — matches our Gmail \"drafts only\"\n// stance via gmail.compose.\n// - Calendars.ReadWrite → list/get/create/update/delete events on the\n// user's existing calendars.\nexport const MICROSOFT_SCOPES = [\n \"offline_access\",\n \"User.Read\",\n \"Mail.ReadWrite\",\n \"Calendars.ReadWrite\",\n];\n\nexport function buildAuthorizeUrl(opts: {\n clientId: string;\n redirectUri: string;\n state: string;\n}): string {\n const p = new URLSearchParams({\n client_id: opts.clientId,\n redirect_uri: opts.redirectUri,\n response_type: \"code\",\n response_mode: \"query\",\n scope: MICROSOFT_SCOPES.join(\" \"),\n // Force consent so a returning user actually re-grants any newly-added\n // scope (otherwise MS silently reuses the prior grant minus the new bit).\n prompt: \"consent\",\n state: opts.state,\n });\n return `https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/authorize?${p.toString()}`;\n}\n\n// NOTE: Unlike Google, MS v2 endpoint **requires** the `scope` parameter on\n// every grant_type call (both authorization_code and refresh_token). Leaving\n// it out yields `AADSTS900144: The request body must contain the following\n// parameter: 'scope'.`. We always pass the full scope set.\nexport async function exchangeCode(opts: {\n code: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n}): Promise<{ refresh_token?: string; access_token?: string; expires_in?: number; scope?: string }> {\n const body = new URLSearchParams({\n code: opts.code,\n client_id: opts.clientId,\n client_secret: opts.clientSecret,\n redirect_uri: opts.redirectUri,\n grant_type: \"authorization_code\",\n scope: MICROSOFT_SCOPES.join(\" \"),\n });\n const res = await fetch(`https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n const parsed = parseJsonSafe<Record<string, unknown>>(text, {});\n if (!res.ok) {\n const err = (parsed[\"error_description\"] || parsed[\"error\"] || text || `HTTP ${res.status}`) as string;\n throw new Error(err);\n }\n return parsed as { refresh_token?: string; access_token?: string; expires_in?: number; scope?: string };\n}\n\n// ---------------------------------------------------------------------------\n// Shared Microsoft Graph auth (Outlook Mail + Calendar + future Graph scopes)\n// ---------------------------------------------------------------------------\n\nexport interface MicrosoftAuth {\n client_id: string;\n client_secret: string;\n refresh_token: string;\n}\n\nexport function resolveMicrosoftAuth(): MicrosoftAuth | { error: string } {\n const envId = process.env.OUTLOOK_CLIENT_ID;\n const envSecret = process.env.OUTLOOK_CLIENT_SECRET;\n const envRefresh = process.env.OUTLOOK_REFRESH_TOKEN;\n if (envId && envSecret && envRefresh) {\n return { client_id: envId, client_secret: envSecret, refresh_token: envRefresh };\n }\n const saved = getIntegrationRaw(\"outlook\");\n if (saved?.client_id && saved.client_secret && saved.refresh_token) {\n return {\n client_id: saved.client_id,\n client_secret: saved.client_secret,\n refresh_token: saved.refresh_token,\n };\n }\n return {\n error:\n \"Microsoft account not connected. Open the gear menu → Integrations tab → \" +\n \"Outlook card and click Connect Outlook to authorize Mail + Calendar access.\",\n };\n}\n\ninterface CachedAccessToken { token: string; expires_at: number }\nconst accessTokenCache = new Map<string, CachedAccessToken>();\n\nexport async function getMicrosoftAccessToken(\n auth: MicrosoftAuth,\n): Promise<string | { error: string }> {\n const key = auth.refresh_token.slice(0, 20);\n const cached = accessTokenCache.get(key);\n if (cached && cached.expires_at > Date.now() + 60_000) return cached.token;\n\n const body = new URLSearchParams({\n client_id: auth.client_id,\n client_secret: auth.client_secret,\n refresh_token: auth.refresh_token,\n grant_type: \"refresh_token\",\n // Required on the v2 endpoint even for refresh_token grants.\n scope: MICROSOFT_SCOPES.join(\" \"),\n });\n try {\n const res = await fetch(`https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n if (!res.ok) {\n accessTokenCache.delete(key);\n return { error: `Microsoft OAuth refresh failed (${res.status}): ${text.slice(0, 300)}` };\n }\n const parsed = JSON.parse(text) as { access_token?: string; expires_in?: number };\n if (!parsed.access_token) return { error: \"OAuth response missing access_token\" };\n const expires_at = Date.now() + (parsed.expires_in ?? 3000) * 1000;\n accessTokenCache.set(key, { token: parsed.access_token, expires_at });\n return parsed.access_token;\n } catch (err) {\n return { error: `Microsoft OAuth refresh threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n\n// Shared Graph fetch helper. Used by both lib/tools/outlook.ts and\n// lib/tools/outlook-calendar.ts. Returns parsed JSON or { error: string, url? }.\n// 204 No Content (e.g. successful DELETE) returns { ok: true }.\nexport async function graphFetch(\n auth: MicrosoftAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const token = await getMicrosoftAccessToken(auth);\n if (typeof token !== \"string\") return token;\n const url = path.startsWith(\"http\") ? path : `https://graph.microsoft.com/v1.0${path}`;\n try {\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n signal: AbortSignal.timeout(30_000),\n });\n if (res.status === 204) return { ok: true };\n const text = await res.text();\n if (!res.ok) {\n return { error: `Graph ${res.status}: ${text.slice(0, 500)}`, url };\n }\n try { return JSON.parse(text); } catch { return text; }\n } catch (err) {\n return { error: `Graph fetch threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\nimport { embedOne } from \"@/lib/embeddings\";\n\nconst now = () => new Date().toISOString();\n\n// Explicit column list for message reads — omits `embedding` (~20KB of\n// JSON-encoded float[] per row) which only the embeddings module reads.\n// Avoids dragging it through the chat-history result set on every call.\nconst MSG_COLS_SQL = \"SELECT msg_id, thread_id, role, content, created_at, tool_events, category FROM messages\";\n\nexport interface ThreadRow {\n thread_id: string; agent_id: string; title: string | null;\n created_at: string; updated_at: string; message_count: number;\n}\nexport interface MessageRow {\n msg_id: string; thread_id: string; role: string; content: string; created_at: string;\n // JSON-encoded array of PersistedToolEvent. null when no tool work happened\n // on this turn or for user messages. Read back by the chat UI so historical\n // bubbles show the same expandable CALL/RESULT entries as live streaming.\n tool_events?: string | null;\n // Non-null tags classify the message into a filterable group in the chat\n // panel (e.g. 'scheduled_task', 'bridge', 'synthetic'). NULL = ordinary\n // user/assistant chat content.\n category?: string | null;\n}\n\nexport interface PersistedToolEvent {\n id: string;\n phase: \"call\" | \"result\";\n name: string;\n payload: unknown;\n}\n\nexport function listThreads(limit = 50, offset = 0): ThreadRow[] {\n return getDb()\n .prepare(\"SELECT * FROM threads ORDER BY updated_at DESC LIMIT ? OFFSET ?\")\n .all(limit, offset) as unknown as ThreadRow[];\n}\n\nexport function listThreadsByAgent(agent_id: string, limit = 50): ThreadRow[] {\n return getDb()\n .prepare(\"SELECT * FROM threads WHERE agent_id=? ORDER BY updated_at DESC LIMIT ?\")\n .all(agent_id, limit) as unknown as ThreadRow[];\n}\n\nexport function getThread(thread_id: string): ThreadRow | null {\n return (getDb().prepare(\"SELECT * FROM threads WHERE thread_id=?\").get(thread_id) as unknown as ThreadRow) ?? null;\n}\n\nexport function createThread(agent_id: string, title?: string): ThreadRow {\n const t = now();\n const thread_id = randomUUID();\n getDb()\n .prepare(\"INSERT INTO threads (thread_id,agent_id,title,created_at,updated_at,message_count) VALUES (?,?,?,?,?,0)\")\n .run(thread_id, agent_id, title ?? null, t, t);\n return { thread_id, agent_id, title: title ?? null, created_at: t, updated_at: t, message_count: 0 };\n}\n\nexport function deleteThread(thread_id: string): boolean {\n const db = getDb();\n db.prepare(\"DELETE FROM messages WHERE thread_id=?\").run(thread_id);\n const r = db.prepare(\"DELETE FROM threads WHERE thread_id=?\").run(thread_id);\n return r.changes > 0;\n}\n\nexport function getMessages(thread_id: string): MessageRow[] {\n return getDb()\n .prepare(MSG_COLS_SQL + \" WHERE thread_id=? ORDER BY created_at ASC\")\n .all(thread_id) as unknown as MessageRow[];\n}\n\n// Pull the latest N messages within a time window. Used to build the LLM\n// context — keeps prompt size bounded as threads grow indefinitely.\n// limit: 0 or negative = unlimited\n// sinceISO: undefined = no time bound\n// Returns chronological order (oldest first) so it can be appended to the prompt directly.\nexport function getRecentMessagesWindow(\n thread_id: string,\n limit: number,\n sinceISO?: string,\n): MessageRow[] {\n const db = getDb();\n const params: (string | number)[] = [thread_id];\n let sql = MSG_COLS_SQL + \" WHERE thread_id=?\";\n if (sinceISO) {\n sql += \" AND created_at >= ?\";\n params.push(sinceISO);\n }\n sql += \" ORDER BY created_at DESC\";\n if (limit > 0) {\n sql += \" LIMIT ?\";\n params.push(limit);\n }\n const rows = db.prepare(sql).all(...params) as unknown as MessageRow[];\n return rows.reverse();\n}\n\n// Forward-fetch — return messages strictly newer than `afterISO`, oldest\n// first, capped at `limit`. Used by the chat view to pull only the\n// freshly-persisted user+assistant pair after a run completes, instead of\n// re-fetching the whole most-recent page.\nexport function getMessagesAfter(\n thread_id: string,\n afterISO: string,\n limit = 50,\n): MessageRow[] {\n return getDb()\n .prepare(\n MSG_COLS_SQL +\n \" WHERE thread_id=? AND created_at > ? ORDER BY created_at ASC LIMIT ?\",\n )\n .all(thread_id, afterISO, limit) as unknown as MessageRow[];\n}\n\n// Pagination for the chat UI. Returns the latest N messages strictly older\n// than `beforeISO` (cursor). Caller passes the oldest already-loaded message's\n// created_at as the cursor; first page omits beforeISO.\nexport function getMessagesPage(\n thread_id: string,\n limit: number,\n beforeISO?: string,\n): { messages: MessageRow[]; has_more: boolean } {\n const db = getDb();\n const params: (string | number)[] = [thread_id];\n let sql = MSG_COLS_SQL + \" WHERE thread_id=?\";\n if (beforeISO) {\n sql += \" AND created_at < ?\";\n params.push(beforeISO);\n }\n sql += \" ORDER BY created_at DESC LIMIT ?\";\n params.push(limit + 1); // fetch one extra to detect if there's more\n const rows = db.prepare(sql).all(...params) as unknown as MessageRow[];\n const has_more = rows.length > limit;\n return { messages: rows.slice(0, limit).reverse(), has_more };\n}\n\nexport function addMessage(\n thread_id: string,\n role: \"user\" | \"assistant\",\n content: string,\n toolEvents?: PersistedToolEvent[] | null,\n category: string | null = null,\n): MessageRow {\n const msg_id = randomUUID();\n const t = now();\n const db = getDb();\n const toolEventsJson = toolEvents && toolEvents.length > 0 ? JSON.stringify(toolEvents) : null;\n db.prepare(\"INSERT INTO messages (msg_id,thread_id,role,content,created_at,tool_events,category) VALUES (?,?,?,?,?,?,?)\")\n .run(msg_id, thread_id, role, content, t, toolEventsJson, category);\n db.prepare(\"UPDATE threads SET message_count=message_count+1 WHERE thread_id=?\").run(thread_id);\n // Best-effort: embed the message so semantic recall can pull it back later.\n // Skip empty / very short content (greetings have no useful signal).\n if (content.trim().length >= 12) {\n embedOne(content).then((vec) => {\n if (vec) {\n getDb().prepare(\"UPDATE messages SET embedding=? WHERE msg_id=?\").run(JSON.stringify(vec), msg_id);\n }\n }).catch(() => { /* logged in embeddings module */ });\n }\n return { msg_id, thread_id, role, content, created_at: t, tool_events: toolEventsJson, category };\n}\n\nexport function getOrCreateAgentThread(agentId: string): ThreadRow {\n const existing = getDb()\n .prepare(\"SELECT * FROM threads WHERE agent_id=? LIMIT 1\")\n .get(agentId) as ThreadRow | undefined;\n if (existing) return existing;\n return createThread(agentId);\n}\n\nexport function clearThreadMessages(threadId: string): void {\n const db = getDb();\n db.prepare(\"DELETE FROM messages WHERE thread_id=?\").run(threadId);\n db.prepare(\"UPDATE threads SET message_count=0, updated_at=? WHERE thread_id=?\")\n .run(new Date().toISOString(), threadId);\n}\n\nexport function touchThread(thread_id: string, firstMsg?: string): void {\n const t = now();\n getDb()\n .prepare(\"UPDATE threads SET updated_at=?, title=COALESCE(title,?) WHERE thread_id=?\")\n .run(t, firstMsg ? firstMsg.slice(0, 80) : null, thread_id);\n}\n","import { getDb } from \"@/lib/db\";\n\nconst now = () => new Date().toISOString();\n\n// Persona presets (see ADR — to be written). Drives the Credentials\n// panel's category filter so the agent surface stays calm.\n//\n// home → llm + mail + calendar + chat\n// work → everything except chat-only (everyone uses work mail/cal/jira)\n// dev → everything (including infrastructure)\n// custom → no filter, show everything\n//\n// NULL in the DB also means \"no filter\".\nexport type UserPreset = \"home\" | \"work\" | \"dev\" | \"custom\";\n\nexport function isUserPreset(v: unknown): v is UserPreset {\n return v === \"home\" || v === \"work\" || v === \"dev\" || v === \"custom\";\n}\n\nexport interface UserProfileRow {\n id: string;\n name: string;\n icon: string | null;\n about: string;\n created_at: string;\n updated_at: string;\n // ── Geolocation (opt-in) ─────────────────────────────────────────────\n // Populated by the client (navigator.geolocation) only when\n // location_consent === 1. All five fields are null when sharing is off.\n location_lat: number | null;\n location_lng: number | null;\n location_accuracy_m: number | null;\n location_label: string | null;\n location_updated_at: string | null;\n location_consent: number; // 0 | 1\n // ── Persona ──────────────────────────────────────────────────────────\n preset: UserPreset | null;\n}\n\nexport function getUserProfile(): UserProfileRow | null {\n return (\n (getDb()\n .prepare(\"SELECT * FROM user_profile WHERE id='me'\")\n .get() as unknown as UserProfileRow) ?? null\n );\n}\n\nexport function upsertUserProfile(\n name: string,\n icon: string | null,\n about: string,\n): UserProfileRow {\n const t = now();\n const db = getDb();\n const existing = getUserProfile();\n const created_at = existing?.created_at ?? t;\n // Preserve location columns on profile edit — we only update them via the\n // dedicated location endpoints.\n db.prepare(\n `INSERT INTO user_profile (id, name, icon, about, created_at, updated_at)\n VALUES ('me', ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n name=excluded.name, icon=excluded.icon, about=excluded.about,\n updated_at=excluded.updated_at`,\n ).run(name, icon ?? null, about, created_at, t);\n return getUserProfile()!;\n}\n\nexport function setLocationConsent(consent: boolean): UserProfileRow {\n const t = now();\n const db = getDb();\n // Ensure a row exists.\n const existing = getUserProfile();\n if (!existing) upsertUserProfile(\"\", null, \"\");\n db.prepare(\n `UPDATE user_profile SET location_consent=?, updated_at=?\n ${consent ? \"\" : \", location_lat=NULL, location_lng=NULL, location_accuracy_m=NULL, location_label=NULL, location_updated_at=NULL\"}\n WHERE id='me'`,\n ).run(consent ? 1 : 0, t);\n return getUserProfile()!;\n}\n\nexport function updateUserLocation(input: {\n lat: number;\n lng: number;\n accuracy_m?: number | null;\n label?: string | null;\n}): UserProfileRow {\n const existing = getUserProfile();\n if (!existing || existing.location_consent !== 1) {\n throw new Error(\"location sharing is not enabled\");\n }\n const t = now();\n getDb()\n .prepare(\n `UPDATE user_profile SET\n location_lat=?, location_lng=?, location_accuracy_m=?, location_label=?,\n location_updated_at=?, updated_at=?\n WHERE id='me'`,\n )\n .run(\n input.lat,\n input.lng,\n input.accuracy_m ?? null,\n input.label ?? null,\n t,\n t,\n );\n return getUserProfile()!;\n}\n\nexport function setUserPreset(preset: UserPreset | null): UserProfileRow {\n const t = now();\n const db = getDb();\n // Ensure a row exists so the UPDATE has something to touch.\n if (!getUserProfile()) upsertUserProfile(\"\", null, \"\");\n db.prepare(\n `UPDATE user_profile SET preset=?, updated_at=? WHERE id='me'`,\n ).run(preset, t);\n return getUserProfile()!;\n}\n","// Scheduler loop. Owns the timer + the \"is a tick in flight?\" guard. The\n// actual firing logic lives in lib/triggers — this file only schedules\n// runTriggerTick() and exports a \"Run now\" helper that the existing\n// scheduled-tasks HTTP route uses.\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { indexAllSources } from \"@/lib/documents/indexer\";\nimport { runTriggerTick, runScheduledTaskFiringNow } from \"@/lib/triggers\";\nimport type { ScheduledTaskRow } from \"@/lib/stores/scheduled-tasks\";\n\n// Env-tunable so e2e tests can ride a tighter loop without waiting 30 s\n// per fs-watch firing. Production / dev use the 30 s default; tests\n// should set JARELA_SCHEDULER_TICK_MS=200 (or similar).\nconst POLL_INTERVAL_MS = (() => {\n const raw = process.env.JARELA_SCHEDULER_TICK_MS;\n if (!raw) return 30_000;\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) && n >= 50 ? n : 30_000;\n})();\n// Sweep document sources every Nth tick. 20 ticks × 30s = 10 min, which\n// matches typical \"I edited a file, ask Jarela about it\" patience. PR-D\n// upgrades this to event-driven fs watching.\nconst DOC_SWEEP_EVERY_TICKS = 20;\n\ninterface SchedulerState {\n started: boolean;\n timer: NodeJS.Timeout | null;\n running: boolean;\n tickCount: number;\n}\nconst state = getOrCreateGlobal<SchedulerState>(\"__jarela_scheduler\", () => ({\n started: false,\n timer: null,\n running: false,\n tickCount: 0,\n}));\n\n// Idempotent — call repeatedly; only the first call starts the loop.\nexport function startScheduler(): void {\n if (state.started) return;\n state.started = true;\n setImmediate(() => { void tick(); });\n state.timer = setInterval(() => { void tick(); }, POLL_INTERVAL_MS);\n if (typeof state.timer.unref === \"function\") state.timer.unref();\n}\n\nexport function stopScheduler(): void {\n if (state.timer) {\n clearInterval(state.timer);\n state.timer = null;\n }\n state.started = false;\n}\n\nasync function tick(): Promise<void> {\n if (state.running) return;\n state.running = true;\n try {\n await runTriggerTick();\n\n // Document-RAG reindex sweep (ADR-0024). Polled here until PR-D wires\n // an fs watcher. Failures are logged but never block the tick.\n state.tickCount = (state.tickCount + 1) % DOC_SWEEP_EVERY_TICKS;\n if (state.tickCount === 0) {\n try {\n await indexAllSources();\n } catch (err) {\n console.error(\n \"[scheduler] document index sweep failed:\",\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n } finally {\n state.running = false;\n }\n}\n\n/**\n * Public wrapper retained for the \"Run now\" UI button + HTTP route.\n * Internally delegates to the trigger runner so the manual path and the\n * tick path share the exact same code.\n */\nexport async function runScheduledTaskNow(task: ScheduledTaskRow): Promise<void> {\n await runScheduledTaskFiringNow(task.id);\n}\n","// Branding knobs sourced from NEXT_PUBLIC_* env vars so forks can rebrand\n// the app without patching source. NEXT_PUBLIC_* is the right\n// channel here because Next.js inlines these at build time, which lets\n// client components read them directly (no React Context, no server\n// round-trip). Server-only modules read the same keys at runtime.\n//\n// Keep this module client-safe — no Node-only imports, no DB/FS access.\n\nconst DEFAULT_APP_NAME = \"Jarela\";\nconst DEFAULT_APP_DESCRIPTION = \"Jarela — local chat interface for LangGraph agents\";\nconst DEFAULT_ISSUE_URL = \"https://github.com/CircuitWall/jarela/issues/new\";\n\nexport function getAppName(): string {\n return process.env.NEXT_PUBLIC_APP_NAME?.trim() || DEFAULT_APP_NAME;\n}\n\nexport function getAppDescription(): string {\n return process.env.NEXT_PUBLIC_APP_DESCRIPTION?.trim() || DEFAULT_APP_DESCRIPTION;\n}\n\nexport function getAppIssueUrl(): string {\n return process.env.NEXT_PUBLIC_APP_ISSUE_URL?.trim() || DEFAULT_ISSUE_URL;\n}\n","// Central runtime configuration, resolved from environment variables.\n//\n// All operational knobs (port, host, data dir, timeouts, agent limits) flow\n// through this module so there is exactly one place documenting which env\n// vars Jarela respects and what the defaults are. Code MUST NOT read these\n// `process.env` keys directly — import `config` instead.\n//\n// Resolution order for every entry: explicit JARELA_* var → legacy/standard\n// var (where one exists, e.g. PORT/HOSTNAME for Next.js compatibility) →\n// hard-coded default.\n//\n// Values are resolved lazily on first read and cached. Tests that mutate\n// `process.env` must call `resetConfigCache()` between cases.\n\nimport { getDataDir } from \"@/lib/db/data-dir\";\nimport { getAppName, getAppDescription, getAppIssueUrl } from \"./app-config\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface JarelaConfig {\n /** TCP port the Next.js server binds to. */\n readonly port: number;\n /** Hostname/interface the server binds to (loopback by default). */\n readonly hostname: string;\n /** Absolute path to the SQLite + files data directory. */\n readonly dataDir: string;\n /** Absolute path to the external-tools directory (CJS/TS plugins). */\n readonly toolsDir: string;\n /** Max LangGraph node visits per agent run before erroring out. */\n readonly recursionLimit: number;\n /** Per-request timeout for Gemini voice (TTS/STT) calls, ms. */\n readonly voiceTimeoutMs: number;\n /** Per-request timeout for Gemini image-generation calls, ms. */\n readonly imageTimeoutMs: number;\n /** User-visible app name. Forks override via NEXT_PUBLIC_APP_NAME. */\n readonly appName: string;\n /** Meta description for the HTML <head>. NEXT_PUBLIC_APP_DESCRIPTION. */\n readonly appDescription: string;\n /** \"Report a bug\" target — GitHub issues URL. NEXT_PUBLIC_APP_ISSUE_URL. */\n readonly issueUrl: string;\n}\n\nconst DEFAULTS = {\n port: 4312,\n hostname: \"127.0.0.1\",\n recursionLimit: 200,\n voiceTimeoutMs: 60_000,\n imageTimeoutMs: 60_000,\n} as const;\n\nfunction parsePositiveInt(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;\n}\n\nfunction parsePort(value: string | undefined, fallback: number): number {\n const n = parsePositiveInt(value, fallback);\n return n >= 1 && n <= 65_535 ? n : fallback;\n}\n\nlet cached: JarelaConfig | null = null;\n\nfunction expandHome(p: string): string {\n return p.startsWith(\"~\") ? p.replace(/^~/, homedir()) : p;\n}\n\nexport function getConfig(): JarelaConfig {\n if (cached) return cached;\n const env = process.env;\n const dataDir = getDataDir();\n cached = {\n port: parsePort(env.JARELA_PORT ?? env.PORT, DEFAULTS.port),\n hostname: (env.JARELA_HOSTNAME ?? env.HOSTNAME ?? DEFAULTS.hostname).trim() || DEFAULTS.hostname,\n dataDir,\n toolsDir: env.JARELA_TOOLS_DIR ? expandHome(env.JARELA_TOOLS_DIR) : join(dataDir, \"tools\"),\n recursionLimit: parsePositiveInt(env.JARELA_RECURSION_LIMIT, DEFAULTS.recursionLimit),\n voiceTimeoutMs: parsePositiveInt(env.JARELA_VOICE_TIMEOUT_MS, DEFAULTS.voiceTimeoutMs),\n imageTimeoutMs: parsePositiveInt(env.JARELA_IMAGE_TIMEOUT_MS, DEFAULTS.imageTimeoutMs),\n appName: getAppName(),\n appDescription: getAppDescription(),\n issueUrl: getAppIssueUrl(),\n };\n return cached;\n}\n\n/** Test-only: drop the memoised config so the next read picks up env edits. */\nexport function resetConfigCache(): void {\n cached = null;\n}\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getMemory, putMemory, listMemory } from \"@/lib/stores/memory\";\nimport { registerTools } from \"./registry\";\n\nexport const memoryReadTool = tool(\n async ({ namespace, key }) => {\n const row = getMemory(namespace, key);\n if (!row) return JSON.stringify(null);\n return row.value; // already stored as a JSON string\n },\n {\n name: \"memory_read\",\n description: \"Read a value from long-term memory by namespace and key. Returns null if not found.\",\n schema: z.object({\n namespace: z.string().describe(\"Memory namespace (e.g. 'user', 'facts', 'tasks')\"),\n key: z.string().describe(\"Key within the namespace\"),\n }),\n },\n);\n\nexport const memoryWriteTool = tool(\n async ({ namespace, key, value }) => {\n putMemory(namespace, key, value);\n return JSON.stringify({ ok: true, namespace, key });\n },\n {\n name: \"memory_write\",\n description:\n \"Write or update a value in long-term memory. Use this to remember facts, user preferences, or any information that should persist across conversations.\",\n schema: z.object({\n namespace: z.string().describe(\"Memory namespace (e.g. 'user', 'facts', 'tasks')\"),\n key: z.string().describe(\"Key within the namespace\"),\n value: z.string().describe(\"Value to store (serialize objects to JSON before passing)\"),\n }),\n },\n);\n\nexport const memoryListTool = tool(\n async ({ namespace, search, limit }) => {\n const rows = listMemory(namespace, search, limit ?? 20);\n const result = rows.map((r) => ({\n namespace: r.namespace,\n key: r.key,\n value: (() => {\n try {\n return JSON.parse(r.value);\n } catch {\n return r.value;\n }\n })(),\n updated_at: r.updated_at,\n }));\n return JSON.stringify(result);\n },\n {\n name: \"memory_list\",\n description: \"List memory entries, optionally filtered by namespace or search term.\",\n schema: z.object({\n namespace: z.string().optional().describe(\"Filter by namespace (optional)\"),\n search: z.string().optional().describe(\"Search term to filter keys/values (optional)\"),\n limit: z.number().optional().describe(\"Max results (default 20)\"),\n }),\n },\n);\n\nregisterTools(\"Memory\", [memoryReadTool, memoryWriteTool, memoryListTool]);\n","// Semantic search over document_chunks (ADR-0024). Cosine over embedded\n// chunks; substring fallback for chunks without embeddings (covers the\n// \"no embedding provider configured\" case and the brief window before\n// async embed completes after indexing).\n\nimport { getDb } from \"@/lib/db\";\nimport { embedOne, cosine } from \"@/lib/embeddings\";\n\nexport interface DocumentHit {\n document_id: string;\n source_id: string;\n source_label: string | null;\n rel_path: string;\n abs_path: string;\n chunk_index: number;\n text: string;\n score: number;\n match: \"semantic\" | \"substring\";\n}\n\ninterface Row {\n chunk_id: string;\n document_id: string;\n chunk_index: number;\n text: string;\n embedding: string | null;\n source_id: string;\n source_label: string | null;\n rel_path: string;\n abs_path: string;\n}\n\nexport async function searchDocuments(\n query: string,\n opts?: { limit?: number; sourceId?: string },\n): Promise<DocumentHit[]> {\n const limit = Math.min(Math.max(opts?.limit ?? 8, 1), 25);\n const db = getDb();\n const trimmed = query.trim();\n if (trimmed.length === 0) return [];\n\n // Hard cap on rows scanned per query — at thousands of chunks the JS\n // cosine pass is still milliseconds, but we still want a ceiling.\n const limitRows = 20_000;\n const rows = (\n opts?.sourceId\n ? db.prepare(\n `SELECT dc.id AS chunk_id, dc.document_id, dc.chunk_index, dc.text, dc.embedding,\n d.source_id, ds.label AS source_label, d.rel_path, d.path AS abs_path\n FROM document_chunks dc\n JOIN documents d ON dc.document_id = d.id\n JOIN document_sources ds ON d.source_id = ds.id\n WHERE d.source_id = ? AND ds.enabled = 1\n LIMIT ?`,\n ).all(opts.sourceId, limitRows)\n : db.prepare(\n `SELECT dc.id AS chunk_id, dc.document_id, dc.chunk_index, dc.text, dc.embedding,\n d.source_id, ds.label AS source_label, d.rel_path, d.path AS abs_path\n FROM document_chunks dc\n JOIN documents d ON dc.document_id = d.id\n JOIN document_sources ds ON d.source_id = ds.id\n WHERE ds.enabled = 1\n LIMIT ?`,\n ).all(limitRows)\n ) as unknown as Row[];\n\n if (rows.length === 0) return [];\n\n const qVec = await embedOne(trimmed);\n const scored: DocumentHit[] = [];\n const lowered = trimmed.toLowerCase();\n\n for (const r of rows) {\n let score = 0;\n let match: \"semantic\" | \"substring\" = \"semantic\";\n if (qVec && r.embedding) {\n let vec: number[] | null = null;\n try { vec = JSON.parse(r.embedding) as number[]; } catch { vec = null; }\n if (vec) score = cosine(qVec, vec);\n else { score = substringScore(r.text, lowered); match = \"substring\"; }\n } else {\n score = substringScore(r.text, lowered);\n match = \"substring\";\n }\n if (score <= 0) continue;\n scored.push({\n document_id: r.document_id,\n source_id: r.source_id,\n source_label: r.source_label,\n rel_path: r.rel_path,\n abs_path: r.abs_path,\n chunk_index: r.chunk_index,\n text: r.text,\n score,\n match,\n });\n }\n\n scored.sort((a, b) => b.score - a.score);\n return scored.slice(0, limit);\n}\n\nfunction substringScore(haystack: string, needleLower: string): number {\n const hay = haystack.toLowerCase();\n if (!hay.includes(needleLower)) {\n // Try token-level OR match — at least one query token has to appear.\n const tokens = needleLower.split(/\\s+/).filter((t) => t.length > 2);\n let hits = 0;\n for (const t of tokens) if (hay.includes(t)) hits++;\n if (hits === 0) return 0;\n return Math.min(0.4, hits / Math.max(tokens.length, 1) * 0.4);\n }\n // Phrase match — high but below typical semantic top scores.\n return 0.6;\n}\n","// documents_search — semantic recall over folders the user indexed under\n// Documents (ADR-0024). Cosine over embedded chunks; substring fallback\n// when no embedding provider is configured or chunks haven't been\n// embedded yet.\n\nimport { tool } from \"@langchain/core/tools\";\nimport path from \"node:path\";\nimport { promises as fs } from \"node:fs\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport { searchDocuments } from \"@/lib/documents/search\";\nimport {\n createDocumentSource,\n deleteDocumentSource,\n getDocumentSource,\n getDocumentSourceByPath,\n listDocumentSources,\n type DocumentSourceKind,\n} from \"@/lib/stores/document-sources\";\nimport { indexOnDemand, runRemoteSource } from \"@/lib/documents/remote\";\nimport { notifyTriggerHandlers } from \"@/lib/triggers\";\n\nexport const documentsSearch = tool(\n async ({ query, limit, source_id }) => {\n const hits = await searchDocuments(query, { limit, sourceId: source_id });\n return JSON.stringify({\n query,\n hits: hits.map((h) => ({\n source: h.source_label ?? h.source_id,\n path: h.rel_path,\n chunk_index: h.chunk_index,\n score: Number(h.score.toFixed(4)),\n match: h.match,\n text: h.text,\n })),\n });\n },\n {\n name: \"documents_search\",\n description:\n \"Search indexed local documents (notes, READMEs, code, configs) by semantic similarity. \" +\n \"Use when the user references files in folders they've added under Documents, or when \" +\n \"you need facts from project-specific text the model wouldn't otherwise know. Returns \" +\n \"the top matching text chunks with their source path.\",\n schema: z.object({\n query: z.string().describe(\"Natural-language question or keywords to look up.\"),\n limit: z.number().int().min(1).max(25).optional()\n .describe(\"Max results to return (default 8).\"),\n source_id: z.string().optional()\n .describe(\"Restrict the search to a single document_source id. Omit to search all.\"),\n }),\n },\n);\n\nexport const documentsListSources = tool(\n async () => {\n const rows = listDocumentSources();\n return JSON.stringify({\n sources: rows.map((r) => ({\n id: r.id,\n path: r.path,\n label: r.label,\n enabled: r.enabled === 1,\n last_scan_at: r.last_scan_at,\n })),\n });\n },\n {\n name: \"documents_list_sources\",\n description:\n \"List the folders Jarela is indexing for document search. Useful before calling \" +\n \"documents_search with a source_id filter.\",\n schema: z.object({}),\n },\n);\n\nexport const documentsAddLocalSource = tool(\n async ({ path: inputPath, label }) => {\n const abs = path.resolve(inputPath);\n try {\n const st = await fs.stat(abs);\n if (!st.isDirectory()) {\n return JSON.stringify({ error: \"path is not a directory\" });\n }\n } catch {\n return JSON.stringify({ error: \"path does not exist or is unreadable\" });\n }\n if (getDocumentSourceByPath(abs)) {\n return JSON.stringify({ error: \"source already exists for this path\" });\n }\n try {\n const row = createDocumentSource({ path: abs, label: label ?? null, kind: \"local_folder\" });\n await notifyTriggerHandlers(\"source_changed\");\n return JSON.stringify({\n ok: true,\n id: row.id,\n kind: row.kind,\n path: row.path,\n label: row.label,\n note: \"Local folders auto-reindex on file changes (fs-watch on macOS/Windows; periodic sweep fallback on Linux).\",\n });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_add_local_source\",\n description:\n \"Add a local folder as a Documents source so its files become searchable via documents_search. \" +\n \"Pass any relative or absolute path; the tool resolves it to an absolute directory and validates it.\",\n schema: z.object({\n path: z.string().min(1).describe(\"Local folder path to index (relative or absolute).\"),\n label: z.string().optional().describe(\"Optional source label shown in the Documents panel.\"),\n }),\n },\n);\n\nregisterTools(\"Documents\", [documentsSearch, documentsListSources, documentsAddLocalSource]);\n\n// ── Remote document sources (ADR-0026) ──────────────────────────────────────\n//\n// These tools let agents add Jira projects, JQL queries, Confluence spaces,\n// and CQL queries as document sources, so a single retrieval surface\n// (`documents_search`) covers both local files and Atlassian content.\n\nconst REMOTE_KINDS = [\n \"confluence_space\",\n \"confluence_cql\",\n \"jira_project\",\n \"jira_jql\",\n \"github_pulls\",\n \"github_repo\",\n] as const;\n\nfunction syntheticPath(kind: DocumentSourceKind, config: Record<string, unknown>): string {\n switch (kind) {\n case \"confluence_space\": return `confluence-space://${String(config.space_key ?? \"\").trim()}`;\n case \"confluence_cql\": return `confluence-cql://${Buffer.from(String(config.cql ?? \"\")).toString(\"base64\").slice(0, 32)}`;\n case \"jira_project\": return `jira-project://${String(config.project_key ?? \"\").trim()}`;\n case \"jira_jql\": return `jira-jql://${Buffer.from(String(config.jql ?? \"\")).toString(\"base64\").slice(0, 32)}`;\n case \"github_pulls\": return `github-pulls://${String(config.owner ?? \"\").trim()}/${String(config.repo ?? \"\").trim()}`;\n case \"github_repo\": return `github-repo://${String(config.owner ?? \"\").trim()}/${String(config.repo ?? \"\").trim()}`;\n default: return `remote://${kind}/${Date.now()}`;\n }\n}\n\nfunction validateRemoteConfig(kind: typeof REMOTE_KINDS[number], cfg: Record<string, unknown>): string | null {\n if (kind === \"confluence_space\" && !cfg.space_key) return \"config.space_key is required for confluence_space\";\n if (kind === \"confluence_cql\" && !cfg.cql) return \"config.cql is required for confluence_cql\";\n if (kind === \"jira_project\" && !cfg.project_key) return \"config.project_key is required for jira_project\";\n if (kind === \"jira_jql\" && !cfg.jql) return \"config.jql is required for jira_jql\";\n if (kind === \"github_pulls\" && (!cfg.owner || !cfg.repo)) return \"config.owner and config.repo are required for github_pulls\";\n if (kind === \"github_repo\" && (!cfg.owner || !cfg.repo)) return \"config.owner and config.repo are required for github_repo\";\n return null;\n}\n\nexport const documentsAddRemoteSource = tool(\n async ({ kind, label, config }) => {\n const err = validateRemoteConfig(kind, config);\n if (err) return JSON.stringify({ error: err });\n const path = syntheticPath(kind, config);\n try {\n const row = createDocumentSource({ path, label, kind, config });\n return JSON.stringify({\n ok: true,\n id: row.id,\n kind: row.kind,\n label: row.label,\n note: \"Remote sources index on the scheduler sweep (~10 min). Call documents_reindex_source with this id to force an immediate sync. Local folders auto-reindex on file changes.\",\n });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_add_remote_source\",\n description:\n \"Add a Jira project / JQL query / Confluence space / CQL query / GitHub repo as a document source. \" +\n \"Indexed content becomes searchable via documents_search alongside local folders. \" +\n \"Examples: kind='confluence_space' config={space_key:'ENG'}; kind='jira_project' \" +\n \"config={project_key:'ABC', recency_days:90}; kind='jira_jql' config={jql:'project = ABC AND status != Done'}; \" +\n \"kind='github_pulls' config={owner:'octocat', repo:'hello-world', state:'all', recency_days:60}; \" +\n \"kind='github_repo' config={owner:'octocat', repo:'hello-world', ref:'main', path_prefix:'docs'}.\",\n schema: z.object({\n kind: z.enum(REMOTE_KINDS),\n label: z.string().describe(\"Human-readable label shown in the Documents panel.\"),\n config: z.record(z.string(), z.unknown())\n .describe(\"Per-kind config. confluence_space: {space_key}. confluence_cql: {cql}. \" +\n \"jira_project: {project_key}. jira_jql: {jql}. \" +\n \"github_pulls: {owner, repo, state?, recency_days?}. \" +\n \"github_repo: {owner, repo, ref?, path_prefix?}. Optional everywhere: recency_days (int).\"),\n }),\n },\n);\n\nexport const documentsRemoveSource = tool(\n async ({ source_id, confirm }) => {\n if (confirm !== source_id) {\n return JSON.stringify({ error: \"pass confirm equal to source_id to actually delete\" });\n }\n const row = getDocumentSource(source_id);\n if (!row) return JSON.stringify({ error: \"source not found\" });\n const ok = deleteDocumentSource(source_id);\n return JSON.stringify({ ok, id: source_id, label: row.label });\n },\n {\n name: \"documents_remove_source\",\n description:\n \"Delete a document source and all its indexed chunks. Destructive — requires `confirm` to equal `source_id`.\",\n schema: z.object({\n source_id: z.string(),\n confirm: z.string().describe(\"Must equal source_id to proceed.\"),\n }),\n },\n);\n\nexport const documentsReindexSource = tool(\n async ({ source_id }) => {\n const row = getDocumentSource(source_id);\n if (!row) return JSON.stringify({ error: \"source not found\" });\n if (row.kind === \"local_folder\") {\n return JSON.stringify({\n error: \"documents_reindex_source is only for remote sources (Jira/Confluence). \" +\n \"Local folders auto-reindex on file changes (fs-watch on macOS/Windows; periodic sweep fallback on Linux).\",\n });\n }\n try {\n const stats = await runRemoteSource(row);\n return JSON.stringify({ ok: true, id: source_id, stats });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_reindex_source\",\n description:\n \"Force an immediate incremental sync of a remote document source. Returns counts of added / updated / unchanged docs.\",\n schema: z.object({ source_id: z.string() }),\n },\n);\n\nexport const documentsIndexUrl = tool(\n async ({ input }) => {\n try {\n const res = await indexOnDemand(input);\n return JSON.stringify({ ok: true, ...res });\n } catch (e) {\n return JSON.stringify({ error: e instanceof Error ? e.message : String(e) });\n }\n },\n {\n name: \"documents_index_url\",\n description:\n \"Fetch and index a single Jira issue, Confluence page, or GitHub PR/issue/file on demand, \" +\n \"stored under a shared 'On-demand URLs' source. Accepts a bare Jira key (ABC-123), a \" +\n \"/browse/<KEY> URL, a Confluence /wiki/spaces/.../pages/<id> URL, or a GitHub /pull/<n>, \" +\n \"/issues/<n>, or /blob/<ref>/<path> URL.\",\n schema: z.object({\n input: z.string().describe(\"Jira key, Jira URL, Confluence page URL, or GitHub PR/issue/blob URL\"),\n }),\n },\n);\n\nregisterTools(\"Documents\", [\n documentsAddRemoteSource,\n documentsRemoveSource,\n documentsReindexSource,\n documentsIndexUrl,\n]);\n","import { execSync } from \"node:child_process\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport { getInjectedSubprocessEnv } from \"@/lib/env/allowlist\";\n\nconst MAX_OUTPUT_BYTES = 8_000;\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_TIMEOUT_MS = 60_000;\n\nconst BLOCKED_PATTERNS = [\n /\\brm\\s+-rf\\s+\\/\\b/i,\n /\\bshutdown\\b/i,\n /\\breboot\\b/i,\n /\\bmkfs\\b/i,\n /:\\s*\\(\\)\\s*\\{\\s*:\\s*\\|\\s*:\\s*&\\s*\\}\\s*;/,\n];\n\nfunction isBlockedCommand(command: string): boolean {\n return BLOCKED_PATTERNS.some((pattern) => pattern.test(command));\n}\n\nfunction clipOutput(text: string, max = MAX_OUTPUT_BYTES): { value: string; truncated: boolean } {\n if (text.length <= max) return { value: text, truncated: false };\n return { value: `${text.slice(0, max)}\\n[output truncated]`, truncated: true };\n}\n\nfunction runLocalCommand(\n command: string,\n options: {\n cwd?: string;\n env?: Record<string, string>;\n timeout_ms?: number;\n allow_unsafe?: boolean;\n },\n): string {\n if (!command.trim()) {\n return JSON.stringify({ exit_code: 1, stderr: \"command is required\" });\n }\n\n const timeout = Math.min(options.timeout_ms ?? DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);\n\n if (!options.allow_unsafe && isBlockedCommand(command)) {\n return JSON.stringify({\n exit_code: 126,\n stderr: \"Command blocked by safety policy. Pass allow_unsafe=true only when you fully trust the command.\",\n });\n }\n\n const cwd = options.cwd?.trim() ? options.cwd : process.cwd();\n // Layered env. Later spreads win:\n // 1. process.env — PATH, HOME, locale, the shell's exports\n // 2. integration-store credentials — so a service install (launchd,\n // systemd) where ANTHROPIC_API_KEY etc. were never exported in the\n // service's environment still hands those values to subprocesses.\n // The encrypted store, populated by env-sync from the user's rc\n // or via the Integrations panel, is the canonical source.\n // 3. options.env — explicit per-call override always wins.\n const env = { ...process.env, ...getInjectedSubprocessEnv(), ...options.env };\n\n try {\n const output = execSync(command, {\n cwd,\n env,\n timeout,\n encoding: \"utf8\",\n maxBuffer: MAX_OUTPUT_BYTES * 2,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n const clipped = clipOutput(output);\n return JSON.stringify({ exit_code: 0, stdout: clipped.value, truncated: clipped.truncated, cwd });\n } catch (err: unknown) {\n const e = err as { stdout?: string; stderr?: string; status?: number; message?: string };\n const out = clipOutput(String(e.stdout ?? \"\"));\n const errText = clipOutput(String(e.stderr ?? e.message ?? \"\"), 2_000);\n return JSON.stringify({\n exit_code: e.status ?? 1,\n stdout: out.value,\n stderr: errText.value,\n truncated: out.truncated || errText.truncated,\n cwd,\n });\n }\n}\n\nconst execSchema = z.object({\n command: z.string().describe(\"Shell command to execute\"),\n cwd: z.string().optional().describe(\"Working directory for command execution (defaults to process cwd)\"),\n env: z.record(z.string(), z.string()).optional().describe(\"Environment variables to inject for this command\"),\n timeout_ms: z.number().optional().describe(\"Timeout in milliseconds (default 10000, max 60000)\"),\n allow_unsafe: z.boolean().optional().describe(\"Set true to bypass safety blocking for risky commands\"),\n});\n\nexport const localExecTool = tool(\n async ({ command, cwd, env, timeout_ms, allow_unsafe }) =>\n runLocalCommand(command, { cwd, env, timeout_ms, allow_unsafe }),\n {\n name: \"local_exec\",\n description: \"Run local shell commands with optional cwd/env overrides. Output is truncated to 8 KB.\",\n schema: execSchema,\n },\n);\n\nexport const shellExecTool = tool(\n async ({ command, cwd, env, timeout_ms, allow_unsafe }) =>\n runLocalCommand(command, { cwd, env, timeout_ms, allow_unsafe }),\n {\n name: \"shell_exec\",\n description: \"Backward-compatible alias for local_exec.\",\n schema: execSchema,\n },\n);\n\nregisterTools(\"Shell\", [localExecTool, shellExecTool]);\n","import { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\n\n// Dedicated file tools. Agents previously had to drive every edit through\n// `local_exec` / `shell_exec`, which works for \"create a new file with this\n// content\" (echo / Set-Content) but is hostile to in-place edits: quoting\n// rules differ per shell, multi-line strings break under cmd.exe, and a\n// read-modify-write cycle needs two shell calls plus careful diff-by-hand.\n// These tools give agents a first-class file write + targeted edit surface.\n\nconst MAX_READ_BYTES = 64_000;\nconst MAX_WRITE_BYTES = 2_000_000;\n// Hard cap on the JSON payload returned by file_list. Stops a misconfigured\n// recursive listing of a giant tree from blowing the LLM's prompt budget\n// (one user hit 361K tokens / 64K limit from a single call).\nconst MAX_LIST_JSON_BYTES = 24_000;\n\nfunction clip(text: string, max: number): { value: string; truncated: boolean } {\n if (text.length <= max) return { value: text, truncated: false };\n return { value: text.slice(0, max), truncated: true };\n}\n\n// Resolve agent-supplied paths against the USER'S HOME directory, not\n// process.cwd(). In production cwd is the Jarela install dir\n// (%LOCALAPPDATA%\\Programs\\Jarela) — if the agent writes \"notes.txt\"\n// expecting it to land somewhere visible, it lands buried in the install\n// tree and the user concludes the tool didn't run. Home is the natural\n// default for an \"assistant on my computer\". Absolute paths and ~/ paths\n// are honored verbatim.\nfunction resolvePath(p: string): string {\n if (!p.trim()) throw new Error(\"path is required\");\n let s = p.trim();\n if (s === \"~\") return os.homedir();\n if (s.startsWith(\"~/\") || s.startsWith(\"~\\\\\")) {\n s = path.join(os.homedir(), s.slice(2));\n return path.resolve(s);\n }\n if (path.isAbsolute(s)) return path.resolve(s);\n return path.resolve(os.homedir(), s);\n}\n\n// Filesystem denylist for agent-driven file tools. The LLM has free\n// rein over the user's HOME by design — but a handful of subtrees hold\n// credentials whose disclosure or mutation is far more dangerous than\n// any chat use case justifies: SSH private keys, GPG secret rings,\n// cached cloud-provider tokens, the gh CLI auth blob, kubeconfig, the\n// docker daemon config. We also forbid writes to ~/.jarela so a\n// prompt-injected page can't rewrite the app's own SQLite state.\n//\n// Operators with an explicit need (e.g. asking the agent to fix an\n// authorized_keys file) can opt back in with\n// JARELA_ALLOW_SENSITIVE_FILES=1.\nfunction isInside(abs: string, parent: string): boolean {\n const a = path.resolve(abs);\n const p = path.resolve(parent);\n if (a === p) return true;\n const rel = path.relative(p, a);\n return !!rel && !rel.startsWith(\"..\") && !path.isAbsolute(rel);\n}\n\nfunction sensitiveBase(): string[] {\n const home = os.homedir();\n return [\n path.join(home, \".ssh\"),\n path.join(home, \".gnupg\"),\n path.join(home, \".aws\"),\n path.join(home, \".config\", \"gh\"),\n path.join(home, \".kube\"),\n path.join(home, \".docker\"),\n ];\n}\n\nfunction sensitiveFiles(): string[] {\n const home = os.homedir();\n return [\n path.join(home, \".netrc\"),\n path.join(home, \"_netrc\"), // Windows convention\n path.join(home, \".pgpass\"),\n ];\n}\n\nfunction jarelaDataDir(): string {\n return process.env.JARELA_DB_DIR\n ? path.resolve(process.env.JARELA_DB_DIR)\n : path.join(os.homedir(), \".jarela\");\n}\n\nfunction assertSafePath(abs: string, op: \"read\" | \"write\"): void {\n if (process.env.JARELA_ALLOW_SENSITIVE_FILES === \"1\") return;\n for (const base of sensitiveBase()) {\n if (isInside(abs, base)) {\n throw new Error(\n `refused: '${abs}' is inside a credential directory (${path.basename(base)}). ` +\n `Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n );\n }\n }\n for (const f of sensitiveFiles()) {\n if (path.resolve(abs) === path.resolve(f)) {\n throw new Error(\n `refused: '${abs}' is a credential file. Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n );\n }\n }\n // Filename-based defense: catch private-key files anywhere on disk.\n const base = path.basename(abs).toLowerCase();\n if (\n base === \"id_rsa\" ||\n base === \"id_ed25519\" ||\n base === \"id_ecdsa\" ||\n base === \"id_dsa\" ||\n base.endsWith(\".pem\") ||\n base.endsWith(\".key\") ||\n base === \"credentials\"\n ) {\n throw new Error(\n `refused: '${abs}' looks like a credential file. Set JARELA_ALLOW_SENSITIVE_FILES=1 to override.`,\n );\n }\n if (op === \"write\" && isInside(abs, jarelaDataDir())) {\n throw new Error(\n `refused: '${abs}' is inside Jarela's data dir; the agent must not mutate app state directly.`,\n );\n }\n}\n\n// --- read ---------------------------------------------------------------\n\nconst readSchema = z.object({\n path: z.string().describe(\"File path. Absolute (C:\\\\... or /...) or ~/foo recommended; bare relative paths resolve against the user's HOME directory.\"),\n start_line: z.number().int().min(1).optional().describe(\"1-based first line to include\"),\n end_line: z.number().int().min(1).optional().describe(\"1-based last line to include (inclusive)\"),\n});\n\nexport const fileReadTool = tool(\n async ({ path: filePath, start_line, end_line }) => {\n let abs = filePath;\n try {\n abs = resolvePath(filePath);\n assertSafePath(abs, \"read\");\n const raw = await fs.readFile(abs, \"utf8\");\n let content = raw;\n let lineRange: { start: number; end: number } | null = null;\n if (start_line || end_line) {\n const lines = raw.split(/\\r?\\n/);\n const s = Math.max(1, start_line ?? 1);\n const e = Math.min(lines.length, end_line ?? lines.length);\n content = lines.slice(s - 1, e).join(\"\\n\");\n lineRange = { start: s, end: e };\n }\n const clipped = clip(content, MAX_READ_BYTES);\n return JSON.stringify({\n ok: true,\n path: abs,\n content: clipped.value,\n truncated: clipped.truncated,\n line_range: lineRange,\n total_lines: raw.split(/\\r?\\n/).length,\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_read\",\n description:\n \"Read a UTF-8 text file. Optional 1-based start_line/end_line slice. Output clipped at 64 KB — for large files always pass a line range and walk in chunks.\",\n schema: readSchema,\n },\n);\n\n// --- write --------------------------------------------------------------\n\nconst writeSchema = z.object({\n path: z.string().describe(\"File path. Absolute (C:\\\\... or /...) or ~/foo recommended; bare relative paths resolve against the user's HOME directory.\"),\n content: z.string().describe(\"Full file content. Overwrites the file if it exists.\"),\n create_dirs: z\n .boolean()\n .optional()\n .describe(\"Create missing parent directories (default true)\"),\n});\n\nexport const fileWriteTool = tool(\n async ({ path: filePath, content, create_dirs }) => {\n let abs = filePath;\n try {\n abs = resolvePath(filePath);\n if (content.length > MAX_WRITE_BYTES) {\n return JSON.stringify({ ok: false, path: abs, error: `content exceeds ${MAX_WRITE_BYTES} bytes` });\n }\n assertSafePath(abs, \"write\");\n if (create_dirs !== false) {\n await fs.mkdir(path.dirname(abs), { recursive: true });\n }\n let existed = true;\n try {\n await fs.access(abs);\n } catch {\n existed = false;\n }\n await fs.writeFile(abs, content, \"utf8\");\n return JSON.stringify({\n ok: true,\n path: abs,\n bytes_written: Buffer.byteLength(content, \"utf8\"),\n created: !existed,\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_write\",\n description:\n \"Create or fully overwrite a UTF-8 text file. Parent directories are created by default. Use file_edit for targeted in-place changes.\",\n schema: writeSchema,\n },\n);\n\n// --- edit ---------------------------------------------------------------\n\nconst editSchema = z.object({\n path: z.string().describe(\"File path. Absolute (C:\\\\... or /...) or ~/foo recommended; bare relative paths resolve against the user's HOME directory.\"),\n old_string: z\n .string()\n .min(1)\n .describe(\n \"Exact literal substring to replace. Must appear EXACTLY ONCE in the file (include surrounding context to disambiguate).\",\n ),\n new_string: z.string().describe(\"Replacement text. May be empty to delete.\"),\n});\n\nexport const fileEditTool = tool(\n async ({ path: filePath, old_string, new_string }) => {\n let abs = filePath;\n try {\n abs = resolvePath(filePath);\n assertSafePath(abs, \"write\");\n const raw = await fs.readFile(abs, \"utf8\");\n const first = raw.indexOf(old_string);\n if (first === -1) {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"old_string not found. Re-read the file and try with the exact current content.\",\n });\n }\n const second = raw.indexOf(old_string, first + old_string.length);\n if (second !== -1) {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"old_string matches multiple times. Add surrounding context to make it unique.\",\n match_count: raw.split(old_string).length - 1,\n });\n }\n const next = raw.slice(0, first) + new_string + raw.slice(first + old_string.length);\n await fs.writeFile(abs, next, \"utf8\");\n return JSON.stringify({\n ok: true,\n path: abs,\n bytes_before: Buffer.byteLength(raw, \"utf8\"),\n bytes_after: Buffer.byteLength(next, \"utf8\"),\n });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_edit\",\n description:\n \"Replace a single exact-match substring inside a file. The old_string must appear exactly once — include enough surrounding context to disambiguate. Use this for in-place edits instead of shell heredocs.\",\n schema: editSchema,\n },\n);\n\n// --- move / rename ------------------------------------------------------\n\nconst moveSchema = z.object({\n source: z.string().describe(\"Existing file or directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n destination: z.string().describe(\"New path (absolute or ~/foo; bare relative resolves against HOME). If it ends with a separator or is an existing directory, source is moved into it preserving its basename.\"),\n overwrite: z\n .boolean()\n .optional()\n .describe(\"Allow replacing an existing destination file (default false). Existing directories are never overwritten.\"),\n create_dirs: z\n .boolean()\n .optional()\n .describe(\"Create missing parent directories of the destination (default true).\"),\n});\n\nexport const fileMoveTool = tool(\n async ({ source, destination, overwrite, create_dirs }) => {\n let srcAbs = source;\n let dstAbs = destination;\n try {\n srcAbs = resolvePath(source);\n dstAbs = resolvePath(destination);\n assertSafePath(srcAbs, \"write\");\n assertSafePath(dstAbs, \"write\");\n const srcStat = await fs.stat(srcAbs);\n // If destination is an existing directory, move source INTO it\n // preserving its basename — matches `mv src dir/` semantics.\n let dstStat: import(\"node:fs\").Stats | null = null;\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n // dst missing — fine\n }\n if (dstStat?.isDirectory()) {\n dstAbs = path.join(dstAbs, path.basename(srcAbs));\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n dstStat = null;\n }\n }\n if (dstStat) {\n if (dstStat.isDirectory()) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n destination: dstAbs,\n error: \"destination is an existing directory; refusing to overwrite\",\n });\n }\n if (!overwrite) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n destination: dstAbs,\n error: \"destination exists. Pass overwrite=true to replace it.\",\n });\n }\n }\n if (create_dirs !== false) {\n await fs.mkdir(path.dirname(dstAbs), { recursive: true });\n }\n await fs.rename(srcAbs, dstAbs);\n return JSON.stringify({\n ok: true,\n source: srcAbs,\n destination: dstAbs,\n kind: srcStat.isDirectory() ? \"directory\" : \"file\",\n });\n } catch (err) {\n // Cross-device rename fails with EXDEV on Linux/macOS. Fall back to\n // copy+unlink so the agent doesn't need to know about device boundaries.\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"EXDEV\") {\n try {\n await fs.cp(srcAbs, dstAbs, { recursive: true, force: overwrite === true, errorOnExist: !overwrite });\n await fs.rm(srcAbs, { recursive: true, force: true });\n return JSON.stringify({ ok: true, source: srcAbs, destination: dstAbs, cross_device: true });\n } catch (err2) {\n return JSON.stringify({ ok: false, source: srcAbs, destination: dstAbs, error: (err2 as Error).message });\n }\n }\n return JSON.stringify({ ok: false, source: srcAbs, destination: dstAbs, error: (err as Error).message });\n }\n },\n {\n name: \"file_move\",\n description:\n \"Move or rename a file or directory. If destination is an existing directory, source is moved into it. Handles cross-device moves via copy+remove fallback.\",\n schema: moveSchema,\n },\n);\n\n// --- list ---------------------------------------------------------------\n\nconst listSchema = z.object({\n path: z.string().describe(\"Directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n max_entries: z\n .number()\n .int()\n .min(1)\n .max(500)\n .optional()\n .describe(\"Cap on returned entries (default 200, max 500). Listings are non-recursive — to explore subtrees, call file_list once per directory.\"),\n include_hidden: z\n .boolean()\n .optional()\n .describe(\"Include dot-prefixed entries (default false)\"),\n pattern: z\n .string()\n .optional()\n .describe(\"Optional case-insensitive substring filter applied to the basename\"),\n});\n\nexport const fileListTool = tool(\n async ({ path: dirPath, max_entries, include_hidden, pattern }) => {\n let abs = dirPath;\n try {\n abs = resolvePath(dirPath);\n assertSafePath(abs, \"read\");\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n const cap = max_entries ?? 200;\n const filter = pattern?.toLowerCase() ?? null;\n const entries: Array<{ path: string; kind: \"file\" | \"directory\" | \"other\"; size?: number }> = [];\n let truncated = false;\n try {\n let items: import(\"node:fs\").Dirent[];\n try {\n items = await fs.readdir(abs, { withFileTypes: true });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n items.sort((a, b) => a.name.localeCompare(b.name));\n for (const it of items) {\n if (entries.length >= cap) {\n truncated = true;\n break;\n }\n if (!include_hidden && it.name.startsWith(\".\")) continue;\n if (filter && !it.name.toLowerCase().includes(filter)) continue;\n const full = path.join(abs, it.name);\n const kind: \"file\" | \"directory\" | \"other\" = it.isDirectory()\n ? \"directory\"\n : it.isFile()\n ? \"file\"\n : \"other\";\n let size: number | undefined;\n if (kind === \"file\") {\n try {\n const st = await fs.stat(full);\n size = st.size;\n } catch {\n // ignore\n }\n }\n entries.push({ path: full, kind, size });\n }\n // Build the payload, then enforce a hard JSON byte cap. If the entry\n // list itself is too large (e.g. extremely long filenames), drop\n // entries from the tail until we fit so the LLM never gets a result\n // that blows past its prompt budget.\n const build = (es: typeof entries, droppedForSize: number) => JSON.stringify({\n ok: true,\n path: abs,\n entries: es,\n count: es.length,\n total_in_dir_after_filters: entries.length,\n truncated: truncated || droppedForSize > 0,\n truncated_hint: (truncated || droppedForSize > 0)\n ? \"Result truncated. Lower max_entries, add a `pattern` filter, or descend into a more specific subdirectory.\"\n : undefined,\n dropped_for_size: droppedForSize > 0 ? droppedForSize : undefined,\n filters: {\n include_hidden: !!include_hidden,\n pattern: pattern ?? null,\n max_entries: cap,\n },\n });\n let payload = build(entries, 0);\n if (payload.length > MAX_LIST_JSON_BYTES) {\n // Binary-trim entries from the tail until we fit.\n let lo = 0, hi = entries.length;\n while (lo < hi) {\n const mid = Math.floor((lo + hi + 1) / 2);\n if (build(entries.slice(0, mid), entries.length - mid).length <= MAX_LIST_JSON_BYTES) lo = mid;\n else hi = mid - 1;\n }\n payload = build(entries.slice(0, lo), entries.length - lo);\n }\n return payload;\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_list\",\n description:\n \"List one directory's entries (NON-RECURSIVE). To explore a subtree, call file_list once per directory and decide what to descend into based on the result — do NOT try to list everything at once. Hidden (dot) entries are skipped unless include_hidden=true. Optional `pattern` substring filter on basenames. Default cap 200 entries (max 500); the JSON result is hard-capped at ~24 KB and excess entries are dropped with a hint.\",\n schema: listSchema,\n },\n);\n\n// --- mkdir --------------------------------------------------------------\n\nconst mkdirSchema = z.object({\n path: z.string().describe(\"Directory path to create. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n recursive: z.boolean().optional().describe(\"Create parent directories as needed (default true)\"),\n});\n\nexport const fileMkdirTool = tool(\n async ({ path: dirPath, recursive }) => {\n let abs = dirPath;\n try {\n abs = resolvePath(dirPath);\n assertSafePath(abs, \"write\");\n await fs.mkdir(abs, { recursive: recursive !== false });\n return JSON.stringify({ ok: true, path: abs });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_mkdir\",\n description: \"Create a directory. Creates parents by default.\",\n schema: mkdirSchema,\n },\n);\n\n// --- delete -------------------------------------------------------------\n\nconst deleteSchema = z.object({\n path: z.string().describe(\"File or directory path to remove. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n recursive: z\n .boolean()\n .optional()\n .describe(\"Required to delete a non-empty directory (default false)\"),\n});\n\nexport const fileDeleteTool = tool(\n async ({ path: targetPath, recursive }) => {\n let abs = targetPath;\n try {\n abs = resolvePath(targetPath);\n assertSafePath(abs, \"write\");\n const st = await fs.stat(abs);\n if (st.isDirectory()) {\n if (!recursive) {\n // Try non-recursive rmdir first — succeeds only if empty.\n try {\n await fs.rmdir(abs);\n return JSON.stringify({ ok: true, path: abs, kind: \"directory\", removed: \"empty\" });\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOTEMPTY\") {\n return JSON.stringify({\n ok: false,\n path: abs,\n error: \"directory is not empty. Pass recursive=true to delete its contents.\",\n });\n }\n throw err;\n }\n }\n await fs.rm(abs, { recursive: true, force: false });\n return JSON.stringify({ ok: true, path: abs, kind: \"directory\", removed: \"recursive\" });\n }\n await fs.unlink(abs);\n return JSON.stringify({ ok: true, path: abs, kind: \"file\" });\n } catch (err) {\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_delete\",\n description:\n \"Delete a file or directory. Non-empty directories require recursive=true. Symlinks are not followed.\",\n schema: deleteSchema,\n },\n);\n\n// --- copy ---------------------------------------------------------------\n\nconst copySchema = z.object({\n source: z.string().describe(\"Existing file or directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n destination: z.string().describe(\"New path (absolute or ~/foo; bare relative resolves against HOME). If it ends with a separator or is an existing directory, source is copied into it preserving its basename.\"),\n overwrite: z.boolean().optional().describe(\"Allow replacing an existing destination (default false)\"),\n recursive: z.boolean().optional().describe(\"Recurse when copying a directory (default true)\"),\n});\n\nexport const fileCopyTool = tool(\n async ({ source, destination, overwrite, recursive }) => {\n let srcAbs = source;\n let dstAbs = destination;\n try {\n srcAbs = resolvePath(source);\n dstAbs = resolvePath(destination);\n assertSafePath(srcAbs, \"read\");\n assertSafePath(dstAbs, \"write\");\n const srcStat = await fs.stat(srcAbs);\n let dstStat: import(\"node:fs\").Stats | null = null;\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n // missing\n }\n if (dstStat?.isDirectory()) {\n dstAbs = path.join(dstAbs, path.basename(srcAbs));\n try {\n dstStat = await fs.stat(dstAbs);\n } catch {\n dstStat = null;\n }\n }\n if (dstStat && !overwrite) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n destination: dstAbs,\n error: \"destination exists. Pass overwrite=true to replace it.\",\n });\n }\n await fs.mkdir(path.dirname(dstAbs), { recursive: true });\n if (srcStat.isDirectory()) {\n if (recursive === false) {\n return JSON.stringify({\n ok: false,\n source: srcAbs,\n error: \"source is a directory but recursive=false\",\n });\n }\n await fs.cp(srcAbs, dstAbs, { recursive: true, force: overwrite === true, errorOnExist: !overwrite });\n } else {\n await fs.copyFile(srcAbs, dstAbs);\n }\n return JSON.stringify({\n ok: true,\n source: srcAbs,\n destination: dstAbs,\n kind: srcStat.isDirectory() ? \"directory\" : \"file\",\n });\n } catch (err) {\n return JSON.stringify({ ok: false, source: srcAbs, destination: dstAbs, error: (err as Error).message });\n }\n },\n {\n name: \"file_copy\",\n description:\n \"Copy a file or directory. If destination is an existing directory, source is copied into it. Directories require recursive=true (default).\",\n schema: copySchema,\n },\n);\n\n// --- stat ---------------------------------------------------------------\n\nconst statSchema = z.object({\n path: z.string().describe(\"File or directory path. Absolute or ~/foo; bare relative paths resolve against HOME.\"),\n});\n\nexport const fileStatTool = tool(\n async ({ path: targetPath }) => {\n let abs = targetPath;\n try {\n abs = resolvePath(targetPath);\n const st = await fs.stat(abs);\n return JSON.stringify({\n ok: true,\n path: abs,\n exists: true,\n kind: st.isDirectory() ? \"directory\" : st.isFile() ? \"file\" : \"other\",\n size: st.size,\n modified_ms: st.mtimeMs,\n created_ms: st.birthtimeMs,\n mode: st.mode,\n });\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") {\n return JSON.stringify({ ok: true, path: abs, exists: false });\n }\n return JSON.stringify({ ok: false, path: abs, error: (err as Error).message });\n }\n },\n {\n name: \"file_stat\",\n description: \"Check whether a path exists and return its kind, size, and timestamps.\",\n schema: statSchema,\n },\n);\n\nregisterTools(\"Files\", [\n fileReadTool, fileWriteTool, fileEditTool, fileMoveTool, fileCopyTool,\n fileDeleteTool, fileListTool, fileMkdirTool, fileStatTool,\n]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\n\ninterface SearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\n// Tavily is the preferred backend for agent-grade search (clean JSON, citations,\n// good ranking) but requires an API key. Without one we fall back to scraping\n// DuckDuckGo's HTML endpoint — which works without auth and goes through\n// EnvHttpProxyAgent on corporate networks.\nasync function tavilySearch(query: string, limit: number, apiKey: string): Promise<SearchResult[]> {\n const res = await fetch(\"https://api.tavily.com/search\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n api_key: apiKey,\n query,\n max_results: limit,\n search_depth: \"basic\",\n }),\n });\n if (!res.ok) throw new Error(`Tavily ${res.status}: ${await res.text()}`);\n const data = (await res.json()) as { results?: Array<{ title: string; url: string; content?: string }> };\n return (data.results ?? []).slice(0, limit).map((r) => ({\n title: r.title,\n url: r.url,\n snippet: r.content ?? \"\",\n }));\n}\n\n// Rotate UA across retries — DDG flags repeated identical fingerprints.\nconst UA_POOL = [\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36\",\n \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0 Safari/537.36\",\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36\",\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15\",\n \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0\",\n];\n\nasync function ddgSearch(query: string, limit: number): Promise<SearchResult[]> {\n // DDG returns a 202 \"anomaly detection\" placeholder when it suspects\n // automation. Retry with rotated UAs and exponential backoff. Empty results\n // on a 200 are treated as legitimate \"no hits\" and not retried.\n let lastStatus = 0;\n for (let attempt = 0; attempt < 5; attempt++) {\n const ua = UA_POOL[attempt % UA_POOL.length];\n const res = await fetch(\"https://html.duckduckgo.com/html/\", {\n method: \"POST\",\n headers: {\n \"User-Agent\": ua,\n \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n \"Referer\": \"https://duckduckgo.com/\",\n },\n body: `q=${encodeURIComponent(query)}&kl=us-en`,\n });\n lastStatus = res.status;\n if (!res.ok) throw new Error(`DuckDuckGo ${res.status}`);\n const html = await res.text();\n const parsed = parseDDGHtml(html, limit);\n if (parsed.length > 0) return parsed;\n if (res.status !== 202) return parsed; // genuine empty result on 200\n // Backoff: 400, 900, 1600, 2500 ms — total max ≈ 5.4s\n await new Promise((r) => setTimeout(r, 400 + attempt * 500));\n }\n // All retries returned 202 placeholder — surface as empty so caller can handle.\n console.warn(`[web_search] DDG returned ${lastStatus} placeholder on all attempts for \"${query}\"`);\n return [];\n}\n\nfunction parseDDGHtml(html: string, limit: number): SearchResult[] {\n const results: SearchResult[] = [];\n // Each result block contains a result__a (title link) and a result__snippet (snippet link).\n const blockRe = /<div\\s+class=\"result\\s+results_links[^\"]*\"[\\s\\S]*?<\\/div>\\s*<\\/div>/g;\n let match: RegExpExecArray | null;\n while ((match = blockRe.exec(html)) !== null) {\n if (results.length >= limit) break;\n const block = match[0];\n const titleMatch = /<a[^>]+class=\"result__a\"[^>]+href=\"([^\"]+)\"[^>]*>([\\s\\S]*?)<\\/a>/.exec(block);\n const snippetMatch = /<a[^>]+class=\"result__snippet\"[^>]*>([\\s\\S]*?)<\\/a>/.exec(block);\n if (!titleMatch) continue;\n const url = unwrapDDGRedirect(decodeHTML(titleMatch[1]));\n if (!url) continue;\n const title = stripTags(titleMatch[2]).trim();\n const snippet = snippetMatch ? stripTags(snippetMatch[1]).trim() : \"\";\n if (title) results.push({ title, url, snippet });\n }\n return results;\n}\n\nfunction unwrapDDGRedirect(href: string): string | null {\n // DDG wraps outbound links as //duckduckgo.com/l/?uddg=<encoded>&...\n if (href.startsWith(\"//\")) href = `https:${href}`;\n try {\n const u = new URL(href);\n if (u.hostname.endsWith(\"duckduckgo.com\") && u.pathname === \"/l/\") {\n const real = u.searchParams.get(\"uddg\");\n return real ? decodeURIComponent(real) : null;\n }\n return u.toString();\n } catch {\n return null;\n }\n}\n\nfunction stripTags(s: string): string {\n return s.replace(/<[^>]+>/g, \"\");\n}\n\nfunction decodeHTML(s: string): string {\n return s\n .replace(/&amp;/g, \"&\")\n .replace(/&quot;/g, '\"')\n .replace(/&#x27;/g, \"'\")\n .replace(/&#39;/g, \"'\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\");\n}\n\nexport const webSearchTool = tool(\n async ({ query, max_results }) => {\n const limit = Math.min(max_results ?? 5, 10);\n const tavilyKey = process.env.TAVILY_API_KEY;\n\n try {\n const results = tavilyKey\n ? await tavilySearch(query, limit, tavilyKey)\n : await ddgSearch(query, limit);\n return JSON.stringify({\n query,\n provider: tavilyKey ? \"tavily\" : \"duckduckgo\",\n results,\n total: results.length,\n });\n } catch (err) {\n return JSON.stringify({\n query,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n },\n {\n name: \"web_search\",\n description:\n \"Search the web and return relevant results (title, url, snippet). \" +\n \"Best for factual lookups, current events, documentation, and research. \" +\n \"Returns up to 10 results per call; default 5.\",\n schema: z.object({\n query: z.string().describe(\"Search query\"),\n max_results: z.number().optional().describe(\"Max results to return (default 5, max 10)\"),\n }),\n },\n);\n\nregisterTools(\"Web\", [webSearchTool]);\n","// SSRF guard: classify an address (or hostname) as \"private\" — i.e. one\n// that an LLM-driven agent should never be allowed to reach with a\n// server-side fetch driven by attacker-controlled input. The bar is set\n// by what the access middleware (lib/auth/access.ts) treats as\n// privileged: anything that resolves to loopback hits the API without\n// authentication, and link-local / cloud-metadata / RFC1918 ranges\n// reach the host's LAN or cloud provider's introspection surface.\n//\n// Used by `web_fetch` and other agent-controlled URL fetchers to block\n// the canonical SSRF / metadata-service paths:\n// - http://127.0.0.1:4312/api/v1/... → self-call into our own admin API\n// - http://169.254.169.254/... → AWS/GCE/Azure metadata\n// - http://10.x / 192.168.x / etc. → LAN router / printer admin\n//\n// Operators with a legitimate need (e.g. fetching from an internal docs\n// server) can opt back in with `JARELA_ALLOW_PRIVATE_FETCH=1`.\n\nimport { promises as dns } from \"node:dns\";\nimport net from \"node:net\";\n\nexport type PrivateClassification =\n | \"public\"\n | \"loopback\"\n | \"private\"\n | \"link-local\"\n | \"unspecified\"\n | \"broadcast\"\n | \"reserved\";\n\nfunction ipv4InCidr(addr: number, prefix: number, bits: number): boolean {\n const mask = bits === 0 ? 0 : (~0 << (32 - bits)) >>> 0;\n return (addr & mask) === (prefix & mask);\n}\n\nfunction ipv4ToNumber(ip: string): number | null {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let n = 0;\n for (const part of parts) {\n const v = Number(part);\n if (!Number.isInteger(v) || v < 0 || v > 255) return null;\n n = (n << 8) | v;\n }\n return n >>> 0;\n}\n\nfunction classifyIPv4(ip: string): PrivateClassification {\n const n = ipv4ToNumber(ip);\n if (n === null) return \"reserved\";\n // 0.0.0.0/8 — \"this network\"\n if (ipv4InCidr(n, ipv4ToNumber(\"0.0.0.0\")!, 8)) return \"unspecified\";\n // 127.0.0.0/8 — loopback\n if (ipv4InCidr(n, ipv4ToNumber(\"127.0.0.0\")!, 8)) return \"loopback\";\n // 10.0.0.0/8\n if (ipv4InCidr(n, ipv4ToNumber(\"10.0.0.0\")!, 8)) return \"private\";\n // 172.16.0.0/12\n if (ipv4InCidr(n, ipv4ToNumber(\"172.16.0.0\")!, 12)) return \"private\";\n // 192.168.0.0/16\n if (ipv4InCidr(n, ipv4ToNumber(\"192.168.0.0\")!, 16)) return \"private\";\n // 169.254.0.0/16 — link-local (incl. cloud metadata at 169.254.169.254)\n if (ipv4InCidr(n, ipv4ToNumber(\"169.254.0.0\")!, 16)) return \"link-local\";\n // 100.64.0.0/10 — CGNAT / Tailscale carrier-grade NAT range. Treat as\n // private: anything reachable here is a tailnet peer, not a public URL.\n if (ipv4InCidr(n, ipv4ToNumber(\"100.64.0.0\")!, 10)) return \"private\";\n // 224.0.0.0/4 — multicast; 240.0.0.0/4 — reserved; 255.255.255.255 — broadcast\n if (ipv4InCidr(n, ipv4ToNumber(\"224.0.0.0\")!, 4)) return \"reserved\";\n if (ipv4InCidr(n, ipv4ToNumber(\"240.0.0.0\")!, 4)) return \"reserved\";\n return \"public\";\n}\n\nfunction classifyIPv6(ip: string): PrivateClassification {\n // Normalise: lower-case, drop zone id (fe80::1%eth0).\n const bare = ip.toLowerCase().split(\"%\")[0];\n if (bare === \"::\" || bare === \"::0\") return \"unspecified\";\n if (bare === \"::1\") return \"loopback\";\n // IPv4-mapped (::ffff:a.b.c.d) — classify the embedded v4.\n if (bare.startsWith(\"::ffff:\")) {\n const v4 = bare.slice(7);\n if (net.isIPv4(v4)) return classifyIPv4(v4);\n }\n // fe80::/10 — link-local\n if (/^fe[89ab][0-9a-f]?:/.test(bare)) return \"link-local\";\n // fc00::/7 — unique local addresses\n if (/^f[cd][0-9a-f]{0,2}:/.test(bare)) return \"private\";\n // ff00::/8 — multicast\n if (bare.startsWith(\"ff\")) return \"reserved\";\n return \"public\";\n}\n\nexport function classifyAddress(ip: string): PrivateClassification {\n if (net.isIPv4(ip)) return classifyIPv4(ip);\n if (net.isIPv6(ip)) return classifyIPv6(ip);\n return \"reserved\";\n}\n\nexport function isPrivateAddress(ip: string): boolean {\n const cls = classifyAddress(ip);\n return cls !== \"public\";\n}\n\nexport interface UrlCheckResult {\n allowed: boolean;\n reason?: PrivateClassification | \"invalid-url\" | \"unsupported-scheme\" | \"resolve-failed\";\n resolved?: string[];\n}\n\n/**\n * Pre-flight check for a server-side fetch driven by agent input.\n *\n * Returns `{ allowed: true }` when every IP the URL's hostname resolves\n * to is publicly routable. If `JARELA_ALLOW_PRIVATE_FETCH=1` the result\n * is always `{ allowed: true }` (operator opt-out).\n *\n * Hostnames that fail to resolve are treated as **rejected** — better to\n * refuse than to hand the question off to undici and re-resolve at\n * connect time, when we have no way to inspect the answer.\n */\nexport async function checkPublicUrl(rawUrl: string): Promise<UrlCheckResult> {\n if (process.env.JARELA_ALLOW_PRIVATE_FETCH === \"1\") {\n return { allowed: true };\n }\n let url: URL;\n try {\n url = new URL(rawUrl);\n } catch {\n return { allowed: false, reason: \"invalid-url\" };\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return { allowed: false, reason: \"unsupported-scheme\" };\n }\n // Strip [] from IPv6 literals so net.isIP / dns.lookup work.\n const host = url.hostname.replace(/^\\[|\\]$/g, \"\");\n if (net.isIP(host)) {\n const cls = classifyAddress(host);\n return cls === \"public\" ? { allowed: true, resolved: [host] } : { allowed: false, reason: cls, resolved: [host] };\n }\n let addrs: Array<{ address: string; family: number }>;\n try {\n addrs = await dns.lookup(host, { all: true });\n } catch {\n return { allowed: false, reason: \"resolve-failed\" };\n }\n const resolved = addrs.map((a) => a.address);\n for (const addr of resolved) {\n const cls = classifyAddress(addr);\n if (cls !== \"public\") return { allowed: false, reason: cls, resolved };\n }\n return { allowed: true, resolved };\n}\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { stripHtml } from \"@/lib/utils/html\";\nimport { checkPublicUrl } from \"@/lib/utils/private-ip\";\nimport { registerTools } from \"./registry\";\n\nconst MAX_BYTES = 200_000;\nconst TIMEOUT_MS = 15_000;\n// Defense against SSRF redirect chains: every Location-hop is re-checked\n// against the SSRF policy. Cap the chain so a malicious server can't\n// pin us in a redirect loop.\nconst MAX_REDIRECTS = 5;\n\nfunction extractTitle(html: string): string | null {\n const m = /<title[^>]*>([^<]+)<\\/title>/i.exec(html);\n return m ? m[1].trim() : null;\n}\n\n// Pull image URLs out of a fetched page so the agent can embed them in its\n// reply via standard markdown `![alt](url)`. We expose three categories:\n// - og: the page's primary OG image (most useful — chosen by the publisher)\n// - twitter: the Twitter card image (close second)\n// - samples: the first few <img src=…> tags (fallback when meta is missing)\n//\n// All URLs are resolved to absolute against the final fetched URL so the\n// agent can use them as-is. Data URIs and tracking pixels are filtered out.\nfunction extractImages(html: string, baseUrl: string): {\n og: string | null;\n twitter: string | null;\n samples: string[];\n} {\n const og =\n /<meta[^>]+property=[\"']og:image(?::secure_url|:url)?[\"'][^>]+content=[\"']([^\"']+)[\"']/i.exec(html)?.[1] ??\n /<meta[^>]+content=[\"']([^\"']+)[\"'][^>]+property=[\"']og:image[\"']/i.exec(html)?.[1] ?? null;\n\n const twitter =\n /<meta[^>]+name=[\"']twitter:image(?::src)?[\"'][^>]+content=[\"']([^\"']+)[\"']/i.exec(html)?.[1] ??\n /<meta[^>]+content=[\"']([^\"']+)[\"'][^>]+name=[\"']twitter:image[\"']/i.exec(html)?.[1] ?? null;\n\n const seen = new Set<string>();\n const samples: string[] = [];\n for (const m of html.matchAll(/<img[^>]+src=[\"']([^\"']+)[\"']/gi)) {\n const src = m[1];\n if (!src || src.startsWith(\"data:\")) continue;\n // Skip obvious tracking pixels and tiny svgs.\n if (/(?:1x1|pixel|spacer)\\.(?:gif|png)/i.test(src)) continue;\n const abs = resolveUrl(src, baseUrl);\n if (!abs || seen.has(abs)) continue;\n seen.add(abs);\n samples.push(abs);\n if (samples.length >= 6) break;\n }\n\n return {\n og: resolveUrl(og, baseUrl),\n twitter: resolveUrl(twitter, baseUrl),\n samples,\n };\n}\n\nfunction resolveUrl(u: string | null | undefined, base: string): string | null {\n if (!u) return null;\n try { return new URL(u, base).toString(); } catch { return null; }\n}\n\nexport const webFetchTool = tool(\n async ({ url, mode, max_chars }) => {\n if (!/^https?:\\/\\//.test(url)) {\n return JSON.stringify({ error: \"url must start with http:// or https://\" });\n }\n const ctrl = new AbortController();\n const timeout = setTimeout(() => ctrl.abort(), TIMEOUT_MS);\n try {\n // SSRF guard. The LLM controls `url`, and our HTTP middleware\n // treats loopback callers as the host machine's admin user — a\n // prompt-injected page could otherwise ask the agent to fetch\n // http://127.0.0.1:4312/api/v1/... and elevate. Same story for\n // 169.254.169.254 (cloud metadata) and the RFC1918 ranges.\n // Operators with a legitimate intranet need can opt back in via\n // JARELA_ALLOW_PRIVATE_FETCH=1.\n const initialCheck = await checkPublicUrl(url);\n if (!initialCheck.allowed) {\n return JSON.stringify({\n url,\n error: `Refused to fetch private/loopback address (${initialCheck.reason}). Set JARELA_ALLOW_PRIVATE_FETCH=1 to override.`,\n });\n }\n\n // Manual redirect chasing so each hop is re-checked against the\n // SSRF policy. A 30x to an attacker-controlled host could otherwise\n // bounce us into 169.254.x even though the initial URL looked\n // public.\n let currentUrl = url;\n let res: Response;\n for (let hop = 0; ; hop++) {\n res = await fetch(currentUrl, {\n signal: ctrl.signal,\n redirect: \"manual\",\n headers: {\n \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36\",\n \"Accept\": \"text/html,application/xhtml+xml,*/*;q=0.8\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n },\n });\n if (res.status < 300 || res.status >= 400) break;\n const loc = res.headers.get(\"location\");\n if (!loc) break;\n if (hop >= MAX_REDIRECTS) {\n return JSON.stringify({ url: currentUrl, error: `too many redirects (>${MAX_REDIRECTS})` });\n }\n let next: string;\n try {\n next = new URL(loc, currentUrl).toString();\n } catch {\n return JSON.stringify({ url: currentUrl, error: `invalid redirect target: ${loc}` });\n }\n const hopCheck = await checkPublicUrl(next);\n if (!hopCheck.allowed) {\n return JSON.stringify({\n url: next,\n error: `Refused redirect to private/loopback address (${hopCheck.reason}).`,\n });\n }\n currentUrl = next;\n }\n\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n const finalUrl = res.url || currentUrl;\n // Read up to MAX_BYTES so a 5MB page doesn't blow the agent's context.\n const reader = res.body?.getReader();\n const decoder = new TextDecoder();\n let bytesRead = 0;\n let raw = \"\";\n if (reader) {\n while (bytesRead < MAX_BYTES) {\n const { value, done } = await reader.read();\n if (done) break;\n bytesRead += value.byteLength;\n raw += decoder.decode(value, { stream: true });\n if (bytesRead >= MAX_BYTES) {\n await reader.cancel();\n break;\n }\n }\n }\n const truncated = bytesRead >= MAX_BYTES;\n const cap = max_chars ?? 8000;\n const wantHtml = mode === \"html\";\n const title = extractTitle(raw);\n const body = wantHtml ? raw : stripHtml(raw);\n const clipped = body.length > cap ? body.slice(0, cap) + \"…\" : body;\n const images = extractImages(raw, finalUrl);\n\n return JSON.stringify({\n url: finalUrl,\n status: res.status,\n content_type: contentType,\n title,\n mode: wantHtml ? \"html\" : \"text\",\n bytes_read: bytesRead,\n truncated,\n content: clipped,\n images,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return JSON.stringify({ url, error: msg });\n } finally {\n clearTimeout(timeout);\n }\n },\n {\n name: \"web_fetch\",\n description:\n \"Fetch the content of a URL. Default mode='text' returns extracted plain text (good for summarizing articles). \" +\n \"mode='html' returns raw HTML if you specifically need markup. Truncates after 200KB. \" +\n \"Use this when web_search returns a URL but you need the actual page content, or to fetch a specific known page. \" +\n \"The response also includes an `images` object with absolute URLs extracted from the page: \" +\n \"`og` (og:image — usually the best hero image), `twitter` (twitter:image), and `samples` (first few <img> tags). \" +\n \"Embed these in your reply with markdown `![alt](url)` to produce rich, image-rich answers.\",\n schema: z.object({\n url: z.string().describe(\"Absolute URL starting with http:// or https://\"),\n mode: z.enum([\"text\", \"html\"]).optional().describe(\"'text' (default) extracts readable text; 'html' returns raw markup\"),\n max_chars: z.number().optional().describe(\"Max characters to return after extraction (default 8000)\"),\n }),\n },\n);\n\nregisterTools(\"Web\", [webFetchTool]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getUserProfile } from \"@/lib/stores/user-profile\";\nimport { registerTools } from \"./registry\";\n\n// Returns the user's last reported browser geolocation, if they've opted in\n// from the UI. The agent should call this whenever a request is location-\n// dependent (\"what's the weather\", \"find a coffee shop near me\", \"how long\n// to drive home\"). It returns a structured JSON payload — never coordinates\n// inline in prose. If sharing is disabled the result explains how to enable\n// it, so the agent can relay that to the user.\nexport const getUserLocationTool = tool(\n async () => {\n const profile = getUserProfile();\n if (!profile || profile.location_consent !== 1) {\n return JSON.stringify({\n available: false,\n reason: \"user has not enabled location sharing\",\n how_to_enable: \"Open the Profile panel and toggle 'Share my location'.\",\n });\n }\n if (\n typeof profile.location_lat !== \"number\" ||\n typeof profile.location_lng !== \"number\"\n ) {\n return JSON.stringify({\n available: false,\n reason: \"consent granted but no coordinates reported yet\",\n how_to_enable: \"Reload the app so the browser can request a fix.\",\n });\n }\n const updatedAt = profile.location_updated_at;\n const ageMs = updatedAt ? Date.now() - Date.parse(updatedAt) : null;\n return JSON.stringify({\n available: true,\n lat: profile.location_lat,\n lng: profile.location_lng,\n accuracy_m: profile.location_accuracy_m ?? null,\n label: profile.location_label ?? null,\n updated_at: updatedAt,\n age_seconds: ageMs !== null ? Math.round(ageMs / 1000) : null,\n });\n },\n {\n name: \"get_user_location\",\n description:\n \"Get the user's current geographic location (latitude/longitude) from their browser. Use this whenever the answer depends on where the user is — weather, nearby places, directions home, local time of points-of-interest. Returns { available, lat, lng, accuracy_m, label, age_seconds } or { available: false, reason } if the user hasn't opted in.\",\n schema: z.object({}).describe(\"No arguments — the user's location is stored server-side and updated by the client.\"),\n },\n);\n\nregisterTools(\"Web\", [getUserLocationTool]);\n","// Local file store for binary artifacts produced by tools (generated images,\n// downloads, etc.). Files live under ~/.jarela/files/ and are served by\n// GET /api/v1/files/[name]. The tool returns a relative URL the chat\n// renderer can embed as <img src=\"/api/v1/files/...\">.\n\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getDataDir } from \"@/lib/db/data-dir\";\n\nexport const FILES_DIR = join(getDataDir(), \"files\");\n\nmkdirSync(FILES_DIR, { recursive: true });\n\n// Name must be a single path segment with no separators or \"..\". Callers\n// generate names from randomUUID() so this is mostly defense-in-depth.\nconst SAFE_NAME = /^[A-Za-z0-9._-]+$/;\n\nexport function isSafeFileName(name: string): boolean {\n return SAFE_NAME.test(name) && !name.includes(\"..\");\n}\n\nexport function fileAbsPath(name: string): string | null {\n if (!isSafeFileName(name)) return null;\n return join(FILES_DIR, name);\n}\n\nexport function writeBinaryFile(name: string, data: Buffer): string {\n if (!isSafeFileName(name)) throw new Error(`unsafe file name: ${name}`);\n const p = join(FILES_DIR, name);\n writeFileSync(p, data);\n return p;\n}\n","import { getIntegrationRaw } from \"@/lib/stores/integrations\";\n\nexport function timeoutSignal(ms: number): AbortSignal {\n const c = new AbortController();\n setTimeout(() => c.abort(new Error(`timeout after ${ms}ms`)), ms).unref?.();\n return c.signal;\n}\n\nexport function resolveGoogleApiKey(): string | null {\n const raw = getIntegrationRaw(\"google\");\n const fromStore = raw?.api_key?.trim();\n if (fromStore) return fromStore;\n return (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || \"\").trim() || null;\n}\n","// generate_image: produce an image from a text prompt using Google's Gemini\n// image-generation models (a.k.a. \"nano banana\") via the Generative Language\n// REST API. Falls back to Imagen if the user picks one of those model ids.\n//\n// API key resolution: integrations store (\"google\" → api_key) →\n// GEMINI_API_KEY env → GOOGLE_API_KEY env. The Integrations panel is the\n// recommended way to set this.\n//\n// Output: PNG bytes written to ~/.jarela/files/<uuid>.png. The tool returns\n// a relative URL the chat renderer can embed via markdown `![alt](url)`.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { randomUUID } from \"node:crypto\";\nimport { writeBinaryFile } from \"@/lib/files\";\nimport { getConfig } from \"@/lib/env/config\";\nimport { resolveGoogleApiKey, timeoutSignal } from \"@/lib/utils/google-api\";\nimport { registerTools } from \"./registry\";\n\nconst DEFAULT_MODEL = \"gemini-2.5-flash-image\";\nconst ENDPOINT = \"https://generativelanguage.googleapis.com/v1beta/models\";\n\ninterface InlineData {\n mimeType?: string;\n mime_type?: string;\n data?: string;\n}\ninterface GeminiPart {\n text?: string;\n inlineData?: InlineData;\n inline_data?: InlineData;\n}\ninterface GeminiResponse {\n candidates?: Array<{ content?: { parts?: GeminiPart[] } }>;\n error?: { message?: string };\n}\n\ninterface ImagenPrediction {\n bytesBase64Encoded?: string;\n mimeType?: string;\n}\ninterface ImagenResponse {\n predictions?: ImagenPrediction[];\n error?: { message?: string };\n}\n\nasync function callGemini(model: string, prompt: string, apiKey: string): Promise<{ data: Buffer; mime: string }> {\n const url = `${ENDPOINT}/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(apiKey)}`;\n const body = {\n contents: [{ role: \"user\", parts: [{ text: prompt }] }],\n generationConfig: { responseModalities: [\"IMAGE\", \"TEXT\"] },\n };\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().imageTimeoutMs),\n });\n } catch (err) {\n throw new Error(`Gemini request failed: ${describeError(err)}`);\n }\n const json = (await res.json()) as GeminiResponse;\n if (!res.ok) {\n throw new Error(`Gemini ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const parts = json.candidates?.[0]?.content?.parts ?? [];\n for (const p of parts) {\n const inline = p.inlineData ?? p.inline_data;\n const data = inline?.data;\n const mime = inline?.mimeType ?? inline?.mime_type ?? \"image/png\";\n if (data) return { data: Buffer.from(data, \"base64\"), mime };\n }\n const text = parts.map((p) => p.text).filter(Boolean).join(\" \").trim();\n throw new Error(text ? `Gemini returned no image: ${text}` : \"Gemini returned no image\");\n}\n\nasync function callImagen(model: string, prompt: string, apiKey: string, n: number, aspect: string): Promise<Array<{ data: Buffer; mime: string }>> {\n const url = `${ENDPOINT}/${encodeURIComponent(model)}:predict?key=${encodeURIComponent(apiKey)}`;\n const body = {\n instances: [{ prompt }],\n parameters: { sampleCount: Math.max(1, Math.min(4, n)), aspectRatio: aspect },\n };\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().imageTimeoutMs),\n });\n } catch (err) {\n throw new Error(`Imagen request failed: ${describeError(err)}`);\n }\n const json = (await res.json()) as ImagenResponse;\n if (!res.ok) {\n throw new Error(`Imagen ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const preds = json.predictions ?? [];\n const out: Array<{ data: Buffer; mime: string }> = [];\n for (const p of preds) {\n if (p.bytesBase64Encoded) {\n out.push({ data: Buffer.from(p.bytesBase64Encoded, \"base64\"), mime: p.mimeType ?? \"image/png\" });\n }\n }\n if (out.length === 0) throw new Error(\"Imagen returned no image\");\n return out;\n}\n\nfunction describeError(err: unknown): string {\n if (!(err instanceof Error)) return String(err);\n const cause = (err as { cause?: unknown }).cause;\n if (cause instanceof Error) {\n const code = (cause as { code?: string }).code;\n return code ? `${err.message}: ${cause.message} (${code})` : `${err.message}: ${cause.message}`;\n }\n return err.message;\n}\n\nfunction extForMime(mime: string): string {\n if (mime === \"image/jpeg\") return \"jpg\";\n if (mime === \"image/webp\") return \"webp\";\n if (mime === \"image/gif\") return \"gif\";\n return \"png\";\n}\n\nexport const generateImageTool = tool(\n async ({ prompt, model, count, aspect_ratio }) => {\n const trimmed = prompt.trim();\n if (!trimmed) throw new Error(\"prompt is required and must be non-empty\");\n\n const apiKey = resolveGoogleApiKey();\n if (!apiKey) {\n throw new Error(\n 'Google API key not configured. Open the Integrations panel and set \"Google AI (Gemini + Imagen)\", or set GEMINI_API_KEY in the environment.',\n );\n }\n\n const m = (model ?? DEFAULT_MODEL).trim() || DEFAULT_MODEL;\n const aspect = aspect_ratio ?? \"1:1\";\n const n = count ?? 1;\n\n const images = m.startsWith(\"imagen\")\n ? await callImagen(m, trimmed, apiKey, n, aspect)\n : [await callGemini(m, trimmed, apiKey)];\n\n const saved = images.map((img) => {\n const name = `img-${randomUUID()}.${extForMime(img.mime)}`;\n writeBinaryFile(name, img.data);\n const url = `/api/v1/files/${name}`;\n return { url, mime: img.mime, bytes: img.data.length };\n });\n\n return JSON.stringify({\n model: m,\n prompt: trimmed,\n images: saved,\n markdown: saved.map((s, i) => `![${trimmed.slice(0, 80)}${images.length > 1 ? ` (${i + 1})` : \"\"}](${s.url})`).join(\"\\n\\n\"),\n hint: \"Embed images in your reply using the `markdown` field verbatim, or build your own `![alt](url)` from `images[].url`.\",\n });\n },\n {\n name: \"generate_image\",\n description:\n \"Generate one or more images from a text prompt using Google's Gemini image models (default: gemini-2.5-flash-image) or Imagen. Returns local URLs the assistant should embed in its reply via markdown `![alt](url)`. Requires the Google integration (api_key) to be configured.\",\n schema: z.object({\n prompt: z.string().describe(\"Detailed description of the image to generate.\"),\n model: z\n .string()\n .optional()\n .describe(\n \"Optional Google model id. Defaults to `gemini-2.5-flash-image`. Use an `imagen-*` model (e.g. `imagen-3.0-generate-002`) for higher-fidelity stills.\",\n ),\n count: z\n .number()\n .int()\n .min(1)\n .max(4)\n .optional()\n .describe(\"Number of images to generate. Only honored by Imagen models; Gemini models always return 1.\"),\n aspect_ratio: z\n .enum([\"1:1\", \"3:4\", \"4:3\", \"9:16\", \"16:9\"])\n .optional()\n .describe(\"Aspect ratio. Only honored by Imagen models; ignored by Gemini image models.\"),\n }),\n },\n);\n\nregisterTools(\"Images\", [generateImageTool]);\n","// Client-safe constants for the voice picker UI. Kept in a standalone\n// module so client components can import them without dragging server-only\n// modules (lib/db, undici, node:child_process) through the import graph.\n\nexport const GEMINI_VOICES: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"Zephyr\", label: \"Zephyr · bright\" },\n { id: \"Puck\", label: \"Puck · upbeat\" },\n { id: \"Charon\", label: \"Charon · informative\" },\n { id: \"Kore\", label: \"Kore · firm\" },\n { id: \"Fenrir\", label: \"Fenrir · excitable\" },\n { id: \"Leda\", label: \"Leda · youthful\" },\n { id: \"Orus\", label: \"Orus · firm\" },\n { id: \"Aoede\", label: \"Aoede · breezy\" },\n { id: \"Callirrhoe\", label: \"Callirrhoe · easy-going\" },\n { id: \"Autonoe\", label: \"Autonoe · bright\" },\n { id: \"Enceladus\", label: \"Enceladus · breathy\" },\n { id: \"Iapetus\", label: \"Iapetus · clear\" },\n { id: \"Umbriel\", label: \"Umbriel · easy-going\" },\n { id: \"Algieba\", label: \"Algieba · smooth\" },\n { id: \"Despina\", label: \"Despina · smooth\" },\n { id: \"Erinome\", label: \"Erinome · clear\" },\n { id: \"Algenib\", label: \"Algenib · gravelly\" },\n { id: \"Rasalgethi\", label: \"Rasalgethi · informative\" },\n { id: \"Laomedeia\", label: \"Laomedeia · upbeat\" },\n { id: \"Achernar\", label: \"Achernar · soft\" },\n { id: \"Alnilam\", label: \"Alnilam · firm\" },\n { id: \"Schedar\", label: \"Schedar · even\" },\n { id: \"Gacrux\", label: \"Gacrux · mature\" },\n { id: \"Pulcherrima\", label: \"Pulcherrima · forward\" },\n { id: \"Achird\", label: \"Achird · friendly\" },\n { id: \"Zubenelgenubi\", label: \"Zubenelgenubi · casual\" },\n { id: \"Vindemiatrix\", label: \"Vindemiatrix · gentle\" },\n { id: \"Sadachbia\", label: \"Sadachbia · lively\" },\n { id: \"Sadaltager\", label: \"Sadaltager · knowledgeable\" },\n { id: \"Sulafat\", label: \"Sulafat · warm\" },\n];\n\nexport const GEMINI_TTS_MODELS: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"gemini-2.5-flash-preview-tts\", label: \"Flash TTS (fast, cheap)\" },\n { id: \"gemini-2.5-pro-preview-tts\", label: \"Pro TTS (higher quality)\" },\n];\n\nexport const GEMINI_STT_MODELS: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"gemini-2.5-flash\", label: \"Flash (fast, multilingual)\" },\n { id: \"gemini-2.5-pro\", label: \"Pro (slower, more accurate)\" },\n];\n","// Gemini voice helpers — TTS via the *-preview-tts models and STT by\n// feeding inline audio bytes to a multimodal Gemini model. Both call the\n// native REST API (the OpenAI-compat proxy doesn't expose AUDIO modality\n// or inline_data parts). API key is resolved from the \"google\" integration,\n// same source as lib/tools/generate_image.ts.\n\nimport { getConfig } from \"@/lib/env/config\";\nimport {\n resolveGoogleApiKey as resolveGoogleApiKeyShared,\n timeoutSignal,\n} from \"@/lib/utils/google-api\";\n\nconst ENDPOINT = \"https://generativelanguage.googleapis.com/v1beta/models\";\n\nexport function resolveGoogleApiKey(): string | null {\n return resolveGoogleApiKeyShared();\n}\n\ninterface InlineData {\n mimeType?: string;\n mime_type?: string;\n data?: string;\n}\ninterface GeminiPart {\n text?: string;\n inlineData?: InlineData;\n inline_data?: InlineData;\n}\ninterface GeminiResponse {\n candidates?: Array<{ content?: { parts?: GeminiPart[] } }>;\n error?: { message?: string };\n}\n\n/**\n * Synthesize speech with Gemini TTS. Gemini returns PCM L16 (raw 16-bit\n * little-endian, 24 kHz mono); we wrap it with a WAV header so any\n * <audio> element can play it.\n *\n * Style/tone is steered by prepending a natural-language instruction to\n * the spoken text (Gemini's recommended pattern), e.g. style=\"Say warmly\n * and slowly\" produces \"Say warmly and slowly: <text>\". For multi-speaker\n * scenes, pass `speakers` with up to 2 entries and write the text as\n * `Name: line ...` per turn — Gemini will switch voices accordingly.\n */\nexport async function geminiTts(opts: {\n apiKey: string;\n model: string;\n voiceName: string;\n text: string;\n style?: string;\n speakers?: Array<{ name: string; voiceName: string }>;\n}): Promise<{ wav: Buffer; mime: \"audio/wav\" }> {\n const url = `${ENDPOINT}/${encodeURIComponent(opts.model)}:generateContent?key=${encodeURIComponent(opts.apiKey)}`;\n const style = opts.style?.trim();\n const spoken = style ? `${style.replace(/:\\s*$/, \"\")}: ${opts.text}` : opts.text;\n const speakers = (opts.speakers ?? []).filter((s) => s.name && s.voiceName).slice(0, 2);\n const speechConfig: Record<string, unknown> =\n speakers.length >= 2\n ? {\n multiSpeakerVoiceConfig: {\n speakerVoiceConfigs: speakers.map((s) => ({\n speaker: s.name,\n voiceConfig: { prebuiltVoiceConfig: { voiceName: s.voiceName } },\n })),\n },\n }\n : {\n voiceConfig: {\n prebuiltVoiceConfig: { voiceName: opts.voiceName },\n },\n };\n const body = {\n contents: [{ role: \"user\", parts: [{ text: spoken }] }],\n generationConfig: {\n responseModalities: [\"AUDIO\"],\n speechConfig,\n },\n };\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().voiceTimeoutMs),\n });\n const json = (await res.json()) as GeminiResponse;\n if (!res.ok) {\n throw new Error(`Gemini TTS ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const parts = json.candidates?.[0]?.content?.parts ?? [];\n for (const p of parts) {\n const inline = p.inlineData ?? p.inline_data;\n const data = inline?.data;\n const mime = inline?.mimeType ?? inline?.mime_type ?? \"\";\n if (data) {\n const pcm = Buffer.from(data, \"base64\");\n const rate = parseSampleRate(mime) ?? 24000;\n return { wav: pcmToWav(pcm, rate, 1, 16), mime: \"audio/wav\" };\n }\n }\n const text = parts.map((p) => p.text).filter(Boolean).join(\" \").trim();\n throw new Error(text ? `Gemini TTS returned no audio: ${text}` : \"Gemini TTS returned no audio\");\n}\n\n/**\n * Transcribe audio via a Gemini multimodal model. Returns the verbatim\n * transcript, preserving the speaker's original language (including code-\n * switched English/Chinese).\n */\nexport async function geminiStt(opts: {\n apiKey: string;\n model: string;\n audio: Buffer;\n mimeType: string;\n}): Promise<{ text: string }> {\n const url = `${ENDPOINT}/${encodeURIComponent(opts.model)}:generateContent?key=${encodeURIComponent(opts.apiKey)}`;\n const body = {\n contents: [{\n role: \"user\",\n parts: [\n {\n text:\n \"Transcribe the following audio verbatim. Preserve the speaker's \" +\n \"original language, including mixed English and Chinese. Output ONLY \" +\n \"the transcript text — no quotes, no commentary, no language tags.\",\n },\n { inline_data: { mime_type: opts.mimeType, data: opts.audio.toString(\"base64\") } },\n ],\n }],\n };\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: timeoutSignal(getConfig().voiceTimeoutMs),\n });\n const json = (await res.json()) as GeminiResponse;\n if (!res.ok) {\n throw new Error(`Gemini STT ${res.status}: ${json.error?.message ?? \"request failed\"}`);\n }\n const parts = json.candidates?.[0]?.content?.parts ?? [];\n const text = parts.map((p) => p.text).filter(Boolean).join(\"\").trim();\n if (!text) throw new Error(\"Gemini STT returned no transcript\");\n return { text };\n}\n\n// `audio/L16;codec=pcm;rate=24000` → 24000\nfunction parseSampleRate(mime: string): number | null {\n const m = /rate=(\\d+)/i.exec(mime);\n if (!m) return null;\n const n = parseInt(m[1], 10);\n return Number.isFinite(n) && n > 0 ? n : null;\n}\n\n// Build a RIFF/WAVE header for raw PCM. Standard 16-bit, mono unless told\n// otherwise. No fancy chunks — just enough to satisfy browser audio.\nfunction pcmToWav(pcm: Buffer, sampleRate: number, channels: number, bitsPerSample: number): Buffer {\n const byteRate = (sampleRate * channels * bitsPerSample) / 8;\n const blockAlign = (channels * bitsPerSample) / 8;\n const dataSize = pcm.length;\n const header = Buffer.alloc(44);\n header.write(\"RIFF\", 0);\n header.writeUInt32LE(36 + dataSize, 4);\n header.write(\"WAVE\", 8);\n header.write(\"fmt \", 12);\n header.writeUInt32LE(16, 16); // fmt chunk size\n header.writeUInt16LE(1, 20); // PCM\n header.writeUInt16LE(channels, 22);\n header.writeUInt32LE(sampleRate, 24);\n header.writeUInt32LE(byteRate, 28);\n header.writeUInt16LE(blockAlign, 32);\n header.writeUInt16LE(bitsPerSample, 34);\n header.write(\"data\", 36);\n header.writeUInt32LE(dataSize, 40);\n return Buffer.concat([header, pcm]);\n}\n\n// Re-export the client-safe constants for callers that already import from\n// this module on the server side.\nexport { GEMINI_VOICES, GEMINI_TTS_MODELS, GEMINI_STT_MODELS } from \"./constants\";\n","// generate_voice: synthesize spoken audio from text using Gemini TTS and\n// return a /api/v1/files/ URL the assistant should embed in its reply.\n//\n// Voice/model are NOT exposed to the agent — they're locked to the\n// active agent's per-agent voice config (set by the user in AgentEditor).\n// The agent only controls *what* to say, *how* to say it (style), and\n// whether to autoplay. Multi-speaker scenes still allow per-speaker\n// voice selection because that's compositional, not preference.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport { writeBinaryFile } from \"@/lib/files\";\nimport { geminiTts, resolveGoogleApiKey } from \"@/lib/voice/gemini\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { getAgentConfig } from \"@/lib/stores/agent-configs\";\n\nconst DEFAULT_MODEL = \"gemini-2.5-flash-preview-tts\";\nconst DEFAULT_VOICE = \"Kore\";\nconst MAX_TEXT_CHARS = 5000;\n\nconst SpeakerSchema = z.object({\n name: z.string().min(1).describe(\"Speaker label that appears in the text, e.g. 'Alice'.\"),\n voice_name: z.string().min(1).describe(\"Gemini prebuilt voice for this speaker (e.g. 'Kore', 'Puck').\"),\n});\n\nfunction resolveAgentVoice(config?: RunnableConfig): { model: string; voice: string } {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return { model: DEFAULT_MODEL, voice: DEFAULT_VOICE };\n const thread = getThread(threadId);\n if (!thread?.agent_id) return { model: DEFAULT_MODEL, voice: DEFAULT_VOICE };\n const agent = getAgentConfig(thread.agent_id);\n return {\n model: agent?.voice_model?.trim() || DEFAULT_MODEL,\n voice: agent?.voice_name?.trim() || DEFAULT_VOICE,\n };\n}\n\nexport const generateVoiceTool = tool(\n async ({ text, style, speakers, autoplay }, config) => {\n const trimmed = (text ?? \"\").trim();\n if (!trimmed) throw new Error(\"text is required and must be non-empty\");\n if (trimmed.length > MAX_TEXT_CHARS) {\n throw new Error(`text exceeds ${MAX_TEXT_CHARS} character cap`);\n }\n\n const apiKey = resolveGoogleApiKey();\n if (!apiKey) {\n throw new Error(\n 'Google API key not configured. Open Integrations and set \"Google AI (Gemini + Imagen)\", or set GEMINI_API_KEY in the environment.',\n );\n }\n\n const { model, voice } = resolveAgentVoice(config);\n const speakerList = (speakers ?? [])\n .map((s) => ({ name: s.name.trim(), voiceName: s.voice_name.trim() }))\n .filter((s) => s.name && s.voiceName);\n\n const { wav } = await geminiTts({\n apiKey,\n model,\n voiceName: voice,\n text: trimmed,\n style: style?.trim() || undefined,\n speakers: speakerList.length >= 2 ? speakerList : undefined,\n });\n\n const name = `voice-${randomUUID()}.wav`;\n writeBinaryFile(name, wav);\n const baseUrl = `/api/v1/files/${name}`;\n const url = autoplay ? `${baseUrl}?autoplay=1` : baseUrl;\n\n return JSON.stringify({\n style: style ?? null,\n speakers: speakerList.length >= 2 ? speakerList : null,\n autoplay: !!autoplay,\n bytes: wav.length,\n url,\n markdown: `[\\u{1F50A} Voice clip${autoplay ? \" (auto)\" : \"\"}](${url})`,\n hint: \"Embed the `markdown` field verbatim in your reply on its own line; the chat renderer will turn that link into an inline audio player. Set autoplay=true only when the user asked you to speak (e.g. they sent voice input or explicitly asked you to talk). Do NOT wrap it in a code fence and do NOT transcribe the audio in the reply \\u2014 the player is the answer.\",\n });\n },\n {\n name: \"generate_voice\",\n description:\n \"Synthesize speech with Google's Gemini TTS using the agent's configured voice, and return a local audio URL the assistant must embed via the returned `markdown`. Use the `style` arg to steer tone/emotion (e.g. 'Say cheerfully', 'Whisper conspiratorially'). For dialogues, pass up to 2 `speakers` (with explicit voice names per speaker) and prefix each line in `text` with `Name: `. Requires the Google integration (api_key). The voice and model are picked by the user in the agent's settings and cannot be overridden here.\",\n schema: z.object({\n text: z\n .string()\n .min(1)\n .describe(\n \"The text to speak. For dialogues, write one turn per line as `Name: line` matching the `speakers` labels. Max 5000 chars.\",\n ),\n style: z\n .string()\n .optional()\n .describe(\n \"Natural-language style instruction prepended to the text, e.g. 'Say warmly and slowly', 'Whisper conspiratorially', 'In a tired, defeated voice', 'Read like a 1940s radio host'.\",\n ),\n speakers: z\n .array(SpeakerSchema)\n .min(2)\n .max(2)\n .optional()\n .describe(\n \"Optional 2-speaker setup for dialogues. When set, the agent's default voice is ignored and each line in `text` should start with one of the speaker `name`s followed by ': '. Use this only when composing a scripted dialogue with two distinct characters.\",\n ),\n autoplay: z\n .boolean()\n .optional()\n .describe(\n \"If true, the audio plays automatically when the message renders. Use this ONLY when the user clearly wants you to speak back (they sent voice input, said 'say it out loud', etc.). Default false \\u2014 user clicks play.\",\n ),\n }),\n },\n);\n\nregisterTools(\"Voice\", [generateVoiceTool]);\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport {\n createScheduledTask,\n listScheduledTasks,\n deleteScheduledTask,\n computeNextRun,\n} from \"@/lib/stores/scheduled-tasks\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { startScheduler } from \"@/lib/scheduler\";\n\nfunction safeJson(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\nfunction agentIdFromConfig(config?: RunnableConfig): string | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n const thread = getThread(threadId);\n return thread?.agent_id ?? null;\n}\n\nexport const scheduleTaskTool = tool(\n async (\n { prompt, when_iso, cron, description, silent, reaction_kind, reaction_script, reaction_script_args },\n config,\n ) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context (missing thread_id)\" });\n if (!when_iso && !cron) return JSON.stringify({ error: \"Provide either when_iso (one-shot) or cron (recurring)\" });\n if (when_iso && cron) return JSON.stringify({ error: \"Provide only one of when_iso or cron, not both\" });\n // ADR-0032 — for kind='script' the agent must supply reaction_script.\n // For kind='agent_prompt' (default) prompt is required.\n if (reaction_kind === \"script\") {\n if (!reaction_script) {\n return JSON.stringify({ error: \"reaction_kind='script' requires reaction_script\" });\n }\n } else if (!prompt) {\n return JSON.stringify({ error: \"prompt is required when reaction_kind='agent_prompt'\" });\n }\n\n try {\n const kind = cron ? \"cron\" : \"once\";\n const schedule = cron ?? when_iso!;\n // Validate by computing the first run.\n const firstRun = computeNextRun(kind, schedule);\n if (kind === \"once\" && firstRun.getTime() < Date.now() - 60_000) {\n return JSON.stringify({ error: `when_iso \"${schedule}\" is in the past` });\n }\n const row = createScheduledTask({\n agent_id: agentId,\n prompt,\n description,\n kind,\n schedule,\n silent,\n reaction_kind,\n reaction_script,\n reaction_script_args,\n });\n // Make sure the poller is awake so newly created tasks fire on time.\n startScheduler();\n return JSON.stringify({\n ok: true,\n id: row.id,\n next_run_at: row.next_run_at,\n kind,\n schedule,\n silent: row.silent === 1,\n reaction_kind: row.reaction_kind,\n reaction_script: row.reaction_script,\n });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n {\n name: \"schedule_task\",\n description:\n \"Schedule a future firing for this agent. \" +\n \"For one-shot reminders pass when_iso (ISO 8601 timestamp, e.g. '2026-05-15T15:00:00Z'). \" +\n \"For recurring tasks pass a 5-field cron expression (e.g. '0 9 * * 1-5' = weekdays 9am). \" +\n \"Use the current time from your context to convert phrases like 'in 30 minutes' or 'tomorrow at 9am' into when_iso. \" +\n \"Default reaction_kind is 'agent_prompt' — the firing sends `prompt` to the agent. \" +\n \"Set reaction_kind='script' to fire a registered reaction.* script with no LLM round-trip; \" +\n \"use list_reaction_scripts to discover names. \" +\n \"Set silent=true for background polling tasks: suppresses the task_completed notification AND instructs the \" +\n \"agent to answer NO_REPLY on firings where there is nothing material to surface (those turns are dropped). \" +\n \"Errors still notify so failures aren't hidden. Visible firings remain tagged 'scheduled' so the user can hide \" +\n \"the group with the chat filter toolbar.\",\n schema: z.object({\n prompt: z.string().optional().describe(\n \"The prompt the agent will receive when the task fires. Required when reaction_kind='agent_prompt' (the default).\",\n ),\n when_iso: z.string().optional().describe(\"ISO 8601 UTC timestamp for one-shot scheduling\"),\n cron: z.string().optional().describe(\"5-field cron expression for recurring scheduling\"),\n description: z.string().optional().describe(\"Short human-readable label for the task\"),\n silent: z.boolean().optional().describe(\n \"When true the task is muted: the task_completed notification is suppressed and the agent is instructed to \" +\n \"reply only when something material surfaces (NO_REPLY answers are dropped). Errors still notify. \" +\n \"Useful for background polling jobs (e.g. 'check inbox every 10 min').\",\n ),\n reaction_kind: z.enum([\"agent_prompt\", \"script\"]).optional().describe(\n \"ADR-0032 reaction discriminator. 'agent_prompt' (default) runs the agent with `prompt`. \" +\n \"'script' runs a registered reaction.* script with no LLM round-trip.\",\n ),\n reaction_script: z.string().optional().describe(\n \"Required when reaction_kind='script'. Must be a name returned by list_reaction_scripts (begins with 'reaction.').\",\n ),\n reaction_script_args: z.record(z.string(), z.unknown()).optional().describe(\n \"Optional JSON object of args forwarded to the reaction script. The script also receives a `task` descriptor.\",\n ),\n }),\n },\n);\n\nexport const listScheduledTasksTool = tool(\n async (_args, config) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context\" });\n const tasks = listScheduledTasks(agentId).map((t) => ({\n id: t.id,\n prompt: t.prompt,\n description: t.description,\n kind: t.kind,\n schedule: t.schedule,\n next_run_at: t.next_run_at,\n last_run_at: t.last_run_at,\n last_error: t.last_error,\n enabled: t.enabled === 1,\n silent: t.silent === 1,\n reaction_kind: t.reaction_kind,\n reaction_script: t.reaction_script,\n reaction_script_args: t.reaction_script_args ? safeJson(t.reaction_script_args) : null,\n }));\n return JSON.stringify({ tasks, count: tasks.length });\n },\n {\n name: \"list_scheduled_tasks\",\n description: \"List all scheduled tasks for the current agent.\",\n schema: z.object({}),\n },\n);\n\nexport const cancelScheduledTaskTool = tool(\n async ({ id }) => {\n const ok = deleteScheduledTask(id);\n return JSON.stringify(ok ? { ok: true, id } : { error: `Task ${id} not found` });\n },\n {\n name: \"cancel_scheduled_task\",\n description: \"Cancel a previously scheduled task by id.\",\n schema: z.object({\n id: z.string().describe(\"Task id returned by schedule_task or list_scheduled_tasks\"),\n }),\n },\n);\n\nregisterTools(\"Schedule\", [scheduleTaskTool, listScheduledTasksTool, cancelScheduledTaskTool]);\n","// Watcher tools (ADR-0027). Agent-facing CRUD for event-driven tasks.\n// Mirrors lib/tools/schedule.ts in shape so agents have a familiar\n// surface area: schedule_task ↔ schedule_watcher, list_scheduled_tasks\n// ↔ list_watchers, cancel_scheduled_task ↔ cancel_watcher.\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools, registeredTools } from \"./registry\";\nimport {\n createWatcher,\n listWatchers,\n deleteWatcher,\n} from \"@/lib/stores/watchers\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { startScheduler } from \"@/lib/scheduler\";\nimport { listReactionScripts } from \"@/lib/triggers/scripts\";\n\nfunction agentIdFromConfig(config?: RunnableConfig): string | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n const thread = getThread(threadId);\n return thread?.agent_id ?? null;\n}\n\nexport const scheduleWatcherTool = tool(\n async (\n {\n label,\n tool: toolName,\n args,\n every_seconds,\n silent,\n reaction_kind,\n reaction_prompt,\n reaction_script,\n reaction_script_args,\n },\n config,\n ) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context (missing thread_id)\" });\n // Sanity-check that the tool exists locally. We can only register\n // watchers over built-in tools — MCP / external tool surfaces aren't\n // poll-safe in the scheduler (no per-request side context).\n const target = registeredTools().find((t) => t.name === toolName);\n if (!target) {\n return JSON.stringify({\n error: `Tool \"${toolName}\" is not a built-in tool. Watchers can only poll built-in tools.`,\n });\n }\n try {\n const row = createWatcher({\n agent_id: agentId,\n label,\n tool_name: toolName,\n tool_args: args ?? {},\n interval_seconds: every_seconds,\n silent,\n reaction_kind,\n reaction_prompt,\n reaction_script,\n reaction_script_args,\n });\n startScheduler();\n return JSON.stringify({\n ok: true,\n id: row.id,\n next_run_at: row.next_run_at,\n interval_seconds: row.interval_seconds,\n silent: row.silent === 1,\n reaction_kind: row.reaction_kind,\n reaction_prompt: row.reaction_prompt,\n reaction_script: row.reaction_script,\n });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n },\n {\n name: \"schedule_watcher\",\n description:\n \"Register an event-driven watcher: poll one built-in tool every N seconds \" +\n \"and re-engage this agent only when the tool's output changes since the \" +\n \"previous poll. Unlike schedule_task, this consumes zero LLM tokens between \" +\n \"changes — the scheduler runs the tool, hashes the result (SHA-256 of the \" +\n \"stringified return value), and only fires the agent on a diff. The agent \" +\n \"receives the previous + current results as context.\\n\\n\" +\n \"WHEN TO USE (use this instead of schedule_task whenever the user wants \" +\n \"to be notified about CHANGES rather than at fixed times):\\n\" +\n \" • 'tell me when Jira issue ABC-123 changes status' → jira_get_issue\\n\" +\n \" • 'ping me when a new ticket lands in SLPV assigned to me' → jira_search with a narrow JQL\\n\" +\n \" • 'notify me when files appear in ~/Downloads' → file_list on that path\\n\" +\n \" • 'watch this Confluence page for edits' → confluence_get_page\\n\" +\n \" • 'tell me when a webpage changes' → web_fetch\\n\\n\" +\n \"This is the SUBSTITUTE for webhooks and OS-level filesystem events, which \" +\n \"Jarela does not have. Don't tell the user 'no webhook support' — propose a \" +\n \"watcher instead.\\n\\n\" +\n \"LIMITS (be honest with the user about these):\\n\" +\n \" • Built-in tools only (no MCP / external tools — scheduler runs without per-request context).\\n\" +\n \" • Minimum interval 60 seconds.\\n\" +\n \" • Diff is byte-exact SHA-256 of the tool's stringified result. If the tool \" +\n \"returns volatile fields (e.g. `updated` timestamps, view counts) the watcher \" +\n \"will fire on every poll. Mitigate by passing args that narrow the tool's \" +\n \"output (e.g. `fields` on jira_search, specific paths on file_list).\\n\" +\n \" • First poll seeds the baseline silently — the agent is NOT fired on creation.\\n\\n\" +\n \"Set silent=true to mute the watcher: suppresses the task_completed notification on firing \" +\n \"AND lets the agent reply with NO_REPLY on changes it judges immaterial. Errors still notify.\\n\\n\" +\n \"REACTION KIND (ADR-0031): two reaction modes are supported.\\n\" +\n \" • 'agent_prompt' (default): on diff, this agent runs with reaction_prompt as the \" +\n \"directive (or the default 'summarise' directive if not supplied). Costs LLM tokens.\\n\" +\n \" • 'script': on diff, a built-in reaction script (`reaction.*`) runs INSTEAD of the \" +\n \"agent. Zero LLM tokens. Use list_reaction_scripts to discover available scripts \" +\n \"(e.g. `reaction.notify` posts a UI notification with the diff). Provide \" +\n \"reaction_script and optional reaction_script_args. Cannot be combined with reaction_prompt.\",\n schema: z.object({\n label: z.string().min(1).describe(\"Short human-readable name (e.g. 'ABC-123 status')\"),\n tool: z.string().min(1).describe(\"Name of a built-in tool to poll (e.g. 'jira_get_issue')\"),\n args: z.record(z.string(), z.unknown()).optional().describe(\n \"Arguments to pass to the tool on every poll, as a JSON object\",\n ),\n every_seconds: z.number().int().min(60).describe(\n \"Polling interval in seconds. Minimum 60.\",\n ),\n silent: z.boolean().optional().describe(\n \"When true the watcher is muted: the task_completed notification is suppressed and the agent is \" +\n \"instructed to reply only when the change is material (NO_REPLY firings are dropped). Errors still notify. \" +\n \"Visible firings remain tagged 'watcher'.\",\n ),\n reaction_kind: z.enum([\"agent_prompt\", \"script\"]).optional().describe(\n \"Reaction mode (ADR-0031). 'agent_prompt' (default) runs this agent on each diff; \" +\n \"'script' runs a built-in reaction.* script with no LLM round-trip.\",\n ),\n reaction_prompt: z.string().max(4000).optional().describe(\n \"Only valid when reaction_kind='agent_prompt' (or unset). Optional instruction for \" +\n \"what the agent should do on each detected change. Replaces the default 'summarise \" +\n \"the diff' directive. The previous + current tool results are still appended as \" +\n \"context, so the prompt should describe the REACTION (e.g. 'open a Jira ticket \" +\n \"against the broken dashboard', 'message me in plain English only if the price \" +\n \"dropped >5%'). Max 4000 characters.\",\n ),\n reaction_script: z.string().optional().describe(\n \"Required when reaction_kind='script'. Name of a registered reaction script \" +\n \"(must start with 'reaction.'). Use list_reaction_scripts to discover.\",\n ),\n reaction_script_args: z.record(z.string(), z.unknown()).optional().describe(\n \"Optional JSON object forwarded to the reaction script alongside the diff context \" +\n \"({watcher, previous, current}). Schema is script-specific.\",\n ),\n }),\n },\n);\n\nexport const listReactionScriptsTool = tool(\n async () => {\n const scripts = listReactionScripts();\n return JSON.stringify({ scripts, count: scripts.length });\n },\n {\n name: \"list_reaction_scripts\",\n description:\n \"List the names of built-in reaction scripts available to schedule_watcher AND \" +\n \"schedule_task when reaction_kind='script'. Reaction scripts run with NO LLM round-trip \" +\n \"on a firing. Watchers auto-merge {watcher, previous, current} into the script args; \" +\n \"scheduled tasks auto-merge a `task` descriptor (no diff context). Names are always \" +\n \"prefixed with `reaction.` (e.g. `reaction.notify`). Internal built-in scripts outside \" +\n \"the `reaction.` namespace (for example documents.reindex_local_file) are intentionally \" +\n \"excluded from this list.\",\n schema: z.object({}),\n },\n);\n\nexport const listWatchersTool = tool(\n async (_args, config) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"No agent context\" });\n const watchers = listWatchers(agentId).map((w) => ({\n id: w.id,\n label: w.label,\n tool: w.tool_name,\n args: safeParse(w.tool_args),\n interval_seconds: w.interval_seconds,\n next_run_at: w.next_run_at,\n last_run_at: w.last_run_at,\n last_fired_at: w.last_fired_at,\n last_error: w.last_error,\n enabled: w.enabled === 1,\n silent: w.silent === 1,\n reaction_kind: w.reaction_kind,\n reaction_prompt: w.reaction_prompt,\n reaction_script: w.reaction_script,\n reaction_script_args: w.reaction_script_args ? safeParse(w.reaction_script_args) : null,\n }));\n return JSON.stringify({ watchers, count: watchers.length });\n },\n {\n name: \"list_watchers\",\n description: \"List all event-driven watchers registered for the current agent.\",\n schema: z.object({}),\n },\n);\n\nexport const cancelWatcherTool = tool(\n async ({ id }) => {\n const ok = deleteWatcher(id);\n return JSON.stringify(ok ? { ok: true, id } : { error: `Watcher ${id} not found` });\n },\n {\n name: \"cancel_watcher\",\n description: \"Cancel a previously registered watcher by id.\",\n schema: z.object({\n id: z.string().describe(\"Watcher id returned by schedule_watcher or list_watchers\"),\n }),\n },\n);\n\nfunction safeParse(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\nregisterTools(\"Schedule\", [\n scheduleWatcherTool,\n listWatchersTool,\n cancelWatcherTool,\n listReactionScriptsTool,\n]);\n","import { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\n\nconst now = () => new Date().toISOString();\n\nexport type ActionKind =\n | \"install_mcp\"\n | \"toggle_mcp\"\n | \"update_agent_tools\"\n | \"update_agent\"\n // Added by ADR-0010 (agent-led setup).\n | \"start_oauth\"\n | \"set_provider_key\"\n | \"enable_integration\"\n // Added by ADR-0036 (agent-driven harness edits).\n | \"upsert_harness\";\n\nexport type ActionStatus = \"pending\" | \"approved\" | \"denied\" | \"failed\";\n\nexport interface PendingActionRow {\n id: string;\n agent_id: string;\n kind: ActionKind;\n payload: string; // JSON\n reason: string | null;\n status: ActionStatus;\n result: string | null; // JSON or error message\n created_at: string;\n decided_at: string | null;\n}\n\nexport interface CreatePendingActionInput {\n agent_id: string;\n kind: ActionKind;\n payload: unknown;\n reason?: string;\n}\n\nexport function createPendingAction(input: CreatePendingActionInput): PendingActionRow {\n const id = randomUUID();\n const t = now();\n getDb()\n .prepare(\n `INSERT INTO pending_actions (id, agent_id, kind, payload, reason, status, result, created_at, decided_at)\n VALUES (?, ?, ?, ?, ?, 'pending', NULL, ?, NULL)`,\n )\n .run(id, input.agent_id, input.kind, JSON.stringify(input.payload), input.reason ?? null, t);\n return getPendingAction(id)!;\n}\n\nexport function getPendingAction(id: string): PendingActionRow | null {\n return (getDb()\n .prepare(\"SELECT * FROM pending_actions WHERE id=?\")\n .get(id) as unknown as PendingActionRow) ?? null;\n}\n\nexport function listPendingActions(opts: { status?: ActionStatus; agent_id?: string } = {}): PendingActionRow[] {\n let sql = \"SELECT * FROM pending_actions WHERE 1=1\";\n const params: string[] = [];\n if (opts.status) { sql += \" AND status=?\"; params.push(opts.status); }\n if (opts.agent_id) { sql += \" AND agent_id=?\"; params.push(opts.agent_id); }\n sql += \" ORDER BY created_at DESC LIMIT 200\";\n return getDb().prepare(sql).all(...params) as unknown as PendingActionRow[];\n}\n\nexport function setActionStatus(\n id: string,\n status: ActionStatus,\n result: unknown,\n): PendingActionRow | null {\n getDb()\n .prepare(\"UPDATE pending_actions SET status=?, result=?, decided_at=? WHERE id=?\")\n .run(status, result === undefined ? null : JSON.stringify(result), now(), id);\n return getPendingAction(id);\n}\n","import { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { registerTools } from \"./registry\";\nimport { createPendingAction, getPendingAction } from \"@/lib/stores/pending-actions\";\nimport { getThread } from \"@/lib/stores/threads\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\n\nfunction agentIdFromConfig(config?: RunnableConfig): string | null {\n const threadId = config?.configurable?.thread_id as string | undefined;\n if (!threadId) return null;\n return getThread(threadId)?.agent_id ?? null;\n}\n\nexport const proposeConfigChangeTool = tool(\n async ({ kind, payload, reason }, config) => {\n const agentId = agentIdFromConfig(config);\n if (!agentId) return JSON.stringify({ error: \"no agent context\" });\n const row = createPendingAction({ agent_id: agentId, kind, payload, reason });\n // Surface as a browser notification so the user notices even if not on this agent.\n publishNotification({\n type: \"run_completed\", // reuse channel; UI can branch on preview text\n thread_id: \"\",\n agent_id: agentId,\n status: \"done\",\n preview: `🛠️ Proposed config change (${kind}) — awaiting your approval`,\n ts: Date.now(),\n });\n return JSON.stringify({\n proposal_id: row.id,\n status: \"pending\",\n message:\n \"Proposal queued for the user's approval. Tell the user briefly what you proposed and that \" +\n \"they need to approve it in the chat. Do not retry; check status later with check_proposal.\",\n });\n },\n {\n name: \"propose_config_change\",\n description:\n \"Propose a configuration change that requires user approval. Use this when you'd benefit from \" +\n \"installing/toggling an MCP server, or modifying agent settings (tool allowlist, identity, instructions, history window). \" +\n \"The proposal is queued and shown to the user; they explicitly approve or deny. \" +\n \"Don't propose changes the user didn't ask for — only when the current task clearly needs it.\",\n schema: z.object({\n kind: z\n .enum([\n \"install_mcp\",\n \"toggle_mcp\",\n \"update_agent_tools\",\n \"update_agent\",\n \"start_oauth\",\n \"set_provider_key\",\n \"enable_integration\",\n \"upsert_harness\",\n ])\n .describe(\"Type of change being proposed\"),\n payload: z.record(z.string(), z.unknown())\n .describe(\n \"Parameters for the change. NEVER put secrets, API keys, OAuth tokens, \" +\n \"or passwords in this object — those are collected by the approval UI \" +\n \"directly. Examples by kind:\\n\" +\n \"- install_mcp: { registry_id: 'github', variables: { GITHUB_TOKEN: 'asks-user-for-it' } } \" +\n \" OR { name, transport, spec }\\n\" +\n \"- toggle_mcp: { name: 'github', enabled: true }\\n\" +\n \"- update_agent_tools: { agent_id: '<this-agent>', tools: ['web_search', 'memory_*'] }\\n\" +\n \"- update_agent: { agent_id, identity?, instructions?, history_limit?, history_window_hours?, harness_id? } \" +\n \" — harness_id accepts an existing harness id ('builtin:default' or 'custom:<uuid>'), or null to inherit the global default\\n\" +\n \"- start_oauth: { integration_id: 'gmail' } — only after enable_integration saved client_id/secret\\n\" +\n \"- set_provider_key: { name: 'anthropic-default', provider: 'anthropic', model_id: 'claude-opus-4-7', is_default?: true } \" +\n \" — the user pastes the API key into the approval modal; do NOT include it here\\n\" +\n \"- enable_integration: { id: 'gmail' } — the user fills credentials in the approval modal\\n\" +\n \"- upsert_harness: { id?: 'custom:<uuid>', name, description?, sections: { capabilities?: {enabled,body}, plan_first?: {enabled,body}, presentation?: {enabled,body}, citation?: {enabled,body}, self_config?: {enabled,body} } } \" +\n \" — omit `id` to create; pass an existing custom:* id to edit. Built-in harnesses ('builtin:*') are read-only and rejected.\"\n ),\n reason: z.string().describe(\"Short human-readable reason shown to the user (≤100 chars)\"),\n }),\n },\n);\n\nexport const checkProposalTool = tool(\n async ({ proposal_id }) => {\n const row = getPendingAction(proposal_id);\n if (!row) return JSON.stringify({ error: `proposal ${proposal_id} not found` });\n return JSON.stringify({\n id: row.id,\n kind: row.kind,\n status: row.status,\n result: row.result ? safeParse(row.result) : null,\n created_at: row.created_at,\n decided_at: row.decided_at,\n });\n },\n {\n name: \"check_proposal\",\n description: \"Check the status of a previously-submitted config-change proposal by its id.\",\n schema: z.object({\n proposal_id: z.string(),\n }),\n },\n);\n\nfunction safeParse(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\nregisterTools(\"Config\", [proposeConfigChangeTool, checkProposalTool]);\n","import type { IntegrationManifest } from \"@/lib/integrations/manifest\";\n\nexport const atlassianManifest: IntegrationManifest = {\n id: \"atlassian\",\n name: \"Atlassian (Jira + Confluence)\",\n summary:\n \"Lets the agent search and modify Jira issues, read and post comments, and \" +\n \"read Confluence pages. Also powers smart-indexed document RAG over selected \" +\n \"Jira projects/JQL and Confluence spaces/CQL via the documents_add_remote_source \" +\n \"tool (ADR-0026). Authenticates with an Atlassian API token tied to your account email.\",\n category: \"issue-tracker\",\n prerequisites: [\n {\n check: \"credentials\",\n detail:\n \"An Atlassian Cloud account with access to the site (e.g. https://your-team.atlassian.net) \" +\n \"and permission to view the projects/spaces you want the agent to read.\",\n },\n {\n check: \"credentials\",\n detail:\n \"An API token created at id.atlassian.com → Security → API tokens. \" +\n \"The token is bound to your account email — you'll provide both.\",\n docs_url: \"https://id.atlassian.com/manage-profile/security/api-tokens\",\n },\n ],\n steps: [\n {\n id: \"create-token\",\n title: \"Create an Atlassian API token\",\n description:\n \"Open id.atlassian.com → Security → API tokens, click Create API token, give it \" +\n \"a label like 'Jarela', and copy the token immediately — Atlassian only shows it once.\",\n docs_url: \"https://id.atlassian.com/manage-profile/security/api-tokens\",\n },\n {\n id: \"save-credentials\",\n title: \"Save the credentials in Jarela\",\n description:\n \"Propose enabling the integration. The user will be asked for the site URL, \" +\n \"their account email, and the API token. The token is stored encrypted at rest.\",\n proposes: \"enable_integration\",\n },\n {\n id: \"configure-rag\",\n title: \"Optional: scope a Jira/Confluence document source for semantic search (ADR-0026)\",\n description:\n \"After credentials are saved, suggest adding a scoped RAG source so the agent \" +\n \"can answer questions from Atlassian content without reading everything. Use \" +\n \"documents_add_remote_source with one of: kind='confluence_space' \" +\n \"(config.space_key='ENG'), kind='jira_project' (config.project_key='ABC', \" +\n \"optional config.recency_days=90), kind='confluence_cql' (config.cql='label = \\\"runbook\\\"'), \" +\n \"or kind='jira_jql' (config.jql='project = ABC AND status != Done'). Indexing runs \" +\n \"incrementally on the existing scheduler sweep; results are searchable via documents_search.\",\n },\n ],\n troubleshooting: [\n {\n when: \"tool returns 401 Unauthorized\",\n say:\n \"The API token or email is wrong, or the token was revoked. Ask the user to regenerate \" +\n \"the token at id.atlassian.com → Security → API tokens and re-enter both the email and the new token.\",\n },\n {\n when: \"tool returns 403 Forbidden on a specific issue or page\",\n say:\n \"The account doesn't have permission for that resource. Either the project/space hasn't been \" +\n \"shared with this user, or the issue is restricted. Ask the user to verify in the Atlassian web UI.\",\n },\n {\n when: \"tool returns 404 on a Confluence page id\",\n say:\n \"Confluence page ids change when pages are moved between spaces. Ask the user to re-share \" +\n \"the page URL — the integration will resolve it to the current id.\",\n },\n ],\n};\n","import type { IntegrationManifest } from \"@/lib/integrations/manifest\";\n\nexport const githubManifest: IntegrationManifest = {\n id: \"github\",\n name: \"GitHub\",\n summary:\n \"Lets the agent search, read, create, comment on, open/merge, and review GitHub issues \" +\n \"and pull requests, list branches, read repo files, and search code via the REST API. \" +\n \"Authenticates with a Personal Access Token.\",\n category: \"issue-tracker\",\n prerequisites: [\n {\n check: \"credentials\",\n detail:\n \"A GitHub account with access to the repos you want the agent to read or write. \" +\n \"For org repos, the org must allow PAT access (Settings → Third-party Access → Personal access tokens).\",\n },\n {\n check: \"credentials\",\n detail:\n \"A Personal Access Token (classic or fine-grained) created at github.com/settings/tokens. \" +\n \"Required scopes: `repo` (or `public_repo` for public-only), plus `read:org` if you target org repos.\",\n docs_url: \"https://github.com/settings/tokens\",\n },\n ],\n steps: [\n {\n id: \"create-pat\",\n title: \"Create a GitHub Personal Access Token\",\n description:\n \"Open github.com/settings/tokens → Generate new token. For classic tokens, tick `repo` (or \" +\n \"`public_repo` for public repos only) and `read:org`. For fine-grained tokens, pick the repos and \" +\n \"grant Issues: Read+Write and Pull requests: Read+Write. Copy the token immediately — GitHub only \" +\n \"shows it once.\",\n docs_url: \"https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens\",\n },\n {\n id: \"save-credentials\",\n title: \"Save the token in Jarela\",\n description:\n \"Propose enabling the integration. The user will be asked for the token; it is stored encrypted at rest.\",\n proposes: \"enable_integration\",\n },\n ],\n troubleshooting: [\n {\n when: \"tool returns 401 Unauthorized\",\n say:\n \"The token is wrong, expired, or was revoked. Ask the user to regenerate it at \" +\n \"github.com/settings/tokens and re-enter it in the Integrations panel.\",\n },\n {\n when: \"tool returns 403 with rate-limit message\",\n say:\n \"GitHub rate-limited this token. Wait until the reset window indicated in the response, or ask the \" +\n \"user to switch to a token with higher limits (authenticated requests get 5000/hr).\",\n },\n {\n when: \"tool returns 403 'Resource not accessible by personal access token'\",\n say:\n \"Fine-grained tokens are scoped to specific repos AND specific permissions. Either widen the token's \" +\n \"repo selection, grant the missing permission (Issues / Pull requests: Read+Write), or fall back to a \" +\n \"classic token with the `repo` scope.\",\n },\n {\n when: \"tool returns 404 on a repo the user can see in the browser\",\n say:\n \"The token can't see the repo. For org-owned private repos, the org must allow PAT access \" +\n \"(org Settings → Third-party Access). Ask the user to verify the org's PAT policy.\",\n },\n ],\n};\n","import type { IntegrationManifest } from \"@/lib/integrations/manifest\";\n\nexport const gmailManifest: IntegrationManifest = {\n id: \"gmail\",\n name: \"Gmail + Google Calendar\",\n summary:\n \"Lets the agent search/read mail, create drafts (never send), label/archive, \" +\n \"and read or modify calendar events. Drafts-only is a deliberate safety choice — \" +\n \"this integration intentionally cannot send mail on the user's behalf.\",\n category: \"mail\",\n prerequisites: [\n {\n check: \"oauth_app\",\n detail:\n \"A Google Cloud project with the Gmail API and Calendar API enabled, plus a \" +\n \"Web Application OAuth client. The client_id and client_secret are required \" +\n \"BEFORE the agent can propose start_oauth.\",\n docs_url: \"https://console.cloud.google.com/apis/credentials\",\n },\n {\n check: \"custom\",\n detail:\n \"The OAuth client's authorized redirect URI must match where Jarela is reachable. \" +\n \"For local use that's typically http://localhost:4312/api/v1/integrations/gmail/oauth/callback.\",\n },\n ],\n steps: [\n {\n id: \"create-cloud-project\",\n title: \"Create or pick a Google Cloud project\",\n description:\n \"Open console.cloud.google.com, create a new project (or pick an existing one). \" +\n \"This is purely an instructional step — Jarela can't create the project for the user.\",\n docs_url: \"https://console.cloud.google.com/projectcreate\",\n },\n {\n id: \"enable-apis\",\n title: \"Enable the Gmail and Calendar APIs\",\n description:\n \"In the project, open APIs & Services → Library, search for Gmail API and Google Calendar API, \" +\n \"and enable both. The Calendar scope is required for calendarList.list to return calendars.\",\n },\n {\n id: \"create-oauth-client\",\n title: \"Create an OAuth 2.0 Client ID\",\n description:\n \"APIs & Services → Credentials → Create Credentials → OAuth client ID → Web application. \" +\n \"Add the redirect URI from the prerequisite above. Copy client_id and client_secret.\",\n docs_url: \"https://console.cloud.google.com/apis/credentials\",\n },\n {\n id: \"save-client\",\n title: \"Save the OAuth client in Jarela\",\n description:\n \"Propose enabling the integration. The user will paste client_id and client_secret \" +\n \"into the secure form. Both are stored encrypted at rest.\",\n proposes: \"enable_integration\",\n },\n {\n id: \"authorize\",\n title: \"Run the OAuth consent flow\",\n description:\n \"Once client_id and client_secret are saved, propose start_oauth. The user approves, a \" +\n \"Google consent screen opens in a new tab, and on success a refresh_token is captured \" +\n \"automatically. The agent can then use gmail_* and calendar_* tools.\",\n proposes: \"start_oauth\",\n verify: { tool: \"gmail_list_labels\" },\n },\n ],\n troubleshooting: [\n {\n when: \"OAuth redirect returns 'redirect_uri_mismatch'\",\n say:\n \"The redirect URI in the Google Cloud OAuth client doesn't match what Jarela sent. \" +\n \"Open the OAuth client in Cloud Console → Authorized redirect URIs, and add the URI exactly \" +\n \"as shown in the error page (including the port).\",\n },\n {\n when: \"OAuth consent screen says 'access_denied'\",\n say:\n \"The Google project is in 'Testing' mode and the user's email isn't on the allowed test users \" +\n \"list. Either add their email under OAuth consent screen → Test users, or publish the app.\",\n },\n {\n when: \"tool returns 403 invalid_scope or insufficient_permissions for calendar\",\n say:\n \"An older Gmail-only consent didn't include the Calendar scopes. Propose start_oauth again — \" +\n \"the new consent will request both Gmail and Calendar scopes and overwrite the refresh token.\",\n },\n {\n when: \"tool returns 401 invalid_grant\",\n say:\n \"The refresh token was revoked (often because the OAuth client_secret was rotated, or the user \" +\n \"revoked access at myaccount.google.com). Propose start_oauth to re-authorize.\",\n },\n ],\n};\n","import type { IntegrationManifest } from \"@/lib/integrations/manifest\";\n\nexport const googleManifest: IntegrationManifest = {\n id: \"google\",\n name: \"Google AI (Gemini + Imagen)\",\n summary:\n \"Powers the generate_image tool via Google's Gemini and Imagen models. \" +\n \"Independent from the Gmail integration — this is just an API key, no OAuth.\",\n category: \"llm\",\n prerequisites: [\n {\n check: \"credentials\",\n detail:\n \"A Google AI Studio API key. Free tier is sufficient for most use; \" +\n \"Imagen requires a paid project.\",\n docs_url: \"https://aistudio.google.com/apikey\",\n },\n ],\n steps: [\n {\n id: \"get-api-key\",\n title: \"Create an API key in Google AI Studio\",\n description:\n \"Open aistudio.google.com/apikey, sign in, click Create API key, \" +\n \"and copy the value (starts with AIza). Keep the tab open until it's saved in Jarela.\",\n docs_url: \"https://aistudio.google.com/apikey\",\n },\n {\n id: \"save-key\",\n title: \"Save the key in Jarela\",\n description:\n \"Propose enabling the integration. The user will paste the API key into \" +\n \"a secure field; it's stored encrypted at rest and never sent to the model in plaintext.\",\n proposes: \"enable_integration\",\n },\n ],\n troubleshooting: [\n {\n when: \"generate_image returns 'API key not valid'\",\n say:\n \"The Google AI key is wrong or revoked. Ask the user to regenerate it at \" +\n \"aistudio.google.com/apikey and re-save in the Integrations panel.\",\n },\n {\n when: \"generate_image returns 'Imagen requires a paid plan'\",\n say:\n \"The free Gemini key doesn't include Imagen. Ask the user to enable billing on the \" +\n \"Google Cloud project linked to the AI Studio key, or pick a Gemini-only image variant.\",\n },\n ],\n};\n","import type { IntegrationManifest } from \"@/lib/integrations/manifest\";\n\nexport const outlookManifest: IntegrationManifest = {\n id: \"outlook\",\n name: \"Outlook + Microsoft Calendar\",\n summary:\n \"Lets the agent search/read mail, create drafts (never send), move messages between \" +\n \"folders, and read or modify Microsoft 365 calendar events. Drafts-only by design — \" +\n \"the integration intentionally cannot send mail on the user's behalf.\",\n category: \"mail\",\n prerequisites: [\n {\n check: \"oauth_app\",\n detail:\n \"An Azure app registration with delegated Mail.ReadWrite, Calendars.ReadWrite, \" +\n \"User.Read, and offline_access permissions. Both personal Microsoft accounts and \" +\n \"M365 work/school accounts are supported via the 'common' tenant.\",\n docs_url: \"https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade\",\n },\n {\n check: \"custom\",\n detail:\n \"The Azure app's redirect URI must be of type 'Web' and match where Jarela is reachable. \" +\n \"For local use that's typically http://localhost:4312/api/v1/integrations/outlook/oauth/callback.\",\n },\n ],\n steps: [\n {\n id: \"register-app\",\n title: \"Register an Azure application\",\n description:\n \"Open portal.azure.com → Microsoft Entra ID → App registrations → New registration. \" +\n \"Name it (e.g. 'Jarela'), pick 'Accounts in any organizational directory and personal Microsoft accounts', \" +\n \"and set the redirect URI of type Web to match the prerequisite above.\",\n docs_url: \"https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade\",\n },\n {\n id: \"create-secret\",\n title: \"Create a client secret\",\n description:\n \"Inside the app registration, open Certificates & secrets → Client secrets → New client secret. \" +\n \"Copy the Value (not the Secret ID) immediately — Azure only shows it once.\",\n },\n {\n id: \"grant-scopes\",\n title: \"Grant the required Graph permissions\",\n description:\n \"API permissions → Add a permission → Microsoft Graph → Delegated permissions. \" +\n \"Add Mail.ReadWrite, Calendars.ReadWrite, User.Read, offline_access. \" +\n \"No admin consent required for personal accounts; M365 tenants may need an admin to consent.\",\n },\n {\n id: \"save-client\",\n title: \"Save the OAuth client in Jarela\",\n description:\n \"Propose enabling the integration. The user pastes Application (client) ID and the client secret value. \" +\n \"Both are stored encrypted at rest.\",\n proposes: \"enable_integration\",\n },\n {\n id: \"authorize\",\n title: \"Run the OAuth consent flow\",\n description:\n \"Once client credentials are saved, propose start_oauth. The user approves, Microsoft's consent \" +\n \"screen opens in a new tab, and a refresh_token is captured on success.\",\n proposes: \"start_oauth\",\n verify: { tool: \"outlook_list_folders\" },\n },\n ],\n troubleshooting: [\n {\n when: \"consent fails with AADSTS50011 redirect_uri mismatch\",\n say:\n \"The redirect URI in the Azure app registration doesn't match. Open the app → Authentication, \" +\n \"and verify the Web redirect URI matches exactly (scheme, host, port, path).\",\n },\n {\n when: \"token endpoint returns AADSTS900144 'scope' missing\",\n say:\n \"Microsoft's v2 endpoint requires the scope parameter on every token call. This is a Jarela bug \" +\n \"— file an issue. Workaround: re-run start_oauth, the consent flow includes the scope.\",\n },\n {\n when: \"tool returns 403 InsufficientScope\",\n say:\n \"The user consented to fewer scopes than the integration needs. Propose start_oauth — the \" +\n \"consent screen will re-prompt for the missing permission.\",\n },\n {\n when: \"M365 work account fails with 'admin consent required'\",\n say:\n \"The tenant admin has restricted user consent. Either ask the admin to grant tenant-wide \" +\n \"consent for the Jarela app registration, or use a personal Microsoft account instead.\",\n },\n ],\n};\n","// Integration manifest contract — see ADR-0010.\n//\n// Every directory under lib/integrations/ must export a `manifest` from\n// `manifest.ts` matching this schema. The manifest is the single source of\n// truth for both the agent's setup guidance and the static Integrations\n// panel. A lint check (scripts/check-integration-manifests.mjs) enforces\n// presence at build time.\n\nimport { z } from \"zod\";\nimport type { ActionKind } from \"@/lib/stores/pending-actions\";\n\nexport const PrerequisiteSchema = z.object({\n check: z.enum([\"provider_key\", \"oauth_app\", \"env\", \"credentials\", \"custom\"]),\n detail: z.string().min(1),\n docs_url: z.string().url().optional(),\n});\n\nexport const SetupStepSchema = z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n description: z.string().min(1),\n // Which propose_config_change kind (if any) implements this step.\n // When unset, the step is purely instructional (e.g. \"create an Azure app\n // registration in the Azure portal\" — no Jarela-side mutation).\n proposes: z\n .enum([\n \"install_mcp\",\n \"toggle_mcp\",\n \"update_agent_tools\",\n \"update_agent\",\n \"start_oauth\",\n \"set_provider_key\",\n \"enable_integration\",\n ])\n .optional(),\n // Optional self-test the agent can run after the step completes.\n verify: z\n .object({\n tool: z.string(),\n args: z.record(z.string(), z.unknown()).optional(),\n })\n .optional(),\n docs_url: z.string().url().optional(),\n});\n\nexport const TroubleshootingSchema = z.object({\n when: z.string().min(1),\n say: z.string().min(1),\n});\n\nexport const IntegrationManifestSchema = z.object({\n id: z\n .string()\n .min(1)\n .regex(/^[a-z][a-z0-9-]*$/, \"id must be lowercase kebab-case\"),\n name: z.string().min(1),\n summary: z.string().min(1),\n category: z.enum([\"llm\", \"mail\", \"calendar\", \"issue-tracker\", \"chat\", \"infrastructure\", \"other\"]),\n prerequisites: z.array(PrerequisiteSchema),\n steps: z.array(SetupStepSchema).min(1),\n troubleshooting: z.array(TroubleshootingSchema),\n});\n\nexport type Prerequisite = z.infer<typeof PrerequisiteSchema>;\nexport type SetupStep = z.infer<typeof SetupStepSchema>;\nexport type Troubleshooting = z.infer<typeof TroubleshootingSchema>;\n\nexport interface IntegrationManifest {\n id: string;\n name: string;\n summary: string;\n category: \"llm\" | \"mail\" | \"calendar\" | \"issue-tracker\" | \"chat\" | \"infrastructure\" | \"other\";\n prerequisites: Prerequisite[];\n steps: Array<Omit<SetupStep, \"proposes\"> & { proposes?: ActionKind }>;\n troubleshooting: Troubleshooting[];\n}\n\nexport function validateManifest(m: unknown): IntegrationManifest {\n return IntegrationManifestSchema.parse(m) as IntegrationManifest;\n}\n","// Static registry of all integration manifests. New integrations must be\n// added here AND ship a manifest.ts; the lint check\n// (scripts/check-integration-manifests.mjs) verifies the two stay in sync.\n//\n// We use static imports rather than a dynamic `import.meta.glob`-style\n// loader because the Next.js bundler needs the imports visible at build\n// time (the agent tools that read manifests run server-side in the same\n// runtime as the Next API routes).\n\nimport { atlassianManifest } from \"@/lib/integrations/atlassian/manifest\";\nimport { githubManifest } from \"@/lib/integrations/github/manifest\";\nimport { gmailManifest } from \"@/lib/integrations/gmail/manifest\";\nimport { googleManifest } from \"@/lib/integrations/google/manifest\";\nimport { outlookManifest } from \"@/lib/integrations/outlook/manifest\";\nimport type { IntegrationManifest } from \"@/lib/integrations/manifest\";\nimport { validateManifest } from \"@/lib/integrations/manifest\";\n\nconst RAW: IntegrationManifest[] = [\n atlassianManifest,\n githubManifest,\n gmailManifest,\n googleManifest,\n outlookManifest,\n];\n\n// Validate at module load. A bad manifest is a build-time bug we want to\n// surface immediately, not a runtime surprise the agent papers over.\nconst MANIFESTS: IntegrationManifest[] = RAW.map((m) => validateManifest(m));\n\nexport function listManifests(): IntegrationManifest[] {\n return MANIFESTS.slice();\n}\n\nexport function getManifest(id: string): IntegrationManifest | null {\n return MANIFESTS.find((m) => m.id === id) ?? null;\n}\n\nexport function manifestIds(): string[] {\n return MANIFESTS.map((m) => m.id).sort();\n}\n","// Read-only tools that expose integration manifests to the agent. See\n// ADR-0010 — these power the \"user asks how to connect X → agent narrates\n// the steps and proposes actions\" loop without giving the agent any new\n// privileges.\n\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getManifest, listManifests } from \"@/lib/integrations/registry\";\nimport { registerTools } from \"./registry\";\nimport { getIntegrationStatus, isKnownIntegration } from \"@/lib/stores/integrations\";\n\nfunction manifestStatus(id: string): \"configured\" | \"not_configured\" | \"no_credentials_schema\" {\n if (!isKnownIntegration(id)) return \"no_credentials_schema\";\n return getIntegrationStatus(id)?.configured ? \"configured\" : \"not_configured\";\n}\n\nexport const listIntegrationsTool = tool(\n async () => {\n const summary = listManifests().map((m) => ({\n id: m.id,\n name: m.name,\n category: m.category,\n summary: m.summary,\n status: manifestStatus(m.id),\n }));\n return JSON.stringify({ integrations: summary });\n },\n {\n name: \"list_integrations\",\n description:\n \"List every integration Jarela knows how to set up, with a one-line summary and \" +\n \"current configuration status. Read-only. Use this when the user asks 'what can I connect?' \" +\n \"or before proposing enable_integration, so you know what's available and whether it's \" +\n \"already configured.\",\n schema: z.object({}),\n },\n);\n\nexport const getIntegrationSetupTool = tool(\n async ({ id }) => {\n const manifest = getManifest(id);\n if (!manifest) {\n return JSON.stringify({\n error: `unknown integration \"${id}\". Call list_integrations to see available ids.`,\n });\n }\n return JSON.stringify({\n id: manifest.id,\n name: manifest.name,\n summary: manifest.summary,\n category: manifest.category,\n status: manifestStatus(manifest.id),\n prerequisites: manifest.prerequisites,\n steps: manifest.steps,\n troubleshooting: manifest.troubleshooting,\n notes: [\n \"Walk the user through `prerequisites` first; some require browser actions outside Jarela.\",\n \"For each step that has a `proposes` field, call propose_config_change with that kind when ready.\",\n \"When a step has a `verify.tool`, call that tool after applying the step to confirm success.\",\n ],\n });\n },\n {\n name: \"get_integration_setup\",\n description:\n \"Return the full setup manifest for one integration — prerequisites, ordered steps, and \" +\n \"troubleshooting hints. Read-only. Use this before walking the user through a setup, or \" +\n \"when a tool fails and you need the integration-specific recovery hint.\",\n schema: z.object({\n id: z.string().describe(\"Integration id from list_integrations (e.g. 'gmail', 'atlassian')\"),\n }),\n },\n);\n\nregisterTools(\"Config\", [listIntegrationsTool, getIntegrationSetupTool]);\n","/**\n * Native Jira Align tools — direct REST API calls.\n *\n * Sibling to `atlassian.ts` (Jira/Confluence). Jira Align is a separate\n * Atlassian product with its own API surface, hostname, and auth model:\n * - URL: https://<instance>.jiraalign.com\n * - Auth: Bearer token (NOT email + API token like Jira Cloud)\n * - API: /rest/align/api/2/<collection> per-type collections, no /items\n *\n * IMPORTANT — v2 has no generic `/items` endpoint. Work items are split by\n * type, each at its own collection: /epics, /capabilities, /features,\n * /stories, /themes, /tasks, /defects. Every tool here therefore requires\n * a `type` argument so we can route to the right collection. See ADR-0021\n * for why; ADR-0019 (which assumed /items) is superseded.\n *\n * Each CRUD operation is a separate tool so users can flip read-only /\n * write / delete permissions independently in the AgentEditor — see\n * ToolPolicy in lib/agents/base.ts. To revoke writes, uncheck the\n * `jira_align_create_*` / `jira_align_update_*` / `jira_align_delete_*`\n * tools while leaving the read tools enabled.\n *\n * Auth resolution (priority order):\n * 1. Env: JIRA_ALIGN_URL, JIRA_ALIGN_TOKEN\n * 2. Memory store: namespace=\"integrations\", key=\"jira_align\",\n * value={ url, api_token } (set via the Integrations panel UI)\n *\n * Field shapes still vary by instance (custom fields, workflow names,\n * type-specific attributes). Verify exact field names against your\n * instance's Swagger at `<instance>.jiraalign.com/rest/align/api/docs/`.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\nimport { registerTools } from \"./registry\";\n\nexport interface JiraAlignAuth {\n url: string; // e.g. \"https://acme.jiraalign.com\"\n apiToken: string;\n}\n\n// Logical type → URL collection segment. JA pluralization isn't a regex —\n// \"capability\" → \"capabilities\", \"story\" → \"stories\" — so map explicitly\n// and reject unknown types up front rather than constructing dead URLs.\nconst TYPE_TO_COLLECTION: Record<string, string> = {\n epic: \"epics\",\n capability: \"capabilities\",\n feature: \"features\",\n story: \"stories\",\n theme: \"themes\",\n task: \"tasks\",\n defect: \"defects\",\n objective: \"objectives\",\n};\nconst KNOWN_TYPES = Object.keys(TYPE_TO_COLLECTION) as ReadonlyArray<keyof typeof TYPE_TO_COLLECTION>;\nconst TYPE_ENUM = z.enum(KNOWN_TYPES as [string, ...string[]]);\n\nfunction collectionFor(type: string): string | { error: string } {\n const seg = TYPE_TO_COLLECTION[type.toLowerCase()];\n if (!seg) {\n return {\n error: `unknown Jira Align work-item type \"${type}\". Expected one of: ${KNOWN_TYPES.join(\", \")}.`,\n };\n }\n return seg;\n}\n\nexport function _resolveJiraAlignAuth(): JiraAlignAuth | { error: string } {\n return resolveAuth();\n}\n\nfunction resolveAuth(): JiraAlignAuth | { error: string } {\n const envUrl = process.env.JIRA_ALIGN_URL;\n const envToken = process.env.JIRA_ALIGN_TOKEN;\n if (envUrl && envToken) {\n return { url: stripTrailingSlash(envUrl), apiToken: envToken };\n }\n const saved = getIntegrationRaw(\"jira_align\");\n if (saved?.url && saved.api_token) {\n return { url: stripTrailingSlash(saved.url), apiToken: saved.api_token };\n }\n return {\n error:\n \"Jira Align not configured. Open the gear menu → Integrations tab and add your \" +\n \"Jira Align instance URL and API token. (Or set JIRA_ALIGN_URL / JIRA_ALIGN_TOKEN \" +\n \"env vars before starting Jarela.)\",\n };\n}\n\nfunction stripTrailingSlash(s: string): string { return s.replace(/\\/+$/, \"\"); }\n\nasync function jaFetch(\n auth: JiraAlignAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const url = path.startsWith(\"http\") ? path : `${auth.url}${path}`;\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${auth.apiToken}`,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n });\n const text = await res.text();\n if (!res.ok) {\n return { error: `Jira Align ${res.status}: ${text.slice(0, 500)}`, url };\n }\n return parseJsonSafe<unknown>(text, text);\n}\n\n// Shape an item payload back into a stable, typeless summary so the agent\n// gets the same fields regardless of which /<type>s endpoint we hit. Field\n// casing varies across JA endpoints (parentId vs parentID etc.), so we\n// fall back through the known variants.\nfunction summarizeItem(\n type: string,\n data: Record<string, unknown>,\n baseUrl: string,\n): Record<string, unknown> {\n return {\n id: data.id,\n type,\n url: `${baseUrl}/Item/${data.id}`,\n title: data.title ?? data.name ?? null,\n state: data.state ?? data.status ?? null,\n description: data.description ?? null,\n parent_id: data.parentId ?? data.parentID ?? null,\n program_id: data.programId ?? data.programID ?? null,\n team_id: data.teamId ?? data.teamID ?? null,\n release_id: data.releaseId ?? data.releaseID ?? null,\n sprint_id: data.sprintId ?? data.sprintID ?? null,\n owner: data.owner ?? data.ownerEmail ?? null,\n created_at: data.createDate ?? data.createdAt ?? null,\n updated_at: data.lastUpdated ?? data.updatedAt ?? null,\n };\n}\n\n// ── Read tools ──────────────────────────────────────────────────────────────\n\nexport const jiraAlignGetItemTool = tool(\n async ({ type, item_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const collection = collectionFor(type);\n if (typeof collection !== \"string\") return JSON.stringify(collection);\n\n const data = await jaFetch(auth, `/rest/align/api/2/${collection}/${encodeURIComponent(item_id)}`) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify(summarizeItem(type, data, auth.url));\n },\n {\n name: \"jira_align_get_item\",\n description:\n \"Fetch a Jira Align work item by id. **Must specify `type`** — Jira Align v2 has no \" +\n \"generic /items endpoint, so the type tells us which collection to hit (epic|capability|\" +\n \"feature|story|theme|task|defect|objective). Returns title, state, hierarchy refs \" +\n \"(parent/program/team/release/sprint), owner, and timestamps. Use jira_align_list_children \" +\n \"to walk the tree.\",\n schema: z.object({\n type: TYPE_ENUM.describe(\"Work-item type — required to route to the right /<type>s collection\"),\n item_id: z.string().describe(\"Numeric Jira Align item id (e.g. '12345')\"),\n }),\n },\n);\n\nexport const jiraAlignSearchItemsTool = tool(\n async ({ type, state, owner, program_id, team_id, updated_since, max_results, filter }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const collection = collectionFor(type);\n if (typeof collection !== \"string\") return JSON.stringify(collection);\n\n const params = new URLSearchParams();\n // JA v2 uses OData-style $filter for predicates. Build a conjunction\n // from the structured args; let callers append via `filter` for things\n // we don't model (custom fields etc.).\n const clauses: string[] = [];\n if (state) clauses.push(`state eq '${escapeOData(state)}'`);\n if (owner) clauses.push(`owner eq '${escapeOData(owner)}'`);\n if (program_id) clauses.push(`programId eq ${Number.isFinite(Number(program_id)) ? program_id : `'${escapeOData(program_id)}'`}`);\n if (team_id) clauses.push(`teamId eq ${Number.isFinite(Number(team_id)) ? team_id : `'${escapeOData(team_id)}'`}`);\n if (updated_since) clauses.push(`lastUpdated ge ${normalizeDate(updated_since)}`);\n if (filter) clauses.push(`(${filter})`);\n if (clauses.length) params.set(\"$filter\", clauses.join(\" and \"));\n params.set(\"limit\", String(Math.min(max_results ?? 25, 100)));\n\n const data = await jaFetch(auth, `/rest/align/api/2/${collection}?${params.toString()}`) as { items?: Array<Record<string, unknown>>; nextPageToken?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n items: (data.items ?? []).map((i) => ({\n id: i.id,\n type,\n title: i.title ?? i.name ?? null,\n state: i.state ?? null,\n owner: i.owner ?? null,\n url: `${auth.url}/Item/${i.id}`,\n })),\n next_page_token: data.nextPageToken ?? null,\n });\n },\n {\n name: \"jira_align_search_items\",\n description:\n \"Search Jira Align work items of a given type, with optional state/owner/program/team \" +\n \"filters. **`type` is required** — JA v2 has no cross-type item collection, so each \" +\n \"search hits one /<type>s endpoint. Use `filter` to pass an OData expression for fields \" +\n \"this tool doesn't model (e.g. custom fields). Returns a compact list (id, title, state, \" +\n \"owner). Pass updated_since='-7d' or an ISO date for recency.\",\n schema: z.object({\n type: TYPE_ENUM.describe(\"Work-item type to search\"),\n state: z.string().optional().describe(\"Workflow state name (e.g. 'In Progress', 'Done')\"),\n owner: z.string().optional().describe(\"Owner email or username\"),\n program_id: z.string().optional(),\n team_id: z.string().optional(),\n updated_since: z.string().optional().describe(\"ISO timestamp or relative (e.g. '-7d')\"),\n filter: z.string().optional().describe(\"Raw OData $filter expression appended to the structured filters (advanced)\"),\n max_results: z.number().optional().describe(\"Default 25, max 100\"),\n }),\n },\n);\n\nexport const jiraAlignListChildrenTool = tool(\n async ({ child_type, parent_id, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const collection = collectionFor(child_type);\n if (typeof collection !== \"string\") return JSON.stringify(collection);\n\n // JA hierarchy is implicit: get children by querying the child collection\n // with $filter=parentId eq {id}. There is no /<type>/{id}/children sub-route.\n const params = new URLSearchParams();\n params.set(\"$filter\", `parentId eq ${parent_id}`);\n params.set(\"limit\", String(Math.min(max_results ?? 50, 100)));\n const data = await jaFetch(auth, `/rest/align/api/2/${collection}?${params.toString()}`) as { items?: Array<Record<string, unknown>>; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n parent_id,\n child_type,\n items: (data.items ?? []).map((i) => ({\n id: i.id,\n type: child_type,\n title: i.title ?? i.name ?? null,\n state: i.state ?? null,\n url: `${auth.url}/Item/${i.id}`,\n })),\n });\n },\n {\n name: \"jira_align_list_children\",\n description:\n \"List the direct children of a Jira Align work item. **Both `parent_id` and `child_type` \" +\n \"are required** — the API has no generic `/items/{id}/children` route, so we query the \" +\n \"child collection with a parentId filter. Use the standard hierarchy: theme → epic → \" +\n \"capability → feature → story (instances may differ; check your portfolio config). For \" +\n \"deeper trees, call this once per level.\",\n schema: z.object({\n parent_id: z.string().describe(\"Numeric id of the parent item\"),\n child_type: TYPE_ENUM.describe(\"Type of children to fetch — must match your hierarchy level\"),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\n// ── Write tools ─────────────────────────────────────────────────────────────\n\nexport const jiraAlignCreateItemTool = tool(\n async ({ type, title, description, parent_id, program_id, team_id, owner }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const collection = collectionFor(type);\n if (typeof collection !== \"string\") return JSON.stringify(collection);\n\n const body: Record<string, unknown> = { title };\n if (description) body.description = description;\n if (parent_id) body.parentId = parent_id;\n if (program_id) body.programId = program_id;\n if (team_id) body.teamId = team_id;\n if (owner) body.owner = owner;\n const data = await jaFetch(auth, `/rest/align/api/2/${collection}`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n id: data.id,\n type,\n url: data.id ? `${auth.url}/Item/${data.id}` : null,\n });\n },\n {\n name: \"jira_align_create_item\",\n description:\n \"Create a Jira Align work item in a given type's collection. Set `type` to one of \" +\n \"epic|capability|feature|story|theme|task|defect|objective. Pass `parent_id` to attach \" +\n \"to an existing hierarchy. **Disable this tool to make the agent read-only.**\",\n schema: z.object({\n type: TYPE_ENUM.describe(\"Work-item type — selects which /<type>s collection receives the POST\"),\n title: z.string().describe(\"Item title\"),\n description: z.string().optional(),\n parent_id: z.string().optional().describe(\"Attach under this parent item\"),\n program_id: z.string().optional(),\n team_id: z.string().optional(),\n owner: z.string().optional().describe(\"Owner email or username\"),\n }),\n },\n);\n\nexport const jiraAlignUpdateItemTool = tool(\n async ({ type, item_id, fields }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const collection = collectionFor(type);\n if (typeof collection !== \"string\") return JSON.stringify(collection);\n if (!fields || Object.keys(fields).length === 0) {\n return JSON.stringify({ error: \"fields object must contain at least one field to update\" });\n }\n const data = await jaFetch(auth, `/rest/align/api/2/${collection}/${encodeURIComponent(item_id)}`, {\n method: \"PATCH\",\n body: JSON.stringify(fields),\n }) as { error?: string };\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n id: item_id,\n type,\n url: `${auth.url}/Item/${item_id}`,\n updated_fields: Object.keys(fields),\n });\n },\n {\n name: \"jira_align_update_item\",\n description:\n \"Patch fields on a Jira Align item (title, description, owner, programId, teamId, \" +\n \"parentId, custom fields, …). Only the listed fields are touched. **`type` is required** \" +\n \"to route the PATCH to the correct /<type>s/{id} resource. **Disable this tool to make \" +\n \"the agent read-only.**\",\n schema: z.object({\n type: TYPE_ENUM,\n item_id: z.string(),\n fields: z.record(z.string(), z.unknown()).describe(\n \"Map of field name → new value. Use the camelCase JA REST field names.\",\n ),\n }),\n },\n);\n\nexport const jiraAlignTransitionItemTool = tool(\n async ({ type, item_id, state }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const collection = collectionFor(type);\n if (typeof collection !== \"string\") return JSON.stringify(collection);\n if (!state) {\n // List available states for the item type if the agent didn't pass one.\n const wf = await jaFetch(auth, `/rest/align/api/2/workflows?itemType=${encodeURIComponent(type)}`) as { states?: Array<{ name: string }>; error?: string };\n if (wf && typeof wf === \"object\" && \"error\" in wf) return JSON.stringify(wf);\n return JSON.stringify({\n item_id,\n item_type: type,\n available_states: (wf.states ?? []).map((s) => s.name),\n });\n }\n const data = await jaFetch(auth, `/rest/align/api/2/${collection}/${encodeURIComponent(item_id)}`, {\n method: \"PATCH\",\n body: JSON.stringify({ state }),\n }) as { error?: string };\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, id: item_id, type, state });\n },\n {\n name: \"jira_align_transition_item\",\n description:\n \"Move a Jira Align work item to a new workflow state (e.g. 'In Progress' → 'Done'). \" +\n \"Call without `state` to list valid transitions for the item's type. **`type` is required.**\",\n schema: z.object({\n type: TYPE_ENUM,\n item_id: z.string(),\n state: z.string().optional().describe(\"Target state name. Omit to list available states.\"),\n }),\n },\n);\n\nexport const jiraAlignDeleteItemTool = tool(\n async ({ type, item_id, confirm }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const collection = collectionFor(type);\n if (typeof collection !== \"string\") return JSON.stringify(collection);\n // Refuse without explicit confirm — the agent has to opt in per call,\n // not just because the tool is enabled. Mirrors the pattern in\n // exec.ts where destructive shell calls are gated by an extra arg.\n if (confirm !== item_id) {\n return JSON.stringify({\n error:\n `Refusing to delete item ${item_id}: pass \\`confirm\\` set to the same id to proceed. ` +\n `Deletes are not undoable in Jira Align — verify with the user first.`,\n });\n }\n const data = await jaFetch(auth, `/rest/align/api/2/${collection}/${encodeURIComponent(item_id)}`, {\n method: \"DELETE\",\n }) as { error?: string };\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_id: item_id, type });\n },\n {\n name: \"jira_align_delete_item\",\n description:\n \"Permanently delete a Jira Align work item. **Irreversible.** **`type` is required** to \" +\n \"route to the correct collection. The agent must also pass `confirm` set to the same \" +\n \"`item_id` — a deliberate two-arg gate so a mis-issued tool call can't wipe an item. \" +\n \"**Leave this tool disabled unless the user explicitly wants delete capability.**\",\n schema: z.object({\n type: TYPE_ENUM,\n item_id: z.string(),\n confirm: z.string().describe(\"Must equal `item_id` for the delete to proceed.\"),\n }),\n },\n);\n\n// ── Comments / discussion (read-write but lower blast-radius than item edits) ──\n\nexport const jiraAlignAddCommentTool = tool(\n async ({ type, item_id, body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const collection = collectionFor(type);\n if (typeof collection !== \"string\") return JSON.stringify(collection);\n const data = await jaFetch(auth, `/rest/align/api/2/${collection}/${encodeURIComponent(item_id)}/comments`, {\n method: \"POST\",\n body: JSON.stringify({ body }),\n }) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, comment_id: data.id, type });\n },\n {\n name: \"jira_align_add_comment\",\n description:\n \"Post a comment on a Jira Align work item. **`type` is required** to route to the \" +\n \"correct /<type>s/{id}/comments resource. Plain text body. Note: not all instances \" +\n \"expose comments as a sub-resource on every type — check your Swagger if this 404s.\",\n schema: z.object({\n type: TYPE_ENUM,\n item_id: z.string(),\n body: z.string().describe(\"Comment text\"),\n }),\n },\n);\n\n// ── Hierarchy entities (read-only listing — ADR-0035) ──────────────────────\n//\n// Jira Align organizes work-items inside a hierarchy of programs, teams,\n// releases, sprints (PIs), portfolios, and value streams. The work-item tools\n// above return ids for those entities (programId, teamId, etc.) but until now\n// the agent had no way to resolve those ids to names without a manual lookup.\n// These two tools fill that gap. They mirror TYPE_TO_COLLECTION's discipline:\n// reject unknown entity_type up front, route to the right /<collection>.\n\nconst ENTITY_TO_COLLECTION: Record<string, string> = {\n program: \"programs\",\n team: \"teams\",\n release: \"releases\",\n sprint: \"sprints\",\n portfolio: \"portfolios\",\n value_stream: \"valueStreams\",\n};\nconst KNOWN_ENTITIES = Object.keys(ENTITY_TO_COLLECTION) as ReadonlyArray<keyof typeof ENTITY_TO_COLLECTION>;\nconst ENTITY_ENUM = z.enum(KNOWN_ENTITIES as [string, ...string[]]);\n\nfunction entityCollectionFor(entity_type: string): string | { error: string } {\n const seg = ENTITY_TO_COLLECTION[entity_type.toLowerCase()];\n if (!seg) {\n return {\n error: `unknown Jira Align entity_type \"${entity_type}\". Expected one of: ${KNOWN_ENTITIES.join(\", \")}.`,\n };\n }\n return seg;\n}\n\nfunction summarizeEntity(\n entity_type: string,\n data: Record<string, unknown>,\n): Record<string, unknown> {\n return {\n id: data.id,\n entity_type,\n name: data.name ?? data.title ?? null,\n description: data.description ?? null,\n state: data.state ?? data.status ?? null,\n parent_id: data.parentId ?? data.parentID ?? null,\n program_id: data.programId ?? data.programID ?? null,\n portfolio_id: data.portfolioId ?? data.portfolioID ?? null,\n start_date: data.startDate ?? null,\n end_date: data.endDate ?? null,\n active: data.isActive ?? data.active ?? null,\n };\n}\n\nexport const jiraAlignListEntitiesTool = tool(\n async ({ entity_type, name_filter, max_results, filter }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const collection = entityCollectionFor(entity_type);\n if (typeof collection !== \"string\") return JSON.stringify(collection);\n\n const params = new URLSearchParams();\n const clauses: string[] = [];\n if (name_filter) clauses.push(`contains(name, '${escapeOData(name_filter)}')`);\n if (filter) clauses.push(`(${filter})`);\n if (clauses.length) params.set(\"$filter\", clauses.join(\" and \"));\n params.set(\"limit\", String(Math.min(max_results ?? 50, 100)));\n\n const data = await jaFetch(auth, `/rest/align/api/2/${collection}?${params}`) as {\n items?: Array<Record<string, unknown>>;\n nextPageToken?: string;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n entity_type,\n items: (data.items ?? []).map((d) => summarizeEntity(entity_type, d)),\n next_page_token: data.nextPageToken ?? null,\n });\n },\n {\n name: \"jira_align_list_entities\",\n description:\n \"List non-work-item Jira Align entities of a given type: programs, teams, releases, sprints (PIs), \" +\n \"portfolios, or value streams. Use to resolve human names → ids before passing to work-item tools, \" +\n \"or to enumerate available programs/teams when planning work. Filter by `name_filter` (contains-match) \" +\n \"or by raw OData `filter` for advanced cases.\",\n schema: z.object({\n entity_type: ENTITY_ENUM,\n name_filter: z.string().optional().describe(\"Case-insensitive name fragment\"),\n filter: z.string().optional().describe(\"Raw OData $filter expression (advanced)\"),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\nexport const jiraAlignGetEntityTool = tool(\n async ({ entity_type, entity_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const collection = entityCollectionFor(entity_type);\n if (typeof collection !== \"string\") return JSON.stringify(collection);\n const data = await jaFetch(auth, `/rest/align/api/2/${collection}/${encodeURIComponent(entity_id)}`) as\n Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify(summarizeEntity(entity_type, data));\n },\n {\n name: \"jira_align_get_entity\",\n description:\n \"Fetch a single Jira Align hierarchy entity by id: program, team, release, sprint (PI), portfolio, \" +\n \"or value stream. Returns id, name, description, state, hierarchy refs, dates.\",\n schema: z.object({\n entity_type: ENTITY_ENUM,\n entity_id: z.string(),\n }),\n },\n);\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\n// JA's $filter accepts ISO-8601 date literals without quotes. Map a small set\n// of relative shorthands so callers can pass \"-7d\" the same way they do for\n// the Jira Cloud tool, without knowing OData.\nfunction normalizeDate(input: string): string {\n const m = /^-(\\d+)([dhm])$/.exec(input);\n if (!m) return input; // assume caller passed an ISO string\n const n = Number(m[1]);\n const unitMs = m[2] === \"d\" ? 86_400_000 : m[2] === \"h\" ? 3_600_000 : 60_000;\n return new Date(Date.now() - n * unitMs).toISOString();\n}\n\n// OData string literals double single quotes for escaping. We don't get fancy\n// — JA usernames and state names don't contain backslashes — but we do need\n// to make sure a quote in the input doesn't break the filter.\nfunction escapeOData(s: string): string {\n return s.replace(/'/g, \"''\");\n}\n\nregisterTools(\"JiraAlign\", [\n jiraAlignGetItemTool, jiraAlignSearchItemsTool, jiraAlignListChildrenTool,\n jiraAlignCreateItemTool, jiraAlignUpdateItemTool, jiraAlignTransitionItemTool,\n jiraAlignDeleteItemTool, jiraAlignAddCommentTool,\n // Hierarchy entity listing (ADR-0035)\n jiraAlignListEntitiesTool, jiraAlignGetEntityTool,\n]);\n","/**\n * Native Gmail tools — direct REST API calls to gmail.googleapis.com, no MCP.\n *\n * Why native: same reasoning as lib/tools/atlassian.ts. The MCP servers that\n * wrap Gmail OAuth bring an opaque token cache + extra subprocess; doing it\n * inline keeps a single source of credential truth (the Integrations panel)\n * and surfaces clean error messages to the agent.\n *\n * Auth resolution (in priority order):\n * 1. Env: GMAIL_CLIENT_ID, GMAIL_CLIENT_SECRET, GMAIL_REFRESH_TOKEN\n * 2. Memory store: namespace=\"integrations\", key=\"gmail\",\n * value={ client_id, client_secret, refresh_token }\n *\n * The user obtains a refresh token once via Google OAuth Playground\n * (https://developers.google.com/oauthplayground) — matches the Atlassian\n * paste-API-token UX. In-app OAuth flow is intentionally deferred.\n *\n * Scope-wise this integration is **drafts only**: there is deliberately no\n * `gmail_send` tool. Users promote drafts in Gmail itself.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { stripHtml } from \"@/lib/utils/html\";\nimport { truncateBytes } from \"@/lib/utils/text\";\nimport { registerTools } from \"./registry\";\nimport {\n googleFetch,\n resolveGoogleAuth,\n type GoogleAuth,\n} from \"@/lib/integrations/gmail-oauth\";\n\n// Re-export under the old name so existing imports (e.g. the integrations\n// test endpoint) keep working unchanged.\nexport type GmailAuth = GoogleAuth;\n\n// Exposed for the integrations test endpoint.\nexport function _resolveGmailAuth(): GmailAuth | { error: string } {\n return resolveGoogleAuth();\n}\n\nconst GMAIL_BASE = \"https://gmail.googleapis.com/gmail/v1/users/me\";\nconst gmailFetch = (auth: GmailAuth, path: string, init?: RequestInit) =>\n googleFetch(auth, \"Gmail\", GMAIL_BASE, path, init);\n\n// ── Decoders / helpers ──────────────────────────────────────────────────────\n\n// Gmail uses base64url (no padding, +/ → -_). Node's Buffer handles it directly.\nfunction decodeBase64Url(s: string): string {\n try {\n return Buffer.from(s, \"base64url\").toString(\"utf8\");\n } catch {\n return \"\";\n }\n}\n\ninterface MessagePart {\n mimeType?: string;\n filename?: string;\n body?: { data?: string; size?: number };\n parts?: MessagePart[];\n}\n\n// Walk the MIME tree, preferring text/plain. Fall back to a naive HTML strip\n// when no plain part exists. Skips attachments (filename != \"\").\nfunction extractBody(payload: MessagePart | undefined): string {\n if (!payload) return \"\";\n const plain = findPart(payload, \"text/plain\");\n if (plain?.body?.data) return decodeBase64Url(plain.body.data);\n const html = findPart(payload, \"text/html\");\n if (html?.body?.data) return stripHtml(decodeBase64Url(html.body.data), { preserveParagraphs: true });\n return \"\";\n}\n\nfunction findPart(part: MessagePart, mime: string): MessagePart | null {\n if (!part) return null;\n if (part.mimeType === mime && !part.filename && part.body?.data) return part;\n for (const child of part.parts ?? []) {\n const hit = findPart(child, mime);\n if (hit) return hit;\n }\n return null;\n}\n\nconst MAX_BODY_BYTES = 30_000;\n\ninterface Header { name?: string; value?: string }\nfunction header(headers: Header[] | undefined, name: string): string | null {\n const h = (headers ?? []).find((x) => (x.name ?? \"\").toLowerCase() === name.toLowerCase());\n return h?.value ?? null;\n}\n\n// Build an RFC 2822 message and base64url-encode it for the drafts API.\nfunction buildRawMessage(opts: {\n to: string[];\n cc?: string[];\n bcc?: string[];\n subject: string;\n body: string;\n in_reply_to?: string | null; // value of Message-Id header from the parent\n references?: string | null;\n}): string {\n const lines: string[] = [];\n lines.push(`To: ${opts.to.join(\", \")}`);\n if (opts.cc?.length) lines.push(`Cc: ${opts.cc.join(\", \")}`);\n if (opts.bcc?.length) lines.push(`Bcc: ${opts.bcc.join(\", \")}`);\n lines.push(`Subject: ${encodeSubject(opts.subject)}`);\n if (opts.in_reply_to) lines.push(`In-Reply-To: ${opts.in_reply_to}`);\n if (opts.references) lines.push(`References: ${opts.references}`);\n lines.push(\"Content-Type: text/plain; charset=\\\"UTF-8\\\"\");\n lines.push(\"MIME-Version: 1.0\");\n lines.push(\"\");\n lines.push(opts.body);\n const raw = lines.join(\"\\r\\n\");\n return Buffer.from(raw, \"utf8\").toString(\"base64url\");\n}\n\n// RFC 2047 encoded-word for non-ASCII subjects.\nfunction encodeSubject(s: string): string {\n if (/^[\\x20-\\x7E]*$/.test(s)) return s;\n return `=?UTF-8?B?${Buffer.from(s, \"utf8\").toString(\"base64\")}?=`;\n}\n\n// ── Tools ───────────────────────────────────────────────────────────────────\n\nexport const gmailSearchTool = tool(\n async ({ query, max_results }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(Math.max(max_results ?? 25, 1), 100);\n const list = await gmailFetch(\n auth,\n `/messages?q=${encodeURIComponent(query)}&maxResults=${limit}`,\n ) as { messages?: Array<{ id: string; threadId: string }>; resultSizeEstimate?: number; nextPageToken?: string; error?: string };\n if (\"error\" in list && list.error) return JSON.stringify(list);\n const ids = (list.messages ?? []).map((m) => m.id);\n if (ids.length === 0) {\n return JSON.stringify({\n query,\n result_size_estimate: list.resultSizeEstimate ?? 0,\n next_page_token: list.nextPageToken ?? null,\n messages: [],\n });\n }\n // Parallel metadata fetch; the API recommends batching but for ≤100 ids\n // parallel single calls are simpler and well within quota.\n const details = await Promise.all(ids.map(async (id) => {\n const m = await gmailFetch(\n auth,\n `/messages/${id}?format=metadata&metadataHeaders=From&metadataHeaders=To&metadataHeaders=Subject&metadataHeaders=Date`,\n ) as { id?: string; threadId?: string; snippet?: string; labelIds?: string[]; payload?: { headers?: Header[] }; error?: string };\n if (m.error) return { id, error: m.error };\n return {\n id: m.id,\n thread_id: m.threadId,\n from: header(m.payload?.headers, \"From\"),\n to: header(m.payload?.headers, \"To\"),\n subject: header(m.payload?.headers, \"Subject\"),\n date: header(m.payload?.headers, \"Date\"),\n snippet: m.snippet ?? null,\n labels: m.labelIds ?? [],\n };\n }));\n return JSON.stringify({\n query,\n result_size_estimate: list.resultSizeEstimate ?? details.length,\n next_page_token: list.nextPageToken ?? null,\n messages: details,\n });\n },\n {\n name: \"gmail_search\",\n description:\n \"Search the user's Gmail with Gmail query syntax. Returns message metadata (from, to, subject, \" +\n \"date, snippet, labels) plus Gmail's resultSizeEstimate and next page token so '1 result' \" +\n \"doesn't get mistaken for '1 unread email'. Examples: 'is:unread newer_than:1d', \" +\n \"'from:notifications@github.com', 'subject:invoice has:attachment', 'in:inbox -category:promotions'. \" +\n \"Use this before calling gmail_get_message — the snippet is often enough.\",\n schema: z.object({\n query: z.string().describe(\"Gmail query string\"),\n max_results: z.number().int().optional().describe(\"Max messages (default 25, max 100)\"),\n }),\n },\n);\n\nexport const gmailGetMessageTool = tool(\n async ({ id }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const m = await gmailFetch(auth, `/messages/${encodeURIComponent(id)}?format=full`) as {\n id?: string;\n threadId?: string;\n snippet?: string;\n labelIds?: string[];\n payload?: MessagePart & { headers?: Header[] };\n error?: string;\n };\n if (m.error) return JSON.stringify(m);\n const body = extractBody(m.payload);\n const { text: capped, truncated } = truncateBytes(body, MAX_BODY_BYTES);\n return JSON.stringify({\n id: m.id,\n thread_id: m.threadId,\n labels: m.labelIds ?? [],\n from: header(m.payload?.headers, \"From\"),\n to: header(m.payload?.headers, \"To\"),\n cc: header(m.payload?.headers, \"Cc\"),\n subject: header(m.payload?.headers, \"Subject\"),\n date: header(m.payload?.headers, \"Date\"),\n message_id: header(m.payload?.headers, \"Message-Id\") ?? header(m.payload?.headers, \"Message-ID\"),\n snippet: m.snippet ?? null,\n body: capped,\n truncated,\n });\n },\n {\n name: \"gmail_get_message\",\n description:\n \"Fetch one Gmail message by id, including full headers and the decoded text body (text/plain \" +\n \"preferred, HTML stripped if only HTML is available). Body capped at 30KB with `truncated:true` \" +\n \"when cut off.\",\n schema: z.object({\n id: z.string().describe(\"Gmail message id (from gmail_search results)\"),\n }),\n },\n);\n\nexport const gmailListLabelsTool = tool(\n async () => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await gmailFetch(auth, `/labels`) as { labels?: Array<{ id: string; name: string; type: string }>; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n labels: (data.labels ?? []).map((l) => ({ id: l.id, name: l.name, type: l.type })),\n });\n },\n {\n name: \"gmail_list_labels\",\n description:\n \"List all Gmail labels (system + user). System label ids are uppercase (INBOX, UNREAD, \" +\n \"STARRED, IMPORTANT, SPAM, TRASH, SENT, DRAFT, CATEGORY_*). User labels have lowercase \" +\n \"alphanumeric ids like 'Label_42'. Use the id values with gmail_modify_message.\",\n schema: z.object({}),\n },\n);\n\nexport const gmailModifyMessageTool = tool(\n async ({ id, add_labels, remove_labels }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!(add_labels?.length || remove_labels?.length)) {\n return JSON.stringify({ error: \"Provide at least one of add_labels / remove_labels\" });\n }\n const data = await gmailFetch(auth, `/messages/${encodeURIComponent(id)}/modify`, {\n method: \"POST\",\n body: JSON.stringify({\n addLabelIds: add_labels ?? [],\n removeLabelIds: remove_labels ?? [],\n }),\n }) as { id?: string; labelIds?: string[]; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, id: data.id, labels: data.labelIds ?? [] });\n },\n {\n name: \"gmail_modify_message\",\n description:\n \"Add or remove labels on a Gmail message. Common patterns: \" +\n \"archive = remove_labels=['INBOX']; mark read = remove_labels=['UNREAD']; \" +\n \"star = add_labels=['STARRED']; mark important = add_labels=['IMPORTANT']. \" +\n \"Use gmail_list_labels first if you don't know a user label id.\",\n schema: z.object({\n id: z.string().describe(\"Gmail message id\"),\n add_labels: z.array(z.string()).optional().describe(\"Label ids to add\"),\n remove_labels: z.array(z.string()).optional().describe(\"Label ids to remove\"),\n }),\n },\n);\n\nexport const gmailCreateDraftTool = tool(\n async ({ to, cc, bcc, subject, body, in_reply_to_id }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n let in_reply_to: string | null = null;\n let references: string | null = null;\n let threadId: string | null = null;\n if (in_reply_to_id) {\n // Pull the parent so the draft threads properly. Need the parent's\n // Message-Id header for In-Reply-To, and threadId for Gmail's\n // server-side threading.\n const parent = await gmailFetch(\n auth,\n `/messages/${encodeURIComponent(in_reply_to_id)}?format=metadata&metadataHeaders=Message-Id&metadataHeaders=References`,\n ) as { threadId?: string; payload?: { headers?: Header[] }; error?: string };\n if (parent.error) {\n return JSON.stringify({ error: `Failed to load parent for threading: ${parent.error}` });\n }\n threadId = parent.threadId ?? null;\n in_reply_to = header(parent.payload?.headers, \"Message-Id\") ?? header(parent.payload?.headers, \"Message-ID\");\n const prevRefs = header(parent.payload?.headers, \"References\");\n references = prevRefs && in_reply_to ? `${prevRefs} ${in_reply_to}` : in_reply_to;\n }\n\n const raw = buildRawMessage({ to, cc, bcc, subject, body, in_reply_to, references });\n const data = await gmailFetch(auth, `/drafts`, {\n method: \"POST\",\n body: JSON.stringify({\n message: { raw, ...(threadId ? { threadId } : {}) },\n }),\n }) as { id?: string; message?: { id?: string; threadId?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n draft_id: data.id,\n message_id: data.message?.id,\n thread_id: data.message?.threadId,\n });\n },\n {\n name: \"gmail_create_draft\",\n description:\n \"Create a Gmail draft. **THIS INTEGRATION CANNOT SEND MAIL** — drafts only; the user promotes \" +\n \"them manually in Gmail. When replying to an existing message, pass `in_reply_to_id` (the parent \" +\n \"message id from gmail_search/gmail_get_message) — the tool will set Message-Id/References/\" +\n \"threadId so the draft appears inside the right Gmail thread.\",\n schema: z.object({\n to: z.array(z.string()).describe(\"Recipient email addresses\"),\n cc: z.array(z.string()).optional(),\n bcc: z.array(z.string()).optional(),\n subject: z.string(),\n body: z.string().describe(\"Plain text body (use \\\\n for line breaks)\"),\n in_reply_to_id: z.string().optional().describe(\"Gmail message id to reply to (for threading)\"),\n }),\n },\n);\n\nexport const gmailTrashMessageTool = tool(\n async ({ id }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await gmailFetch(auth, `/messages/${encodeURIComponent(id)}/trash`, {\n method: \"POST\",\n }) as { id?: string; labelIds?: string[]; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, id: data.id, labels: data.labelIds ?? [] });\n },\n {\n name: \"gmail_trash_message\",\n description:\n \"Move a Gmail message to Trash (reversible for 30 days, not permanent delete). Only call this \" +\n \"when the user has explicitly asked to trash/delete a message — never on your own initiative \" +\n \"as part of a triage flow. Prefer gmail_modify_message remove_labels=['INBOX'] to archive.\",\n schema: z.object({\n id: z.string().describe(\"Gmail message id\"),\n }),\n },\n);\n\nregisterTools(\"Mail\", [\n gmailSearchTool, gmailGetMessageTool, gmailListLabelsTool,\n gmailModifyMessageTool, gmailCreateDraftTool, gmailTrashMessageTool,\n]);\n","/**\n * Native Google Calendar tools — direct REST calls to\n * calendar.googleapis.com, sharing the Gmail OAuth client (one Google\n * account, one refresh token, one access-token cache; see\n * lib/integrations/gmail-oauth.ts).\n *\n * Scope-wise this surface is **events on existing calendars**:\n * - list / get / create / update / delete events\n * - list the user's calendars (read-only)\n * There is deliberately no calendar-list create/delete and no ACL\n * editing. To enable a wider surface, add the broader scope to\n * GMAIL_SCOPES and (force users to) reconnect.\n *\n * v1 design notes:\n * - calendarId defaults to \"primary\" everywhere so the agent can\n * create a quick event without first calling list_calendars.\n * - All datetimes are RFC3339 strings (e.g. \"2026-05-19T16:00:00-07:00\").\n * When the caller omits a timezone offset, Google falls back to the\n * calendar's default TZ. The tools surface a `time_zone` field that\n * forwards an IANA name in case the caller wants to be explicit.\n * - `calendar_create_event` can provision a Google Meet link via the\n * conferenceData createRequest dance — gated behind `add_meet_link`\n * so unused calls don't trip Google's quota.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport {\n googleFetch,\n resolveGoogleAuth,\n type GoogleAuth,\n} from \"@/lib/integrations/gmail-oauth\";\n\nconst CALENDAR_BASE = \"https://www.googleapis.com/calendar/v3\";\nconst calendarFetch = (auth: GoogleAuth, path: string, init?: RequestInit) =>\n googleFetch(auth, \"Calendar\", CALENDAR_BASE, path, init);\n\n// ── Type shapes (minimal — only what we read back) ──────────────────────────\n\ninterface CalendarListEntry {\n id?: string;\n summary?: string;\n primary?: boolean;\n timeZone?: string;\n accessRole?: string;\n}\n\ninterface EventDateTime {\n dateTime?: string;\n date?: string;\n timeZone?: string;\n}\n\ninterface EventAttendee {\n email?: string;\n displayName?: string;\n responseStatus?: string;\n}\n\ninterface CalendarEvent {\n id?: string;\n status?: string;\n htmlLink?: string;\n hangoutLink?: string;\n summary?: string;\n description?: string;\n location?: string;\n start?: EventDateTime;\n end?: EventDateTime;\n attendees?: EventAttendee[];\n}\n\n// Slim down a full event to the fields the agent actually needs in a\n// thread response. Keeps tool outputs small enough not to blow context.\nfunction slimEvent(e: CalendarEvent): Record<string, unknown> {\n return {\n id: e.id,\n status: e.status,\n summary: e.summary ?? null,\n description: e.description ?? null,\n location: e.location ?? null,\n start: e.start?.dateTime ?? e.start?.date ?? null,\n end: e.end?.dateTime ?? e.end?.date ?? null,\n time_zone: e.start?.timeZone ?? e.end?.timeZone ?? null,\n attendees: (e.attendees ?? []).map((a) => ({\n email: a.email,\n name: a.displayName ?? null,\n response: a.responseStatus ?? null,\n })),\n meet_link: e.hangoutLink ?? null,\n html_link: e.htmlLink ?? null,\n };\n}\n\n// ── Tools ───────────────────────────────────────────────────────────────────\n\nexport const calendarListCalendarsTool = tool(\n async () => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await calendarFetch(auth, \"/users/me/calendarList\") as {\n items?: CalendarListEntry[];\n error?: string;\n };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n calendars: (data.items ?? []).map((c) => ({\n id: c.id,\n summary: c.summary ?? null,\n primary: c.primary === true,\n time_zone: c.timeZone ?? null,\n access_role: c.accessRole ?? null,\n })),\n });\n },\n {\n name: \"calendar_list_calendars\",\n description:\n \"List the user's Google calendars (primary + any they've subscribed to). \" +\n \"Returns id, summary, primary flag, time zone, access role per entry. The \" +\n \"`id` is what other calendar_* tools expect as `calendar_id`. Use this when \" +\n \"the user mentions a non-primary calendar by name (e.g. 'put it on my Work \" +\n \"calendar') — match against `summary` to find the right id.\",\n schema: z.object({}),\n },\n);\n\nexport const calendarListEventsTool = tool(\n async ({ calendar_id, time_min, time_max, query, max_results }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const params = new URLSearchParams({\n singleEvents: \"true\",\n orderBy: \"startTime\",\n maxResults: String(Math.min(Math.max(max_results ?? 25, 1), 100)),\n });\n // Default window: now → +7 days. Keeps \"what's on my schedule\" cheap.\n const now = new Date();\n const inAWeek = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);\n params.set(\"timeMin\", time_min ?? now.toISOString());\n params.set(\"timeMax\", time_max ?? inAWeek.toISOString());\n if (query) params.set(\"q\", query);\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events?${params.toString()}`,\n ) as { items?: CalendarEvent[]; error?: string };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n events: (data.items ?? []).map(slimEvent),\n });\n },\n {\n name: \"calendar_list_events\",\n description:\n \"List events on a calendar within a time window. Defaults: primary calendar, \" +\n \"now → +7 days, ordered by start, recurring events expanded into single \" +\n \"instances. **Use this before creating an event** to avoid double-booking, \" +\n \"and to look up existing event ids before updating/deleting. \" +\n \"Datetimes are RFC3339 (e.g. '2026-05-19T16:00:00-07:00').\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n time_min: z.string().optional().describe(\"RFC3339 lower bound (default: now)\"),\n time_max: z.string().optional().describe(\"RFC3339 upper bound (default: now + 7 days)\"),\n query: z.string().optional().describe(\"Free-text search across event fields\"),\n max_results: z.number().int().optional().describe(\"Max events (default 25, max 100)\"),\n }),\n },\n);\n\nexport const calendarGetEventTool = tool(\n async ({ calendar_id, event_id }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const eid = encodeURIComponent(event_id);\n const data = await calendarFetch(auth, `/calendars/${cal}/events/${eid}`) as\n CalendarEvent & { error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify(slimEvent(data));\n },\n {\n name: \"calendar_get_event\",\n description:\n \"Fetch one Google Calendar event by id. Returns the same slim shape as \" +\n \"calendar_list_events but for a single event.\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n event_id: z.string().describe(\"Event id (from calendar_list_events results)\"),\n }),\n },\n);\n\nexport const calendarCreateEventTool = tool(\n async ({\n calendar_id, summary, start_iso, end_iso, description, location,\n attendees, time_zone, add_meet_link,\n }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n\n interface EventBody {\n summary: string;\n description?: string;\n location?: string;\n start: EventDateTime;\n end: EventDateTime;\n attendees?: { email: string }[];\n conferenceData?: {\n createRequest: { requestId: string; conferenceSolutionKey: { type: string } };\n };\n }\n const body: EventBody = {\n summary,\n start: { dateTime: start_iso, ...(time_zone ? { timeZone: time_zone } : {}) },\n end: { dateTime: end_iso, ...(time_zone ? { timeZone: time_zone } : {}) },\n };\n if (description) body.description = description;\n if (location) body.location = location;\n if (attendees && attendees.length > 0) {\n body.attendees = attendees.map((email) => ({ email }));\n }\n if (add_meet_link) {\n body.conferenceData = {\n createRequest: {\n // requestId must be unique per createRequest; Google echoes it back.\n requestId: `jarela-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n conferenceSolutionKey: { type: \"hangoutsMeet\" },\n },\n };\n }\n\n // conferenceDataVersion=1 is required for Google to honor the\n // createRequest and provision a Meet URL. Harmless to set without it.\n const params = add_meet_link ? \"?conferenceDataVersion=1\" : \"\";\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events${params}`,\n { method: \"POST\", body: JSON.stringify(body) },\n ) as CalendarEvent & { error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify(slimEvent(data));\n },\n {\n name: \"calendar_create_event\",\n description:\n \"Create a Google Calendar event on a calendar (default: 'primary'). \" +\n \"Datetimes are RFC3339 strings — include a timezone offset (e.g. \" +\n \"'2026-05-19T16:00:00-07:00') or set `time_zone` to an IANA name (e.g. \" +\n \"'America/Los_Angeles') so the user's calendar interprets the time \" +\n \"correctly. Attendees are emailed an invite automatically. Set \" +\n \"`add_meet_link: true` to provision a Google Meet URL on the event.\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n summary: z.string().min(1).describe(\"Event title shown on the calendar\"),\n start_iso: z.string().describe(\"Start datetime, RFC3339\"),\n end_iso: z.string().describe(\"End datetime, RFC3339 (must be after start)\"),\n description: z.string().optional().describe(\"Long-form event body (markdown not rendered)\"),\n location: z.string().optional().describe(\"Free-text location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Invitee email addresses\"),\n time_zone: z.string().optional().describe(\"IANA timezone, e.g. 'America/Los_Angeles'\"),\n add_meet_link: z.boolean().optional().describe(\"Provision a Google Meet URL on this event\"),\n }),\n },\n);\n\nexport const calendarUpdateEventTool = tool(\n async ({\n calendar_id, event_id, summary, start_iso, end_iso, description, location,\n attendees, time_zone,\n }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const eid = encodeURIComponent(event_id);\n\n const patch: Record<string, unknown> = {};\n if (summary !== undefined) patch.summary = summary;\n if (description !== undefined) patch.description = description;\n if (location !== undefined) patch.location = location;\n if (start_iso !== undefined) {\n patch.start = { dateTime: start_iso, ...(time_zone ? { timeZone: time_zone } : {}) };\n }\n if (end_iso !== undefined) {\n patch.end = { dateTime: end_iso, ...(time_zone ? { timeZone: time_zone } : {}) };\n }\n if (attendees !== undefined) {\n patch.attendees = attendees.map((email) => ({ email }));\n }\n if (Object.keys(patch).length === 0) {\n return JSON.stringify({ error: \"Provide at least one field to update\" });\n }\n\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events/${eid}`,\n { method: \"PATCH\", body: JSON.stringify(patch) },\n ) as CalendarEvent & { error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify(slimEvent(data));\n },\n {\n name: \"calendar_update_event\",\n description:\n \"Patch a Google Calendar event. Only the fields you supply are changed; \" +\n \"omit fields to leave them alone. Use this to reschedule (`start_iso`/`end_iso`), \" +\n \"rename (`summary`), or adjust the invitee list (`attendees` — note this \" +\n \"**replaces** the full list, so include everyone who should remain).\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n event_id: z.string().describe(\"Event id\"),\n summary: z.string().optional().describe(\"New event title\"),\n start_iso: z.string().optional().describe(\"New start datetime, RFC3339\"),\n end_iso: z.string().optional().describe(\"New end datetime, RFC3339\"),\n description: z.string().optional().describe(\"New event body\"),\n location: z.string().optional().describe(\"New location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Replacement attendee list\"),\n time_zone: z.string().optional().describe(\"IANA timezone applied to start/end\"),\n }),\n },\n);\n\nexport const calendarDeleteEventTool = tool(\n async ({ calendar_id, event_id }) => {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const cal = encodeURIComponent(calendar_id ?? \"primary\");\n const eid = encodeURIComponent(event_id);\n const data = await calendarFetch(\n auth,\n `/calendars/${cal}/events/${eid}`,\n { method: \"DELETE\" },\n ) as { ok?: boolean; error?: string };\n if (data.error) return JSON.stringify({ error: data.error });\n return JSON.stringify({ ok: true, id: event_id });\n },\n {\n name: \"calendar_delete_event\",\n description:\n \"Delete a Google Calendar event by id. Attendees are notified by default. \" +\n \"Returns `{ ok: true, id }` on success. Use `calendar_list_events` to find \" +\n \"the event id first if you only know the title/time.\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: 'primary')\"),\n event_id: z.string().describe(\"Event id to delete\"),\n }),\n },\n);\n\nregisterTools(\"Calendar\", [\n calendarListCalendarsTool, calendarListEventsTool, calendarGetEventTool,\n calendarCreateEventTool, calendarUpdateEventTool, calendarDeleteEventTool,\n]);\n","/**\n * Native Outlook / Microsoft Graph mail tools. Mirrors lib/tools/gmail.ts\n * one-for-one (search/get/list_folders/modify/create_draft/trash) but\n * targets graph.microsoft.com/v1.0/me/messages and uses the shared\n * Microsoft auth helpers from lib/integrations/microsoft-oauth.ts.\n *\n * Design parity with Gmail:\n * - \"drafts only\" — we never expose send. Mail.ReadWrite gives us\n * drafts and folder moves; we deliberately did NOT request Mail.Send.\n * - same six-tool surface so the agent's mental model carries over.\n * - JSON outputs slimmed to fields the agent actually uses; full\n * bodies are capped at 30KB to keep context manageable.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { stripHtml } from \"@/lib/utils/html\";\nimport { truncateBytes } from \"@/lib/utils/text\";\nimport { registerTools } from \"./registry\";\nimport {\n graphFetch,\n resolveMicrosoftAuth,\n type MicrosoftAuth,\n} from \"@/lib/integrations/microsoft-oauth\";\n\n// Exposed for the integrations test endpoint.\nexport function _resolveOutlookAuth(): MicrosoftAuth | { error: string } {\n return resolveMicrosoftAuth();\n}\n\n// ── Type shapes (minimal subset of Graph's Message resource) ───────────────\n\ninterface GraphEmailAddress {\n name?: string;\n address?: string;\n}\ninterface GraphRecipient {\n emailAddress?: GraphEmailAddress;\n}\ninterface GraphMessage {\n id?: string;\n conversationId?: string;\n subject?: string;\n bodyPreview?: string;\n body?: { contentType?: \"html\" | \"text\"; content?: string };\n from?: GraphRecipient;\n toRecipients?: GraphRecipient[];\n ccRecipients?: GraphRecipient[];\n receivedDateTime?: string;\n isRead?: boolean;\n isDraft?: boolean;\n hasAttachments?: boolean;\n categories?: string[];\n parentFolderId?: string;\n webLink?: string;\n}\ninterface GraphFolder {\n id?: string;\n displayName?: string;\n parentFolderId?: string;\n totalItemCount?: number;\n unreadItemCount?: number;\n wellKnownName?: string;\n}\n\nfunction recipientToStr(r?: GraphRecipient): string | null {\n const addr = r?.emailAddress?.address;\n if (!addr) return null;\n const name = r?.emailAddress?.name;\n return name && name !== addr ? `${name} <${addr}>` : addr;\n}\n\nfunction summarizeMessage(m: GraphMessage): Record<string, unknown> {\n return {\n id: m.id,\n conversation_id: m.conversationId,\n from: recipientToStr(m.from),\n to: (m.toRecipients ?? []).map(recipientToStr).filter(Boolean),\n cc: (m.ccRecipients ?? []).map(recipientToStr).filter(Boolean),\n subject: m.subject ?? null,\n received: m.receivedDateTime ?? null,\n is_read: m.isRead === true,\n is_draft: m.isDraft === true,\n has_attachments: m.hasAttachments === true,\n categories: m.categories ?? [],\n folder_id: m.parentFolderId ?? null,\n snippet: m.bodyPreview ?? null,\n web_link: m.webLink ?? null,\n };\n}\n\nconst BODY_CAP = 30_000;\n\n// ── Tools ───────────────────────────────────────────────────────────────────\n\nexport const outlookSearchTool = tool(\n async ({ query, max_results }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const top = Math.min(Math.max(max_results ?? 25, 1), 100);\n // Use $search (KQL); Graph requires the ConsistencyLevel:eventual header\n // when $search is present on /messages.\n const params = new URLSearchParams({\n $top: String(top),\n $select: \"id,conversationId,subject,bodyPreview,from,toRecipients,ccRecipients,receivedDateTime,isRead,isDraft,hasAttachments,categories,parentFolderId,webLink\",\n });\n // $search wants a quoted KQL query; pass through whatever the agent supplied.\n params.set(\"$search\", `\"${query.replace(/\"/g, '\\\\\"')}\"`);\n const data = await graphFetch(\n auth,\n `/me/messages?${params.toString()}`,\n { headers: { ConsistencyLevel: \"eventual\" } },\n ) as { value?: GraphMessage[]; \"@odata.count\"?: number; \"@odata.nextLink\"?: string; error?: string };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n query,\n total_count: data[\"@odata.count\"] ?? null,\n next_link: data[\"@odata.nextLink\"] ?? null,\n messages: (data.value ?? []).map(summarizeMessage),\n });\n },\n {\n name: \"outlook_search\",\n description:\n \"Search the user's Outlook mailbox using KQL (Microsoft's keyword query language). \" +\n \"Returns message metadata (from, to, subject, received, snippet, labels) plus @odata.count \" +\n \"and next_link when available. Examples: \" +\n \"'from:notifications@github.com', 'subject:invoice hasAttachment:true', \" +\n \"'isRead:false received>=2026-05-17'. **Use this before calling outlook_get_message** — \" +\n \"the snippet is often enough.\",\n schema: z.object({\n query: z.string().describe(\"KQL query string\"),\n max_results: z.number().int().optional().describe(\"Max messages (default 25, max 100)\"),\n }),\n },\n);\n\nexport const outlookGetMessageTool = tool(\n async ({ id }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const m = await graphFetch(\n auth,\n `/me/messages/${encodeURIComponent(id)}`,\n ) as GraphMessage & { error?: string };\n if (m.error) return JSON.stringify(m);\n const summary = summarizeMessage(m);\n const rawBody = m.body?.content ?? \"\";\n const plain = m.body?.contentType === \"html\"\n ? stripHtml(rawBody, { preserveParagraphs: true })\n : rawBody;\n const { text: body, truncated } = truncateBytes(plain, BODY_CAP);\n return JSON.stringify({ ...summary, body, truncated });\n },\n {\n name: \"outlook_get_message\",\n description:\n \"Fetch one Outlook message by id, including full headers and the decoded text body \" +\n \"(HTML stripped to plain text when needed). Body capped at 30KB with `truncated:true` \" +\n \"when cut off.\",\n schema: z.object({\n id: z.string().describe(\"Outlook message id (from outlook_search results)\"),\n }),\n },\n);\n\nexport const outlookListFoldersTool = tool(\n async () => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await graphFetch(\n auth,\n \"/me/mailFolders?$top=100&$select=id,displayName,parentFolderId,totalItemCount,unreadItemCount,wellKnownName\",\n ) as { value?: GraphFolder[]; error?: string };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n folders: (data.value ?? []).map((f) => ({\n id: f.id,\n name: f.displayName ?? null,\n parent_id: f.parentFolderId ?? null,\n total: f.totalItemCount ?? 0,\n unread: f.unreadItemCount ?? 0,\n // Well-known shortcuts like 'inbox', 'drafts', 'sentitems',\n // 'deleteditems', 'junkemail', 'archive', 'outbox'. Useful as\n // stable ids when you need to move messages.\n well_known: f.wellKnownName ?? null,\n })),\n });\n },\n {\n name: \"outlook_list_folders\",\n description:\n \"List all Outlook mail folders. Use the `id` (or `well_known` name like 'inbox', \" +\n \"'drafts', 'sentitems', 'deleteditems', 'archive') with outlook_modify_message to move \" +\n \"a message between folders.\",\n schema: z.object({}),\n },\n);\n\nexport const outlookModifyMessageTool = tool(\n async ({ id, mark_read, move_to_folder }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (mark_read === undefined && !move_to_folder) {\n return JSON.stringify({ error: \"Provide mark_read and/or move_to_folder\" });\n }\n\n let lastResult: unknown = null;\n if (mark_read !== undefined) {\n const r = await graphFetch(\n auth,\n `/me/messages/${encodeURIComponent(id)}`,\n { method: \"PATCH\", body: JSON.stringify({ isRead: mark_read }) },\n ) as GraphMessage & { error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n lastResult = summarizeMessage(r);\n }\n if (move_to_folder) {\n // The /move action returns the **new** message resource (id changes\n // because Graph clones the item into the target folder).\n const r = await graphFetch(\n auth,\n `/me/messages/${encodeURIComponent(id)}/move`,\n { method: \"POST\", body: JSON.stringify({ destinationId: move_to_folder }) },\n ) as GraphMessage & { error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n lastResult = summarizeMessage(r);\n }\n return JSON.stringify(lastResult);\n },\n {\n name: \"outlook_modify_message\",\n description:\n \"Modify an Outlook message: mark read/unread and/or move to another folder. Use \" +\n \"`mark_read: true` to mark read, `mark_read: false` to mark unread. `move_to_folder` \" +\n \"accepts a folder id from outlook_list_folders or a well-known name (e.g. 'archive', \" +\n \"'deleteditems'). Note that moving returns a NEW message id because Graph clones the \" +\n \"item into the destination folder.\",\n schema: z.object({\n id: z.string().describe(\"Outlook message id\"),\n mark_read: z.boolean().optional().describe(\"Mark read (true) or unread (false)\"),\n move_to_folder: z.string().optional().describe(\"Destination folder id or well-known name\"),\n }),\n },\n);\n\nexport const outlookCreateDraftTool = tool(\n async ({ to, cc, subject, body, content_type }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const draft = {\n subject: subject ?? \"\",\n body: {\n contentType: content_type === \"html\" ? \"html\" : \"text\",\n content: body ?? \"\",\n },\n toRecipients: to.map((address) => ({ emailAddress: { address } })),\n ccRecipients: (cc ?? []).map((address) => ({ emailAddress: { address } })),\n };\n const r = await graphFetch(\n auth,\n \"/me/messages\",\n { method: \"POST\", body: JSON.stringify(draft) },\n ) as GraphMessage & { error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify({\n ...summarizeMessage(r),\n note: \"Saved to Drafts. The user must open Outlook to review and send.\",\n });\n },\n {\n name: \"outlook_create_draft\",\n description:\n \"Create an Outlook draft email (saved to the Drafts folder, NOT sent). The user opens \" +\n \"Outlook to review and click Send. `to` and `cc` are arrays of plain email addresses. \" +\n \"`content_type` defaults to 'text'; pass 'html' if `body` contains HTML markup.\",\n schema: z.object({\n to: z.array(z.string().email()).min(1).describe(\"Primary recipient emails\"),\n cc: z.array(z.string().email()).optional().describe(\"CC recipient emails\"),\n subject: z.string().optional().describe(\"Subject line\"),\n body: z.string().optional().describe(\"Email body\"),\n content_type: z.enum([\"text\", \"html\"]).optional().describe(\"Body content type (default 'text')\"),\n }),\n },\n);\n\nexport const outlookTrashMessageTool = tool(\n async ({ id }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Move to the user's Deleted Items folder (well-known shortcut). This\n // matches Gmail's \"trash, don't hard-delete\" behavior.\n const r = await graphFetch(\n auth,\n `/me/messages/${encodeURIComponent(id)}/move`,\n { method: \"POST\", body: JSON.stringify({ destinationId: \"deleteditems\" }) },\n ) as GraphMessage & { error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify({ ok: true, new_id: r.id });\n },\n {\n name: \"outlook_trash_message\",\n description:\n \"Move an Outlook message to Deleted Items (recoverable from the trash for 30 days). \" +\n \"Does NOT permanently delete. Returns the new message id assigned after the move.\",\n schema: z.object({\n id: z.string().describe(\"Outlook message id to trash\"),\n }),\n },\n);\n\nregisterTools(\"Mail\", [\n outlookSearchTool, outlookGetMessageTool, outlookListFoldersTool,\n outlookModifyMessageTool, outlookCreateDraftTool, outlookTrashMessageTool,\n]);\n","/**\n * Outlook Calendar tools via Microsoft Graph. Mirrors lib/tools/calendar.ts\n * (the Google Calendar set) one-for-one so the agent's mental model\n * carries over between providers.\n *\n * Graph differences vs Google Calendar worth knowing:\n * - Each event's start/end is { dateTime, timeZone } where timeZone is\n * a Windows-time-zone string by default (\"Pacific Standard Time\"),\n * not IANA. We pass an explicit `Prefer: outlook.timezone=\"UTC\"`\n * header so reads come back in UTC and the agent doesn't have to\n * navigate two TZ namespaces.\n * - Listing events in a window uses /calendarView (auto-expands\n * recurring series), parallel to Google's `singleEvents=true`.\n * - Online meetings use `isOnlineMeeting:true` +\n * `onlineMeetingProvider:\"teamsForBusiness\"`. Provisioning a Teams\n * link is gated behind `add_teams_link` to keep create_event cheap\n * when the agent just wants a plain event.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { registerTools } from \"./registry\";\nimport {\n graphFetch,\n resolveMicrosoftAuth,\n} from \"@/lib/integrations/microsoft-oauth\";\n\n// ── Graph type shapes (minimal subset) ──────────────────────────────────────\n\ninterface GraphCalendar {\n id?: string;\n name?: string;\n isDefaultCalendar?: boolean;\n canEdit?: boolean;\n owner?: { name?: string; address?: string };\n}\n\ninterface GraphDateTimeTimeZone {\n dateTime?: string;\n timeZone?: string;\n}\n\ninterface GraphAttendee {\n emailAddress?: { name?: string; address?: string };\n status?: { response?: string; time?: string };\n type?: string;\n}\n\ninterface GraphEvent {\n id?: string;\n subject?: string;\n bodyPreview?: string;\n body?: { contentType?: \"html\" | \"text\"; content?: string };\n start?: GraphDateTimeTimeZone;\n end?: GraphDateTimeTimeZone;\n location?: { displayName?: string };\n attendees?: GraphAttendee[];\n isAllDay?: boolean;\n isCancelled?: boolean;\n showAs?: string;\n webLink?: string;\n onlineMeeting?: { joinUrl?: string };\n onlineMeetingProvider?: string;\n}\n\nfunction slimEvent(e: GraphEvent): Record<string, unknown> {\n return {\n id: e.id,\n subject: e.subject ?? null,\n description: e.bodyPreview ?? null,\n location: e.location?.displayName ?? null,\n start: e.start?.dateTime ?? null,\n end: e.end?.dateTime ?? null,\n time_zone: e.start?.timeZone ?? e.end?.timeZone ?? null,\n attendees: (e.attendees ?? []).map((a) => ({\n email: a.emailAddress?.address ?? null,\n name: a.emailAddress?.name ?? null,\n response: a.status?.response ?? null,\n })),\n is_all_day: e.isAllDay === true,\n is_cancelled: e.isCancelled === true,\n show_as: e.showAs ?? null,\n teams_link: e.onlineMeeting?.joinUrl ?? null,\n web_link: e.webLink ?? null,\n };\n}\n\n// ── Tools ───────────────────────────────────────────────────────────────────\n\nexport const outlookCalendarListCalendarsTool = tool(\n async () => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await graphFetch(auth, \"/me/calendars\") as {\n value?: GraphCalendar[];\n error?: string;\n };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n calendars: (data.value ?? []).map((c) => ({\n id: c.id,\n name: c.name ?? null,\n is_default: c.isDefaultCalendar === true,\n can_edit: c.canEdit === true,\n owner: c.owner?.address ?? null,\n })),\n });\n },\n {\n name: \"outlook_calendar_list_calendars\",\n description:\n \"List the user's Outlook calendars (primary + shared). Returns id, name, \" +\n \"is_default flag, edit permission, owner. The `id` is what other \" +\n \"outlook_calendar_* tools expect as `calendar_id`. Omit `calendar_id` \" +\n \"in those tools to use the user's default calendar.\",\n schema: z.object({}),\n },\n);\n\nexport const outlookCalendarListEventsTool = tool(\n async ({ calendar_id, time_min, time_max, max_results }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const now = new Date();\n const inAWeek = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);\n const startISO = time_min ?? now.toISOString();\n const endISO = time_max ?? inAWeek.toISOString();\n const top = Math.min(Math.max(max_results ?? 25, 1), 100);\n // /calendarView expands recurring series into individual instances —\n // the closest parallel to Google's singleEvents=true.\n const base = calendar_id\n ? `/me/calendars/${encodeURIComponent(calendar_id)}/calendarView`\n : \"/me/calendarView\";\n const params = new URLSearchParams({\n startDateTime: startISO,\n endDateTime: endISO,\n $top: String(top),\n $orderby: \"start/dateTime\",\n });\n const data = await graphFetch(auth, `${base}?${params.toString()}`, {\n // Force UTC in responses so the agent doesn't juggle Windows-TZ names.\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n }) as { value?: GraphEvent[]; error?: string };\n if (\"error\" in data && data.error) return JSON.stringify(data);\n return JSON.stringify({\n events: (data.value ?? []).map(slimEvent),\n });\n },\n {\n name: \"outlook_calendar_list_events\",\n description:\n \"List Outlook calendar events within a time window. Defaults: default \" +\n \"calendar, now → +7 days, ordered by start, recurring series expanded. \" +\n \"**Use this before creating an event** to avoid double-booking, and to \" +\n \"look up event ids before updating/deleting. All datetimes returned in \" +\n \"UTC (RFC3339 'Z'-suffixed).\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: user's default calendar)\"),\n time_min: z.string().optional().describe(\"RFC3339 lower bound (default: now)\"),\n time_max: z.string().optional().describe(\"RFC3339 upper bound (default: now + 7 days)\"),\n max_results: z.number().int().optional().describe(\"Max events (default 25, max 100)\"),\n }),\n },\n);\n\nexport const outlookCalendarGetEventTool = tool(\n async ({ event_id }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const e = await graphFetch(auth, `/me/events/${encodeURIComponent(event_id)}`, {\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n }) as GraphEvent & { error?: string };\n if (e.error) return JSON.stringify({ error: e.error });\n return JSON.stringify(slimEvent(e));\n },\n {\n name: \"outlook_calendar_get_event\",\n description:\n \"Fetch one Outlook calendar event by id. Returns the same slim shape as \" +\n \"outlook_calendar_list_events but for a single event.\",\n schema: z.object({\n event_id: z.string().describe(\"Event id (from outlook_calendar_list_events)\"),\n }),\n },\n);\n\nexport const outlookCalendarCreateEventTool = tool(\n async ({\n calendar_id, subject, start_iso, end_iso, description, location,\n attendees, time_zone, add_teams_link,\n }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n interface EventBody {\n subject: string;\n body?: { contentType: \"text\"; content: string };\n start: GraphDateTimeTimeZone;\n end: GraphDateTimeTimeZone;\n location?: { displayName: string };\n attendees?: Array<{ emailAddress: { address: string }; type: \"required\" }>;\n isOnlineMeeting?: boolean;\n onlineMeetingProvider?: string;\n }\n // Graph uses Windows TZ names by default but also accepts IANA names\n // when the body specifies them per-field. Default to UTC if the\n // caller omits time_zone (matches the list endpoint's behavior).\n const tz = time_zone ?? \"UTC\";\n const body: EventBody = {\n subject,\n start: { dateTime: start_iso, timeZone: tz },\n end: { dateTime: end_iso, timeZone: tz },\n };\n if (description) body.body = { contentType: \"text\", content: description };\n if (location) body.location = { displayName: location };\n if (attendees && attendees.length > 0) {\n body.attendees = attendees.map((address) => ({\n emailAddress: { address },\n type: \"required\" as const,\n }));\n }\n if (add_teams_link) {\n body.isOnlineMeeting = true;\n body.onlineMeetingProvider = \"teamsForBusiness\";\n }\n\n const path = calendar_id\n ? `/me/calendars/${encodeURIComponent(calendar_id)}/events`\n : \"/me/events\";\n const r = await graphFetch(auth, path, {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n }) as GraphEvent & { error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify(slimEvent(r));\n },\n {\n name: \"outlook_calendar_create_event\",\n description:\n \"Create an Outlook calendar event. Datetimes are RFC3339 strings; pair \" +\n \"with `time_zone` (IANA like 'America/Los_Angeles' or Windows TZ like \" +\n \"'Pacific Standard Time') so Outlook interprets them correctly. Defaults \" +\n \"to UTC if omitted. Attendees are automatically sent invites. Set \" +\n \"`add_teams_link: true` to provision a Teams meeting URL (requires a \" +\n \"work/school M365 account; personal Microsoft accounts cannot create \" +\n \"Teams meetings via Graph).\",\n schema: z.object({\n calendar_id: z.string().optional().describe(\"Calendar id (default: user's default calendar)\"),\n subject: z.string().min(1).describe(\"Event title shown on the calendar\"),\n start_iso: z.string().describe(\"Start datetime, RFC3339\"),\n end_iso: z.string().describe(\"End datetime, RFC3339 (must be after start)\"),\n description: z.string().optional().describe(\"Long-form event body (plain text)\"),\n location: z.string().optional().describe(\"Free-text location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Invitee email addresses\"),\n time_zone: z.string().optional().describe(\"IANA or Windows timezone (default 'UTC')\"),\n add_teams_link: z.boolean().optional().describe(\"Provision a Teams meeting URL on this event\"),\n }),\n },\n);\n\nexport const outlookCalendarUpdateEventTool = tool(\n async ({\n event_id, subject, start_iso, end_iso, description, location,\n attendees, time_zone,\n }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n const tz = time_zone ?? \"UTC\";\n const patch: Record<string, unknown> = {};\n if (subject !== undefined) patch.subject = subject;\n if (description !== undefined) patch.body = { contentType: \"text\", content: description };\n if (location !== undefined) patch.location = { displayName: location };\n if (start_iso !== undefined) patch.start = { dateTime: start_iso, timeZone: tz };\n if (end_iso !== undefined) patch.end = { dateTime: end_iso, timeZone: tz };\n if (attendees !== undefined) {\n patch.attendees = attendees.map((address) => ({\n emailAddress: { address },\n type: \"required\" as const,\n }));\n }\n if (Object.keys(patch).length === 0) {\n return JSON.stringify({ error: \"Provide at least one field to update\" });\n }\n\n const r = await graphFetch(\n auth,\n `/me/events/${encodeURIComponent(event_id)}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(patch),\n headers: { Prefer: 'outlook.timezone=\"UTC\"' },\n },\n ) as GraphEvent & { error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify(slimEvent(r));\n },\n {\n name: \"outlook_calendar_update_event\",\n description:\n \"Patch an Outlook calendar event. Only supplied fields are changed; omit \" +\n \"fields to leave them alone. Note `attendees` REPLACES the full invitee \" +\n \"list, so include everyone who should remain.\",\n schema: z.object({\n event_id: z.string().describe(\"Event id\"),\n subject: z.string().optional().describe(\"New event title\"),\n start_iso: z.string().optional().describe(\"New start datetime, RFC3339\"),\n end_iso: z.string().optional().describe(\"New end datetime, RFC3339\"),\n description: z.string().optional().describe(\"New event body (plain text)\"),\n location: z.string().optional().describe(\"New location string\"),\n attendees: z.array(z.string().email()).optional().describe(\"Replacement attendee list\"),\n time_zone: z.string().optional().describe(\"IANA or Windows TZ applied to start/end (default 'UTC')\"),\n }),\n },\n);\n\nexport const outlookCalendarDeleteEventTool = tool(\n async ({ event_id }) => {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const r = await graphFetch(\n auth,\n `/me/events/${encodeURIComponent(event_id)}`,\n { method: \"DELETE\" },\n ) as { ok?: boolean; error?: string };\n if (r.error) return JSON.stringify({ error: r.error });\n return JSON.stringify({ ok: true, id: event_id });\n },\n {\n name: \"outlook_calendar_delete_event\",\n description:\n \"Delete an Outlook calendar event by id. Attendees are notified. Returns \" +\n \"`{ ok: true, id }` on success. Use outlook_calendar_list_events to find \" +\n \"the event id first if you only know the title/time.\",\n schema: z.object({\n event_id: z.string().describe(\"Event id to delete\"),\n }),\n },\n);\n\nregisterTools(\"Calendar\", [\n outlookCalendarListCalendarsTool, outlookCalendarListEventsTool,\n outlookCalendarGetEventTool, outlookCalendarCreateEventTool,\n outlookCalendarUpdateEventTool, outlookCalendarDeleteEventTool,\n]);\n","// Barrel of built-in tool modules. Each side-effect import triggers the\n// module's `registerTools(...)` call (see ./registry.ts). Adding a new\n// built-in tool: add the file under lib/tools/ and append a line here.\n//\n// Order matters only for deterministic logging / UI ordering — registry\n// preserves insertion order.\n\nimport \"./memory\";\nimport \"./documents\";\nimport \"./exec\";\nimport \"./files\";\nimport \"./search\";\nimport \"./fetch\";\nimport \"./location\";\nimport \"./generate_image\";\nimport \"./generate_voice\";\nimport \"./schedule\";\nimport \"./watcher\";\nimport \"./propose\";\nimport \"./integrations\";\nimport \"./atlassian\";\nimport \"./jira-align\";\nimport \"./github\";\nimport \"./gmail\";\nimport \"./calendar\";\nimport \"./outlook\";\nimport \"./outlook-calendar\";\n","import { getDb } from \"@/lib/db\";\nimport { encrypt, decryptIfNeeded } from \"@/lib/crypto/envelope\";\n\nconst now = () => new Date().toISOString();\n\nexport type McpTransport = \"stdio\" | \"http\";\n\nexport interface McpStdioSpec {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\nexport interface McpHttpSpec {\n url: string;\n headers?: Record<string, string>;\n}\n\nexport interface McpServerRow {\n name: string;\n transport: McpTransport;\n spec: string; // JSON-encoded McpStdioSpec | McpHttpSpec\n enabled: number; // 0 | 1\n last_error: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface McpServerInput {\n name: string;\n transport: McpTransport;\n spec: McpStdioSpec | McpHttpSpec;\n enabled?: boolean;\n}\n\n// `spec` may contain MCP env vars like GITHUB_TOKEN, GOOGLE_MAPS_API_KEY,\n// BRAVE_API_KEY etc. — encrypted at rest (ADR-0005). Decrypt on read.\nfunction decryptRow<T extends { spec: string }>(row: T): T {\n return { ...row, spec: decryptIfNeeded(row.spec) };\n}\n\nexport function listMcpServers(): McpServerRow[] {\n const rows = getDb()\n .prepare(\"SELECT * FROM mcp_servers ORDER BY name ASC\")\n .all() as unknown as McpServerRow[];\n return rows.map(decryptRow);\n}\n\nexport function getMcpServer(name: string): McpServerRow | null {\n const row = (getDb()\n .prepare(\"SELECT * FROM mcp_servers WHERE name=?\")\n .get(name) as unknown as McpServerRow) ?? null;\n return row ? decryptRow(row) : null;\n}\n\nexport function upsertMcpServer(input: McpServerInput): McpServerRow {\n const t = now();\n const existing = getMcpServer(input.name);\n const created_at = existing?.created_at ?? t;\n const enabled = input.enabled === false ? 0 : 1;\n getDb()\n .prepare(\n `INSERT OR REPLACE INTO mcp_servers (name, transport, spec, enabled, last_error, created_at, updated_at)\n VALUES (?, ?, ?, ?, NULL, ?, ?)`,\n )\n .run(input.name, input.transport, encrypt(JSON.stringify(input.spec)), enabled, created_at, t);\n return getMcpServer(input.name)!;\n}\n\nexport function deleteMcpServer(name: string): boolean {\n return (getDb()\n .prepare(\"DELETE FROM mcp_servers WHERE name=?\")\n .run(name) as { changes: number }).changes > 0;\n}\n\nexport function setMcpServerError(name: string, error: string | null): void {\n getDb()\n .prepare(\"UPDATE mcp_servers SET last_error=?, updated_at=? WHERE name=?\")\n .run(error, now(), name);\n}\n","import type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport {\n listMcpServers,\n setMcpServerError,\n type McpServerRow,\n type McpHttpSpec,\n type McpStdioSpec,\n} from \"@/lib/stores/mcp-servers\";\nimport { getInjectedSubprocessEnv } from \"@/lib/env/allowlist\";\n\n// Singleton MCP client manager. Connects to enabled servers on first access,\n// caches the resulting StructuredTools, and invalidates on configuration\n// changes (when the API CRUD endpoints touch the table they call refresh()).\n//\n// We intentionally don't keep stdio child processes alive forever — the\n// MultiServerMCPClient owns connections, and if a server is disabled or\n// removed we close the existing client and rebuild on next access.\n\nlet cachedTools: StructuredToolInterface[] | null = null;\nlet cacheKey = \"\"; // hash of the enabled server set; cache invalidated on change\nlet pending: Promise<StructuredToolInterface[]> | null = null;\nlet activeClient: { close: () => Promise<void> } | null = null;\n\nfunction specHash(rows: McpServerRow[]): string {\n // Only enabled servers matter. Order by name so the hash is stable.\n return rows\n .filter((r) => r.enabled === 1)\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((r) => `${r.name}:${r.transport}:${r.spec}`)\n .join(\"|\");\n}\n\nexport async function getMcpTools(): Promise<StructuredToolInterface[]> {\n const rows = listMcpServers();\n const enabled = rows.filter((r) => r.enabled === 1);\n const key = specHash(rows);\n\n if (cachedTools && cacheKey === key) return cachedTools;\n if (pending) return pending;\n\n if (enabled.length === 0) {\n cachedTools = [];\n cacheKey = key;\n return cachedTools;\n }\n\n pending = (async () => {\n // Close prior client if we're rebuilding due to a config change.\n if (activeClient) {\n try { await activeClient.close(); } catch { /* swallow */ }\n activeClient = null;\n }\n\n const { MultiServerMCPClient } = await import(\"@langchain/mcp-adapters\");\n\n // Connect each server in its own client so one broken server (e.g. missing\n // `uvx` on PATH, bad API key) doesn't poison the others. Previously a\n // single MultiServerMCPClient.getTools() throw would mark ALL enabled\n // servers with the same error message — confusing because the UI showed\n // e.g. google-maps tagged with the `time` server's connection error.\n const tools: StructuredToolInterface[] = [];\n const subClients: Array<{ close: () => Promise<void> }> = [];\n\n for (const row of enabled) {\n let serverConfig: Record<string, unknown>;\n try {\n const spec = JSON.parse(row.spec) as McpStdioSpec | McpHttpSpec;\n if (row.transport === \"stdio\") {\n const s = spec as McpStdioSpec;\n serverConfig = {\n transport: \"stdio\",\n command: s.command,\n args: s.args ?? [],\n // Inherit host env (PATH, HOME, proxies, registry configs) and\n // layer spec.env on top. See buildSubprocessEnv below.\n env: buildSubprocessEnv(s.env ?? {}),\n };\n } else {\n const s = spec as McpHttpSpec;\n serverConfig = {\n transport: \"http\",\n url: s.url,\n headers: s.headers ?? {},\n };\n }\n } catch (err) {\n setMcpServerError(row.name, `bad spec: ${err instanceof Error ? err.message : String(err)}`);\n continue;\n }\n\n try {\n const client = new MultiServerMCPClient({\n mcpServers: { [row.name]: serverConfig },\n throwOnLoadError: false,\n } as ConstructorParameters<typeof MultiServerMCPClient>[0]);\n const serverTools = (await client.getTools()) as unknown as StructuredToolInterface[];\n tools.push(...serverTools);\n subClients.push(client as unknown as { close: () => Promise<void> });\n setMcpServerError(row.name, null);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[mcp] server \"${row.name}\" failed:`, msg);\n setMcpServerError(row.name, msg);\n }\n }\n\n activeClient = {\n close: async () => {\n await Promise.allSettled(subClients.map((c) => c.close()));\n },\n };\n cachedTools = tools;\n cacheKey = key;\n return tools;\n })();\n\n try {\n return await pending;\n } finally {\n pending = null;\n }\n}\n\n// Called by API endpoints when a server is added/edited/deleted/toggled so\n// the next getAllTools() call re-resolves connections.\nexport function invalidateMcpTools(): void {\n cachedTools = null;\n cacheKey = \"\";\n if (activeClient) {\n activeClient.close().catch(() => { /* */ });\n activeClient = null;\n }\n}\n\n// ── Subprocess environment ──────────────────────────────────────────────────\n// Be transparent: whatever the host can reach, the subprocess can reach.\n//\n// Why this design:\n// - On a clean machine (no JFrog, no special config), uv/npm fall through to\n// their public defaults. Nothing extra needed.\n// - On a corporate machine (JFrog or Artifactory in env / ~/.config/uv/uv.toml /\n// ~/.npmrc), public PyPI/npm are usually blocked at the network layer.\n// The user's existing config is the ONLY thing that works — so inherit it.\n// - Per-server overrides still work: spec.env wins over inherited env, so a\n// user who wants this specific server pinned to a custom registry can do\n// so without affecting everything else.\n//\n// The MCP SDK's default behavior (a curated minimal env) breaks corporate\n// installs because it strips registry env vars; we explicitly opt out of that.\n\n// Only a few env vars are worth scrubbing — the ones that actively confuse\n// stdio MCP processes or leak our internal state. Everything else flows.\nconst SCRUBBED_VARS = new Set([\n // Our own DB path — irrelevant to MCP servers, and exposes our layout.\n \"JARELA_DB_DIR\",\n // Defensive: don't leak npm/yarn auth tokens into a stdio child unless\n // the server explicitly opted in via spec.env. (Most public MCP packages\n // don't need auth to install.)\n \"NPM_TOKEN\", \"NODE_AUTH_TOKEN\",\n]);\n\nfunction buildSubprocessEnv(userEnv: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {};\n\n // 1. Inherit the host process env wholesale. This carries through:\n // - PATH (so uvx, npx, python, node are findable)\n // - HOME (so uv/pip/npm read user-level config files like ~/.config/uv/uv.toml,\n // ~/.npmrc, ~/.pip/pip.conf — which may pin JFrog, Artifactory, etc.)\n // - HTTP_PROXY / HTTPS_PROXY / NO_PROXY (corporate proxy routing)\n // - UV_INDEX_URL / PIP_INDEX_URL / npm_config_registry if the user set\n // them — letting their JFrog or Artifactory setup work transparently\n // - Locale, terminal, etc.\n for (const [k, v] of Object.entries(process.env)) {\n if (typeof v !== \"string\") continue;\n if (SCRUBBED_VARS.has(k)) continue;\n out[k] = v;\n }\n\n // 2. Inject env-sync-managed credentials from the encrypted integration\n // store. Service-mode installs (launchd, systemd, brew services)\n // start with no shell env, so ANTHROPIC_API_KEY / GITHUB_TOKEN / …\n // have to come from the store or downstream tools see nothing. This\n // layer goes after process.env so that when the store has been\n // refreshed by env-sync, the new value wins over a stale shell\n // export.\n for (const [k, v] of Object.entries(getInjectedSubprocessEnv())) {\n out[k] = v;\n }\n\n // 3. Per-server spec.env layered on top — user's explicit config always\n // wins. Use this to (a) supply API keys, (b) pin THIS server to a\n // specific registry without affecting the rest, or (c) unset something\n // via empty string.\n for (const [k, v] of Object.entries(userEnv)) {\n if (typeof v === \"string\") out[k] = v;\n }\n\n return out;\n}\n","// Encrypted-at-rest secrets for external tools (ADR-0023).\n//\n// External tools declare secret \"slots\" in their module.exports:\n// secrets: [{ key: \"api_key\", label: \"OpenWeather API key\", required: true }]\n//\n// Values are persisted in the `tool-secrets` namespace of the memory store\n// (which is flagged sensitive in lib/crypto/sensitive.ts, so envelope\n// encryption applies — same primitive as the integrations store).\n//\n// Keys are stored as `<toolName>:<slotKey>`. Tool names and slot keys are\n// validated to a conservative character set so they can't collide with the\n// namespace delimiter or smuggle SQL/JSON metacharacters.\n//\n// Note on isolation: external tools run in-process with full Node privileges\n// (ADR-0013), so a malicious tool could read another tool's secrets by going\n// around this API (e.g. directly opening the SQLite file). The per-tool\n// scoping here is a *convention* surfaced through `ctx.getSecret`, not a\n// sandbox boundary.\n\nimport { getMemory, putMemory, deleteMemory, listMemory } from \"@/lib/stores/memory\";\n\nconst NAMESPACE = \"tool-secrets\";\nconst NAME_RE = /^[a-z0-9_-]+$/i;\n\nexport interface ToolSecretSlot {\n key: string;\n label?: string;\n required?: boolean;\n description?: string;\n}\n\nfunction validName(s: string): boolean {\n return typeof s === \"string\" && s.length > 0 && s.length <= 64 && NAME_RE.test(s);\n}\n\nfunction compoundKey(toolName: string, key: string): string {\n return `${toolName}:${key}`;\n}\n\nfunction parseStored(raw: string): string | null {\n try {\n const v = JSON.parse(raw);\n return typeof v === \"string\" ? v : null;\n } catch {\n return null;\n }\n}\n\nexport function getToolSecret(toolName: string, key: string): string | null {\n if (!validName(toolName) || !validName(key)) return null;\n const row = getMemory(NAMESPACE, compoundKey(toolName, key));\n if (!row) return null;\n return parseStored(row.value);\n}\n\nexport function setToolSecret(toolName: string, key: string, value: string): void {\n if (!validName(toolName)) throw new Error(`invalid tool name: ${toolName}`);\n if (!validName(key)) throw new Error(`invalid secret key: ${key}`);\n if (typeof value !== \"string\") throw new Error(\"secret value must be a string\");\n putMemory(NAMESPACE, compoundKey(toolName, key), value);\n}\n\nexport function deleteToolSecret(toolName: string, key: string): boolean {\n if (!validName(toolName) || !validName(key)) return false;\n return deleteMemory(NAMESPACE, compoundKey(toolName, key));\n}\n\n// Returns which declared slots have a value persisted. Never returns the\n// plaintext — that only escapes via `ctx.getSecret` inside the tool's own\n// run loop.\nexport function describeToolSecrets(\n toolName: string,\n slots: ToolSecretSlot[],\n): Array<ToolSecretSlot & { is_set: boolean }> {\n if (!validName(toolName)) return slots.map((s) => ({ ...s, is_set: false }));\n return slots.map((s) => ({\n ...s,\n is_set: getToolSecret(toolName, s.key) !== null,\n }));\n}\n\n// Delete every persisted secret for a tool — used when an external tool\n// file is removed and the operator wants to clear stale credentials.\nexport function purgeToolSecrets(toolName: string): number {\n if (!validName(toolName)) return 0;\n const prefix = `${toolName}:`;\n const rows = listMemory(NAMESPACE, undefined, 1000).filter((r) =>\n r.key.startsWith(prefix),\n );\n let n = 0;\n for (const r of rows) {\n if (deleteMemory(NAMESPACE, r.key)) n++;\n }\n return n;\n}\n","import { join } from \"node:path\";\nimport { existsSync, readdirSync, statSync } from \"node:fs\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { tool } from \"@langchain/core/tools\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { getConfig } from \"@/lib/env/config\";\nimport { getToolSecret, type ToolSecretSlot } from \"@/lib/stores/tool-secrets\";\nimport type { ToolCategory } from \"./registry\";\n\n/**\n * Absolute path to the external tools directory. Resolved lazily from\n * `getConfig().toolsDir` so JARELA_TOOLS_DIR (and JARELA_DB_DIR fallback)\n * are honoured.\n */\nexport function getToolsDir(): string {\n return getConfig().toolsDir;\n}\n\nexport interface ExternalToolDef {\n name: string;\n description: string;\n schema: object;\n category?: ToolCategory;\n // Optional per-tool secret slots. Surfaced in the Extensions panel as\n // editable form fields; persisted (encrypted at rest) in the\n // `tool-secrets` memory namespace. Read at run time via `ctx.getSecret`.\n // See ADR-0023.\n secrets?: ToolSecretSlot[];\n run: (\n args: Record<string, unknown>,\n ctx: {\n thread_id?: string;\n // Returns the persisted secret for this tool's slot, or `null` if\n // it has not been configured. Always scoped to the current tool —\n // a tool cannot read another tool's secrets via this helper.\n getSecret: (key: string) => string | null;\n },\n ) => unknown | Promise<unknown>;\n}\n\nexport interface ExtensionLoadError {\n file: string;\n error: string;\n}\n\nexport interface ExternalToolsResult {\n tools: StructuredToolInterface[];\n categories: Map<string, ToolCategory>;\n files: Map<string, string>;\n // Declared secret slots per tool name (empty array if the tool did not\n // declare any). Used by the Extensions panel to render input fields.\n secrets: Map<string, ToolSecretSlot[]>;\n errors: ExtensionLoadError[];\n}\n\nfunction isValidSlot(v: unknown): v is ToolSecretSlot {\n if (!v || typeof v !== \"object\") return false;\n const o = v as Record<string, unknown>;\n if (typeof o.key !== \"string\" || !/^[a-z0-9_-]+$/i.test(o.key)) return false;\n if (o.label !== undefined && typeof o.label !== \"string\") return false;\n if (o.required !== undefined && typeof o.required !== \"boolean\") return false;\n if (o.description !== undefined && typeof o.description !== \"string\") return false;\n return true;\n}\n\nfunction isValid(p: unknown): p is ExternalToolDef {\n if (!p || typeof p !== \"object\") return false;\n const o = p as Record<string, unknown>;\n if (\n typeof o.name !== \"string\" ||\n o.name.trim() === \"\" ||\n typeof o.description !== \"string\" ||\n typeof o.schema !== \"object\" ||\n o.schema === null ||\n typeof o.run !== \"function\"\n ) return false;\n if (o.secrets !== undefined) {\n if (!Array.isArray(o.secrets)) return false;\n if (!o.secrets.every(isValidSlot)) return false;\n }\n return true;\n}\n\nexport function loadExternalTools(\n builtinNames: ReadonlySet<string>,\n): ExternalToolsResult {\n const tools: StructuredToolInterface[] = [];\n const categories = new Map<string, ToolCategory>();\n const files = new Map<string, string>();\n const secrets = new Map<string, ToolSecretSlot[]>();\n const errors: ExtensionLoadError[] = [];\n\n const toolsDir = getToolsDir();\n if (!existsSync(toolsDir)) {\n return { tools, categories, files, secrets, errors };\n }\n\n // Same trick as lib/providers/external.ts: bypass webpack's static analysis\n // so the dynamic require survives the Next build.\n const { createRequire } = (\n process as unknown as { getBuiltinModule: (id: string) => typeof import(\"node:module\") }\n ).getBuiltinModule(\"node:module\");\n const req = createRequire(join(toolsDir, \"_anchor\"));\n\n let entries: string[];\n try {\n entries = readdirSync(toolsDir);\n } catch {\n return { tools, categories, files, secrets, errors };\n }\n\n const seen = new Set<string>();\n\n for (const entry of entries) {\n if (!/\\.(c?js|ts)$/i.test(entry)) continue;\n const path = join(toolsDir, entry);\n try {\n if (!statSync(path).isFile()) continue;\n } catch {\n continue;\n }\n\n let mod: unknown;\n try {\n delete req.cache[req.resolve(path)];\n mod = req(path);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n errors.push({ file: entry, error: message });\n console.error(`[tools] failed to load ${entry}:`, err);\n continue;\n }\n\n const candidate =\n (mod as { default?: unknown })?.default ?? (mod as unknown);\n if (!isValid(candidate)) {\n const msg =\n \"does not export a valid ExternalToolDef (need { name, description, schema, run })\";\n errors.push({ file: entry, error: msg });\n console.error(`[tools] ${entry} ${msg}`);\n continue;\n }\n\n const def = candidate;\n if (builtinNames.has(def.name)) {\n const msg = `name \"${def.name}\" collides with a built-in tool — built-in takes precedence`;\n errors.push({ file: entry, error: msg });\n console.warn(`[tools] external ${entry}: ${msg}`);\n continue;\n }\n if (seen.has(def.name)) {\n const msg = `duplicate external tool \"${def.name}\"`;\n errors.push({ file: entry, error: msg });\n console.warn(`[tools] ${entry}: ${msg}`);\n continue;\n }\n seen.add(def.name);\n\n const wrapped = tool(\n async (args: unknown, _runManager?: unknown, config?: RunnableConfig) => {\n const ctx = {\n thread_id: config?.configurable?.thread_id as string | undefined,\n getSecret: (key: string) => getToolSecret(def.name, key),\n };\n const result = await def.run(args as Record<string, unknown>, ctx);\n return typeof result === \"string\" ? result : JSON.stringify(result);\n },\n {\n name: def.name,\n description: def.description,\n schema: def.schema as never,\n },\n ) as unknown as StructuredToolInterface;\n\n tools.push(wrapped);\n files.set(def.name, entry);\n if (def.category) categories.set(def.name, def.category);\n secrets.set(def.name, def.secrets ?? []);\n }\n\n return { tools, categories, files, secrets, errors };\n}\n","// Built-in tool category toggles.\n//\n// A category is \"enabled\" unless an explicit row in `builtin_tool_categories`\n// says otherwise. Default-enabled semantics mean upgrading installs keep\n// every category working with zero migration work.\n//\n// Disabled categories are filtered at three layers:\n// - GET /api/v1/tools (so the agent editor never offers them as permissions)\n// - getAllTools / getAllToolsAsync (so the agent runtime can't see them)\n// - executeTool (defense in depth, blocks stale agent configs)\n\nimport { getDb } from \"@/lib/db\";\nimport type { BuiltinCategory } from \"@/lib/tools/registry\";\n\ninterface Row {\n category: string;\n enabled: number;\n updated_at: string;\n}\n\nconst now = () => new Date().toISOString();\n\nexport function isCategoryEnabled(category: BuiltinCategory): boolean {\n const row = getDb()\n .prepare(\"SELECT enabled FROM builtin_tool_categories WHERE category=?\")\n .get(category) as { enabled: number } | undefined;\n return row ? row.enabled === 1 : true;\n}\n\nexport function disabledCategories(): Set<BuiltinCategory> {\n const rows = getDb()\n .prepare(\"SELECT category FROM builtin_tool_categories WHERE enabled=0\")\n .all() as unknown as Array<{ category: string }>;\n return new Set(rows.map((r) => r.category as BuiltinCategory));\n}\n\nexport function listCategoryStates(): Array<{ category: string; enabled: boolean; updated_at: string | null }> {\n const rows = getDb()\n .prepare(\"SELECT category, enabled, updated_at FROM builtin_tool_categories\")\n .all() as unknown as Row[];\n return rows.map((r) => ({\n category: r.category,\n enabled: r.enabled === 1,\n updated_at: r.updated_at,\n }));\n}\n\nexport function setCategoryEnabled(category: BuiltinCategory, enabled: boolean): void {\n getDb()\n .prepare(\n `INSERT INTO builtin_tool_categories (category, enabled, updated_at)\n VALUES (?, ?, ?)\n ON CONFLICT(category) DO UPDATE SET enabled=excluded.enabled, updated_at=excluded.updated_at`,\n )\n .run(category, enabled ? 1 : 0, now());\n}\n","// Public tool surface for the agent runtime.\n//\n// Built-in tools register themselves at module load (see ./registry.ts and\n// ./builtins.ts). External tools live under JARELA_TOOLS_DIR and are\n// loaded per-call (hot-reload). MCP tools come from lib/mcp/client.ts.\n//\n// To add a new built-in tool:\n// 1. Copy lib/tools/template.ts to lib/tools/<name>.ts and implement it.\n// 2. Call `registerTools(\"<Category>\", [yourTool, ...])` at the bottom.\n// 3. Add `import \"./<name>\";` to lib/tools/builtins.ts.\n//\n// That's it — no central array to update, no parallel category map.\n\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { convertToOpenAITool } from \"@langchain/core/utils/function_calling\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\n\n// Side-effect import: triggers registerTools() in every built-in module.\nimport \"./builtins\";\n\nimport {\n registeredTools,\n registeredNames,\n registeredCategory,\n registeredGroup,\n type ToolCategory,\n type ToolGroup,\n} from \"./registry\";\nimport { getMcpTools } from \"@/lib/mcp/client\";\nimport {\n loadExternalTools,\n getToolsDir,\n type ExtensionLoadError,\n} from \"./external\";\nimport type { OpenAITool, ToolContext, ToolParamSchema } from \"./types\";\nimport type { ToolPolicy } from \"@/lib/agents/base\";\nimport { disabledCategories } from \"@/lib/stores/builtin-tools\";\n\nexport * from \"./types\";\nexport { getToolsDir, type ExtensionLoadError } from \"./external\";\nexport { registerTools, type ToolCategory, type ToolGroup } from \"./registry\";\n\nconst ALL_BUILTINS: StructuredToolInterface[] = registeredTools();\nexport const BUILTIN_TOOL_NAMES: ReadonlySet<string> = registeredNames();\n\n// Per-call recompute so files dropped in $JARELA_TOOLS_DIR are picked up\n// without restart. loadExternalTools cache-busts require() per file.\nfunction loadExternal() {\n return loadExternalTools(BUILTIN_TOOL_NAMES);\n}\n\nexport function getToolCategory(name: string, source: \"builtin\" | \"mcp\"): ToolCategory {\n const builtin = registeredCategory(name);\n if (builtin) return builtin;\n const ext = loadExternal().categories.get(name);\n if (ext) return ext;\n return source === \"mcp\" ? \"MCP\" : \"Config\";\n}\n\nexport function getToolGroup(name: string, source: \"builtin\" | \"mcp\"): ToolGroup {\n const cat = getToolCategory(name, source);\n if (cat === \"MCP\") return null;\n return registeredGroup(name) ?? null;\n}\n\nfunction applyPolicy(\n tools: StructuredToolInterface[],\n policy?: ToolPolicy,\n): StructuredToolInterface[] {\n const allowSet = policy?.allow?.length ? new Set(policy.allow) : null;\n const denySet = policy?.deny?.length ? new Set(policy.deny) : null;\n return tools.filter((t) => {\n if (allowSet && !allowSet.has(t.name)) return false;\n if (denySet && denySet.has(t.name)) return false;\n return true;\n });\n}\n\n// Filter built-in tools whose category is disabled in the toggle store.\n// External + MCP tools are untouched (they have their own enable surfaces).\nfunction applyCategoryToggles(tools: StructuredToolInterface[]): StructuredToolInterface[] {\n const disabled = disabledCategories();\n if (disabled.size === 0) return tools;\n return tools.filter((t) => {\n const cat = registeredCategory(t.name);\n if (!cat) return true; // not a built-in (or unregistered) → leave it\n return !disabled.has(cat);\n });\n}\n\n// Synchronous: built-in + external tools (no MCP). Used by GET /api/v1/tools\n// and any code path that can't await.\nexport function getAllTools(policy?: ToolPolicy): StructuredToolInterface[] {\n return applyPolicy(\n [...applyCategoryToggles(ALL_BUILTINS), ...loadExternal().tools],\n policy,\n );\n}\n\n// Async: built-in + external + MCP tools.\n// Use this anywhere the agent might invoke tools (createReactAgent input).\n// External tools are loaded per-call (hot-reload). MCP tools are cached by\n// lib/mcp/client.ts and only re-resolved when the mcp_servers table changes.\nexport async function getAllToolsAsync(policy?: ToolPolicy): Promise<StructuredToolInterface[]> {\n let mcpTools: StructuredToolInterface[] = [];\n try {\n mcpTools = await getMcpTools();\n } catch (err) {\n console.error(\"[tools] MCP load failed, continuing with built-ins only:\", err);\n }\n return applyPolicy(\n [...applyCategoryToggles(ALL_BUILTINS), ...loadExternal().tools, ...mcpTools],\n policy,\n );\n}\n\nexport function toOpenAITools(tools: StructuredToolInterface[]): OpenAITool[] {\n return tools.map((t) => {\n const oai = convertToOpenAITool(t);\n return {\n type: \"function\",\n function: {\n name: oai.function.name,\n description: oai.function.description ?? \"\",\n parameters: oai.function.parameters as ToolParamSchema,\n },\n };\n });\n}\n\nexport async function executeTool(\n name: string,\n args: Record<string, unknown>,\n context: ToolContext = {},\n): Promise<unknown> {\n let t = ALL_BUILTINS.find((x) => x.name === name);\n if (t) {\n const cat = registeredCategory(name);\n if (cat && disabledCategories().has(cat)) {\n throw new Error(`Tool \"${name}\" is disabled (category ${cat} is turned off)`);\n }\n }\n if (!t) {\n t = loadExternal().tools.find((x) => x.name === name);\n }\n if (!t) throw new Error(`Unknown tool: ${name}`);\n\n const config: RunnableConfig = context.thread_id\n ? { configurable: { thread_id: context.thread_id } }\n : {};\n\n const result = await t.invoke(args, config);\n\n // Tools return JSON strings per LangChain convention; parse back for downstream use.\n if (typeof result === \"string\") {\n try {\n return JSON.parse(result);\n } catch {\n return result;\n }\n }\n return result;\n}\n\n// One-shot startup loader. Call from instrumentation.ts so external tools\n// load + log their status at boot rather than lazily on first agent turn.\nlet _initialized = false;\nexport interface InitToolsSummary {\n builtinCount: number;\n externalCount: number;\n errors: ExtensionLoadError[];\n toolsDir: string;\n}\n\nexport function initTools(): InitToolsSummary {\n const toolsDir = getToolsDir();\n const result = loadExternal();\n const summary: InitToolsSummary = {\n builtinCount: ALL_BUILTINS.length,\n externalCount: result.tools.length,\n errors: result.errors,\n toolsDir,\n };\n\n if (!_initialized) {\n console.info(\n `[tools] ${summary.builtinCount} built-in tool(s) registered; ` +\n `${summary.externalCount} external tool(s) loaded from ${toolsDir}`,\n );\n for (const err of summary.errors) {\n console.error(`[tools] external ${err.file}: ${err.error}`);\n }\n _initialized = true;\n }\n return summary;\n}\n","import { getDb } from \"@/lib/db\";\nimport { MBTI_PRESETS, type MbtiType } from \"@/lib/agents/adaptive-persona-presets\";\n\nconst now = () => new Date().toISOString();\n\nexport interface AgentConfigRow {\n id: string;\n name: string;\n icon: string | null;\n identity: string;\n instructions: string;\n tools: string; // JSON string[]\n model_config_name: string | null;\n is_default: number;\n history_limit: number; // 0 = unlimited\n history_window_hours: number; // 0 = no time bound\n never_reply: number; // 1 = run the agent but don't auto-send replies via bridges\n adaptive_persona_enabled: number; // 1 = use runtime mood/tone adaptation hints\n adaptive_persona_strength: number; // 0..100, how strongly to adapt to cues\n adaptive_empathy: number; // 0..100, baseline empathetic tone\n adaptive_expressiveness: number; // 0..100, restrained -> energetic\n adaptive_verbosity: number; // 0..100, concise -> detailed\n adaptive_mbti: string; // one of 16 MBTI types\n voice_enabled: number; // 1 = expose mic/play UI for this agent\n voice_model: string; // Gemini TTS model id\n voice_name: string; // Gemini prebuilt voice name (Kore, Puck, …)\n voice_stt_model: string; // Gemini multimodal model used for transcription\n voice_auto_speak: number; // 1 = auto-play reply when user sent voice\n display_filters: string | null; // JSON: Partial<DisplayFilters>; NULL = inherit defaults (ADR-0022)\n harness_id: string | null; // ADR-0033: per-agent harness override; NULL = inherit global default\n created_at: string;\n updated_at: string;\n}\n\nexport function listAgentConfigs(): AgentConfigRow[] {\n return getDb()\n .prepare(\"SELECT * FROM agent_configs ORDER BY is_default DESC, created_at ASC\")\n .all() as unknown as AgentConfigRow[];\n}\n\nexport function getDefaultAgentConfig(): AgentConfigRow | null {\n return (\n (getDb()\n .prepare(\"SELECT * FROM agent_configs WHERE is_default=1 LIMIT 1\")\n .get() as unknown as AgentConfigRow) ?? null\n );\n}\n\nexport function getAgentConfig(id: string): AgentConfigRow | null {\n return (\n (getDb()\n .prepare(\"SELECT * FROM agent_configs WHERE id=?\")\n .get(id) as unknown as AgentConfigRow) ?? null\n );\n}\n\nexport interface UpsertAgentInput {\n id: string;\n name: string;\n icon?: string | null;\n identity: string;\n instructions: string;\n tools: string[];\n model_config_name?: string | null;\n is_default?: boolean;\n history_limit?: number;\n history_window_hours?: number;\n never_reply?: boolean;\n adaptive_persona_enabled?: boolean;\n adaptive_persona_strength?: number;\n adaptive_empathy?: number;\n adaptive_expressiveness?: number;\n adaptive_verbosity?: number;\n adaptive_mbti?: MbtiType;\n voice_enabled?: boolean;\n voice_model?: string;\n voice_name?: string;\n voice_stt_model?: string;\n voice_auto_speak?: boolean;\n harness_id?: string | null;\n}\n\nexport function upsertAgentConfig(input: UpsertAgentInput): AgentConfigRow {\n const t = now();\n const db = getDb();\n const existing = getAgentConfig(input.id);\n const created_at = existing?.created_at ?? t;\n const mbti = input.adaptive_mbti ?? toMbti(existing?.adaptive_mbti) ?? \"INTJ\";\n const preset = MBTI_PRESETS[mbti];\n const strength = input.adaptive_persona_strength ?? preset.strength;\n const empathy = input.adaptive_empathy ?? preset.empathy;\n const expressiveness = input.adaptive_expressiveness ?? preset.expressiveness;\n const verbosity = input.adaptive_verbosity ?? preset.verbosity;\n if (input.is_default) db.prepare(\"UPDATE agent_configs SET is_default=0\").run();\n // harness_id: explicit `undefined` means \"keep existing\"; explicit `null`\n // means \"use the global default\". Empty string is normalised to null too,\n // matching how the AgentEditor sends \"\" for the inherit option.\n const harnessId =\n input.harness_id === undefined\n ? (existing?.harness_id ?? null)\n : (input.harness_id && input.harness_id.length > 0 ? input.harness_id : null);\n db.prepare(\n `INSERT OR REPLACE INTO agent_configs\n (id, name, icon, identity, instructions, tools, model_config_name, is_default,\n history_limit, history_window_hours, never_reply,\n adaptive_persona_enabled, adaptive_persona_strength, adaptive_empathy, adaptive_expressiveness, adaptive_verbosity, adaptive_mbti,\n voice_enabled, voice_model, voice_name, voice_stt_model, voice_auto_speak,\n harness_id,\n created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n )\n .run(\n input.id,\n input.name,\n input.icon ?? null,\n input.identity,\n input.instructions,\n JSON.stringify(input.tools),\n input.model_config_name ?? null,\n input.is_default ? 1 : (existing?.is_default ?? 0),\n input.history_limit ?? existing?.history_limit ?? 50,\n input.history_window_hours ?? existing?.history_window_hours ?? 8,\n // never_reply is a boolean toggle — explicit `undefined` means \"keep existing\"\n // (important for PATCH-style updates that omit the field).\n input.never_reply === undefined\n ? (existing?.never_reply ?? 0)\n : (input.never_reply ? 1 : 0),\n input.adaptive_persona_enabled === undefined\n ? (existing?.adaptive_persona_enabled ?? 0)\n : (input.adaptive_persona_enabled ? 1 : 0),\n clampPercent(strength, existing?.adaptive_persona_strength ?? 50),\n clampPercent(empathy, existing?.adaptive_empathy ?? 50),\n clampPercent(expressiveness, existing?.adaptive_expressiveness ?? 50),\n clampPercent(verbosity, existing?.adaptive_verbosity ?? 50),\n mbti,\n input.voice_enabled === undefined\n ? (existing?.voice_enabled ?? 0)\n : (input.voice_enabled ? 1 : 0),\n (input.voice_model ?? existing?.voice_model ?? \"gemini-2.5-flash-preview-tts\").trim() ||\n \"gemini-2.5-flash-preview-tts\",\n (input.voice_name ?? existing?.voice_name ?? \"Kore\").trim() || \"Kore\",\n (input.voice_stt_model ?? existing?.voice_stt_model ?? \"gemini-2.5-flash\").trim() ||\n \"gemini-2.5-flash\",\n input.voice_auto_speak === undefined\n ? (existing?.voice_auto_speak ?? 1)\n : (input.voice_auto_speak ? 1 : 0),\n harnessId,\n created_at,\n t,\n );\n return getAgentConfig(input.id)!;\n}\n\nfunction clampPercent(next: number | undefined, fallback: number): number {\n const n = Number.isFinite(next) ? Number(next) : fallback;\n return Math.max(0, Math.min(100, Math.round(n)));\n}\n\nfunction toMbti(v: string | null | undefined): MbtiType | null {\n if (!v) return null;\n return (v in MBTI_PRESETS ? v : null) as MbtiType | null;\n}\n\nexport function deleteAgentConfig(id: string): boolean {\n return (\n (getDb().prepare(\"DELETE FROM agent_configs WHERE id=?\").run(id) as { changes: number }).changes > 0\n );\n}\n\nexport function generateAgentId(name: string): string {\n const slug = name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 40);\n const suffix = Math.random().toString(36).slice(2, 6);\n return slug ? `${slug}-${suffix}` : `agent-${suffix}`;\n}\n\n// ── ADR-0022: per-agent message-channel display filters ─────────────────\n// Canonical channel keys mirrored in `hooks/useMessageFilters.ts`. Kept\n// in sync there by importing this constant — single source of truth.\nexport const DISPLAY_FILTER_KEYS = [\n \"scheduled_task\",\n \"watcher\",\n \"bridge\",\n \"synthetic\",\n \"tool_use\",\n \"thinking\",\n] as const;\nexport type DisplayFilterKey = (typeof DISPLAY_FILTER_KEYS)[number];\nexport type DisplayFilters = Record<DisplayFilterKey, boolean>;\n\nexport const DISPLAY_FILTER_DEFAULTS: DisplayFilters = {\n scheduled_task: true,\n watcher: true,\n bridge: true,\n synthetic: true,\n tool_use: true,\n thinking: true,\n};\n\nfunction parseDisplayFilters(raw: string | null | undefined): DisplayFilters {\n if (!raw) return { ...DISPLAY_FILTER_DEFAULTS };\n try {\n const parsed = JSON.parse(raw) as Partial<DisplayFilters>;\n // Merge over defaults so newly-added channels stay visible on old rows.\n return { ...DISPLAY_FILTER_DEFAULTS, ...parsed };\n } catch {\n return { ...DISPLAY_FILTER_DEFAULTS };\n }\n}\n\nexport function getAgentDisplayFilters(id: string): DisplayFilters | null {\n const row = getAgentConfig(id);\n if (!row) return null;\n return parseDisplayFilters(row.display_filters);\n}\n\n/**\n * Merge a partial filter map into the agent's stored prefs. Pass `null` to\n * reset to defaults (clears the column). Safe against concurrent toggles\n * from multiple browser tabs because the merge happens server-side.\n */\nexport function updateAgentDisplayFilters(\n id: string,\n patch: Partial<DisplayFilters> | null,\n): DisplayFilters | null {\n const row = getAgentConfig(id);\n if (!row) return null;\n if (patch === null) {\n getDb()\n .prepare(\"UPDATE agent_configs SET display_filters=NULL, updated_at=? WHERE id=?\")\n .run(now(), id);\n return { ...DISPLAY_FILTER_DEFAULTS };\n }\n const current = parseDisplayFilters(row.display_filters);\n const next: DisplayFilters = { ...current };\n for (const k of DISPLAY_FILTER_KEYS) {\n if (k in patch && typeof patch[k] === \"boolean\") next[k] = patch[k] as boolean;\n }\n getDb()\n .prepare(\"UPDATE agent_configs SET display_filters=?, updated_at=? WHERE id=?\")\n .run(JSON.stringify(next), now(), id);\n return next;\n}\n","// Cap a string at `maxBytes` UTF-8 bytes. Returns the original (and\n// truncated:false) when already under the cap. Counting bytes — not chars —\n// matters for emoji / CJK / accented characters where char-count would let\n// the payload double the byte budget.\nexport function truncateBytes(s: string, maxBytes: number): { text: string; truncated: boolean } {\n if (Buffer.byteLength(s, \"utf8\") <= maxBytes) return { text: s, truncated: false };\n\n // Slice by char until under the byte cap. Linear scan is fine for the\n // ~30KB caps we use; if a caller ever needs MB-scale truncation, swap for\n // a binary search.\n let end = s.length;\n while (end > 0 && Buffer.byteLength(s.slice(0, end), \"utf8\") > maxBytes) {\n end--;\n }\n return { text: s.slice(0, end), truncated: true };\n}\n","/**\n * Native Atlassian tools (Jira + Confluence) — direct REST API calls, no MCP.\n *\n * Why this exists: corporate networks often block public PyPI/npm, which makes\n * the `mcp-atlassian` install path fragile. These tools just hit the Atlassian\n * REST API over HTTPS, which goes through the same proxy (EnvHttpProxyAgent)\n * the rest of the server uses — so they work anywhere a browser can reach\n * `*.atlassian.net`.\n *\n * Auth resolution (in priority order):\n * 1. Env: ATLASSIAN_URL, ATLASSIAN_EMAIL, ATLASSIAN_API_TOKEN\n * 2. Memory store: namespace=\"integrations\", key=\"atlassian\", value=\n * { url, email, api_token }\n *\n * The agent can populate option 2 via memory_write if the user shares the\n * credentials in chat — but most users will set env vars at server boot.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\nimport { registerTools } from \"./registry\";\n\nexport interface AtlassianAuth {\n url: string; // e.g. \"https://your-team.atlassian.net\"\n email: string;\n apiToken: string;\n}\n\n// Exposed so the integrations test endpoint can probe the live API after save.\nexport function _resolveAtlassianAuth(): AtlassianAuth | { error: string } {\n return resolveAuth();\n}\n\nfunction resolveAuth(): AtlassianAuth | { error: string } {\n // Env first (deployment-level config, wins over per-user secrets stored in DB)\n const envUrl = process.env.ATLASSIAN_URL;\n const envEmail = process.env.ATLASSIAN_EMAIL;\n const envToken = process.env.ATLASSIAN_API_TOKEN;\n if (envUrl && envEmail && envToken) {\n return { url: stripTrailingSlash(envUrl), email: envEmail, apiToken: envToken };\n }\n // Saved integration creds (from the Integrations panel in the UI).\n const saved = getIntegrationRaw(\"atlassian\");\n if (saved?.url && saved.email && saved.api_token) {\n return { url: stripTrailingSlash(saved.url), email: saved.email, apiToken: saved.api_token };\n }\n return {\n error:\n \"Atlassian not configured. Open the gear menu → Integrations tab and add your Atlassian site URL, \" +\n \"email, and API token. (Or set ATLASSIAN_URL / ATLASSIAN_EMAIL / ATLASSIAN_API_TOKEN env vars.)\",\n };\n}\n\nfunction stripTrailingSlash(s: string): string { return s.replace(/\\/+$/, \"\"); }\n\nfunction authHeader(a: AtlassianAuth): string {\n return \"Basic \" + Buffer.from(`${a.email}:${a.apiToken}`).toString(\"base64\");\n}\n\n// Sibling-module accessor: the remote document-RAG indexers (lib/documents/\n// remote/{jira,confluence}.ts, ADR-0026) reuse the same proxy-aware fetch\n// wrapper + auth header so they don't duplicate the Atlassian REST plumbing.\n// Underscore prefix marks it as \"internal API, but reachable across modules\".\nexport async function _atlassianFetch(\n auth: AtlassianAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n return atlassianFetch(auth, path, init);\n}\n\nasync function atlassianFetch(\n auth: AtlassianAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const url = path.startsWith(\"http\") ? path : `${auth.url}${path}`;\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: authHeader(auth),\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n });\n const text = await res.text();\n if (!res.ok) {\n return { error: `Atlassian ${res.status}: ${text.slice(0, 500)}`, url };\n }\n return parseJsonSafe<unknown>(text, text);\n}\n\n// ── Jira tools ──────────────────────────────────────────────────────────────\n\nexport const jiraSearchTool = tool(\n async ({ jql, max_results, fields }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const fieldList = fields ?? [\"summary\", \"status\", \"assignee\", \"priority\", \"created\", \"updated\"];\n // Atlassian removed /rest/api/3/search in 2025 (returns 410). The replacement\n // is /rest/api/3/search/jql — same JQL semantics, slightly different shape:\n // - POST body: { jql, fields: string[] | \"*all\", maxResults?, nextPageToken? }\n // - Response uses cursor-based `nextPageToken` instead of legacy offset.\n const data = await atlassianFetch(auth, `/rest/api/3/search/jql`, {\n method: \"POST\",\n body: JSON.stringify({ jql, maxResults: limit, fields: fieldList }),\n }) as { issues?: Array<Record<string, unknown>>; nextPageToken?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issues: (data.issues ?? []).map((i: Record<string, unknown>) => ({\n key: i.key,\n url: `${auth.url}/browse/${i.key}`,\n summary: (i.fields as Record<string, unknown>)?.summary,\n status: ((i.fields as Record<string, unknown>)?.status as Record<string, unknown>)?.name,\n assignee: ((i.fields as Record<string, unknown>)?.assignee as Record<string, unknown>)?.displayName ?? null,\n priority: ((i.fields as Record<string, unknown>)?.priority as Record<string, unknown>)?.name ?? null,\n })),\n next_page_token: data.nextPageToken ?? null,\n });\n },\n {\n name: \"jira_search\",\n description:\n \"Search Jira issues using JQL. **PREFER THIS over shell-exec'ing the jira CLI** — this tool uses \" +\n \"the configured Atlassian credentials directly via REST. Returns key, summary, status, assignee. \" +\n \"JQL examples: 'assignee = currentUser() AND resolution = Unresolved', \" +\n \"'project = ABC AND status = \\\"In Progress\\\"', 'updated >= -7d ORDER BY updated DESC'.\",\n schema: z.object({\n jql: z.string().describe(\"JQL query string\"),\n max_results: z.number().optional().describe(\"Max issues (default 25, max 100)\"),\n fields: z.array(z.string()).optional().describe(\"Field names to fetch; defaults to common ones\"),\n }),\n },\n);\n\nexport const jiraGetIssueTool = tool(\n async ({ issue_key, expand, custom_fields, include_comments }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n let resolvedCustom: Array<{ input: string; id: string; name: string }> = [];\n if (custom_fields?.length) {\n const fieldList = await loadJiraFields(auth);\n if (!Array.isArray(fieldList)) return JSON.stringify(fieldList);\n const r = resolveCustomFieldNames(custom_fields, fieldList);\n if (r.unresolved.length) {\n const candidates = fieldList\n .filter((f) => f.custom)\n .slice(0, 25)\n .map((f) => `${f.name} (${f.id})`)\n .join(\"; \");\n return JSON.stringify({\n error: `unresolved custom_fields: ${r.unresolved.join(\", \")}. Pass either the customfield_NNNNN id or the exact display name.`,\n hint_first_25_custom_fields: candidates,\n });\n }\n resolvedCustom = r.resolved;\n }\n\n const expandSet = new Set(expand ?? []);\n if (resolvedCustom.length) {\n expandSet.add(\"names\");\n expandSet.add(\"renderedFields\");\n }\n const params: string[] = [];\n if (expandSet.size) params.push(`expand=${[...expandSet].join(\",\")}`);\n // Always pull issuelinks/subtasks/attachment/parent so callers see what's\n // attached to the issue without a follow-up call. Custom fields are\n // additive — when the caller asked for any, we explicitly enumerate the\n // base set + customs to keep the response shape stable.\n const baseFields = [\n \"summary\", \"description\", \"status\", \"issuetype\", \"priority\",\n \"assignee\", \"reporter\", \"created\", \"updated\", \"labels\", \"components\", \"comment\",\n \"issuelinks\", \"subtasks\", \"attachment\", \"parent\",\n ];\n if (resolvedCustom.length) {\n params.push(`fields=${[...baseFields, ...resolvedCustom.map((c) => c.id)].join(\",\")}`);\n } else {\n params.push(`fields=${baseFields.join(\",\")}`);\n }\n const qs = params.length ? `?${params.join(\"&\")}` : \"\";\n\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}${qs}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n\n const f = (data.fields ?? {}) as Record<string, unknown>;\n const rendered = (data.renderedFields ?? {}) as Record<string, unknown>;\n\n const customOut: Record<string, unknown> = {};\n for (const c of resolvedCustom) {\n customOut[c.name] = extractFieldValue(f[c.id], rendered[c.id]);\n }\n\n // Issue links: each entry has an `id` (needed by jira_delete_link),\n // a type, and one of inwardIssue / outwardIssue depending on direction.\n const issueLinks = ((f.issuelinks as Array<Record<string, unknown>>) ?? []).map((l) => {\n const t = l.type as Record<string, unknown> | undefined;\n const inward = l.inwardIssue as Record<string, unknown> | undefined;\n const outward = l.outwardIssue as Record<string, unknown> | undefined;\n return {\n id: l.id,\n type: t?.name,\n direction: inward ? \"inward\" : \"outward\",\n verb: inward ? t?.inward : t?.outward,\n other_issue: inward\n ? { key: inward.key, summary: (inward.fields as Record<string, unknown>)?.summary }\n : outward\n ? { key: outward.key, summary: (outward.fields as Record<string, unknown>)?.summary }\n : null,\n };\n });\n\n // Remote/web links live under a separate endpoint — fetch in parallel\n // when requested (and if the issue actually has any) so we don't waste a\n // call on every get. Cheap heuristic: only fetch when the caller passed\n // include_remote_links, or always if expand contains \"remoteLinks\".\n let remoteLinks: Array<Record<string, unknown>> | undefined;\n if (expandSet.has(\"remoteLinks\")) {\n const rl = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/remotelink`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (Array.isArray(rl)) {\n remoteLinks = rl.map((entry) => {\n const obj = entry.object as Record<string, unknown> | undefined;\n return { id: entry.id, url: obj?.url, title: obj?.title, summary: obj?.summary };\n });\n }\n }\n\n return JSON.stringify({\n key: data.key,\n url: `${auth.url}/browse/${data.key}`,\n summary: f.summary,\n description: simplifyADF(f.description),\n status: (f.status as Record<string, unknown>)?.name,\n type: (f.issuetype as Record<string, unknown>)?.name,\n priority: (f.priority as Record<string, unknown>)?.name,\n assignee: (f.assignee as Record<string, unknown>)?.displayName ?? null,\n reporter: (f.reporter as Record<string, unknown>)?.displayName ?? null,\n created: f.created,\n updated: f.updated,\n labels: f.labels,\n components: ((f.components as Array<Record<string, unknown>>) ?? []).map((c) => c.name),\n comments_count: ((f.comment as Record<string, unknown>)?.total) ?? 0,\n ...(include_comments ? {\n comments: (((f.comment as Record<string, unknown>)?.comments as Array<Record<string, unknown>>) ?? []).map((c) => ({\n id: c.id,\n author: (c.author as Record<string, unknown>)?.displayName ?? null,\n created: c.created,\n updated: c.updated,\n body: simplifyADF(c.body),\n })),\n } : {}),\n parent: f.parent ? {\n key: (f.parent as Record<string, unknown>).key,\n summary: ((f.parent as Record<string, unknown>).fields as Record<string, unknown>)?.summary,\n } : null,\n subtasks: ((f.subtasks as Array<Record<string, unknown>>) ?? []).map((s) => ({\n key: s.key,\n summary: (s.fields as Record<string, unknown>)?.summary,\n status: ((s.fields as Record<string, unknown>)?.status as Record<string, unknown>)?.name,\n })),\n issue_links: issueLinks,\n attachments: ((f.attachment as Array<Record<string, unknown>>) ?? []).map((a) => ({\n id: a.id,\n filename: a.filename,\n size: a.size,\n mime_type: a.mimeType,\n created: a.created,\n author: (a.author as Record<string, unknown>)?.displayName,\n content_url: a.content,\n })),\n ...(remoteLinks !== undefined ? { remote_links: remoteLinks } : {}),\n ...(resolvedCustom.length ? { custom_fields: customOut } : {}),\n });\n },\n {\n name: \"jira_get_issue\",\n description:\n \"Fetch a single Jira issue by key (e.g. 'PROJ-123'). Returns full detail including description, \" +\n \"parent, sub-tasks, issue_links (with link ids for jira_delete_link), and attachment metadata. \" +\n \"Pass `expand: ['remoteLinks']` to also fetch web/Confluence/GitHub links. \" +\n \"Pass `custom_fields` (display names like 'Vulnerability Description', or `customfield_NNNNN` ids) \" +\n \"to include them in the response under a `custom_fields` map. \" +\n \"Pass `include_comments: true` to include flattened comment bodies (author, timestamps, text). \" +\n \"ADF/rich-text is auto-flattened. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue key like PROJ-123\"),\n expand: z.array(z.string()).optional().describe(\"Fields to expand (e.g. ['changelog', 'transitions'])\"),\n custom_fields: z.array(z.string()).optional().describe(\n \"Custom field display names ('Vulnerability Description') or ids ('customfield_10473') to include\",\n ),\n include_comments: z.boolean().optional().describe(\n \"If true, include a `comments` array with author/created/updated/body for each comment. \" +\n \"Comments come from the same call (no extra API round-trip) but Jira caps the embedded list at ~50 — \" +\n \"use a follow-up call for issues with more.\",\n ),\n }),\n },\n);\n\nexport const jiraCreateIssueTool = tool(\n async ({ project_key, summary, description, issue_type, parent_key, labels, assignee_account_id, custom_fields }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const fields: Record<string, unknown> = {\n project: { key: project_key },\n summary,\n issuetype: { name: issue_type ?? \"Task\" },\n };\n if (description) fields.description = textToADF(description);\n if (parent_key) fields.parent = { key: parent_key };\n if (Array.isArray(labels)) fields.labels = labels;\n if (assignee_account_id) fields.assignee = { accountId: assignee_account_id };\n if (custom_fields && typeof custom_fields === \"object\" && Object.keys(custom_fields).length > 0) {\n const fieldList = await loadJiraFields(auth);\n if (!Array.isArray(fieldList)) return JSON.stringify(fieldList);\n const r = resolveCustomFieldNames(Object.keys(custom_fields), fieldList);\n if (r.unresolved.length) {\n return JSON.stringify({\n error: `unresolved custom_fields: ${r.unresolved.join(\", \")}`,\n hint_first_25_custom_fields: fieldList\n .filter((f) => f.custom).slice(0, 25)\n .map((f) => `${f.name} (${f.id})`).join(\"; \"),\n });\n }\n for (const c of r.resolved) {\n fields[c.id] = (custom_fields as Record<string, unknown>)[c.input];\n }\n }\n const data = await atlassianFetch(auth, `/rest/api/3/issue`, {\n method: \"POST\",\n body: JSON.stringify({ fields }),\n }) as { key?: string; id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n key: data.key,\n url: data.key ? `${auth.url}/browse/${data.key}` : null,\n });\n },\n {\n name: \"jira_create_issue\",\n description:\n \"Create a new Jira issue. Defaults to issue_type='Task'. Pass parent_key to create a sub-task \" +\n \"or attach a Story to an Epic. Custom fields accept display names or customfield_NNNNN ids. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n project_key: z.string().describe(\"Project key (e.g. 'ENG')\"),\n summary: z.string().describe(\"Issue title\"),\n description: z.string().optional().describe(\"Plain-text description (auto-converted to ADF)\"),\n issue_type: z.string().optional().describe(\"Issue type name (default: Task; valid: Task, Bug, Story, Epic, Sub-task, …)\"),\n parent_key: z.string().optional().describe(\n \"Parent issue key. Required for Sub-task issue types; also used to attach a Story/Task to an Epic.\",\n ),\n labels: z.array(z.string()).optional().describe(\"Labels to set on the new issue\"),\n assignee_account_id: z.string().optional().describe(\n \"Jira Cloud accountId to assign on creation (use jira_find_user to resolve)\",\n ),\n custom_fields: z.record(z.string(), z.unknown()).optional().describe(\n \"Map of custom field display names or customfield_NNNNN ids → values (e.g. { 'Due Date': '2026-06-15' })\",\n ),\n }),\n },\n);\n\nexport const jiraAddCommentTool = tool(\n async ({ issue_key, body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment`, {\n method: \"POST\",\n body: JSON.stringify({ body: textToADF(body) }),\n }) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, comment_id: data.id });\n },\n {\n name: \"jira_add_comment\",\n description:\n \"Add a comment to a Jira issue. Plain text is auto-converted to ADF (Atlassian Document Format). \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n issue_key: z.string(),\n body: z.string().describe(\"Comment text (plain text, line breaks preserved)\"),\n }),\n },\n);\n\nexport const jiraFindUserTool = tool(\n async ({ query }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/user/search?query=${encodeURIComponent(query)}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n users: data.map((u) => ({\n account_id: u.accountId,\n display_name: u.displayName,\n email: u.emailAddress ?? null,\n active: u.active,\n })),\n });\n },\n {\n name: \"jira_find_user\",\n description:\n \"Look up Jira Cloud users by email or display-name fragment. Returns accountId values \" +\n \"you can pass to jira_update_issue's assignee_account_id. Use when you only have an email.\",\n schema: z.object({\n query: z.string().describe(\"Email address or partial display name\"),\n }),\n },\n);\n\nexport const jiraUpdateIssueTool = tool(\n async ({\n issue_key, summary, description, priority, assignee_account_id, assignee_email,\n fix_versions, labels, labels_add, labels_remove, custom_fields, parent_key,\n }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n const fields: Record<string, unknown> = {};\n const update: Record<string, Array<Record<string, unknown>>> = {};\n\n if (typeof summary === \"string\") fields.summary = summary;\n if (typeof description === \"string\") fields.description = textToADF(description);\n if (typeof priority === \"string\") fields.priority = { name: priority };\n if (typeof parent_key === \"string\") {\n // Empty string clears the parent (detach from epic / promote sub-task to standalone).\n fields.parent = parent_key.length > 0 ? { key: parent_key } : null;\n }\n if (Array.isArray(fix_versions)) fields.fixVersions = fix_versions.map((name) => ({ name }));\n if (Array.isArray(labels)) fields.labels = labels;\n\n // Custom fields: caller passes display names (\"Due Date\") or ids\n // (customfield_10015) → values. We resolve names → ids via the same\n // /rest/api/3/field cache jira_get_issue uses. Values are passed through\n // verbatim — Jira accepts strings, numbers, arrays, or full ADF docs\n // depending on the field's underlying type, and forcing one shape here\n // would break the others. The model already knows the field type from a\n // prior get_issue call (or an error message will steer it).\n if (custom_fields && typeof custom_fields === \"object\" && Object.keys(custom_fields).length > 0) {\n const inputs = Object.keys(custom_fields);\n const fieldList = await loadJiraFields(auth);\n if (!Array.isArray(fieldList)) return JSON.stringify(fieldList);\n const r = resolveCustomFieldNames(inputs, fieldList);\n if (r.unresolved.length) {\n return JSON.stringify({\n error: `unresolved custom_fields: ${r.unresolved.join(\", \")}. Pass either the customfield_NNNNN id or the exact display name.`,\n hint_first_25_custom_fields: fieldList\n .filter((f) => f.custom)\n .slice(0, 25)\n .map((f) => `${f.name} (${f.id})`)\n .join(\"; \"),\n });\n }\n for (const c of r.resolved) {\n fields[c.id] = (custom_fields as Record<string, unknown>)[c.input];\n }\n }\n\n if (Array.isArray(labels_add) || Array.isArray(labels_remove)) {\n const ops: Array<Record<string, string>> = [];\n for (const l of labels_add ?? []) ops.push({ add: l });\n for (const l of labels_remove ?? []) ops.push({ remove: l });\n if (ops.length) update.labels = ops;\n }\n\n // Assignee: explicit accountId wins; otherwise resolve email; \"unassigned\" / null clears.\n if (assignee_account_id !== undefined) {\n const v = assignee_account_id;\n if (v === null || v === \"\" || v === \"unassigned\") {\n fields.assignee = { accountId: null };\n } else {\n fields.assignee = { accountId: v };\n }\n } else if (typeof assignee_email === \"string\" && assignee_email.length > 0) {\n if (assignee_email === \"unassigned\") {\n fields.assignee = { accountId: null };\n } else {\n const users = await atlassianFetch(\n auth,\n `/rest/api/3/user/search?query=${encodeURIComponent(assignee_email)}`,\n ) as Array<{ accountId?: string; emailAddress?: string }> | { error?: string };\n if (!Array.isArray(users)) return JSON.stringify(users);\n // Prefer exact email match (case-insensitive); fall back to single result.\n const exact = users.find(\n (u) => (u.emailAddress ?? \"\").toLowerCase() === assignee_email.toLowerCase(),\n );\n const picked = exact ?? (users.length === 1 ? users[0] : undefined);\n if (!picked?.accountId) {\n return JSON.stringify({\n error: `could not resolve assignee_email \"${assignee_email}\" — got ${users.length} matches; ` +\n `pass assignee_account_id explicitly`,\n candidates: users.map((u) => ({ email: u.emailAddress, account_id: u.accountId })),\n });\n }\n fields.assignee = { accountId: picked.accountId };\n }\n }\n\n if (Object.keys(fields).length === 0 && Object.keys(update).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of summary, description, priority, assignee_*, fix_versions, labels, labels_add, labels_remove, parent_key, custom_fields\" });\n }\n\n const body: Record<string, unknown> = {};\n if (Object.keys(fields).length) body.fields = fields;\n if (Object.keys(update).length) body.update = update;\n\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}`, {\n method: \"PUT\",\n body: JSON.stringify(body),\n }) as { error?: string } | string;\n // Successful PUT returns 204 No Content → atlassianFetch returns \"\" (parsed as string).\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n key: issue_key,\n url: `${auth.url}/browse/${issue_key}`,\n updated_fields: [...Object.keys(fields), ...Object.keys(update).map((k) => `${k}(±)`)],\n });\n },\n {\n name: \"jira_update_issue\",\n description:\n \"Edit fields on an existing Jira issue: summary, description, priority, assignee, fix versions, \" +\n \"labels, and arbitrary custom fields (including 'Due Date' and 'Story Points' on sites where \" +\n \"those are custom). Pass only the fields you want to change. Description is auto-converted from \" +\n \"plain text to ADF. Labels support either full replace (`labels`) or incremental \" +\n \"`labels_add`/`labels_remove`. Assignee can be set by `assignee_account_id` or by \" +\n \"`assignee_email` (auto-resolved); pass null/\\\"unassigned\\\" to clear. Custom fields accept \" +\n \"display names ('Due Date') or ids ('customfield_10015'); values are passed through verbatim \" +\n \"(string for date/text, number for numeric, full ADF object for rich-text custom fields). \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.** Disable to make the agent read-only.\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue key like PROJ-123\"),\n summary: z.string().optional().describe(\"New issue title\"),\n description: z.string().optional().describe(\n \"Plain-text description (auto-converted to ADF). Replaces existing description.\",\n ),\n priority: z.string().optional().describe(\"Priority name (e.g. 'High', 'Medium', 'Low')\"),\n assignee_account_id: z.string().nullable().optional().describe(\n \"Jira Cloud accountId; null or 'unassigned' clears assignee\",\n ),\n assignee_email: z.string().optional().describe(\n \"Email to resolve via /user/search; alternative to assignee_account_id\",\n ),\n fix_versions: z.array(z.string()).optional().describe(\n \"Replace fix versions with these names (empty array clears all)\",\n ),\n labels: z.array(z.string()).optional().describe(\n \"Replace labels entirely with this set (empty array clears all)\",\n ),\n labels_add: z.array(z.string()).optional().describe(\"Labels to add (incremental)\"),\n labels_remove: z.array(z.string()).optional().describe(\"Labels to remove (incremental)\"),\n parent_key: z.string().optional().describe(\n \"Reparent: pass a parent issue key to attach this issue to (Epic key for Stories, Story/Task key for Sub-tasks). Pass an empty string to detach from the current parent.\",\n ),\n custom_fields: z.record(z.string(), z.unknown()).optional().describe(\n \"Map of custom field display names or customfield_NNNNN ids → values. \" +\n \"Examples: { \\\"Due Date\\\": \\\"2026-06-15\\\", \\\"Story Points\\\": 8 }. \" +\n \"For rich-text custom fields, pass a full ADF document as the value.\",\n ),\n }),\n },\n);\n\nexport const jiraTransitionsTool = tool(\n async ({ issue_key, transition_name }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Step 1: list available transitions for this issue.\n const list = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/transitions`) as { transitions?: Array<{ id: string; name: string }>; error?: string };\n if (list.error) return JSON.stringify(list);\n if (!transition_name) {\n return JSON.stringify({ available_transitions: (list.transitions ?? []).map((t) => t.name) });\n }\n const match = (list.transitions ?? []).find((t) => t.name.toLowerCase() === transition_name.toLowerCase());\n if (!match) {\n return JSON.stringify({\n error: `transition \"${transition_name}\" not available for ${issue_key}`,\n available: (list.transitions ?? []).map((t) => t.name),\n });\n }\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/transitions`, {\n method: \"POST\",\n body: JSON.stringify({ transition: { id: match.id } }),\n }) as { error?: string };\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, transitioned_to: match.name });\n },\n {\n name: \"jira_transition_issue\",\n description:\n \"Transition a Jira issue's status (e.g. 'In Progress' → 'Done'). \" +\n \"Call without transition_name to list available transitions for the issue. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n issue_key: z.string(),\n transition_name: z.string().optional().describe(\"Name of the transition (case-insensitive). Omit to list.\"),\n }),\n },\n);\n\nexport const jiraLinkIssuesTool = tool(\n async ({ from_issue, to_issue, link_type, comment }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n // Step 1: load global link types and resolve the requested name. Same\n // \"omit to list\" pattern as jira_transition_issue — agents can probe this\n // tool to discover what's available without a separate list endpoint.\n const list = await atlassianFetch(auth, `/rest/api/3/issueLinkType`) as\n | { issueLinkTypes?: Array<{ id: string; name: string; inward: string; outward: string }>; error?: string };\n if (\"error\" in list && list.error) return JSON.stringify(list);\n const types = list.issueLinkTypes ?? [];\n if (!link_type || !from_issue || !to_issue) {\n return JSON.stringify({\n available_link_types: types.map((t) => ({ name: t.name, outward: t.outward, inward: t.inward })),\n usage: \"Pass from_issue, to_issue, and link_type (e.g. 'Blocks'). The link reads as: '<from_issue> <outward verb> <to_issue>'.\",\n });\n }\n const wanted = link_type.toLowerCase();\n const match = types.find((t) => t.name.toLowerCase() === wanted);\n if (!match) {\n return JSON.stringify({\n error: `link_type \"${link_type}\" not configured for this site`,\n available: types.map((t) => t.name),\n });\n }\n\n // Jira's outwardIssue is the SOURCE (subject of the outward verb), inwardIssue\n // is the TARGET. So `{from: A, to: B, type: \"Blocks\"}` reads as \"A blocks B\".\n const body: Record<string, unknown> = {\n type: { name: match.name },\n outwardIssue: { key: from_issue },\n inwardIssue: { key: to_issue },\n };\n if (typeof comment === \"string\" && comment.length > 0) {\n body.comment = { body: textToADF(comment) };\n }\n\n const data = await atlassianFetch(auth, `/rest/api/3/issueLink`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as { error?: string } | string;\n // Successful POST returns 201 Created with empty body → \"\" (string).\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n reads_as: `${from_issue} ${match.outward} ${to_issue}`,\n from: { key: from_issue, url: `${auth.url}/browse/${from_issue}` },\n to: { key: to_issue, url: `${auth.url}/browse/${to_issue}` },\n link_type: match.name,\n });\n },\n {\n name: \"jira_link_issues\",\n description:\n \"Create an issue link between two Jira issues (Blocks, Relates, Duplicates, Cloners, etc.). \" +\n \"The link reads left-to-right: 'from_issue <outward verb> to_issue'. For example, \" +\n \"{ from_issue: 'A-1', to_issue: 'B-2', link_type: 'Blocks' } means 'A-1 blocks B-2' \" +\n \"(and 'B-2 is blocked by A-1' shows on the other side automatically). \" +\n \"Call without arguments to list available link types for the site. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI or hitting REST directly.** Disable to make the agent read-only.\",\n schema: z.object({\n from_issue: z.string().optional().describe(\"Source issue key (subject of the outward verb), e.g. 'PROJ-1'\"),\n to_issue: z.string().optional().describe(\"Target issue key (object of the outward verb), e.g. 'PROJ-2'\"),\n link_type: z.string().optional().describe(\n \"Link type name, case-insensitive (e.g. 'Blocks', 'Relates', 'Duplicates'). Omit to list available types.\",\n ),\n comment: z.string().optional().describe(\n \"Optional plain-text comment posted to the from_issue alongside the link\",\n ),\n }),\n },\n);\n\n// Shape for one issue inside a bulk-create payload. Mirrors the create tool's\n// schema so callers building one off a loop don't have to re-learn fields.\nconst bulkIssueSchema = z.object({\n project_key: z.string(),\n summary: z.string(),\n description: z.string().optional(),\n issue_type: z.string().optional(),\n parent_key: z.string().optional(),\n labels: z.array(z.string()).optional(),\n assignee_account_id: z.string().optional(),\n custom_fields: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const jiraCreateIssuesBulkTool = tool(\n async ({ issues }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issues?.length) return JSON.stringify({ error: \"issues array is empty\" });\n if (issues.length > 50) return JSON.stringify({ error: `bulk endpoint accepts up to 50 per call (got ${issues.length})` });\n\n // Custom fields: do ONE field-cache load if any issue uses them, then\n // resolve names → ids per-issue. Bulk creates that share custom fields\n // (the common case) thus only pay the cache cost once.\n let fieldList: JiraFieldDef[] | undefined;\n const anyCustom = issues.some((i) => i.custom_fields && Object.keys(i.custom_fields).length > 0);\n if (anyCustom) {\n const loaded = await loadJiraFields(auth);\n if (!Array.isArray(loaded)) return JSON.stringify(loaded);\n fieldList = loaded;\n }\n\n const issueUpdates: Array<{ fields: Record<string, unknown> }> = [];\n for (const i of issues) {\n const fields: Record<string, unknown> = {\n project: { key: i.project_key },\n summary: i.summary,\n issuetype: { name: i.issue_type ?? \"Task\" },\n };\n if (i.description) fields.description = textToADF(i.description);\n if (i.parent_key) fields.parent = { key: i.parent_key };\n if (Array.isArray(i.labels)) fields.labels = i.labels;\n if (i.assignee_account_id) fields.assignee = { accountId: i.assignee_account_id };\n if (i.custom_fields && fieldList) {\n const r = resolveCustomFieldNames(Object.keys(i.custom_fields), fieldList);\n if (r.unresolved.length) {\n return JSON.stringify({ error: `unresolved custom_fields on \"${i.summary}\": ${r.unresolved.join(\", \")}` });\n }\n for (const c of r.resolved) {\n fields[c.id] = (i.custom_fields as Record<string, unknown>)[c.input];\n }\n }\n issueUpdates.push({ fields });\n }\n\n const data = await atlassianFetch(auth, `/rest/api/3/issue/bulk`, {\n method: \"POST\",\n body: JSON.stringify({ issueUpdates }),\n }) as {\n issues?: Array<{ key?: string; id?: string }>;\n errors?: Array<{ status: number; elementErrors: { errors?: Record<string, string> } }>;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n created: (data.issues ?? []).map((i) => ({\n key: i.key,\n url: i.key ? `${auth.url}/browse/${i.key}` : null,\n })),\n errors: data.errors ?? [],\n });\n },\n {\n name: \"jira_create_issues_bulk\",\n description:\n \"Create up to 50 Jira issues in a single API call. Each entry takes the same shape as \" +\n \"jira_create_issue (project_key, summary, description, issue_type, parent_key, labels, \" +\n \"assignee_account_id, custom_fields). Returns per-issue keys plus any partial errors. \" +\n \"**PREFER THIS over many sequential jira_create_issue calls** when creating ≥3 tickets.\",\n schema: z.object({\n issues: z.array(bulkIssueSchema).describe(\"Array of issues to create (1–50)\"),\n }),\n },\n);\n\nexport const jiraAddRemoteLinkTool = tool(\n async ({ issue_key, url, title, summary, icon_url, global_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = {\n object: {\n url,\n title,\n ...(summary ? { summary } : {}),\n ...(icon_url ? { icon: { url16x16: icon_url } } : {}),\n },\n };\n // globalId is what makes a remote link idempotent — repeat-posting with\n // the same globalId updates the existing link instead of creating a dup.\n if (global_id) body.globalId = global_id;\n\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/remotelink`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as { id?: number; self?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n remote_link_id: data.id,\n issue: { key: issue_key, url: `${auth.url}/browse/${issue_key}` },\n target: { url, title },\n });\n },\n {\n name: \"jira_add_remote_link\",\n description:\n \"Attach a web/external link to a Jira issue (Confluence pages, GitHub PRs, dashboards, Slack threads, \" +\n \"any URL). Distinct from jira_link_issues, which links one Jira issue to another. \" +\n \"Pass `global_id` to make the link idempotent — re-posting with the same global_id updates the \" +\n \"existing link rather than creating a duplicate. **PREFER THIS over pasting URLs into the description.**\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue to attach the link to\"),\n url: z.string().describe(\"Target URL\"),\n title: z.string().describe(\"Link title shown in Jira's 'web links' panel\"),\n summary: z.string().optional().describe(\"Optional one-line description shown under the title\"),\n icon_url: z.string().optional().describe(\"Optional 16×16 icon URL\"),\n global_id: z.string().optional().describe(\n \"Optional stable identifier for idempotent upserts (e.g. 'github-pr-1234'). Re-posting with the same value updates the existing link.\",\n ),\n }),\n },\n);\n\nexport const jiraDeleteLinkTool = tool(\n async ({ link_id, link_type, kind }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!link_id) return JSON.stringify({ error: \"link_id is required (look up via jira_get_issue → issue_links[].id or remote_links[].id)\" });\n\n // \"issue\" = link between two Jira issues (DELETE /issueLink/{id})\n // \"remote\" = link to an external URL (DELETE /issue/{key}/remotelink/{id})\n // Caller must specify because the same numeric id can exist in both spaces.\n if (kind === \"remote\") {\n if (!link_type) {\n return JSON.stringify({ error: \"for kind='remote', pass link_type as the issue key (the link is scoped to an issue)\" });\n }\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(link_type)}/remotelink/${encodeURIComponent(link_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted: { kind: \"remote\", link_id, issue_key: link_type } });\n }\n\n const data = await atlassianFetch(auth, `/rest/api/3/issueLink/${encodeURIComponent(link_id)}`, {\n method: \"DELETE\",\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted: { kind: \"issue\", link_id } });\n },\n {\n name: \"jira_delete_link\",\n description:\n \"Delete an issue link (Jira-to-Jira, default) or a remote/web link. Look up the id first with \" +\n \"jira_get_issue (issue_links[].id or remote_links[].id — pass `expand: ['remoteLinks']` for the latter). \" +\n \"For remote links, also pass the issue key as `link_type` since the API is scoped per-issue.\",\n schema: z.object({\n link_id: z.string().describe(\"Numeric link id from jira_get_issue\"),\n kind: z.enum([\"issue\", \"remote\"]).optional().describe(\n \"'issue' (default) for Jira-to-Jira links, 'remote' for web/external URL links\",\n ),\n link_type: z.string().optional().describe(\n \"When kind='remote', the issue key the remote link is attached to (required by Jira's per-issue endpoint)\",\n ),\n }),\n },\n);\n\nexport const jiraUploadAttachmentTool = tool(\n async ({ issue_key, filename, content_base64, content_text }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!content_base64 && !content_text) {\n return JSON.stringify({ error: \"pass either content_base64 (binary) or content_text (UTF-8)\" });\n }\n\n const buf = content_base64\n ? Buffer.from(content_base64, \"base64\")\n : Buffer.from(content_text!, \"utf8\");\n\n // Jira attachment uploads require X-Atlassian-Token: no-check (CSRF\n // bypass) and multipart/form-data. node's built-in FormData + Blob (Node\n // 22+) handle the body shape; fetch sets the multipart boundary.\n const form = new FormData();\n form.append(\"file\", new Blob([buf]), filename);\n\n const url = `${auth.url}/rest/api/3/issue/${encodeURIComponent(issue_key)}/attachments`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: authHeader(auth),\n Accept: \"application/json\",\n \"X-Atlassian-Token\": \"no-check\",\n // Do NOT set Content-Type — fetch fills in the multipart boundary.\n },\n body: form,\n });\n const text = await res.text();\n if (!res.ok) return JSON.stringify({ error: `Atlassian ${res.status}: ${text.slice(0, 500)}` });\n const parsed = parseJsonSafe<Array<{ id: string; filename: string; size: number; mimeType: string; content: string }>>(text, []);\n return JSON.stringify({\n ok: true,\n issue: { key: issue_key, url: `${auth.url}/browse/${issue_key}` },\n attachments: parsed.map((a) => ({\n id: a.id,\n filename: a.filename,\n size: a.size,\n mime_type: a.mimeType,\n content_url: a.content,\n })),\n });\n },\n {\n name: \"jira_upload_attachment\",\n description:\n \"Upload a file as an attachment to a Jira issue. Pass content_base64 for binary files (PNG, PDF, \" +\n \"ZIP, etc.) or content_text for plain UTF-8 text (logs, CSVs, JSON). The agent itself reads/encodes \" +\n \"the source file — this tool only handles the upload. **PREFER THIS over pasting file contents into \" +\n \"a comment.** Disable to make the agent unable to add attachments.\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue to attach to\"),\n filename: z.string().describe(\"Filename shown in Jira (include the extension)\"),\n content_base64: z.string().optional().describe(\"Base64-encoded file contents (use for binary)\"),\n content_text: z.string().optional().describe(\"Raw UTF-8 text contents (use for logs/CSVs/JSON)\"),\n }),\n },\n);\n\nexport const jiraDeleteIssueTool = tool(\n async ({ issue_key, delete_subtasks }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const qs = delete_subtasks ? `?deleteSubtasks=true` : \"\";\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}${qs}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n // Successful DELETE returns 204 No Content → atlassianFetch returns \"\" (parsed as string).\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted: issue_key });\n },\n {\n name: \"jira_delete_issue\",\n description:\n \"Permanently delete a Jira issue. **DESTRUCTIVE — there is no undo from the API.** By default, \" +\n \"Jira refuses to delete an issue that has sub-tasks; pass delete_subtasks=true to delete them too. \" +\n \"Disable this tool entirely to make the agent unable to delete tickets.\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue to delete\"),\n delete_subtasks: z.boolean().optional().describe(\n \"If true, also delete all sub-tasks. Required when the issue has sub-tasks; otherwise Jira returns 400.\",\n ),\n }),\n },\n);\n\n// ── Jira agile tools ────────────────────────────────────────────────────────\n//\n// Sprint/board/backlog/rank lives at `/rest/agile/1.0/...`, NOT `/rest/api/3/`.\n// Same hostname + same Basic auth as the platform API, so atlassianFetch works\n// unchanged — only the path family differs. See ADR-0035.\n//\n// Sprint state machine: future → active → closed (one-way). Atlassian rejects\n// other transitions server-side, but we validate client-side too so the agent\n// gets a clean error with the list of legal next states instead of a 400.\n\nconst SPRINT_STATES = [\"future\", \"active\", \"closed\"] as const;\ntype SprintState = (typeof SPRINT_STATES)[number];\n\n// Pure — exported for tests. Returns the state argument shape Atlassian's\n// `POST /sprint/{id}` accepts, or an error if the transition is illegal.\nexport function validateSprintTransition(\n current: string | undefined,\n target: SprintState,\n): { ok: true } | { error: string } {\n if (target === \"future\") {\n return { error: \"cannot transition a sprint back to 'future' once created\" };\n }\n if (current === \"closed\") {\n return { error: \"sprint is already closed; no further transitions allowed\" };\n }\n if (target === \"active\" && current && current !== \"future\") {\n return { error: `cannot start a sprint in state '${current}' — only 'future' sprints can be started` };\n }\n if (target === \"closed\" && current && current !== \"active\") {\n return { error: `cannot complete a sprint in state '${current}' — only 'active' sprints can be completed` };\n }\n return { ok: true };\n}\n\nexport const jiraListBoardsTool = tool(\n async ({ project, name, type, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (project) params.set(\"projectKeyOrId\", project);\n if (name) params.set(\"name\", name);\n if (type) params.set(\"type\", type);\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(auth, `/rest/agile/1.0/board?${params}`) as\n | { values?: Array<Record<string, unknown>>; isLast?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n boards: (data.values ?? []).map((b) => ({\n id: b.id,\n name: b.name,\n type: b.type,\n project_key: ((b.location as Record<string, unknown>)?.projectKey) ?? null,\n })),\n is_last: data.isLast ?? null,\n });\n },\n {\n name: \"jira_list_boards\",\n description:\n \"List Jira agile boards (Scrum or Kanban). Filter by project key, name fragment, or board type. \" +\n \"Returns id, name, type, project_key. Use the id with jira_list_sprints / jira_get_backlog / etc.\",\n schema: z.object({\n project: z.string().optional().describe(\"Project key or id to filter by\"),\n name: z.string().optional().describe(\"Board name fragment (case-insensitive contains-match)\"),\n type: z.enum([\"scrum\", \"kanban\", \"simple\"]).optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\nexport const jiraGetBoardTool = tool(\n async ({ board_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Two calls in parallel — board metadata + configuration. The configuration\n // endpoint is what reveals estimation field, sub-query, ranking field, etc.,\n // which the agent often needs alongside the basic board info.\n const [meta, config] = await Promise.all([\n atlassianFetch(auth, `/rest/agile/1.0/board/${encodeURIComponent(board_id)}`),\n atlassianFetch(auth, `/rest/agile/1.0/board/${encodeURIComponent(board_id)}/configuration`),\n ]) as [Record<string, unknown> & { error?: string }, Record<string, unknown> & { error?: string }];\n if (meta.error) return JSON.stringify(meta);\n return JSON.stringify({\n id: meta.id,\n name: meta.name,\n type: meta.type,\n project_key: ((meta.location as Record<string, unknown>)?.projectKey) ?? null,\n configuration: config.error ? null : {\n filter_id: ((config.filter as Record<string, unknown>)?.id) ?? null,\n sub_query: ((config.subQuery as Record<string, unknown>)?.query) ?? null,\n estimation_field: ((config.estimation as Record<string, unknown>)?.field as Record<string, unknown>)?.fieldId ?? null,\n ranking_field: ((config.ranking as Record<string, unknown>)?.rankCustomFieldId) ?? null,\n },\n });\n },\n {\n name: \"jira_get_board\",\n description:\n \"Fetch board metadata and configuration in one call: id, name, type, project_key, plus filter id, \" +\n \"sub-query JQL, estimation field, and ranking custom field. Use this when you need to know how \" +\n \"issues are estimated or ranked on a specific board.\",\n schema: z.object({\n board_id: z.union([z.string(), z.number()]).describe(\"Board id from jira_list_boards\"),\n }),\n },\n);\n\nexport const jiraListSprintsTool = tool(\n async ({ board_id, state, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (state) params.set(\"state\", state);\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(\n auth,\n `/rest/agile/1.0/board/${encodeURIComponent(board_id)}/sprint?${params}`,\n ) as { values?: Array<Record<string, unknown>>; isLast?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n sprints: (data.values ?? []).map((s) => ({\n id: s.id,\n name: s.name,\n state: s.state,\n goal: s.goal ?? null,\n start_date: s.startDate ?? null,\n end_date: s.endDate ?? null,\n complete_date: s.completeDate ?? null,\n origin_board_id: s.originBoardId ?? null,\n })),\n is_last: data.isLast ?? null,\n });\n },\n {\n name: \"jira_list_sprints\",\n description:\n \"List sprints on a board. Filter by state ('active', 'closed', 'future'). Returns sprint id, name, \" +\n \"state, goal, dates, origin_board_id. To list issues IN a sprint, use jira_search with \" +\n \"JQL `sprint = {id}` — that's faster and supports custom field selection.\",\n schema: z.object({\n board_id: z.union([z.string(), z.number()]),\n state: z.enum([\"active\", \"closed\", \"future\"]).optional().describe(\"Comma in API but tool takes one state\"),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\nexport const jiraGetSprintTool = tool(\n async ({ sprint_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n id: data.id,\n name: data.name,\n state: data.state,\n goal: data.goal ?? null,\n start_date: data.startDate ?? null,\n end_date: data.endDate ?? null,\n complete_date: data.completeDate ?? null,\n origin_board_id: data.originBoardId ?? null,\n });\n },\n {\n name: \"jira_get_sprint\",\n description:\n \"Fetch a single sprint by id. Returns name, state, goal, start/end/complete dates. Use jira_search \" +\n \"with `sprint = {id}` to list its issues.\",\n schema: z.object({ sprint_id: z.union([z.string(), z.number()]) }),\n },\n);\n\nexport const jiraCreateSprintTool = tool(\n async ({ board_id, name, goal, start_date, end_date }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = { originBoardId: Number(board_id), name };\n if (goal) body.goal = goal;\n if (start_date) body.startDate = start_date;\n if (end_date) body.endDate = end_date;\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as { id?: number; self?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, sprint_id: data.id, board_id });\n },\n {\n name: \"jira_create_sprint\",\n description:\n \"Create a future sprint on a board. New sprints always start in 'future' state — use \" +\n \"jira_update_sprint with state='active' to start it. start_date/end_date are ISO 8601 strings; \" +\n \"they're optional but required by Atlassian before you can start the sprint.\",\n schema: z.object({\n board_id: z.union([z.string(), z.number()]).describe(\"Origin board id\"),\n name: z.string().describe(\"Sprint name\"),\n goal: z.string().optional(),\n start_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n end_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n }),\n },\n);\n\nexport const jiraUpdateSprintTool = tool(\n async ({ sprint_id, name, goal, start_date, end_date, state }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n if (state) {\n // Validate transition client-side. Fetch current state for a clean error.\n const current = await atlassianFetch(\n auth,\n `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`,\n ) as { state?: string; error?: string };\n if (current.error) return JSON.stringify(current);\n const check = validateSprintTransition(current.state, state);\n if (\"error\" in check) {\n return JSON.stringify({\n error: check.error,\n current_state: current.state,\n legal_next_states: SPRINT_STATES.filter(\n (s) => !(\"error\" in validateSprintTransition(current.state, s)),\n ),\n });\n }\n }\n\n const body: Record<string, unknown> = {};\n if (name !== undefined) body.name = name;\n if (goal !== undefined) body.goal = goal;\n if (start_date !== undefined) body.startDate = start_date;\n if (end_date !== undefined) body.endDate = end_date;\n if (state !== undefined) body.state = state;\n if (Object.keys(body).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of name, goal, start_date, end_date, state\" });\n }\n\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n sprint_id,\n state: data.state,\n updated_fields: Object.keys(body),\n });\n },\n {\n name: \"jira_update_sprint\",\n description:\n \"Update a sprint's name, goal, dates, or state. State transitions: future→active (start) or \" +\n \"active→closed (complete). Other transitions are rejected client-side with the list of legal \" +\n \"next states. Pass only the fields you want to change. **Disable to make the agent unable to \" +\n \"start/complete sprints.**\",\n schema: z.object({\n sprint_id: z.union([z.string(), z.number()]),\n name: z.string().optional(),\n goal: z.string().optional(),\n start_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n end_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n state: z.enum([\"active\", \"closed\"]).optional().describe(\n \"Target state. 'active' starts a future sprint; 'closed' completes an active sprint.\",\n ),\n }),\n },\n);\n\nexport const jiraDeleteSprintTool = tool(\n async ({ sprint_id, confirm }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (String(confirm) !== String(sprint_id)) {\n return JSON.stringify({\n error:\n `Refusing to delete sprint ${sprint_id}: pass \\`confirm\\` set to the same id to proceed. ` +\n `Sprint deletion is irreversible — the issues are unassigned but historical sprint data is lost.`,\n });\n }\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`, {\n method: \"DELETE\",\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_sprint_id: sprint_id });\n },\n {\n name: \"jira_delete_sprint\",\n description:\n \"Permanently delete a sprint. **Irreversible** — issues are unassigned from the sprint but the \" +\n \"sprint's velocity/burndown data is lost. The agent must pass `confirm` set to the same `sprint_id` \" +\n \"to proceed (two-arg gate). **Leave this tool disabled unless the user explicitly wants delete capability.**\",\n schema: z.object({\n sprint_id: z.union([z.string(), z.number()]),\n confirm: z.union([z.string(), z.number()]).describe(\"Must equal `sprint_id` for the delete to proceed\"),\n }),\n },\n);\n\nexport const jiraMoveIssuesToSprintTool = tool(\n async ({ sprint_id, issue_keys }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issue_keys.length) return JSON.stringify({ error: \"issue_keys is empty\" });\n if (issue_keys.length > 50) {\n return JSON.stringify({ error: `agile API accepts up to 50 issues per call (got ${issue_keys.length})` });\n }\n const data = await atlassianFetch(\n auth,\n `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}/issue`,\n { method: \"POST\", body: JSON.stringify({ issues: issue_keys }) },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, sprint_id, moved: issue_keys });\n },\n {\n name: \"jira_move_issues_to_sprint\",\n description:\n \"Move issues into a sprint. Up to 50 issues per call. Issues already in another sprint are \" +\n \"transparently moved (no separate remove step needed). Use jira_move_issues_to_backlog to remove \" +\n \"issues from sprints without putting them in a new one.\",\n schema: z.object({\n sprint_id: z.union([z.string(), z.number()]),\n issue_keys: z.array(z.string()).describe(\"Issue keys to move (e.g. ['PROJ-1','PROJ-2'])\"),\n }),\n },\n);\n\nexport const jiraMoveIssuesToBacklogTool = tool(\n async ({ issue_keys, board_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issue_keys.length) return JSON.stringify({ error: \"issue_keys is empty\" });\n if (issue_keys.length > 50) {\n return JSON.stringify({ error: `agile API accepts up to 50 issues per call (got ${issue_keys.length})` });\n }\n // The board-scoped endpoint /backlog/{boardId}/issue moves issues into THAT\n // board's backlog (preserving rank). The unscoped /backlog/issue endpoint\n // works for Scrum boards but not Kanban. Caller passes board_id when known.\n const path = board_id\n ? `/rest/agile/1.0/backlog/${encodeURIComponent(board_id)}/issue`\n : `/rest/agile/1.0/backlog/issue`;\n const data = await atlassianFetch(auth, path, {\n method: \"POST\",\n body: JSON.stringify({ issues: issue_keys }),\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, moved_to_backlog: issue_keys, board_id: board_id ?? null });\n },\n {\n name: \"jira_move_issues_to_backlog\",\n description:\n \"Remove issues from their current sprint and put them back on the backlog. Up to 50 issues per \" +\n \"call. Pass `board_id` for Kanban boards (the unscoped endpoint only works for Scrum). For Scrum, \" +\n \"board_id is optional but recommended for clarity.\",\n schema: z.object({\n issue_keys: z.array(z.string()),\n board_id: z.union([z.string(), z.number()]).optional().describe(\n \"Required for Kanban boards; optional but recommended for Scrum\",\n ),\n }),\n },\n);\n\nexport const jiraRankIssuesTool = tool(\n async ({ issues, rank_before_issue, rank_after_issue, rank_custom_field_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issues.length) return JSON.stringify({ error: \"issues is empty\" });\n if (issues.length > 50) {\n return JSON.stringify({ error: `agile API accepts up to 50 issues per call (got ${issues.length})` });\n }\n if ((rank_before_issue && rank_after_issue) || (!rank_before_issue && !rank_after_issue)) {\n return JSON.stringify({\n error: \"pass exactly one of rank_before_issue or rank_after_issue (not both, not neither)\",\n });\n }\n const body: Record<string, unknown> = { issues };\n if (rank_before_issue) body.rankBeforeIssue = rank_before_issue;\n if (rank_after_issue) body.rankAfterIssue = rank_after_issue;\n if (rank_custom_field_id !== undefined) body.rankCustomFieldId = rank_custom_field_id;\n const data = await atlassianFetch(auth, `/rest/agile/1.0/issue/rank`, {\n method: \"PUT\",\n body: JSON.stringify(body),\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n ranked: issues,\n relative_to: rank_before_issue ? { before: rank_before_issue } : { after: rank_after_issue },\n });\n },\n {\n name: \"jira_rank_issues\",\n description:\n \"Rank up to 50 issues relative to a single anchor issue (before XOR after). Pass \" +\n \"rank_custom_field_id only on sites that have a non-default rank field — get it from \" +\n \"jira_get_board.configuration.ranking_field. Order within `issues[]` is preserved.\",\n schema: z.object({\n issues: z.array(z.string()).describe(\"Issue keys in the order they should be placed\"),\n rank_before_issue: z.string().optional().describe(\"Anchor: place `issues` immediately before this key\"),\n rank_after_issue: z.string().optional().describe(\"Anchor: place `issues` immediately after this key\"),\n rank_custom_field_id: z.number().optional().describe(\n \"Custom rank field id (numeric). Default is the global rank field; rarely needed.\",\n ),\n }),\n },\n);\n\n// ── Jira issue extras (comments CRUD, worklogs, attachments, changelog) ─────\n//\n// These fill specific gaps left by the issue-CRUD tools above:\n// - jira_get_issue caps embedded comments at ~50; jira_get_comments paginates.\n// - jira_update_issue can't touch existing comments — that needs the per-comment endpoint.\n// - jira_upload_attachment uploads but doesn't read or delete; the get/delete pair completes it.\n// - jira_get_issue's changelog field is opt-in via expand and capped; the dedicated endpoint paginates.\n// See ADR-0035.\n\nexport const jiraGetCommentsTool = tool(\n async ({ issue_key, start_at, max_results, order_by }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n if (order_by) params.set(\"orderBy\", order_by);\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment?${params}`,\n ) as {\n comments?: Array<Record<string, unknown>>;\n startAt?: number; maxResults?: number; total?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issue_key,\n start_at: data.startAt ?? 0,\n max_results: data.maxResults ?? 0,\n total: data.total ?? 0,\n comments: (data.comments ?? []).map((c) => ({\n id: c.id,\n author: (c.author as Record<string, unknown>)?.displayName ?? null,\n created: c.created,\n updated: c.updated,\n body: simplifyADF(c.body),\n })),\n });\n },\n {\n name: \"jira_get_comments\",\n description:\n \"Paginated comment list for a Jira issue. Use this when an issue has more comments than the \" +\n \"embedded list returned by jira_get_issue (Jira caps that at ~50). order_by accepts 'created' \" +\n \"or '-created' for ascending/descending. ADF bodies auto-flattened.\",\n schema: z.object({\n issue_key: z.string(),\n start_at: z.number().optional().describe(\"Offset for pagination (default 0)\"),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n order_by: z.enum([\"created\", \"-created\"]).optional(),\n }),\n },\n);\n\nexport const jiraUpdateCommentTool = tool(\n async ({ issue_key, comment_id, body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment/${encodeURIComponent(comment_id)}`,\n { method: \"PUT\", body: JSON.stringify({ body: textToADF(body) }) },\n ) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, comment_id: data.id ?? comment_id });\n },\n {\n name: \"jira_update_comment\",\n description:\n \"Edit an existing comment on a Jira issue. Plain-text body is auto-converted to ADF (same as \" +\n \"jira_add_comment). The author and created timestamp are preserved; updated reflects this edit.\",\n schema: z.object({\n issue_key: z.string(),\n comment_id: z.string().describe(\"Comment id from jira_get_issue.comments[].id or jira_get_comments\"),\n body: z.string(),\n }),\n },\n);\n\nexport const jiraDeleteCommentTool = tool(\n async ({ issue_key, comment_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment/${encodeURIComponent(comment_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_comment_id: comment_id, issue_key });\n },\n {\n name: \"jira_delete_comment\",\n description:\n \"Permanently delete a comment from a Jira issue. **Destructive — no undo.** Look up the id via \" +\n \"jira_get_issue (include_comments: true) or jira_get_comments. Disable to make the agent unable \" +\n \"to delete comments.\",\n schema: z.object({ issue_key: z.string(), comment_id: z.string() }),\n },\n);\n\nexport const jiraGetAttachmentContentTool = tool(\n async ({ content_url, as_text }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Attachment content URLs from /rest/api/3/issue/{key} come pre-built as\n // absolute URLs under the auth.url host. We accept either absolute or\n // relative; build the request URL accordingly.\n const fullUrl = content_url.startsWith(\"http\")\n ? content_url\n : `${auth.url}${content_url.startsWith(\"/\") ? \"\" : \"/\"}${content_url}`;\n const res = await fetch(fullUrl, { headers: { Authorization: authHeader(auth) } });\n if (!res.ok) {\n const errText = await res.text();\n return JSON.stringify({ error: `Atlassian ${res.status}: ${errText.slice(0, 500)}` });\n }\n const ct = res.headers.get(\"content-type\") ?? \"\";\n const looksText = as_text === true\n || (as_text !== false && /^(text\\/|application\\/(json|xml|yaml|x-yaml))/i.test(ct));\n if (looksText) {\n const text = await res.text();\n return JSON.stringify({\n content_type: ct,\n size: text.length,\n as: \"text\",\n content: text.slice(0, 50_000),\n truncated: text.length > 50_000,\n });\n }\n const buf = Buffer.from(await res.arrayBuffer());\n return JSON.stringify({\n content_type: ct,\n size: buf.length,\n as: \"base64\",\n content: buf.toString(\"base64\"),\n });\n },\n {\n name: \"jira_get_attachment_content\",\n description:\n \"Fetch a Jira issue attachment's bytes by content_url (from jira_get_issue.attachments[].content_url). \" +\n \"Returns UTF-8 text capped at 50KB for text-like content types, or base64 for binary. Override the \" +\n \"auto-detection via `as_text`. Mirrors confluence_get_attachment_content.\",\n schema: z.object({\n content_url: z.string().describe(\"content_url from jira_get_issue.attachments[]\"),\n as_text: z.boolean().optional().describe(\n \"Force text decode (true) or binary base64 (false). Default: auto-detect by content-type.\",\n ),\n }),\n },\n);\n\nexport const jiraDeleteAttachmentTool = tool(\n async ({ attachment_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/attachment/${encodeURIComponent(attachment_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_attachment_id: attachment_id });\n },\n {\n name: \"jira_delete_attachment\",\n description:\n \"Permanently delete an attachment from a Jira issue by id. **Destructive — no undo.** Look up \" +\n \"the id via jira_get_issue.attachments[].id. Disable to make the agent unable to delete attachments.\",\n schema: z.object({\n attachment_id: z.string().describe(\"Attachment id (from jira_get_issue.attachments[].id)\"),\n }),\n },\n);\n\nexport const jiraAddWorklogTool = tool(\n async ({ issue_key, time_spent, started, comment }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = { timeSpent: time_spent };\n if (started) body.started = started;\n if (comment) body.comment = textToADF(comment);\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/worklog`,\n { method: \"POST\", body: JSON.stringify(body) },\n ) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, worklog_id: data.id, issue_key });\n },\n {\n name: \"jira_add_worklog\",\n description:\n \"Log time spent on a Jira issue. time_spent uses Jira's duration syntax: '1h', '30m', '2d 4h', etc. \" +\n \"started is an ISO 8601 timestamp (defaults to now). comment is plain text auto-converted to ADF.\",\n schema: z.object({\n issue_key: z.string(),\n time_spent: z.string().describe(\"Duration string ('1h', '30m', '2d 4h')\"),\n started: z.string().optional().describe(\"ISO 8601 timestamp; defaults to now\"),\n comment: z.string().optional(),\n }),\n },\n);\n\nexport const jiraListWorklogsTool = tool(\n async ({ issue_key, start_at, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 1000)));\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/worklog?${params}`,\n ) as {\n worklogs?: Array<Record<string, unknown>>;\n startAt?: number; maxResults?: number; total?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issue_key,\n start_at: data.startAt ?? 0,\n max_results: data.maxResults ?? 0,\n total: data.total ?? 0,\n worklogs: (data.worklogs ?? []).map((w) => ({\n id: w.id,\n author: (w.author as Record<string, unknown>)?.displayName ?? null,\n time_spent: w.timeSpent,\n time_spent_seconds: w.timeSpentSeconds,\n started: w.started,\n created: w.created,\n updated: w.updated,\n comment: simplifyADF(w.comment),\n })),\n });\n },\n {\n name: \"jira_list_worklogs\",\n description:\n \"List worklog entries on a Jira issue (paginated). Returns id, author, time_spent (display string + \" +\n \"seconds), started, comment. Use to compute totals or audit time tracking.\",\n schema: z.object({\n issue_key: z.string(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 1000\"),\n }),\n },\n);\n\nexport const jiraGetChangelogTool = tool(\n async ({ issue_key, start_at, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/changelog?${params}`,\n ) as {\n values?: Array<Record<string, unknown>>;\n startAt?: number; maxResults?: number; total?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issue_key,\n start_at: data.startAt ?? 0,\n max_results: data.maxResults ?? 0,\n total: data.total ?? 0,\n changelog: (data.values ?? []).map((entry) => ({\n id: entry.id,\n author: (entry.author as Record<string, unknown>)?.displayName ?? null,\n created: entry.created,\n items: ((entry.items as Array<Record<string, unknown>>) ?? []).map((item) => ({\n field: item.field,\n field_type: item.fieldtype,\n // Atlassian returns both `from`/`to` (raw ids) and `fromString`/`toString`\n // (human-readable). Prefer the human form when present. NB: hasOwn check\n // is required because `toString` is inherited from Object.prototype.\n from: Object.hasOwn(item, \"fromString\") ? item.fromString : (item.from ?? null),\n to: Object.hasOwn(item, \"toString\") ? item.toString : (item.to ?? null),\n })),\n })),\n });\n },\n {\n name: \"jira_get_changelog\",\n description:\n \"Fetch a Jira issue's history (paginated). Each entry has author, timestamp, and a list of \" +\n \"field-level changes (field name, from, to). Useful for 'what changed yesterday?' audits and \" +\n \"for surfacing the previous value of a field.\",\n schema: z.object({\n issue_key: z.string(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\n// ── Jira project metadata (projects, versions, components, generic enums) ──\n//\n// These let the agent introspect a site without guessing — list projects,\n// list versions on a project, read the canonical issue-type/priority/status\n// names. Mostly thin wrappers around /rest/api/3/project*, /version, /component,\n// and the four enum endpoints. See ADR-0035.\n\nexport const jiraListProjectsTool = tool(\n async ({ query, category_id, max_results, start_at }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (query) params.set(\"query\", query);\n if (category_id !== undefined) params.set(\"categoryId\", String(category_id));\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(auth, `/rest/api/3/project/search?${params}`) as\n | { values?: Array<Record<string, unknown>>; total?: number; isLast?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total ?? 0,\n is_last: data.isLast ?? null,\n projects: (data.values ?? []).map((p) => ({\n id: p.id,\n key: p.key,\n name: p.name,\n type_key: p.projectTypeKey ?? null,\n style: p.style ?? null,\n lead: ((p.lead as Record<string, unknown>)?.displayName) ?? null,\n })),\n });\n },\n {\n name: \"jira_list_projects\",\n description:\n \"List Jira projects (paginated). Filter by name fragment via `query` or by category. Returns \" +\n \"id, key, name, type, style ('classic'|'next-gen'), lead.\",\n schema: z.object({\n query: z.string().optional().describe(\"Project name/key fragment\"),\n category_id: z.number().optional(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\nexport const jiraGetProjectTool = tool(\n async ({ project_key, include_versions, include_components, include_issue_types }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const expand: string[] = [];\n if (include_versions) expand.push(\"versions\");\n if (include_components) expand.push(\"components\");\n if (include_issue_types) expand.push(\"issueTypes\");\n const qs = expand.length ? `?expand=${expand.join(\",\")}` : \"\";\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/project/${encodeURIComponent(project_key)}${qs}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n id: data.id,\n key: data.key,\n name: data.name,\n type_key: data.projectTypeKey ?? null,\n style: data.style ?? null,\n description: data.description ?? null,\n lead: ((data.lead as Record<string, unknown>)?.displayName) ?? null,\n url: `${auth.url}/browse/${data.key}`,\n ...(include_versions ? {\n versions: ((data.versions as Array<Record<string, unknown>>) ?? []).map((v) => ({\n id: v.id, name: v.name, released: v.released, archived: v.archived,\n start_date: v.startDate ?? null, release_date: v.releaseDate ?? null,\n })),\n } : {}),\n ...(include_components ? {\n components: ((data.components as Array<Record<string, unknown>>) ?? []).map((c) => ({\n id: c.id, name: c.name,\n lead: ((c.lead as Record<string, unknown>)?.displayName) ?? null,\n })),\n } : {}),\n ...(include_issue_types ? {\n issue_types: ((data.issueTypes as Array<Record<string, unknown>>) ?? []).map((t) => ({\n id: t.id, name: t.name, subtask: t.subtask, hierarchy_level: t.hierarchyLevel,\n })),\n } : {}),\n });\n },\n {\n name: \"jira_get_project\",\n description:\n \"Fetch a single Jira project by key. Optionally include versions, components, and/or issue types \" +\n \"in the response — saves separate calls for the common 'tell me about this project' use case.\",\n schema: z.object({\n project_key: z.string(),\n include_versions: z.boolean().optional(),\n include_components: z.boolean().optional(),\n include_issue_types: z.boolean().optional(),\n }),\n },\n);\n\nexport const jiraListVersionsTool = tool(\n async ({ project_key, start_at, max_results, order_by }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n if (order_by) params.set(\"orderBy\", order_by);\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/project/${encodeURIComponent(project_key)}/version?${params}`,\n ) as {\n values?: Array<Record<string, unknown>>;\n total?: number; isLast?: boolean; error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total ?? 0,\n is_last: data.isLast ?? null,\n versions: (data.values ?? []).map((v) => ({\n id: v.id,\n name: v.name,\n released: v.released,\n archived: v.archived,\n start_date: v.startDate ?? null,\n release_date: v.releaseDate ?? null,\n description: v.description ?? null,\n })),\n });\n },\n {\n name: \"jira_list_versions\",\n description:\n \"List versions on a Jira project (paginated). Returns id, name, released/archived flags, dates. \" +\n \"Use jira_create_version to add a new one and jira_update_version to release/archive.\",\n schema: z.object({\n project_key: z.string(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n order_by: z.enum([\"sequence\", \"name\", \"startDate\", \"releaseDate\", \"-sequence\", \"-name\", \"-startDate\", \"-releaseDate\"]).optional(),\n }),\n },\n);\n\nexport const jiraCreateVersionTool = tool(\n async ({ project_key, name, description, start_date, release_date, released }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Resolve project key → numeric project id (the version endpoint requires id, not key).\n const proj = await atlassianFetch(auth, `/rest/api/3/project/${encodeURIComponent(project_key)}`) as\n { id?: string; error?: string };\n if (proj.error) return JSON.stringify(proj);\n if (!proj.id) return JSON.stringify({ error: `could not resolve project_key \"${project_key}\" to a numeric id` });\n const body: Record<string, unknown> = { projectId: Number(proj.id), name };\n if (description !== undefined) body.description = description;\n if (start_date !== undefined) body.startDate = start_date;\n if (release_date !== undefined) body.releaseDate = release_date;\n if (released !== undefined) body.released = released;\n const data = await atlassianFetch(auth, `/rest/api/3/version`, {\n method: \"POST\", body: JSON.stringify(body),\n }) as { id?: string; name?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, version_id: data.id, name: data.name });\n },\n {\n name: \"jira_create_version\",\n description:\n \"Create a new version on a Jira project. Pass the project key — we resolve it to the numeric id. \" +\n \"start_date / release_date are 'YYYY-MM-DD'. Set released=true to mark released on creation.\",\n schema: z.object({\n project_key: z.string(),\n name: z.string(),\n description: z.string().optional(),\n start_date: z.string().optional().describe(\"YYYY-MM-DD\"),\n release_date: z.string().optional().describe(\"YYYY-MM-DD\"),\n released: z.boolean().optional(),\n }),\n },\n);\n\nexport const jiraUpdateVersionTool = tool(\n async ({ version_id, name, description, start_date, release_date, released, archived }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = {};\n if (name !== undefined) body.name = name;\n if (description !== undefined) body.description = description;\n if (start_date !== undefined) body.startDate = start_date;\n if (release_date !== undefined) body.releaseDate = release_date;\n if (released !== undefined) body.released = released;\n if (archived !== undefined) body.archived = archived;\n if (Object.keys(body).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of name, description, start_date, release_date, released, archived\" });\n }\n const data = await atlassianFetch(auth, `/rest/api/3/version/${encodeURIComponent(version_id)}`, {\n method: \"PUT\", body: JSON.stringify(body),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n version_id,\n released: data.released ?? null,\n archived: data.archived ?? null,\n updated_fields: Object.keys(body),\n });\n },\n {\n name: \"jira_update_version\",\n description:\n \"Edit a version: rename, change dates, mark released/unreleased, mark archived/unarchived. \" +\n \"Pass only the fields you want to change. To 'release' a version, pass released=true (and \" +\n \"release_date if not already set). To unrelease, pass released=false. **Disable to make the \" +\n \"agent unable to release versions.**\",\n schema: z.object({\n version_id: z.string(),\n name: z.string().optional(),\n description: z.string().optional(),\n start_date: z.string().optional(),\n release_date: z.string().optional(),\n released: z.boolean().optional(),\n archived: z.boolean().optional(),\n }),\n },\n);\n\nexport const jiraListComponentsTool = tool(\n async ({ project_key }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/project/${encodeURIComponent(project_key)}/components`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n components: data.map((c) => ({\n id: c.id,\n name: c.name,\n description: c.description ?? null,\n lead: ((c.lead as Record<string, unknown>)?.displayName) ?? null,\n assignee_type: c.assigneeType ?? null,\n })),\n });\n },\n {\n name: \"jira_list_components\",\n description:\n \"List components on a Jira project. Returns id, name, description, lead, default assignee type. \" +\n \"Components are not paginated by Jira — the full list returns in one call.\",\n schema: z.object({ project_key: z.string() }),\n },\n);\n\nexport const jiraCreateComponentTool = tool(\n async ({ project_key, name, description, lead_account_id, assignee_type }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = { project: project_key, name };\n if (description !== undefined) body.description = description;\n if (lead_account_id !== undefined) body.leadAccountId = lead_account_id;\n if (assignee_type !== undefined) body.assigneeType = assignee_type;\n const data = await atlassianFetch(auth, `/rest/api/3/component`, {\n method: \"POST\", body: JSON.stringify(body),\n }) as { id?: string; name?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, component_id: data.id, name: data.name });\n },\n {\n name: \"jira_create_component\",\n description:\n \"Create a component on a Jira project. assignee_type controls default assignee for issues with \" +\n \"this component: 'PROJECT_DEFAULT' | 'COMPONENT_LEAD' | 'PROJECT_LEAD' | 'UNASSIGNED'.\",\n schema: z.object({\n project_key: z.string(),\n name: z.string(),\n description: z.string().optional(),\n lead_account_id: z.string().optional(),\n assignee_type: z.enum([\"PROJECT_DEFAULT\", \"COMPONENT_LEAD\", \"PROJECT_LEAD\", \"UNASSIGNED\"]).optional(),\n }),\n },\n);\n\nconst META_KIND_TO_PATH: Record<string, string> = {\n issue_type: \"/rest/api/3/issuetype\",\n priority: \"/rest/api/3/priority\",\n status: \"/rest/api/3/status\",\n resolution: \"/rest/api/3/resolution\",\n};\nconst META_KINDS = Object.keys(META_KIND_TO_PATH) as ReadonlyArray<keyof typeof META_KIND_TO_PATH>;\n\nexport const jiraListMetaTool = tool(\n async ({ kind }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!kind) {\n return JSON.stringify({\n available_kinds: META_KINDS,\n usage: \"Pass kind='issue_type' | 'priority' | 'status' | 'resolution' to list that enum's values for the site.\",\n });\n }\n const path = META_KIND_TO_PATH[kind];\n if (!path) {\n return JSON.stringify({ error: `unknown kind \"${kind}\". Expected one of: ${META_KINDS.join(\", \")}.` });\n }\n const data = await atlassianFetch(auth, path) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n kind,\n values: data.map((v) => ({\n id: v.id,\n name: v.name,\n description: v.description ?? null,\n ...(kind === \"issue_type\" ? { subtask: v.subtask, hierarchy_level: v.hierarchyLevel } : {}),\n ...(kind === \"status\" ? {\n status_category: ((v.statusCategory as Record<string, unknown>)?.name) ?? null,\n } : {}),\n })),\n });\n },\n {\n name: \"jira_list_meta\",\n description:\n \"List values for a Jira site-wide enum: issue types, priorities, statuses, or resolutions. \" +\n \"Pass `kind` = 'issue_type' | 'priority' | 'status' | 'resolution'. Omit `kind` to list available kinds. \" +\n \"Use this before jira_create_issue / jira_update_issue when you don't know the exact name on this site.\",\n schema: z.object({\n kind: z.enum(META_KINDS as [string, ...string[]]).optional(),\n }),\n },\n);\n\n// ── Confluence tools ────────────────────────────────────────────────────────\n//\n// Most tools below use the Confluence v2 REST API (/wiki/api/v2/...). Three\n// gaps still require v1 paths as of 2026 and are flagged inline:\n// - confluence_search: v2 has no CQL endpoint.\n// - confluence_upload_attachment: v2 Attachment group is read-only (CONFCLOUD-77196).\n// - confluence_add_label: v2 Label group is read-only (CONFCLOUD-76866).\n// The remote document-RAG indexer in lib/documents/remote/confluence.ts (ADR-0026)\n// stays on v1 — it has its own concerns and is intentionally untouched here.\n\nexport const confluenceSearchTool = tool(\n async ({ cql, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 15, 50);\n // v1: CQL search has no v2 equivalent.\n const data = await atlassianFetch(\n auth,\n `/wiki/rest/api/content/search?cql=${encodeURIComponent(cql)}&limit=${limit}`,\n ) as { results?: Array<Record<string, unknown>>; size?: number; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.size,\n results: (data.results ?? []).map((r: Record<string, unknown>) => ({\n id: r.id,\n type: r.type,\n title: r.title,\n url: `${auth.url}/wiki${((r._links as Record<string, unknown>)?.webui) ?? \"\"}`,\n })),\n });\n },\n {\n name: \"confluence_search\",\n description:\n \"Search Confluence pages with CQL (Confluence Query Language). \" +\n \"Examples: 'type=page AND title~\\\"runbook\\\"', 'space=ENG AND lastmodified > now(\\\"-7d\\\")'.\",\n schema: z.object({\n cql: z.string().describe(\"CQL query string\"),\n max_results: z.number().optional().describe(\"Max results (default 15, max 50)\"),\n }),\n },\n);\n\nexport const confluenceGetPageTool = tool(\n async ({ page_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}?body-format=storage,view&include-version=true`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const body = data.body as Record<string, Record<string, unknown> | undefined> | undefined;\n const storageVal = body?.storage?.value as string | undefined;\n const viewVal = body?.view?.value as string | undefined;\n const links = data._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n return JSON.stringify({\n id: data.id,\n title: data.title,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n space_id: data.spaceId ?? null,\n parent_id: data.parentId ?? null,\n status: data.status,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? null,\n // body_storage round-trips into confluence_update_page; body_view is rendered HTML\n // for summarization. Each capped to 20KB to keep context lean.\n body_storage: storageVal ? storageVal.slice(0, 20_000) : null,\n body_storage_truncated: storageVal ? storageVal.length > 20_000 : false,\n body_view: viewVal ? viewVal.slice(0, 20_000) : null,\n body_view_truncated: viewVal ? viewVal.length > 20_000 : false,\n });\n },\n {\n name: \"confluence_get_page\",\n description:\n \"Fetch a Confluence page by id (v2). Returns title, space_id, parent_id, version, and BOTH \" +\n \"body_storage (round-trippable into confluence_update_page) and body_view (rendered HTML, \" +\n \"easier to summarize). Each body capped at 20KB.\",\n schema: z.object({\n page_id: z.string(),\n }),\n },\n);\n\nexport const confluenceGetPageByTitleTool = tool(\n async ({ space_key, title, include_body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const sid = await resolveSpaceId(auth, space_key);\n if (typeof sid !== \"string\") return JSON.stringify(sid);\n const params = new URLSearchParams({ title, \"space-id\": sid, limit: \"5\" });\n if (include_body) params.set(\"body-format\", \"storage\");\n const data = await atlassianFetch(auth, `/wiki/api/v2/pages?${params}`) as\n | { results?: Array<Record<string, unknown>>; error?: string };\n if (!Array.isArray(data?.results)) return JSON.stringify(data);\n return JSON.stringify({\n matches: data.results.map((p) => {\n const links = p._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n const body = p.body as Record<string, Record<string, unknown> | undefined> | undefined;\n return {\n id: p.id,\n title: p.title,\n space_id: p.spaceId,\n parent_id: p.parentId ?? null,\n status: p.status,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n ...(include_body\n ? { body_storage: ((body?.storage?.value as string | undefined) ?? \"\").slice(0, 20_000) }\n : {}),\n };\n }),\n });\n },\n {\n name: \"confluence_get_page_by_title\",\n description:\n \"Find Confluence page(s) by exact title within a space. Auto-resolves `space_key` (e.g. 'ENG') \" +\n \"to the v2 space id. Returns up to 5 matches; pass `include_body: true` to also include storage XHTML.\",\n schema: z.object({\n space_key: z.string().describe(\"Space key like 'ENG'\"),\n title: z.string().describe(\"Exact page title (case-sensitive on Cloud)\"),\n include_body: z.boolean().optional(),\n }),\n },\n);\n\nexport const confluenceGetPageChildrenTool = tool(\n async ({ page_id, cursor, limit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 25, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/children?${params}`,\n ) as { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n children: (data.results ?? []).map((p) => ({\n id: p.id,\n title: p.title,\n type: p.type,\n status: p.status,\n parent_id: p.parentId ?? null,\n position: p.position ?? null,\n })),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_get_page_children\",\n description:\n \"List direct children of a Confluence page (cursor-paginated). Pass `cursor` from a prior call's \" +\n \"`next_cursor` to fetch the next page. Default limit 25 (max 250).\",\n schema: z.object({\n page_id: z.string(),\n cursor: z.string().optional(),\n limit: z.number().optional(),\n }),\n },\n);\n\nexport const confluenceGetPageAncestorsTool = tool(\n async ({ page_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/ancestors`,\n ) as { results?: Array<Record<string, unknown>>; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ancestors: (data.results ?? []).map((a) => ({ id: a.id, title: a.title, type: a.type })),\n });\n },\n {\n name: \"confluence_get_page_ancestors\",\n description:\n \"Return the parent chain (root → leaf) for a Confluence page. Useful for breadcrumbs and \" +\n \"understanding where a page lives in the tree.\",\n schema: z.object({ page_id: z.string() }),\n },\n);\n\nexport const confluenceListSpacesTool = tool(\n async ({ cursor, limit, type, status }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 25, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n if (type) params.set(\"type\", type);\n if (status) params.set(\"status\", status);\n const data = await atlassianFetch(auth, `/wiki/api/v2/spaces?${params}`) as\n | { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n spaces: (data.results ?? []).map((s) => ({\n id: s.id,\n key: s.key,\n name: s.name,\n type: s.type,\n status: s.status,\n homepage_id: s.homepageId ?? null,\n })),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_list_spaces\",\n description:\n \"List Confluence spaces (cursor-paginated). Returns id, key, name, type, status, homepage_id. \" +\n \"Useful for discovering space keys to pass to confluence_create_page or confluence_get_page_by_title.\",\n schema: z.object({\n cursor: z.string().optional(),\n limit: z.number().optional(),\n type: z.enum([\"global\", \"personal\", \"collaboration\", \"knowledge_base\"]).optional(),\n status: z.enum([\"current\", \"archived\"]).optional(),\n }),\n },\n);\n\nexport const confluenceGetCommentsTool = tool(\n async ({ page_id, include_inline }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const footerData = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/footer-comments?body-format=storage&limit=100`,\n ) as { results?: Array<Record<string, unknown>>; error?: string };\n let inlineData: { results?: Array<Record<string, unknown>>; error?: string } | undefined;\n if (include_inline !== false) {\n // Known v2 bug: some sites 404 here even when comments exist. Tolerate\n // and surface as `inline_warning` so the caller still gets footer comments.\n inlineData = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/inline-comments?body-format=storage&limit=100`,\n ) as { results?: Array<Record<string, unknown>>; error?: string };\n }\n if (footerData.error && !Array.isArray(footerData.results)) return JSON.stringify(footerData);\n const flatten = (c: Record<string, unknown>) => {\n const ver = c.version as Record<string, unknown> | undefined;\n const body = c.body as Record<string, Record<string, unknown> | undefined> | undefined;\n return {\n id: c.id,\n version: ver?.number ?? null,\n author_id: c.authorId ?? ver?.authorId ?? null,\n created_at: ver?.createdAt ?? null,\n body_storage: (body?.storage?.value as string | undefined) ?? null,\n parent_comment_id: c.parentCommentId ?? null,\n };\n };\n return JSON.stringify({\n footer_comments: (footerData.results ?? []).map(flatten),\n inline_comments: inlineData && Array.isArray(inlineData.results) ? inlineData.results.map(flatten) : [],\n ...(inlineData && inlineData.error ? { inline_warning: inlineData.error } : {}),\n });\n },\n {\n name: \"confluence_get_comments\",\n description:\n \"List footer comments (and inline comments by default) on a Confluence page. Returns id, \" +\n \"version, author_id, created_at, body_storage, parent_comment_id (for threading). Tolerates \" +\n \"the known v2 inline-comments 404 bug — surfaces it as `inline_warning` rather than failing.\",\n schema: z.object({\n page_id: z.string(),\n include_inline: z.boolean().optional().describe(\"Default true; pass false to skip inline-comments.\"),\n }),\n },\n);\n\nexport const confluenceListAttachmentsTool = tool(\n async ({ page_id, cursor, limit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 50, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/attachments?${params}`,\n ) as { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n attachments: (data.results ?? []).map((a) => {\n const ver = a.version as Record<string, unknown> | undefined;\n const links = a._links as Record<string, unknown> | undefined;\n return {\n id: a.id,\n title: a.title,\n media_type: a.mediaType,\n file_size: a.fileSize ?? null,\n created_at: ver?.createdAt ?? null,\n download_link: a.downloadLink ?? null,\n webui_link: links?.webui ?? null,\n };\n }),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_list_attachments\",\n description:\n \"List attachments on a Confluence page (cursor-paginated). Returns id, title, media_type, \" +\n \"file_size, download_link. Use confluence_get_attachment_content with the download_link to \" +\n \"fetch bytes.\",\n schema: z.object({\n page_id: z.string(),\n cursor: z.string().optional(),\n limit: z.number().optional(),\n }),\n },\n);\n\nexport const confluenceGetLabelsTool = tool(\n async ({ page_id, cursor, limit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 50, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/labels?${params}`,\n ) as { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n labels: (data.results ?? []).map((l) => ({ id: l.id, name: l.name, prefix: l.prefix })),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_get_labels\",\n description: \"List labels on a Confluence page (cursor-paginated). Default limit 50 (max 250).\",\n schema: z.object({\n page_id: z.string(),\n cursor: z.string().optional(),\n limit: z.number().optional(),\n }),\n },\n);\n\nexport const confluenceGetAttachmentContentTool = tool(\n async ({ download_link, as_text }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // download_link from v2 is typically `/download/attachments/{pageId}/{filename}?...`\n // — under the /wiki app, NOT under the bare auth.url. Build the absolute URL\n // explicitly because atlassianFetch's plain `${auth.url}${path}` join would\n // miss the /wiki prefix.\n const fullUrl = download_link.startsWith(\"http\")\n ? download_link\n : download_link.startsWith(\"/wiki\")\n ? `${auth.url}${download_link}`\n : `${auth.url}/wiki${download_link.startsWith(\"/\") ? \"\" : \"/\"}${download_link}`;\n const res = await fetch(fullUrl, { headers: { Authorization: authHeader(auth) } });\n if (!res.ok) {\n const errText = await res.text();\n return JSON.stringify({ error: `Atlassian ${res.status}: ${errText.slice(0, 500)}` });\n }\n const ct = res.headers.get(\"content-type\") ?? \"\";\n const looksText = as_text === true\n || (as_text !== false && /^(text\\/|application\\/(json|xml|yaml|x-yaml))/i.test(ct));\n if (looksText) {\n const text = await res.text();\n return JSON.stringify({\n content_type: ct,\n size: text.length,\n as: \"text\",\n content: text.slice(0, 50_000),\n truncated: text.length > 50_000,\n });\n }\n const buf = Buffer.from(await res.arrayBuffer());\n return JSON.stringify({\n content_type: ct,\n size: buf.length,\n as: \"base64\",\n content: buf.toString(\"base64\"),\n });\n },\n {\n name: \"confluence_get_attachment_content\",\n description:\n \"Fetch an attachment's bytes by its download_link (from confluence_list_attachments). Returns \" +\n \"UTF-8 text (capped at 50KB) for text-like content types, or base64 for binary. Override the \" +\n \"auto-detection via `as_text`.\",\n schema: z.object({\n download_link: z.string().describe(\"download_link from confluence_list_attachments\"),\n as_text: z.boolean().optional().describe(\n \"Force text decode (true) or binary base64 (false). Default: auto-detect by content-type.\",\n ),\n }),\n },\n);\n\nexport const confluenceCreatePageTool = tool(\n async ({ space_key, title, parent_id, body_text, body_storage }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const sid = await resolveSpaceId(auth, space_key);\n if (typeof sid !== \"string\") return JSON.stringify(sid);\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n const payload: Record<string, unknown> = {\n spaceId: sid,\n status: \"current\",\n title,\n body: { representation: body.representation, value: body.value },\n };\n if (parent_id) payload.parentId = parent_id;\n const data = await atlassianFetch(auth, `/wiki/api/v2/pages`, {\n method: \"POST\",\n body: JSON.stringify(payload),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const links = data._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n return JSON.stringify({\n ok: true,\n id: data.id,\n title: data.title,\n space_id: data.spaceId,\n parent_id: data.parentId ?? null,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? 1,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n });\n },\n {\n name: \"confluence_create_page\",\n description:\n \"Create a Confluence page (v2). Pass `space_key` (e.g. 'ENG') — auto-resolved to v2 spaceId. \" +\n \"Pass exactly one of `body_text` (plain text → storage XHTML automatically) or `body_storage` \" +\n \"(raw XHTML for advanced edits). `parent_id` makes it a child page. \" +\n \"Disable to make the agent unable to author Confluence pages.\",\n schema: z.object({\n space_key: z.string(),\n title: z.string(),\n parent_id: z.string().optional().describe(\"Page id of the parent; omit for top-level.\"),\n body_text: z.string().optional().describe(\"Plain text; auto-converted to storage XHTML.\"),\n body_storage: z.string().optional().describe(\"Raw Confluence storage-format XHTML.\"),\n }),\n },\n);\n\nexport const confluenceUpdatePageTool = tool(\n async ({ page_id, title, body_text, body_storage, version_number, version_message }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n\n let nextVersion = version_number;\n let resolvedTitle: string | undefined = title;\n if (nextVersion === undefined || resolvedTitle === undefined) {\n // PUT requires both title and version even when not changing them, so\n // fetch the current page when either is omitted. Cheaper than asking\n // every caller to do it.\n const current = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}`,\n ) as { title?: string; version?: { number?: number }; error?: string };\n if (current.error) return JSON.stringify(current);\n if (nextVersion === undefined) {\n const cur = current.version?.number;\n if (typeof cur !== \"number\") return JSON.stringify({ error: \"could not read current version from Confluence response\" });\n nextVersion = cur + 1;\n }\n if (resolvedTitle === undefined) resolvedTitle = current.title;\n }\n\n const payload: Record<string, unknown> = {\n id: page_id,\n status: \"current\",\n title: resolvedTitle,\n body: { representation: body.representation, value: body.value },\n version: { number: nextVersion, ...(version_message ? { message: version_message } : {}) },\n };\n const data = await atlassianFetch(auth, `/wiki/api/v2/pages/${encodeURIComponent(page_id)}`, {\n method: \"PUT\",\n body: JSON.stringify(payload),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const links = data._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n return JSON.stringify({\n ok: true,\n id: data.id,\n title: data.title,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? nextVersion,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n });\n },\n {\n name: \"confluence_update_page\",\n description:\n \"Update an existing Confluence page (v2). Pass exactly one of `body_text` or `body_storage`. \" +\n \"If `version_number` is omitted, the tool auto-fetches the current version and sends current+1 \" +\n \"(Confluence requires strict +1 increments; gaps cause 409). If `title` is omitted, the existing \" +\n \"title is preserved. Avoid back-to-back updates within ~1 second — Confluence may return 409 even \" +\n \"with the correct version. Disable to make the agent read-only on pages.\",\n schema: z.object({\n page_id: z.string(),\n title: z.string().optional().describe(\"New title; omit to keep existing.\"),\n body_text: z.string().optional(),\n body_storage: z.string().optional(),\n version_number: z.number().optional().describe(\n \"Explicit version (must equal currentVersion+1). Omit to auto-fetch and increment.\",\n ),\n version_message: z.string().optional().describe(\"Optional change comment shown in version history.\"),\n }),\n },\n);\n\nexport const confluenceAddCommentTool = tool(\n async ({ page_id, body_text, body_storage, parent_comment_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n const payload: Record<string, unknown> = {\n pageId: page_id,\n body: { representation: body.representation, value: body.value },\n };\n if (parent_comment_id) payload.parentCommentId = parent_comment_id;\n const data = await atlassianFetch(auth, `/wiki/api/v2/footer-comments`, {\n method: \"POST\",\n body: JSON.stringify(payload),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n comment_id: data.id,\n page_id,\n parent_comment_id: data.parentCommentId ?? null,\n });\n },\n {\n name: \"confluence_add_comment\",\n description:\n \"Add a footer comment to a Confluence page (v2). Pass exactly one of `body_text` or \" +\n \"`body_storage`. Pass `parent_comment_id` (from confluence_get_comments) to reply in a thread.\",\n schema: z.object({\n page_id: z.string(),\n body_text: z.string().optional(),\n body_storage: z.string().optional(),\n parent_comment_id: z.string().optional().describe(\"To reply to an existing comment.\"),\n }),\n },\n);\n\nexport const confluenceMovePageTool = tool(\n async ({ page_id, position, target_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/move/${encodeURIComponent(position)}/${encodeURIComponent(target_id)}`,\n { method: \"PUT\" },\n ) as { error?: string } | string | Record<string, unknown>;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, page_id, position, target_id });\n },\n {\n name: \"confluence_move_page\",\n description:\n \"Reorder/reparent a Confluence page (v2). `position`: 'before' or 'after' to place as a sibling \" +\n \"of `target_id`; 'append' to make it a child of `target_id`. Non-destructive.\",\n schema: z.object({\n page_id: z.string(),\n position: z.enum([\"before\", \"after\", \"append\"]),\n target_id: z.string().describe(\"Sibling (for before/after) or new parent (for append).\"),\n }),\n },\n);\n\nexport const confluenceUploadAttachmentTool = tool(\n async ({ page_id, filename, content_base64, content_text, comment, minor_edit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!content_base64 && !content_text) {\n return JSON.stringify({ error: \"pass either content_base64 (binary) or content_text (UTF-8)\" });\n }\n const buf = content_base64\n ? Buffer.from(content_base64, \"base64\")\n : Buffer.from(content_text!, \"utf8\");\n\n // v1 fallback: v2 Attachment group is read-only as of 2026 (CONFCLOUD-77196).\n // Same multipart shape as jiraUploadAttachmentTool — X-Atlassian-Token: no-check\n // bypasses CSRF; do NOT set Content-Type (fetch fills in the multipart boundary).\n const form = new FormData();\n form.append(\"file\", new Blob([buf]), filename);\n if (typeof comment === \"string\") form.append(\"comment\", comment);\n if (minor_edit) form.append(\"minorEdit\", \"true\");\n\n const url = `${auth.url}/wiki/rest/api/content/${encodeURIComponent(page_id)}/child/attachment`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: authHeader(auth),\n Accept: \"application/json\",\n \"X-Atlassian-Token\": \"no-check\",\n },\n body: form,\n });\n const text = await res.text();\n if (!res.ok) return JSON.stringify({ error: `Atlassian ${res.status}: ${text.slice(0, 500)}` });\n const parsed = parseJsonSafe<{\n results?: Array<{ id: string; title: string; metadata?: { mediaType?: string }; extensions?: { fileSize?: number } }>;\n }>(text, {});\n return JSON.stringify({\n ok: true,\n page_id,\n attachments: (parsed.results ?? []).map((a) => ({\n id: a.id,\n title: a.title,\n media_type: a.metadata?.mediaType ?? null,\n file_size: a.extensions?.fileSize ?? null,\n })),\n });\n },\n {\n name: \"confluence_upload_attachment\",\n description:\n \"Attach a file to a Confluence page. Pass content_base64 for binary or content_text for plain \" +\n \"UTF-8. Uses the v1 multipart endpoint (v2 has no attachment-create endpoint as of 2026). \" +\n \"Disable to make the agent unable to add attachments.\",\n schema: z.object({\n page_id: z.string(),\n filename: z.string().describe(\"Filename shown in Confluence (include the extension).\"),\n content_base64: z.string().optional().describe(\"Base64-encoded file contents (use for binary).\"),\n content_text: z.string().optional().describe(\"Raw UTF-8 text contents (use for logs/CSVs/JSON).\"),\n comment: z.string().optional().describe(\"Version comment shown in the attachment history.\"),\n minor_edit: z.boolean().optional().describe(\"If true, doesn't notify watchers.\"),\n }),\n },\n);\n\nexport const confluenceAddLabelTool = tool(\n async ({ page_id, labels }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!labels.length) return JSON.stringify({ error: \"labels is empty\" });\n // v1 fallback: v2 Label group is read-only as of 2026 (CONFCLOUD-76866).\n const payload = labels.map((name) => ({ prefix: \"global\", name }));\n const data = await atlassianFetch(\n auth,\n `/wiki/rest/api/content/${encodeURIComponent(page_id)}/label`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { results?: Array<{ name?: string; prefix?: string }>; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n page_id,\n added: labels,\n total_labels: (data.results ?? []).map((r) => r.name).filter(Boolean),\n });\n },\n {\n name: \"confluence_add_label\",\n description:\n \"Add one or more labels to a Confluence page (additive — does not replace existing labels). \" +\n \"Uses the v1 endpoint (v2 only reads labels as of 2026).\",\n schema: z.object({\n page_id: z.string(),\n labels: z.array(z.string()).describe(\"Label names to add (e.g. ['runbook', 'on-call']).\"),\n }),\n },\n);\n\n// ── Confluence v2 gap-fillers (ADR-0035) ────────────────────────────────────\n//\n// v2 audit on 2026-05-28 confirmed:\n// - DELETE /pages/{id} exists (with optional purge=true).\n// - PUT/DELETE /footer-comments/{id} and /inline-comments/{id} exist.\n// - DELETE /attachments/{id} exists (with optional purge=true).\n// - Label group is STILL read-only (CONFCLOUD-76866); confluence_remove_label\n// uses the v1 fallback `DELETE /content/{id}/label?name=...`.\n\nexport const confluenceDeletePageTool = tool(\n async ({ page_id, purge, confirm }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (purge && confirm !== page_id) {\n return JSON.stringify({\n error:\n `Refusing to permanently delete page ${page_id}: purge=true requires confirm to equal page_id. ` +\n `A purged page cannot be restored from trash. Drop purge if you only want to soft-delete.`,\n });\n }\n const qs = purge ? `?purge=true` : \"\";\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}${qs}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_page_id: page_id, purged: !!purge });\n },\n {\n name: \"confluence_delete_page\",\n description:\n \"Delete a Confluence page (v2). Default soft-deletes (page goes to trash, restorable). \" +\n \"Pass purge=true for permanent deletion, which **also requires `confirm` to equal page_id** \" +\n \"as a guardrail. Disable to make the agent unable to delete pages.\",\n schema: z.object({\n page_id: z.string(),\n purge: z.boolean().optional().describe(\"If true, permanently delete (skip trash). Requires confirm=page_id.\"),\n confirm: z.string().optional().describe(\"Required when purge=true; must equal page_id.\"),\n }),\n },\n);\n\nconst COMMENT_KIND_TO_PATH: Record<string, string> = {\n footer: \"footer-comments\",\n inline: \"inline-comments\",\n};\n\nexport const confluenceUpdateCommentTool = tool(\n async ({ comment_id, kind, body_text, body_storage, version_number, version_message }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const segment = COMMENT_KIND_TO_PATH[kind];\n if (!segment) {\n return JSON.stringify({ error: `unknown kind \"${kind}\". Expected 'footer' or 'inline'.` });\n }\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n\n let nextVersion = version_number;\n if (nextVersion === undefined) {\n // PUT requires version.number = current + 1; auto-fetch when not passed.\n const current = await atlassianFetch(\n auth,\n `/wiki/api/v2/${segment}/${encodeURIComponent(comment_id)}`,\n ) as { version?: { number?: number }; error?: string };\n if (current.error) return JSON.stringify(current);\n const cur = current.version?.number;\n if (typeof cur !== \"number\") return JSON.stringify({ error: \"could not read current comment version\" });\n nextVersion = cur + 1;\n }\n\n const payload: Record<string, unknown> = {\n version: { number: nextVersion, ...(version_message ? { message: version_message } : {}) },\n body: { representation: body.representation, value: body.value },\n };\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/${segment}/${encodeURIComponent(comment_id)}`,\n { method: \"PUT\", body: JSON.stringify(payload) },\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n comment_id,\n kind,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? nextVersion,\n });\n },\n {\n name: \"confluence_update_comment\",\n description:\n \"Edit an existing Confluence comment (v2). Pass `kind: 'footer' | 'inline'` to route to the \" +\n \"correct endpoint. Same `body_text` xor `body_storage` pattern as confluence_add_comment. If \" +\n \"version_number is omitted, the tool auto-fetches the current version and sends current+1 \" +\n \"(Confluence requires strict +1 increments).\",\n schema: z.object({\n comment_id: z.string(),\n kind: z.enum([\"footer\", \"inline\"]),\n body_text: z.string().optional(),\n body_storage: z.string().optional(),\n version_number: z.number().optional().describe(\"Explicit version (must be current+1). Omit to auto-fetch.\"),\n version_message: z.string().optional(),\n }),\n },\n);\n\nexport const confluenceDeleteCommentTool = tool(\n async ({ comment_id, kind }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const segment = COMMENT_KIND_TO_PATH[kind];\n if (!segment) {\n return JSON.stringify({ error: `unknown kind \"${kind}\". Expected 'footer' or 'inline'.` });\n }\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/${segment}/${encodeURIComponent(comment_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_comment_id: comment_id, kind });\n },\n {\n name: \"confluence_delete_comment\",\n description:\n \"Permanently delete a Confluence comment (v2). Pass `kind: 'footer' | 'inline'`. **Destructive — \" +\n \"no undo.** Disable to make the agent unable to delete comments.\",\n schema: z.object({\n comment_id: z.string(),\n kind: z.enum([\"footer\", \"inline\"]),\n }),\n },\n);\n\nexport const confluenceRemoveLabelTool = tool(\n async ({ page_id, label }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // v1 fallback — v2 Label group is read-only as of 2026-05-28 (CONFCLOUD-76866).\n // The v1 endpoint accepts the label name as a query param; the prefix\n // defaults to \"global\" which is what confluence_add_label uses.\n const data = await atlassianFetch(\n auth,\n `/wiki/rest/api/content/${encodeURIComponent(page_id)}/label?name=${encodeURIComponent(label)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, page_id, removed_label: label });\n },\n {\n name: \"confluence_remove_label\",\n description:\n \"Remove a single label from a Confluence page. Uses the v1 endpoint (v2 Label group is still \" +\n \"read-only as of 2026). Counterpart to confluence_add_label.\",\n schema: z.object({\n page_id: z.string(),\n label: z.string().describe(\"Label name to remove (no prefix; we always use 'global')\"),\n }),\n },\n);\n\nexport const confluenceDeleteAttachmentTool = tool(\n async ({ attachment_id, purge, confirm }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (purge && confirm !== attachment_id) {\n return JSON.stringify({\n error:\n `Refusing to permanently delete attachment ${attachment_id}: purge=true requires confirm to equal attachment_id. ` +\n `A purged attachment cannot be restored.`,\n });\n }\n const qs = purge ? `?purge=true` : \"\";\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/attachments/${encodeURIComponent(attachment_id)}${qs}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_attachment_id: attachment_id, purged: !!purge });\n },\n {\n name: \"confluence_delete_attachment\",\n description:\n \"Delete a Confluence attachment by id (v2). Default soft-deletes (trash, restorable). Pass \" +\n \"purge=true for permanent deletion, which **also requires `confirm` to equal attachment_id** \" +\n \"as a guardrail.\",\n schema: z.object({\n attachment_id: z.string(),\n purge: z.boolean().optional(),\n confirm: z.string().optional().describe(\"Required when purge=true; must equal attachment_id.\"),\n }),\n },\n);\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\n// Convert plain text → Confluence storage-format XHTML. Splits on blank lines\n// for paragraphs and uses <br/> for single newlines. Escapes &, <, > because\n// Confluence storage rejects unescaped ampersands and stray angle brackets.\n// Pure — exported for unit testing.\nexport function confluenceTextToStorage(text: string): string {\n if (text.length === 0) return \"<p></p>\";\n const escape = (s: string) =>\n s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n return text\n .split(/\\n{2,}/)\n .map((para) => `<p>${para.split(\"\\n\").map(escape).join(\"<br/>\")}</p>`)\n .join(\"\");\n}\n\n// Extract the opaque cursor query param from a Confluence v2 `_links.next` URL.\n// v2 cursors are not safe to construct — Atlassian explicitly says \"always parse\n// the next link, never build it\". Pure — exported for unit testing.\nexport function parseV2NextCursor(linksNext: string | undefined): string | null {\n if (!linksNext) return null;\n const m = linksNext.match(/[?&]cursor=([^&]+)/);\n return m ? decodeURIComponent(m[1]) : null;\n}\n\n// Body input dispatcher used by create_page / update_page / add_comment.\n// Callers pass body_text XOR body_storage; this resolves to the wire format\n// or a structured error for the LLM. body_storage is rejected if it contains\n// <script>/<style> — Confluence storage rejects those with opaque 400s, so\n// catch it here with a useful message.\nfunction resolveBody(input: { body_text?: string; body_storage?: string }):\n | { value: string; representation: \"storage\" }\n | { error: string }\n{\n const hasText = typeof input.body_text === \"string\";\n const hasStorage = typeof input.body_storage === \"string\";\n if (hasText && hasStorage) {\n return { error: \"pass exactly one of body_text or body_storage, not both\" };\n }\n if (!hasText && !hasStorage) {\n return { error: \"pass exactly one of body_text or body_storage\" };\n }\n if (hasStorage) {\n const s = input.body_storage!;\n if (/<\\s*(script|style)[\\s>]/i.test(s)) {\n return { error: \"body_storage rejected: <script>/<style> tags are not allowed by Confluence storage format\" };\n }\n return { value: s, representation: \"storage\" };\n }\n return { value: confluenceTextToStorage(input.body_text!), representation: \"storage\" };\n}\n\n// Per-site cache of space key → numeric space id. v2 page endpoints take\n// spaceId, but humans (and the LLM) think in space keys. 1h TTL mirrors\n// loadJiraFields below.\nconst SPACE_ID_CACHE_TTL_MS = 60 * 60 * 1000;\nconst spaceIdCache = new Map<string, { id: string; loaded: number }>();\n\nasync function resolveSpaceId(\n auth: AtlassianAuth,\n spaceKey: string,\n): Promise<string | { error: string }> {\n const cacheKey = `${auth.url}|${spaceKey}`;\n const cached = spaceIdCache.get(cacheKey);\n if (cached && Date.now() - cached.loaded < SPACE_ID_CACHE_TTL_MS) return cached.id;\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/spaces?keys=${encodeURIComponent(spaceKey)}&limit=1`,\n ) as { results?: Array<{ id: string; key: string }>; error?: string };\n if (\"error\" in data && data.error) return { error: data.error };\n const hit = (data.results ?? []).find((s) => s.key === spaceKey) ?? data.results?.[0];\n if (!hit?.id) return { error: `space key \"${spaceKey}\" not found` };\n spaceIdCache.set(cacheKey, { id: hit.id, loaded: Date.now() });\n return hit.id;\n}\n\n// Per-site cache of /rest/api/3/field. Custom field IDs are stable per site,\n// but display names can be edited; 1h TTL keeps us fresh without thrashing.\nexport interface JiraFieldDef { id: string; name: string; custom: boolean }\nconst FIELD_CACHE_TTL_MS = 60 * 60 * 1000;\nconst fieldCache = new Map<string, { fields: JiraFieldDef[]; loaded: number }>();\n\nasync function loadJiraFields(auth: AtlassianAuth): Promise<JiraFieldDef[] | { error: string }> {\n const cached = fieldCache.get(auth.url);\n if (cached && Date.now() - cached.loaded < FIELD_CACHE_TTL_MS) return cached.fields;\n const data = await atlassianFetch(auth, `/rest/api/3/field`) as\n | Array<{ id: string; name: string; custom: boolean }>\n | { error?: string };\n if (!Array.isArray(data)) return data as { error: string };\n const fields = data.map((f) => ({ id: f.id, name: f.name, custom: f.custom }));\n fieldCache.set(auth.url, { fields, loaded: Date.now() });\n return fields;\n}\n\n// Pure helper — exported for unit testing. Given a list of caller inputs and\n// the site's field definitions, partition into resolved (matched by id or\n// case-insensitive display name) and unresolved.\nexport function resolveCustomFieldNames(\n inputs: string[],\n fields: JiraFieldDef[],\n): { resolved: Array<{ input: string; id: string; name: string }>; unresolved: string[] } {\n const byId = new Map<string, JiraFieldDef>();\n const byName = new Map<string, JiraFieldDef>();\n for (const f of fields) {\n byId.set(f.id, f);\n byName.set(f.name.toLowerCase(), f);\n }\n const resolved: Array<{ input: string; id: string; name: string }> = [];\n const unresolved: string[] = [];\n for (const input of inputs) {\n const trimmed = input.trim();\n const hit = byId.get(trimmed) ?? byName.get(trimmed.toLowerCase());\n if (hit) resolved.push({ input, id: hit.id, name: hit.name });\n else unresolved.push(input);\n }\n return { resolved, unresolved };\n}\n\n// Coerce a Jira field value (which can be string, number, ADF doc, option\n// object, user object, array of those) into something an LLM can read. When\n// Jira returns a renderedFields HTML version, prefer that — it's the author's\n// formatting, flattened.\nexport function extractFieldValue(raw: unknown, renderedHTML: unknown): unknown {\n if (typeof renderedHTML === \"string\" && renderedHTML.length > 0) {\n return stripHtml(renderedHTML);\n }\n if (raw == null) return null;\n if (typeof raw === \"string\" || typeof raw === \"number\" || typeof raw === \"boolean\") return raw;\n if (Array.isArray(raw)) return raw.map(coerceItem);\n if (typeof raw === \"object\") {\n const obj = raw as Record<string, unknown>;\n if (obj.type === \"doc\" && Array.isArray(obj.content)) return simplifyADF(obj);\n if (typeof obj.value === \"string\") return obj.value;\n if (typeof obj.displayName === \"string\") return obj.displayName;\n if (typeof obj.name === \"string\") return obj.name;\n return obj;\n }\n return raw;\n}\n\nfunction coerceItem(item: unknown): unknown {\n if (!item || typeof item !== \"object\") return item;\n const obj = item as Record<string, unknown>;\n if (typeof obj.value === \"string\") return obj.value;\n if (typeof obj.name === \"string\") return obj.name;\n if (typeof obj.displayName === \"string\") return obj.displayName;\n return obj;\n}\n\nfunction stripHtml(html: string): string {\n return html\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/p>/gi, \"\\n\\n\")\n .replace(/<\\/li>/gi, \"\\n\")\n .replace(/<li[^>]*>/gi, \"• \")\n .replace(/<[^>]+>/g, \"\")\n .replace(/&nbsp;/g, \" \")\n .replace(/&amp;/g, \"&\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&#39;/g, \"'\")\n .replace(/&quot;/g, '\"')\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\n// Atlassian's REST API takes ADF (Atlassian Document Format), not plain text.\n// This wraps a plain string so the agent doesn't have to know the schema.\nfunction textToADF(text: string): unknown {\n type ADFNode = { type: string; text?: string };\n return {\n type: \"doc\",\n version: 1,\n content: text.split(/\\n\\n+/).map((para) => ({\n type: \"paragraph\",\n content: para.split(\"\\n\").flatMap<ADFNode>((line, i) =>\n i === 0\n ? [{ type: \"text\", text: line }]\n : [{ type: \"hardBreak\" }, { type: \"text\", text: line }],\n ),\n })),\n };\n}\n\n// Best-effort flatten of an ADF document back to plain text. Doesn't preserve\n// formatting but gives the agent something readable to summarize.\nfunction simplifyADF(adf: unknown): string {\n if (!adf || typeof adf !== \"object\") return typeof adf === \"string\" ? adf : \"\";\n const out: string[] = [];\n walk(adf);\n return out.join(\"\").trim();\n\n function walk(node: unknown): void {\n if (!node || typeof node !== \"object\") return;\n const n = node as Record<string, unknown>;\n if (n.type === \"text\" && typeof n.text === \"string\") out.push(n.text);\n if (n.type === \"hardBreak\") out.push(\"\\n\");\n if (n.type === \"paragraph\") { walkChildren(n.content); out.push(\"\\n\\n\"); }\n else if (n.type === \"bulletList\" || n.type === \"orderedList\") walkChildren(n.content);\n else if (n.type === \"listItem\") { out.push(\"• \"); walkChildren(n.content); }\n else walkChildren(n.content);\n }\n function walkChildren(children: unknown): void {\n if (Array.isArray(children)) for (const c of children) walk(c);\n }\n}\n\nregisterTools(\"Atlassian\", [\n jiraSearchTool, jiraGetIssueTool, jiraFindUserTool,\n jiraCreateIssueTool, jiraCreateIssuesBulkTool, jiraUpdateIssueTool,\n jiraAddCommentTool, jiraTransitionsTool,\n jiraLinkIssuesTool, jiraAddRemoteLinkTool, jiraDeleteLinkTool,\n jiraUploadAttachmentTool, jiraDeleteIssueTool,\n // Agile (ADR-0035): boards, sprints, backlog, rank\n jiraListBoardsTool, jiraGetBoardTool,\n jiraListSprintsTool, jiraGetSprintTool,\n jiraCreateSprintTool, jiraUpdateSprintTool, jiraDeleteSprintTool,\n jiraMoveIssuesToSprintTool, jiraMoveIssuesToBacklogTool,\n jiraRankIssuesTool,\n // Issue extras (ADR-0035): comments CRUD, worklogs, attachments, changelog\n jiraGetCommentsTool, jiraUpdateCommentTool, jiraDeleteCommentTool,\n jiraGetAttachmentContentTool, jiraDeleteAttachmentTool,\n jiraAddWorklogTool, jiraListWorklogsTool, jiraGetChangelogTool,\n // Project metadata (ADR-0035): projects, versions, components, generic enums\n jiraListProjectsTool, jiraGetProjectTool,\n jiraListVersionsTool, jiraCreateVersionTool, jiraUpdateVersionTool,\n jiraListComponentsTool, jiraCreateComponentTool,\n jiraListMetaTool,\n confluenceSearchTool, confluenceGetPageTool,\n confluenceGetPageByTitleTool, confluenceGetPageChildrenTool,\n confluenceGetPageAncestorsTool, confluenceListSpacesTool,\n confluenceGetCommentsTool, confluenceListAttachmentsTool,\n confluenceGetLabelsTool, confluenceGetAttachmentContentTool,\n confluenceCreatePageTool, confluenceUpdatePageTool,\n confluenceAddCommentTool, confluenceMovePageTool,\n confluenceUploadAttachmentTool, confluenceAddLabelTool,\n // Confluence gap-fillers (ADR-0035)\n confluenceDeletePageTool, confluenceUpdateCommentTool, confluenceDeleteCommentTool,\n confluenceRemoveLabelTool, confluenceDeleteAttachmentTool,\n]);\n","// Shared reaction-discriminator helpers for the watcher (ADR-0031) and\n// scheduled-task (ADR-0032) stores. Both schemas use the same\n// `reaction_kind` / `reaction_script` / `reaction_script_args` triple, so\n// validation lives here and is imported by both.\n\nimport { isReactionScript, REACTION_SCRIPT_PREFIX } from \"@/lib/triggers/scripts\";\n\nexport type ReactionKind = \"agent_prompt\" | \"script\";\n\nconst MAX_REACTION_PROMPT_CHARS = 4000;\nconst MAX_REACTION_SCRIPT_ARGS_CHARS = 4000;\n\n/**\n * Normalise a reaction-prompt input into the value we store. Treats\n * undefined / null / whitespace-only as \"no override\" → NULL. Throws when\n * the prompt exceeds 4000 characters (the firing-prompt budget).\n */\nexport function normaliseReactionPrompt(input: unknown): string | null {\n if (input === undefined || input === null) return null;\n if (typeof input !== \"string\") {\n throw new Error(\"reaction_prompt must be a string\");\n }\n const trimmed = input.trim();\n if (!trimmed) return null;\n if (trimmed.length > MAX_REACTION_PROMPT_CHARS) {\n throw new Error(\n `reaction_prompt must be <= ${MAX_REACTION_PROMPT_CHARS} characters (got ${trimmed.length})`,\n );\n }\n return trimmed;\n}\n\n/**\n * Validate a reaction-script name: must start with the `reaction.` prefix\n * AND be registered in the in-process script registry. Validated at write\n * time so a bad name is rejected by the agent tool / HTTP route, not by\n * the scheduler tick.\n */\nexport function validateReactionScript(name: unknown): string {\n if (typeof name !== \"string\" || !name.trim()) {\n throw new Error(\"reaction_script must be a non-empty string\");\n }\n const trimmed = name.trim();\n if (!trimmed.startsWith(REACTION_SCRIPT_PREFIX)) {\n throw new Error(\n `reaction_script must begin with \"${REACTION_SCRIPT_PREFIX}\" — got \"${trimmed}\"`,\n );\n }\n if (!isReactionScript(trimmed)) {\n throw new Error(`reaction_script \"${trimmed}\" is not registered`);\n }\n return trimmed;\n}\n\n/**\n * Normalise reaction-script args into a JSON-encoded string suitable for\n * the DB column. undefined / null → NULL. Anything else must be a plain\n * object that JSON-encodes to <= 4000 chars.\n */\nexport function normaliseReactionScriptArgs(input: unknown): string | null {\n if (input === undefined || input === null) return null;\n if (typeof input !== \"object\" || Array.isArray(input)) {\n throw new Error(\"reaction_script_args must be a JSON object\");\n }\n const json = JSON.stringify(input);\n if (json.length > MAX_REACTION_SCRIPT_ARGS_CHARS) {\n throw new Error(\n `reaction_script_args JSON must be <= ${MAX_REACTION_SCRIPT_ARGS_CHARS} chars (got ${json.length})`,\n );\n }\n return json;\n}\n\nexport interface ResolvedReaction {\n kind: ReactionKind;\n prompt: string | null;\n script: string | null;\n scriptArgs: string | null;\n}\n\n/**\n * Apply the discriminated-union rules for the reaction columns:\n * kind='script' → prompt forced NULL; script + scriptArgs validated.\n * kind='agent_prompt' → script + scriptArgs forced NULL; prompt normalised.\n * Centralised so create/update paths in both stores share one source of\n * truth for the union semantics.\n */\nexport function resolveReaction(input: {\n reaction_kind?: ReactionKind;\n reaction_prompt?: string | null;\n reaction_script?: string | null;\n reaction_script_args?: Record<string, unknown> | null;\n}): ResolvedReaction {\n const kind: ReactionKind = input.reaction_kind ?? \"agent_prompt\";\n if (kind === \"script\") {\n if (!input.reaction_script) {\n throw new Error(\"reaction_kind='script' requires reaction_script\");\n }\n return {\n kind,\n prompt: null,\n script: validateReactionScript(input.reaction_script),\n scriptArgs: normaliseReactionScriptArgs(input.reaction_script_args ?? null),\n };\n }\n return {\n kind,\n prompt: normaliseReactionPrompt(input.reaction_prompt),\n script: null,\n scriptArgs: null,\n };\n}\n","// Plain-text chunker for document RAG (ADR-0024).\n//\n// Strategy:\n// 1. Split on blank-line paragraph boundaries.\n// 2. Greedily pack paragraphs into chunks up to ~MAX_CHARS.\n// 3. Overlap: prepend the trailing portion of the previous chunk to each\n// new chunk so cross-chunk context survives splits (helps recall when\n// a question spans a paragraph boundary).\n//\n// Char count is used as a token proxy — 1 token ≈ 4 chars for English.\n// MAX_CHARS = 3200 ≈ 800 tokens, well under any embedding-model limit.\n\nconst MAX_CHARS = 3200;\nconst OVERLAP_CHARS = 400;\n\nexport interface Chunk {\n text: string;\n start_offset: number; // byte offset (utf-8) into original text\n end_offset: number;\n}\n\nexport function chunkText(text: string): Chunk[] {\n if (!text || text.length === 0) return [];\n\n // Split on one-or-more blank lines. Keep paragraphs with their separator\n // so offsets stay accurate.\n const paragraphs: { text: string; start: number; end: number }[] = [];\n let cursor = 0;\n const re = /\\n\\s*\\n/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const start = cursor;\n const end = m.index;\n paragraphs.push({ text: text.slice(start, end), start, end });\n cursor = re.lastIndex;\n }\n if (cursor < text.length) {\n paragraphs.push({ text: text.slice(cursor), start: cursor, end: text.length });\n }\n\n const chunks: Chunk[] = [];\n let buf: { text: string; start: number; end: number } | null = null;\n\n for (const p of paragraphs) {\n if (!buf) {\n buf = { text: p.text, start: p.start, end: p.end };\n continue;\n }\n if (buf.text.length + 2 + p.text.length <= MAX_CHARS) {\n buf.text = `${buf.text}\\n\\n${p.text}`;\n buf.end = p.end;\n } else {\n chunks.push({ text: buf.text, start_offset: buf.start, end_offset: buf.end });\n // Overlap: take the tail of the previous chunk.\n const tail = buf.text.slice(Math.max(0, buf.text.length - OVERLAP_CHARS));\n buf = {\n text: `${tail}\\n\\n${p.text}`,\n // Anchor the new chunk's start_offset at the paragraph that's\n // logically new — the overlap tail is prepended for context only.\n start: p.start,\n end: p.end,\n };\n }\n }\n if (buf) {\n chunks.push({ text: buf.text, start_offset: buf.start, end_offset: buf.end });\n }\n\n // If a single paragraph is bigger than MAX_CHARS, the above will emit it\n // as one over-sized chunk. Split it on character boundaries as a last\n // resort so we don't exceed the embedding model's input limit.\n const out: Chunk[] = [];\n for (const c of chunks) {\n if (c.text.length <= MAX_CHARS) {\n out.push(c);\n continue;\n }\n let pos = 0;\n while (pos < c.text.length) {\n const end = Math.min(pos + MAX_CHARS, c.text.length);\n out.push({\n text: c.text.slice(pos, end),\n start_offset: c.start_offset + pos,\n end_offset: c.start_offset + end,\n });\n pos = end - OVERLAP_CHARS;\n if (pos < 0) pos = 0;\n if (end === c.text.length) break;\n }\n }\n return out;\n}\n","// Filesystem walker + indexer for document RAG (ADR-0024).\n//\n// Walks each enabled document_source, identifies text files whose\n// mtime/size differs from the indexed copy, re-chunks + re-embeds them.\n// Files removed on disk are evicted (chunks + document row).\n//\n// Defaults are conservative on purpose: extension allowlist, size cap,\n// directory denylist for VCS / build output. Binary files are skipped via\n// a fast non-printable-byte heuristic on the first 4 KB.\n\nimport { randomUUID, createHash } from \"node:crypto\";\nimport { promises as fs } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\nimport { getDb } from \"@/lib/db\";\nimport { embedBestEffort } from \"@/lib/embeddings\";\nimport {\n listEnabledDocumentSources,\n markSourceScanned,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { chunkText } from \"./chunker\";\nimport { isRemoteKind, runRemoteSource, type RemoteIndexStats } from \"./remote\";\n\n// Conservative defaults; v1 is not configurable per source. ADR-0024\n// documents the rationale and the path to opening these up.\nconst ALLOWED_EXT = new Set([\n \".md\", \".markdown\", \".txt\", \".rst\", \".log\",\n \".json\", \".jsonc\", \".yaml\", \".yml\", \".toml\", \".ini\", \".cfg\", \".env\",\n \".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\",\n \".py\", \".rs\", \".go\", \".java\", \".kt\", \".scala\", \".swift\",\n \".c\", \".cpp\", \".cc\", \".h\", \".hpp\",\n \".cs\", \".rb\", \".php\", \".lua\", \".pl\", \".r\",\n \".sh\", \".bash\", \".zsh\", \".ps1\", \".bat\",\n \".html\", \".htm\", \".css\", \".scss\", \".sass\", \".vue\", \".svelte\",\n \".sql\", \".graphql\", \".proto\",\n \".csv\", \".tsv\",\n]);\nconst SKIP_DIRS = new Set([\n \"node_modules\", \".git\", \".hg\", \".svn\", \".next\", \".turbo\", \".cache\",\n \"dist\", \"build\", \"out\", \"target\", \".venv\", \"venv\", \"env\",\n \"__pycache__\", \".pytest_cache\", \".mypy_cache\",\n \".idea\", \".vscode\", \".vs\",\n \"coverage\", \".nyc_output\",\n]);\nconst MAX_FILE_BYTES = 2 * 1024 * 1024; // 2 MB — bigger files almost always\n // belong in proper RAG, not ad-hoc.\nconst MAX_FILES_PER_SOURCE = 5000;\n// Per-call cap so a freshly-added source with thousands of files doesn't\n// block the scheduler tick for minutes. Subsequent ticks pick up the rest.\nconst MAX_INDEX_PER_TICK_PER_SOURCE = 50;\n\nexport { ALLOWED_EXT, SKIP_DIRS, MAX_FILE_BYTES };\n\nexport function lowerExt(name: string): string {\n const i = name.lastIndexOf(\".\");\n return i < 0 ? \"\" : name.slice(i).toLowerCase();\n}\n\nexport function isLikelyBinary(buf: Buffer): boolean {\n const len = Math.min(buf.length, 4096);\n if (len === 0) return false;\n let suspicious = 0;\n for (let i = 0; i < len; i++) {\n const b = buf[i];\n // NUL byte = almost certainly binary.\n if (b === 0) return true;\n // Outside printable ASCII + common whitespace and not high-bit UTF-8.\n if (b < 0x09 || (b > 0x0d && b < 0x20)) suspicious++;\n }\n return suspicious / len > 0.05;\n}\n\nexport interface FileEntry {\n abs: string;\n rel: string;\n mtime_ms: number;\n size: number;\n}\n\nasync function walk(root: string): Promise<FileEntry[]> {\n const out: FileEntry[] = [];\n // Cloud-synced filesystems (OneDrive's macOS file provider in\n // particular) can re-emit the same entry from readdir during sync\n // transitions, sometimes with a different Unicode normalization\n // (NFC vs NFD). Without dedupe, the second visit would attempt a\n // second INSERT for the same (source_id, path) and trip the UNIQUE\n // constraint on `documents`.\n const seen = new Set<string>();\n async function visit(dir: string): Promise<void> {\n if (out.length >= MAX_FILES_PER_SOURCE) return;\n let entries: import(\"node:fs\").Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries) {\n if (out.length >= MAX_FILES_PER_SOURCE) return;\n if (e.name.startsWith(\".\")) {\n // Hide dot-dirs by default. Users who want them indexed should\n // pick a more specific subdirectory as the source.\n if (e.isDirectory()) continue;\n // Keep dot-files like .env, .gitignore as text candidates.\n }\n const abs = join(dir, e.name);\n if (e.isDirectory()) {\n if (SKIP_DIRS.has(e.name)) continue;\n if (seen.has(abs)) continue;\n seen.add(abs);\n await visit(abs);\n } else if (e.isFile()) {\n const ext = lowerExt(e.name);\n if (!ALLOWED_EXT.has(ext)) continue;\n if (seen.has(abs)) continue;\n seen.add(abs);\n let st;\n try { st = await fs.stat(abs); } catch { continue; }\n if (st.size > MAX_FILE_BYTES) continue;\n out.push({\n abs,\n rel: relative(root, abs).split(sep).join(\"/\"),\n mtime_ms: Math.floor(st.mtimeMs),\n size: st.size,\n });\n }\n }\n }\n await visit(root);\n return out;\n}\n\ninterface IndexedDocRow {\n id: string;\n path: string;\n mtime_ms: number;\n size_bytes: number;\n content_hash: string;\n}\n\nfunction listIndexedDocs(sourceId: string): Map<string, IndexedDocRow> {\n const rows = getDb()\n .prepare(\"SELECT id, path, mtime_ms, size_bytes, content_hash FROM documents WHERE source_id=?\")\n .all(sourceId) as unknown as IndexedDocRow[];\n const map = new Map<string, IndexedDocRow>();\n for (const r of rows) map.set(r.path, r);\n return map;\n}\n\ninterface UnembeddedChunkRow {\n id: string;\n text: string;\n}\n\nfunction listUnembeddedChunks(documentId: string): UnembeddedChunkRow[] {\n return getDb()\n .prepare(\n `SELECT id, text\n FROM document_chunks\n WHERE document_id=? AND embedding IS NULL\n ORDER BY chunk_index ASC`,\n )\n .all(documentId) as unknown as UnembeddedChunkRow[];\n}\n\nasync function backfillDocumentEmbeddings(documentId: string): Promise<{ missing: number; embedded: number; embedError: string | null }> {\n const rows = listUnembeddedChunks(documentId);\n if (rows.length === 0) return { missing: 0, embedded: 0, embedError: null };\n\n const { vectors, error } = await embedBestEffort(rows.map((r) => r.text));\n const updateEmb = getDb().prepare(\"UPDATE document_chunks SET embedding=? WHERE id=?\");\n let embedded = 0;\n for (let i = 0; i < rows.length; i++) {\n const v = vectors[i];\n if (v == null) continue;\n updateEmb.run(JSON.stringify(v), rows[i].id);\n embedded++;\n }\n return { missing: rows.length, embedded, embedError: error };\n}\n\nexport async function readTextFile(abs: string): Promise<string | null> {\n let buf: Buffer;\n try { buf = await fs.readFile(abs); } catch { return null; }\n if (isLikelyBinary(buf)) return null;\n return buf.toString(\"utf8\");\n}\n\nexport function hashContent(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\ninterface IndexStats {\n scanned: number;\n added: number;\n updated: number;\n removed: number;\n unchanged: number;\n errors: number;\n embed_failed?: number;\n embed_error?: string | null;\n}\n\nexport async function indexSource(\n source: DocumentSourceRow,\n opts?: { maxFiles?: number },\n): Promise<IndexStats> {\n const stats: IndexStats = { scanned: 0, added: 0, updated: 0, removed: 0, unchanged: 0, errors: 0 };\n const db = getDb();\n let lastError: string | null = null;\n let embedFailed = 0;\n let embedError: string | null = null;\n\n // Resolve real files on disk.\n const files = await walk(source.path);\n stats.scanned = files.length;\n\n const indexed = listIndexedDocs(source.id);\n const onDisk = new Set<string>(files.map((f) => f.abs));\n\n // Drop entries whose file is gone.\n for (const [path, row] of indexed.entries()) {\n if (!onDisk.has(path)) {\n db.prepare(\"DELETE FROM documents WHERE id=?\").run(row.id);\n stats.removed++;\n }\n }\n\n // Index new + changed files.\n const maxThisRun = opts?.maxFiles ?? MAX_INDEX_PER_TICK_PER_SOURCE;\n let processed = 0;\n for (const f of files) {\n if (processed >= maxThisRun) break;\n const existing = indexed.get(f.abs);\n if (existing && existing.mtime_ms === f.mtime_ms && existing.size_bytes === f.size) {\n // Root-cause fix: if a file was indexed while embeddings were\n // unavailable, unchanged files used to be skipped forever and never\n // backfilled. Try to embed any still-null chunks on unchanged docs.\n try {\n const r = await backfillDocumentEmbeddings(existing.id);\n if (r.missing > 0) {\n embedFailed += Math.max(r.missing - r.embedded, 0);\n if (r.embedError && !embedError) embedError = r.embedError;\n processed++;\n }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n stats.unchanged++;\n continue;\n }\n\n let text: string | null;\n try { text = await readTextFile(f.abs); } catch {\n stats.errors++;\n continue;\n }\n if (text === null) continue; // binary / unreadable — skip silently.\n\n const hash = hashContent(text);\n if (existing && existing.content_hash === hash) {\n // Mtime/size changed but content didn't — just touch the row.\n db.prepare(\"UPDATE documents SET mtime_ms=?, size_bytes=?, last_indexed_at=? WHERE id=?\")\n .run(f.mtime_ms, f.size, new Date().toISOString(), existing.id);\n try {\n const r = await backfillDocumentEmbeddings(existing.id);\n if (r.missing > 0) {\n embedFailed += Math.max(r.missing - r.embedded, 0);\n if (r.embedError && !embedError) embedError = r.embedError;\n processed++;\n }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n stats.unchanged++;\n continue;\n }\n\n try {\n const r = await upsertLocalDocument(source.id, f, text, hash, existing?.id);\n embedFailed += r.chunks - r.embedded;\n if (r.embedError && !embedError) embedError = r.embedError;\n processed++;\n if (existing) stats.updated++;\n else stats.added++;\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n }\n\n // Embed failures are not fetch failures — but if everything else\n // succeeded we still want them visible on the row, so the operator\n // doesn't have to grep server logs to discover that semantic search\n // is degraded for this source.\n const composite = lastError\n ? lastError\n : embedFailed > 0\n ? `${embedFailed} chunk${embedFailed === 1 ? \"\" : \"s\"} failed to embed${embedError ? \": \" + embedError : \"\"}`\n : null;\n if (embedFailed > 0) {\n stats.embed_failed = embedFailed;\n stats.embed_error = embedError;\n }\n markSourceScanned(source.id, composite);\n return stats;\n}\n\n/**\n * Upsert one local document row (and its chunks). Exported so\n * single-file watcher firings can reuse it without going through\n * a full source sweep.\n */\nexport async function upsertLocalDocument(\n sourceId: string,\n f: FileEntry,\n text: string,\n hash: string,\n existingId: string | undefined,\n): Promise<{ chunks: number; embedded: number; embedError: string | null }> {\n const db = getDb();\n const t = new Date().toISOString();\n const docId = existingId ?? randomUUID();\n\n // Two writers can race on (source_id, path): the full sweep in\n // indexSource() loads listIndexedDocs() once and iterates, while\n // fs-watch firings call reindexLocalFile() per file. If a watcher\n // event lands mid-sweep, both paths can see \"no existing row\" and\n // both try to INSERT, tripping UNIQUE(source_id, path)\n // (lib/db/migrations.ts). REPLACE INTO is unsafe: document_chunks\n // has ON DELETE CASCADE on documents.id, so REPLACE would nuke every\n // chunk on each call. Use ON CONFLICT DO NOTHING, and if we lost the\n // race, adopt the winner's id and overwrite via UPDATE so the latest\n // content still wins.\n let writeId = docId;\n if (existingId) {\n db.prepare(\n `UPDATE documents\n SET path=?, rel_path=?, mtime_ms=?, size_bytes=?, content_hash=?, last_indexed_at=?\n WHERE id=?`,\n ).run(f.abs, f.rel, f.mtime_ms, f.size, hash, t, existingId);\n db.prepare(\"DELETE FROM document_chunks WHERE document_id=?\").run(existingId);\n writeId = existingId;\n } else {\n const info = db.prepare(\n `INSERT INTO documents\n (id, source_id, path, rel_path, mtime_ms, size_bytes, content_hash, last_indexed_at, chunk_count)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)\n ON CONFLICT(source_id, path) DO NOTHING`,\n ).run(docId, sourceId, f.abs, f.rel, f.mtime_ms, f.size, hash, t);\n if (info.changes === 0) {\n const winner = db\n .prepare(\"SELECT id FROM documents WHERE source_id=? AND path=?\")\n .get(sourceId, f.abs) as { id: string } | undefined;\n if (winner) {\n db.prepare(\n `UPDATE documents\n SET rel_path=?, mtime_ms=?, size_bytes=?, content_hash=?, last_indexed_at=?\n WHERE id=?`,\n ).run(f.rel, f.mtime_ms, f.size, hash, t, winner.id);\n db.prepare(\"DELETE FROM document_chunks WHERE document_id=?\").run(winner.id);\n writeId = winner.id;\n }\n }\n }\n\n return chunkAndEmbedDocument(writeId, text, f.rel);\n}\n\n/**\n * Chunk a document's text, persist the chunks, and best-effort embed\n * them. Shared between the local sweep, single-file watcher firings,\n * and remote-source upserts. Returns counts so the caller can aggregate\n * embed failures up to the source row instead of swallowing them.\n */\nexport async function chunkAndEmbedDocument(\n documentId: string,\n text: string,\n _label: string,\n): Promise<{ chunks: number; embedded: number; embedError: string | null }> {\n const db = getDb();\n const chunks = chunkText(text);\n if (chunks.length === 0) {\n db.prepare(\"UPDATE documents SET chunk_count=0 WHERE id=?\").run(documentId);\n return { chunks: 0, embedded: 0, embedError: null };\n }\n\n // Insert chunks first without embeddings — recall falls back to\n // substring scan, so they're useful immediately. Then attempt to embed\n // in a single batch; persist whichever vectors came back.\n const insertChunk = db.prepare(\n `INSERT INTO document_chunks\n (id, document_id, chunk_index, text, start_offset, end_offset, embedding)\n VALUES (?, ?, ?, ?, ?, ?, NULL)`,\n );\n const chunkIds: string[] = [];\n for (let i = 0; i < chunks.length; i++) {\n const id = randomUUID();\n chunkIds.push(id);\n insertChunk.run(id, documentId, i, chunks[i].text, chunks[i].start_offset, chunks[i].end_offset);\n }\n db.prepare(\"UPDATE documents SET chunk_count=? WHERE id=?\").run(chunks.length, documentId);\n\n // embedBestEffort handles retry + halving fallback internally so a\n // single bad input or transient 429 doesn't drop the whole document.\n const { vectors, error } = await embedBestEffort(chunks.map((c) => c.text));\n const updateEmb = db.prepare(\"UPDATE document_chunks SET embedding=? WHERE id=?\");\n let embedded = 0;\n for (let i = 0; i < vectors.length; i++) {\n if (vectors[i] != null) {\n updateEmb.run(JSON.stringify(vectors[i]), chunkIds[i]);\n embedded++;\n }\n }\n return { chunks: chunks.length, embedded, embedError: error };\n}\n\nexport async function indexAllSources(opts?: { maxFilesPerSource?: number }): Promise<{\n source_id: string;\n path: string;\n stats: IndexStats | RemoteIndexStats;\n}[]> {\n const sources = listEnabledDocumentSources();\n const out: { source_id: string; path: string; stats: IndexStats | RemoteIndexStats }[] = [];\n for (const s of sources) {\n try {\n if (isRemoteKind(s.kind)) {\n // Delegate to the per-kind remote handler (ADR-0026). Remote\n // sources don't have an mtime stat — they have their own\n // incremental cursor stored in document_sources.last_cursor.\n const stats = await runRemoteSource(s);\n out.push({ source_id: s.id, path: s.path, stats });\n continue;\n }\n const stats = await indexSource(s, { maxFiles: opts?.maxFilesPerSource });\n out.push({ source_id: s.id, path: s.path, stats });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n markSourceScanned(s.id, msg);\n console.error(\"[documents] index failed for\", s.path, msg);\n }\n }\n return out;\n}\n","import type { TriggerHandler } from \"./types\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\n\n// Module-level registry. getOrCreateGlobal so HMR / repeated imports in\n// dev don't lose registrations across module re-evaluations.\ninterface RegistryState {\n handlers: Map<string, TriggerHandler>;\n}\nconst state = getOrCreateGlobal<RegistryState>(\"__jarela_trigger_registry\", () => ({\n handlers: new Map(),\n}));\n\nexport function registerTriggerHandler(handler: TriggerHandler): void {\n state.handlers.set(handler.kind, handler);\n}\n\nexport function getTriggerHandler(kind: string): TriggerHandler | undefined {\n return state.handlers.get(kind);\n}\n\nexport function listTriggerHandlers(): TriggerHandler[] {\n return Array.from(state.handlers.values());\n}\n\n// Test helper. Not exposed in the public surface — only the test file\n// reaches in to reset.\nexport function __resetTriggerRegistry(): void {\n state.handlers.clear();\n}\n","// Shared collector for agent stream consumers.\n//\n// Previously three near-identical drain loops lived in:\n// - app/api/v1/threads/[thread_id]/run/route.ts (HTTP run)\n// - lib/scheduler/index.ts (cron tasks)\n// - lib/bridges/dispatcher.ts (WhatsApp / bridges)\n//\n// They all read `prepared.stream`, accumulate `text_delta` into a single\n// assistant string, record `tool_call`/`tool_result` events, stop on\n// `done`/`error`, and surface the terminal state. This helper unifies that.\n\nimport type { StreamChunk } from \"@/lib/agents/base\";\nimport type { PersistedToolEvent } from \"@/lib/stores/threads\";\n\nexport interface CollectedRun {\n assistantContent: string;\n usedTools: string[];\n toolEvents: PersistedToolEvent[];\n terminal: \"done\" | \"error\";\n errorMessage?: string;\n}\n\nexport interface CollectStreamOptions {\n // Called for every chunk before it is interpreted. Use for live broadcast\n // (HTTP SSE, websocket, etc.). Throwing here aborts the run with terminal\n // = \"error\".\n onChunk?: (chunk: StreamChunk) => void;\n}\n\n/** Drain an async stream of `StreamChunk` into a single `CollectedRun`. */\nexport async function collectStream(\n stream: AsyncIterable<StreamChunk>,\n opts: CollectStreamOptions = {},\n): Promise<CollectedRun> {\n const result: CollectedRun = {\n assistantContent: \"\",\n usedTools: [],\n toolEvents: [],\n terminal: \"done\",\n };\n\n try {\n for await (const chunk of stream) {\n opts.onChunk?.(chunk);\n switch (chunk.type) {\n case \"text_delta\": {\n result.assistantContent += (chunk.data.delta as string) ?? \"\";\n break;\n }\n case \"tool_call\": {\n const d = chunk.data as { id?: string; name?: string; arguments?: unknown };\n if (d.name) result.usedTools.push(d.name);\n result.toolEvents.push({\n id: d.id ?? `call-${result.toolEvents.length}`,\n phase: \"call\",\n name: d.name ?? \"\",\n payload: d.arguments,\n });\n break;\n }\n case \"tool_result\": {\n const d = chunk.data as { id?: string; name?: string; result?: unknown };\n result.toolEvents.push({\n id: d.id ?? `result-${result.toolEvents.length}`,\n phase: \"result\",\n name: d.name ?? \"\",\n payload: d.result,\n });\n break;\n }\n case \"error\": {\n result.terminal = \"error\";\n const msg = (chunk.data as { message?: unknown })?.message;\n if (typeof msg === \"string\") result.errorMessage = msg;\n return result;\n }\n case \"done\": {\n return result;\n }\n // thinking_delta and unknown types are pass-through (already\n // forwarded to onChunk above).\n }\n }\n } catch (err) {\n result.terminal = \"error\";\n result.errorMessage = err instanceof Error ? err.message : String(err);\n }\n\n return result;\n}\n","import { getOrCreateAgentThread } from \"@/lib/stores/threads\";\nimport { getAgentConfig } from \"@/lib/stores/agent-configs\";\nimport { prepareThreadRun, persistAssistantMessage } from \"@/lib/agents/run-thread\";\nimport { collectStream } from \"@/lib/agents/stream-collector\";\nimport { getScript } from \"./scripts\";\nimport type {\n PromptFiring,\n ScriptFiring,\n TriggerFiring,\n TriggerOutcome,\n} from \"./types\";\n\n/**\n * Invoke an agent for one prompt firing. Extracted from the original\n * scheduler `runTask` so any handler that wants chat semantics goes\n * through the exact same run/persist/silent code path.\n *\n * The runner does NOT publish notifications — different trigger kinds\n * want different notification payloads, so that responsibility stays\n * with each handler's markFired().\n */\nexport async function runTriggerAgent(firing: PromptFiring): Promise<TriggerOutcome> {\n const agent = getAgentConfig(firing.agentId);\n if (!agent) {\n return {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: `Agent \"${firing.agentId}\" not found`,\n };\n }\n const thread = getOrCreateAgentThread(firing.agentId);\n const category = firing.category ?? firing.kind;\n\n // Silent mode: wrap the prompt with a \"reply only if material\" directive\n // AND a NO_REPLY sentinel so the post-run code can drop the assistant\n // turn entirely when nothing is worth surfacing. Visibility itself is\n // handled at the chat-panel layer via the category-filter toolbar.\n const effectivePrompt = firing.silent\n ? `${firing.prompt}\\n\\n[SILENT_TRIGGER] This prompt was triggered automatically. Reply with information only if there is something material the user needs to see right now. If nothing material to report, reply with exactly the single token NO_REPLY and nothing else.`\n : firing.prompt;\n\n try {\n const prepared = await prepareThreadRun(\n thread.thread_id,\n effectivePrompt,\n undefined,\n undefined,\n undefined,\n undefined,\n category,\n );\n const collected = await collectStream(prepared.stream);\n const replyText = collected.assistantContent.trim();\n const isNoReply = firing.silent === true && /^\\s*NO[_ ]?REPLY\\b/i.test(replyText);\n const skipAssistant = firing.silent === true && (isNoReply || replyText.length === 0);\n if (!skipAssistant) {\n persistAssistantMessage(\n thread.thread_id,\n collected.assistantContent,\n collected.usedTools,\n collected.toolEvents,\n category,\n );\n }\n return {\n status: skipAssistant ? \"skipped\" : \"done\",\n preview: skipAssistant\n ? \"\"\n : collected.assistantContent.replace(/\\s+/g, \" \").trim().slice(0, 120),\n threadId: thread.thread_id,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"error\",\n preview: \"\",\n threadId: thread.thread_id,\n error: msg,\n };\n }\n}\n\n/**\n * Run an in-process script for one script firing. No thread, no LLM,\n * no message persistence — the script does its own side effects. The\n * preview goes into TriggerOutcome for telemetry / notifications.\n */\nexport async function runTriggerScript(firing: ScriptFiring): Promise<TriggerOutcome> {\n const fn = getScript(firing.script);\n if (!fn) {\n return {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: `Script \"${firing.script}\" not registered`,\n };\n }\n try {\n const result = await fn(firing.args ?? {});\n return {\n status: \"done\",\n preview: result.preview,\n threadId: \"\",\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: msg,\n };\n }\n}\n\n/**\n * Dispatch one firing by mode. The fan-out loop in runTriggerTick\n * goes through here so handlers don't have to know which runner to\n * call.\n */\nexport async function runTriggerFiring(firing: TriggerFiring): Promise<TriggerOutcome> {\n if (firing.mode === \"script\") return runTriggerScript(firing);\n return runTriggerAgent(firing);\n}\n","import {\n getDueTasks,\n markTaskRan,\n getScheduledTask,\n type ScheduledTaskRow,\n} from \"@/lib/stores/scheduled-tasks\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\nimport type {\n TriggerFiring,\n TriggerHandler,\n TriggerOutcome,\n} from \"../types\";\n\nexport const SCHEDULED_TASK_KIND = \"scheduled_task\";\n\n/**\n * ADR-0032 — produce the right firing for a scheduled task. Routes on\n * `reaction_kind`: 'agent_prompt' → PromptFiring (the original ADR-0021\n * path); 'script' → ScriptFiring dispatched through the trigger runner\n * with no LLM round-trip. Unlike watchers, scheduled-task script firings\n * do NOT carry diff context (`previous`/`current`) — there's no diff to\n * report. Scripts that don't read those fields work in both contexts\n * unchanged.\n */\nfunction buildFiring(task: ScheduledTaskRow): TriggerFiring {\n if (task.reaction_kind === \"script\" && task.reaction_script) {\n let userArgs: Record<string, unknown> = {};\n if (task.reaction_script_args) {\n try {\n const parsed = JSON.parse(task.reaction_script_args);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n userArgs = parsed as Record<string, unknown>;\n }\n } catch {\n // Persisted args are validated at write time; a parse error here\n // means storage corruption. Fall back to empty.\n }\n }\n return {\n id: task.id,\n kind: SCHEDULED_TASK_KIND,\n mode: \"script\",\n script: task.reaction_script,\n args: {\n ...userArgs,\n task: {\n id: task.id,\n agent_id: task.agent_id,\n description: task.description,\n schedule: task.schedule,\n schedule_kind: task.kind,\n },\n },\n meta: {\n agent_id: task.agent_id,\n schedule: task.schedule,\n scheduleKind: task.kind,\n reaction_kind: \"script\",\n reaction_script: task.reaction_script,\n // Carry silent through so markFired can suppress the\n // task_completed notification when the user has muted this task.\n silent: task.silent === 1,\n },\n };\n }\n return {\n id: task.id,\n kind: SCHEDULED_TASK_KIND,\n mode: \"prompt\",\n agentId: task.agent_id,\n prompt: task.prompt,\n silent: task.silent === 1,\n // Preserves the existing message-channel filter behaviour (ADR-0022).\n category: \"scheduled_task\",\n meta: { schedule: task.schedule, scheduleKind: task.kind, reaction_kind: \"agent_prompt\", silent: task.silent === 1 },\n };\n}\n\nexport const scheduledTaskHandler: TriggerHandler = {\n kind: SCHEDULED_TASK_KIND,\n\n getDueFirings(asOf: Date): TriggerFiring[] {\n return getDueTasks(asOf).map(buildFiring);\n },\n\n markFired(firing: TriggerFiring, outcome: TriggerOutcome): void {\n const scheduleKind = (firing.meta?.scheduleKind as ScheduledTaskRow[\"kind\"] | undefined) ?? \"cron\";\n const schedule = (firing.meta?.schedule as string | undefined) ?? \"\";\n // Always advance the schedule (or delete the row for one-shots),\n // regardless of which firing mode we ran.\n markTaskRan(firing.id, scheduleKind, schedule, outcome.error);\n\n // ADR-0032 — silent=true on the task suppresses both NO_REPLY-style\n // agent behaviour AND the task_completed notification. Errors still\n // surface so the user sees failures even on muted tasks.\n const silent = firing.mode === \"prompt\"\n ? firing.silent === true\n : firing.meta?.silent === true;\n if (silent && !outcome.error) return;\n\n if (firing.mode === \"prompt\") {\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: firing.agentId,\n prompt: firing.prompt,\n thread_id: outcome.threadId,\n status: outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n return;\n }\n // ADR-0032 — script firings publish a synthesised notification so the\n // UI event stream still lights up. No thread, so threadId is empty.\n const meta = (firing.meta ?? {}) as { agent_id?: string; reaction_script?: string };\n const scriptName = meta.reaction_script ?? firing.script;\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: meta.agent_id ?? \"\",\n prompt: `Scheduled task fired script ${scriptName}`,\n thread_id: \"\",\n status: outcome.status === \"skipped\" ? \"done\" : outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n },\n};\n\n/** Public helper for the \"Run now\" API route — fires a single task by id. */\nexport function firingForTaskId(taskId: string): TriggerFiring | null {\n const task = getScheduledTask(taskId);\n return task ? buildFiring(task) : null;\n}\n","// Watcher trigger handler (ADR-0027). Sibling of scheduled-task.ts.\n//\n// Per scheduler tick, for every due watcher row:\n// 1. Resolve the named tool from the built-in registry.\n// 2. Invoke it with the saved JSON args (no agent context — watcher\n// tools must be context-free).\n// 3. Hash the stringified result and compare to last_fingerprint.\n// 4. If the hash differs from the previous run, return a TriggerFiring\n// whose prompt embeds {previous, current} as context for the agent.\n// If it matches (or this is the first run with no previous), record\n// the fingerprint and skip — no LLM call, no firing.\n// 5. Either way the watcher's next_run_at is advanced by\n// interval_seconds. Errors during polling are recorded on the row\n// and surfaced in the UI.\n//\n// All scheduling work happens inside `getDueFirings` because the\n// abstraction's markFired is only called for actually-fired runs.\nimport { createHash } from \"node:crypto\";\nimport {\n getDueWatchers,\n getWatcher,\n recordWatcherPoll,\n recordWatcherPollError,\n type WatcherRow,\n} from \"@/lib/stores/watchers\";\nimport { registeredTools } from \"@/lib/tools/registry\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\nimport type { TriggerFiring, TriggerHandler, TriggerOutcome } from \"../types\";\n\nexport const WATCHER_KIND = \"watcher\";\n\nfunction fingerprint(s: string): string {\n return createHash(\"sha256\").update(s).digest(\"hex\");\n}\n\nfunction stringifyResult(value: unknown): string {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nconst DEFAULT_REACTION_DIRECTIVE =\n `Summarise what changed and decide whether the user needs to know. ` +\n `If nothing material changed, you may stay silent.`;\n\nfunction buildFiringPrompt(watcher: WatcherRow, previous: string | null, current: string): string {\n const argsPretty = (() => {\n try { return JSON.stringify(JSON.parse(watcher.tool_args), null, 2); }\n catch { return watcher.tool_args; }\n })();\n // ADR-0030: a non-null reaction_prompt swaps in for the default directive.\n // The diff envelope (label/tool/args/previous/current) is unchanged so the\n // agent always has the change context regardless of the user's instruction.\n const directive = watcher.reaction_prompt?.trim() || DEFAULT_REACTION_DIRECTIVE;\n return [\n `Watcher \"${watcher.label}\" detected a change.`,\n ``,\n `Tool: ${watcher.tool_name}`,\n `Args: ${argsPretty}`,\n ``,\n `--- Previous result ---`,\n previous ?? \"(none — first observation)\",\n ``,\n `--- Current result ---`,\n current,\n ``,\n directive,\n ].join(\"\\n\");\n}\n\n/**\n * ADR-0031 — build the args bundle handed to a `reaction.*` script when\n * a watcher with reaction_kind='script' fires. The bundle merges the\n * user-supplied script args with diff context (previous + current\n * stringified results, plus a slim `watcher` descriptor) so any reaction\n * script can access both the static config and the change context.\n */\nfunction buildScriptArgs(watcher: WatcherRow, previous: string | null, current: string): Record<string, unknown> {\n let userArgs: Record<string, unknown> = {};\n if (watcher.reaction_script_args) {\n try {\n const parsed = JSON.parse(watcher.reaction_script_args);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n userArgs = parsed as Record<string, unknown>;\n }\n } catch {\n // Persisted args are validated at write time; a parse error here\n // means storage corruption. Fall back to empty so the script still\n // runs with diff context.\n }\n }\n return {\n ...userArgs,\n watcher: {\n id: watcher.id,\n label: watcher.label,\n tool_name: watcher.tool_name,\n tool_args: safeJson(watcher.tool_args),\n agent_id: watcher.agent_id,\n },\n previous,\n current,\n };\n}\n\nfunction safeJson(s: string): unknown {\n try { return JSON.parse(s); } catch { return s; }\n}\n\n/**\n * ADR-0031 — produce the right firing for a watcher that just observed\n * a change. Routes on `reaction_kind`: 'agent_prompt' → PromptFiring (the\n * original ADR-0027 path); 'script' → ScriptFiring dispatched through\n * the trigger runner with no LLM round-trip.\n */\nfunction buildFiring(watcher: WatcherRow, previous: string | null, current: string): TriggerFiring {\n if (watcher.reaction_kind === \"script\" && watcher.reaction_script) {\n return {\n id: watcher.id,\n kind: WATCHER_KIND,\n mode: \"script\",\n script: watcher.reaction_script,\n args: buildScriptArgs(watcher, previous, current),\n meta: {\n label: watcher.label,\n tool_name: watcher.tool_name,\n agent_id: watcher.agent_id,\n reaction_kind: \"script\",\n reaction_script: watcher.reaction_script,\n // Carry silent through so markFired can suppress the\n // task_completed notification when the user has muted this watcher.\n silent: watcher.silent === 1,\n },\n };\n }\n return {\n id: watcher.id,\n kind: WATCHER_KIND,\n mode: \"prompt\",\n agentId: watcher.agent_id,\n prompt: buildFiringPrompt(watcher, previous, current),\n silent: watcher.silent === 1,\n category: \"watcher\",\n meta: { label: watcher.label, tool_name: watcher.tool_name, reaction_kind: \"agent_prompt\", silent: watcher.silent === 1 },\n };\n}\n\nasync function invokeWatcherTool(watcher: WatcherRow): Promise<string> {\n const entry = registeredTools().find((t) => t.name === watcher.tool_name);\n if (!entry) throw new Error(`tool \"${watcher.tool_name}\" is not registered`);\n let args: unknown;\n try { args = JSON.parse(watcher.tool_args); }\n catch (e) { throw new Error(`tool_args is not valid JSON: ${e instanceof Error ? e.message : String(e)}`); }\n // LangChain tools accept the args object directly via .invoke().\n // Watcher tools must be context-free (no thread_id / agent_id).\n const result = await entry.invoke(args as Record<string, unknown>);\n return stringifyResult(result);\n}\n\n/**\n * Poll every due watcher and produce firings only for those whose\n * tool result changed since the last poll. Updates polling state\n * synchronously so subsequent ticks see the advanced next_run_at.\n */\nasync function pollDueWatchers(asOf: Date): Promise<TriggerFiring[]> {\n const due = getDueWatchers(asOf);\n const firings: TriggerFiring[] = [];\n for (const watcher of due) {\n try {\n const result = await invokeWatcherTool(watcher);\n const fp = fingerprint(result);\n const firstRun = watcher.last_fingerprint === null;\n const changed = !firstRun && fp !== watcher.last_fingerprint;\n recordWatcherPoll({\n id: watcher.id,\n fingerprint: fp,\n result,\n fired: changed,\n });\n if (changed) {\n firings.push(buildFiring(watcher, watcher.last_result, result));\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n recordWatcherPollError(watcher.id, msg);\n // A polling error doesn't fire the agent; it's surfaced via\n // last_error on the row + UI. Logging only.\n console.error(`[watcher] poll ${watcher.id} (${watcher.tool_name}) failed:`, msg);\n }\n }\n return firings;\n}\n\nexport const watcherHandler: TriggerHandler = {\n kind: WATCHER_KIND,\n\n async getDueFirings(asOf: Date): Promise<TriggerFiring[]> {\n return pollDueWatchers(asOf);\n },\n\n markFired(firing: TriggerFiring, outcome: TriggerOutcome): void {\n // Polling state (last_run_at, last_fingerprint, last_result,\n // next_run_at) was already advanced inside getDueFirings — we only\n // publish a notification here so the UI's event stream lights up.\n // ADR-0031 — script firings publish too; reuse `task_completed` with\n // a synthesised prompt and the watcher's agent_id from meta (script\n // firings have no thread, so threadId is empty).\n // silent=true on the watcher suppresses the notification (in addition\n // to the prompt-mode NO_REPLY semantic). Errors still surface.\n const silent = firing.mode === \"prompt\"\n ? firing.silent === true\n : firing.meta?.silent === true;\n if (silent && !outcome.error) return;\n if (firing.mode === \"prompt\") {\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: firing.agentId,\n prompt: firing.prompt,\n thread_id: outcome.threadId,\n status: outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n return;\n }\n const meta = (firing.meta ?? {}) as { label?: string; agent_id?: string; reaction_script?: string };\n const label = meta.label ?? \"(watcher)\";\n const scriptName = meta.reaction_script ?? firing.script;\n publishNotification({\n type: \"task_completed\",\n task_id: firing.id,\n agent_id: meta.agent_id ?? \"\",\n prompt: `Watcher \"${label}\" fired script ${scriptName}`,\n thread_id: \"\",\n status: outcome.status === \"skipped\" ? \"done\" : outcome.status,\n preview: outcome.preview,\n error: outcome.error,\n ts: Date.now(),\n });\n },\n};\n\n/**\n * \"Run now\" — force a single poll of one watcher and, if the result\n * differs from `last_fingerprint`, return a ready-to-run firing. Used by\n * the manual /run HTTP endpoint. Returns null when the poll didn't\n * trigger a firing (no change, or the watcher is gone).\n */\nexport async function firingForWatcherIdNow(id: string): Promise<TriggerFiring | null> {\n const watcher = getWatcher(id);\n if (!watcher) return null;\n try {\n const result = await invokeWatcherTool(watcher);\n const fp = fingerprint(result);\n const firstRun = watcher.last_fingerprint === null;\n const changed = !firstRun && fp !== watcher.last_fingerprint;\n recordWatcherPoll({ id: watcher.id, fingerprint: fp, result, fired: changed });\n if (!changed) return null;\n return buildFiring(watcher, watcher.last_result, result);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n recordWatcherPollError(watcher.id, msg);\n throw err;\n }\n}\n","// Single-file re-index path used by the fs-watch trigger.\n//\n// The full sweep in indexer.ts handles \"scan everything\" semantics —\n// allowlists, size caps, deletion sweeps. For watcher firings we\n// already know the absolute path, so we duplicate just the per-file\n// part: stat → read → hash → upsert (or delete).\n\nimport { promises as fs } from \"node:fs\";\nimport { relative, sep } from \"node:path\";\nimport { getDb } from \"@/lib/db\";\nimport { getDocumentSource } from \"@/lib/stores/document-sources\";\nimport { registerScript } from \"@/lib/triggers/scripts\";\nimport {\n ALLOWED_EXT,\n MAX_FILE_BYTES,\n hashContent,\n lowerExt,\n readTextFile,\n upsertLocalDocument,\n type FileEntry,\n} from \"./indexer\";\n\nexport interface ReindexResult {\n preview: string;\n}\n\n/**\n * Re-index a single file inside a local_folder source. Idempotent;\n * returns \"deleted\" / \"skipped\" / \"added\" / \"updated\" / \"unchanged\".\n */\nexport async function reindexLocalFile(args: {\n source_id: string;\n abs: string;\n}): Promise<ReindexResult> {\n const source = getDocumentSource(args.source_id);\n if (!source) return { preview: `skipped: source ${args.source_id} missing` };\n if (source.kind !== \"local_folder\") {\n return { preview: `skipped: source ${args.source_id} is not local_folder` };\n }\n\n const db = getDb();\n\n let stat;\n try {\n stat = await fs.stat(args.abs);\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\") {\n // File gone — drop the row (chunks cascade via FK).\n const info = db\n .prepare(\"DELETE FROM documents WHERE source_id=? AND path=?\")\n .run(args.source_id, args.abs);\n return {\n preview: info.changes > 0 ? `deleted ${args.abs}` : `skipped: not indexed (${args.abs})`,\n };\n }\n throw err;\n }\n\n if (!stat.isFile()) return { preview: `skipped: not a regular file (${args.abs})` };\n if (stat.size > MAX_FILE_BYTES) return { preview: `skipped: file > MAX_FILE_BYTES (${args.abs})` };\n\n // Watchers don't pre-filter by extension as aggressively as the\n // sweep does, so re-check here. Keeps the allowlist as the single\n // source of truth even if a future caller forgets.\n if (!ALLOWED_EXT.has(lowerExt(args.abs))) {\n return { preview: `skipped: ext not allowed (${args.abs})` };\n }\n\n const text = await readTextFile(args.abs);\n if (text === null) return { preview: `skipped: binary or unreadable (${args.abs})` };\n\n const hash = hashContent(text);\n const existing = db\n .prepare(\n \"SELECT id, mtime_ms, size_bytes, content_hash FROM documents WHERE source_id=? AND path=?\",\n )\n .get(args.source_id, args.abs) as\n | { id: string; mtime_ms: number; size_bytes: number; content_hash: string }\n | undefined;\n\n if (existing && existing.content_hash === hash) {\n // Mtime/size may have shifted (touch / OneDrive sync) but content\n // is unchanged — touch the row instead of re-embedding.\n db.prepare(\n \"UPDATE documents SET mtime_ms=?, size_bytes=?, last_indexed_at=? WHERE id=?\",\n ).run(Math.floor(stat.mtimeMs), stat.size, new Date().toISOString(), existing.id);\n return { preview: `unchanged ${args.abs}` };\n }\n\n const f: FileEntry = {\n abs: args.abs,\n rel: relative(source.path, args.abs).split(sep).join(\"/\"),\n mtime_ms: Math.floor(stat.mtimeMs),\n size: stat.size,\n };\n await upsertLocalDocument(args.source_id, f, text, hash, existing?.id);\n return { preview: existing ? `updated ${args.abs}` : `added ${args.abs}` };\n}\n\n// Registry side-effect: register the script the fs-watch handler\n// emits. Importing this module wires it. Call sites are\n// instrumentation.ts (boot) and the fs-watch handler module\n// (defensive in case boot order changes).\nlet registered = false;\nexport function registerDocumentScripts(): void {\n if (registered) return;\n registerScript(\"documents.reindex_local_file\", async (args) => {\n const sourceId = String(args.source_id ?? \"\");\n const abs = String(args.abs ?? \"\");\n if (!sourceId || !abs) {\n return { preview: \"skipped: missing source_id or abs\" };\n }\n return reindexLocalFile({ source_id: sourceId, abs });\n });\n registered = true;\n}\n\nregisterDocumentScripts();\n","// fs.watch-driven re-indexing for local document sources.\n//\n// Boots one watcher per enabled `local_folder` source. Filesystem events\n// are filtered (skip dot-dirs / build output / disallowed extensions)\n// and debounced per-(source_id, abs) for 500 ms. Each surviving event\n// becomes a ScriptFiring that the runner dispatches to\n// `documents.reindex_local_file`.\n//\n// On Linux, fs.watch with `recursive: true` is unsupported — we log\n// once per source and rely on the 10-min full sweep there. On macOS\n// and Windows this gives sub-second propagation from save-to-search.\n\nimport { promises as fs, type FSWatcher, watch as fsWatch } from \"node:fs\";\nimport { join, sep } from \"node:path\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { listEnabledDocumentSources } from \"@/lib/stores/document-sources\";\nimport { ALLOWED_EXT, SKIP_DIRS, lowerExt } from \"@/lib/documents/indexer\";\n// Side-effect import: ensures `documents.reindex_local_file` is in the\n// script registry before the first firing dispatches.\nimport \"@/lib/documents/reindex-local-file\";\nimport type {\n ScriptFiring,\n TriggerFiring,\n TriggerHandler,\n} from \"../types\";\n\nexport const FS_WATCH_KIND = \"fs_watch\";\n\nconst DEBOUNCE_MS = 500;\n\ninterface WatcherState {\n sourceId: string;\n rootPath: string;\n watcher: FSWatcher | null;\n /** Map<abs, debounce-timer-id> while a debounce is in flight. */\n debounceTimers: Map<string, NodeJS.Timeout>;\n}\n\ninterface FsWatchState {\n watchers: Map<string, WatcherState>; // sourceId → state\n /** Coalesced pending firings, keyed by `${source_id}:${abs}`. */\n pending: Map<string, { source_id: string; abs: string }>;\n unsupportedLogged: Set<string>;\n}\n\n// Stored on globalThis: Next's standalone build bundles this module into\n// multiple chunks (one per route that transitively imports it), and each\n// chunk would otherwise have its own copy of `state`. Without the global\n// pin, the chunk that runs `attachWatcher` enqueues into a different Map\n// than the chunk the scheduler tick reads via `drainPending`.\nconst state = getOrCreateGlobal<FsWatchState>(\"__jarela_fs_watch_state\", () => ({\n watchers: new Map(),\n pending: new Map(),\n unsupportedLogged: new Set(),\n}));\n\nfunction pendingKey(sourceId: string, abs: string): string {\n return `${sourceId}:${abs}`;\n}\n\nfunction enqueuePending(sourceId: string, abs: string): void {\n state.pending.set(pendingKey(sourceId, abs), { source_id: sourceId, abs });\n}\n\nfunction scheduleDebounce(w: WatcherState, abs: string): void {\n const existing = w.debounceTimers.get(abs);\n if (existing) clearTimeout(existing);\n const t = setTimeout(() => {\n w.debounceTimers.delete(abs);\n enqueuePending(w.sourceId, abs);\n }, DEBOUNCE_MS);\n // Don't keep the event loop alive just for the debounce.\n if (typeof t.unref === \"function\") t.unref();\n w.debounceTimers.set(abs, t);\n}\n\nfunction handleEvent(w: WatcherState, filename: string | null): void {\n if (!filename) return;\n // Filter dot-dirs and SKIP_DIRS inline. We can't trust the\n // recursive watcher to honour them.\n const segments = filename.split(/[\\\\/]+/).filter((s) => s.length > 0);\n if (segments.length === 0) return;\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n if (SKIP_DIRS.has(seg)) return;\n if (seg.startsWith(\".\")) return;\n }\n const file = segments[segments.length - 1];\n if (!ALLOWED_EXT.has(lowerExt(file))) return;\n const abs = join(w.rootPath, ...segments);\n scheduleDebounce(w, abs);\n}\n\nasync function attachWatcher(sourceId: string, rootPath: string): Promise<void> {\n if (state.watchers.has(sourceId)) return;\n // Confirm the directory still exists; fs.watch on a nonexistent path\n // throws synchronously and tears down the boot loop.\n try {\n const st = await fs.stat(rootPath);\n if (!st.isDirectory()) return;\n } catch {\n return;\n }\n\n const w: WatcherState = {\n sourceId,\n rootPath,\n watcher: null,\n debounceTimers: new Map(),\n };\n try {\n w.watcher = fsWatch(\n rootPath,\n { recursive: true, persistent: false },\n (_event, filename) => {\n const name: string | null =\n typeof filename === \"string\"\n ? filename\n : filename\n ? (filename as Buffer).toString()\n : null;\n handleEvent(w, name);\n },\n );\n w.watcher.on(\"error\", (err) => {\n console.warn(`[triggers/fs_watch] watcher error for ${rootPath}:`, err.message);\n });\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ERR_FEATURE_UNAVAILABLE_ON_PLATFORM\") {\n // Linux: recursive fs.watch isn't supported. Falling back to the\n // 10-min full sweep is fine — log once per source.\n if (!state.unsupportedLogged.has(sourceId)) {\n console.warn(\n `[triggers/fs_watch] recursive fs.watch unsupported on this platform; ` +\n `relying on the full sweep for source \"${rootPath}\"`,\n );\n state.unsupportedLogged.add(sourceId);\n }\n return;\n }\n console.warn(`[triggers/fs_watch] failed to attach watcher to ${rootPath}:`, e.message);\n return;\n }\n state.watchers.set(sourceId, w);\n}\n\nfunction detachWatcher(sourceId: string): void {\n const w = state.watchers.get(sourceId);\n if (!w) return;\n for (const t of w.debounceTimers.values()) clearTimeout(t);\n w.debounceTimers.clear();\n if (w.watcher) {\n try { w.watcher.close(); } catch { /* noop */ }\n }\n state.watchers.delete(sourceId);\n}\n\nasync function syncWatchers(): Promise<void> {\n const sources = listEnabledDocumentSources().filter((s) => s.kind === \"local_folder\");\n const wantSourceIds = new Set(sources.map((s) => s.id));\n\n // Drop watchers whose source disappeared / disabled.\n for (const sourceId of Array.from(state.watchers.keys())) {\n if (!wantSourceIds.has(sourceId)) {\n detachWatcher(sourceId);\n }\n }\n\n // Attach new watchers.\n for (const s of sources) {\n if (state.watchers.has(s.id)) continue;\n await attachWatcher(s.id, s.path);\n }\n}\n\nfunction drainPending(): ScriptFiring[] {\n if (state.pending.size === 0) return [];\n const now = Date.now();\n const firings: ScriptFiring[] = [];\n for (const { source_id, abs } of state.pending.values()) {\n firings.push({\n id: `${source_id}:${abs}:${now}`,\n kind: FS_WATCH_KIND,\n mode: \"script\",\n script: \"documents.reindex_local_file\",\n args: { source_id, abs },\n });\n }\n state.pending.clear();\n return firings;\n}\n\nexport const fsWatchHandler: TriggerHandler = {\n kind: FS_WATCH_KIND,\n\n async start(): Promise<void> {\n await syncWatchers();\n },\n\n async sync(): Promise<void> {\n await syncWatchers();\n },\n\n async stop(): Promise<void> {\n for (const sourceId of Array.from(state.watchers.keys())) {\n detachWatcher(sourceId);\n }\n state.pending.clear();\n },\n\n getDueFirings(_asOf: Date): TriggerFiring[] {\n return drainPending();\n },\n\n markFired(): void {\n // The script writes its own state into `documents`. Nothing extra\n // to bookkeep here — keeping this empty also means re-firing after\n // an error is the next watcher event, which is the right thing.\n },\n};\n\n/** Test-only helper. */\nexport function __resetFsWatchState(): void {\n for (const sourceId of Array.from(state.watchers.keys())) {\n detachWatcher(sourceId);\n }\n state.pending.clear();\n state.unsupportedLogged.clear();\n}\n\n/** Test-only helper. Pumps a synthetic event without touching the real fs. */\nexport function __pushEventForTest(sourceId: string, rootPath: string, filename: string): void {\n let w = state.watchers.get(sourceId);\n if (!w) {\n w = { sourceId, rootPath, watcher: null, debounceTimers: new Map() };\n state.watchers.set(sourceId, w);\n }\n handleEvent(w, filename);\n}\n","// Fast (60 s) re-sweep loop for remote document sources.\n//\n// Local folders use fs.watch for low-latency reindexing; remote\n// sources (Confluence / Jira) have no inotify equivalent, so we poll\n// — but at a much higher cadence than the 10-min full sweep. Each\n// source's existing cursor (last_cursor on document_sources) means\n// the upstream API call only fetches what changed since last poll,\n// keeping rate-limit pressure low.\n\nimport {\n listEnabledDocumentSources,\n markSourceScanned,\n} from \"@/lib/stores/document-sources\";\nimport { isRemoteKind, runRemoteSource } from \"@/lib/documents/remote\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\nimport { registerScript } from \"../scripts\";\nimport type {\n ScriptFiring,\n TriggerFiring,\n TriggerHandler,\n} from \"../types\";\n\nexport const DOCUMENT_FAST_SWEEP_KIND = \"doc_fast_sweep\";\n\nconst DEFAULT_INTERVAL_MS = 60_000;\n\nfunction intervalMs(): number {\n const raw = process.env.JARELA_FAST_REMOTE_SWEEP_MS;\n if (!raw) return DEFAULT_INTERVAL_MS;\n const n = Number.parseInt(raw, 10);\n return Number.isFinite(n) && n >= 1000 ? n : DEFAULT_INTERVAL_MS;\n}\n\ninterface SweepState {\n /** sourceId → last fired (ms epoch). */\n lastRunAt: Map<string, number>;\n}\n\n// Pinned to globalThis: Next's standalone build bundles handler files\n// into multiple chunks, and module-local state would otherwise be split\n// across them. See lib/triggers/handlers/fs-watch.ts for the same fix.\nconst state = getOrCreateGlobal<SweepState>(\n \"__jarela_doc_fast_sweep_state\",\n () => ({ lastRunAt: new Map() }),\n);\n\nlet scriptRegistered = false;\nfunction registerSweepScript(): void {\n if (scriptRegistered) return;\n registerScript(\"documents.run_remote_source\", async (args) => {\n const sourceId = String(args.source_id ?? \"\");\n if (!sourceId) return { preview: \"skipped: missing source_id\" };\n // Resolve the source row at fire time so we always pick up the\n // latest config / cursor without caching it.\n const sources = listEnabledDocumentSources();\n const source = sources.find((s) => s.id === sourceId);\n if (!source) return { preview: `skipped: source ${sourceId} not enabled` };\n if (!isRemoteKind(source.kind)) {\n return { preview: `skipped: source ${sourceId} is not a remote kind` };\n }\n try {\n const stats = await runRemoteSource(source);\n return {\n preview:\n `${source.kind} ${source.path}: ` +\n `+${stats.added} ~${stats.updated} =${stats.unchanged} !${stats.errors}`,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // The runRemoteSource path normally swallows its own errors; if\n // something escaped, mark the source so the panel surfaces it.\n try { markSourceScanned(source.id, msg); } catch { /* noop */ }\n throw err;\n }\n });\n scriptRegistered = true;\n}\n\nregisterSweepScript();\n\nexport const documentFastSweepHandler: TriggerHandler = {\n kind: DOCUMENT_FAST_SWEEP_KIND,\n\n getDueFirings(asOf: Date): TriggerFiring[] {\n const now = asOf.getTime();\n const interval = intervalMs();\n const sources = listEnabledDocumentSources().filter((s) => isRemoteKind(s.kind));\n const firings: ScriptFiring[] = [];\n for (const s of sources) {\n const last = state.lastRunAt.get(s.id) ?? 0;\n if (now - last < interval) continue;\n firings.push({\n id: `${s.id}:${now}`,\n kind: DOCUMENT_FAST_SWEEP_KIND,\n mode: \"script\",\n script: \"documents.run_remote_source\",\n args: { source_id: s.id },\n });\n }\n return firings;\n },\n\n markFired(firing: TriggerFiring): void {\n if (firing.mode !== \"script\") return;\n const sourceId = firing.args ? String(firing.args.source_id ?? \"\") : \"\";\n if (!sourceId) return;\n // Throttle on every firing regardless of outcome — Atlassian\n // rate-limits don't differentiate between success and error.\n state.lastRunAt.set(sourceId, Date.now());\n },\n};\n\n/** Test-only helper. */\nexport function __resetFastSweepState(): void {\n state.lastRunAt.clear();\n}\n","// ADR-0031 — `reaction.notify`: a watcher reaction script that publishes\n// a `task_completed` notification with the watcher's diff preview.\n//\n// Args provided by the watcher handler at fire time (see\n// pollDueWatchers in handlers/watcher.ts):\n// { watcher: { id, label, tool_name, tool_args, agent_id },\n// previous: string | null,\n// current: string,\n// ...userArgs }\n//\n// User-supplied args (subset that this script reads):\n// { title?: string, level?: \"info\" | \"warning\" }\nimport { registerScript, type ScriptResult } from \"@/lib/triggers/scripts\";\nimport { publish as publishNotification } from \"@/lib/notifications/bus\";\n\ninterface NotifyContext {\n watcher?: {\n id?: string;\n label?: string;\n tool_name?: string;\n agent_id?: string;\n };\n previous?: string | null;\n current?: string;\n title?: string;\n level?: \"info\" | \"warning\";\n}\n\nfunction shortPreview(previous: string | null | undefined, current: string | undefined): string {\n const cur = (current ?? \"\").replace(/\\s+/g, \" \").trim();\n const prev = (previous ?? \"\").replace(/\\s+/g, \" \").trim();\n if (!prev) return cur.slice(0, 120);\n // Trivial diff: just show \"<prev> → <current>\" trimmed at both ends.\n const left = prev.slice(0, 50);\n const right = cur.slice(0, 50);\n return `${left} → ${right}`;\n}\n\nregisterScript(\"reaction.notify\", async (args: Record<string, unknown>): Promise<ScriptResult> => {\n const ctx = args as NotifyContext;\n const watcher = ctx.watcher ?? {};\n const label = watcher.label ?? \"(unknown watcher)\";\n const title = (typeof ctx.title === \"string\" && ctx.title.trim()) || label;\n const preview = shortPreview(ctx.previous, ctx.current);\n // Reuse `task_completed` as the notification surface — the UI already\n // subscribes to it for scheduled-task / agent-prompt firings, and it\n // tolerates an empty thread_id (script firings have no thread).\n publishNotification({\n type: \"task_completed\",\n task_id: watcher.id ?? \"\",\n agent_id: watcher.agent_id ?? \"\",\n prompt: `Watcher \"${label}\" detected a change.`,\n thread_id: \"\",\n status: \"done\",\n preview,\n ts: Date.now(),\n });\n return { preview: `notify: ${title} — ${preview}`.slice(0, 160) };\n});\n","import { listTriggerHandlers, registerTriggerHandler } from \"./registry\";\nimport { runTriggerAgent, runTriggerFiring, runTriggerScript } from \"./runner\";\nimport {\n scheduledTaskHandler,\n firingForTaskId,\n SCHEDULED_TASK_KIND,\n} from \"./handlers/scheduled-task\";\nimport {\n watcherHandler,\n firingForWatcherIdNow,\n WATCHER_KIND,\n} from \"./handlers/watcher\";\nimport { fsWatchHandler } from \"./handlers/fs-watch\";\nimport { documentFastSweepHandler } from \"./handlers/document-fast-sweep\";\n// Side-effect imports: ensure built-in reaction scripts (ADR-0031) are\n// in the registry before the first watcher firing dispatches.\nimport \"./reactions/notify\";\nimport type { TriggerFiring } from \"./types\";\n\n// Single registration site for built-in handlers. Importing this file\n// from the scheduler ensures every handler is wired before the first\n// tick. Future PRs add their handlers here.\nlet registered = false;\nexport function registerHandlers(): void {\n if (registered) return;\n registerTriggerHandler(scheduledTaskHandler);\n registerTriggerHandler(watcherHandler);\n registerTriggerHandler(fsWatchHandler);\n registerTriggerHandler(documentFastSweepHandler);\n registered = true;\n}\n\n// Eager registration on module load — preserves the legacy behaviour\n// where importing this module wires the scheduled-task handler.\nregisterHandlers();\n\n/** Boot every registered handler that has a start() lifecycle hook. */\nexport async function startAllTriggerHandlers(): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n if (!handler.start) continue;\n try {\n await handler.start();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" start failed:`, msg);\n }\n }\n}\n\n/** Drain every registered handler that has a stop() lifecycle hook. */\nexport async function stopAllTriggerHandlers(): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n if (!handler.stop) continue;\n try {\n await handler.stop();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" stop failed:`, msg);\n }\n }\n}\n\n/**\n * Notify handlers that something they care about changed. Today this\n * is fired by the document-source mutation routes so fs-watch and the\n * fast remote sweep can re-evaluate which sources they're watching.\n */\nexport async function notifyTriggerHandlers(_reason: string): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n if (!handler.sync) continue;\n try {\n await handler.sync();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" sync failed:`, msg);\n }\n }\n}\n\n/** Run one tick of the trigger fan-out. Used by the scheduler loop. */\nexport async function runTriggerTick(asOf: Date = new Date()): Promise<void> {\n for (const handler of listTriggerHandlers()) {\n let firings: TriggerFiring[];\n try {\n firings = await handler.getDueFirings(asOf);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] handler \"${handler.kind}\" getDueFirings failed:`, msg);\n continue;\n }\n for (const firing of firings) {\n try {\n const outcome = await runTriggerFiring(firing);\n await handler.markFired(firing, outcome);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`[triggers] firing ${handler.kind}/${firing.id} failed:`, msg);\n try {\n await handler.markFired(firing, {\n status: \"error\",\n preview: \"\",\n threadId: \"\",\n error: msg,\n });\n } catch (innerErr) {\n console.error(\n `[triggers] handler \"${handler.kind}\" markFired threw after error:`,\n innerErr,\n );\n }\n }\n }\n }\n}\n\n/**\n * Fire a single scheduled-task by id, on demand. Preserves the original\n * runScheduledTaskNow surface: returns when the run completes, throws\n * the underlying error if the run itself threw.\n */\nexport async function runScheduledTaskFiringNow(taskId: string): Promise<void> {\n const firing = firingForTaskId(taskId);\n if (!firing) throw new Error(`scheduled task ${taskId} not found`);\n // Route through runTriggerFiring so script-kind firings dispatch\n // through the script registry instead of the agent (ADR-0032).\n const outcome = await runTriggerFiring(firing);\n await scheduledTaskHandler.markFired(firing, outcome);\n if (outcome.status === \"error\" && outcome.error) {\n throw new Error(outcome.error);\n }\n}\n\n/**\n * Force a single watcher to poll right now. If the polled value differs\n * from the previously stored fingerprint, fire the agent and return.\n * Returns silently when there's no diff (so the manual \"Run now\" button\n * doesn't fabricate a turn out of an unchanged poll).\n */\nexport async function runWatcherFiringNow(watcherId: string): Promise<void> {\n const firing = await firingForWatcherIdNow(watcherId);\n if (!firing) return;\n if (firing.mode !== \"prompt\") return;\n const outcome = await runTriggerAgent(firing);\n await watcherHandler.markFired(firing, outcome);\n if (outcome.status === \"error\" && outcome.error) {\n throw new Error(outcome.error);\n }\n}\n\nexport { SCHEDULED_TASK_KIND, WATCHER_KIND };\nexport * from \"./types\";\nexport { registerTriggerHandler, listTriggerHandlers } from \"./registry\";\nexport { runTriggerAgent, runTriggerScript, runTriggerFiring };\nexport {\n registerScript,\n getScript,\n listScripts,\n listReactionScripts,\n isReactionScript,\n REACTION_SCRIPT_PREFIX,\n} from \"./scripts\";\n","// Cheap HTML → plain text. Not a parser — regex-only, deterministic, no deps.\n//\n// Two modes:\n// - default (preserveParagraphs: false): collapses ALL whitespace to single\n// spaces. Right for web-page summarization where the agent wants prose.\n// - preserveParagraphs: true: keeps newline structure (br → \\n, /p → \\n\\n)\n// and only collapses runs of spaces/tabs. Right for email bodies where the\n// agent benefits from paragraph breaks.\nexport function stripHtml(html: string, opts?: { preserveParagraphs?: boolean }): string {\n let s = html\n .replace(/<style[\\s\\S]*?<\\/style>/gi, \" \")\n .replace(/<script[\\s\\S]*?<\\/script>/gi, \" \")\n .replace(/<noscript[\\s\\S]*?<\\/noscript>/gi, \" \")\n .replace(/<!--[\\s\\S]*?-->/g, \" \");\n\n if (opts?.preserveParagraphs) {\n s = s\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/p>/gi, \"\\n\\n\");\n // Strip remaining tags with empty (so the br/p newlines we just injected\n // aren't surrounded by stray spaces from the opening tags).\n s = s.replace(/<\\/?[^>]+>/g, \"\");\n } else {\n // Default mode: replace tags with spaces so adjacent words don't merge.\n s = s.replace(/<\\/?[^>]+>/g, \" \");\n }\n\n s = decodeHtmlEntities(s);\n\n s = opts?.preserveParagraphs\n ? s.replace(/[ \\t]+/g, \" \").replace(/\\n{3,}/g, \"\\n\\n\")\n : s.replace(/\\s+/g, \" \");\n\n return s.trim();\n}\n\nexport function decodeHtmlEntities(s: string): string {\n return s\n .replace(/&nbsp;/g, \" \")\n .replace(/&amp;/g, \"&\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\");\n}\n","// ADR-0028. In-process script registry for ScriptFiring.\n//\n// Trust model: only built-ins are registered, in code, at module load\n// time. There is NO mechanism to register a script from DB, user input,\n// or shell-out — `script` on a ScriptFiring is just a key into this\n// map. This keeps scripted triggers safe even though they bypass the\n// LLM/thread machinery that gates prompt firings.\n\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\n\nexport interface ScriptResult {\n /** Short, single-line summary suitable for telemetry / logs. */\n preview: string;\n}\n\nexport type ScriptFn = (args: Record<string, unknown>) => Promise<ScriptResult>;\n\ninterface ScriptRegistryState {\n scripts: Map<string, ScriptFn>;\n}\n\nconst state = getOrCreateGlobal<ScriptRegistryState>(\n \"__jarela_trigger_scripts\",\n () => ({ scripts: new Map() }),\n);\n\nexport function registerScript(name: string, fn: ScriptFn): void {\n // Idempotent re-registration is fine — HMR and repeated module imports\n // in dev re-execute the registration calls. We just overwrite with the\n // latest function, matching the trigger handler registry's behaviour.\n state.scripts.set(name, fn);\n}\n\nexport function getScript(name: string): ScriptFn | undefined {\n return state.scripts.get(name);\n}\n\nexport function listScripts(): string[] {\n return Array.from(state.scripts.keys()).sort();\n}\n\n// ADR-0031 — names beginning with this prefix are user-attachable\n// reaction scripts. Internal plumbing scripts (e.g.\n// `documents.reindex_local_file`) live under other namespaces and are\n// excluded so the watcher schedule surface can't accidentally invoke\n// them.\nexport const REACTION_SCRIPT_PREFIX = \"reaction.\";\n\nexport function listReactionScripts(): string[] {\n return listScripts().filter((n) => n.startsWith(REACTION_SCRIPT_PREFIX));\n}\n\nexport function isReactionScript(name: string): boolean {\n return name.startsWith(REACTION_SCRIPT_PREFIX) && state.scripts.has(name);\n}\n\n/** Test-only helper. */\nexport function __resetScriptRegistry(): void {\n state.scripts.clear();\n}\n"],"names":["BaseChatModel","AIMessage","AIMessageChunk","isAIMessage","isHumanMessage","isSystemMessage","isToolMessage","ChatGenerationChunk","convertToOpenAITool","JarelaChatModel","fields","lc_namespace","lc_serializable","_provider","provider","_modelId","modelId","_params","params","_boundTools","boundTools","_llmType","name","bindTools","tools","_kwargs","_convertedTools","flatMap","t","oai","function","type","description","parameters","_generate","messages","_options","runManager","invokeMessages","toInvokeMessages","openaiTools","streamInvoke","length","finalChunk","_streamToFinalChunk","gen","message","aiMessageFromChunk","text","content","generations","invoke","result","aiMsg","tool_calls","map","tc","id","args","arguments","providerMessages","filter","m","role","stream","chat","chunk","acc","_streamFromProvider","concat","_streamResponseChunks","msg","tool_call_chunks","i","index","JSON","stringify","emittedAny","stopReason","event","handleLLMNewToken","delta","additional_kwargs","reasoning_content","args_delta","reason","Error","console","warn","empty_stream_reason","stop_reason","invalid_tool_calls","lcContentToInvoke","Array","isArray","parts","block","push","b","url","image_url","dataUrl","startsWith","exec","media_type","data","src","source","every","p","join","ai","invokeMsg","reasoning","tool_call_id","BaseStore","getMemory","putMemory","deleteMemory","listMemory","SqliteMemoryStore","batch","operations","results","Promise","all","op","ns","namespace","row","key","value","parse","_raw","createdAt","Date","created_at","updatedAt","updated_at","undefined","prefix","namespacePrefix","limit","rows","r","split","DatabaseSync","BaseCheckpointSaver","TASKS","copyCheckpoint","maxChannelVersion","VALID_FILTER_KEYS","buildLatestSelect","includeCheckpointId","nv","v","NodeSqliteSaver","db","serde","isSetup","fromConnString","connStringOrLocalPath","setup","withoutCheckpoint","prepare","withCheckpoint","txn","fn","err","decodeRowState","pendingWrites","String","pending_writes","write","task_id","channel","loadsTyped","checkpoint","parent_checkpoint_id","migratePendingSends","thread_id","metadata","getTuple","config","checkpoint_ns","checkpoint_id","configurable","stmt","get","finalConfig","parentConfig","list","options","before","sql","whereClause","sanitizedFilter","Object","fromEntries","entries","includes","parseInt","values","put","preparedCheckpoint","type1","serializedCheckpoint","type2","serializedMetadata","dumpsTyped","run","putWrites","writes","taskId","idx","serializedWrite","deleteThread","threadId","parentCheckpointId","pendingSendsJson","pending_sends","mutable","channel_values","channel_versions","keys","getNextVersion","getDataDir","CHECKPOINT_PATH","_saver","getCheckpointer","createReactAgent","HumanMessage","SystemMessage","ToolMessage","getProvider","getModelConfig","getDefaultModelConfig","getAllToolsAsync","getConfig","toBaseMessages","systemPrompt","base","blocks","part","streamWithConfig","signal","runCfg","agent_run_config","cfgName","model_config_name","cfg","code","toolPolicy","allowed_tools","allow","tool_policy","model","model_id","store","checkpointer","test","error","agent","llm","announcedToolIds","Set","pendingAIChunk","totalOutputTokens","truncatedByLength","needsParagraphBreak","textEmittedSinceLastBreak","flushPendingToolCalls","calls","has","add","agentStream","system_prompt","streamMode","recursionLimit","mode","payload","baseMsg","stack","causeChain","cur","depth","c","cause","cMsg","cCode","rawMsg","aborted","message_id","now","usage","input_tokens","output_tokens","friendly","firstAppFrame","find","l","trimmed","trim","getDb","toISOString","UPSERT_SQL","recordToolUsage","toolEvents","assistantContent","deltas","summarizeToolUsage","stamp","successes","errors","used","listToolStats","getToolStatsMap","names","out","Map","set","tool_name","toStats","defaultToolStats","call_count","success_count","error_count","used_count","success_rate","usefulness_rate","score","never_used","last_called_at","Math","max","successRate","clamp01","usefulnessRate","byId","assistantTerms","normalizeText","ev","phase","existing","successful","isErrorPayload","payloadLooksUsed","totals","outcome","next","size","candidates","extractPayloadTerms","matched","term","raw","stringifyPayload","unique","token","toLowerCase","status","min","MBTI_PRESETS","buildAdaptivePersonaContext","userMessage","adaptive_persona_enabled","mbti","toMbti","adaptive_mbti","mbtiLabel","label","strength","clampPercent","adaptive_persona_strength","empathy","adaptive_empathy","expressiveness","adaptive_expressiveness","verbosity","adaptive_verbosity","detectSignals","intensity","targetEmpathy","round","frustration","urgency","positivity","targetExpressive","targetVerbosity","empathyBand","bandLabel","expressiveBand","verbosityBand","directives","mood","d","lower","frustrationHits","countMatches","urgencyHits","positivityHits","terms","n","Number","isFinite","cutoffs","labels","HARNESS_SECTION_KEYS","BUILTIN_HARNESS_ID_PREFIX","CUSTOM_HARNESS_ID_PREFIX","DEFAULT_HARNESS_ID","isBuiltinHarnessId","SECTION_DISPLAY","capabilities","title","hint","plan_first","presentation","citation","self_config","getAppName","APP_NAME","CAPABILITIES_BODY","PLAN_FIRST_BODY","SELF_CONFIG_BODY","PRESENTATION_BODY","CITATION_BODY","BUILTIN_HARNESSES","builtin","sections","enabled","body","getBuiltinHarness","h","randomUUID","NS","CUSTOMS_KEY","DEFAULT_KEY","readJson","writeJson","created","deleteKey","sanitizeSections","input","obj","k","s","listCustomHarnesses","item","writeCustomHarnesses","listAllHarnesses","getHarness","getDefaultHarnessId","setDefaultHarnessId","createCustomHarness","harness","updateCustomHarness","findIndex","prev","deleteCustomHarness","resolveHarness","agentCfg","harness_id","section","ACTION_VERBS","VERB_GROUP","PATTERNS","RegExp","FUTURE_PATTERNS","findActionClaims","seen","re","lastIndex","verb","start","window","slice","some","f","VIA_RE","findCitations","tool","SUMMARY_PATTERNS","validateAssistantOutput","toolCalls","allowedTools","calledSet","allowedSet","citations","ok","kind","evidence","claims","match","addMessage","getRecentMessagesWindow","getThread","touchThread","getAgentConfig","getUserProfile","startScheduler","recall","listIntegrations","os","RunThreadError","RECALL_BUDGET_MS","raceWithBudget","promise","ms","fallback","resolve","settled","setTimeout","then","clearTimeout","MAX_STALL_AUTO_RETRIES","parseContent","parsed","contentText","prepareThreadRun","attachments","_stallRetriesLeft","userCategory","thread","agent_id","stored","history_limit","windowHours","history_window_hours","sinceISO","history","userProfile","userCtxParts","about","location_consent","location_lat","location_lng","ageSec","location_updated_at","ageStr","location_accuracy_m","location_label","toFixed","userCtx","timeCtx","envCtx","process","platform","arch","cwd","homedir","Boolean","configuredIntegrations","configured","integrationsCtx","email","memoryCtx","oldestInWindow","recallCtx","buildRecallContext","adaptivePersonaCtx","harnessParts","systemParts","identity","instructions","streamOpts","rawStream","stallRetryStream","inner","retriesLeft","textBuf","toolNames","doneChunk","sawError","stalled","looksLikeStall","fabrication","nudge","retry","persistAssistantMessage","usedTools","category","final","toolList","from","lookupAllowedToolsForThread","sanitizedEvents","capToolEventPayload","persisted","stripAutoplayHints","replace","_full","query","cleaned","MAX_PERSISTED_PAYLOAD_BYTES","serialized","__truncated","preview","original_bytes","STALL_PATTERNS","tail","current_thread_id","windowOldestContent","hits","filtered","lines","truncate","tag","flat","shouldEmitChunk","chunkType","includeTools","filters","include_tools","includeThinking","include_thinking","normaliseReactionPrompt","normaliseReactionScriptArgs","resolveReaction","validateReactionScript","MIN_INTERVAL_SECONDS","clampInterval","seconds","floor","createWatcher","interval","interval_seconds","argsJson","tool_args","silent","reaction","prompt","script","scriptArgs","last_fingerprint","last_result","last_run_at","last_fired_at","last_error","next_run_at","reaction_prompt","reaction_kind","reaction_script","reaction_script_args","listWatchers","agentId","getWatcher","getDueWatchers","asOf","deleteWatcher","changes","updateWatcher","patch","nextRunAt","recordWatcherPoll","fingerprint","fired","recordWatcherPollError","parseJsonSafe","CATEGORY_GROUPS","Memory","Documents","Files","Shell","Web","Images","Voice","Schedule","Config","Mail","Calendar","Atlassian","JiraAlign","GitHub","REGISTRY","registerTools","group","registeredTools","e","registeredNames","registeredCategory","registeredGroup","_resetRegistry","clear","getIntegrationRaw","createOAuthFlowStore","flowStore","globalKey","createFlow","create","getFlow","updateFlow","update","deleteFlow","delete","GMAIL_SCOPES","buildAuthorizeUrl","opts","URLSearchParams","client_id","clientId","redirect_uri","redirectUri","response_type","scope","access_type","include_granted_scopes","state","toString","exchangeCode","client_secret","clientSecret","grant_type","res","fetch","method","headers","AbortSignal","timeout","resolveGoogleAuth","envId","env","GMAIL_CLIENT_ID","envSecret","GMAIL_CLIENT_SECRET","envRefresh","GMAIL_REFRESH_TOKEN","refresh_token","saved","accessTokenCache","getGoogleAccessToken","auth","cached","expires_at","access_token","expires_in","googleFetch","service","baseUrl","path","init","Authorization","Accept","z","isLikelyBinary","_resolveGithubAuth","resolveAuth","GITHUB_TOKEN","GH_TOKEN","API","ghFetch","_ghFetch","BODY_CAP","COMMENT_CAP","PATCH_CAP","SNIPPET_CAP","cap","truncated","decodeContentsBlob","encoding","binary","size_bytes","b64","buf","Buffer","liteUser","u","login","liteLabels","githubSearchIssuesTool","q","repo","max_results","encodeURIComponent","total","total_count","items","number","is_pr","pull_request","html_url","user","comments","schema","object","string","describe","optional","githubGetIssueTool","owner","assignees","a","author","closed_at","int","positive","githubCreateIssueTool","array","githubAddCommentTool","comment_id","githubListPullsTool","head","per_page","pulls","draft","ref","enum","githubGetPullTool","merged","mergeable","mergeable_state","sha","full_name","changed_files","additions","deletions","review_comments","merged_at","githubGetRepoTool","visibility","private","default_branch","topics","language","stars","stargazers_count","forks","forks_count","open_issues","open_issues_count","archived","pushed_at","githubUpdateIssueTool","state_reason","updated_fields","githubListIssueCommentsTool","githubCreatePullTool","maintainer_can_modify","boolean","githubUpdatePullTool","githubMergePullTool","commit_title","commit_message","merge_method","merged_sha","githubRequestReviewersTool","reviewers","team_reviewers","requested_users","requested_reviewers","requested_teams","slug","githubCreateReviewTool","commit_id","review_id","githubListPullFilesTool","files","filename","previous_filename","patch_truncated","githubListPullReviewsTool","reviews","submitted_at","githubListBranchesTool","branches","commit_sha","commit","protected","githubGetFileTool","decoded","githubSearchCodeTool","fragment","text_matches","snip","repository","snippet","snippet_truncated","listDocumentSources","listEnabledDocumentSources","getDocumentSource","getDocumentSourceByPath","createDocumentSource","last_scan_at","last_cursor","parseSourceConfig","updateDocumentSourceCursor","cursor","updateDocumentSource","deleteDocumentSource","markSourceScanned","getDocumentSourceStats","sourceId","docs","chunks","embedded","source_id","document_count","chunk_count","embedded_chunk_count","CronExpressionParser","computeNextRun","schedule","after","ts","isNaN","getTime","it","currentDate","toDate","createScheduledTask","listScheduledTasks","getScheduledTask","getDueTasks","deleteScheduledTask","updateScheduledTask","nextKind","nextSchedule","nextPrompt","markTaskRan","nextRun","randomBytes","getOrCreateGlobal","DEFAULT_TTL_MS","DEFAULT_MAX_FLOWS","ttlMs","maxFlows","flows","gc","oldest","sort","flow","assign","adfToText","adf","walk","node","htmlToText","html","createHash","chunkAndEmbedDocument","findExisting","isoToMtime","iso","digest","readUInt32BE","hashContent","upsertRemoteDocument","hash","mtime","externalUpdatedAt","content_hash","embedError","docId","byteLength","evictMissing","keepPaths","removed","del","_atlassianFetch","_resolveAtlassianAuth","PAGE_LIMIT","MAX_PAGES_PER_RUN","buildCql","since","clauses","space_key","cql","recency_days","pageUpdatedAt","version","when","lastUpdated","createdDate","fetchPage","pageId","runConfluenceIndexer","stats","scanned","added","updated","unchanged","embedFailed","highWater","page","storage","indexConfluencePageById","stripHtml","truncateBytes","graphFetch","resolveMicrosoftAuth","DEFAULT_MAX_RESULTS","DEFAULT_PAGE_SIZE","MAX_RESULTS_CAP","header","hit","decodeBase64Url","findPart","mime","mimeType","child","extractGmailBody","plain","preserveParagraphs","recipientToStr","addr","emailAddress","address","summarizeGraphMessage","to","toRecipients","cc","ccRecipients","bodyPreview","contentType","capped","subject","receivedDateTime","line","lastModifiedDateTime","gmailSourceConfig","page_size","outlookSourceConfig","indexGmailMail","keep","pageToken","qs","maxResults","entry","internalDate","nextPageToken","indexOutlookMail","nextLink","ConsistencyLevel","summary","runMailIndexer","MAX_ISSUES_PER_RUN","buildJql","project_key","jql","formatJqlDate","pad","padStart","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","flattenIssue","issue","desc","comment","displayName","fetchIssue","runJiraIndexer","issues","indexJiraIssueByKey","ALLOWED_EXT","lowerExt","PR_PAGE_LIMIT","MAX_PRS_PER_RUN","MAX_FILES_PER_RUN","MAX_FILE_BYTES","ghError","liteAuthor","flattenPull","pr","listIssueComments","listReviews","emptyStats","applyUpsert","runGithubPullsIndexer","cutoffMs","sinceMs","NaN","outer","updatedMs","resolveDefaultBranch","runGithubRepoIndexer","tree","treeSha","path_prefix","blobs","contents","runGithubIndexer","indexGithubPullByUrl","indexGithubIssueByUrl","indexGithubFileByUrl","isRemoteKind","runRemoteSource","lastError","composite","ON_DEMAND_PATH","getOrCreateOnDemandSource","indexOnDemand","bareKey","identifier","browse","pages","ghPull","ghIssue","ghBlob","cleanPath","RECENT_LIMIT","busState","listeners","recent","publish","shift","subscribe","recentSince","sinceTs","TENANT","OUTLOOK_TENANT","MICROSOFT_SCOPES","response_mode","OUTLOOK_CLIENT_ID","OUTLOOK_CLIENT_SECRET","OUTLOOK_REFRESH_TOKEN","getMicrosoftAccessToken","embedOne","MSG_COLS_SQL","listThreads","offset","listThreadsByAgent","createThread","message_count","getMessages","reverse","getMessagesAfter","afterISO","getMessagesPage","beforeISO","has_more","msg_id","toolEventsJson","vec","catch","tool_events","getOrCreateAgentThread","clearThreadMessages","firstMsg","isUserPreset","upsertUserProfile","icon","setLocationConsent","consent","updateUserLocation","lat","lng","accuracy_m","setUserPreset","preset","indexAllSources","runTriggerTick","runScheduledTaskFiringNow","POLL_INTERVAL_MS","JARELA_SCHEDULER_TICK_MS","DOC_SWEEP_EVERY_TICKS","started","timer","running","tickCount","setImmediate","tick","setInterval","unref","stopScheduler","clearInterval","runScheduledTaskNow","task","DEFAULT_APP_NAME","DEFAULT_APP_DESCRIPTION","DEFAULT_ISSUE_URL","NEXT_PUBLIC_APP_NAME","getAppDescription","NEXT_PUBLIC_APP_DESCRIPTION","getAppIssueUrl","NEXT_PUBLIC_APP_ISSUE_URL","DEFAULTS","port","hostname","voiceTimeoutMs","imageTimeoutMs","parsePositiveInt","parsePort","expandHome","dataDir","JARELA_PORT","PORT","JARELA_HOSTNAME","HOSTNAME","toolsDir","JARELA_TOOLS_DIR","JARELA_RECURSION_LIMIT","JARELA_VOICE_TIMEOUT_MS","JARELA_IMAGE_TIMEOUT_MS","appName","appDescription","issueUrl","resetConfigCache","memoryReadTool","memoryWriteTool","memoryListTool","search","cosine","searchDocuments","limitRows","qVec","scored","lowered","embedding","substringScore","document_id","source_label","rel_path","abs_path","chunk_index","haystack","needleLower","hay","tokens","promises","fs","notifyTriggerHandlers","documentsSearch","documentsListSources","sources","documentsAddLocalSource","inputPath","abs","st","stat","isDirectory","note","REMOTE_KINDS","syntheticPath","validateRemoteConfig","documentsAddRemoteSource","record","unknown","documentsRemoveSource","confirm","documentsReindexSource","documentsIndexUrl","execSync","getInjectedSubprocessEnv","MAX_OUTPUT_BYTES","DEFAULT_TIMEOUT_MS","MAX_TIMEOUT_MS","BLOCKED_PATTERNS","isBlockedCommand","command","pattern","clipOutput","runLocalCommand","exit_code","stderr","timeout_ms","allow_unsafe","output","maxBuffer","stdio","clipped","stdout","errText","execSchema","localExecTool","shellExecTool","MAX_READ_BYTES","MAX_WRITE_BYTES","MAX_LIST_JSON_BYTES","clip","resolvePath","isAbsolute","isInside","parent","rel","relative","sensitiveBase","home","sensitiveFiles","jarelaDataDir","JARELA_DB_DIR","assertSafePath","JARELA_ALLOW_SENSITIVE_FILES","basename","endsWith","readSchema","start_line","end_line","fileReadTool","filePath","readFile","lineRange","end","line_range","total_lines","writeSchema","create_dirs","fileWriteTool","mkdir","dirname","recursive","existed","access","writeFile","bytes_written","editSchema","old_string","new_string","fileEditTool","first","indexOf","second","match_count","bytes_before","bytes_after","moveSchema","destination","overwrite","fileMoveTool","srcAbs","dstAbs","srcStat","dstStat","rename","cp","force","errorOnExist","rm","cross_device","err2","listSchema","max_entries","include_hidden","fileListTool","dirPath","readdir","withFileTypes","localeCompare","full","isFile","build","es","droppedForSize","count","total_in_dir_after_filters","truncated_hint","dropped_for_size","lo","hi","mid","mkdirSchema","fileMkdirTool","deleteSchema","fileDeleteTool","targetPath","rmdir","unlink","copySchema","fileCopyTool","copyFile","statSchema","fileStatTool","exists","modified_ms","mtimeMs","created_ms","birthtimeMs","tavilySearch","apiKey","api_key","search_depth","json","UA_POOL","ddgSearch","lastStatus","attempt","ua","parseDDGHtml","blockRe","titleMatch","snippetMatch","unwrapDDGRedirect","decodeHTML","stripTags","href","URL","pathname","real","searchParams","decodeURIComponent","webSearchTool","tavilyKey","TAVILY_API_KEY","dns","net","ipv4InCidr","bits","mask","ipv4ToNumber","ip","isInteger","classifyIPv4","classifyIPv6","bare","v4","isIPv4","classifyAddress","isIPv6","isPrivateAddress","cls","checkPublicUrl","rawUrl","JARELA_ALLOW_PRIVATE_FETCH","allowed","protocol","host","isIP","resolved","addrs","lookup","MAX_BYTES","TIMEOUT_MS","MAX_REDIRECTS","extractTitle","extractImages","og","twitter","samples","matchAll","resolveUrl","webFetchTool","max_chars","ctrl","AbortController","abort","initialCheck","currentUrl","hop","redirect","loc","hopCheck","finalUrl","reader","getReader","decoder","TextDecoder","bytesRead","done","read","decode","cancel","wantHtml","images","content_type","bytes_read","getUserLocationTool","profile","available","how_to_enable","ageMs","age_seconds","mkdirSync","writeFileSync","FILES_DIR","SAFE_NAME","isSafeFileName","fileAbsPath","writeBinaryFile","timeoutSignal","resolveGoogleApiKey","fromStore","GEMINI_API_KEY","GOOGLE_API_KEY","DEFAULT_MODEL","ENDPOINT","callGemini","generationConfig","responseModalities","describeError","inline","inlineData","inline_data","mime_type","callImagen","aspect","instances","sampleCount","aspectRatio","preds","predictions","bytesBase64Encoded","extForMime","generateImageTool","aspect_ratio","img","bytes","markdown","GEMINI_VOICES","GEMINI_TTS_MODELS","GEMINI_STT_MODELS","resolveGoogleApiKeyShared","geminiTts","style","spoken","speakers","voiceName","speechConfig","multiSpeakerVoiceConfig","speakerVoiceConfigs","speaker","voiceConfig","prebuiltVoiceConfig","pcm","rate","parseSampleRate","wav","pcmToWav","geminiStt","audio","sampleRate","channels","bitsPerSample","byteRate","blockAlign","dataSize","alloc","writeUInt32LE","writeUInt16LE","DEFAULT_VOICE","MAX_TEXT_CHARS","SpeakerSchema","voice_name","resolveAgentVoice","voice","voice_model","generateVoiceTool","autoplay","speakerList","safeJson","agentIdFromConfig","scheduleTaskTool","when_iso","cron","firstRun","listScheduledTasksTool","_args","tasks","cancelScheduledTaskTool","listReactionScripts","scheduleWatcherTool","toolName","every_seconds","target","listReactionScriptsTool","scripts","listWatchersTool","watchers","w","safeParse","cancelWatcherTool","createPendingAction","getPendingAction","listPendingActions","setActionStatus","publishNotification","proposeConfigChangeTool","proposal_id","checkProposalTool","decided_at","atlassianManifest","prerequisites","check","detail","docs_url","steps","proposes","troubleshooting","say","githubManifest","gmailManifest","verify","googleManifest","outlookManifest","PrerequisiteSchema","SetupStepSchema","TroubleshootingSchema","IntegrationManifestSchema","regex","validateManifest","RAW","MANIFESTS","listManifests","getManifest","manifestIds","getIntegrationStatus","isKnownIntegration","manifestStatus","listIntegrationsTool","integrations","getIntegrationSetupTool","manifest","notes","TYPE_TO_COLLECTION","epic","capability","feature","story","theme","defect","objective","KNOWN_TYPES","TYPE_ENUM","collectionFor","seg","_resolveJiraAlignAuth","envUrl","JIRA_ALIGN_URL","envToken","JIRA_ALIGN_TOKEN","stripTrailingSlash","apiToken","api_token","jaFetch","summarizeItem","parent_id","parentId","parentID","program_id","programId","programID","team_id","teamId","teamID","release_id","releaseId","releaseID","sprint_id","sprintId","sprintID","ownerEmail","createDate","jiraAlignGetItemTool","item_id","collection","jiraAlignSearchItemsTool","updated_since","escapeOData","normalizeDate","next_page_token","jiraAlignListChildrenTool","child_type","jiraAlignCreateItemTool","jiraAlignUpdateItemTool","jiraAlignTransitionItemTool","wf","item_type","available_states","states","jiraAlignDeleteItemTool","deleted_id","jiraAlignAddCommentTool","ENTITY_TO_COLLECTION","program","team","release","sprint","portfolio","value_stream","KNOWN_ENTITIES","ENTITY_ENUM","entityCollectionFor","entity_type","summarizeEntity","portfolio_id","portfolioId","portfolioID","start_date","startDate","end_date","endDate","active","isActive","jiraAlignListEntitiesTool","name_filter","jiraAlignGetEntityTool","entity_id","unitMs","_resolveGmailAuth","GMAIL_BASE","gmailFetch","extractBody","MAX_BODY_BYTES","x","buildRawMessage","bcc","encodeSubject","in_reply_to","references","gmailSearchTool","ids","result_size_estimate","resultSizeEstimate","details","date","labelIds","gmailGetMessageTool","gmailListLabelsTool","gmailModifyMessageTool","add_labels","remove_labels","addLabelIds","removeLabelIds","gmailCreateDraftTool","in_reply_to_id","prevRefs","draft_id","gmailTrashMessageTool","CALENDAR_BASE","calendarFetch","slimEvent","location","dateTime","time_zone","timeZone","attendees","response","responseStatus","meet_link","hangoutLink","html_link","htmlLink","calendarListCalendarsTool","calendars","primary","access_role","accessRole","calendarListEventsTool","calendar_id","time_min","time_max","cal","singleEvents","orderBy","inAWeek","events","calendarGetEventTool","event_id","eid","calendarCreateEventTool","start_iso","end_iso","add_meet_link","conferenceData","createRequest","requestId","random","conferenceSolutionKey","calendarUpdateEventTool","calendarDeleteEventTool","_resolveOutlookAuth","summarizeMessage","conversation_id","conversationId","received","is_read","isRead","is_draft","isDraft","has_attachments","hasAttachments","categories","folder_id","parentFolderId","web_link","webLink","outlookSearchTool","top","$top","$select","next_link","outlookGetMessageTool","rawBody","outlookListFoldersTool","folders","totalItemCount","unread","unreadItemCount","well_known","wellKnownName","outlookModifyMessageTool","mark_read","move_to_folder","lastResult","destinationId","outlookCreateDraftTool","outlookTrashMessageTool","new_id","is_all_day","isAllDay","is_cancelled","isCancelled","show_as","showAs","teams_link","onlineMeeting","joinUrl","outlookCalendarListCalendarsTool","is_default","isDefaultCalendar","can_edit","canEdit","outlookCalendarListEventsTool","startISO","endISO","startDateTime","endDateTime","$orderby","Prefer","outlookCalendarGetEventTool","outlookCalendarCreateEventTool","add_teams_link","tz","isOnlineMeeting","onlineMeetingProvider","outlookCalendarUpdateEventTool","outlookCalendarDeleteEventTool","encrypt","decryptIfNeeded","decryptRow","spec","listMcpServers","getMcpServer","upsertMcpServer","transport","deleteMcpServer","setMcpServerError","cachedTools","cacheKey","pending","activeClient","specHash","getMcpTools","close","MultiServerMCPClient","subClients","serverConfig","buildSubprocessEnv","client","mcpServers","throwOnLoadError","serverTools","getTools","allSettled","invalidateMcpTools","SCRUBBED_VARS","userEnv","NAMESPACE","NAME_RE","validName","compoundKey","parseStored","getToolSecret","setToolSecret","deleteToolSecret","describeToolSecrets","slots","is_set","purgeToolSecrets","existsSync","readdirSync","statSync","getToolsDir","isValidSlot","o","required","isValid","secrets","loadExternalTools","builtinNames","createRequire","getBuiltinModule","req","mod","cache","file","candidate","default","def","wrapped","_runManager","ctx","getSecret","isCategoryEnabled","disabledCategories","listCategoryStates","setCategoryEnabled","ALL_BUILTINS","BUILTIN_TOOL_NAMES","loadExternal","getToolCategory","ext","getToolGroup","cat","applyPolicy","policy","allowSet","denySet","deny","applyCategoryToggles","disabled","getAllTools","mcpTools","toOpenAITools","executeTool","context","_initialized","initTools","builtinCount","externalCount","info","listAgentConfigs","getDefaultAgentConfig","upsertAgentConfig","harnessId","never_reply","voice_enabled","voice_stt_model","voice_auto_speak","deleteAgentConfig","generateAgentId","suffix","DISPLAY_FILTER_KEYS","DISPLAY_FILTER_DEFAULTS","scheduled_task","watcher","bridge","synthetic","tool_use","thinking","parseDisplayFilters","getAgentDisplayFilters","display_filters","updateAgentDisplayFilters","current","maxBytes","ATLASSIAN_URL","envEmail","ATLASSIAN_EMAIL","ATLASSIAN_API_TOKEN","authHeader","atlassianFetch","jiraSearchTool","fieldList","assignee","priority","jiraGetIssueTool","issue_key","expand","custom_fields","include_comments","resolvedCustom","loadJiraFields","resolveCustomFieldNames","unresolved","custom","hint_first_25_custom_fields","expandSet","baseFields","rendered","renderedFields","customOut","extractFieldValue","issueLinks","issuelinks","inward","inwardIssue","outward","outwardIssue","direction","other_issue","remoteLinks","rl","simplifyADF","issuetype","reporter","components","comments_count","subtasks","issue_links","attachment","content_url","remote_links","jiraCreateIssueTool","issue_type","parent_key","assignee_account_id","project","textToADF","accountId","jiraAddCommentTool","jiraFindUserTool","users","account_id","display_name","jiraUpdateIssueTool","assignee_email","fix_versions","labels_add","labels_remove","fixVersions","inputs","ops","remove","exact","picked","nullable","jiraTransitionsTool","transition_name","available_transitions","transitions","transition","transitioned_to","jiraLinkIssuesTool","from_issue","to_issue","link_type","types","issueLinkTypes","available_link_types","wanted","reads_as","bulkIssueSchema","jiraCreateIssuesBulkTool","anyCustom","loaded","issueUpdates","jiraAddRemoteLinkTool","icon_url","global_id","url16x16","globalId","remote_link_id","jiraDeleteLinkTool","link_id","deleted","jiraUploadAttachmentTool","content_base64","content_text","form","FormData","append","Blob","jiraDeleteIssueTool","delete_subtasks","SPRINT_STATES","validateSprintTransition","jiraListBoardsTool","boards","projectKey","is_last","isLast","jiraGetBoardTool","board_id","meta","configuration","filter_id","sub_query","subQuery","estimation_field","estimation","field","fieldId","ranking_field","ranking","rankCustomFieldId","union","jiraListSprintsTool","sprints","goal","complete_date","completeDate","origin_board_id","originBoardId","jiraGetSprintTool","jiraCreateSprintTool","jiraUpdateSprintTool","current_state","legal_next_states","jiraDeleteSprintTool","deleted_sprint_id","jiraMoveIssuesToSprintTool","issue_keys","moved","jiraMoveIssuesToBacklogTool","moved_to_backlog","jiraRankIssuesTool","rank_before_issue","rank_after_issue","rank_custom_field_id","rankBeforeIssue","rankAfterIssue","ranked","relative_to","jiraGetCommentsTool","start_at","order_by","startAt","jiraUpdateCommentTool","jiraDeleteCommentTool","deleted_comment_id","jiraGetAttachmentContentTool","as_text","fullUrl","ct","looksText","as","arrayBuffer","jiraDeleteAttachmentTool","attachment_id","deleted_attachment_id","jiraAddWorklogTool","time_spent","timeSpent","worklog_id","jiraListWorklogsTool","worklogs","time_spent_seconds","timeSpentSeconds","jiraGetChangelogTool","changelog","field_type","fieldtype","hasOwn","fromString","jiraListProjectsTool","category_id","projects","type_key","projectTypeKey","lead","jiraGetProjectTool","include_versions","include_components","include_issue_types","versions","released","release_date","releaseDate","issue_types","issueTypes","subtask","hierarchy_level","hierarchyLevel","jiraListVersionsTool","jiraCreateVersionTool","proj","projectId","version_id","jiraUpdateVersionTool","jiraListComponentsTool","assignee_type","assigneeType","jiraCreateComponentTool","lead_account_id","leadAccountId","component_id","META_KIND_TO_PATH","resolution","META_KINDS","jiraListMetaTool","available_kinds","status_category","statusCategory","confluenceSearchTool","_links","webui","confluenceGetPageTool","page_id","storageVal","viewVal","view","links","space_id","spaceId","body_storage","body_storage_truncated","body_view","body_view_truncated","confluenceGetPageByTitleTool","include_body","sid","resolveSpaceId","matches","confluenceGetPageChildrenTool","children","position","next_cursor","parseV2NextCursor","confluenceGetPageAncestorsTool","ancestors","confluenceListSpacesTool","spaces","homepage_id","homepageId","confluenceGetCommentsTool","include_inline","footerData","flatten","ver","author_id","authorId","parent_comment_id","parentCommentId","footer_comments","inline_comments","inline_warning","confluenceListAttachmentsTool","mediaType","file_size","fileSize","download_link","downloadLink","webui_link","confluenceGetLabelsTool","confluenceGetAttachmentContentTool","confluenceCreatePageTool","body_text","resolveBody","representation","confluenceUpdatePageTool","version_number","version_message","nextVersion","resolvedTitle","confluenceAddCommentTool","confluenceMovePageTool","target_id","confluenceUploadAttachmentTool","minor_edit","extensions","confluenceAddLabelTool","total_labels","confluenceDeletePageTool","purge","deleted_page_id","purged","COMMENT_KIND_TO_PATH","footer","confluenceUpdateCommentTool","segment","confluenceDeleteCommentTool","confluenceRemoveLabelTool","removed_label","confluenceDeleteAttachmentTool","confluenceTextToStorage","escape","para","linksNext","hasText","hasStorage","SPACE_ID_CACHE_TTL_MS","spaceIdCache","spaceKey","FIELD_CACHE_TTL_MS","fieldCache","byName","renderedHTML","coerceItem","walkChildren","isReactionScript","REACTION_SCRIPT_PREFIX","MAX_REACTION_PROMPT_CHARS","MAX_REACTION_SCRIPT_ARGS_CHARS","MAX_CHARS","OVERLAP_CHARS","chunkText","paragraphs","start_offset","end_offset","pos","sep","embedBestEffort","SKIP_DIRS","MAX_FILES_PER_SOURCE","MAX_INDEX_PER_TICK_PER_SOURCE","lastIndexOf","len","suspicious","root","visit","dir","mtime_ms","listIndexedDocs","listUnembeddedChunks","documentId","backfillDocumentEmbeddings","missing","vectors","updateEmb","readTextFile","indexSource","indexed","onDisk","maxThisRun","maxFiles","processed","upsertLocalDocument","embed_failed","embed_error","existingId","writeId","winner","_label","insertChunk","chunkIds","maxFilesPerSource","handlers","registerTriggerHandler","handler","getTriggerHandler","listTriggerHandlers","__resetTriggerRegistry","collectStream","terminal","onChunk","errorMessage","getScript","runTriggerAgent","firing","effectivePrompt","prepared","collected","replyText","isNoReply","skipAssistant","runTriggerScript","runTriggerFiring","SCHEDULED_TASK_KIND","buildFiring","userArgs","schedule_kind","scheduleKind","scheduledTaskHandler","getDueFirings","markFired","scriptName","firingForTaskId","WATCHER_KIND","stringifyResult","DEFAULT_REACTION_DIRECTIVE","buildFiringPrompt","previous","argsPretty","directive","buildScriptArgs","invokeWatcherTool","pollDueWatchers","due","firings","fp","changed","watcherHandler","firingForWatcherIdNow","registerScript","reindexLocalFile","registered","registerDocumentScripts","watch","fsWatch","FS_WATCH_KIND","DEBOUNCE_MS","unsupportedLogged","pendingKey","enqueuePending","scheduleDebounce","debounceTimers","handleEvent","segments","rootPath","attachWatcher","persistent","_event","on","detachWatcher","syncWatchers","wantSourceIds","drainPending","fsWatchHandler","sync","stop","_asOf","__resetFsWatchState","__pushEventForTest","DOCUMENT_FAST_SWEEP_KIND","DEFAULT_INTERVAL_MS","intervalMs","JARELA_FAST_REMOTE_SWEEP_MS","lastRunAt","scriptRegistered","registerSweepScript","documentFastSweepHandler","last","__resetFastSweepState","shortPreview","left","right","registerHandlers","startAllTriggerHandlers","stopAllTriggerHandlers","_reason","innerErr","runWatcherFiringNow","watcherId","listScripts","decodeHtmlEntities","__resetScriptRegistry"],"sourceRoot":"","ignoreList":[]}