@linghun/tools 0.1.1 → 0.1.2

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.
@@ -1,30 +1,36 @@
1
+ import {
2
+ WriteTool
3
+ } from "./chunk-I3Z4OKMS.js";
4
+ import {
5
+ WebFetchTool
6
+ } from "./chunk-LGZOG7IQ.js";
1
7
  import {
2
8
  WebSearchTool
3
9
  } from "./chunk-4EZHIDZ6.js";
4
10
  import {
5
- WriteTool
6
- } from "./chunk-I3Z4OKMS.js";
11
+ ReadSnippetsTool
12
+ } from "./chunk-GI5XI4HN.js";
13
+ import {
14
+ SourcePackTool
15
+ } from "./chunk-A6FUAM64.js";
7
16
  import {
8
17
  TodoTool
9
18
  } from "./chunk-MFHY7PBM.js";
10
19
  import {
11
- WebFetchTool
12
- } from "./chunk-LGZOG7IQ.js";
20
+ GrepTool
21
+ } from "./chunk-AZCQL24J.js";
13
22
  import {
14
23
  MultiEditTool
15
24
  } from "./chunk-VJDLOFCF.js";
16
- import {
17
- GlobTool
18
- } from "./chunk-DN3KJZRV.js";
19
25
  import {
20
26
  ReadTool
21
27
  } from "./chunk-TZ6QK52L.js";
28
+ import {
29
+ GlobTool
30
+ } from "./chunk-DN3KJZRV.js";
22
31
  import {
23
32
  EditTool
24
33
  } from "./chunk-WLQ7DGMG.js";
25
- import {
26
- GrepTool
27
- } from "./chunk-AZCQL24J.js";
28
34
  import {
29
35
  BashTool
30
36
  } from "./chunk-VZWMPUSS.js";
@@ -35,6 +41,8 @@ import {
35
41
  // src/tools/ui.ts
36
42
  var toolUserFacingNames = {
37
43
  Read: ReadTool.userFacingName,
44
+ ReadSnippets: ReadSnippetsTool.userFacingName,
45
+ SourcePack: SourcePackTool.userFacingName,
38
46
  Write: WriteTool.userFacingName,
39
47
  Edit: EditTool.userFacingName,
40
48
  MultiEdit: MultiEditTool.userFacingName,
@@ -0,0 +1,11 @@
1
+ import {
2
+ prompt
3
+ } from "./chunk-YCO6C7KF.js";
4
+
5
+ // src/tools/SourcePack/SourcePackTool.ts
6
+ var userFacingName = "\u5B9A\u4F4D\u4EE3\u7801\u7247\u6BB5";
7
+ var SourcePackTool = { name: "SourcePack", prompt, userFacingName };
8
+
9
+ export {
10
+ SourcePackTool
11
+ };
@@ -1,30 +1,36 @@
1
+ import {
2
+ WriteTool
3
+ } from "./chunk-I3Z4OKMS.js";
4
+ import {
5
+ WebFetchTool
6
+ } from "./chunk-LGZOG7IQ.js";
1
7
  import {
2
8
  WebSearchTool
3
9
  } from "./chunk-4EZHIDZ6.js";
4
10
  import {
5
- WriteTool
6
- } from "./chunk-I3Z4OKMS.js";
11
+ ReadSnippetsTool
12
+ } from "./chunk-GI5XI4HN.js";
13
+ import {
14
+ SourcePackTool
15
+ } from "./chunk-A6FUAM64.js";
7
16
  import {
8
17
  TodoTool
9
18
  } from "./chunk-MFHY7PBM.js";
10
19
  import {
11
- WebFetchTool
12
- } from "./chunk-LGZOG7IQ.js";
20
+ GrepTool
21
+ } from "./chunk-AZCQL24J.js";
13
22
  import {
14
23
  MultiEditTool
15
24
  } from "./chunk-VJDLOFCF.js";
16
- import {
17
- GlobTool
18
- } from "./chunk-DN3KJZRV.js";
19
25
  import {
20
26
  ReadTool
21
27
  } from "./chunk-TZ6QK52L.js";
28
+ import {
29
+ GlobTool
30
+ } from "./chunk-DN3KJZRV.js";
22
31
  import {
23
32
  EditTool
24
33
  } from "./chunk-WLQ7DGMG.js";
25
- import {
26
- GrepTool
27
- } from "./chunk-AZCQL24J.js";
28
34
  import {
29
35
  BashTool
30
36
  } from "./chunk-VZWMPUSS.js";
