@henryqw/pi-add-dir 2.1.6 → 2.2.1
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.
- package/README.md +8 -2
- package/extensions/add-dir.ts +38 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,8 +21,8 @@ Use slash commands from the Pi prompt as a human; Pi agents use the tools.
|
|
|
21
21
|
| `/dir-add [path]` | command | Add to this session by default; pass `--project` or `--global` before the path to persist for this Git repository's linked worktrees or every workspace. Omit the path to enter it when prompted; supports `~`. |
|
|
22
22
|
| `/dir-ls` | command | List directories with their scope; select one to remove from that scope. |
|
|
23
23
|
| `/dir-reload` | command | Reload external directory resources. |
|
|
24
|
-
| `add_directory(path)` | tool | Add a directory to this session and return its context and instructions. |
|
|
25
|
-
| `search_external_files(pattern, maxResults?)` | tool | Glob-search added directories; returns up to 50 results by default, configurable to 1,000. |
|
|
24
|
+
| `add_directory(path)` | tool | Add a directory to this session and return its context and instructions. Model-only: codemode scripts cannot call it. |
|
|
25
|
+
| `search_external_files(pattern, maxResults?)` | tool | Glob-search added directories; returns up to 50 results by default, configurable to 1,000. Returns a structured result to codemode scripts. |
|
|
26
26
|
| `@` file autocomplete | ui | Find files in added directories and insert their absolute paths. |
|
|
27
27
|
| External directory widget | ui | Show added directories and point to `/dir-ls` for management. |
|
|
28
28
|
|
|
@@ -34,6 +34,12 @@ Added directories give Pi these resources:
|
|
|
34
34
|
|
|
35
35
|
`/dir-add` reloads only when the discovered external skill paths change, not merely because the directory contains skills. `add_directory` stays session-local; when its result asks for `/reload`, run it to update external skills.
|
|
36
36
|
|
|
37
|
+
### Programmatic use
|
|
38
|
+
|
|
39
|
+
`search_external_files` declares an output schema. Programmatic callers such as Pi `codemode` scripts receive `{ pattern, maxResults, searchedDirectories, totalFound, truncated, directories }`. `directories` lists each directory with at least one match, with its label and absolute file paths. `searchedDirectories` counts only directories actually searched, including those with no matches; directories skipped after reaching the cap are not counted. `truncated` is true when the result cap stopped the search, so later directories or files may hold more matches. The model receives the same matches as text. Calling the tool with no added directories is a tool error, and scripts reject with the message.
|
|
40
|
+
|
|
41
|
+
`add_directory` is declared to the model only (Pi `model-only` exposure). Codemode scripts and other tools cannot call it, so another directory's `AGENTS.md`, `CLAUDE.md`, and skills enter the session only through a model-visible tool call or a user command. This package does not enable codemode.
|
|
42
|
+
|
|
37
43
|
## Config
|
|
38
44
|
|
|
39
45
|
Package-owned: `~/.pi/agent/config/pi-add-dir/config.json`
|
package/extensions/add-dir.ts
CHANGED
|
@@ -66,6 +66,20 @@ const SearchExternalFilesParams = Type.Object({
|
|
|
66
66
|
),
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
+
// Programmatic result of search_external_files. Codemode scripts receive it;
|
|
70
|
+
// the model receives the text listing.
|
|
71
|
+
const SearchExternalFilesOutput = Type.Object({
|
|
72
|
+
pattern: Type.String(),
|
|
73
|
+
maxResults: Type.Integer({ description: "Result cap applied to this call." }),
|
|
74
|
+
searchedDirectories: Type.Integer({ description: "Active external directories searched, in order." }),
|
|
75
|
+
totalFound: Type.Integer(),
|
|
76
|
+
truncated: Type.Boolean({ description: "True when the cap stopped the search; later directories or files may hold more matches." }),
|
|
77
|
+
directories: Type.Array(
|
|
78
|
+
Type.Object({ path: Type.String(), label: Type.String(), files: Type.Array(Type.String()) }),
|
|
79
|
+
{ description: "Directories with at least one match, with absolute file paths." },
|
|
80
|
+
),
|
|
81
|
+
});
|
|
82
|
+
|
|
69
83
|
interface AddDirectoryDetails {
|
|
70
84
|
directory: string;
|
|
71
85
|
hasAgentsMd: boolean;
|
|
@@ -625,6 +639,10 @@ export default function addDirExtension(pi: ExtensionAPI, options: ExtensionOpti
|
|
|
625
639
|
"After adding, you can read/edit/write files in the external directory using absolute paths.",
|
|
626
640
|
],
|
|
627
641
|
parameters: AddDirectoryParams,
|
|
642
|
+
// Loading another directory's instructions must stay a model-visible call,
|
|
643
|
+
// never a nested call a codemode script can issue and filter.
|
|
644
|
+
exposure: "model-only",
|
|
645
|
+
annotations: { destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
628
646
|
|
|
629
647
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
630
648
|
const inputPath = params.path.trim();
|
|
@@ -693,6 +711,8 @@ export default function addDirExtension(pi: ExtensionAPI, options: ExtensionOpti
|
|
|
693
711
|
"Returns matching file paths with their parent directory labels.",
|
|
694
712
|
],
|
|
695
713
|
parameters: SearchExternalFilesParams,
|
|
714
|
+
outputSchema: SearchExternalFilesOutput,
|
|
715
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
696
716
|
|
|
697
717
|
async execute(_toolCallId, params, signal) {
|
|
698
718
|
if (addedDirs.length === 0) {
|
|
@@ -701,22 +721,32 @@ export default function addDirExtension(pi: ExtensionAPI, options: ExtensionOpti
|
|
|
701
721
|
|
|
702
722
|
const pattern = params.pattern.trim();
|
|
703
723
|
const limit = params.maxResults ?? DEFAULT_MAX_RESULTS;
|
|
704
|
-
const
|
|
724
|
+
const directories: Array<{ path: string; label: string; files: string[] }> = [];
|
|
705
725
|
let totalFound = 0;
|
|
726
|
+
let searchedDirectories = 0;
|
|
706
727
|
|
|
707
728
|
for (const dir of addedDirs) {
|
|
708
729
|
signal?.throwIfAborted();
|
|
709
730
|
const remaining = limit - totalFound;
|
|
710
731
|
if (remaining <= 0) break;
|
|
711
732
|
|
|
733
|
+
searchedDirectories++;
|
|
712
734
|
const files = await findFiles(dir.absolutePath, pattern, remaining, signal);
|
|
713
735
|
if (files.length > 0) {
|
|
714
|
-
|
|
736
|
+
directories.push({ path: dir.absolutePath, label: dir.label, files });
|
|
715
737
|
totalFound += files.length;
|
|
716
738
|
}
|
|
717
739
|
}
|
|
718
740
|
|
|
719
741
|
signal?.throwIfAborted();
|
|
742
|
+
const structuredContent = {
|
|
743
|
+
pattern,
|
|
744
|
+
maxResults: limit,
|
|
745
|
+
searchedDirectories,
|
|
746
|
+
totalFound,
|
|
747
|
+
truncated: totalFound >= limit,
|
|
748
|
+
directories,
|
|
749
|
+
};
|
|
720
750
|
if (totalFound === 0) {
|
|
721
751
|
return {
|
|
722
752
|
content: [
|
|
@@ -726,19 +756,21 @@ export default function addDirExtension(pi: ExtensionAPI, options: ExtensionOpti
|
|
|
726
756
|
},
|
|
727
757
|
],
|
|
728
758
|
details: { totalFound: 0, pattern, dirCount: 0 } satisfies SearchDetails,
|
|
759
|
+
structuredContent,
|
|
729
760
|
};
|
|
730
761
|
}
|
|
731
762
|
|
|
732
763
|
const lines = [`Found ${totalFound} file(s) matching "${pattern}":\n`];
|
|
733
|
-
for (const
|
|
734
|
-
lines.push(`📂 ${
|
|
735
|
-
for (const file of
|
|
764
|
+
for (const directory of directories) {
|
|
765
|
+
lines.push(`📂 ${directory.label} (${directory.path}):`);
|
|
766
|
+
for (const file of directory.files) lines.push(` ${file}`);
|
|
736
767
|
lines.push("");
|
|
737
768
|
}
|
|
738
769
|
|
|
739
770
|
return {
|
|
740
771
|
content: [{ type: "text", text: lines.join("\n") }],
|
|
741
|
-
details: { totalFound, pattern, dirCount:
|
|
772
|
+
details: { totalFound, pattern, dirCount: directories.length } satisfies SearchDetails,
|
|
773
|
+
structuredContent,
|
|
742
774
|
};
|
|
743
775
|
},
|
|
744
776
|
|