@caupulican/pi-adaptative 0.93.19 → 0.94.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +3 -2
  3. package/dist/core/extensions/loader.d.ts +0 -1
  4. package/dist/core/extensions/loader.d.ts.map +1 -1
  5. package/dist/core/extensions/loader.js +0 -1
  6. package/dist/core/extensions/loader.js.map +1 -1
  7. package/dist/core/extensions/types.d.ts +0 -4
  8. package/dist/core/extensions/types.d.ts.map +1 -1
  9. package/dist/core/extensions/types.js.map +1 -1
  10. package/dist/core/tools/artifact-retrieve.d.ts.map +1 -1
  11. package/dist/core/tools/artifact-retrieve.js +0 -1
  12. package/dist/core/tools/artifact-retrieve.js.map +1 -1
  13. package/dist/core/tools/edit.d.ts.map +1 -1
  14. package/dist/core/tools/edit.js +0 -7
  15. package/dist/core/tools/edit.js.map +1 -1
  16. package/dist/core/tools/find.d.ts.map +1 -1
  17. package/dist/core/tools/find.js +0 -1
  18. package/dist/core/tools/find.js.map +1 -1
  19. package/dist/core/tools/grep.d.ts.map +1 -1
  20. package/dist/core/tools/grep.js +0 -1
  21. package/dist/core/tools/grep.js.map +1 -1
  22. package/dist/core/tools/ls.d.ts.map +1 -1
  23. package/dist/core/tools/ls.js +0 -1
  24. package/dist/core/tools/ls.js.map +1 -1
  25. package/dist/core/tools/skill-audit.d.ts.map +1 -1
  26. package/dist/core/tools/skill-audit.js +0 -1
  27. package/dist/core/tools/skill-audit.js.map +1 -1
  28. package/dist/core/tools/skill.d.ts.map +1 -1
  29. package/dist/core/tools/skill.js +0 -1
  30. package/dist/core/tools/skill.js.map +1 -1
  31. package/dist/core/tools/skillify.d.ts.map +1 -1
  32. package/dist/core/tools/skillify.js +0 -1
  33. package/dist/core/tools/skillify.js.map +1 -1
  34. package/dist/core/tools/write.d.ts.map +1 -1
  35. package/dist/core/tools/write.js +1 -2
  36. package/dist/core/tools/write.js.map +1 -1
  37. package/dist/modes/interactive/components/action-transcript.d.ts +24 -0
  38. package/dist/modes/interactive/components/action-transcript.d.ts.map +1 -0
  39. package/dist/modes/interactive/components/action-transcript.js +72 -0
  40. package/dist/modes/interactive/components/action-transcript.js.map +1 -0
  41. package/dist/modes/interactive/components/active-tool-call-registry.d.ts +12 -0
  42. package/dist/modes/interactive/components/active-tool-call-registry.d.ts.map +1 -0
  43. package/dist/modes/interactive/components/active-tool-call-registry.js +25 -0
  44. package/dist/modes/interactive/components/active-tool-call-registry.js.map +1 -0
  45. package/dist/modes/interactive/components/activity-lane.d.ts +1 -1
  46. package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -1
  47. package/dist/modes/interactive/components/activity-lane.js.map +1 -1
  48. package/dist/modes/interactive/components/assistant-message.d.ts +2 -0
  49. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  50. package/dist/modes/interactive/components/assistant-message.js +7 -1
  51. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  52. package/dist/modes/interactive/components/index.d.ts +0 -2
  53. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  54. package/dist/modes/interactive/components/index.js +0 -2
  55. package/dist/modes/interactive/components/index.js.map +1 -1
  56. package/dist/modes/interactive/components/tool-execution.d.ts +0 -7
  57. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  58. package/dist/modes/interactive/components/tool-execution.js +2 -76
  59. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  60. package/dist/modes/interactive/components/transcript-overlay.d.ts +3 -1
  61. package/dist/modes/interactive/components/transcript-overlay.d.ts.map +1 -1
  62. package/dist/modes/interactive/components/transcript-overlay.js +8 -5
  63. package/dist/modes/interactive/components/transcript-overlay.js.map +1 -1
  64. package/dist/modes/interactive/interactive-event-controller.d.ts +2 -3
  65. package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -1
  66. package/dist/modes/interactive/interactive-event-controller.js +9 -9
  67. package/dist/modes/interactive/interactive-event-controller.js.map +1 -1
  68. package/dist/modes/interactive/interactive-mode.d.ts +6 -6
  69. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  70. package/dist/modes/interactive/interactive-mode.js +50 -100
  71. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  72. package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -1
  73. package/dist/modes/interactive/settings-selector-flow.js +3 -4
  74. package/dist/modes/interactive/settings-selector-flow.js.map +1 -1
  75. package/docs/UI_POLISH_ORCHESTRATION.md +4 -4
  76. package/docs/extensions.md +4 -12
  77. package/docs/keybindings.md +2 -2
  78. package/docs/settings.md +1 -1
  79. package/docs/task-steps.md +3 -3
  80. package/docs/tool-repair.md +1 -1
  81. package/docs/usage.md +1 -1
  82. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  83. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  84. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  85. package/examples/extensions/sandbox/package-lock.json +2 -2
  86. package/examples/extensions/sandbox/package.json +1 -1
  87. package/examples/extensions/with-deps/package-lock.json +2 -2
  88. package/examples/extensions/with-deps/package.json +1 -1
  89. package/npm-shrinkwrap.json +12 -12
  90. package/package.json +4 -4
  91. package/dist/modes/interactive/components/tool-group.d.ts +0 -28
  92. package/dist/modes/interactive/components/tool-group.d.ts.map +0 -1
  93. package/dist/modes/interactive/components/tool-group.js +0 -200
  94. package/dist/modes/interactive/components/tool-group.js.map +0 -1
  95. package/dist/modes/interactive/components/tool-panel-registry.d.ts +0 -30
  96. package/dist/modes/interactive/components/tool-panel-registry.d.ts.map +0 -1
  97. package/dist/modes/interactive/components/tool-panel-registry.js +0 -145
  98. package/dist/modes/interactive/components/tool-panel-registry.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile as fsReadFile, stat as fsStat } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateLine,\n} from \"@caupulican/pi-agent-core/truncate\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core/types\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { waitForChildProcessWithTermination } from \"../../utils/child-process.ts\";\nimport type { ArtifactStore } from \"../context/context-artifacts.ts\";\nimport {\n\ttype BroadQueryTracker,\n\tbroadQueryInvalidationNote,\n\tformatArtifactNotice,\n\tnormalizeBroadQueryKey,\n\tpackToolOutput,\n} from \"../context/tool-output-packer.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport {\n\ttype FffGrepMatch,\n\ttype FffGrepResult,\n\ttype FffSearchBackend,\n\thasGitignoreInTree,\n\tresolveRoutedFffFinder,\n} from \"./fff-search-backend.ts\";\nimport { type ManagedSearchToolOptions, resolveManagedSearchTool } from \"./managed-search-tool.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatCollapsibleToolResult,\n\tinvalidArgText,\n\trenderTextComponent,\n\tshortenPath,\n\tstr,\n\ttoolTextResult,\n} from \"./render-utils.ts\";\nimport type { SearchRouter } from \"./search-router.ts\";\nimport { resolveSearchToolRuntime } from \"./search-tool-runtime.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\nconst GREP_PROCESS_TIMEOUT_MS = 5 * 60_000;\nconst GREP_PROCESS_KILL_GRACE_MS = 1_000;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n\t/** Set only when output was packed to an artifact; see tool-output-packer.ts. */\n\tartifactId?: string;\n\t/** Set when this exact query has repeatedly produced broad/truncated results. */\n\tinvalidationCandidate?: boolean;\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: async (p) => (await fsStat(p)).isDirectory(),\n\treadFile: (p) => fsReadFile(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions extends ManagedSearchToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus routed FFF/rg search */\n\toperations?: GrepOperations;\n\t/** FFF backend for resident indexed search. Set false to force ripgrep fallback. */\n\tfff?: FffSearchBackend | false;\n\t/** Pure router that selects FFF or rg from request filters and environment facts. */\n\tsearchRouter?: SearchRouter;\n\t/**\n\t * Opt-in artifact store for first-capture-then-bound output packing (Phase 3). When\n\t * omitted (the default), behavior is byte-for-byte unchanged from before this option\n\t * existed: output is truncated the same way, just never artifact-backed.\n\t */\n\tartifactStore?: ArtifactStore;\n\t/** Opt-in tracker for repeated-broad-query \"do not repeat\" signals. Also default-off. */\n\tbroadQueryTracker?: BroadQueryTracker;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: Theme,\n\tcwd: string,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\", cwd) : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\treturn formatCollapsibleToolResult({\n\t\tresult,\n\t\toptions,\n\t\ttheme,\n\t\tshowImages,\n\t\tcollapsedLineLimit: 15,\n\t\twarnings: (details) => {\n\t\t\tconst warnings: string[] = [];\n\t\t\tif (details?.matchLimitReached) warnings.push(`${details.matchLimitReached} matches limit`);\n\t\t\tif (details?.truncation?.truncated) {\n\t\t\t\twarnings.push(`${formatSize(details.truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\t\t}\n\t\t\tif (details?.linesTruncated) warnings.push(\"some lines truncated\");\n\t\t\treturn warnings;\n\t\t},\n\t});\n}\n\nfunction globConstraintForFff(glob: string | undefined): string {\n\tif (!glob) return \"\";\n\tif (glob.includes(\"/\") || glob.startsWith(\"**/\")) return glob;\n\treturn `**/${glob}`;\n}\n\nfunction fffGrepQuery(options: {\n\tpattern: string;\n\tglob?: string;\n\tisDirectory: boolean;\n\tsearchPathRelativeToCwd: string;\n}): string | undefined {\n\tconst parts: string[] = [];\n\tif (options.searchPathRelativeToCwd) {\n\t\tparts.push(options.isDirectory ? `${options.searchPathRelativeToCwd}/` : options.searchPathRelativeToCwd);\n\t}\n\tparts.push(globConstraintForFff(options.glob));\n\tparts.push(options.pattern);\n\treturn parts.filter(Boolean).join(\" \");\n}\n\nfunction fffDisplayPath(\n\tmatch: FffGrepMatch,\n\toptions: { isDirectory: boolean; searchPathRelativeToCwd: string },\n): string | undefined {\n\tconst relativePath = match.relativePath.replaceAll(\"\\\\\", \"/\");\n\tif (!options.searchPathRelativeToCwd) return relativePath;\n\tif (!options.isDirectory) {\n\t\treturn relativePath === options.searchPathRelativeToCwd ? path.posix.basename(relativePath) : undefined;\n\t}\n\tconst prefix = `${options.searchPathRelativeToCwd}/`;\n\tif (!relativePath.startsWith(prefix)) return undefined;\n\treturn relativePath.slice(prefix.length);\n}\n\nfunction appendFffMatchLines(options: {\n\tmatch: FffGrepMatch;\n\toutputLines: string[];\n\tlinesTruncated: { value: boolean };\n\tcontextValue: number;\n}): void {\n\tconst before = options.match.contextBefore ?? [];\n\tfor (let i = 0; i < before.length; i++) {\n\t\tconst lineNumber = options.match.lineNumber - before.length + i;\n\t\tconst { text, wasTruncated } = truncateLine(before[i] ?? \"\");\n\t\tif (wasTruncated) options.linesTruncated.value = true;\n\t\toptions.outputLines.push(` ${lineNumber}- ${text}`);\n\t}\n\n\tconst { text, wasTruncated } = truncateLine(options.match.lineContent.replace(/\\r/g, \"\"));\n\tif (wasTruncated) options.linesTruncated.value = true;\n\toptions.outputLines.push(` ${options.match.lineNumber}: ${text}`);\n\n\tif (options.contextValue === 0) return;\n\tconst after = options.match.contextAfter ?? [];\n\tfor (let i = 0; i < after.length; i++) {\n\t\tconst lineNumber = options.match.lineNumber + 1 + i;\n\t\tconst { text: contextText, wasTruncated: contextWasTruncated } = truncateLine(after[i] ?? \"\");\n\t\tif (contextWasTruncated) options.linesTruncated.value = true;\n\t\toptions.outputLines.push(` ${lineNumber}- ${contextText}`);\n\t}\n}\n\n/**\n * Shared \"measure -> pack -> notices\" tail for both the FFF and ripgrep result paths:\n * first-capture the raw output to an artifact if it's oversized and a store was provided\n * (Phase 3 tool-output-artifacts.md boundary rule), then append the same match-limit/\n * byte-limit/line-truncation/broad-query notices either path already produced.\n */\nfunction packGrepOutput(options: {\n\trawOutput: string;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\tpattern: string;\n\trawPath?: string;\n\tglob?: string;\n\tmatchLimitReached: number | false;\n\tlinesTruncated: boolean;\n}): { text: string; details: GrepToolDetails } {\n\tconst packed = packToolOutput(\n\t\t{\n\t\t\ttoolName: \"grep\",\n\t\t\tpath: options.rawPath,\n\t\t\trawContent: options.rawOutput,\n\t\t\t// No line limit here because the match limit already caps rows; only the byte\n\t\t\t// cap should apply, matching the pre-Slice-B truncateHead call exactly.\n\t\t\ttruncation: { maxLines: Number.MAX_SAFE_INTEGER },\n\t\t},\n\t\toptions.artifactStore,\n\t\toptions.toolCallId,\n\t);\n\tlet output = packed.content;\n\tconst details: GrepToolDetails = {};\n\n\tconst notices: string[] = [];\n\tif (packed.artifactId) {\n\t\tnotices.push(formatArtifactNotice(packed.artifactId));\n\t\tdetails.artifactId = packed.artifactId;\n\t}\n\tif (options.matchLimitReached) {\n\t\tnotices.push(\n\t\t\t`${options.matchLimitReached} matches limit reached. Use limit=${options.matchLimitReached * 2} for more, or refine pattern`,\n\t\t);\n\t\tdetails.matchLimitReached = options.matchLimitReached;\n\t}\n\tif (packed.truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t// Drop the duplicated bounded-preview text: it's already in the message's own\n\t\t// content, and re-including it here can push `details` past\n\t\t// MAX_RETAINED_TOOL_RESULT_DETAILS_BYTES (message-retention.ts), which replaces\n\t\t// the *entire* details object with a stub -- silently losing artifactId and every\n\t\t// other field alongside it. This is load-bearing beyond just the retention budget:\n\t\t// agent-session.ts's _releaseGcPackedArtifactReferences() reads artifactId back off\n\t\t// this same canonical message at eviction time (potentially many turns later), so\n\t\t// keeping `details` small here is what keeps that release path working at all. If\n\t\t// this field ever grows a large addition again, add a regression proving artifactId\n\t\t// survives compactToolResultDetailsForRetention (see\n\t\t// test/suite/agent-session-artifact-lifecycle.test.ts), not just a details-size check.\n\t\tdetails.truncation = { ...packed.truncation, content: \"\" };\n\t}\n\tif (options.linesTruncated) {\n\t\tnotices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);\n\t\tdetails.linesTruncated = true;\n\t}\n\tif (options.matchLimitReached || packed.truncation.truncated) {\n\t\tconst note = broadQueryInvalidationNote(\n\t\t\toptions.broadQueryTracker,\n\t\t\tnormalizeBroadQueryKey({\n\t\t\t\ttoolName: \"grep\",\n\t\t\t\tpattern: options.pattern,\n\t\t\t\tpath: options.rawPath,\n\t\t\t\tglob: options.glob,\n\t\t\t}),\n\t\t\t`grep \"${options.pattern}\" in ${options.rawPath ?? \".\"}`,\n\t\t);\n\t\tif (note) {\n\t\t\tnotices.push(note);\n\t\t\tdetails.invalidationCandidate = true;\n\t\t}\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn { text: output, details };\n}\n\nfunction formatFffGrepResult(options: {\n\tresult: FffGrepResult;\n\tisDirectory: boolean;\n\tsearchPathRelativeToCwd: string;\n\teffectiveLimit: number;\n\tcontextValue: number;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\tpattern: string;\n\trawPath?: string;\n\tglob?: string;\n}): { text: string; details: GrepToolDetails } {\n\tif (options.result.items.length === 0) return { text: \"No matches found\", details: {} };\n\n\tconst outputLines: string[] = [];\n\tconst linesTruncated = { value: false };\n\tconst resultLimitReached =\n\t\toptions.result.items.length > options.effectiveLimit || Boolean(options.result.nextCursor);\n\tconst displayedMatches = resultLimitReached\n\t\t? options.result.items.slice(0, options.effectiveLimit)\n\t\t: options.result.items;\n\tlet currentPath = \"\";\n\tfor (const match of displayedMatches) {\n\t\tconst displayPath = fffDisplayPath(match, options);\n\t\tif (!displayPath) continue;\n\t\tif (displayPath !== currentPath) {\n\t\t\tcurrentPath = displayPath;\n\t\t\toutputLines.push(`${displayPath}:`);\n\t\t}\n\t\tappendFffMatchLines({\n\t\t\tmatch,\n\t\t\toutputLines,\n\t\t\tlinesTruncated,\n\t\t\tcontextValue: options.contextValue,\n\t\t});\n\t}\n\n\tif (outputLines.length === 0) return { text: \"No matches found\", details: {} };\n\tconst rawOutput = outputLines.join(\"\\n\");\n\treturn packGrepOutput({\n\t\trawOutput,\n\t\ttoolCallId: options.toolCallId,\n\t\tartifactStore: options.artifactStore,\n\t\tbroadQueryTracker: options.broadQueryTracker,\n\t\tpattern: options.pattern,\n\t\trawPath: options.rawPath,\n\t\tglob: options.glob,\n\t\tmatchLimitReached: resultLimitReached ? options.effectiveLimit : false,\n\t\tlinesTruncated: linesTruncated.value,\n\t});\n}\n\nexport async function tryFffGrep(options: {\n\tbackend: FffSearchBackend;\n\trouter: SearchRouter;\n\tcwd: string;\n\tsearchPath: string;\n\tpattern: string;\n\tglob?: string;\n\tignoreCase?: boolean;\n\tliteral?: boolean;\n\tcontextValue: number;\n\teffectiveLimit: number;\n\tisDirectory: boolean;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\trawPath?: string;\n}): Promise<{ text: string; details: GrepToolDetails } | undefined> {\n\tconst routed = await resolveRoutedFffFinder({\n\t\tbackend: options.backend,\n\t\trouter: options.router,\n\t\ttool: \"grep\",\n\t\tcwd: options.cwd,\n\t\tsearchPath: options.searchPath,\n\t\tglob: Boolean(options.glob),\n\t\tignoreCase: Boolean(options.ignoreCase),\n\t\tlimit: options.effectiveLimit,\n\t\treadGitignoreInTree: () => (options.isDirectory ? hasGitignoreInTree(options.searchPath) : false),\n\t});\n\tif (!routed) return undefined;\n\tconst { finder, searchPathRelativeToCwd } = routed;\n\n\tconst query = fffGrepQuery({\n\t\tpattern: options.pattern,\n\t\tglob: options.glob,\n\t\tisDirectory: options.isDirectory,\n\t\tsearchPathRelativeToCwd,\n\t});\n\tif (!query) return undefined;\n\n\tconst probeLimit = options.effectiveLimit + 1;\n\tconst result = finder.grep(query, {\n\t\tmode: options.literal ? \"plain\" : \"regex\",\n\t\tsmartCase: false,\n\t\tmaxMatchesPerFile: probeLimit,\n\t\tbeforeContext: options.contextValue,\n\t\tafterContext: options.contextValue,\n\t\tpageSize: probeLimit,\n\t});\n\tif (!result.ok || result.value.regexFallbackError) return undefined;\n\treturn formatFffGrepResult({\n\t\tresult: result.value,\n\t\tisDirectory: options.isDirectory,\n\t\tsearchPathRelativeToCwd,\n\t\teffectiveLimit: options.effectiveLimit,\n\t\tcontextValue: options.contextValue,\n\t\ttoolCallId: options.toolCallId,\n\t\tartifactStore: options.artifactStore,\n\t\tbroadQueryTracker: options.broadQueryTracker,\n\t\tpattern: options.pattern,\n\t\trawPath: options.rawPath,\n\t\tglob: options.glob,\n\t});\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst search = resolveSearchToolRuntime(options);\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file text; respects .gitignore\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use narrowest known root/glob; discover paths first. Never repeatedly scan repo/home/filesystem.\",\n\t\t],\n\t\tparameters: grepSchema,\n\t\ttoolGroup: \"explore\",\n\t\tasync execute(\n\t\t\ttoolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t}: {\n\t\t\t\tpattern: string;\n\t\t\t\tpath?: string;\n\t\t\t\tglob?: string;\n\t\t\t\tignoreCase?: boolean;\n\t\t\t\tliteral?: boolean;\n\t\t\t\tcontext?: number;\n\t\t\t\tlimit?: number;\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = search.operations ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) {\n\t\t\t\t\t\t\t\t\treturn relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (!search.operations && search.fffBackend) {\n\t\t\t\t\t\t\tconst fffResult = await tryFffGrep({\n\t\t\t\t\t\t\t\tbackend: search.fffBackend,\n\t\t\t\t\t\t\t\trouter: search.searchRouter,\n\t\t\t\t\t\t\t\tcwd,\n\t\t\t\t\t\t\t\tsearchPath,\n\t\t\t\t\t\t\t\tpattern,\n\t\t\t\t\t\t\t\tglob,\n\t\t\t\t\t\t\t\tignoreCase,\n\t\t\t\t\t\t\t\tliteral,\n\t\t\t\t\t\t\t\tcontextValue,\n\t\t\t\t\t\t\t\teffectiveLimit,\n\t\t\t\t\t\t\t\tisDirectory,\n\t\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\t\tartifactStore: search.artifactStore,\n\t\t\t\t\t\t\t\tbroadQueryTracker: search.broadQueryTracker,\n\t\t\t\t\t\t\t\trawPath: searchDir,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (fffResult) {\n\t\t\t\t\t\t\t\tsettle(() => resolve(toolTextResult(fffResult)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rgPath = await resolveManagedSearchTool(\"rg\", options?.managedToolResolver);\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(\"--\", pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, {\n\t\t\t\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst terminationController = new AbortController();\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (dueToLimit) killedDueToLimit = true;\n\t\t\t\t\t\t\tterminationController.abort();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (signal?.aborted) onAbort();\n\t\t\t\t\t\telse signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [`${relativePath}:${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${relativePath}:${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${relativePath}-${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number; lineText?: string }> = [];\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || matchLimitReached) return;\n\t\t\t\t\t\t\tlet event: any;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.type === \"match\") {\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tif (matchCount > effectiveLimit) {\n\t\t\t\t\t\t\t\t\tmatchLimitReached = true;\n\t\t\t\t\t\t\t\t\tstopChild(true);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tconst lineText = event.data?.lines?.text;\n\t\t\t\t\t\t\t\tif (filePath && typeof lineNumber === \"number\")\n\t\t\t\t\t\t\t\t\tmatches.push({ filePath, lineNumber, lineText });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst terminal = await waitForChildProcessWithTermination(child, {\n\t\t\t\t\t\t\tsignal: terminationController.signal,\n\t\t\t\t\t\t\ttimeoutMs: GREP_PROCESS_TIMEOUT_MS,\n\t\t\t\t\t\t\tkillGraceMs: GREP_PROCESS_KILL_GRACE_MS,\n\t\t\t\t\t\t}).finally(cleanup);\n\t\t\t\t\t\tconst code = terminal.code;\n\t\t\t\t\t\tif (terminal.reason === \"timeout\") {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`ripgrep timed out after ${GREP_PROCESS_TIMEOUT_MS}ms`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Format matches after streaming finishes so custom readFile() backends can be async.\n\t\t\t\t\t\tconst fileGroups = new Map<string, string[]>();\n\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\tconst relativePath = formatPath(match.filePath);\n\t\t\t\t\t\t\tif (!fileGroups.has(relativePath)) {\n\t\t\t\t\t\t\t\tfileGroups.set(relativePath, []);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst group = fileGroups.get(relativePath)!;\n\n\t\t\t\t\t\t\tif (contextValue === 0 && match.lineText !== undefined) {\n\t\t\t\t\t\t\t\tconst sanitized = match.lineText.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\").replace(/\\n$/, \"\");\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tgroup.push(` ${match.lineNumber}: ${truncatedText}`);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\tfor (const line of block) {\n\t\t\t\t\t\t\t\t\tif (line.startsWith(`${relativePath}:`)) {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line.slice(relativePath.length + 1)}`);\n\t\t\t\t\t\t\t\t\t} else if (line.startsWith(`${relativePath}-`)) {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line.slice(relativePath.length + 1)}`);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line}`);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (const [relativePath, lines] of fileGroups) {\n\t\t\t\t\t\t\toutputLines.push(`${relativePath}:`);\n\t\t\t\t\t\t\tlet lastLine = \"\";\n\t\t\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\t\t\tif (line === lastLine) continue;\n\t\t\t\t\t\t\t\toutputLines.push(line);\n\t\t\t\t\t\t\t\tlastLine = line;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t// Measure -> pack (artifact-backed if oversized and a store was provided) -> notices.\n\t\t\t\t\t\t// There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\tconst { text: output, details } = packGrepOutput({\n\t\t\t\t\t\t\trawOutput,\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\tartifactStore: search.artifactStore,\n\t\t\t\t\t\t\tbroadQueryTracker: search.broadQueryTracker,\n\t\t\t\t\t\t\tpattern,\n\t\t\t\t\t\t\trawPath: searchDir,\n\t\t\t\t\t\t\tglob,\n\t\t\t\t\t\t\tmatchLimitReached: matchLimitReached ? effectiveLimit : false,\n\t\t\t\t\t\t\tlinesTruncated,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tsettle(() => resolve(toolTextResult({ text: output, details })));\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\treturn renderTextComponent(context.lastComponent, formatGrepCall(args, theme, context.cwd));\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\treturn renderTextComponent(\n\t\t\t\tcontext.lastComponent,\n\t\t\t\tformatGrepResult(result as Parameters<typeof formatGrepResult>[0], options, theme, context.showImages),\n\t\t\t);\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile as fsReadFile, stat as fsStat } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateLine,\n} from \"@caupulican/pi-agent-core/truncate\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core/types\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { waitForChildProcessWithTermination } from \"../../utils/child-process.ts\";\nimport type { ArtifactStore } from \"../context/context-artifacts.ts\";\nimport {\n\ttype BroadQueryTracker,\n\tbroadQueryInvalidationNote,\n\tformatArtifactNotice,\n\tnormalizeBroadQueryKey,\n\tpackToolOutput,\n} from \"../context/tool-output-packer.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport {\n\ttype FffGrepMatch,\n\ttype FffGrepResult,\n\ttype FffSearchBackend,\n\thasGitignoreInTree,\n\tresolveRoutedFffFinder,\n} from \"./fff-search-backend.ts\";\nimport { type ManagedSearchToolOptions, resolveManagedSearchTool } from \"./managed-search-tool.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatCollapsibleToolResult,\n\tinvalidArgText,\n\trenderTextComponent,\n\tshortenPath,\n\tstr,\n\ttoolTextResult,\n} from \"./render-utils.ts\";\nimport type { SearchRouter } from \"./search-router.ts\";\nimport { resolveSearchToolRuntime } from \"./search-tool-runtime.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\nconst GREP_PROCESS_TIMEOUT_MS = 5 * 60_000;\nconst GREP_PROCESS_KILL_GRACE_MS = 1_000;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n\t/** Set only when output was packed to an artifact; see tool-output-packer.ts. */\n\tartifactId?: string;\n\t/** Set when this exact query has repeatedly produced broad/truncated results. */\n\tinvalidationCandidate?: boolean;\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: async (p) => (await fsStat(p)).isDirectory(),\n\treadFile: (p) => fsReadFile(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions extends ManagedSearchToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus routed FFF/rg search */\n\toperations?: GrepOperations;\n\t/** FFF backend for resident indexed search. Set false to force ripgrep fallback. */\n\tfff?: FffSearchBackend | false;\n\t/** Pure router that selects FFF or rg from request filters and environment facts. */\n\tsearchRouter?: SearchRouter;\n\t/**\n\t * Opt-in artifact store for first-capture-then-bound output packing (Phase 3). When\n\t * omitted (the default), behavior is byte-for-byte unchanged from before this option\n\t * existed: output is truncated the same way, just never artifact-backed.\n\t */\n\tartifactStore?: ArtifactStore;\n\t/** Opt-in tracker for repeated-broad-query \"do not repeat\" signals. Also default-off. */\n\tbroadQueryTracker?: BroadQueryTracker;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: Theme,\n\tcwd: string,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\", cwd) : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\treturn formatCollapsibleToolResult({\n\t\tresult,\n\t\toptions,\n\t\ttheme,\n\t\tshowImages,\n\t\tcollapsedLineLimit: 15,\n\t\twarnings: (details) => {\n\t\t\tconst warnings: string[] = [];\n\t\t\tif (details?.matchLimitReached) warnings.push(`${details.matchLimitReached} matches limit`);\n\t\t\tif (details?.truncation?.truncated) {\n\t\t\t\twarnings.push(`${formatSize(details.truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\t\t}\n\t\t\tif (details?.linesTruncated) warnings.push(\"some lines truncated\");\n\t\t\treturn warnings;\n\t\t},\n\t});\n}\n\nfunction globConstraintForFff(glob: string | undefined): string {\n\tif (!glob) return \"\";\n\tif (glob.includes(\"/\") || glob.startsWith(\"**/\")) return glob;\n\treturn `**/${glob}`;\n}\n\nfunction fffGrepQuery(options: {\n\tpattern: string;\n\tglob?: string;\n\tisDirectory: boolean;\n\tsearchPathRelativeToCwd: string;\n}): string | undefined {\n\tconst parts: string[] = [];\n\tif (options.searchPathRelativeToCwd) {\n\t\tparts.push(options.isDirectory ? `${options.searchPathRelativeToCwd}/` : options.searchPathRelativeToCwd);\n\t}\n\tparts.push(globConstraintForFff(options.glob));\n\tparts.push(options.pattern);\n\treturn parts.filter(Boolean).join(\" \");\n}\n\nfunction fffDisplayPath(\n\tmatch: FffGrepMatch,\n\toptions: { isDirectory: boolean; searchPathRelativeToCwd: string },\n): string | undefined {\n\tconst relativePath = match.relativePath.replaceAll(\"\\\\\", \"/\");\n\tif (!options.searchPathRelativeToCwd) return relativePath;\n\tif (!options.isDirectory) {\n\t\treturn relativePath === options.searchPathRelativeToCwd ? path.posix.basename(relativePath) : undefined;\n\t}\n\tconst prefix = `${options.searchPathRelativeToCwd}/`;\n\tif (!relativePath.startsWith(prefix)) return undefined;\n\treturn relativePath.slice(prefix.length);\n}\n\nfunction appendFffMatchLines(options: {\n\tmatch: FffGrepMatch;\n\toutputLines: string[];\n\tlinesTruncated: { value: boolean };\n\tcontextValue: number;\n}): void {\n\tconst before = options.match.contextBefore ?? [];\n\tfor (let i = 0; i < before.length; i++) {\n\t\tconst lineNumber = options.match.lineNumber - before.length + i;\n\t\tconst { text, wasTruncated } = truncateLine(before[i] ?? \"\");\n\t\tif (wasTruncated) options.linesTruncated.value = true;\n\t\toptions.outputLines.push(` ${lineNumber}- ${text}`);\n\t}\n\n\tconst { text, wasTruncated } = truncateLine(options.match.lineContent.replace(/\\r/g, \"\"));\n\tif (wasTruncated) options.linesTruncated.value = true;\n\toptions.outputLines.push(` ${options.match.lineNumber}: ${text}`);\n\n\tif (options.contextValue === 0) return;\n\tconst after = options.match.contextAfter ?? [];\n\tfor (let i = 0; i < after.length; i++) {\n\t\tconst lineNumber = options.match.lineNumber + 1 + i;\n\t\tconst { text: contextText, wasTruncated: contextWasTruncated } = truncateLine(after[i] ?? \"\");\n\t\tif (contextWasTruncated) options.linesTruncated.value = true;\n\t\toptions.outputLines.push(` ${lineNumber}- ${contextText}`);\n\t}\n}\n\n/**\n * Shared \"measure -> pack -> notices\" tail for both the FFF and ripgrep result paths:\n * first-capture the raw output to an artifact if it's oversized and a store was provided\n * (Phase 3 tool-output-artifacts.md boundary rule), then append the same match-limit/\n * byte-limit/line-truncation/broad-query notices either path already produced.\n */\nfunction packGrepOutput(options: {\n\trawOutput: string;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\tpattern: string;\n\trawPath?: string;\n\tglob?: string;\n\tmatchLimitReached: number | false;\n\tlinesTruncated: boolean;\n}): { text: string; details: GrepToolDetails } {\n\tconst packed = packToolOutput(\n\t\t{\n\t\t\ttoolName: \"grep\",\n\t\t\tpath: options.rawPath,\n\t\t\trawContent: options.rawOutput,\n\t\t\t// No line limit here because the match limit already caps rows; only the byte\n\t\t\t// cap should apply, matching the pre-Slice-B truncateHead call exactly.\n\t\t\ttruncation: { maxLines: Number.MAX_SAFE_INTEGER },\n\t\t},\n\t\toptions.artifactStore,\n\t\toptions.toolCallId,\n\t);\n\tlet output = packed.content;\n\tconst details: GrepToolDetails = {};\n\n\tconst notices: string[] = [];\n\tif (packed.artifactId) {\n\t\tnotices.push(formatArtifactNotice(packed.artifactId));\n\t\tdetails.artifactId = packed.artifactId;\n\t}\n\tif (options.matchLimitReached) {\n\t\tnotices.push(\n\t\t\t`${options.matchLimitReached} matches limit reached. Use limit=${options.matchLimitReached * 2} for more, or refine pattern`,\n\t\t);\n\t\tdetails.matchLimitReached = options.matchLimitReached;\n\t}\n\tif (packed.truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t// Drop the duplicated bounded-preview text: it's already in the message's own\n\t\t// content, and re-including it here can push `details` past\n\t\t// MAX_RETAINED_TOOL_RESULT_DETAILS_BYTES (message-retention.ts), which replaces\n\t\t// the *entire* details object with a stub -- silently losing artifactId and every\n\t\t// other field alongside it. This is load-bearing beyond just the retention budget:\n\t\t// agent-session.ts's _releaseGcPackedArtifactReferences() reads artifactId back off\n\t\t// this same canonical message at eviction time (potentially many turns later), so\n\t\t// keeping `details` small here is what keeps that release path working at all. If\n\t\t// this field ever grows a large addition again, add a regression proving artifactId\n\t\t// survives compactToolResultDetailsForRetention (see\n\t\t// test/suite/agent-session-artifact-lifecycle.test.ts), not just a details-size check.\n\t\tdetails.truncation = { ...packed.truncation, content: \"\" };\n\t}\n\tif (options.linesTruncated) {\n\t\tnotices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);\n\t\tdetails.linesTruncated = true;\n\t}\n\tif (options.matchLimitReached || packed.truncation.truncated) {\n\t\tconst note = broadQueryInvalidationNote(\n\t\t\toptions.broadQueryTracker,\n\t\t\tnormalizeBroadQueryKey({\n\t\t\t\ttoolName: \"grep\",\n\t\t\t\tpattern: options.pattern,\n\t\t\t\tpath: options.rawPath,\n\t\t\t\tglob: options.glob,\n\t\t\t}),\n\t\t\t`grep \"${options.pattern}\" in ${options.rawPath ?? \".\"}`,\n\t\t);\n\t\tif (note) {\n\t\t\tnotices.push(note);\n\t\t\tdetails.invalidationCandidate = true;\n\t\t}\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn { text: output, details };\n}\n\nfunction formatFffGrepResult(options: {\n\tresult: FffGrepResult;\n\tisDirectory: boolean;\n\tsearchPathRelativeToCwd: string;\n\teffectiveLimit: number;\n\tcontextValue: number;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\tpattern: string;\n\trawPath?: string;\n\tglob?: string;\n}): { text: string; details: GrepToolDetails } {\n\tif (options.result.items.length === 0) return { text: \"No matches found\", details: {} };\n\n\tconst outputLines: string[] = [];\n\tconst linesTruncated = { value: false };\n\tconst resultLimitReached =\n\t\toptions.result.items.length > options.effectiveLimit || Boolean(options.result.nextCursor);\n\tconst displayedMatches = resultLimitReached\n\t\t? options.result.items.slice(0, options.effectiveLimit)\n\t\t: options.result.items;\n\tlet currentPath = \"\";\n\tfor (const match of displayedMatches) {\n\t\tconst displayPath = fffDisplayPath(match, options);\n\t\tif (!displayPath) continue;\n\t\tif (displayPath !== currentPath) {\n\t\t\tcurrentPath = displayPath;\n\t\t\toutputLines.push(`${displayPath}:`);\n\t\t}\n\t\tappendFffMatchLines({\n\t\t\tmatch,\n\t\t\toutputLines,\n\t\t\tlinesTruncated,\n\t\t\tcontextValue: options.contextValue,\n\t\t});\n\t}\n\n\tif (outputLines.length === 0) return { text: \"No matches found\", details: {} };\n\tconst rawOutput = outputLines.join(\"\\n\");\n\treturn packGrepOutput({\n\t\trawOutput,\n\t\ttoolCallId: options.toolCallId,\n\t\tartifactStore: options.artifactStore,\n\t\tbroadQueryTracker: options.broadQueryTracker,\n\t\tpattern: options.pattern,\n\t\trawPath: options.rawPath,\n\t\tglob: options.glob,\n\t\tmatchLimitReached: resultLimitReached ? options.effectiveLimit : false,\n\t\tlinesTruncated: linesTruncated.value,\n\t});\n}\n\nexport async function tryFffGrep(options: {\n\tbackend: FffSearchBackend;\n\trouter: SearchRouter;\n\tcwd: string;\n\tsearchPath: string;\n\tpattern: string;\n\tglob?: string;\n\tignoreCase?: boolean;\n\tliteral?: boolean;\n\tcontextValue: number;\n\teffectiveLimit: number;\n\tisDirectory: boolean;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\trawPath?: string;\n}): Promise<{ text: string; details: GrepToolDetails } | undefined> {\n\tconst routed = await resolveRoutedFffFinder({\n\t\tbackend: options.backend,\n\t\trouter: options.router,\n\t\ttool: \"grep\",\n\t\tcwd: options.cwd,\n\t\tsearchPath: options.searchPath,\n\t\tglob: Boolean(options.glob),\n\t\tignoreCase: Boolean(options.ignoreCase),\n\t\tlimit: options.effectiveLimit,\n\t\treadGitignoreInTree: () => (options.isDirectory ? hasGitignoreInTree(options.searchPath) : false),\n\t});\n\tif (!routed) return undefined;\n\tconst { finder, searchPathRelativeToCwd } = routed;\n\n\tconst query = fffGrepQuery({\n\t\tpattern: options.pattern,\n\t\tglob: options.glob,\n\t\tisDirectory: options.isDirectory,\n\t\tsearchPathRelativeToCwd,\n\t});\n\tif (!query) return undefined;\n\n\tconst probeLimit = options.effectiveLimit + 1;\n\tconst result = finder.grep(query, {\n\t\tmode: options.literal ? \"plain\" : \"regex\",\n\t\tsmartCase: false,\n\t\tmaxMatchesPerFile: probeLimit,\n\t\tbeforeContext: options.contextValue,\n\t\tafterContext: options.contextValue,\n\t\tpageSize: probeLimit,\n\t});\n\tif (!result.ok || result.value.regexFallbackError) return undefined;\n\treturn formatFffGrepResult({\n\t\tresult: result.value,\n\t\tisDirectory: options.isDirectory,\n\t\tsearchPathRelativeToCwd,\n\t\teffectiveLimit: options.effectiveLimit,\n\t\tcontextValue: options.contextValue,\n\t\ttoolCallId: options.toolCallId,\n\t\tartifactStore: options.artifactStore,\n\t\tbroadQueryTracker: options.broadQueryTracker,\n\t\tpattern: options.pattern,\n\t\trawPath: options.rawPath,\n\t\tglob: options.glob,\n\t});\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst search = resolveSearchToolRuntime(options);\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file text; respects .gitignore\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use narrowest known root/glob; discover paths first. Never repeatedly scan repo/home/filesystem.\",\n\t\t],\n\t\tparameters: grepSchema,\n\t\tasync execute(\n\t\t\ttoolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t}: {\n\t\t\t\tpattern: string;\n\t\t\t\tpath?: string;\n\t\t\t\tglob?: string;\n\t\t\t\tignoreCase?: boolean;\n\t\t\t\tliteral?: boolean;\n\t\t\t\tcontext?: number;\n\t\t\t\tlimit?: number;\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = search.operations ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) {\n\t\t\t\t\t\t\t\t\treturn relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (!search.operations && search.fffBackend) {\n\t\t\t\t\t\t\tconst fffResult = await tryFffGrep({\n\t\t\t\t\t\t\t\tbackend: search.fffBackend,\n\t\t\t\t\t\t\t\trouter: search.searchRouter,\n\t\t\t\t\t\t\t\tcwd,\n\t\t\t\t\t\t\t\tsearchPath,\n\t\t\t\t\t\t\t\tpattern,\n\t\t\t\t\t\t\t\tglob,\n\t\t\t\t\t\t\t\tignoreCase,\n\t\t\t\t\t\t\t\tliteral,\n\t\t\t\t\t\t\t\tcontextValue,\n\t\t\t\t\t\t\t\teffectiveLimit,\n\t\t\t\t\t\t\t\tisDirectory,\n\t\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\t\tartifactStore: search.artifactStore,\n\t\t\t\t\t\t\t\tbroadQueryTracker: search.broadQueryTracker,\n\t\t\t\t\t\t\t\trawPath: searchDir,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (fffResult) {\n\t\t\t\t\t\t\t\tsettle(() => resolve(toolTextResult(fffResult)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rgPath = await resolveManagedSearchTool(\"rg\", options?.managedToolResolver);\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(\"--\", pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, {\n\t\t\t\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst terminationController = new AbortController();\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (dueToLimit) killedDueToLimit = true;\n\t\t\t\t\t\t\tterminationController.abort();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (signal?.aborted) onAbort();\n\t\t\t\t\t\telse signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [`${relativePath}:${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${relativePath}:${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${relativePath}-${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number; lineText?: string }> = [];\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || matchLimitReached) return;\n\t\t\t\t\t\t\tlet event: any;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.type === \"match\") {\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tif (matchCount > effectiveLimit) {\n\t\t\t\t\t\t\t\t\tmatchLimitReached = true;\n\t\t\t\t\t\t\t\t\tstopChild(true);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tconst lineText = event.data?.lines?.text;\n\t\t\t\t\t\t\t\tif (filePath && typeof lineNumber === \"number\")\n\t\t\t\t\t\t\t\t\tmatches.push({ filePath, lineNumber, lineText });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst terminal = await waitForChildProcessWithTermination(child, {\n\t\t\t\t\t\t\tsignal: terminationController.signal,\n\t\t\t\t\t\t\ttimeoutMs: GREP_PROCESS_TIMEOUT_MS,\n\t\t\t\t\t\t\tkillGraceMs: GREP_PROCESS_KILL_GRACE_MS,\n\t\t\t\t\t\t}).finally(cleanup);\n\t\t\t\t\t\tconst code = terminal.code;\n\t\t\t\t\t\tif (terminal.reason === \"timeout\") {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`ripgrep timed out after ${GREP_PROCESS_TIMEOUT_MS}ms`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Format matches after streaming finishes so custom readFile() backends can be async.\n\t\t\t\t\t\tconst fileGroups = new Map<string, string[]>();\n\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\tconst relativePath = formatPath(match.filePath);\n\t\t\t\t\t\t\tif (!fileGroups.has(relativePath)) {\n\t\t\t\t\t\t\t\tfileGroups.set(relativePath, []);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst group = fileGroups.get(relativePath)!;\n\n\t\t\t\t\t\t\tif (contextValue === 0 && match.lineText !== undefined) {\n\t\t\t\t\t\t\t\tconst sanitized = match.lineText.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\").replace(/\\n$/, \"\");\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tgroup.push(` ${match.lineNumber}: ${truncatedText}`);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\tfor (const line of block) {\n\t\t\t\t\t\t\t\t\tif (line.startsWith(`${relativePath}:`)) {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line.slice(relativePath.length + 1)}`);\n\t\t\t\t\t\t\t\t\t} else if (line.startsWith(`${relativePath}-`)) {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line.slice(relativePath.length + 1)}`);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line}`);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (const [relativePath, lines] of fileGroups) {\n\t\t\t\t\t\t\toutputLines.push(`${relativePath}:`);\n\t\t\t\t\t\t\tlet lastLine = \"\";\n\t\t\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\t\t\tif (line === lastLine) continue;\n\t\t\t\t\t\t\t\toutputLines.push(line);\n\t\t\t\t\t\t\t\tlastLine = line;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t// Measure -> pack (artifact-backed if oversized and a store was provided) -> notices.\n\t\t\t\t\t\t// There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\tconst { text: output, details } = packGrepOutput({\n\t\t\t\t\t\t\trawOutput,\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\tartifactStore: search.artifactStore,\n\t\t\t\t\t\t\tbroadQueryTracker: search.broadQueryTracker,\n\t\t\t\t\t\t\tpattern,\n\t\t\t\t\t\t\trawPath: searchDir,\n\t\t\t\t\t\t\tglob,\n\t\t\t\t\t\t\tmatchLimitReached: matchLimitReached ? effectiveLimit : false,\n\t\t\t\t\t\t\tlinesTruncated,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tsettle(() => resolve(toolTextResult({ text: output, details })));\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\treturn renderTextComponent(context.lastComponent, formatGrepCall(args, theme, context.cwd));\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\treturn renderTextComponent(\n\t\t\t\tcontext.lastComponent,\n\t\t\t\tformatGrepResult(result as Parameters<typeof formatGrepResult>[0], options, theme, context.showImages),\n\t\t\t);\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../../src/core/tools/ls.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,oCAAoC,CAAC;AAExH,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAEN,KAAK,4BAA4B,EAEjC,MAAM,4BAA4B,CAAC;AAWpC,QAAA,MAAM,QAAQ;;;;EAIZ,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC;AAIlD,MAAM,WAAW,aAAa;IAC7B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC5B,2BAA2B;IAC3B,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7D,wDAAwD;IACxD,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;IACrE,6BAA6B;IAC7B,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;CAChE;AAQD,MAAM,WAAW,aAAa;IAC7B,yEAAyE;IACzE,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,oFAAoF;IACpF,wBAAwB,CAAC,EAAE,4BAA4B,CAAC;CACxD;AA+CD,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,aAAa,GACrB,cAAc,CAAC,OAAO,QAAQ,EAAE,aAAa,GAAG,SAAS,CAAC,CAgK5D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC,OAAO,QAAQ,CAAC,CAE7F"}
