@amaster.ai/pi-attachments 0.1.2-beta.2 → 0.1.2-beta.20

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 (63) hide show
  1. package/README.md +50 -27
  2. package/dist/classify.d.ts +18 -7
  3. package/dist/classify.d.ts.map +1 -1
  4. package/dist/classify.js +235 -92
  5. package/dist/classify.js.map +1 -1
  6. package/dist/extension.d.ts +22 -0
  7. package/dist/extension.d.ts.map +1 -0
  8. package/dist/extension.js +359 -0
  9. package/dist/extension.js.map +1 -0
  10. package/dist/index.d.ts +2 -7
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +2 -5
  13. package/dist/index.js.map +1 -1
  14. package/package.json +32 -5
  15. package/preview.png +0 -0
  16. package/dist/diagnostics.d.ts +0 -8
  17. package/dist/diagnostics.d.ts.map +0 -1
  18. package/dist/diagnostics.js +0 -30
  19. package/dist/diagnostics.js.map +0 -1
  20. package/dist/http.d.ts +0 -10
  21. package/dist/http.d.ts.map +0 -1
  22. package/dist/http.js +0 -44
  23. package/dist/http.js.map +0 -1
  24. package/dist/local-store.d.ts +0 -20
  25. package/dist/local-store.d.ts.map +0 -1
  26. package/dist/local-store.js +0 -121
  27. package/dist/local-store.js.map +0 -1
  28. package/dist/multipart.d.ts +0 -9
  29. package/dist/multipart.d.ts.map +0 -1
  30. package/dist/multipart.js +0 -48
  31. package/dist/multipart.js.map +0 -1
  32. package/dist/normalize.d.ts +0 -7
  33. package/dist/normalize.d.ts.map +0 -1
  34. package/dist/normalize.js +0 -83
  35. package/dist/normalize.js.map +0 -1
  36. package/dist/parser.d.ts +0 -12
  37. package/dist/parser.d.ts.map +0 -1
  38. package/dist/parser.js +0 -168
  39. package/dist/parser.js.map +0 -1
  40. package/dist/prompt.d.ts +0 -10
  41. package/dist/prompt.d.ts.map +0 -1
  42. package/dist/prompt.js +0 -38
  43. package/dist/prompt.js.map +0 -1
  44. package/dist/remote-fetch.d.ts +0 -10
  45. package/dist/remote-fetch.d.ts.map +0 -1
  46. package/dist/remote-fetch.js +0 -35
  47. package/dist/remote-fetch.js.map +0 -1
  48. package/dist/routes.d.ts +0 -14
  49. package/dist/routes.d.ts.map +0 -1
  50. package/dist/routes.js +0 -91
  51. package/dist/routes.js.map +0 -1
  52. package/dist/service.d.ts +0 -9
  53. package/dist/service.d.ts.map +0 -1
  54. package/dist/service.js +0 -140
  55. package/dist/service.js.map +0 -1
  56. package/dist/types.d.ts +0 -85
  57. package/dist/types.d.ts.map +0 -1
  58. package/dist/types.js +0 -2
  59. package/dist/types.js.map +0 -1
  60. package/dist/upload-proxy.d.ts +0 -19
  61. package/dist/upload-proxy.d.ts.map +0 -1
  62. package/dist/upload-proxy.js +0 -105
  63. package/dist/upload-proxy.js.map +0 -1
package/README.md CHANGED
@@ -1,37 +1,60 @@
1
1
  # @amaster.ai/pi-attachments
2
2
 
