@ashx-j/lunr 0.2.8 → 0.2.9

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 (127) hide show
  1. package/dist/builtin-extensions/ashxj-spinners.d.ts +7 -0
  2. package/dist/builtin-extensions/ashxj-spinners.d.ts.map +1 -1
  3. package/dist/builtin-extensions/ashxj-spinners.js +40 -3
  4. package/dist/builtin-extensions/ashxj-spinners.js.map +1 -1
  5. package/dist/builtin-extensions/ashxj-tui.d.ts +4 -0
  6. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  7. package/dist/builtin-extensions/ashxj-tui.js +44 -0
  8. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  9. package/dist/builtin-extensions/lunr-behavior.d.ts +2 -1
  10. package/dist/builtin-extensions/lunr-behavior.d.ts.map +1 -1
  11. package/dist/builtin-extensions/lunr-behavior.js +26 -14
  12. package/dist/builtin-extensions/lunr-behavior.js.map +1 -1
  13. package/dist/builtin-extensions/lunr-todos.d.ts +4 -7
  14. package/dist/builtin-extensions/lunr-todos.d.ts.map +1 -1
  15. package/dist/builtin-extensions/lunr-todos.js +18 -10
  16. package/dist/builtin-extensions/lunr-todos.js.map +1 -1
  17. package/dist/builtin-extensions/pi-subagents/src/agents/agent-management.d.ts.map +1 -1
  18. package/dist/builtin-extensions/pi-subagents/src/agents/agent-management.js +3 -3
  19. package/dist/builtin-extensions/pi-subagents/src/agents/agent-management.js.map +1 -1
  20. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  21. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +2 -2
  22. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  23. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +2 -2
  24. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  25. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +3 -4
  26. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  27. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  28. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +6 -18
  29. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  30. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  31. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +13 -5
  32. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  33. package/dist/builtin-extensions/pi-subagents/src/shared/lunr-child-context.d.ts +21 -0
  34. package/dist/builtin-extensions/pi-subagents/src/shared/lunr-child-context.d.ts.map +1 -0
  35. package/dist/builtin-extensions/pi-subagents/src/shared/lunr-child-context.js +22 -0
  36. package/dist/builtin-extensions/pi-subagents/src/shared/lunr-child-context.js.map +1 -0
  37. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  38. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +2 -1
  39. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  40. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  41. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +10 -18
  42. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  43. package/dist/builtin-extensions/pi-web-access/render-search-error.d.ts.map +1 -1
  44. package/dist/builtin-extensions/pi-web-access/render-search-error.js +1 -1
  45. package/dist/builtin-extensions/pi-web-access/render-search-error.js.map +1 -1
  46. package/dist/catalog/models.json +1 -1
  47. package/dist/catalog/providers/openrouter.json +1 -1
  48. package/dist/catalog/providers/vercel-ai-gateway.json +1 -1
  49. package/dist/catalog/publication.json +3 -3
  50. package/dist/cli/update-cli.d.ts +16 -0
  51. package/dist/cli/update-cli.d.ts.map +1 -0
  52. package/dist/cli/update-cli.js +83 -0
  53. package/dist/cli/update-cli.js.map +1 -0
  54. package/dist/cli.d.ts.map +1 -1
  55. package/dist/cli.js +6 -0
  56. package/dist/cli.js.map +1 -1
  57. package/dist/core/behavior-preset.d.ts +60 -0
  58. package/dist/core/behavior-preset.d.ts.map +1 -0
  59. package/dist/core/behavior-preset.js +257 -0
  60. package/dist/core/behavior-preset.js.map +1 -0
  61. package/dist/core/customize.d.ts +3 -0
  62. package/dist/core/customize.d.ts.map +1 -1
  63. package/dist/core/customize.js +9 -0
  64. package/dist/core/customize.js.map +1 -1
  65. package/dist/core/footer-data-provider.d.ts +12 -1
  66. package/dist/core/footer-data-provider.d.ts.map +1 -1
  67. package/dist/core/footer-data-provider.js +70 -5
  68. package/dist/core/footer-data-provider.js.map +1 -1
  69. package/dist/core/keybindings.d.ts +2 -2
  70. package/dist/core/keybindings.d.ts.map +1 -1
  71. package/dist/core/keybindings.js +1 -1
  72. package/dist/core/keybindings.js.map +1 -1
  73. package/dist/core/model-tiers.d.ts +9 -0
  74. package/dist/core/model-tiers.d.ts.map +1 -1
  75. package/dist/core/model-tiers.js +16 -0
  76. package/dist/core/model-tiers.js.map +1 -1
  77. package/dist/core/settings-manager.d.ts +23 -0
  78. package/dist/core/settings-manager.d.ts.map +1 -1
  79. package/dist/core/settings-manager.js +66 -0
  80. package/dist/core/settings-manager.js.map +1 -1
  81. package/dist/core/tools/bash.d.ts.map +1 -1
  82. package/dist/core/tools/bash.js +1 -3
  83. package/dist/core/tools/bash.js.map +1 -1
  84. package/dist/core/update-check.d.ts +32 -0
  85. package/dist/core/update-check.d.ts.map +1 -0
  86. package/dist/core/update-check.js +112 -0
  87. package/dist/core/update-check.js.map +1 -0
  88. package/dist/core/usage-service.d.ts +24 -1
  89. package/dist/core/usage-service.d.ts.map +1 -1
  90. package/dist/core/usage-service.js +91 -14
  91. package/dist/core/usage-service.js.map +1 -1
  92. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  93. package/dist/gateway/agent-bridge.js +5 -1
  94. package/dist/gateway/agent-bridge.js.map +1 -1
  95. package/dist/gateway/cron.d.ts.map +1 -1
  96. package/dist/gateway/cron.js +5 -1
  97. package/dist/gateway/cron.js.map +1 -1
  98. package/dist/main.d.ts.map +1 -1
  99. package/dist/main.js +13 -1
  100. package/dist/main.js.map +1 -1
  101. package/dist/modes/interactive/components/assistant-message.d.ts +4 -0
  102. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  103. package/dist/modes/interactive/components/assistant-message.js +68 -10
  104. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  105. package/dist/modes/interactive/components/settings-selector.d.ts +13 -0
  106. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  107. package/dist/modes/interactive/components/settings-selector.js +157 -10
  108. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  109. package/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  110. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  111. package/dist/modes/interactive/components/tool-execution.js +9 -0
  112. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  113. package/dist/modes/interactive/interactive-mode.d.ts +4 -1
  114. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  115. package/dist/modes/interactive/interactive-mode.js +82 -3
  116. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  117. package/docs/keybindings.md +1 -1
  118. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  119. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  120. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  121. package/examples/extensions/gondolin/package-lock.json +2 -2
  122. package/examples/extensions/gondolin/package.json +1 -1
  123. package/examples/extensions/sandbox/package-lock.json +2 -2
  124. package/examples/extensions/sandbox/package.json +1 -1
  125. package/examples/extensions/with-deps/package-lock.json +2 -2
  126. package/examples/extensions/with-deps/package.json +1 -1
  127. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"render-search-error.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/render-search-error.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IAClC,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC1C;8EAC0E;IAC1E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC/B,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oEAAoE;IACpE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,qFAAqF;IACrF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,GAAG,SAAS,GAAG,IAAI,GAAG,eAAe,GAAG,IAAI,CA0G3G","sourcesContent":["// @ts-nocheck\n/**\n * Pure, dependency-free renderer for web_search error / cancel results.\n *\n * WHY THIS EXISTS: the upstream web_search `renderResult` (index.ts) early-returns\n * a SINGLE line on the error/cancel path, before the collapsed/expanded branch.\n * That makes Ctrl+O (app.tools.expand) flip `expanded` with zero visible effect —\n * a dead-end with no diagnostics. It also discards the partial search results\n * gathered before the cancel, so even an expandable view would have nothing to show.\n *\n * This module is the single source of truth for the error/cancel render PLAN\n * (plain strings, no theme/ANSI), so it is unit-testable without pi's runtime\n * (@mariozechner/pi-tui Text/Box). index.ts.renderResult delegates to it and only\n * applies theme colors + creates Text/Box components.\n *\n * Contract for callers:\n * const plan = buildSearchErrorPlan(details);\n * if (plan === null) ... // not an error/cancel result; use the normal renderer\n * // collapsed: [statusLine, ...plan.collapsed, plan.expandHint].filter(Boolean)\n * // expanded: plan.expanded\n */\n\nexport interface CancelledQueryDetail {\n\tquery: string;\n\tprovider: string | null;\n\terror: string | null; // null = completed ok; string = per-query error\n\tresultCount: number;\n}\n\nexport interface SearchErrorDetails {\n\t/** The headline error/cancel message, e.g. \"Search curation cancelled (stale).\" */\n\terror?: string;\n\tcancelled?: boolean;\n\tcancelReason?: string;\n\t/** Did the curator browser page ever establish a connection? */\n\tbrowserConnected?: boolean;\n\t/** Age (ms) of the last curator heartbeat at cancel time, if known. */\n\tlastHeartbeatAgeMs?: number | null;\n\t/** Total queries the user requested. */\n\tqueryCount?: number;\n\t/** Partial per-query results gathered before the cancel/error. */\n\tcancelledQueries?: CancelledQueryDetail[];\n\t/** Arbitrary extra diagnostic lines (e.g. URLs, response id) for non-cancel errors\n\t * like fetch_content / get_search_content. Shown in the expanded view. */\n\textraLines?: string[];\n}\n\nexport interface SearchErrorPlan {\n\t/** Full diagnostic block, shown when expanded (Ctrl+O). */\n\texpanded: string[];\n\t/** Short preview lines, shown under the headline when collapsed. */\n\tcollapsed: string[];\n\t/** The \"... (N more lines, ctrl+o to expand)\" hint, or null if nothing is hidden. */\n\texpandHint: string | null;\n}\n\nfunction truncate(text: string, max: number): string {\n\treturn text.length > max ? text.slice(0, max - 1) + \"\\u2026\" : text;\n}\n\n/**\n * Build the error/cancel render plan. Returns null when `details` carries no\n * error/cancel signal (so the caller falls through to the normal success renderer).\n */\nexport function buildSearchErrorPlan(details: SearchErrorDetails | undefined | null): SearchErrorPlan | null {\n\tif (!details || (!details.error && !details.cancelled)) {\n\t\treturn null;\n\t}\n\n\tconst headline = details.error ?? \"Search cancelled.\";\n\tconst queries = details.cancelledQueries ?? [];\n\tconst queryCount = typeof details.queryCount === \"number\" && details.queryCount > 0\n\t\t? details.queryCount\n\t\t: queries.length;\n\tconst done = queries.length;\n\tconst errored = queries.filter(q => q.error).length;\n\n\t// Rich diagnostics only make sense when there is something to diagnose: a\n\t// cancelled/curator result with partial data, OR a non-cancel error that carries\n\t// extra detail (urls/response-id for fetch_content, the failed query for\n\t// get_search_content). A bare argument error (e.g. \"No URL\n\t// provided\") stays a clean single line -- no noise.\n\tconst extras = details.extraLines ?? [];\n\tconst rich = details.cancelled === true || queries.length > 0 || extras.length > 0;\n\tif (!rich) {\n\t\treturn { expanded: [headline], collapsed: [], expandHint: null };\n\t}\n\n\t// --- diagnostics block (expanded): curator/cancel-specific only. For non-cancel\n\t// errors (fetch_content/get_search_content) there is no browser or\n\t// query-curation state to report, so we skip this block and show only Details. ---\n\tconst expanded: string[] = [headline, \"\"];\n\n\tif (details.cancelled === true || queries.length > 0) {\n\t\tconst diag: string[] = [];\n\t\tif (details.cancelled) {\n\t\t\tdiag.push(`cancel reason : ${details.cancelReason ?? \"unknown\"}`);\n\t\t}\n\t\t// Browser connection state — the most common stale cause (page never opened).\n\t\tconst browserLabel = details.browserConnected === undefined\n\t\t\t? \"unknown\"\n\t\t\t: details.browserConnected\n\t\t\t\t? \"connected\"\n\t\t\t\t: \"never connected\";\n\t\tdiag.push(`browser : ${browserLabel}`);\n\t\tif (typeof details.lastHeartbeatAgeMs === \"number\" && Number.isFinite(details.lastHeartbeatAgeMs)) {\n\t\t\tdiag.push(`last heartbeat : ${Math.round(details.lastHeartbeatAgeMs / 1000)}s ago`);\n\t\t}\n\t\tif (queryCount > 0) {\n\t\t\tdiag.push(`queries started : ${queryCount}`);\n\t\t\tdiag.push(`queries done : ${done}`);\n\t\t\tif (errored > 0) diag.push(`queries errored : ${errored}`);\n\t\t}\n\t\texpanded.push(\"Diagnostics:\");\n\t\tfor (const line of diag) expanded.push(` ${line}`);\n\t}\n\n\t// --- per-query results gathered before cancel ---\n\tif (queries.length > 0) {\n\t\texpanded.push(\"\");\n\t\texpanded.push(\"Per-query results (gathered before cancel):\");\n\t\tfor (const q of queries) {\n\t\t\tconst dq = truncate(q.query, 52);\n\t\t\tconst tag = q.error ? \"[err] \" : \"[ok] \";\n\t\t\tconst provider = q.provider ? ` (${q.provider})` : \"\";\n\t\t\tconst tail = q.error\n\t\t\t\t? `\\u2014 ${truncate(q.error, 60)}`\n\t\t\t\t: `\\u2014 ${q.resultCount} source${q.resultCount === 1 ? \"\" : \"s\"}`;\n\t\t\texpanded.push(` ${tag}\"${dq}\"${provider} ${tail}`);\n\t\t}\n\t}\n\n\t// --- arbitrary extra detail (non-cancel errors) ---\n\tif (extras.length > 0) {\n\t\texpanded.push(\"\");\n\t\texpanded.push(\"Details:\");\n\t\tfor (const e of extras) expanded.push(` ${e}`);\n\t}\n\n\t// --- collapsed preview ---\n\tconst collapsed: string[] = [];\n\tconst parts: string[] = [];\n\tif (queryCount > 0) {\n\t\tparts.push(`${done}/${queryCount} queries completed`);\n\t}\n\tif (errored > 0) {\n\t\tparts.push(`${errored} errored`);\n\t}\n\tif (details.browserConnected === false) {\n\t\tparts.push(\"browser never connected\");\n\t} else if (details.cancelReason) {\n\t\tparts.push(`reason: ${details.cancelReason}`);\n\t}\n\tif (parts.length > 0) {\n\t\tcollapsed.push(parts.join(\"; \") + \".\");\n\t}\n\t// For non-cancel errors with extra detail, preview the first detail line.\n\tif (collapsed.length === 0 && extras.length > 0) {\n\t\tfor (const e of extras.slice(0, 2)) {\n\t\t\tcollapsed.push(truncate(e, 100));\n\t\t}\n\t}\n\n\t// --- expand hint ---\n\tconst hiddenLines = Math.max(0, expanded.length - (1 + collapsed.length)); // headline + preview shown when collapsed\n\tconst expandHint = hiddenLines > 0\n\t\t? `... (${hiddenLines} more lines, ${expanded.length} total, ctrl+o to expand)`\n\t\t: null;\n\n\treturn { expanded, collapsed, expandHint };\n}\n"]}