1
+ {"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../../src/core/tools/ls.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,oCAAoC,CAAC;AAExH,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAEN,KAAK,4BAA4B,EAEjC,MAAM,4BAA4B,CAAC;AAWpC,QAAA,MAAM,QAAQ;;;;EAIZ,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC;AAIlD,MAAM,WAAW,aAAa;IAC7B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC5B,2BAA2B;IAC3B,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7D,wDAAwD;IACxD,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;IACrE,6BAA6B;IAC7B,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;CAChE;AAQD,MAAM,WAAW,aAAa;IAC7B,yEAAyE;IACzE,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,oFAAoF;IACpF,wBAAwB,CAAC,EAAE,4BAA4B,CAAC;CACxD;AA+CD,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,aAAa,GACrB,cAAc,CAAC,OAAO,QAAQ,EAAE,aAAa,GAAG,SAAS,CAAC,CA+J5D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC,OAAO,QAAQ,CAAC,CAE7F"}
@@ -73,7 +73,6 @@ export function createLsToolDefinition(cwd, options) {
73
73
  ]
74
74
  : [],
75
75
  },
76
- toolGroup: "explore",
77
76
  async execute(_toolCallId, { path, limit, metadata }, signal, _onUpdate, _ctx) {
78
77
  return new Promise((resolve, reject) => {
79
78
  if (signal?.aborted) {
@@ -1 +1 @@
1
- {"version":3,"file":"ls.js","sourceRoot":"","sources":["../../../src/core/tools/ls.ts"],"names":[],"mappings":"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","sourcesContent":["import { readdir as fsReaddir, stat as fsStat } from \"node:fs/promises\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"@caupulican/pi-agent-core/truncate\";\nimport nodePath from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport {\n\tFILE_EXISTS_RECOVERY_TARGET_KIND,\n\ttype FileFailureRecoveryAuthority,\n\tselectFileFailureRecoveryAuthority,\n} from \"./file-failure-recovery.ts\";\nimport { pathExists, resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatCollapsibleToolResult,\n\trenderTextComponent,\n\trenderToolPath,\n\tstr,\n\ttoolTextResult,\n} from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst lsSchema = Type.Object({\n\tpath: Type.Optional(Type.String({ description: \"Directory to list (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of entries to return (default: 500)\" })),\n\tmetadata: Type.Optional(Type.Boolean({ description: \"Include file size and permission metadata (default: false)\" })),\n});\n\nexport type LsToolInput = Static<typeof lsSchema>;\n\nconst DEFAULT_LIMIT = 500;\n\nexport interface LsToolDetails {\n\ttruncation?: TruncationResult;\n\tentryLimitReached?: number;\n}\n\n/**\n * Pluggable operations for the ls tool.\n * Override these to delegate directory listing to remote systems (for example SSH).\n */\nexport interface LsEntryStats {\n\tisDirectory: () => boolean;\n\tsize?: number;\n\tmode?: number;\n}\n\nexport interface LsOperations {\n\t/** Check if path exists */\n\texists: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Get file or directory stats. Throws if not found. */\n\tstat: (absolutePath: string) => Promise<LsEntryStats> | LsEntryStats;\n\t/** Read directory entries */\n\treaddir: (absolutePath: string) => Promise<string[]> | string[];\n}\n\nconst defaultLsOperations: LsOperations = {\n\texists: pathExists,\n\tstat: fsStat,\n\treaddir: fsReaddir,\n};\n\nexport interface LsToolOptions {\n\t/** Custom operations for directory listing. Default: local filesystem */\n\toperations?: LsOperations;\n\t/** Shared backend identity for exact cross-tool recovery with custom operations. */\n\tfailureRecoveryAuthority?: FileFailureRecoveryAuthority;\n}\n\nfunction formatLsCall(args: { path?: string; limit?: number } | undefined, theme: Theme, cwd: string): string {\n\tconst limit = args?.limit;\n\tconst pathDisplay = renderToolPath(str(args?.path), theme, cwd, { emptyFallback: \".\" });\n\tlet text = `${theme.fg(\"toolTitle\", theme.bold(\"ls\"))} ${pathDisplay}`;\n\tif (limit !== undefined) {\n\t\ttext += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n\t}\n\treturn text;\n}\n\nfunction formatLsResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: LsToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\treturn formatCollapsibleToolResult({\n\t\tresult,\n\t\toptions,\n\t\ttheme,\n\t\tshowImages,\n\t\tcollapsedLineLimit: 20,\n\t\twarnings: (details) => {\n\t\t\tconst warnings: string[] = [];\n\t\t\tif (details?.entryLimitReached) warnings.push(`${details.entryLimitReached} entries limit`);\n\t\t\tif (details?.truncation?.truncated) {\n\t\t\t\twarnings.push(`${formatSize(details.truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\t\t}\n\t\t\treturn warnings;\n\t\t},\n\t});\n}\n\nfunction getPermissionString(mode: number, isDirectory: boolean): string {\n\tconst typeChar = isDirectory ? \"d\" : \"-\";\n\tconst rwx = (m: number) => [m & 4 ? \"r\" : \"-\", m & 2 ? \"w\" : \"-\", m & 1 ? \"x\" : \"-\"].join(\"\");\n\tconst owner = rwx((mode >> 6) & 7);\n\tconst group = rwx((mode >> 3) & 7);\n\tconst others = rwx(mode & 7);\n\treturn `${typeChar}${owner}${group}${others}`;\n}\n\nexport function createLsToolDefinition(\n\tcwd: string,\n\toptions?: LsToolOptions,\n): ToolDefinition<typeof lsSchema, LsToolDetails | undefined> {\n\tconst ops = options?.operations ?? defaultLsOperations;\n\tconst failureRecoveryAuthority = selectFileFailureRecoveryAuthority(\n\t\toptions?.operations !== undefined,\n\t\toptions?.failureRecoveryAuthority,\n\t);\n\treturn {\n\t\tname: \"ls\",\n\t\tlabel: \"ls\",\n\t\tdescription: `List directory contents. Returns entries sorted alphabetically, with '/' suffix for directories. Includes dotfiles. Output is truncated to ${DEFAULT_LIMIT} entries or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n\t\tpromptSnippet: \"List directory contents\",\n\t\tparameters: lsSchema,\n\t\tfailureRecovery: {\n\t\t\tactions: failureRecoveryAuthority\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: \"correct\",\n\t\t\t\t\t\t\tauthority: failureRecoveryAuthority.contractAuthority,\n\t\t\t\t\t\t\ttargetKind: FILE_EXISTS_RECOVERY_TARGET_KIND,\n\t\t\t\t\t\t\tinstruction:\n\t\t\t\t\t\t\t\t\"Use ls on the parent directory to find the actual entry, then submit a changed path.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t: [],\n\t\t},\n\t\ttoolGroup: \"explore\",\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ path, limit, metadata }: { path?: string; limit?: number; metadata?: boolean },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst onAbort = () => reject(new Error(\"Operation aborted\"));\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst dirPath = resolveToCwd(path || \".\", cwd);\n\t\t\t\t\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\n\n\t\t\t\t\t\t// Check if path exists.\n\t\t\t\t\t\tif (!(await ops.exists(dirPath))) {\n\t\t\t\t\t\t\treject(new Error(`Path not found: ${dirPath}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Check if path is a directory.\n\t\t\t\t\t\tconst stat = await ops.stat(dirPath);\n\t\t\t\t\t\tif (!stat.isDirectory()) {\n\t\t\t\t\t\t\treject(new Error(`Not a directory: ${dirPath}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Read directory entries.\n\t\t\t\t\t\tlet entries: string[];\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tentries = await ops.readdir(dirPath);\n\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\treject(new Error(`Cannot read directory: ${e.message}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Sort alphabetically, case-insensitive.\n\t\t\t\t\t\tentries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));\n\n\t\t\t\t\t\t// Format entries with directory indicators.\n\t\t\t\t\t\tconst results: string[] = [];\n\t\t\t\t\t\tlet entryLimitReached = false;\n\t\t\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\t\t\tif (results.length >= effectiveLimit) {\n\t\t\t\t\t\t\t\tentryLimitReached = true;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst fullPath = nodePath.join(dirPath, entry);\n\t\t\t\t\t\t\tlet suffix = \"\";\n\t\t\t\t\t\t\tlet sizeStr = \"\";\n\t\t\t\t\t\t\tlet modeStr = \"\";\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst entryStat = await ops.stat(fullPath);\n\t\t\t\t\t\t\t\tconst isDir = entryStat.isDirectory();\n\t\t\t\t\t\t\t\tif (isDir) suffix = \"/\";\n\n\t\t\t\t\t\t\t\tif (metadata) {\n\t\t\t\t\t\t\t\t\tif (isDir) {\n\t\t\t\t\t\t\t\t\t\tsizeStr = \" -\";\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst sizeVal = entryStat.size ?? 0;\n\t\t\t\t\t\t\t\t\t\tsizeStr = formatSize(sizeVal).padStart(7);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (typeof entryStat.mode === \"number\") {\n\t\t\t\t\t\t\t\t\t\tmodeStr = getPermissionString(entryStat.mode, isDir);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tmodeStr = isDir ? \"d---------\" : \"----------\";\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tif (metadata) {\n\t\t\t\t\t\t\t\t\tsizeStr = \"???????\";\n\t\t\t\t\t\t\t\t\tmodeStr = \"??????????\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (metadata) {\n\t\t\t\t\t\t\t\tresults.push(`${modeStr} ${sizeStr} ${entry}${suffix}`);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresults.push(entry + suffix);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\n\t\t\t\t\t\tif (results.length === 0) {\n\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"(empty directory)\" }], details: undefined });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rawOutput = results.join(\"\\n\");\n\t\t\t\t\t\t// Apply byte truncation. There is no separate line limit because entry count is already capped.\n\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\tconst details: LsToolDetails = {};\n\t\t\t\t\t\t// Build actionable notices for truncation and entry limits.\n\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\tif (entryLimitReached) {\n\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);\n\t\t\t\t\t\t\tdetails.entryLimitReached = effectiveLimit;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\toutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresolve(toolTextResult({ text: output, details }));\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\treject(e);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\treturn renderTextComponent(context.lastComponent, formatLsCall(args, theme, context.cwd));\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\treturn renderTextComponent(\n\t\t\t\tcontext.lastComponent,\n\t\t\t\tformatLsResult(result as Parameters<typeof formatLsResult>[0], options, theme, context.showImages),\n\t\t\t);\n\t\t},\n\t};\n}\n\nexport function createLsTool(cwd: string, options?: LsToolOptions): AgentTool<typeof lsSchema> {\n\treturn wrapToolDefinition(createLsToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"ls.js","sourceRoot":"","sources":["../../../src/core/tools/ls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,IAAI,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAExE,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAyB,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACxH,OAAO,QAAQ,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,EACN,gCAAgC,EAEhC,kCAAkC,GAClC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EACN,2BAA2B,EAC3B,mBAAmB,EACnB,cAAc,EACd,GAAG,EACH,cAAc,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC;IAC5B,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,gDAAgD,EAAE,CAAC,CAAC;IACnG,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,oDAAoD,EAAE,CAAC,CAAC;IACxG,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,4DAA4D,EAAE,CAAC,CAAC;CACpH,CAAC,CAAC;AAIH,MAAM,aAAa,GAAG,GAAG,CAAC;AA0B1B,MAAM,mBAAmB,GAAiB;IACzC,MAAM,EAAE,UAAU;IAClB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;CAClB,CAAC;AASF,SAAS,YAAY,CAAC,IAAmD,EAAE,KAAY,EAAE,GAAW;IACnG,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;IAC1B,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;IACxF,IAAI,IAAI,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC;IACvE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,WAAW,KAAK,GAAG,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,cAAc,CACtB,MAGC,EACD,OAAgC,EAChC,KAAY,EACZ,UAAmB;IAEnB,OAAO,2BAA2B,CAAC;QAClC,MAAM;QACN,OAAO;QACP,KAAK;QACL,UAAU;QACV,kBAAkB,EAAE,EAAE;QACtB,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE;YACrB,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,IAAI,OAAO,EAAE,iBAAiB;gBAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,iBAAiB,gBAAgB,CAAC,CAAC;YAC5F,IAAI,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;gBACpC,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,IAAI,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YACxF,CAAC;YACD,OAAO,QAAQ,CAAC;QACjB,CAAC;KACD,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY,EAAE,WAAoB;IAC9D,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACzC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9F,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAC7B,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,sBAAsB,CACrC,GAAW,EACX,OAAuB;IAEvB,MAAM,GAAG,GAAG,OAAO,EAAE,UAAU,IAAI,mBAAmB,CAAC;IACvD,MAAM,wBAAwB,GAAG,kCAAkC,CAClE,OAAO,EAAE,UAAU,KAAK,SAAS,EACjC,OAAO,EAAE,wBAAwB,CACjC,CAAC;IACF,OAAO;QACN,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,WAAW,EAAE,8IAA8I,aAAa,eAAe,iBAAiB,GAAG,IAAI,8BAA8B;QAC7O,aAAa,EAAE,yBAAyB;QACxC,UAAU,EAAE,QAAQ;QACpB,eAAe,EAAE;YAChB,OAAO,EAAE,wBAAwB;gBAChC,CAAC,CAAC;oBACA;wBACC,IAAI,EAAE,SAAS;wBACf,SAAS,EAAE,wBAAwB,CAAC,iBAAiB;wBACrD,UAAU,EAAE,gCAAgC;wBAC5C,WAAW,EACV,sFAAsF;qBACvF;iBACD;gBACF,CAAC,CAAC,EAAE;SACL;QACD,KAAK,CAAC,OAAO,CACZ,WAAW,EACX,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAyD,EAChF,MAAoB,EACpB,SAAU,EACV,IAAK;YAEL,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACtC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;oBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;oBACvC,OAAO;gBACR,CAAC;gBAED,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBAC7D,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBAE3D,CAAC,KAAK,IAAI,EAAE;oBACX,IAAI,CAAC;wBACJ,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;wBAC/C,MAAM,cAAc,GAAG,KAAK,IAAI,aAAa,CAAC;wBAE9C,wBAAwB;wBACxB,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;4BAClC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAC,CAAC;4BAChD,OAAO;wBACR,CAAC;wBAED,gCAAgC;wBAChC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBACrC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;4BACzB,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC,CAAC;4BACjD,OAAO;wBACR,CAAC;wBAED,0BAA0B;wBAC1B,IAAI,OAAiB,CAAC;wBACtB,IAAI,CAAC;4BACJ,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;wBACtC,CAAC;wBAAC,OAAO,CAAM,EAAE,CAAC;4BACjB,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;4BACzD,OAAO;wBACR,CAAC;wBAED,yCAAyC;wBACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;wBAEvE,4CAA4C;wBAC5C,MAAM,OAAO,GAAa,EAAE,CAAC;wBAC7B,IAAI,iBAAiB,GAAG,KAAK,CAAC;wBAC9B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;4BAC7B,IAAI,OAAO,CAAC,MAAM,IAAI,cAAc,EAAE,CAAC;gCACtC,iBAAiB,GAAG,IAAI,CAAC;gCACzB,MAAM;4BACP,CAAC;4BAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;4BAC/C,IAAI,MAAM,GAAG,EAAE,CAAC;4BAChB,IAAI,OAAO,GAAG,EAAE,CAAC;4BACjB,IAAI,OAAO,GAAG,EAAE,CAAC;4BACjB,IAAI,CAAC;gCACJ,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gCAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;gCACtC,IAAI,KAAK;oCAAE,MAAM,GAAG,GAAG,CAAC;gCAExB,IAAI,QAAQ,EAAE,CAAC;oCACd,IAAI,KAAK,EAAE,CAAC;wCACX,OAAO,GAAG,OAAO,CAAC;oCACnB,CAAC;yCAAM,CAAC;wCACP,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,IAAI,CAAC,CAAC;wCACpC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oCAC3C,CAAC;oCACD,IAAI,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wCACxC,OAAO,GAAG,mBAAmB,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;oCACtD,CAAC;yCAAM,CAAC;wCACP,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;oCAC/C,CAAC;gCACF,CAAC;4BACF,CAAC;4BAAC,MAAM,CAAC;gCACR,IAAI,QAAQ,EAAE,CAAC;oCACd,OAAO,GAAG,SAAS,CAAC;oCACpB,OAAO,GAAG,YAAY,CAAC;gCACxB,CAAC;4BACF,CAAC;4BACD,IAAI,QAAQ,EAAE,CAAC;gCACd,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,KAAK,OAAO,KAAK,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;4BAC3D,CAAC;iCAAM,CAAC;gCACP,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;4BAC9B,CAAC;wBACF,CAAC;wBAED,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBAE9C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;4BAC1B,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;4BACxF,OAAO;wBACR,CAAC;wBAED,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACrC,gGAAgG;wBAChG,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;wBAClF,IAAI,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC;wBAChC,MAAM,OAAO,GAAkB,EAAE,CAAC;wBAClC,4DAA4D;wBAC5D,MAAM,OAAO,GAAa,EAAE,CAAC;wBAC7B,IAAI,iBAAiB,EAAE,CAAC;4BACvB,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,qCAAqC,cAAc,GAAG,CAAC,WAAW,CAAC,CAAC;4BAClG,OAAO,CAAC,iBAAiB,GAAG,cAAc,CAAC;wBAC5C,CAAC;wBACD,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;4BAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;4BAC/D,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;wBACjC,CAAC;wBACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACxB,MAAM,IAAI,QAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;wBACzC,CAAC;wBAED,OAAO,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;oBACpD,CAAC;oBAAC,OAAO,CAAM,EAAE,CAAC;wBACjB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBAC9C,MAAM,CAAC,CAAC,CAAC,CAAC;oBACX,CAAC;gBACF,CAAC,CAAC,EAAE,CAAC;YACN,CAAC,CAAC,CAAC;QACJ,CAAC;QACD,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO;YAC9B,OAAO,mBAAmB,CAAC,OAAO,CAAC,aAAa,EAAE,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3F,CAAC;QACD,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;YAC3C,OAAO,mBAAmB,CACzB,OAAO,CAAC,aAAa,EACrB,cAAc,CAAC,MAA8C,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAClG,CAAC;QACH,CAAC;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,OAAuB;IAChE,OAAO,kBAAkB,CAAC,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AACjE,CAAC","sourcesContent":["import { readdir as fsReaddir, stat as fsStat } from \"node:fs/promises\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"@caupulican/pi-agent-core/truncate\";\nimport nodePath from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport {\n\tFILE_EXISTS_RECOVERY_TARGET_KIND,\n\ttype FileFailureRecoveryAuthority,\n\tselectFileFailureRecoveryAuthority,\n} from \"./file-failure-recovery.ts\";\nimport { pathExists, resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatCollapsibleToolResult,\n\trenderTextComponent,\n\trenderToolPath,\n\tstr,\n\ttoolTextResult,\n} from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst lsSchema = Type.Object({\n\tpath: Type.Optional(Type.String({ description: \"Directory to list (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of entries to return (default: 500)\" })),\n\tmetadata: Type.Optional(Type.Boolean({ description: \"Include file size and permission metadata (default: false)\" })),\n});\n\nexport type LsToolInput = Static<typeof lsSchema>;\n\nconst DEFAULT_LIMIT = 500;\n\nexport interface LsToolDetails {\n\ttruncation?: TruncationResult;\n\tentryLimitReached?: number;\n}\n\n/**\n * Pluggable operations for the ls tool.\n * Override these to delegate directory listing to remote systems (for example SSH).\n */\nexport interface LsEntryStats {\n\tisDirectory: () => boolean;\n\tsize?: number;\n\tmode?: number;\n}\n\nexport interface LsOperations {\n\t/** Check if path exists */\n\texists: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Get file or directory stats. Throws if not found. */\n\tstat: (absolutePath: string) => Promise<LsEntryStats> | LsEntryStats;\n\t/** Read directory entries */\n\treaddir: (absolutePath: string) => Promise<string[]> | string[];\n}\n\nconst defaultLsOperations: LsOperations = {\n\texists: pathExists,\n\tstat: fsStat,\n\treaddir: fsReaddir,\n};\n\nexport interface LsToolOptions {\n\t/** Custom operations for directory listing. Default: local filesystem */\n\toperations?: LsOperations;\n\t/** Shared backend identity for exact cross-tool recovery with custom operations. */\n\tfailureRecoveryAuthority?: FileFailureRecoveryAuthority;\n}\n\nfunction formatLsCall(args: { path?: string; limit?: number } | undefined, theme: Theme, cwd: string): string {\n\tconst limit = args?.limit;\n\tconst pathDisplay = renderToolPath(str(args?.path), theme, cwd, { emptyFallback: \".\" });\n\tlet text = `${theme.fg(\"toolTitle\", theme.bold(\"ls\"))} ${pathDisplay}`;\n\tif (limit !== undefined) {\n\t\ttext += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n\t}\n\treturn text;\n}\n\nfunction formatLsResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: LsToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\treturn formatCollapsibleToolResult({\n\t\tresult,\n\t\toptions,\n\t\ttheme,\n\t\tshowImages,\n\t\tcollapsedLineLimit: 20,\n\t\twarnings: (details) => {\n\t\t\tconst warnings: string[] = [];\n\t\t\tif (details?.entryLimitReached) warnings.push(`${details.entryLimitReached} entries limit`);\n\t\t\tif (details?.truncation?.truncated) {\n\t\t\t\twarnings.push(`${formatSize(details.truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\t\t}\n\t\t\treturn warnings;\n\t\t},\n\t});\n}\n\nfunction getPermissionString(mode: number, isDirectory: boolean): string {\n\tconst typeChar = isDirectory ? \"d\" : \"-\";\n\tconst rwx = (m: number) => [m & 4 ? \"r\" : \"-\", m & 2 ? \"w\" : \"-\", m & 1 ? \"x\" : \"-\"].join(\"\");\n\tconst owner = rwx((mode >> 6) & 7);\n\tconst group = rwx((mode >> 3) & 7);\n\tconst others = rwx(mode & 7);\n\treturn `${typeChar}${owner}${group}${others}`;\n}\n\nexport function createLsToolDefinition(\n\tcwd: string,\n\toptions?: LsToolOptions,\n): ToolDefinition<typeof lsSchema, LsToolDetails | undefined> {\n\tconst ops = options?.operations ?? defaultLsOperations;\n\tconst failureRecoveryAuthority = selectFileFailureRecoveryAuthority(\n\t\toptions?.operations !== undefined,\n\t\toptions?.failureRecoveryAuthority,\n\t);\n\treturn {\n\t\tname: \"ls\",\n\t\tlabel: \"ls\",\n\t\tdescription: `List directory contents. Returns entries sorted alphabetically, with '/' suffix for directories. Includes dotfiles. Output is truncated to ${DEFAULT_LIMIT} entries or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n\t\tpromptSnippet: \"List directory contents\",\n\t\tparameters: lsSchema,\n\t\tfailureRecovery: {\n\t\t\tactions: failureRecoveryAuthority\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind: \"correct\",\n\t\t\t\t\t\t\tauthority: failureRecoveryAuthority.contractAuthority,\n\t\t\t\t\t\t\ttargetKind: FILE_EXISTS_RECOVERY_TARGET_KIND,\n\t\t\t\t\t\t\tinstruction:\n\t\t\t\t\t\t\t\t\"Use ls on the parent directory to find the actual entry, then submit a changed path.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t: [],\n\t\t},\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ path, limit, metadata }: { path?: string; limit?: number; metadata?: boolean },\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst onAbort = () => reject(new Error(\"Operation aborted\"));\n\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst dirPath = resolveToCwd(path || \".\", cwd);\n\t\t\t\t\t\tconst effectiveLimit = limit ?? DEFAULT_LIMIT;\n\n\t\t\t\t\t\t// Check if path exists.\n\t\t\t\t\t\tif (!(await ops.exists(dirPath))) {\n\t\t\t\t\t\t\treject(new Error(`Path not found: ${dirPath}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Check if path is a directory.\n\t\t\t\t\t\tconst stat = await ops.stat(dirPath);\n\t\t\t\t\t\tif (!stat.isDirectory()) {\n\t\t\t\t\t\t\treject(new Error(`Not a directory: ${dirPath}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Read directory entries.\n\t\t\t\t\t\tlet entries: string[];\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tentries = await ops.readdir(dirPath);\n\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\treject(new Error(`Cannot read directory: ${e.message}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Sort alphabetically, case-insensitive.\n\t\t\t\t\t\tentries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));\n\n\t\t\t\t\t\t// Format entries with directory indicators.\n\t\t\t\t\t\tconst results: string[] = [];\n\t\t\t\t\t\tlet entryLimitReached = false;\n\t\t\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\t\t\tif (results.length >= effectiveLimit) {\n\t\t\t\t\t\t\t\tentryLimitReached = true;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst fullPath = nodePath.join(dirPath, entry);\n\t\t\t\t\t\t\tlet suffix = \"\";\n\t\t\t\t\t\t\tlet sizeStr = \"\";\n\t\t\t\t\t\t\tlet modeStr = \"\";\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst entryStat = await ops.stat(fullPath);\n\t\t\t\t\t\t\t\tconst isDir = entryStat.isDirectory();\n\t\t\t\t\t\t\t\tif (isDir) suffix = \"/\";\n\n\t\t\t\t\t\t\t\tif (metadata) {\n\t\t\t\t\t\t\t\t\tif (isDir) {\n\t\t\t\t\t\t\t\t\t\tsizeStr = \" -\";\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst sizeVal = entryStat.size ?? 0;\n\t\t\t\t\t\t\t\t\t\tsizeStr = formatSize(sizeVal).padStart(7);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (typeof entryStat.mode === \"number\") {\n\t\t\t\t\t\t\t\t\t\tmodeStr = getPermissionString(entryStat.mode, isDir);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tmodeStr = isDir ? \"d---------\" : \"----------\";\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tif (metadata) {\n\t\t\t\t\t\t\t\t\tsizeStr = \"???????\";\n\t\t\t\t\t\t\t\t\tmodeStr = \"??????????\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (metadata) {\n\t\t\t\t\t\t\t\tresults.push(`${modeStr} ${sizeStr} ${entry}${suffix}`);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresults.push(entry + suffix);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\n\t\t\t\t\t\tif (results.length === 0) {\n\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"(empty directory)\" }], details: undefined });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rawOutput = results.join(\"\\n\");\n\t\t\t\t\t\t// Apply byte truncation. There is no separate line limit because entry count is already capped.\n\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\tconst details: LsToolDetails = {};\n\t\t\t\t\t\t// Build actionable notices for truncation and entry limits.\n\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\tif (entryLimitReached) {\n\t\t\t\t\t\t\tnotices.push(`${effectiveLimit} entries limit reached. Use limit=${effectiveLimit * 2} for more`);\n\t\t\t\t\t\t\tdetails.entryLimitReached = effectiveLimit;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\t\t\toutput += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresolve(toolTextResult({ text: output, details }));\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\treject(e);\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\treturn renderTextComponent(context.lastComponent, formatLsCall(args, theme, context.cwd));\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\treturn renderTextComponent(\n\t\t\t\tcontext.lastComponent,\n\t\t\t\tformatLsResult(result as Parameters<typeof formatLsResult>[0], options, theme, context.showImages),\n\t\t\t);\n\t\t},\n\t};\n}\n\nexport function createLsTool(cwd: string, options?: LsToolOptions): AgentTool<typeof lsSchema> {\n\treturn wrapToolDefinition(createLsToolDefinition(cwd, options));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"skill-audit.d.ts","sourceRoot":"","sources":["../../../src/core/tools/skill-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAY7D;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAU/C;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAQxD;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,cAAc,EAAE,KAAK,CAAC;QACrB,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH,mBAAmB,EAAE,KAAK,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH,cAAc,EAAE,KAAK,CAAC;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,EAAE,CAAC;KAChB,CAAC,CAAC;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC5B,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACjE,gBAAgB,CAqFlB;AAED,QAAA,MAAM,gBAAgB;;;;EAIpB,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE9D,MAAM,WAAW,qBAAqB;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;CAAG;AAEzC,wBAAgB,8BAA8B,CAC7C,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,qBAAqB,GAC9B,cAAc,CAAC,OAAO,gBAAgB,EAAE,gBAAgB,CAAC,CAyE3D;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC,OAAO,gBAAgB,CAAC,CAErH"}
1
+ {"version":3,"file":"skill-audit.d.ts","sourceRoot":"","sources":["../../../src/core/tools/skill-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAY7D;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAU/C;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAQxD;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,cAAc,EAAE,KAAK,CAAC;QACrB,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH,mBAAmB,EAAE,KAAK,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH,cAAc,EAAE,KAAK,CAAC;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,EAAE,CAAC;KAChB,CAAC,CAAC;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC5B,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACjE,gBAAgB,CAqFlB;AAED,QAAA,MAAM,gBAAgB;;;;EAIpB,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE9D,MAAM,WAAW,qBAAqB;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;CAAG;AAEzC,wBAAgB,8BAA8B,CAC7C,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,qBAAqB,GAC9B,cAAc,CAAC,OAAO,gBAAgB,EAAE,gBAAgB,CAAC,CAwE3D;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC,OAAO,gBAAgB,CAAC,CAErH"}
@@ -120,7 +120,6 @@ export function createSkillAuditToolDefinition(cwd, _options) {
120
120
  return {
121
121
  name: "skill_audit",
122
122
  label: "Skill Audit",
123
- toolGroup: "skills",
124
123
  description: "Check a draft/new skill for overlap with existing skills before creating it; flags near-duplicate triggers/descriptions via local Jaccard similarity. Read-only: does not write files.",
125
124
  promptSnippet: "Audit skill for overlaps",
126
125
  promptGuidelines: [
@@ -1 +1 @@
1
- {"version":3,"file":"skill-audit.js","sourceRoot":"","sources":["../../../src/core/tools/skill-audit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport { getAgentDir } from \"../../config.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { loadSkills, type Skill } from \"../skills.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst DUPLICATE_THRESHOLD = 0.55;\n\nconst STOPWORDS = new Set(\n\t\"the a an and or of for to with when use using from into this that skill task work working project agent agents code files file in on by as is are be do not should about\".split(\n\t\t\" \",\n\t),\n);\n\n/**\n * Tokenize text by lowercasing, removing non-alphanumeric chars (except hyphens and colons),\n * splitting on whitespace, and filtering out short tokens and stopwords.\n */\nexport function tokenize(text: string): string[] {\n\treturn [\n\t\t...new Set(\n\t\t\ttext\n\t\t\t\t.toLowerCase()\n\t\t\t\t.replace(/[^a-z0-9:-]+/g, \" \")\n\t\t\t\t.split(/\\s+/)\n\t\t\t\t.filter((token) => token.length >= 3 && !STOPWORDS.has(token)),\n\t\t),\n\t];\n}\n\n/**\n * Calculate Jaccard similarity between two token sets.\n * Jaccard(A, B) = |A ∩ B| / |A ∪ B|\n */\nexport function jaccard(a: string[], b: string[]): number {\n\tif (a.length === 0 || b.length === 0) return 0;\n\tconst setA = new Set(a);\n\tconst setB = new Set(b);\n\tlet intersection = 0;\n\tfor (const item of setA) if (setB.has(item)) intersection++;\n\tconst union = new Set([...a, ...b]).size;\n\treturn union === 0 ? 0 : intersection / union;\n}\n\nexport interface SkillSummary {\n\tname: string;\n\tdescription: string;\n\tpath: string;\n\tscope: string;\n\tkeywords: string[];\n}\n\nexport interface SkillAuditReport {\n\tgeneratedAt: string;\n\tskills: SkillSummary[];\n\tnearDuplicates: Array<{\n\t\ta: string;\n\t\tb: string;\n\t\tsimilarity: number;\n\t\treason: string;\n\t}>;\n\tcompartmentWarnings: Array<{\n\t\tskill: string;\n\t\tpath: string;\n\t\treason: string;\n\t}>;\n\tnameCollisions: Array<{\n\t\tname: string;\n\t\tpaths: string[];\n\t}>;\n\trecommendations?: string[];\n}\n\n/**\n * Audit existing skills for overlap and compare against a draft skill.\n */\nexport function runSkillAudit(\n\tcwd: string,\n\tdraftSkill?: { name?: string; description?: string; body?: string },\n): SkillAuditReport {\n\t// Load existing skills\n\tconst result = loadSkills({\n\t\tcwd,\n\t\tagentDir: getAgentDir(),\n\t\tskillPaths: [],\n\t\tincludeDefaults: true,\n\t});\n\n\tconst skills: SkillSummary[] = result.skills.map((skill: Skill) => ({\n\t\tname: skill.name,\n\t\tdescription: skill.description,\n\t\tpath: skill.filePath,\n\t\tscope: skill.sourceInfo.scope ?? \"unknown\",\n\t\tkeywords: tokenize(`${skill.name} ${skill.description}`),\n\t}));\n\n\t// If a draft skill is provided, add it to the set for comparison\n\tif (draftSkill) {\n\t\tconst draftName = draftSkill.name || \"draft-skill\";\n\t\tconst draftDesc = draftSkill.description || \"\";\n\t\tskills.push({\n\t\t\tname: draftName,\n\t\t\tdescription: draftDesc,\n\t\t\tpath: \"[draft]\",\n\t\t\tscope: \"draft\",\n\t\t\tkeywords: tokenize(`${draftName} ${draftDesc} ${draftSkill.body || \"\"}`),\n\t\t});\n\t}\n\n\t// Find near-duplicates based on Jaccard similarity\n\tconst nearDuplicates: SkillAuditReport[\"nearDuplicates\"] = [];\n\tfor (let i = 0; i < skills.length; i++) {\n\t\tfor (let j = i + 1; j < skills.length; j++) {\n\t\t\tconst similarity = jaccard(skills[i].keywords, skills[j].keywords);\n\t\t\tif (similarity >= DUPLICATE_THRESHOLD) {\n\t\t\t\tconst reason =\n\t\t\t\t\tsimilarity >= 0.9\n\t\t\t\t\t\t? \"90%+ keyword overlap; merge/refine before adding another skill\"\n\t\t\t\t\t\t: \"high trigger/workflow overlap; review for dedup or compartmentalization\";\n\t\t\t\tnearDuplicates.push({\n\t\t\t\t\ta: skills[i].path,\n\t\t\t\t\tb: skills[j].path,\n\t\t\t\t\tsimilarity: Number(similarity.toFixed(3)),\n\t\t\t\t\treason,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\tnearDuplicates.sort((a, b) => b.similarity - a.similarity);\n\n\t// Check for name collisions\n\tconst byName = new Map<string, string[]>();\n\tfor (const skill of skills) {\n\t\tconst existing = byName.get(skill.name) ?? [];\n\t\tbyName.set(skill.name, [...existing, skill.path]);\n\t}\n\tconst nameCollisions = [...byName.entries()]\n\t\t.filter(([, paths]) => paths.length > 1)\n\t\t.map(([name, paths]) => ({ name, paths }));\n\n\t// Build recommendations\n\tconst recommendations: string[] = [];\n\tif (draftSkill && nearDuplicates.length > 0) {\n\t\tconst draftNearDupes = nearDuplicates.filter((d) => d.a === \"[draft]\" || d.b === \"[draft]\");\n\t\tif (draftNearDupes.length > 0) {\n\t\t\trecommendations.push(\n\t\t\t\t`Draft skill has ${draftNearDupes.length} similar existing skill(s). Consider merging or refining the trigger/scope.`,\n\t\t\t);\n\t\t}\n\t}\n\tif (nameCollisions.length > 0) {\n\t\trecommendations.push(\n\t\t\t`Found ${nameCollisions.length} skill name collision(s). Resolve naming conflicts before deployment.`,\n\t\t);\n\t}\n\n\treturn {\n\t\tgeneratedAt: new Date().toISOString(),\n\t\tskills: skills.filter((s) => s.path !== \"[draft]\"), // Don't include draft in final skill list\n\t\tnearDuplicates,\n\t\tcompartmentWarnings: [],\n\t\tnameCollisions,\n\t\trecommendations,\n\t};\n}\n\nconst skillAuditSchema = Type.Object({\n\tdraftName: Type.Optional(Type.String({ description: \"Name of the draft skill to audit\" })),\n\tdraftDescription: Type.Optional(Type.String({ description: \"Description of the draft skill\" })),\n\tdraftBody: Type.Optional(Type.String({ description: \"Body/content of the draft skill\" })),\n});\n\nexport type SkillAuditInput = Static<typeof skillAuditSchema>;\n\nexport interface SkillAuditToolDetails {\n\treportPath?: string;\n}\n\nexport interface SkillAuditToolOptions {}\n\nexport function createSkillAuditToolDefinition(\n\tcwd: string,\n\t_options?: SkillAuditToolOptions,\n): ToolDefinition<typeof skillAuditSchema, SkillAuditReport> {\n\treturn {\n\t\tname: \"skill_audit\",\n\t\tlabel: \"Skill Audit\",\n\t\ttoolGroup: \"skills\",\n\t\tdescription:\n\t\t\t\"Check a draft/new skill for overlap with existing skills before creating it; flags near-duplicate triggers/descriptions via local Jaccard similarity. Read-only: does not write files.\",\n\t\tpromptSnippet: \"Audit skill for overlaps\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use skill_audit to check draft skills for conflicts before creating them.\",\n\t\t\t\"Similarity >= 55% indicates potential dedup or compartmentalization work.\",\n\t\t],\n\t\tparameters: skillAuditSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ draftName, draftDescription, draftBody }: SkillAuditInput,\n\t\t\t_signal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t): Promise<{\n\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\tdetails: SkillAuditReport;\n\t\t}> {\n\t\t\tconst draftSkill =\n\t\t\t\tdraftName || draftDescription\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tname: draftName,\n\t\t\t\t\t\t\tdescription: draftDescription,\n\t\t\t\t\t\t\tbody: draftBody,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\n\t\t\tconst report = runSkillAudit(cwd, draftSkill);\n\n\t\t\t// Format the report as readable text\n\t\t\tconst lines: string[] = [];\n\t\t\tlines.push(\n\t\t\t\t`Skill audit: ${report.skills.length} skill(s), ${report.nearDuplicates.length} overlap warning(s).`,\n\t\t\t);\n\n\t\t\tif (report.nearDuplicates.length > 0) {\n\t\t\t\tlines.push(\"\\nTop overlap warnings:\");\n\t\t\t\tfor (const item of report.nearDuplicates.slice(0, 8)) {\n\t\t\t\t\tconst aName = item.a.split(\"/\").pop() || item.a;\n\t\t\t\t\tconst bName = item.b.split(\"/\").pop() || item.b;\n\t\t\t\t\tlines.push(`- ${(item.similarity * 100).toFixed(1)}%: ${aName} ↔ ${bName} — ${item.reason}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (report.nameCollisions.length > 0) {\n\t\t\t\tlines.push(\"\\nName collisions:\");\n\t\t\t\tfor (const item of report.nameCollisions.slice(0, 8)) {\n\t\t\t\t\tlines.push(`- ${item.name}: ${item.paths.length} paths`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (report.recommendations && report.recommendations.length > 0) {\n\t\t\t\tlines.push(\"\\nRecommendations:\");\n\t\t\t\tfor (const rec of report.recommendations) {\n\t\t\t\t\tlines.push(`- ${rec}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (report.nearDuplicates.length === 0 && report.nameCollisions.length === 0) {\n\t\t\t\tlines.push(\"\\nNo overlaps detected. This skill appears to be unique.\");\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: lines.join(\"\\n\") }],\n\t\t\t\tdetails: report,\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport function createSkillAuditTool(cwd: string, options?: SkillAuditToolOptions): AgentTool<typeof skillAuditSchema> {\n\treturn wrapToolDefinition(createSkillAuditToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"skill-audit.js","sourceRoot":"","sources":["../../../src/core/tools/skill-audit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport { getAgentDir } from \"../../config.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { loadSkills, type Skill } from \"../skills.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst DUPLICATE_THRESHOLD = 0.55;\n\nconst STOPWORDS = new Set(\n\t\"the a an and or of for to with when use using from into this that skill task work working project agent agents code files file in on by as is are be do not should about\".split(\n\t\t\" \",\n\t),\n);\n\n/**\n * Tokenize text by lowercasing, removing non-alphanumeric chars (except hyphens and colons),\n * splitting on whitespace, and filtering out short tokens and stopwords.\n */\nexport function tokenize(text: string): string[] {\n\treturn [\n\t\t...new Set(\n\t\t\ttext\n\t\t\t\t.toLowerCase()\n\t\t\t\t.replace(/[^a-z0-9:-]+/g, \" \")\n\t\t\t\t.split(/\\s+/)\n\t\t\t\t.filter((token) => token.length >= 3 && !STOPWORDS.has(token)),\n\t\t),\n\t];\n}\n\n/**\n * Calculate Jaccard similarity between two token sets.\n * Jaccard(A, B) = |A ∩ B| / |A ∪ B|\n */\nexport function jaccard(a: string[], b: string[]): number {\n\tif (a.length === 0 || b.length === 0) return 0;\n\tconst setA = new Set(a);\n\tconst setB = new Set(b);\n\tlet intersection = 0;\n\tfor (const item of setA) if (setB.has(item)) intersection++;\n\tconst union = new Set([...a, ...b]).size;\n\treturn union === 0 ? 0 : intersection / union;\n}\n\nexport interface SkillSummary {\n\tname: string;\n\tdescription: string;\n\tpath: string;\n\tscope: string;\n\tkeywords: string[];\n}\n\nexport interface SkillAuditReport {\n\tgeneratedAt: string;\n\tskills: SkillSummary[];\n\tnearDuplicates: Array<{\n\t\ta: string;\n\t\tb: string;\n\t\tsimilarity: number;\n\t\treason: string;\n\t}>;\n\tcompartmentWarnings: Array<{\n\t\tskill: string;\n\t\tpath: string;\n\t\treason: string;\n\t}>;\n\tnameCollisions: Array<{\n\t\tname: string;\n\t\tpaths: string[];\n\t}>;\n\trecommendations?: string[];\n}\n\n/**\n * Audit existing skills for overlap and compare against a draft skill.\n */\nexport function runSkillAudit(\n\tcwd: string,\n\tdraftSkill?: { name?: string; description?: string; body?: string },\n): SkillAuditReport {\n\t// Load existing skills\n\tconst result = loadSkills({\n\t\tcwd,\n\t\tagentDir: getAgentDir(),\n\t\tskillPaths: [],\n\t\tincludeDefaults: true,\n\t});\n\n\tconst skills: SkillSummary[] = result.skills.map((skill: Skill) => ({\n\t\tname: skill.name,\n\t\tdescription: skill.description,\n\t\tpath: skill.filePath,\n\t\tscope: skill.sourceInfo.scope ?? \"unknown\",\n\t\tkeywords: tokenize(`${skill.name} ${skill.description}`),\n\t}));\n\n\t// If a draft skill is provided, add it to the set for comparison\n\tif (draftSkill) {\n\t\tconst draftName = draftSkill.name || \"draft-skill\";\n\t\tconst draftDesc = draftSkill.description || \"\";\n\t\tskills.push({\n\t\t\tname: draftName,\n\t\t\tdescription: draftDesc,\n\t\t\tpath: \"[draft]\",\n\t\t\tscope: \"draft\",\n\t\t\tkeywords: tokenize(`${draftName} ${draftDesc} ${draftSkill.body || \"\"}`),\n\t\t});\n\t}\n\n\t// Find near-duplicates based on Jaccard similarity\n\tconst nearDuplicates: SkillAuditReport[\"nearDuplicates\"] = [];\n\tfor (let i = 0; i < skills.length; i++) {\n\t\tfor (let j = i + 1; j < skills.length; j++) {\n\t\t\tconst similarity = jaccard(skills[i].keywords, skills[j].keywords);\n\t\t\tif (similarity >= DUPLICATE_THRESHOLD) {\n\t\t\t\tconst reason =\n\t\t\t\t\tsimilarity >= 0.9\n\t\t\t\t\t\t? \"90%+ keyword overlap; merge/refine before adding another skill\"\n\t\t\t\t\t\t: \"high trigger/workflow overlap; review for dedup or compartmentalization\";\n\t\t\t\tnearDuplicates.push({\n\t\t\t\t\ta: skills[i].path,\n\t\t\t\t\tb: skills[j].path,\n\t\t\t\t\tsimilarity: Number(similarity.toFixed(3)),\n\t\t\t\t\treason,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\tnearDuplicates.sort((a, b) => b.similarity - a.similarity);\n\n\t// Check for name collisions\n\tconst byName = new Map<string, string[]>();\n\tfor (const skill of skills) {\n\t\tconst existing = byName.get(skill.name) ?? [];\n\t\tbyName.set(skill.name, [...existing, skill.path]);\n\t}\n\tconst nameCollisions = [...byName.entries()]\n\t\t.filter(([, paths]) => paths.length > 1)\n\t\t.map(([name, paths]) => ({ name, paths }));\n\n\t// Build recommendations\n\tconst recommendations: string[] = [];\n\tif (draftSkill && nearDuplicates.length > 0) {\n\t\tconst draftNearDupes = nearDuplicates.filter((d) => d.a === \"[draft]\" || d.b === \"[draft]\");\n\t\tif (draftNearDupes.length > 0) {\n\t\t\trecommendations.push(\n\t\t\t\t`Draft skill has ${draftNearDupes.length} similar existing skill(s). Consider merging or refining the trigger/scope.`,\n\t\t\t);\n\t\t}\n\t}\n\tif (nameCollisions.length > 0) {\n\t\trecommendations.push(\n\t\t\t`Found ${nameCollisions.length} skill name collision(s). Resolve naming conflicts before deployment.`,\n\t\t);\n\t}\n\n\treturn {\n\t\tgeneratedAt: new Date().toISOString(),\n\t\tskills: skills.filter((s) => s.path !== \"[draft]\"), // Don't include draft in final skill list\n\t\tnearDuplicates,\n\t\tcompartmentWarnings: [],\n\t\tnameCollisions,\n\t\trecommendations,\n\t};\n}\n\nconst skillAuditSchema = Type.Object({\n\tdraftName: Type.Optional(Type.String({ description: \"Name of the draft skill to audit\" })),\n\tdraftDescription: Type.Optional(Type.String({ description: \"Description of the draft skill\" })),\n\tdraftBody: Type.Optional(Type.String({ description: \"Body/content of the draft skill\" })),\n});\n\nexport type SkillAuditInput = Static<typeof skillAuditSchema>;\n\nexport interface SkillAuditToolDetails {\n\treportPath?: string;\n}\n\nexport interface SkillAuditToolOptions {}\n\nexport function createSkillAuditToolDefinition(\n\tcwd: string,\n\t_options?: SkillAuditToolOptions,\n): ToolDefinition<typeof skillAuditSchema, SkillAuditReport> {\n\treturn {\n\t\tname: \"skill_audit\",\n\t\tlabel: \"Skill Audit\",\n\t\tdescription:\n\t\t\t\"Check a draft/new skill for overlap with existing skills before creating it; flags near-duplicate triggers/descriptions via local Jaccard similarity. Read-only: does not write files.\",\n\t\tpromptSnippet: \"Audit skill for overlaps\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use skill_audit to check draft skills for conflicts before creating them.\",\n\t\t\t\"Similarity >= 55% indicates potential dedup or compartmentalization work.\",\n\t\t],\n\t\tparameters: skillAuditSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ draftName, draftDescription, draftBody }: SkillAuditInput,\n\t\t\t_signal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t): Promise<{\n\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\tdetails: SkillAuditReport;\n\t\t}> {\n\t\t\tconst draftSkill =\n\t\t\t\tdraftName || draftDescription\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tname: draftName,\n\t\t\t\t\t\t\tdescription: draftDescription,\n\t\t\t\t\t\t\tbody: draftBody,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\n\t\t\tconst report = runSkillAudit(cwd, draftSkill);\n\n\t\t\t// Format the report as readable text\n\t\t\tconst lines: string[] = [];\n\t\t\tlines.push(\n\t\t\t\t`Skill audit: ${report.skills.length} skill(s), ${report.nearDuplicates.length} overlap warning(s).`,\n\t\t\t);\n\n\t\t\tif (report.nearDuplicates.length > 0) {\n\t\t\t\tlines.push(\"\\nTop overlap warnings:\");\n\t\t\t\tfor (const item of report.nearDuplicates.slice(0, 8)) {\n\t\t\t\t\tconst aName = item.a.split(\"/\").pop() || item.a;\n\t\t\t\t\tconst bName = item.b.split(\"/\").pop() || item.b;\n\t\t\t\t\tlines.push(`- ${(item.similarity * 100).toFixed(1)}%: ${aName} ↔ ${bName} — ${item.reason}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (report.nameCollisions.length > 0) {\n\t\t\t\tlines.push(\"\\nName collisions:\");\n\t\t\t\tfor (const item of report.nameCollisions.slice(0, 8)) {\n\t\t\t\t\tlines.push(`- ${item.name}: ${item.paths.length} paths`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (report.recommendations && report.recommendations.length > 0) {\n\t\t\t\tlines.push(\"\\nRecommendations:\");\n\t\t\t\tfor (const rec of report.recommendations) {\n\t\t\t\t\tlines.push(`- ${rec}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (report.nearDuplicates.length === 0 && report.nameCollisions.length === 0) {\n\t\t\t\tlines.push(\"\\nNo overlaps detected. This skill appears to be unique.\");\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: lines.join(\"\\n\") }],\n\t\t\t\tdetails: report,\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport function createSkillAuditTool(cwd: string, options?: SkillAuditToolOptions): AgentTool<typeof skillAuditSchema> {\n\treturn wrapToolDefinition(createSkillAuditToolDefinition(cwd, options));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../../src/core/tools/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEpH,QAAA,MAAM,WAAW;;;;;EAWhB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AACxD,MAAM,MAAM,gBAAgB,GACzB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,GAC/C;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAC3C;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;CAAE,GAC9D;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAyBlD,qEAAqE;AACrE,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,oBAAoB,GAAG,cAAc,CAAC,OAAO,WAAW,CAAC,CA+D9G"}
1
+ {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../../src/core/tools/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEpH,QAAA,MAAM,WAAW;;;;;EAWhB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AACxD,MAAM,MAAM,gBAAgB,GACzB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,GAC/C;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAC3C;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;CAAE,GAC9D;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAyBlD,qEAAqE;AACrE,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,oBAAoB,GAAG,cAAc,CAAC,OAAO,WAAW,CAAC,CA8D9G"}
@@ -32,7 +32,6 @@ export function createSkillVaultToolDefinition(vault) {
32
32
  return {
33
33
  name: "skill",
34
34
  label: "Skill",
35
- toolGroup: "skills",
36
35
  description: "Skill vault, up to 3 concurrent skills under one byte budget. Specialist guidance useful: search, load exact name before work. Load may evict the oldest-loaded unpinned skill and reports it; pin protects up to 2 task-critical skills from eviction (they still expire idle). Host injects bodies transiently starting next request, expires idle; unload one name or all.",
37
36
  promptSnippet: "Search/load skill.",
38
37
  parameters: skillSchema,
@@ -1 +1 @@
1
- {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../../src/core/tools/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAI5C,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAC9B;IACC,MAAM,EAAE,IAAI,CAAC,KAAK,CACjB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAC9F,EAAE,WAAW,EAAE,iCAAiC,EAAE,CAClD;IACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC,CAAC;IAClE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC,CAAC;IACpG,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC,CAAC;CAC9F,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AASF,SAAS,UAAU,CAAC,MAAyB;IAC5C,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,wBAAwB,CAAC;IACpE,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvG,CAAC;AAED,SAAS,QAAQ,CAAC,MAA8C;IAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,OAAO,yBAAyB,MAAM,CAAC,IAAI,GAAG,GAAG,UAAU,MAAM,CAAC,OAAO,+CAA+C,OAAO,EAAE,CAAC;AACnI,CAAC;AAED,SAAS,UAAU,CAAC,MAAwB;IAC3C,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,wBAAwB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC1G,OAAO,MAAM,CAAC,KAAK;SACjB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC,KAAK,KAAK,gBAAgB;YACrC,CAAC,CAAC,gCAAgC,IAAI,CAAC,IAAI,GAAG,GAAG,0BAA0B;YAC3E,CAAC,CAAC,wBAAwB,IAAI,CAAC,IAAI,GAAG,GAAG,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,eAAe,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,IAAI,CAAC;IACzI,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,8BAA8B,CAAC,KAA2B;IACzE,OAAO;QACN,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,OAAO;QACd,SAAS,EAAE,QAAQ;QACnB,WAAW,EACV,+WAA+W;QAChX,aAAa,EAAE,oBAAoB;QACnC,UAAU,EAAE,WAAW;QACvB,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK;YAC/B,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;gBACtB,KAAK,QAAQ,EAAE,CAAC;oBACf,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;wBAC1B,MAAM,MAAM,GAAsB,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;wBACrD,OAAO;4BACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC;4BACzE,OAAO,EAAE,EAAE,MAAM,EAAE,QAAiB,EAAE,MAAM,EAAE;4BAC9C,OAAO,EAAE,IAAI;yBACb,CAAC;oBACH,CAAC;oBACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBACzC,OAAO;wBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC9D,OAAO,EAAE,EAAE,MAAM,EAAE,QAAiB,EAAE,MAAM,EAAE;qBAC9C,CAAC;gBACH,CAAC;gBACD,KAAK,MAAM,EAAE,CAAC;oBACb,MAAM,MAAM,GAAoB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE;wBACjD,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC;wBAC5D,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC;oBACjF,OAAO;wBACN,OAAO,EAAE;4BACR;gCACC,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,sBAAsB,MAAM,CAAC,OAAO,EAAE;6BAC3E;yBACD;wBACD,OAAO,EAAE,EAAE,MAAM,EAAE,MAAe,EAAE,MAAM,EAAE;wBAC5C,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE;qBACnB,CAAC;gBACH,CAAC;gBACD,KAAK,QAAQ,EAAE,CAAC;oBACf,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC,CAAC;oBAC7D,OAAO;wBACN,OAAO,EAAE;4BACR;gCACC,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,mBAAmB,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;6BAC3F;yBACD;wBACD,OAAO,EAAE,EAAE,MAAM,EAAE,QAAiB,EAAE,MAAM,EAAE;qBAC9C,CAAC;gBACH,CAAC;gBACD,KAAK,QAAQ,EAAE,CAAC;oBACf,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;oBAC9B,OAAO;wBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC9D,OAAO,EAAE,EAAE,MAAM,EAAE,QAAiB,EAAE,MAAM,EAAE;qBAC9C,CAAC;gBACH,CAAC;YACF,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport type { SkillLoadResult, SkillSearchResult, SkillVaultController, SkillVaultStatus } from \"../skill-vault.ts\";\n\nconst skillSchema = Type.Object(\n\t{\n\t\taction: Type.Union(\n\t\t\t[Type.Literal(\"search\"), Type.Literal(\"load\"), Type.Literal(\"unload\"), Type.Literal(\"status\")],\n\t\t\t{ description: \"search | load | unload | status\" },\n\t\t),\n\t\tquery: Type.Optional(Type.String({ description: \"search query\" })),\n\t\tname: Type.Optional(Type.String({ description: \"exact skill name; unload without it unloads all\" })),\n\t\tpin: Type.Optional(Type.Boolean({ description: \"protect from eviction while loaded; max 2\" })),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type SkillToolInput = Static<typeof skillSchema>;\nexport type SkillToolDetails =\n\t| { action: \"search\"; result: SkillSearchResult }\n\t| { action: \"load\"; result: SkillLoadResult }\n\t| { action: \"unload\"; result: { ok: true; unloaded: string[] } }\n\t| { action: \"status\"; result: SkillVaultStatus };\n\nfunction searchText(result: SkillSearchResult): string {\n\tif (result.candidates.length === 0) return \"skill search: no match\";\n\treturn result.candidates.map((candidate) => `${candidate.name}: ${candidate.description}`).join(\"\\n\");\n}\n\nfunction loadText(result: Extract<SkillLoadResult, { ok: true }>): string {\n\tconst pin = result.pinned ? \" (pinned)\" : \"\";\n\tconst evicted = result.evicted ? `; EVICTED: ${result.evicted.join(\", \")}` : \"\";\n\treturn `skill loaded_pending: ${result.name}${pin} (base ${result.baseDir}), activates next request; expires when idle${evicted}`;\n}\n\nfunction statusText(result: SkillVaultStatus): string {\n\tif (result.slots.length === 0) return `skill state: unloaded${result.reason ? `, ${result.reason}` : \"\"}`;\n\treturn result.slots\n\t\t.map((slot) => {\n\t\t\tconst pin = slot.pinned ? \" (pinned)\" : \"\";\n\t\t\treturn slot.state === \"loaded_pending\"\n\t\t\t\t? `skill state: loaded_pending, ${slot.name}${pin}, activates next request`\n\t\t\t\t: `skill state: active, ${slot.name}${pin}, idle ${Math.round(slot.idleForMs ?? 0)}ms, expires ${Math.round(slot.expiresInMs ?? 0)}ms`;\n\t\t})\n\t\t.join(\"\\n\");\n}\n\n/** One compact agent surface over the host-owned skill lifecycle. */\nexport function createSkillVaultToolDefinition(vault: SkillVaultController): ToolDefinition<typeof skillSchema> {\n\treturn {\n\t\tname: \"skill\",\n\t\tlabel: \"Skill\",\n\t\ttoolGroup: \"skills\",\n\t\tdescription:\n\t\t\t\"Skill vault, up to 3 concurrent skills under one byte budget. Specialist guidance useful: search, load exact name before work. Load may evict the oldest-loaded unpinned skill and reports it; pin protects up to 2 task-critical skills from eviction (they still expire idle). Host injects bodies transiently starting next request, expires idle; unload one name or all.\",\n\t\tpromptSnippet: \"Search/load skill.\",\n\t\tparameters: skillSchema,\n\t\tasync execute(_toolCallId, input) {\n\t\t\tswitch (input.action) {\n\t\t\t\tcase \"search\": {\n\t\t\t\t\tif (!input.query?.trim()) {\n\t\t\t\t\t\tconst result: SkillSearchResult = { candidates: [] };\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: \"skill search requires query\" }],\n\t\t\t\t\t\t\tdetails: { action: \"search\" as const, result },\n\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst result = vault.search(input.query);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: searchText(result) }],\n\t\t\t\t\t\tdetails: { action: \"search\" as const, result },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"load\": {\n\t\t\t\t\tconst result: SkillLoadResult = input.name?.trim()\n\t\t\t\t\t\t? vault.load(input.name.trim(), \"model\", input.pin === true)\n\t\t\t\t\t\t: { ok: false, reason: \"not_found\", message: \"skill load requires exact name\" };\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\t\ttext: result.ok ? loadText(result) : `skill load failed: ${result.message}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdetails: { action: \"load\" as const, result },\n\t\t\t\t\t\tisError: !result.ok,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"unload\": {\n\t\t\t\t\tconst result = vault.unload(input.name?.trim() || undefined);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\t\ttext: `skill unloaded: ${result.unloaded.length > 0 ? result.unloaded.join(\", \") : \"none\"}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdetails: { action: \"unload\" as const, result },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"status\": {\n\t\t\t\t\tconst result = vault.status();\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: statusText(result) }],\n\t\t\t\t\t\tdetails: { action: \"status\" as const, result },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../../src/core/tools/skill.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport type { SkillLoadResult, SkillSearchResult, SkillVaultController, SkillVaultStatus } from \"../skill-vault.ts\";\n\nconst skillSchema = Type.Object(\n\t{\n\t\taction: Type.Union(\n\t\t\t[Type.Literal(\"search\"), Type.Literal(\"load\"), Type.Literal(\"unload\"), Type.Literal(\"status\")],\n\t\t\t{ description: \"search | load | unload | status\" },\n\t\t),\n\t\tquery: Type.Optional(Type.String({ description: \"search query\" })),\n\t\tname: Type.Optional(Type.String({ description: \"exact skill name; unload without it unloads all\" })),\n\t\tpin: Type.Optional(Type.Boolean({ description: \"protect from eviction while loaded; max 2\" })),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type SkillToolInput = Static<typeof skillSchema>;\nexport type SkillToolDetails =\n\t| { action: \"search\"; result: SkillSearchResult }\n\t| { action: \"load\"; result: SkillLoadResult }\n\t| { action: \"unload\"; result: { ok: true; unloaded: string[] } }\n\t| { action: \"status\"; result: SkillVaultStatus };\n\nfunction searchText(result: SkillSearchResult): string {\n\tif (result.candidates.length === 0) return \"skill search: no match\";\n\treturn result.candidates.map((candidate) => `${candidate.name}: ${candidate.description}`).join(\"\\n\");\n}\n\nfunction loadText(result: Extract<SkillLoadResult, { ok: true }>): string {\n\tconst pin = result.pinned ? \" (pinned)\" : \"\";\n\tconst evicted = result.evicted ? `; EVICTED: ${result.evicted.join(\", \")}` : \"\";\n\treturn `skill loaded_pending: ${result.name}${pin} (base ${result.baseDir}), activates next request; expires when idle${evicted}`;\n}\n\nfunction statusText(result: SkillVaultStatus): string {\n\tif (result.slots.length === 0) return `skill state: unloaded${result.reason ? `, ${result.reason}` : \"\"}`;\n\treturn result.slots\n\t\t.map((slot) => {\n\t\t\tconst pin = slot.pinned ? \" (pinned)\" : \"\";\n\t\t\treturn slot.state === \"loaded_pending\"\n\t\t\t\t? `skill state: loaded_pending, ${slot.name}${pin}, activates next request`\n\t\t\t\t: `skill state: active, ${slot.name}${pin}, idle ${Math.round(slot.idleForMs ?? 0)}ms, expires ${Math.round(slot.expiresInMs ?? 0)}ms`;\n\t\t})\n\t\t.join(\"\\n\");\n}\n\n/** One compact agent surface over the host-owned skill lifecycle. */\nexport function createSkillVaultToolDefinition(vault: SkillVaultController): ToolDefinition<typeof skillSchema> {\n\treturn {\n\t\tname: \"skill\",\n\t\tlabel: \"Skill\",\n\t\tdescription:\n\t\t\t\"Skill vault, up to 3 concurrent skills under one byte budget. Specialist guidance useful: search, load exact name before work. Load may evict the oldest-loaded unpinned skill and reports it; pin protects up to 2 task-critical skills from eviction (they still expire idle). Host injects bodies transiently starting next request, expires idle; unload one name or all.\",\n\t\tpromptSnippet: \"Search/load skill.\",\n\t\tparameters: skillSchema,\n\t\tasync execute(_toolCallId, input) {\n\t\t\tswitch (input.action) {\n\t\t\t\tcase \"search\": {\n\t\t\t\t\tif (!input.query?.trim()) {\n\t\t\t\t\t\tconst result: SkillSearchResult = { candidates: [] };\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: \"skill search requires query\" }],\n\t\t\t\t\t\t\tdetails: { action: \"search\" as const, result },\n\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst result = vault.search(input.query);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: searchText(result) }],\n\t\t\t\t\t\tdetails: { action: \"search\" as const, result },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"load\": {\n\t\t\t\t\tconst result: SkillLoadResult = input.name?.trim()\n\t\t\t\t\t\t? vault.load(input.name.trim(), \"model\", input.pin === true)\n\t\t\t\t\t\t: { ok: false, reason: \"not_found\", message: \"skill load requires exact name\" };\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\t\ttext: result.ok ? loadText(result) : `skill load failed: ${result.message}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdetails: { action: \"load\" as const, result },\n\t\t\t\t\t\tisError: !result.ok,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"unload\": {\n\t\t\t\t\tconst result = vault.unload(input.name?.trim() || undefined);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\t\ttext: `skill unloaded: ${result.unloaded.length > 0 ? result.unloaded.join(\", \") : \"none\"}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdetails: { action: \"unload\" as const, result },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"status\": {\n\t\t\t\t\tconst result = vault.status();\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: statusText(result) }],\n\t\t\t\t\t\tdetails: { action: \"status\" as const, result },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"skillify.d.ts","sourceRoot":"","sources":["../../../src/core/tools/skillify.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGxE,QAAA,MAAM,cAAc;;;;EAIlB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE1D,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,gBAAgB,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;KACb,CAAC;CACF;AAED,MAAM,WAAW,mBAAmB;IACnC,MAAM,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;CAAG;AAEvC,wBAAgB,4BAA4B,CAC3C,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,mBAAmB,GAC5B,cAAc,CAAC,OAAO,cAAc,EAAE,cAAc,CAAC,CAsGvD;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC,OAAO,cAAc,CAAC,CAE/G"}
1
+ {"version":3,"file":"skillify.d.ts","sourceRoot":"","sources":["../../../src/core/tools/skillify.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGxE,QAAA,MAAM,cAAc;;;;EAIlB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE1D,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,gBAAgB,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;KACb,CAAC;CACF;AAED,MAAM,WAAW,mBAAmB;IACnC,MAAM,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;CAAG;AAEvC,wBAAgB,4BAA4B,CAC3C,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,mBAAmB,GAC5B,cAAc,CAAC,OAAO,cAAc,EAAE,cAAc,CAAC,CAqGvD;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC,OAAO,cAAc,CAAC,CAE/G"}
@@ -13,7 +13,6 @@ export function createSkillifyToolDefinition(cwd, _options) {
13
13
  return {
14
14
  name: "skillify",
15
15
  label: "Skillify",
16
- toolGroup: "skills",
17
16
  description: "Validate a draft skill and audit for overlaps with existing skills. Pure analysis tool: generates a proposal with validation and audit report, but does NOT write files or activate the skill. Returns structured report with proposed install path.",
18
17
  promptSnippet: "Validate and audit a draft skill",
19
18
  promptGuidelines: [
@@ -1 +1 @@
1
- {"version":3,"file":"skillify.js","sourceRoot":"","sources":["../../../src/core/tools/skillify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,aAAa,EAAyB,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;IAClC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4DAA4D,EAAE,CAAC;IAChG,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,oCAAoC,EAAE,CAAC;IAC/E,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;CACpE,CAAC,CAAC;AAsBH,MAAM,UAAU,4BAA4B,CAC3C,GAAW,EACX,QAA8B;IAE9B,OAAO;QACN,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,UAAU;QACjB,SAAS,EAAE,QAAQ;QACnB,WAAW,EACV,sPAAsP;QACvP,aAAa,EAAE,kCAAkC;QACjD,gBAAgB,EAAE;YACjB,uEAAuE;YACvE,iHAAiH;YACjH,sGAAsG;YACtG,iFAAiF;SACjF;QACD,UAAU,EAAE,cAAc;QAC1B,KAAK,CAAC,OAAO,CACZ,WAAW,EACX,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAiB,EAC1C,OAAqB,EACrB,SAAU,EACV,IAAK;YAKL,MAAM,MAAM,GAAa,EAAE,CAAC;YAE5B,gBAAgB;YAChB,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;YAE3B,uBAAuB;YACvB,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC/C,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACxC,CAAC;iBAAM,IAAI,WAAW,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;gBACtC,MAAM,CAAC,IAAI,CAAC,wCAAwC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;YAC5E,CAAC;YAED,yBAAyB;YACzB,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;YAE9D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;YAClC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;YAEjF,MAAM,MAAM,GAAmB;gBAC9B,KAAK;gBACL,MAAM;gBACN,KAAK;gBACL,YAAY;gBACZ,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;aAClC,CAAC;YAEF,qCAAqC;YACrC,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,wBAAwB,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YAEtE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;gBACnC,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;oBAC1B,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;gBACxB,CAAC;YACF,CAAC;YAED,KAAK,CAAC,IAAI,CACT,YAAY,KAAK,CAAC,MAAM,CAAC,MAAM,uBAAuB,KAAK,CAAC,cAAc,CAAC,MAAM,sBAAsB,CACvG,CAAC;YAEF,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;gBACnD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;oBACrD,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;oBACzD,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC;oBAC1D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBACvF,CAAC;YACF,CAAC;YAED,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBACjC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;oBACzC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,mBAAmB,CAAC,CAAC;gBACrE,CAAC;YACF,CAAC;YAED,IAAI,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/D,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBACjC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;oBACzC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;gBACxB,CAAC;YACF,CAAC;YAED,IAAI,KAAK,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrF,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;YACrD,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,4BAA4B,YAAY,EAAE,CAAC,CAAC;YAEvD,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnD,OAAO,EAAE,MAAM;aACf,CAAC;QACH,CAAC;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,OAA6B;IAC5E,OAAO,kBAAkB,CAAC,4BAA4B,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;AACvE,CAAC","sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { validateSkillName } from \"../skills.ts\";\nimport { runSkillAudit, type SkillAuditReport } from \"./skill-audit.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst skillifySchema = Type.Object({\n\tname: Type.String({ description: \"Skill name (lowercase, a-z 0-9 hyphens only, max 64 chars)\" }),\n\tdescription: Type.String({ description: \"Skill description (max 1024 chars)\" }),\n\tbody: Type.String({ description: \"Skill body/implementation code\" }),\n});\n\nexport type SkillifyInput = Static<typeof skillifySchema>;\n\nexport interface SkillifyReport {\n\tvalid: boolean;\n\terrors: string[];\n\taudit: SkillAuditReport;\n\tproposedPath: string;\n\tdraft: {\n\t\tname: string;\n\t\tdescription: string;\n\t\tbody: string;\n\t};\n}\n\nexport interface SkillifyToolDetails {\n\treport?: SkillifyReport;\n}\n\nexport interface SkillifyToolOptions {}\n\nexport function createSkillifyToolDefinition(\n\tcwd: string,\n\t_options?: SkillifyToolOptions,\n): ToolDefinition<typeof skillifySchema, SkillifyReport> {\n\treturn {\n\t\tname: \"skillify\",\n\t\tlabel: \"Skillify\",\n\t\ttoolGroup: \"skills\",\n\t\tdescription:\n\t\t\t\"Validate a draft skill and audit for overlaps with existing skills. Pure analysis tool: generates a proposal with validation and audit report, but does NOT write files or activate the skill. Returns structured report with proposed install path.\",\n\t\tpromptSnippet: \"Validate and audit a draft skill\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use skillify to validate and audit draft skills before creating them.\",\n\t\t\t\"When MEMORY.md holds a repeatable procedure, draft a skill from that procedure instead of leaving it as a fact.\",\n\t\t\t\"Fix validation errors (name format, description length) and review audit findings before proceeding.\",\n\t\t\t\"The tool returns a proposal only; persistent write and activation happen later.\",\n\t\t],\n\t\tparameters: skillifySchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ name, description, body }: SkillifyInput,\n\t\t\t_signal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t): Promise<{\n\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\tdetails: SkillifyReport;\n\t\t}> {\n\t\t\tconst errors: string[] = [];\n\n\t\t\t// Validate name\n\t\t\tconst nameErrors = validateSkillName(name);\n\t\t\terrors.push(...nameErrors);\n\n\t\t\t// Validate description\n\t\t\tif (!description || description.trim() === \"\") {\n\t\t\t\terrors.push(\"description is required\");\n\t\t\t} else if (description.length > 1024) {\n\t\t\t\terrors.push(`description exceeds 1024 characters (${description.length})`);\n\t\t\t}\n\n\t\t\t// Run audit on the draft\n\t\t\tconst audit = runSkillAudit(cwd, { name, description, body });\n\n\t\t\tconst valid = errors.length === 0;\n\t\t\tconst proposedPath = join(homedir(), \".pi\", \"agent\", \"skills\", name, \"SKILL.md\");\n\n\t\t\tconst report: SkillifyReport = {\n\t\t\t\tvalid,\n\t\t\t\terrors,\n\t\t\t\taudit,\n\t\t\t\tproposedPath,\n\t\t\t\tdraft: { name, description, body },\n\t\t\t};\n\n\t\t\t// Format the report as readable text\n\t\t\tconst lines: string[] = [];\n\t\t\tlines.push(`Skillify validation: ${valid ? \"✓ valid\" : \"✗ invalid\"}`);\n\n\t\t\tif (errors.length > 0) {\n\t\t\t\tlines.push(\"\\nValidation errors:\");\n\t\t\t\tfor (const err of errors) {\n\t\t\t\t\tlines.push(`- ${err}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlines.push(\n\t\t\t\t`\\nAudit: ${audit.skills.length} existing skill(s), ${audit.nearDuplicates.length} overlap warning(s).`,\n\t\t\t);\n\n\t\t\tif (audit.nearDuplicates.length > 0) {\n\t\t\t\tlines.push(\"\\nTop overlaps with existing skills:\");\n\t\t\t\tfor (const item of audit.nearDuplicates.slice(0, 5)) {\n\t\t\t\t\tconst otherPath = item.a === \"[draft]\" ? item.b : item.a;\n\t\t\t\t\tconst otherName = otherPath.split(\"/\").pop() || otherPath;\n\t\t\t\t\tlines.push(`- ${(item.similarity * 100).toFixed(1)}%: ${otherName} — ${item.reason}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (audit.nameCollisions.length > 0) {\n\t\t\t\tlines.push(\"\\nName collisions:\");\n\t\t\t\tfor (const item of audit.nameCollisions) {\n\t\t\t\t\tlines.push(`- ${item.name}: ${item.paths.length} existing path(s)`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (audit.recommendations && audit.recommendations.length > 0) {\n\t\t\t\tlines.push(\"\\nRecommendations:\");\n\t\t\t\tfor (const rec of audit.recommendations) {\n\t\t\t\t\tlines.push(`- ${rec}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (valid && audit.nearDuplicates.length === 0 && audit.nameCollisions.length === 0) {\n\t\t\t\tlines.push(\"\\n✓ Skill appears ready for creation.\");\n\t\t\t}\n\n\t\t\tlines.push(`\\nProposed install path: ${proposedPath}`);\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: lines.join(\"\\n\") }],\n\t\t\t\tdetails: report,\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport function createSkillifyTool(cwd: string, options?: SkillifyToolOptions): AgentTool<typeof skillifySchema> {\n\treturn wrapToolDefinition(createSkillifyToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"skillify.js","sourceRoot":"","sources":["../../../src/core/tools/skillify.ts"],"names":[],"mappings":"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","sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { validateSkillName } from \"../skills.ts\";\nimport { runSkillAudit, type SkillAuditReport } from \"./skill-audit.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst skillifySchema = Type.Object({\n\tname: Type.String({ description: \"Skill name (lowercase, a-z 0-9 hyphens only, max 64 chars)\" }),\n\tdescription: Type.String({ description: \"Skill description (max 1024 chars)\" }),\n\tbody: Type.String({ description: \"Skill body/implementation code\" }),\n});\n\nexport type SkillifyInput = Static<typeof skillifySchema>;\n\nexport interface SkillifyReport {\n\tvalid: boolean;\n\terrors: string[];\n\taudit: SkillAuditReport;\n\tproposedPath: string;\n\tdraft: {\n\t\tname: string;\n\t\tdescription: string;\n\t\tbody: string;\n\t};\n}\n\nexport interface SkillifyToolDetails {\n\treport?: SkillifyReport;\n}\n\nexport interface SkillifyToolOptions {}\n\nexport function createSkillifyToolDefinition(\n\tcwd: string,\n\t_options?: SkillifyToolOptions,\n): ToolDefinition<typeof skillifySchema, SkillifyReport> {\n\treturn {\n\t\tname: \"skillify\",\n\t\tlabel: \"Skillify\",\n\t\tdescription:\n\t\t\t\"Validate a draft skill and audit for overlaps with existing skills. Pure analysis tool: generates a proposal with validation and audit report, but does NOT write files or activate the skill. Returns structured report with proposed install path.\",\n\t\tpromptSnippet: \"Validate and audit a draft skill\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use skillify to validate and audit draft skills before creating them.\",\n\t\t\t\"When MEMORY.md holds a repeatable procedure, draft a skill from that procedure instead of leaving it as a fact.\",\n\t\t\t\"Fix validation errors (name format, description length) and review audit findings before proceeding.\",\n\t\t\t\"The tool returns a proposal only; persistent write and activation happen later.\",\n\t\t],\n\t\tparameters: skillifySchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ name, description, body }: SkillifyInput,\n\t\t\t_signal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t): Promise<{\n\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\tdetails: SkillifyReport;\n\t\t}> {\n\t\t\tconst errors: string[] = [];\n\n\t\t\t// Validate name\n\t\t\tconst nameErrors = validateSkillName(name);\n\t\t\terrors.push(...nameErrors);\n\n\t\t\t// Validate description\n\t\t\tif (!description || description.trim() === \"\") {\n\t\t\t\terrors.push(\"description is required\");\n\t\t\t} else if (description.length > 1024) {\n\t\t\t\terrors.push(`description exceeds 1024 characters (${description.length})`);\n\t\t\t}\n\n\t\t\t// Run audit on the draft\n\t\t\tconst audit = runSkillAudit(cwd, { name, description, body });\n\n\t\t\tconst valid = errors.length === 0;\n\t\t\tconst proposedPath = join(homedir(), \".pi\", \"agent\", \"skills\", name, \"SKILL.md\");\n\n\t\t\tconst report: SkillifyReport = {\n\t\t\t\tvalid,\n\t\t\t\terrors,\n\t\t\t\taudit,\n\t\t\t\tproposedPath,\n\t\t\t\tdraft: { name, description, body },\n\t\t\t};\n\n\t\t\t// Format the report as readable text\n\t\t\tconst lines: string[] = [];\n\t\t\tlines.push(`Skillify validation: ${valid ? \"✓ valid\" : \"✗ invalid\"}`);\n\n\t\t\tif (errors.length > 0) {\n\t\t\t\tlines.push(\"\\nValidation errors:\");\n\t\t\t\tfor (const err of errors) {\n\t\t\t\t\tlines.push(`- ${err}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlines.push(\n\t\t\t\t`\\nAudit: ${audit.skills.length} existing skill(s), ${audit.nearDuplicates.length} overlap warning(s).`,\n\t\t\t);\n\n\t\t\tif (audit.nearDuplicates.length > 0) {\n\t\t\t\tlines.push(\"\\nTop overlaps with existing skills:\");\n\t\t\t\tfor (const item of audit.nearDuplicates.slice(0, 5)) {\n\t\t\t\t\tconst otherPath = item.a === \"[draft]\" ? item.b : item.a;\n\t\t\t\t\tconst otherName = otherPath.split(\"/\").pop() || otherPath;\n\t\t\t\t\tlines.push(`- ${(item.similarity * 100).toFixed(1)}%: ${otherName} — ${item.reason}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (audit.nameCollisions.length > 0) {\n\t\t\t\tlines.push(\"\\nName collisions:\");\n\t\t\t\tfor (const item of audit.nameCollisions) {\n\t\t\t\t\tlines.push(`- ${item.name}: ${item.paths.length} existing path(s)`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (audit.recommendations && audit.recommendations.length > 0) {\n\t\t\t\tlines.push(\"\\nRecommendations:\");\n\t\t\t\tfor (const rec of audit.recommendations) {\n\t\t\t\t\tlines.push(`- ${rec}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (valid && audit.nearDuplicates.length === 0 && audit.nameCollisions.length === 0) {\n\t\t\t\tlines.push(\"\\n✓ Skill appears ready for creation.\");\n\t\t\t}\n\n\t\t\tlines.push(`\\nProposed install path: ${proposedPath}`);\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: lines.join(\"\\n\") }],\n\t\t\t\tdetails: report,\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport function createSkillifyTool(cwd: string, options?: SkillifyToolOptions): AgentTool<typeof skillifySchema> {\n\treturn wrapToolDefinition(createSkillifyToolDefinition(cwd, options));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/core/tools/write.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAA2C,MAAM,iCAAiC,CAAC;AAE1G,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAEN,KAAK,4BAA4B,EAIjC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEN,4BAA4B,EAE5B,MAAM,2BAA2B,CAAC;AAOnC,QAAA,MAAM,WAAW;;;;;;;;;IAsBf,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,oFAAoF;IACpF,UAAU,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,mCAAmC;IACnC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAOD,MAAM,WAAW,gBAAgB;IAChC,oEAAoE;IACpE,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,oFAAoF;IACpF,wBAAwB,CAAC,EAAE,4BAA4B,CAAC;IACxD,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,4BAA4B,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AA6ND,wBAAgB,yBAAyB,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,GACxB,cAAc,CAAC,OAAO,WAAW,EAAE,gBAAgB,CAAC,CAiLtD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC,OAAO,WAAW,CAAC,CAEtG"}
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/core/tools/write.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAA2C,MAAM,iCAAiC,CAAC;AAE1G,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAEN,KAAK,4BAA4B,EAIjC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEN,4BAA4B,EAE5B,MAAM,2BAA2B,CAAC;AAOnC,QAAA,MAAM,WAAW;;;;;;;;;IAsBf,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,oFAAoF;IACpF,UAAU,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,mCAAmC;IACnC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAOD,MAAM,WAAW,gBAAgB;IAChC,oEAAoE;IACpE,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,oFAAoF;IACpF,wBAAwB,CAAC,EAAE,4BAA4B,CAAC;IACxD,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,4BAA4B,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AA6ND,wBAAgB,yBAAyB,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,GACxB,cAAc,CAAC,OAAO,WAAW,EAAE,gBAAgB,CAAC,CAgLtD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC,OAAO,WAAW,CAAC,CAEtG"}