@@ -35,6 +41,8 @@ import {
35
41
  // src/tools/prompts.ts
36
42
  var toolPrompts = {
37
43
  Read: ReadTool.prompt,
44
+ ReadSnippets: ReadSnippetsTool.prompt,
45
+ SourcePack: SourcePackTool.prompt,
38
46
  Write: WriteTool.prompt,
39
47
  Edit: EditTool.prompt,
40
48
  MultiEdit: MultiEditTool.prompt,
@@ -0,0 +1,11 @@
1
+ import {
2
+ prompt
3
+ } from "./chunk-WEWXKRKL.js";
4
+
5
+ // src/tools/ReadSnippets/ReadSnippetsTool.ts
6
+ var userFacingName = "\u8BFB\u53D6\u4EE3\u7801\u7247\u6BB5";
7
+ var ReadSnippetsTool = { name: "ReadSnippets", prompt, userFacingName };
8
+
9
+ export {
10
+ ReadSnippetsTool
11
+ };
@@ -0,0 +1,6 @@
1
+ // src/tools/ReadSnippets/prompt.ts
2
+ var prompt = "Use ReadSnippets to read multiple known file line ranges in one call. Prefer it after search, index, or codebase-memory hits return path/range candidates.";
3
+
4
+ export {
5
+ prompt
6
+ };
@@ -0,0 +1,6 @@
1
+ // src/tools/SourcePack/prompt.ts
2
+ var prompt = "Use SourcePack to locate a small evidence pack of candidate source snippets for a query. If index/codebase-memory already returned paths or ranges, call ReadSnippets on those candidates first.";
3
+
4
+ export {
5
+ prompt
6
+ };
package/dist/index.d.ts CHANGED
@@ -37,18 +37,29 @@ export type ReadSnapshot = {
37
37
  mtimeMs: number;
38
38
  size: number;
39
39
  };
40
+ export type SourcePackCandidate = {
41
+ path: string;
42
+ start: number;
43
+ end: number;
44
+ reason?: string;
45
+ confidence?: number;
46
+ };
40
47
  export type ToolContext = {
41
48
  workspaceRoot: string;
42
49
  logRoot?: string;
43
50
  changedFiles: string[];
44
51
  todos: TodoItem[];
45
52
  readSnapshots?: Record<string, ReadSnapshot>;
53
+ sourcePackCandidates?: SourcePackCandidate[];
46
54
  patchSummaries?: Record<string, DiffSummary>;
47
55
  abortSignal?: AbortSignal;
48
56
  onProgress?: (event: ToolProgressEvent) => void | Promise<void>;
49
57
  trackChildProcess?: (child: Pick<ChildProcess, "kill" | "pid" | "exitCode" | "signalCode" | "once">, options?: ToolChildProcessTrackOptions) => boolean;
50
58
  };
51
- export type ToolName = "Read" | "Write" | "Edit" | "MultiEdit" | "Grep" | "Glob" | "Bash" | "Todo" | "Diff" | "WebSearch" | "WebFetch";
59
+ export type ToolContextOptions = {
60
+ sourcePackCandidates?: SourcePackCandidate[];
61
+ };
62
+ export type ToolName = "Read" | "ReadSnippets" | "SourcePack" | "Write" | "Edit" | "MultiEdit" | "Grep" | "Glob" | "Bash" | "Todo" | "Diff" | "WebSearch" | "WebFetch";
52
63
  export type TodoStatus = "pending" | "in_progress" | "completed" | "blocked";
53
64
  export type TodoItem = {
54
65
  id: string;
@@ -68,6 +79,17 @@ export type ReadInput = {
68
79
  offset?: number;
69
80
  limit?: number;
70
81
  };
82
+ export type ReadSnippetsInput = {
83
+ ranges: {
84
+ path: string;
85
+ start: number;
86
+ end: number;
87
+ }[];
88
+ };
89
+ export type SourcePackInput = {
90
+ query: string;
91
+ limit?: number;
92
+ };
71
93
  export type WriteInput = {
72
94
  path: string;
73
95
  content: string;
@@ -125,7 +147,7 @@ export type ToolRunResult = {
125
147
  output: ToolOutput;
126
148
  };
127
149
  export declare const toolRegistryStatus: "ready";
128
- export declare function createToolContext(workspaceRoot?: string): ToolContext;
150
+ export declare function createToolContext(workspaceRoot?: string, options?: ToolContextOptions): ToolContext;
129
151
  /**
130
152
  * **UNSAFE LOW-LEVEL PRIMITIVE.** Executes a built-in tool directly without
131
153
  * any permission policy check.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,48 +1,52 @@
1
+ import {
2
+ formatFetchOutput,
3
+ webFetch
4
+ } from "./chunk-4UHQWBFA.js";
1
5
  import {
2
6
  applyDomainFilter,
3
7
  bingSearch,
4
8
  formatSearchOutput
5
9
  } from "./chunk-EPIB4FSE.js";
6
- import {
7
- formatFetchOutput,
8
- webFetch
9
- } from "./chunk-4UHQWBFA.js";
10
10
  import {
11
11
  createTool
12
12
  } from "./chunk-MMJX44V6.js";
13
13
  import {
14
14
  toolPrompts
15
- } from "./chunk-3JCXABUK.js";
15
+ } from "./chunk-DWXJBDPQ.js";
16
16
  import {
17
17
  toolUserFacingNames
18
- } from "./chunk-QNZMO55X.js";
19
- import "./chunk-4EZHIDZ6.js";
20
- import "./chunk-YR4HWOR2.js";
21
- import "./chunk-VAFW24RN.js";
18
+ } from "./chunk-2R75FXZG.js";
22
19
  import "./chunk-I3Z4OKMS.js";
23
20
  import "./chunk-PS2ZOFZ6.js";
24
21
  import "./chunk-NPKLGVDQ.js";
25
- import "./chunk-MFHY7PBM.js";
26
- import "./chunk-SZFZPQGL.js";
27
- import "./chunk-XZWSO5CM.js";
28
22
  import "./chunk-LGZOG7IQ.js";
29
23
  import "./chunk-ZYAEUABC.js";
30
24
  import "./chunk-SWK6XRZQ.js";
25
+ import "./chunk-4EZHIDZ6.js";
26
+ import "./chunk-YR4HWOR2.js";
27
+ import "./chunk-VAFW24RN.js";
28
+ import "./chunk-GI5XI4HN.js";
29
+ import "./chunk-WEWXKRKL.js";
30
+ import "./chunk-A6FUAM64.js";
31
+ import "./chunk-YCO6C7KF.js";
32
+ import "./chunk-MFHY7PBM.js";
33
+ import "./chunk-SZFZPQGL.js";
34
+ import "./chunk-XZWSO5CM.js";
35
+ import "./chunk-AZCQL24J.js";
36
+ import "./chunk-HUIZOB4A.js";
37
+ import "./chunk-MK3YP2VR.js";
31
38
  import "./chunk-VJDLOFCF.js";
32
39
  import "./chunk-3RP665TH.js";
33
40
  import "./chunk-IOC3BSPT.js";
34
- import "./chunk-DN3KJZRV.js";
35
- import "./chunk-2U4BZXAI.js";
36
- import "./chunk-ITBZHMZQ.js";
37
41
  import "./chunk-TZ6QK52L.js";
38
42
  import "./chunk-K3YDFDLP.js";
39
43
  import "./chunk-HNIVNZIS.js";
44
+ import "./chunk-DN3KJZRV.js";
45
+ import "./chunk-2U4BZXAI.js";
46
+ import "./chunk-ITBZHMZQ.js";
40
47
  import "./chunk-WLQ7DGMG.js";
41
48
  import "./chunk-SQP6SJRP.js";
42
49
  import "./chunk-BRG64AEC.js";
43
- import "./chunk-AZCQL24J.js";
44
- import "./chunk-HUIZOB4A.js";
45
- import "./chunk-MK3YP2VR.js";
46
50
  import "./chunk-VZWMPUSS.js";
47
51
  import "./chunk-E75PYM7V.js";
48
52
  import "./chunk-GAWMEMXB.js";
@@ -59,6 +63,13 @@ var toolRegistryStatus = "ready";
59
63
  var DEFAULT_LIMIT = 200;
60
64
  var DEFAULT_SEARCH_LIMIT = 100;
61
65
  var DEFAULT_TOOL_TEXT_LIMIT = 5e4;
66
+ var MAX_READ_SNIPPET_RANGES = 20;
67
+ var MAX_READ_SNIPPET_LINES = 120;
68
+ var MAX_READ_SNIPPET_OUTPUT_CHARS = 2e5;
69
+ var SOURCE_PACK_DEFAULT_LIMIT = 6;
70
+ var SOURCE_PACK_MAX_LIMIT = 12;
71
+ var SOURCE_PACK_CONTEXT_LINES = 8;
72
+ var SOURCE_PACK_MAX_TERMS = 6;
62
73
  var BASH_PREVIEW_LIMIT = 3e4;
63
74
  var BASH_TIMEOUT_MS = 12e4;
64
75
  var MAX_TODO_ITEMS = 100;
@@ -66,12 +77,13 @@ var SEARCH_EXCLUDED_DIR_NAMES = ["node_modules", "dist", ".git", ".codebase-memo
66
77
  var SEARCH_EXCLUDED_PATH_PREFIXES = [".linghun/logs", ".linghun/agent-runs", ".linghun/failures"];
67
78
  var SEARCH_EXCLUDED_FILE_SUFFIXES = [".tsbuildinfo"];
68
79
  var RG_TIMEOUT_MS = 3e4;
69
- function createToolContext(workspaceRoot = process.cwd()) {
80
+ function createToolContext(workspaceRoot = process.cwd(), options = {}) {
70
81
  return {
71
82
  workspaceRoot: resolve(workspaceRoot),
72
83
  changedFiles: [],
73
84
  todos: [],
74
85
  readSnapshots: {},
86
+ sourcePackCandidates: options.sourcePackCandidates,
75
87
  patchSummaries: {}
76
88
  };
77
89
  }
@@ -116,6 +128,52 @@ var toolDefinitions = {
116
128
  getToolUseSummary: (input) => `Read ${input.path}`,
117
129
  getActivityDescription: (input) => `Reading ${input.path}`
118
130
  }),
131
+ ReadSnippets: defineTool({
132
+ name: "ReadSnippets",
133
+ title: "\u8BFB\u53D6\u4EE3\u7801\u7247\u6BB5",
134
+ description: "\u4E00\u6B21\u8BFB\u53D6\u591A\u4E2A\u5DE5\u4F5C\u533A\u6587\u4EF6\u8303\u56F4\u3002",
135
+ permission: {
136
+ risk: "low",
137
+ scope: "workspace",
138
+ reason: "\u53EA\u8BFB\u67E5\u770B\u591A\u4E2A\u6587\u4EF6\u7247\u6BB5\u3002",
139
+ phase06Mode: "metadata-only"
140
+ },
141
+ isReadOnly: true,
142
+ isConcurrencySafe: true,
143
+ lifecycle: {
144
+ ...readOnlyLifecycle(),
145
+ maxResultSizeChars: MAX_READ_SNIPPET_OUTPUT_CHARS + 2e3
146
+ },
147
+ validateInput: validateReadSnippetsInput,
148
+ call: readSnippetsTool,
149
+ prompt: () => toolPrompts.ReadSnippets,
150
+ userFacingName: () => toolUserFacingNames.ReadSnippets,
151
+ getToolUseSummary: (input) => `ReadSnippets ${input.ranges.length} ranges`,
152
+ getActivityDescription: (input) => `Reading ${input.ranges.length} snippets`
153
+ }),
154
+ SourcePack: defineTool({
155
+ name: "SourcePack",
156
+ title: "\u5B9A\u4F4D\u4EE3\u7801\u7247\u6BB5",
157
+ description: "\u6309\u67E5\u8BE2\u5B9A\u4F4D\u5E76\u8FD4\u56DE\u5019\u9009\u4EE3\u7801\u7247\u6BB5\u3002",
158
+ permission: {
159
+ risk: "low",
160
+ scope: "workspace",
161
+ reason: "\u53EA\u8BFB\u641C\u7D22\u5E76\u8FD4\u56DE\u5019\u9009\u4EE3\u7801\u7247\u6BB5\u3002",
162
+ phase06Mode: "metadata-only"
163
+ },
164
+ isReadOnly: true,
165
+ isConcurrencySafe: true,
166
+ lifecycle: {
167
+ ...readOnlyLifecycle(),
168
+ maxResultSizeChars: MAX_READ_SNIPPET_OUTPUT_CHARS + 2e3
169
+ },
170
+ validateInput: validateSourcePackInput,
171
+ call: sourcePackTool,
172
+ prompt: () => toolPrompts.SourcePack,
173
+ userFacingName: () => toolUserFacingNames.SourcePack,
174
+ getToolUseSummary: (input) => `SourcePack ${input.query}`,
175
+ getActivityDescription: (input) => `Locating snippets for ${input.query}`
176
+ }),
119
177
  Write: defineTool({
120
178
  name: "Write",
121
179
  title: "\u5199\u5165\u6587\u4EF6",
@@ -420,6 +478,46 @@ function validateReadInput(input) {
420
478
  limit: readOptionalPositiveInteger(record, "limit", "Read")
421
479
  };
422
480
  }
481
+ function validateReadSnippetsInput(input) {
482
+ const record = validateRecord(input, "ReadSnippets");
483
+ const ranges = record.ranges;
484
+ if (!Array.isArray(ranges) || ranges.length === 0) {
485
+ throw new Error("ReadSnippets.ranges \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4\u3002");
486
+ }
487
+ if (ranges.length > MAX_READ_SNIPPET_RANGES) {
488
+ throw new Error(`ReadSnippets.ranges \u6700\u591A ${MAX_READ_SNIPPET_RANGES} \u4E2A\u8303\u56F4\u3002`);
489
+ }
490
+ return {
491
+ ranges: ranges.map((item, index) => {
492
+ const range = validateRecord(item, "ReadSnippets");
493
+ const start = readPositiveLineNumber(range, "start", "ReadSnippets");
494
+ const end = readPositiveLineNumber(range, "end", "ReadSnippets");
495
+ if (end < start) {
496
+ throw new Error(`ReadSnippets.ranges[${index}].end \u5FC5\u987B\u5927\u4E8E\u7B49\u4E8E start\u3002`);
497
+ }
498
+ return {
499
+ path: readString(range, "path", "ReadSnippets"),
500
+ start,
501
+ end
502
+ };
503
+ })
504
+ };
505
+ }
506
+ function validateSourcePackInput(input) {
507
+ const record = validateRecord(input, "SourcePack");
508
+ const limit = readOptionalPositiveInteger(record, "limit", "SourcePack");
509
+ return {
510
+ query: readString(record, "query", "SourcePack"),
511
+ limit: limit === void 0 ? void 0 : Math.min(Math.max(limit, 1), SOURCE_PACK_MAX_LIMIT)
512
+ };
513
+ }
514
+ function readPositiveLineNumber(record, key, toolName) {
515
+ const value = record[key];
516
+ if (!Number.isInteger(value) || value < 1) {
517
+ throw new Error(`${toolName}.${key} \u5FC5\u987B\u662F 1-based \u6B63\u6574\u6570\u884C\u53F7\u3002`);
518
+ }
519
+ return value;
520
+ }
423
521
  function validateWriteInput(input) {
424
522
  const record = validateRecord(input, "Write");
425
523
  return {
@@ -566,6 +664,183 @@ async function readTool(input, context) {
566
664
  truncated
567
665
  };
568
666
  }
667
+ async function readSnippetsTool(input, context) {
668
+ const ranges = [];
669
+ let remainingChars = MAX_READ_SNIPPET_OUTPUT_CHARS;
670
+ let safetyTruncated = false;
671
+ for (const range of input.ranges) {
672
+ const requestedEnd = range.end;
673
+ const boundedEnd = Math.min(range.end, range.start + MAX_READ_SNIPPET_LINES - 1);
674
+ const rangeLineTruncated = boundedEnd < requestedEnd;
675
+ try {
676
+ const filePath = resolveWorkspacePath(context.workspaceRoot, range.path);
677
+ const content = await readFile(filePath, "utf8");
678
+ const info = await stat(filePath);
679
+ rememberReadSnapshot(context, filePath, content, info);
680
+ const lines = splitContentLines(content);
681
+ const selected = lines.slice(range.start - 1, boundedEnd);
682
+ const actualEnd = selected.length > 0 ? range.start + selected.length - 1 : range.start - 1;
683
+ const numbered = selected.map((line, index) => `${range.start + index} ${line}`).join("\n");
684
+ const capped = applySnippetSafetyCap(numbered, remainingChars);
685
+ remainingChars -= capped.usedChars;
686
+ safetyTruncated ||= capped.truncated;
687
+ ranges.push({
688
+ path: relativePath(context.workspaceRoot, filePath),
689
+ start: range.start,
690
+ end: actualEnd,
691
+ content: capped.content,
692
+ requestedStart: range.start,
693
+ requestedEnd,
694
+ totalLines: lines.length,
695
+ truncated: rangeLineTruncated || capped.truncated
696
+ });
697
+ if (capped.truncated) {
698
+ remainingChars = 0;
699
+ }
700
+ } catch (error) {
701
+ ranges.push({
702
+ path: range.path,
703
+ start: range.start,
704
+ end: boundedEnd,
705
+ content: "",
706
+ requestedStart: range.start,
707
+ requestedEnd,
708
+ truncated: rangeLineTruncated,
709
+ error: formatDiagnosticError(error)
710
+ });
711
+ }
712
+ }
713
+ const text = formatReadSnippetsOutput(ranges, safetyTruncated);
714
+ const okCount = ranges.filter((range) => !range.error).length;
715
+ return {
716
+ text,
717
+ summary: `ReadSnippets: ${okCount}/${ranges.length} ranges`,
718
+ data: {
719
+ ranges,
720
+ count: okCount,
721
+ requestedRanges: input.ranges.length,
722
+ safetyTruncated
723
+ },
724
+ truncated: ranges.some((range) => range.truncated) || safetyTruncated
725
+ };
726
+ }
727
+ function applySnippetSafetyCap(content, remainingChars) {
728
+ if (remainingChars <= 0) {
729
+ return {
730
+ content: "...\uFF08\u7ED3\u679C\u5DF2\u622A\u65AD\uFF0C\u540E\u7EED\u5185\u5BB9\u7701\u7565\uFF1B\u5982\u9700\u7CBE\u8BFB\u8BF7\u6307\u5B9A\u66F4\u5C0F\u8303\u56F4\u3002\uFF09",
731
+ usedChars: 0,
732
+ truncated: true
733
+ };
734
+ }
735
+ if (content.length <= remainingChars) {
736
+ return { content, usedChars: content.length, truncated: false };
737
+ }
738
+ const suffix = "\n...\uFF08\u7ED3\u679C\u5DF2\u622A\u65AD\uFF0C\u540E\u7EED\u5185\u5BB9\u7701\u7565\uFF1B\u5982\u9700\u7CBE\u8BFB\u8BF7\u6307\u5B9A\u66F4\u5C0F\u8303\u56F4\u3002\uFF09";
739
+ const sliceLength = Math.max(0, remainingChars - suffix.length);
740
+ return {
741
+ content: `${content.slice(0, sliceLength)}${suffix}`,
742
+ usedChars: remainingChars,
743
+ truncated: true
744
+ };
745
+ }
746
+ function formatReadSnippetsOutput(ranges, safetyTruncated) {
747
+ const lines = [];
748
+ for (const range of ranges) {
749
+ const header = `${range.path}:${range.start}-${range.end}`;
750
+ if (range.error) {
751
+ lines.push(`${header}
752
+ ERROR: ${range.error}`);
753
+ continue;
754
+ }
755
+ lines.push(`${header}
756
+ ${range.content}`);
757
+ if (range.truncated) {
758
+ lines.push("...\uFF08\u8BE5\u8303\u56F4\u5DF2\u622A\u65AD\uFF1B\u53EF\u7EE7\u7EED\u8BFB\u53D6\u540E\u7EED\u8303\u56F4\u3002\uFF09");
759
+ }
760
+ }
761
+ if (safetyTruncated) {
762
+ lines.push("...\uFF08\u7ED3\u679C\u5DF2\u622A\u65AD\uFF0C\u540E\u7EED\u5185\u5BB9\u7701\u7565\uFF1B\u5982\u9700\u7CBE\u8BFB\u8BF7\u6307\u5B9A\u66F4\u5C0F\u8303\u56F4\u3002\uFF09");
763
+ }
764
+ return lines.join("\n\n");
765
+ }
766
+ async function sourcePackTool(input, context) {
767
+ const limit = input.limit ?? SOURCE_PACK_DEFAULT_LIMIT;
768
+ const terms = extractSourcePackTerms(input.query);
769
+ if (terms.length === 0) {
770
+ return {
771
+ text: "empty: query did not contain searchable terms.",
772
+ summary: "SourcePack: 0 snippets",
773
+ data: { query: input.query, snippets: [], count: 0, empty: true }
774
+ };
775
+ }
776
+ const matchResult = await findSourcePackMatches(input.query, terms, context, limit * 4);
777
+ const snippets = [];
778
+ const seen = /* @__PURE__ */ new Set();
779
+ let remainingChars = MAX_READ_SNIPPET_OUTPUT_CHARS;
780
+ let safetyTruncated = false;
781
+ for (const match of matchResult.matches) {
782
+ if (snippets.length >= limit) break;
783
+ const start = match.start ?? Math.max(1, match.line - SOURCE_PACK_CONTEXT_LINES);
784
+ const end = match.end ?? match.line + SOURCE_PACK_CONTEXT_LINES;
785
+ const key = `${match.path}:${start}:${end}`;
786
+ if (seen.has(key)) continue;
787
+ seen.add(key);
788
+ try {
789
+ const filePath = resolveWorkspacePath(context.workspaceRoot, match.path);
790
+ const content = await readFile(filePath, "utf8");
791
+ const info = await stat(filePath);
792
+ rememberReadSnapshot(context, filePath, content, info);
793
+ const lines = splitContentLines(content);
794
+ const boundedEnd = Math.min(end, lines.length);
795
+ const selected = lines.slice(start - 1, boundedEnd);
796
+ const numbered = selected.map((line, index) => `${start + index} ${line}`).join("\n");
797
+ const capped = applySnippetSafetyCap(numbered, remainingChars);
798
+ remainingChars -= capped.usedChars;
799
+ safetyTruncated ||= capped.truncated;
800
+ snippets.push({
801
+ path: relativePath(context.workspaceRoot, filePath),
802
+ start,
803
+ end: boundedEnd,
804
+ content: capped.content,
805
+ requestedStart: start,
806
+ requestedEnd: end,
807
+ totalLines: lines.length,
808
+ truncated: capped.truncated,
809
+ reason: match.reason ?? `matched "${match.term}" at line ${match.line}`,
810
+ confidence: estimateSourcePackConfidence(input.query, match),
811
+ source: match.source
812
+ });
813
+ if (capped.truncated) {
814
+ break;
815
+ }
816
+ } catch {
817
+ continue;
818
+ }
819
+ }
820
+ if (snippets.length === 0) {
821
+ return {
822
+ text: "empty: no matching source snippets found.",
823
+ summary: "SourcePack: 0 snippets",
824
+ data: { query: input.query, snippets: [], count: 0, empty: true }
825
+ };
826
+ }
827
+ const text = formatSourcePackOutput(snippets, safetyTruncated);
828
+ return {
829
+ text,
830
+ summary: `SourcePack: ${snippets.length} snippets`,
831
+ data: {
832
+ query: input.query,
833
+ snippets,
834
+ count: snippets.length,
835
+ searchedTerms: terms,
836
+ source: matchResult.source,
837
+ fallback: matchResult.source !== "index",
838
+ candidatePaths: unique(snippets.map((snippet) => snippet.path)),
839
+ safetyTruncated
840
+ },
841
+ truncated: safetyTruncated || snippets.some((snippet) => snippet.truncated)
842
+ };
843
+ }
569
844
  function splitContentLines(content) {
570
845
  if (content.length === 0) {
571
846
  return [];
@@ -1407,6 +1682,149 @@ async function tryRipgrepFiles(input, context, root, limit) {
1407
1682
  if (!result) return null;
1408
1683
  return { matches: result.lines.slice(0, limit), truncated: result.truncated };
1409
1684
  }
1685
+ async function findSourcePackMatches(query, terms, context, limit) {
1686
+ const indexMatches = sourcePackMatchesFromCandidates(query, context.sourcePackCandidates, limit);
1687
+ if (indexMatches.length > 0) {
1688
+ return { source: "index", matches: indexMatches };
1689
+ }
1690
+ const rgMatches = await tryRipgrepSourcePack(terms, context, limit);
1691
+ if (rgMatches && rgMatches.length > 0) {
1692
+ return { source: "rg", matches: rgMatches };
1693
+ }
1694
+ const matches = [];
1695
+ for await (const filePath of listFiles(context.workspaceRoot, () => matches.length >= limit)) {
1696
+ const content = await safeReadText(filePath, context);
1697
+ if (content === null) continue;
1698
+ const rel = relativePath(context.workspaceRoot, filePath);
1699
+ const pathTerm = terms.find((item) => rel.toLowerCase().includes(item.toLowerCase()));
1700
+ if (pathTerm) {
1701
+ matches.push({
1702
+ path: rel,
1703
+ line: 1,
1704
+ text: rel,
1705
+ term: pathTerm,
1706
+ source: "file_name",
1707
+ confidence: 0.35,
1708
+ reason: `fallback file name matched "${pathTerm}"`
1709
+ });
1710
+ if (matches.length >= limit) break;
1711
+ }
1712
+ const lines = content.split(/\r?\n/u);
1713
+ for (const [index, line] of lines.entries()) {
1714
+ const lower = line.toLowerCase();
1715
+ const term = terms.find((item) => lower.includes(item.toLowerCase()));
1716
+ if (!term) continue;
1717
+ matches.push({
1718
+ path: rel,
1719
+ line: index + 1,
1720
+ text: line,
1721
+ term,
1722
+ source: "local_scan",
1723
+ confidence: 0.4,
1724
+ reason: `fallback local scan matched "${term}" at line ${index + 1}`
1725
+ });
1726
+ if (matches.length >= limit) break;
1727
+ }
1728
+ }
1729
+ return { source: matches[0]?.source ?? "local_scan", matches };
1730
+ }
1731
+ async function tryRipgrepSourcePack(terms, context, limit) {
1732
+ const args = [
1733
+ "--line-number",
1734
+ "--no-heading",
1735
+ "--color",
1736
+ "never",
1737
+ "--hidden",
1738
+ "--no-ignore",
1739
+ "--max-columns",
1740
+ "500",
1741
+ "-i",
1742
+ "-F",
1743
+ ...createRgExcludeArgs(context.workspaceRoot, context.workspaceRoot)
1744
+ ];
1745
+ for (const term of terms) {
1746
+ args.push("-e", term);
1747
+ }
1748
+ args.push(".");
1749
+ const result = await runRipgrep(
1750
+ args,
1751
+ context,
1752
+ limit,
1753
+ (line) => normalizeRgGrepLine(line, context.workspaceRoot)
1754
+ );
1755
+ if (!result) return null;
1756
+ return result.lines.flatMap((line) => parseSourcePackRgLine(line, terms));
1757
+ }
1758
+ function parseSourcePackRgLine(line, terms) {
1759
+ const firstColon = line.indexOf(":");
1760
+ const secondColon = firstColon < 0 ? -1 : line.indexOf(":", firstColon + 1);
1761
+ if (firstColon < 0 || secondColon < 0) return [];
1762
+ const lineNumber = Number.parseInt(line.slice(firstColon + 1, secondColon), 10);
1763
+ if (!Number.isInteger(lineNumber)) return [];
1764
+ const text = line.slice(secondColon + 1).trim();
1765
+ const lower = text.toLowerCase();
1766
+ const term = terms.find((item) => lower.includes(item.toLowerCase())) ?? terms[0];
1767
+ return [
1768
+ {
1769
+ path: line.slice(0, firstColon),
1770
+ line: lineNumber,
1771
+ text,
1772
+ term,
1773
+ source: "rg",
1774
+ confidence: 0.6,
1775
+ reason: `rg matched "${term}" at line ${lineNumber}`
1776
+ }
1777
+ ];
1778
+ }
1779
+ function sourcePackMatchesFromCandidates(query, candidates, limit) {
1780
+ if (!candidates || candidates.length === 0) return [];
1781
+ const terms = extractSourcePackTerms(query);
1782
+ return candidates.slice(0, limit).map((candidate) => {
1783
+ const start = Math.max(1, candidate.start);
1784
+ const end = Math.max(start, candidate.end);
1785
+ const term = terms[0] ?? query;
1786
+ return {
1787
+ path: candidate.path,
1788
+ line: start,
1789
+ text: candidate.reason ?? candidate.path,
1790
+ term,
1791
+ source: "index",
1792
+ start,
1793
+ end,
1794
+ confidence: candidate.confidence ?? 0.85,
1795
+ reason: candidate.reason ?? `index candidate for "${query}"`
1796
+ };
1797
+ });
1798
+ }
1799
+ function extractSourcePackTerms(query) {
1800
+ const terms = query.split(/[^\p{L}\p{N}_.$/@-]+/u).map((term) => term.trim()).filter((term) => term.length >= 2 && !/^\d+$/u.test(term));
1801
+ return unique(terms).slice(0, SOURCE_PACK_MAX_TERMS);
1802
+ }
1803
+ function estimateSourcePackConfidence(query, match) {
1804
+ if (match.confidence !== void 0) return match.confidence;
1805
+ const queryTerms = extractSourcePackTerms(query);
1806
+ const haystack = `${match.path} ${match.text}`.toLowerCase();
1807
+ const hitCount = queryTerms.filter((term) => haystack.includes(term.toLowerCase())).length;
1808
+ const base = match.source === "index" ? 0.7 : match.source === "rg" ? 0.45 : 0.25;
1809
+ const cap = match.source === "index" ? 0.95 : match.source === "rg" ? 0.75 : 0.55;
1810
+ return Math.min(cap, base + hitCount * 0.15);
1811
+ }
1812
+ function formatSourcePackOutput(snippets, safetyTruncated) {
1813
+ const lines = [];
1814
+ for (const snippet of snippets) {
1815
+ lines.push(
1816
+ [
1817
+ `${snippet.path}:${snippet.start}-${snippet.end}`,
1818
+ `source: ${snippet.source}; reason: ${snippet.reason}; confidence: ${snippet.confidence.toFixed(2)}`,
1819
+ snippet.content
1820
+ ].join("\n")
1821
+ );
1822
+ }
1823
+ if (safetyTruncated) {
1824
+ lines.push("...\uFF08\u7ED3\u679C\u5DF2\u622A\u65AD\uFF0C\u540E\u7EED\u5185\u5BB9\u7701\u7565\uFF1B\u5982\u9700\u7CBE\u8BFB\u8BF7\u6307\u5B9A\u66F4\u5C0F\u8303\u56F4\u3002\uFF09");
1825
+ }
1826
+ return lines.join("\n\n");
1827
+ }
1410
1828
  function createRgExcludeArgs(root, workspaceRoot) {
1411
1829
  const searchRootRel = stripCurrentDirectoryPrefix(
1412
1830
  relative(workspaceRoot, root).replaceAll("\\", "/")
@@ -0,0 +1,6 @@
1
+ export declare const ReadSnippetsTool: {
2
+ readonly name: "ReadSnippets";
3
+ readonly prompt: "Use ReadSnippets to read multiple known file line ranges in one call. Prefer it after search, index, or codebase-memory hits return path/range candidates.";
4
+ readonly userFacingName: "读取代码片段";
5
+ };
6
+ //# sourceMappingURL=ReadSnippetsTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReadSnippetsTool.d.ts","sourceRoot":"","sources":["../../../src/tools/ReadSnippets/ReadSnippetsTool.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB;;;;CAA4D,CAAC"}
@@ -0,0 +1,7 @@
1
+ import {
2
+ ReadSnippetsTool
3
+ } from "../../chunk-GI5XI4HN.js";
4
+ import "../../chunk-WEWXKRKL.js";
5
+ export {
6
+ ReadSnippetsTool
7
+ };
@@ -0,0 +1,2 @@
1
+ export declare const prompt = "Use ReadSnippets to read multiple known file line ranges in one call. Prefer it after search, index, or codebase-memory hits return path/range candidates.";
2
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/tools/ReadSnippets/prompt.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,+JAC2I,CAAC"}
@@ -0,0 +1,6 @@
1
+ import {
2
+ prompt
3
+ } from "../../chunk-WEWXKRKL.js";
4
+ export {
5
+ prompt
6
+ };
@@ -0,0 +1,6 @@
1
+ export declare const SourcePackTool: {
2
+ readonly name: "SourcePack";
3
+ readonly prompt: "Use SourcePack to locate a small evidence pack of candidate source snippets for a query. If index/codebase-memory already returned paths or ranges, call ReadSnippets on those candidates first.";
4
+ readonly userFacingName: "定位代码片段";
5
+ };
6
+ //# sourceMappingURL=SourcePackTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SourcePackTool.d.ts","sourceRoot":"","sources":["../../../src/tools/SourcePack/SourcePackTool.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc;;;;CAA0D,CAAC"}
@@ -0,0 +1,7 @@
1
+ import {
2
+ SourcePackTool
3
+ } from "../../chunk-A6FUAM64.js";
4
+ import "../../chunk-YCO6C7KF.js";
5
+ export {
6
+ SourcePackTool
7
+ };
@@ -0,0 +1,2 @@
1
+ export declare const prompt = "Use SourcePack to locate a small evidence pack of candidate source snippets for a query. If index/codebase-memory already returned paths or ranges, call ReadSnippets on those candidates first.";
2
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/tools/SourcePack/prompt.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,qMACiL,CAAC"}
@@ -0,0 +1,6 @@
1
+ import {
2
+ prompt
3
+ } from "../../chunk-YCO6C7KF.js";
4
+ export {
5
+ prompt
6
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/tools/prompts.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAYhD,CAAC"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/tools/prompts.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAchD,CAAC"}
@@ -1,33 +1,37 @@
1
1
  import {
2
2
  toolPrompts
3
- } from "../chunk-3JCXABUK.js";
4
- import "../chunk-4EZHIDZ6.js";
5
- import "../chunk-YR4HWOR2.js";
6
- import "../chunk-VAFW24RN.js";
3
+ } from "../chunk-DWXJBDPQ.js";
7
4
  import "../chunk-I3Z4OKMS.js";
8
5
  import "../chunk-PS2ZOFZ6.js";
9
6
  import "../chunk-NPKLGVDQ.js";
10
- import "../chunk-MFHY7PBM.js";
11
- import "../chunk-SZFZPQGL.js";
12
- import "../chunk-XZWSO5CM.js";
13
7
  import "../chunk-LGZOG7IQ.js";
14
8
  import "../chunk-ZYAEUABC.js";
15
9
  import "../chunk-SWK6XRZQ.js";
10
+ import "../chunk-4EZHIDZ6.js";
11
+ import "../chunk-YR4HWOR2.js";
12
+ import "../chunk-VAFW24RN.js";
13
+ import "../chunk-GI5XI4HN.js";
14
+ import "../chunk-WEWXKRKL.js";
15
+ import "../chunk-A6FUAM64.js";
16
+ import "../chunk-YCO6C7KF.js";
17
+ import "../chunk-MFHY7PBM.js";
18
+ import "../chunk-SZFZPQGL.js";
19
+ import "../chunk-XZWSO5CM.js";
20
+ import "../chunk-AZCQL24J.js";
21
+ import "../chunk-HUIZOB4A.js";
22
+ import "../chunk-MK3YP2VR.js";
16
23
  import "../chunk-VJDLOFCF.js";
17
24
  import "../chunk-3RP665TH.js";
18
25
  import "../chunk-IOC3BSPT.js";
19
- import "../chunk-DN3KJZRV.js";
20
- import "../chunk-2U4BZXAI.js";
21
- import "../chunk-ITBZHMZQ.js";
22
26
  import "../chunk-TZ6QK52L.js";
23
27
  import "../chunk-K3YDFDLP.js";
24
28
  import "../chunk-HNIVNZIS.js";
29
+ import "../chunk-DN3KJZRV.js";
30
+ import "../chunk-2U4BZXAI.js";
31
+ import "../chunk-ITBZHMZQ.js";
25
32
  import "../chunk-WLQ7DGMG.js";
26
33
  import "../chunk-SQP6SJRP.js";
27
34
  import "../chunk-BRG64AEC.js";
28
- import "../chunk-AZCQL24J.js";
29
- import "../chunk-HUIZOB4A.js";
30
- import "../chunk-MK3YP2VR.js";
31
35
  import "../chunk-VZWMPUSS.js";
32
36
  import "../chunk-E75PYM7V.js";
33
37
  import "../chunk-GAWMEMXB.js";
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/tools/ui.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAYxD,CAAC"}
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/tools/ui.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAcxD,CAAC"}
package/dist/tools/ui.js CHANGED
@@ -1,33 +1,37 @@
1
1
  import {
2
2
  toolUserFacingNames
3
- } from "../chunk-QNZMO55X.js";
4
- import "../chunk-4EZHIDZ6.js";
5
- import "../chunk-YR4HWOR2.js";
6
- import "../chunk-VAFW24RN.js";
3
+ } from "../chunk-2R75FXZG.js";
7
4
  import "../chunk-I3Z4OKMS.js";
8
5
  import "../chunk-PS2ZOFZ6.js";
9
6
  import "../chunk-NPKLGVDQ.js";
10
- import "../chunk-MFHY7PBM.js";
11
- import "../chunk-SZFZPQGL.js";
12
- import "../chunk-XZWSO5CM.js";
13
7
  import "../chunk-LGZOG7IQ.js";
14
8
  import "../chunk-ZYAEUABC.js";
15
9
  import "../chunk-SWK6XRZQ.js";
10
+ import "../chunk-4EZHIDZ6.js";
11
+ import "../chunk-YR4HWOR2.js";
12
+ import "../chunk-VAFW24RN.js";
13
+ import "../chunk-GI5XI4HN.js";
14
+ import "../chunk-WEWXKRKL.js";
15
+ import "../chunk-A6FUAM64.js";
16
+ import "../chunk-YCO6C7KF.js";
17
+ import "../chunk-MFHY7PBM.js";
18
+ import "../chunk-SZFZPQGL.js";
19
+ import "../chunk-XZWSO5CM.js";
20
+ import "../chunk-AZCQL24J.js";
21
+ import "../chunk-HUIZOB4A.js";
22
+ import "../chunk-MK3YP2VR.js";
16
23
  import "../chunk-VJDLOFCF.js";
17
24
  import "../chunk-3RP665TH.js";
18
25
  import "../chunk-IOC3BSPT.js";
19
- import "../chunk-DN3KJZRV.js";
20
- import "../chunk-2U4BZXAI.js";
21
- import "../chunk-ITBZHMZQ.js";
22
26
  import "../chunk-TZ6QK52L.js";
23
27
  import "../chunk-K3YDFDLP.js";
24
28
  import "../chunk-HNIVNZIS.js";
29
+ import "../chunk-DN3KJZRV.js";
30
+ import "../chunk-2U4BZXAI.js";
31
+ import "../chunk-ITBZHMZQ.js";
25
32
  import "../chunk-WLQ7DGMG.js";
26
33
  import "../chunk-SQP6SJRP.js";
27
34
  import "../chunk-BRG64AEC.js";
28
- import "../chunk-AZCQL24J.js";
29
- import "../chunk-HUIZOB4A.js";
30
- import "../chunk-MK3YP2VR.js";
31
35
  import "../chunk-VZWMPUSS.js";
32
36
  import "../chunk-E75PYM7V.js";
33
37
  import "../chunk-GAWMEMXB.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linghun/tools",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",