1
+ {"version":3,"file":"render-search-error.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/render-search-error.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IAClC,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC1C;8EAC0E;IAC1E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC/B,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oEAAoE;IACpE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,qFAAqF;IACrF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,GAAG,SAAS,GAAG,IAAI,GAAG,eAAe,GAAG,IAAI,CA0G3G","sourcesContent":["// @ts-nocheck\n/**\n * Pure, dependency-free renderer for web_search error / cancel results.\n *\n * WHY THIS EXISTS: the upstream web_search `renderResult` (index.ts) early-returns\n * a SINGLE line on the error/cancel path, before the collapsed/expanded branch.\n * That makes Ctrl+O (app.tools.expand) flip `expanded` with zero visible effect —\n * a dead-end with no diagnostics. It also discards the partial search results\n * gathered before the cancel, so even an expandable view would have nothing to show.\n *\n * This module is the single source of truth for the error/cancel render PLAN\n * (plain strings, no theme/ANSI), so it is unit-testable without pi's runtime\n * (@mariozechner/pi-tui Text/Box). index.ts.renderResult delegates to it and only\n * applies theme colors + creates Text/Box components.\n *\n * Contract for callers:\n * const plan = buildSearchErrorPlan(details);\n * if (plan === null) ... // not an error/cancel result; use the normal renderer\n * // collapsed: [statusLine, ...plan.collapsed, plan.expandHint].filter(Boolean)\n * // expanded: plan.expanded\n */\n\nexport interface CancelledQueryDetail {\n\tquery: string;\n\tprovider: string | null;\n\terror: string | null; // null = completed ok; string = per-query error\n\tresultCount: number;\n}\n\nexport interface SearchErrorDetails {\n\t/** The headline error/cancel message, e.g. \"Search curation cancelled (stale).\" */\n\terror?: string;\n\tcancelled?: boolean;\n\tcancelReason?: string;\n\t/** Did the curator browser page ever establish a connection? */\n\tbrowserConnected?: boolean;\n\t/** Age (ms) of the last curator heartbeat at cancel time, if known. */\n\tlastHeartbeatAgeMs?: number | null;\n\t/** Total queries the user requested. */\n\tqueryCount?: number;\n\t/** Partial per-query results gathered before the cancel/error. */\n\tcancelledQueries?: CancelledQueryDetail[];\n\t/** Arbitrary extra diagnostic lines (e.g. URLs, response id) for non-cancel errors\n\t * like fetch_content / get_search_content. Shown in the expanded view. */\n\textraLines?: string[];\n}\n\nexport interface SearchErrorPlan {\n\t/** Full diagnostic block, shown when expanded (Ctrl+O). */\n\texpanded: string[];\n\t/** Short preview lines, shown under the headline when collapsed. */\n\tcollapsed: string[];\n\t/** The \"... (N more lines, ctrl+o to expand)\" hint, or null if nothing is hidden. */\n\texpandHint: string | null;\n}\n\nfunction truncate(text: string, max: number): string {\n\treturn text.length > max ? text.slice(0, max - 1) + \"\\u2026\" : text;\n}\n\n/**\n * Build the error/cancel render plan. Returns null when `details` carries no\n * error/cancel signal (so the caller falls through to the normal success renderer).\n */\nexport function buildSearchErrorPlan(details: SearchErrorDetails | undefined | null): SearchErrorPlan | null {\n\tif (!details || (!details.error && !details.cancelled)) {\n\t\treturn null;\n\t}\n\n\tconst headline = details.error ?? \"Search cancelled.\";\n\tconst queries = details.cancelledQueries ?? [];\n\tconst queryCount = typeof details.queryCount === \"number\" && details.queryCount > 0\n\t\t? details.queryCount\n\t\t: queries.length;\n\tconst done = queries.length;\n\tconst errored = queries.filter(q => q.error).length;\n\n\t// Rich diagnostics only make sense when there is something to diagnose: a\n\t// cancelled/curator result with partial data, OR a non-cancel error that carries\n\t// extra detail (urls/response-id for fetch_content, the failed query for\n\t// get_search_content). A bare argument error (e.g. \"No URL\n\t// provided\") stays a clean single line -- no noise.\n\tconst extras = details.extraLines ?? [];\n\tconst rich = details.cancelled === true || queries.length > 0 || extras.length > 0;\n\tif (!rich) {\n\t\treturn { expanded: [headline], collapsed: [], expandHint: null };\n\t}\n\n\t// --- diagnostics block (expanded): curator/cancel-specific only. For non-cancel\n\t// errors (fetch_content/get_search_content) there is no browser or\n\t// query-curation state to report, so we skip this block and show only Details. ---\n\tconst expanded: string[] = [headline, \"\"];\n\n\tif (details.cancelled === true || queries.length > 0) {\n\t\tconst diag: string[] = [];\n\t\tif (details.cancelled) {\n\t\t\tdiag.push(`cancel reason : ${details.cancelReason ?? \"unknown\"}`);\n\t\t}\n\t\t// Browser connection state — the most common stale cause (page never opened).\n\t\tconst browserLabel = details.browserConnected === undefined\n\t\t\t? \"unknown\"\n\t\t\t: details.browserConnected\n\t\t\t\t? \"connected\"\n\t\t\t\t: \"never connected\";\n\t\tdiag.push(`browser : ${browserLabel}`);\n\t\tif (typeof details.lastHeartbeatAgeMs === \"number\" && Number.isFinite(details.lastHeartbeatAgeMs)) {\n\t\t\tdiag.push(`last heartbeat : ${Math.round(details.lastHeartbeatAgeMs / 1000)}s ago`);\n\t\t}\n\t\tif (queryCount > 0) {\n\t\t\tdiag.push(`queries started : ${queryCount}`);\n\t\t\tdiag.push(`queries done : ${done}`);\n\t\t\tif (errored > 0) diag.push(`queries errored : ${errored}`);\n\t\t}\n\t\texpanded.push(\"Diagnostics:\");\n\t\tfor (const line of diag) expanded.push(` ${line}`);\n\t}\n\n\t// --- per-query results gathered before cancel ---\n\tif (queries.length > 0) {\n\t\texpanded.push(\"\");\n\t\texpanded.push(\"Per-query results (gathered before cancel):\");\n\t\tfor (const q of queries) {\n\t\t\tconst dq = truncate(q.query, 52);\n\t\t\tconst tag = q.error ? \"[err] \" : \"[ok] \";\n\t\t\tconst provider = q.provider ? ` (${q.provider})` : \"\";\n\t\t\tconst tail = q.error\n\t\t\t\t? `\\u2014 ${truncate(q.error, 60)}`\n\t\t\t\t: `\\u2014 ${q.resultCount} source${q.resultCount === 1 ? \"\" : \"s\"}`;\n\t\t\texpanded.push(` ${tag}\"${dq}\"${provider} ${tail}`);\n\t\t}\n\t}\n\n\t// --- arbitrary extra detail (non-cancel errors) ---\n\tif (extras.length > 0) {\n\t\texpanded.push(\"\");\n\t\texpanded.push(\"Details:\");\n\t\tfor (const e of extras) expanded.push(` ${e}`);\n\t}\n\n\t// --- collapsed preview ---\n\tconst collapsed: string[] = [];\n\tconst parts: string[] = [];\n\tif (queryCount > 0) {\n\t\tparts.push(`${done}/${queryCount} queries completed`);\n\t}\n\tif (errored > 0) {\n\t\tparts.push(`${errored} errored`);\n\t}\n\tif (details.browserConnected === false) {\n\t\tparts.push(\"browser never connected\");\n\t} else if (details.cancelReason) {\n\t\tparts.push(`reason: ${details.cancelReason}`);\n\t}\n\tif (parts.length > 0) {\n\t\tcollapsed.push(parts.join(\"; \") + \".\");\n\t}\n\t// For non-cancel errors with extra detail, preview the first detail line.\n\tif (collapsed.length === 0 && extras.length > 0) {\n\t\tfor (const e of extras.slice(0, 2)) {\n\t\t\tcollapsed.push(truncate(e, 100));\n\t\t}\n\t}\n\n\t// --- expand hint ---\n\tconst hiddenLines = Math.max(0, expanded.length - (1 + collapsed.length)); // headline + preview shown when collapsed\n\tconst expandHint = hiddenLines > 0\n\t\t? `... (${hiddenLines} more lines, ${expanded.length} total)`\n\t\t: null;\n\n\treturn { expanded, collapsed, expandHint };\n}\n"]}
@@ -124,7 +124,7 @@ export function buildSearchErrorPlan(details) {
124
124
  // --- expand hint ---
125
125
  const hiddenLines = Math.max(0, expanded.length - (1 + collapsed.length)); // headline + preview shown when collapsed
126
126
  const expandHint = hiddenLines > 0
127
- ? `... (${hiddenLines} more lines, ${expanded.length} total, ctrl+o to expand)`
127
+ ? `... (${hiddenLines} more lines, ${expanded.length} total)`
128
128
  : null;
129
129
  return { expanded, collapsed, expandHint };
130
130
  }
