@henryqw/pi-add-dir 0.1.11 → 0.1.13
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 +1 -1
- package/extensions/add-dir.ts +70 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ pi install npm:@henryqw/pi-add-dir
|
|
|
23
23
|
| `add_directory` | tool | Add a directory. |
|
|
24
24
|
| `search_external_files` | tool | Glob-search added directories. |
|
|
25
25
|
|
|
26
|
-
Added directories return root `AGENTS.md`, `CLAUDE.md`, `.pi/AGENTS.md`, and `.pi/CLAUDE.md`, and inject them into later prompts. Skills load from `.pi/skills`, `.agents/skills`, and `.claude/skills`. `/dir-add` reloads when it finds skills; `add_directory` reports when a reload is needed.
|
|
26
|
+
Added directories return root `AGENTS.md`, `CLAUDE.md`, `.pi/AGENTS.md`, and `.pi/CLAUDE.md`, and inject them into later prompts. Skills load from `.pi/skills`, `.agents/skills`, and `.claude/skills`. Their files also appear in the editor's `@` autocomplete with absolute paths. `/dir-add` reloads when it finds skills; `add_directory` reports when a reload is needed.
|
|
27
27
|
|
|
28
28
|
Search uses Node filesystem traversal, skips `.git` and `node_modules`, supports basename and relative-path globs, and caps results at 1,000 per call.
|
|
29
29
|
|
package/extensions/add-dir.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import { basename, isAbsolute, relative, sep } from "node:path";
|
|
2
|
-
import {
|
|
1
|
+
import { basename, isAbsolute, join, relative, sep } from "node:path";
|
|
2
|
+
import {
|
|
3
|
+
Text,
|
|
4
|
+
truncateToWidth,
|
|
5
|
+
visibleWidth,
|
|
6
|
+
type AutocompleteProvider,
|
|
7
|
+
type AutocompleteSuggestions,
|
|
8
|
+
} from "@earendil-works/pi-tui";
|
|
3
9
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
4
10
|
import { Type } from "typebox";
|
|
5
11
|
import {
|
|
@@ -85,6 +91,67 @@ function contextSummary(dirCtx: DirContext): string {
|
|
|
85
91
|
return found.length > 0 ? ` Found: ${found.join(", ")}.` : " No context files found.";
|
|
86
92
|
}
|
|
87
93
|
|
|
94
|
+
function extractAtToken(textBeforeCursor: string): string | undefined {
|
|
95
|
+
return textBeforeCursor.match(/(?:^|[ \t])(@(?:"[^"]*|[^\s"]*))$/)?.[1];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function createExternalAutocompleteProvider(
|
|
99
|
+
current: AutocompleteProvider,
|
|
100
|
+
getAddedDirs: () => AddedDir[],
|
|
101
|
+
): AutocompleteProvider {
|
|
102
|
+
return {
|
|
103
|
+
async getSuggestions(lines, cursorLine, cursorCol, options): Promise<AutocompleteSuggestions | null> {
|
|
104
|
+
const line = lines[cursorLine] ?? "";
|
|
105
|
+
const token = extractAtToken(line.slice(0, cursorCol));
|
|
106
|
+
if (!token) return current.getSuggestions(lines, cursorLine, cursorCol, options);
|
|
107
|
+
|
|
108
|
+
const quoted = token.startsWith('@"');
|
|
109
|
+
const query = token.slice(quoted ? 2 : 1);
|
|
110
|
+
if (isAbsolute(query) || query.startsWith("~/") || query.startsWith("./") || query.startsWith("../")) {
|
|
111
|
+
return current.getSuggestions(lines, cursorLine, cursorCol, options);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const tokenStart = cursorCol - token.length;
|
|
115
|
+
const sources = await Promise.all([
|
|
116
|
+
current.getSuggestions(lines, cursorLine, cursorCol, options),
|
|
117
|
+
...getAddedDirs().map(async (dir) => {
|
|
118
|
+
const externalPath = join(dir.absolutePath, query);
|
|
119
|
+
const externalToken = `${quoted || externalPath.includes(" ") ? '@"' : "@"}${externalPath}`;
|
|
120
|
+
const externalLines = [...lines];
|
|
121
|
+
externalLines[cursorLine] = `${line.slice(0, tokenStart)}${externalToken}${line.slice(cursorCol)}`;
|
|
122
|
+
const suggestions = await current.getSuggestions(
|
|
123
|
+
externalLines,
|
|
124
|
+
cursorLine,
|
|
125
|
+
tokenStart + externalToken.length,
|
|
126
|
+
options,
|
|
127
|
+
);
|
|
128
|
+
return suggestions
|
|
129
|
+
? {
|
|
130
|
+
...suggestions,
|
|
131
|
+
items: suggestions.items.map((item) => ({
|
|
132
|
+
...item,
|
|
133
|
+
description: `${dir.label}: ${item.description ?? item.value}`,
|
|
134
|
+
})),
|
|
135
|
+
}
|
|
136
|
+
: null;
|
|
137
|
+
}),
|
|
138
|
+
]);
|
|
139
|
+
|
|
140
|
+
const itemCount = Math.max(...sources.map((source) => source?.items.length ?? 0));
|
|
141
|
+
const items = Array.from({ length: itemCount }, (_, index) =>
|
|
142
|
+
sources.flatMap((source) => (source?.items[index] ? [source.items[index]] : [])),
|
|
143
|
+
).flat();
|
|
144
|
+
return items.length > 0 ? { prefix: token, items } : null;
|
|
145
|
+
},
|
|
146
|
+
applyCompletion(lines, cursorLine, cursorCol, item, prefix) {
|
|
147
|
+
return current.applyCompletion(lines, cursorLine, cursorCol, item, prefix);
|
|
148
|
+
},
|
|
149
|
+
shouldTriggerFileCompletion(lines, cursorLine, cursorCol) {
|
|
150
|
+
return current.shouldTriggerFileCompletion?.(lines, cursorLine, cursorCol) ?? true;
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
88
155
|
export default function addDirExtension(pi: ExtensionAPI): void {
|
|
89
156
|
let addedDirs: AddedDir[] = [];
|
|
90
157
|
let currentCwd = "";
|
|
@@ -212,6 +279,7 @@ export default function addDirExtension(pi: ExtensionAPI): void {
|
|
|
212
279
|
|
|
213
280
|
pi.on("session_start", async (_event, ctx) => {
|
|
214
281
|
reconstructState(ctx);
|
|
282
|
+
ctx.ui.addAutocompleteProvider((current) => createExternalAutocompleteProvider(current, () => addedDirs));
|
|
215
283
|
});
|
|
216
284
|
pi.on("session_tree", async (_event, ctx) => {
|
|
217
285
|
if (reconstructState(ctx)) pi.sendUserMessage("/dir-reload", { expandPromptTemplates: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@henryqw/pi-add-dir",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "Add external directories to a Pi session with context, skills, and file search.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"pack:check": "npm pack --dry-run"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@earendil-works/pi-coding-agent": "
|
|
29
|
-
"@earendil-works/pi-tui": "
|
|
28
|
+
"@earendil-works/pi-coding-agent": "^0.84.4",
|
|
29
|
+
"@earendil-works/pi-tui": "^0.84.4",
|
|
30
30
|
"typebox": "^1.3.15"
|
|
31
31
|
},
|
|
32
32
|
"repository": {
|