3
- Attachment preparation utilities for Pi Agent runtimes.
3
+ ![pi-attachments preview](https://raw.githubusercontent.com/TGYD-helige/pi/master/packages/pi-attachments/preview.png)
4
4
 
5
- This package normalizes chat attachment inputs, stores or fetches uploaded files,
6
- extracts model-readable text from common document formats, and produces
7
- model-visible image payloads for supported bitmap images.
5
+ Pi extension that intercepts user input, resolves `@`-references to local resources, and injects their content into the prompt before the model sees it.
8
6
 
9
- ## Design
7
+ Hooks the `input` event of `@earendil-works/pi-coding-agent`. When a recognized mention appears in the user message, the original mention is stripped and replaced with structured context (skill block, attachment listing, or `<system-reminder>`). Image attachments are passed through as multimodal `ImageContent`.
10
8
 
11
- - The core package is transport-agnostic. Local uploads and proxied remote
12
- uploads are both represented as attachment sources.
13
- - Platform authentication is injected through `AttachmentUploadAuth`; the
14
- package does not depend on a specific auth provider.
15
- - Provider-specific image content is represented with a small structural type
16
- so callers can adapt it to their own model SDK.
17
- - File parsing is best-effort. Text, SVG, CSV/TSV, PPTX, and legacy PPT fallbacks
18
- are handled locally. Other document formats can use the LiteParse parser when
19
- enabled.
9
+ ## Recognized mentions
20
10
 
21
- ## Supported Inputs
11
+ | Syntax | Resolves to |
12
+ |---------------------------------|-------------------------------------------------------------------|
13
+ | `@path/to/file.ts` | File contents (text/doc) or base64 image |
14
+ | `@"/path with spaces/file.pdf"` | Same as above, supports whitespace in paths |
15
+ | `@path/to/file.ts#L10-20` | Line range syntax preserved in the reference (range applied downstream) |
16
+ | `@path/to/dir` | Directory listing (files + subdirs, ignores `.git`/`node_modules`/build outputs) |
17
+ | `@skill:<name>` | Loads `SKILL.md` for a registered skill |
22
18
 
23
- - Inline text: `txt`, `md`, `json`, `html`, `xml`, `svg`, `yaml`, source files,
24
- logs, CSV, and TSV.
25
- - Bitmap images: `jpeg`, `png`, `gif`, and `webp`.
26
- - Documents: `pdf`, `doc/docx`, `xls/xlsx/xlsm`, `ppt/pptx`, `odt`, `ods`,
27
- `odp`, and `rtf` when parsing is enabled.
19
+ `@http(s)://...` is **not** treated as a file reference. Unknown namespaces (e.g. `@app:erp-prod`) are left alone — neither resolved as a skill nor as a file.
28
20
 
29
- ## Public API
21
+ ## Skill resolution
30
22
 
31
- - `createAttachmentService(config)`
32
- - `handleAttachmentRoutes(input)`
33
- - `normalizeAttachments(value, maxCount)`
34
- - `renderAttachmentPrompt(message, bundle)`
35
- - `checkAttachmentHostDependencies()`
23
+ `@skill:<name>` searches in this order, first hit wins:
36
24
 
37
- The package is ESM-only.
25
+ 1. `<cwd>/.pi/skills/<name>/SKILL.md` project-level skill
26
+ 2. `<agentDir>/skills/<name>/SKILL.md` — user-level skill (resolved via `@amaster.ai/pi-shared`'s `resolveAgentDir()`, override with `PI_AGENT_HOME`)
27
+
28
+ The order matches `loadSkillsFromAllLocations` in the pi-coding-agent SDK so a project skill overrides a user-installed one. Frontmatter is stripped; the body is wrapped in `<skill name="..." location="...">…</skill>` and prepended to the user message.
29
+
30
+ ## Output assembly
31
+
32
+ When at least one mention resolves, the input is rewritten as three optional segments in this order:
33
+
34
+ ```
35
+ <skill name="..." location="...">…</skill> ← skill blocks (if any)
36
+
37
+ <original user text with mentions stripped>
38
+
39
+ <system-reminder>
40
+ ## file.ts: /abs/path/file.ts
41
+ ```text
42
+ …contents…
43
+ ```
44
+ </system-reminder>
45
+ ```
46
+
47
+ Pure-text inputs with no resolvable mentions are left untouched (handler returns `undefined`).
48
+
49
+ ## Configuration
50
+
51
+ | Env var | Default | Meaning |
52
+ |----------------------------------|-------------|----------------------------------------------------------|
53
+ | `PI_ATTACHMENT_MAX_TEXT_CHARS` | `128000` | Max chars per text/doc attachment before truncation |
54
+ | `PI_AGENT_HOME` | (from pi-shared) | Override for user-level skill search root |
55
+
56
+ ## Limits
57
+
58
+ - **Directory listing**: capped at 200 entries per directory; remainder is summarized as `[Listing truncated: showing 200 of N entries]`.
59
+ - **Ignored directory entries**: `.git`, `node_modules`, `.DS_Store`, `.next`, `.turbo`, `dist`, `build`, `.cache`.
60
+ - **Mention ordering**: skills are matched before files, so the resolved `mentions[]` array groups by kind rather than preserving textual order. Downstream consumers must not rely on textual order.
@@ -1,8 +1,19 @@
1
- export declare function mimeTypeFromFileName(fileName: string): string | undefined;
2
- export declare function fileExtension(fileName: string): string;
3
- export declare function isImageMimeType(value: string | undefined): value is string;
4
- export declare function isTextLikeAttachment(name: string, mimeType: string | undefined): boolean;
5
- export declare function isDocumentAttachment(name: string, mimeType: string | undefined): boolean;
6
- export declare function resolveAttachmentMimeType(name: string, mimeType: string | undefined): string | undefined;
7
- export declare function normalizeMimeType(value: string | undefined): string | undefined;
1
+ export type AttachmentKind = 'image' | 'text' | 'doc' | 'binary';
2
+ export type AttachmentMeta = {
3
+ id: string;
4
+ name: string;
5
+ mimeType?: string;
6
+ size?: number;
7
+ path?: string;
8
+ url?: string;
9
+ };
10
+ export declare function classifyAttachment(name: string, mime: string | undefined): AttachmentKind;
11
+ export declare function fenceForName(name: string): string;
12
+ export declare function truncateText(value: string, maxChars: number): string;
13
+ export declare function docReadInstruction(name: string, fsPath: string, mimeType: string | undefined): string | undefined;
14
+ export declare function renderAttachmentBlock(attachment: AttachmentMeta, maxTextChars: number): Promise<string>;
15
+ export declare function renderAttachmentContext(attachments: AttachmentMeta[], options?: {
16
+ maxTextChars?: number;
17
+ hasImages?: boolean;
18
+ }): Promise<string | undefined>;
8
19
  //# sourceMappingURL=classify.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAsBzE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,MAAM,CAM1E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAiBxF;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAqBxF;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,SAAS,CAOpB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG/E"}
1
+ {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEjE,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAyEF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CA+BzF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,SAAS,CAoBpB;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,cAAc,EAC1B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAyED,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,cAAc,EAAE,EAC7B,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3D,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAmC7B"}
package/dist/classify.js CHANGED
@@ -1,103 +1,246 @@
1
+ import { readdir, readFile, stat } from 'node:fs/promises';
1
2
  import path from 'node:path';
2
- export function mimeTypeFromFileName(fileName) {
3
- const lower = fileName.toLowerCase();
4
- if (lower.endsWith('.pdf'))
5
- return 'application/pdf';
6
- if (lower.endsWith('.doc'))
7
- return 'application/msword';
8
- if (lower.endsWith('.docx'))
9
- return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
10
- if (lower.endsWith('.ppt'))
11
- return 'application/vnd.ms-powerpoint';
12
- if (lower.endsWith('.pptx'))
13
- return 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
14
- if (lower.endsWith('.xlsx'))
15
- return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
16
- if (lower.endsWith('.xls'))
17
- return 'application/vnd.ms-excel';
18
- if (lower.endsWith('.csv'))
19
- return 'text/csv';
20
- if (lower.endsWith('.tsv'))
21
- return 'text/tab-separated-values';
22
- if (lower.endsWith('.json'))
23
- return 'application/json';
24
- if (lower.endsWith('.md') || lower.endsWith('.markdown'))
25
- return 'text/markdown';
26
- if (lower.endsWith('.txt') || lower.endsWith('.log'))
27
- return 'text/plain';
28
- if (lower.endsWith('.html'))
29
- return 'text/html';
30
- if (lower.endsWith('.xml'))
31
- return 'application/xml';
32
- if (lower.endsWith('.svg'))
33
- return 'image/svg+xml';
34
- if (lower.endsWith('.yaml') || lower.endsWith('.yml'))
35
- return 'application/yaml';
36
- return undefined;
3
+ const TEXT_FILE_EXTENSIONS = /\.(csv|tsv|json|jsonl|md|markdown|mdx|txt|html|htm|xml|svg|ya?ml|js|jsx|ts|tsx|mjs|cjs|mts|cts|css|scss|sass|less|sql|log|sh|bash|zsh|fish|py|rb|go|rs|java|kt|kts|scala|swift|m|mm|c|h|hh|hpp|cpp|cxx|cc|cs|php|r|lua|toml|ini|cfg|conf|env|gitignore|dockerfile|makefile|gradle|properties|tf|hcl|nix|patch|diff|proto|graphql|gql)$/i;
4
+ const DOC_EXTENSIONS = /\.(pdf|docx|doc|pptx|ppt|xlsx|xls)$/i;
5
+ const FENCE_BY_EXT = {
6
+ js: 'javascript',
7
+ jsx: 'jsx',
8
+ ts: 'typescript',
9
+ tsx: 'tsx',
10
+ mjs: 'javascript',
11
+ cjs: 'javascript',
12
+ mts: 'typescript',
13
+ cts: 'typescript',
14
+ py: 'python',
15
+ rb: 'ruby',
16
+ go: 'go',
17
+ rs: 'rust',
18
+ java: 'java',
19
+ kt: 'kotlin',
20
+ kts: 'kotlin',
21
+ swift: 'swift',
22
+ scala: 'scala',
23
+ c: 'c',
24
+ h: 'c',
25
+ cpp: 'cpp',
26
+ cxx: 'cpp',
27
+ cc: 'cpp',
28
+ hh: 'cpp',
29
+ hpp: 'cpp',
30
+ cs: 'csharp',
31
+ php: 'php',
32
+ r: 'r',
33
+ lua: 'lua',
34
+ sh: 'bash',
35
+ bash: 'bash',
36
+ zsh: 'bash',
37
+ fish: 'fish',
38
+ json: 'json',
39
+ jsonl: 'json',
40
+ md: 'markdown',
41
+ markdown: 'markdown',
42
+ mdx: 'markdown',
43
+ yml: 'yaml',
44
+ yaml: 'yaml',
45
+ toml: 'toml',
46
+ ini: 'ini',
47
+ env: 'ini',
48
+ html: 'html',
49
+ htm: 'html',
50
+ xml: 'xml',
51
+ svg: 'xml',
52
+ css: 'css',
53
+ scss: 'scss',
54
+ sass: 'sass',
55
+ less: 'less',
56
+ sql: 'sql',
57
+ log: '',
58
+ csv: 'csv',
59
+ tsv: 'tsv',
60
+ patch: 'diff',
61
+ diff: 'diff',
62
+ proto: 'protobuf',
63
+ graphql: 'graphql',
64
+ gql: 'graphql',
65
+ tf: 'hcl',
66
+ hcl: 'hcl',
67
+ dockerfile: 'dockerfile',
68
+ makefile: 'makefile',
69
+ };
70
+ export function classifyAttachment(name, mime) {
71
+ const lower = name.toLowerCase();
72
+ const m = mime?.toLowerCase();
73
+ if (m?.startsWith('image/') || /\.(png|jpe?g|gif|webp|bmp|heic|heif|avif)$/i.test(lower)) {
74
+ return 'image';
75
+ }
76
+ if (DOC_EXTENSIONS.test(lower) ||
77
+ m === 'application/pdf' ||
78
+ m === 'application/msword' ||
79
+ m === 'application/vnd.ms-excel' ||
80
+ m === 'application/vnd.ms-powerpoint' ||
81
+ m === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
82
+ m === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
83
+ m === 'application/vnd.openxmlformats-officedocument.presentationml.presentation') {
84
+ return 'doc';
85
+ }
86
+ if (m?.startsWith('text/') ||
87
+ TEXT_FILE_EXTENSIONS.test(lower) ||
88
+ m === 'application/json' ||
89
+ m === 'application/xml' ||
90
+ m === 'application/javascript' ||
91
+ m === 'application/typescript' ||
92
+ m === 'application/x-yaml' ||
93
+ m === 'application/yaml') {
94
+ return 'text';
95
+ }
96
+ return 'binary';
37
97
  }
38
- export function fileExtension(fileName) {
39
- return path.extname(fileName).toLowerCase();
98
+ export function fenceForName(name) {
99
+ const m = name.toLowerCase().match(/\.([a-z0-9]+)$/);
100
+ if (!m)
101
+ return '';
102
+ return FENCE_BY_EXT[m[1]] ?? m[1];
40
103
  }
41
- export function isImageMimeType(value) {
42
- const normalized = normalizeMimeType(value);
43
- return (normalized !== undefined &&
44
- ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'].includes(normalized));
104
+ export function truncateText(value, maxChars) {
105
+ if (maxChars <= 0 || value.length <= maxChars)
106
+ return value;
107
+ return `${value.slice(0, maxChars)}\n\n[truncated after ${maxChars} characters]`;
45
108
  }
46
- export function isTextLikeAttachment(name, mimeType) {
47
- const resolved = normalizeMimeType(mimeType) ?? mimeTypeFromFileName(name);
48
- return (resolved?.startsWith('text/') ||
49
- [
50
- 'application/json',
51
- 'application/xml',
52
- 'image/svg+xml',
53
- 'application/yaml',
54
- 'application/x-yaml',
55
- 'application/javascript',
56
- 'application/typescript',
57
- 'application/sql',
58
- 'application/csv',
59
- ].includes(resolved ?? '') ||
60
- /\.(csv|tsv|json|md|markdown|txt|html|xml|svg|yaml|yml|js|jsx|ts|tsx|css|sql|log)$/i.test(name));
109
+ export function docReadInstruction(name, fsPath, mimeType) {
110
+ const lower = name.toLowerCase();
111
+ const mime = mimeType?.toLowerCase();
112
+ const isPdf = lower.endsWith('.pdf') || mime === 'application/pdf';
113
+ if (isPdf) {
114
+ return `Extract text from this PDF via shell — try \`pdftotext "${fsPath}" -\` first, fall back to a Python one-liner using pypdf or pdfminer. If text extraction returns empty/garbage (likely a scanned PDF), render pages with PyMuPDF (\`fitz.open(...).get_pixmap().save(...)\`) and OCR via pytesseract. Do NOT open it in a browser, take viewer screenshots, or read raw bytes.`;
115
+ }
116
+ if (/\.docx$/.test(lower)) {
117
+ return `Extract text from this .docx via a Python one-liner with python-docx, e.g. \`python -c "import docx; print('\\n'.join(p.text for p in docx.Document('${fsPath}').paragraphs))"\`. Do NOT open it in a browser or screenshot.`;
118
+ }
119
+ if (/\.xlsx$/.test(lower)) {
120
+ return `Extract data from this .xlsx via a Python one-liner using openpyxl. Do NOT open it in a browser or screenshot.`;
121
+ }
122
+ if (/\.pptx$/.test(lower)) {
123
+ return `Extract text from this .pptx via a Python one-liner using python-pptx. Do NOT open it in a browser or screenshot.`;
124
+ }
125
+ if (/\.(docx?|xlsx?|pptx?)$/.test(lower)) {
126
+ return `Convert this Office document with \`libreoffice --headless --convert-to txt "${fsPath}"\` (or a Python equivalent). Do NOT open it in a browser, screenshot, or read it as raw bytes.`;
127
+ }
128
+ return undefined;
61
129
  }
62
- export function isDocumentAttachment(name, mimeType) {
63
- if (isTextLikeAttachment(name, mimeType)) {
64
- return true;
65
- }
66
- const resolved = normalizeMimeType(mimeType) ?? mimeTypeFromFileName(name);
67
- return ([
68
- 'application/pdf',
69
- 'application/msword',
70
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
71
- 'application/vnd.ms-powerpoint',
72
- 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
73
- 'application/vnd.ms-excel',
74
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
75
- 'application/vnd.oasis.opendocument.text',
76
- 'application/vnd.oasis.opendocument.presentation',
77
- 'application/vnd.oasis.opendocument.spreadsheet',
78
- 'application/rtf',
79
- ].includes(resolved ?? '') ||
80
- /\.(pdf|doc|docx|odt|rtf|ppt|pptx|odp|xls|xlsx|xlsm|ods|csv|tsv)$/i.test(name));
130
+ export async function renderAttachmentBlock(attachment, maxTextChars) {
131
+ const { name, path: fsPath, mimeType, url } = attachment;
132
+ const kind = classifyAttachment(name, mimeType);
133
+ if (kind === 'image') {
134
+ return `## ${name}${fsPath ? `: ${fsPath}` : ''}`;
135
+ }
136
+ if (mimeType === 'inode/directory' && fsPath) {
137
+ return await renderDirectoryBlock(name, fsPath, maxTextChars);
138
+ }
139
+ if (kind === 'text' && fsPath) {
140
+ try {
141
+ const buffer = await readFile(fsPath, 'utf8');
142
+ const text = truncateText(buffer, maxTextChars);
143
+ const fence = fenceForName(name);
144
+ return `## ${name}: ${fsPath}\n\`\`\`${fence}\n${text}\n\`\`\``;
145
+ }
146
+ catch (error) {
147
+ return `## ${name}: ${fsPath}\n[Failed to read file: ${error.message}]`;
148
+ }
149
+ }
150
+ if (kind === 'doc') {
151
+ return `## ${name}${fsPath ? `: ${fsPath}` : url ? `: ${url}` : ''}`;
152
+ }
153
+ return `## ${name}${fsPath ? `: ${fsPath}` : url ? `: ${url}` : ''}`;
81
154
  }
82
- export function resolveAttachmentMimeType(name, mimeType) {
83
- const fromName = mimeTypeFromFileName(name);
84
- const normalized = normalizeMimeType(mimeType);
85
- if (fromName && shouldPreferFileNameMimeType(name, normalized)) {
86
- return fromName;
155
+ const DIRECTORY_LISTING_LIMIT = 200;
156
+ const DIRECTORY_IGNORE = new Set([
157
+ '.git',
158
+ 'node_modules',
159
+ '.DS_Store',
160
+ '.next',
161
+ '.turbo',
162
+ 'dist',
163
+ 'build',
164
+ '.cache',
165
+ ]);
166
+ async function renderDirectoryBlock(name, fsPath, maxTextChars) {
167
+ const heading = `## ${name}: ${fsPath} (directory)`;
168
+ let entries;
169
+ try {
170
+ entries = await readdir(fsPath, { withFileTypes: true });
171
+ }
172
+ catch (error) {
173
+ return `${heading}\n[Failed to list directory: ${error.message}]`;
87
174
  }
88
- return normalized ?? fromName;
175
+ const filtered = entries
176
+ .filter((e) => !DIRECTORY_IGNORE.has(e.name))
177
+ .sort((a, b) => {
178
+ const ad = a.isDirectory() ? 0 : 1;
179
+ const bd = b.isDirectory() ? 0 : 1;
180
+ if (ad !== bd)
181
+ return ad - bd;
182
+ return a.name.localeCompare(b.name);
183
+ });
184
+ const truncatedNote = filtered.length > DIRECTORY_LISTING_LIMIT
185
+ ? `\n[Listing truncated: showing ${DIRECTORY_LISTING_LIMIT} of ${filtered.length} entries]`
186
+ : '';
187
+ const slice = filtered.slice(0, DIRECTORY_LISTING_LIMIT);
188
+ const lines = [];
189
+ for (const entry of slice) {
190
+ if (entry.isDirectory()) {
191
+ lines.push(`${entry.name}/`);
192
+ continue;
193
+ }
194
+ if (entry.isSymbolicLink()) {
195
+ lines.push(`${entry.name}@`);
196
+ continue;
197
+ }
198
+ let size;
199
+ try {
200
+ const s = await stat(path.join(fsPath, entry.name));
201
+ size = s.size;
202
+ }
203
+ catch {
204
+ // ignore
205
+ }
206
+ lines.push(size !== undefined ? `${entry.name} (${formatBytes(size)})` : entry.name);
207
+ }
208
+ const body = truncateText(lines.join('\n'), maxTextChars);
209
+ return `${heading}\n\`\`\`\n${body}\n\`\`\`${truncatedNote}`;
89
210
  }
90
- export function normalizeMimeType(value) {
91
- const trimmed = value?.split(';')[0]?.trim().toLowerCase();
92
- return trimmed || undefined;
211
+ function formatBytes(bytes) {
212
+ if (bytes < 1024)
213
+ return `${bytes}B`;
214
+ if (bytes < 1024 * 1024)
215
+ return `${(bytes / 1024).toFixed(1)}KB`;
216
+ if (bytes < 1024 * 1024 * 1024)
217
+ return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
218
+ return `${(bytes / 1024 / 1024 / 1024).toFixed(1)}GB`;
93
219
  }
94
- function shouldPreferFileNameMimeType(name, mimeType) {
95
- if (/\.(svg|ppt|pptx|doc|docx|xls|xlsx|pdf)$/i.test(name)) {
96
- return (!mimeType ||
97
- mimeType === 'application/octet-stream' ||
98
- mimeType === 'text/plain' ||
99
- mimeType === 'binary/octet-stream');
100
- }
101
- return false;
220
+ export async function renderAttachmentContext(attachments, options = {}) {
221
+ const maxTextChars = options.maxTextChars ?? 128_000;
222
+ const fileAttachments = attachments.filter((a) => classifyAttachment(a.name, a.mimeType) !== 'image');
223
+ if (fileAttachments.length === 0 && !options.hasImages) {
224
+ return undefined;
225
+ }
226
+ const lines = [];
227
+ if (fileAttachments.length > 0) {
228
+ const blocks = [];
229
+ for (const attachment of fileAttachments) {
230
+ blocks.push(await renderAttachmentBlock(attachment, maxTextChars));
231
+ }
232
+ if (blocks.length > 0) {
233
+ lines.push('# Files mentioned by the user:', '', blocks.join('\n\n'));
234
+ }
235
+ }
236
+ if (options.hasImages) {
237
+ if (lines.length > 0)
238
+ lines.push('');
239
+ lines.push('(Image attachments are provided directly as model-visible image content. Do not call file tools for those uploaded images.)');
240
+ }
241
+ if (lines.length === 0)
242
+ return undefined;
243
+ lines.push('', "(The user's language follows the request text above, not the attached file contents. Respond in the user's language.)");
244
+ return lines.join('\n').trim();
102
245
  }
103
246
  //# sourceMappingURL=classify.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"classify.js","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ type Mention = {
3
+ kind: 'skill';
4
+ name: string;
5
+ } | {
6
+ kind: 'file';
7
+ ref: string;
8
+ };
9
+ export default function piAttachmentsExtension(pi: ExtensionAPI): void;
10
+ export declare function extractMentions(content: string): {
11
+ mentions: Mention[];
12
+ raw: string[];
13
+ };
14
+ export declare function stripMentions(content: string): string;
15
+ /**
16
+ * Search order for `@skill:<name>`: project-level (`<cwd>/.pi/skills`) before
17
+ * user-level (`<agentDir>/skills`). Matches `loadSkillsFromAllLocations` in
18
+ * the pi-coding-agent SDK so a project skill overrides a user-installed one.
19
+ */
20
+ export declare function skillSearchPaths(name: string, cwd: string): string[];
21
+ export {};
22
+ //# sourceMappingURL=extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AAUtF,KAAK,OAAO,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAkC/E,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA8IrE;AA4CD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAiDvF;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMrD;AAuBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAIpE"}