@@ -1 +1 @@
1
- {"version":3,"file":"render-search-error.js","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/render-search-error.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * Pure, dependency-free renderer for web_search error / cancel results.\n *\n * WHY THIS EXISTS: the upstream web_search `renderResult` (index.ts) early-returns\n * a SINGLE line on the error/cancel path, before the collapsed/expanded branch.\n * That makes Ctrl+O (app.tools.expand) flip `expanded` with zero visible effect —\n * a dead-end with no diagnostics. It also discards the partial search results\n * gathered before the cancel, so even an expandable view would have nothing to show.\n *\n * This module is the single source of truth for the error/cancel render PLAN\n * (plain strings, no theme/ANSI), so it is unit-testable without pi's runtime\n * (@mariozechner/pi-tui Text/Box). index.ts.renderResult delegates to it and only\n * applies theme colors + creates Text/Box components.\n *\n * Contract for callers:\n * const plan = buildSearchErrorPlan(details);\n * if (plan === null) ... // not an error/cancel result; use the normal renderer\n * // collapsed: [statusLine, ...plan.collapsed, plan.expandHint].filter(Boolean)\n * // expanded: plan.expanded\n */\n\nexport interface CancelledQueryDetail {\n\tquery: string;\n\tprovider: string | null;\n\terror: string | null; // null = completed ok; string = per-query error\n\tresultCount: number;\n}\n\nexport interface SearchErrorDetails {\n\t/** The headline error/cancel message, e.g. \"Search curation cancelled (stale).\" */\n\terror?: string;\n\tcancelled?: boolean;\n\tcancelReason?: string;\n\t/** Did the curator browser page ever establish a connection? */\n\tbrowserConnected?: boolean;\n\t/** Age (ms) of the last curator heartbeat at cancel time, if known. */\n\tlastHeartbeatAgeMs?: number | null;\n\t/** Total queries the user requested. */\n\tqueryCount?: number;\n\t/** Partial per-query results gathered before the cancel/error. */\n\tcancelledQueries?: CancelledQueryDetail[];\n\t/** Arbitrary extra diagnostic lines (e.g. URLs, response id) for non-cancel errors\n\t * like fetch_content / get_search_content. Shown in the expanded view. */\n\textraLines?: string[];\n}\n\nexport interface SearchErrorPlan {\n\t/** Full diagnostic block, shown when expanded (Ctrl+O). */\n\texpanded: string[];\n\t/** Short preview lines, shown under the headline when collapsed. */\n\tcollapsed: string[];\n\t/** The \"... (N more lines, ctrl+o to expand)\" hint, or null if nothing is hidden. */\n\texpandHint: string | null;\n}\n\nfunction truncate(text: string, max: number): string {\n\treturn text.length > max ? text.slice(0, max - 1) + \"\\u2026\" : text;\n}\n\n/**\n * Build the error/cancel render plan. Returns null when `details` carries no\n * error/cancel signal (so the caller falls through to the normal success renderer).\n */\nexport function buildSearchErrorPlan(details: SearchErrorDetails | undefined | null): SearchErrorPlan | null {\n\tif (!details || (!details.error && !details.cancelled)) {\n\t\treturn null;\n\t}\n\n\tconst headline = details.error ?? \"Search cancelled.\";\n\tconst queries = details.cancelledQueries ?? [];\n\tconst queryCount = typeof details.queryCount === \"number\" && details.queryCount > 0\n\t\t? details.queryCount\n\t\t: queries.length;\n\tconst done = queries.length;\n\tconst errored = queries.filter(q => q.error).length;\n\n\t// Rich diagnostics only make sense when there is something to diagnose: a\n\t// cancelled/curator result with partial data, OR a non-cancel error that carries\n\t// extra detail (urls/response-id for fetch_content, the failed query for\n\t// get_search_content). A bare argument error (e.g. \"No URL\n\t// provided\") stays a clean single line -- no noise.\n\tconst extras = details.extraLines ?? [];\n\tconst rich = details.cancelled === true || queries.length > 0 || extras.length > 0;\n\tif (!rich) {\n\t\treturn { expanded: [headline], collapsed: [], expandHint: null };\n\t}\n\n\t// --- diagnostics block (expanded): curator/cancel-specific only. For non-cancel\n\t// errors (fetch_content/get_search_content) there is no browser or\n\t// query-curation state to report, so we skip this block and show only Details. ---\n\tconst expanded: string[] = [headline, \"\"];\n\n\tif (details.cancelled === true || queries.length > 0) {\n\t\tconst diag: string[] = [];\n\t\tif (details.cancelled) {\n\t\t\tdiag.push(`cancel reason : ${details.cancelReason ?? \"unknown\"}`);\n\t\t}\n\t\t// Browser connection state — the most common stale cause (page never opened).\n\t\tconst browserLabel = details.browserConnected === undefined\n\t\t\t? \"unknown\"\n\t\t\t: details.browserConnected\n\t\t\t\t? \"connected\"\n\t\t\t\t: \"never connected\";\n\t\tdiag.push(`browser : ${browserLabel}`);\n\t\tif (typeof details.lastHeartbeatAgeMs === \"number\" && Number.isFinite(details.lastHeartbeatAgeMs)) {\n\t\t\tdiag.push(`last heartbeat : ${Math.round(details.lastHeartbeatAgeMs / 1000)}s ago`);\n\t\t}\n\t\tif (queryCount > 0) {\n\t\t\tdiag.push(`queries started : ${queryCount}`);\n\t\t\tdiag.push(`queries done : ${done}`);\n\t\t\tif (errored > 0) diag.push(`queries errored : ${errored}`);\n\t\t}\n\t\texpanded.push(\"Diagnostics:\");\n\t\tfor (const line of diag) expanded.push(` ${line}`);\n\t}\n\n\t// --- per-query results gathered before cancel ---\n\tif (queries.length > 0) {\n\t\texpanded.push(\"\");\n\t\texpanded.push(\"Per-query results (gathered before cancel):\");\n\t\tfor (const q of queries) {\n\t\t\tconst dq = truncate(q.query, 52);\n\t\t\tconst tag = q.error ? \"[err] \" : \"[ok] \";\n\t\t\tconst provider = q.provider ? ` (${q.provider})` : \"\";\n\t\t\tconst tail = q.error\n\t\t\t\t? `\\u2014 ${truncate(q.error, 60)}`\n\t\t\t\t: `\\u2014 ${q.resultCount} source${q.resultCount === 1 ? \"\" : \"s\"}`;\n\t\t\texpanded.push(` ${tag}\"${dq}\"${provider} ${tail}`);\n\t\t}\n\t}\n\n\t// --- arbitrary extra detail (non-cancel errors) ---\n\tif (extras.length > 0) {\n\t\texpanded.push(\"\");\n\t\texpanded.push(\"Details:\");\n\t\tfor (const e of extras) expanded.push(` ${e}`);\n\t}\n\n\t// --- collapsed preview ---\n\tconst collapsed: string[] = [];\n\tconst parts: string[] = [];\n\tif (queryCount > 0) {\n\t\tparts.push(`${done}/${queryCount} queries completed`);\n\t}\n\tif (errored > 0) {\n\t\tparts.push(`${errored} errored`);\n\t}\n\tif (details.browserConnected === false) {\n\t\tparts.push(\"browser never connected\");\n\t} else if (details.cancelReason) {\n\t\tparts.push(`reason: ${details.cancelReason}`);\n\t}\n\tif (parts.length > 0) {\n\t\tcollapsed.push(parts.join(\"; \") + \".\");\n\t}\n\t// For non-cancel errors with extra detail, preview the first detail line.\n\tif (collapsed.length === 0 && extras.length > 0) {\n\t\tfor (const e of extras.slice(0, 2)) {\n\t\t\tcollapsed.push(truncate(e, 100));\n\t\t}\n\t}\n\n\t// --- expand hint ---\n\tconst hiddenLines = Math.max(0, expanded.length - (1 + collapsed.length)); // headline + preview shown when collapsed\n\tconst expandHint = hiddenLines > 0\n\t\t? `... (${hiddenLines} more lines, ${expanded.length} total, ctrl+o to expand)`\n\t\t: null;\n\n\treturn { expanded, collapsed, expandHint };\n}\n"]}
1
+ {"version":3,"file":"render-search-error.js","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/render-search-error.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * Pure, dependency-free renderer for web_search error / cancel results.\n *\n * WHY THIS EXISTS: the upstream web_search `renderResult` (index.ts) early-returns\n * a SINGLE line on the error/cancel path, before the collapsed/expanded branch.\n * That makes Ctrl+O (app.tools.expand) flip `expanded` with zero visible effect —\n * a dead-end with no diagnostics. It also discards the partial search results\n * gathered before the cancel, so even an expandable view would have nothing to show.\n *\n * This module is the single source of truth for the error/cancel render PLAN\n * (plain strings, no theme/ANSI), so it is unit-testable without pi's runtime\n * (@mariozechner/pi-tui Text/Box). index.ts.renderResult delegates to it and only\n * applies theme colors + creates Text/Box components.\n *\n * Contract for callers:\n * const plan = buildSearchErrorPlan(details);\n * if (plan === null) ... // not an error/cancel result; use the normal renderer\n * // collapsed: [statusLine, ...plan.collapsed, plan.expandHint].filter(Boolean)\n * // expanded: plan.expanded\n */\n\nexport interface CancelledQueryDetail {\n\tquery: string;\n\tprovider: string | null;\n\terror: string | null; // null = completed ok; string = per-query error\n\tresultCount: number;\n}\n\nexport interface SearchErrorDetails {\n\t/** The headline error/cancel message, e.g. \"Search curation cancelled (stale).\" */\n\terror?: string;\n\tcancelled?: boolean;\n\tcancelReason?: string;\n\t/** Did the curator browser page ever establish a connection? */\n\tbrowserConnected?: boolean;\n\t/** Age (ms) of the last curator heartbeat at cancel time, if known. */\n\tlastHeartbeatAgeMs?: number | null;\n\t/** Total queries the user requested. */\n\tqueryCount?: number;\n\t/** Partial per-query results gathered before the cancel/error. */\n\tcancelledQueries?: CancelledQueryDetail[];\n\t/** Arbitrary extra diagnostic lines (e.g. URLs, response id) for non-cancel errors\n\t * like fetch_content / get_search_content. Shown in the expanded view. */\n\textraLines?: string[];\n}\n\nexport interface SearchErrorPlan {\n\t/** Full diagnostic block, shown when expanded (Ctrl+O). */\n\texpanded: string[];\n\t/** Short preview lines, shown under the headline when collapsed. */\n\tcollapsed: string[];\n\t/** The \"... (N more lines, ctrl+o to expand)\" hint, or null if nothing is hidden. */\n\texpandHint: string | null;\n}\n\nfunction truncate(text: string, max: number): string {\n\treturn text.length > max ? text.slice(0, max - 1) + \"\\u2026\" : text;\n}\n\n/**\n * Build the error/cancel render plan. Returns null when `details` carries no\n * error/cancel signal (so the caller falls through to the normal success renderer).\n */\nexport function buildSearchErrorPlan(details: SearchErrorDetails | undefined | null): SearchErrorPlan | null {\n\tif (!details || (!details.error && !details.cancelled)) {\n\t\treturn null;\n\t}\n\n\tconst headline = details.error ?? \"Search cancelled.\";\n\tconst queries = details.cancelledQueries ?? [];\n\tconst queryCount = typeof details.queryCount === \"number\" && details.queryCount > 0\n\t\t? details.queryCount\n\t\t: queries.length;\n\tconst done = queries.length;\n\tconst errored = queries.filter(q => q.error).length;\n\n\t// Rich diagnostics only make sense when there is something to diagnose: a\n\t// cancelled/curator result with partial data, OR a non-cancel error that carries\n\t// extra detail (urls/response-id for fetch_content, the failed query for\n\t// get_search_content). A bare argument error (e.g. \"No URL\n\t// provided\") stays a clean single line -- no noise.\n\tconst extras = details.extraLines ?? [];\n\tconst rich = details.cancelled === true || queries.length > 0 || extras.length > 0;\n\tif (!rich) {\n\t\treturn { expanded: [headline], collapsed: [], expandHint: null };\n\t}\n\n\t// --- diagnostics block (expanded): curator/cancel-specific only. For non-cancel\n\t// errors (fetch_content/get_search_content) there is no browser or\n\t// query-curation state to report, so we skip this block and show only Details. ---\n\tconst expanded: string[] = [headline, \"\"];\n\n\tif (details.cancelled === true || queries.length > 0) {\n\t\tconst diag: string[] = [];\n\t\tif (details.cancelled) {\n\t\t\tdiag.push(`cancel reason : ${details.cancelReason ?? \"unknown\"}`);\n\t\t}\n\t\t// Browser connection state — the most common stale cause (page never opened).\n\t\tconst browserLabel = details.browserConnected === undefined\n\t\t\t? \"unknown\"\n\t\t\t: details.browserConnected\n\t\t\t\t? \"connected\"\n\t\t\t\t: \"never connected\";\n\t\tdiag.push(`browser : ${browserLabel}`);\n\t\tif (typeof details.lastHeartbeatAgeMs === \"number\" && Number.isFinite(details.lastHeartbeatAgeMs)) {\n\t\t\tdiag.push(`last heartbeat : ${Math.round(details.lastHeartbeatAgeMs / 1000)}s ago`);\n\t\t}\n\t\tif (queryCount > 0) {\n\t\t\tdiag.push(`queries started : ${queryCount}`);\n\t\t\tdiag.push(`queries done : ${done}`);\n\t\t\tif (errored > 0) diag.push(`queries errored : ${errored}`);\n\t\t}\n\t\texpanded.push(\"Diagnostics:\");\n\t\tfor (const line of diag) expanded.push(` ${line}`);\n\t}\n\n\t// --- per-query results gathered before cancel ---\n\tif (queries.length > 0) {\n\t\texpanded.push(\"\");\n\t\texpanded.push(\"Per-query results (gathered before cancel):\");\n\t\tfor (const q of queries) {\n\t\t\tconst dq = truncate(q.query, 52);\n\t\t\tconst tag = q.error ? \"[err] \" : \"[ok] \";\n\t\t\tconst provider = q.provider ? ` (${q.provider})` : \"\";\n\t\t\tconst tail = q.error\n\t\t\t\t? `\\u2014 ${truncate(q.error, 60)}`\n\t\t\t\t: `\\u2014 ${q.resultCount} source${q.resultCount === 1 ? \"\" : \"s\"}`;\n\t\t\texpanded.push(` ${tag}\"${dq}\"${provider} ${tail}`);\n\t\t}\n\t}\n\n\t// --- arbitrary extra detail (non-cancel errors) ---\n\tif (extras.length > 0) {\n\t\texpanded.push(\"\");\n\t\texpanded.push(\"Details:\");\n\t\tfor (const e of extras) expanded.push(` ${e}`);\n\t}\n\n\t// --- collapsed preview ---\n\tconst collapsed: string[] = [];\n\tconst parts: string[] = [];\n\tif (queryCount > 0) {\n\t\tparts.push(`${done}/${queryCount} queries completed`);\n\t}\n\tif (errored > 0) {\n\t\tparts.push(`${errored} errored`);\n\t}\n\tif (details.browserConnected === false) {\n\t\tparts.push(\"browser never connected\");\n\t} else if (details.cancelReason) {\n\t\tparts.push(`reason: ${details.cancelReason}`);\n\t}\n\tif (parts.length > 0) {\n\t\tcollapsed.push(parts.join(\"; \") + \".\");\n\t}\n\t// For non-cancel errors with extra detail, preview the first detail line.\n\tif (collapsed.length === 0 && extras.length > 0) {\n\t\tfor (const e of extras.slice(0, 2)) {\n\t\t\tcollapsed.push(truncate(e, 100));\n\t\t}\n\t}\n\n\t// --- expand hint ---\n\tconst hiddenLines = Math.max(0, expanded.length - (1 + collapsed.length)); // headline + preview shown when collapsed\n\tconst expandHint = hiddenLines > 0\n\t\t? `... (${hiddenLines} more lines, ${expanded.length} total)`\n\t\t: null;\n\n\treturn { expanded, collapsed, expandHint };\n}\n"]}