@amaster.ai/pi-attachments 0.1.2-beta.1 → 0.1.2-beta.11

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 (62) hide show
  1. package/dist/classify.d.ts +18 -7
  2. package/dist/classify.d.ts.map +1 -1
  3. package/dist/classify.js +172 -93
  4. package/dist/classify.js.map +1 -1
  5. package/dist/extension.d.ts +3 -0
  6. package/dist/extension.d.ts.map +1 -0
  7. package/dist/extension.js +150 -0
  8. package/dist/extension.js.map +1 -0
  9. package/dist/index.d.ts +2 -7
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -5
  12. package/dist/index.js.map +1 -1
  13. package/package.json +29 -6
  14. package/README.md +0 -37
  15. package/dist/diagnostics.d.ts +0 -8
  16. package/dist/diagnostics.d.ts.map +0 -1
  17. package/dist/diagnostics.js +0 -30
  18. package/dist/diagnostics.js.map +0 -1
  19. package/dist/http.d.ts +0 -10
  20. package/dist/http.d.ts.map +0 -1
  21. package/dist/http.js +0 -44
  22. package/dist/http.js.map +0 -1
  23. package/dist/local-store.d.ts +0 -20
  24. package/dist/local-store.d.ts.map +0 -1
  25. package/dist/local-store.js +0 -121
  26. package/dist/local-store.js.map +0 -1
  27. package/dist/multipart.d.ts +0 -9
  28. package/dist/multipart.d.ts.map +0 -1
  29. package/dist/multipart.js +0 -48
  30. package/dist/multipart.js.map +0 -1
  31. package/dist/normalize.d.ts +0 -7
  32. package/dist/normalize.d.ts.map +0 -1
  33. package/dist/normalize.js +0 -83
  34. package/dist/normalize.js.map +0 -1
  35. package/dist/parser.d.ts +0 -12
  36. package/dist/parser.d.ts.map +0 -1
  37. package/dist/parser.js +0 -168
  38. package/dist/parser.js.map +0 -1
  39. package/dist/prompt.d.ts +0 -10
  40. package/dist/prompt.d.ts.map +0 -1
  41. package/dist/prompt.js +0 -38
  42. package/dist/prompt.js.map +0 -1
  43. package/dist/remote-fetch.d.ts +0 -10
  44. package/dist/remote-fetch.d.ts.map +0 -1
  45. package/dist/remote-fetch.js +0 -35
  46. package/dist/remote-fetch.js.map +0 -1
  47. package/dist/routes.d.ts +0 -14
  48. package/dist/routes.d.ts.map +0 -1
  49. package/dist/routes.js +0 -91
  50. package/dist/routes.js.map +0 -1
  51. package/dist/service.d.ts +0 -9
  52. package/dist/service.d.ts.map +0 -1
  53. package/dist/service.js +0 -140
  54. package/dist/service.js.map +0 -1
  55. package/dist/types.d.ts +0 -85
  56. package/dist/types.d.ts.map +0 -1
  57. package/dist/types.js +0 -2
  58. package/dist/types.js.map +0 -1
  59. package/dist/upload-proxy.d.ts +0 -19
  60. package/dist/upload-proxy.d.ts.map +0 -1
  61. package/dist/upload-proxy.js +0 -105
  62. package/dist/upload-proxy.js.map +0 -1
@@ -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":"AAKA,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,CA0BjB;AAED,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,182 @@
1
- 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;
37
- }
38
- export function fileExtension(fileName) {
39
- return path.extname(fileName).toLowerCase();
1
+ /**
2
+ * Attachment classification and prompt rendering utilities.
3
+ */
4
+ import { readFile } from 'node:fs/promises';
5
+ 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;
6
+ const DOC_EXTENSIONS = /\.(pdf|docx|doc|pptx|ppt|xlsx|xls)$/i;
7
+ const FENCE_BY_EXT = {
8
+ js: 'javascript',
9
+ jsx: 'jsx',
10
+ ts: 'typescript',
11
+ tsx: 'tsx',
12
+ mjs: 'javascript',
13
+ cjs: 'javascript',
14
+ mts: 'typescript',
15
+ cts: 'typescript',
16
+ py: 'python',
17
+ rb: 'ruby',
18
+ go: 'go',
19
+ rs: 'rust',
20
+ java: 'java',
21
+ kt: 'kotlin',
22
+ kts: 'kotlin',
23
+ swift: 'swift',
24
+ scala: 'scala',
25
+ c: 'c',
26
+ h: 'c',
27
+ cpp: 'cpp',
28
+ cxx: 'cpp',
29
+ cc: 'cpp',
30
+ hh: 'cpp',
31
+ hpp: 'cpp',
32
+ cs: 'csharp',
33
+ php: 'php',
34
+ r: 'r',
35
+ lua: 'lua',
36
+ sh: 'bash',
37
+ bash: 'bash',
38
+ zsh: 'bash',
39
+ fish: 'fish',
40
+ json: 'json',
41
+ jsonl: 'json',
42
+ md: 'markdown',
43
+ markdown: 'markdown',
44
+ mdx: 'markdown',
45
+ yml: 'yaml',
46
+ yaml: 'yaml',
47
+ toml: 'toml',
48
+ ini: 'ini',
49
+ env: 'ini',
50
+ html: 'html',
51
+ htm: 'html',
52
+ xml: 'xml',
53
+ svg: 'xml',
54
+ css: 'css',
55
+ scss: 'scss',
56
+ sass: 'sass',
57
+ less: 'less',
58
+ sql: 'sql',
59
+ log: '',
60
+ csv: 'csv',
61
+ tsv: 'tsv',
62
+ patch: 'diff',
63
+ diff: 'diff',
64
+ proto: 'protobuf',
65
+ graphql: 'graphql',
66
+ gql: 'graphql',
67
+ tf: 'hcl',
68
+ hcl: 'hcl',
69
+ dockerfile: 'dockerfile',
70
+ makefile: 'makefile',
71
+ };
72
+ export function classifyAttachment(name, mime) {
73
+ const lower = name.toLowerCase();
74
+ const m = mime?.toLowerCase();
75
+ if (m?.startsWith('image/') || /\.(png|jpe?g|gif|webp|bmp|heic|heif|avif)$/i.test(lower)) {
76
+ return 'image';
77
+ }
78
+ if (DOC_EXTENSIONS.test(lower) ||
79
+ m === 'application/pdf' ||
80
+ m === 'application/msword' ||
81
+ m === 'application/vnd.ms-excel' ||
82
+ m === 'application/vnd.ms-powerpoint' ||
83
+ m === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
84
+ m === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
85
+ m === 'application/vnd.openxmlformats-officedocument.presentationml.presentation') {
86
+ return 'doc';
87
+ }
88
+ if (m?.startsWith('text/') ||
89
+ TEXT_FILE_EXTENSIONS.test(lower) ||
90
+ m === 'application/json' ||
91
+ m === 'application/xml' ||
92
+ m === 'application/javascript' ||
93
+ m === 'application/typescript' ||
94
+ m === 'application/x-yaml' ||
95
+ m === 'application/yaml') {
96
+ return 'text';
97
+ }
98
+ return 'binary';
40
99
  }
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));
100
+ export function fenceForName(name) {
101
+ const m = name.toLowerCase().match(/\.([a-z0-9]+)$/);
102
+ if (!m)
103
+ return '';
104
+ return FENCE_BY_EXT[m[1]] ?? m[1];
45
105
  }
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));
106
+ export function truncateText(value, maxChars) {
107
+ if (maxChars <= 0 || value.length <= maxChars)
108
+ return value;
109
+ return `${value.slice(0, maxChars)}\n\n[truncated after ${maxChars} characters]`;
61
110
  }
62
- export function isDocumentAttachment(name, mimeType) {
63
- if (isTextLikeAttachment(name, mimeType)) {
64
- return true;
111
+ export function docReadInstruction(name, fsPath, mimeType) {
112
+ const lower = name.toLowerCase();
113
+ const mime = mimeType?.toLowerCase();
114
+ const isPdf = lower.endsWith('.pdf') || mime === 'application/pdf';
115
+ if (isPdf) {
116
+ 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.`;
65
117
  }
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));
81
- }
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;
118
+ if (/\.docx$/.test(lower)) {
119
+ 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.`;
120
+ }
121
+ if (/\.xlsx$/.test(lower)) {
122
+ return `Extract data from this .xlsx via a Python one-liner using openpyxl. Do NOT open it in a browser or screenshot.`;
123
+ }
124
+ if (/\.pptx$/.test(lower)) {
125
+ return `Extract text from this .pptx via a Python one-liner using python-pptx. Do NOT open it in a browser or screenshot.`;
87
126
  }
88
- return normalized ?? fromName;
127
+ if (/\.(docx?|xlsx?|pptx?)$/.test(lower)) {
128
+ 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.`;
129
+ }
130
+ return undefined;
89
131
  }
90
- export function normalizeMimeType(value) {
91
- const trimmed = value?.split(';')[0]?.trim().toLowerCase();
92
- return trimmed || undefined;
132
+ export async function renderAttachmentBlock(attachment, maxTextChars) {
133
+ const { name, path: fsPath, mimeType, url } = attachment;
134
+ const kind = classifyAttachment(name, mimeType);
135
+ if (kind === 'image') {
136
+ return `## ${name}${fsPath ? `: ${fsPath}` : ''}`;
137
+ }
138
+ if (kind === 'text' && fsPath) {
139
+ try {
140
+ const buffer = await readFile(fsPath, 'utf8');
141
+ const text = truncateText(buffer, maxTextChars);
142
+ const fence = fenceForName(name);
143
+ return `## ${name}: ${fsPath}\n\`\`\`${fence}\n${text}\n\`\`\``;
144
+ }
145
+ catch (error) {
146
+ return `## ${name}: ${fsPath}\n[Failed to read file: ${error.message}]`;
147
+ }
148
+ }
149
+ if (kind === 'doc') {
150
+ const heading = `## ${name}${fsPath ? `: ${fsPath}` : url ? `: ${url}` : ''}`;
151
+ const instruction = fsPath ? docReadInstruction(name, fsPath, mimeType) : undefined;
152
+ return instruction ? `${heading}\n${instruction}` : heading;
153
+ }
154
+ return `## ${name}${fsPath ? `: ${fsPath}` : url ? `: ${url}` : ''}`;
93
155
  }
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');
156
+ export async function renderAttachmentContext(attachments, options = {}) {
157
+ const maxTextChars = options.maxTextChars ?? 128_000;
158
+ const fileAttachments = attachments.filter((a) => classifyAttachment(a.name, a.mimeType) !== 'image');
159
+ if (fileAttachments.length === 0 && !options.hasImages) {
160
+ return undefined;
161
+ }
162
+ const lines = [];
163
+ if (fileAttachments.length > 0) {
164
+ const blocks = [];
165
+ for (const attachment of fileAttachments) {
166
+ blocks.push(await renderAttachmentBlock(attachment, maxTextChars));
167
+ }
168
+ if (blocks.length > 0) {
169
+ lines.push('# Files mentioned by the user:', '', blocks.join('\n\n'));
170
+ }
171
+ }
172
+ if (options.hasImages) {
173
+ if (lines.length > 0)
174
+ lines.push('');
175
+ lines.push('(Image attachments are provided directly as model-visible image content. Do not call file tools for those uploaded images.)');
100
176
  }
101
- return false;
177
+ if (lines.length === 0)
178
+ return undefined;
179
+ lines.push('', "(The user's language follows the request text above, not the attached file contents. Respond in the user's language.)");
180
+ return lines.join('\n').trim();
102
181
  }
103
182
  //# 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,3 @@
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ export default function piAttachmentsExtension(pi: ExtensionAPI): void;
3
+ //# sourceMappingURL=extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AAQtF,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAgFrE"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Pi Attachments Extension
3
+ *
4
+ * Intercepts user input containing @path references, reads the files,
5
+ * classifies them, and injects their content into the prompt as context.
6
+ * Image files are encoded as base64 ImageContent for multimodal input.
7
+ *
8
+ * Supports:
9
+ * - @path/to/file.ts — unquoted file reference
10
+ * - @"/path with spaces/file.pdf" — quoted file reference
11
+ * - @file.ts#L10-20 — line range (parsed but range applied by LLM tools)
12
+ */
13
+ import { readdir, readFile, stat } from 'node:fs/promises';
14
+ import path from 'node:path';
15
+ import { classifyAttachment, renderAttachmentContext } from './classify.js';
16
+ const QUOTED_AT_RE = /(^|\s)@"([^"]+)"/g;
17
+ const REGULAR_AT_RE = /(^|\s)@([^\s@"]+)/g;
18
+ export default function piAttachmentsExtension(pi) {
19
+ const maxTextChars = Number(process.env.PI_ATTACHMENT_MAX_TEXT_CHARS) || 128_000;
20
+ pi.on('input', async (event, ctx) => {
21
+ const mentions = extractAtMentions(event.text);
22
+ if (mentions.length === 0)
23
+ return;
24
+ const cwd = ctx.cwd;
25
+ const attachments = [];
26
+ const images = [...(event.images ?? [])];
27
+ const resolvedPaths = new Set();
28
+ for (const mention of mentions) {
29
+ const { filename } = parseFileReference(mention);
30
+ const absolutePath = path.isAbsolute(filename) ? filename : path.resolve(cwd, filename);
31
+ if (resolvedPaths.has(absolutePath))
32
+ continue;
33
+ resolvedPaths.add(absolutePath);
34
+ try {
35
+ const stats = await stat(absolutePath);
36
+ if (stats.isDirectory()) {
37
+ const entries = await readdir(absolutePath);
38
+ attachments.push({
39
+ id: absolutePath,
40
+ name: path.basename(absolutePath),
41
+ path: absolutePath,
42
+ mimeType: 'inode/directory',
43
+ });
44
+ continue;
45
+ }
46
+ const name = path.basename(absolutePath);
47
+ const mimeType = guessMimeType(name);
48
+ const kind = classifyAttachment(name, mimeType);
49
+ if (kind === 'image') {
50
+ try {
51
+ const data = await readFile(absolutePath);
52
+ images.push({
53
+ type: 'image',
54
+ mimeType: mimeType ?? 'image/png',
55
+ data: data.toString('base64'),
56
+ });
57
+ }
58
+ catch {
59
+ // skip unreadable images
60
+ }
61
+ }
62
+ else {
63
+ attachments.push({
64
+ id: absolutePath,
65
+ name,
66
+ path: absolutePath,
67
+ ...(mimeType ? { mimeType } : {}),
68
+ size: stats.size,
69
+ });
70
+ }
71
+ }
72
+ catch {
73
+ // skip files that don't exist or can't be accessed
74
+ }
75
+ }
76
+ if (attachments.length === 0 && images.length === (event.images?.length ?? 0)) {
77
+ return;
78
+ }
79
+ const cleanText = stripAtMentions(event.text);
80
+ const context = await renderAttachmentContext(attachments, {
81
+ maxTextChars,
82
+ hasImages: images.length > 0,
83
+ });
84
+ const text = context
85
+ ? `${cleanText}\n\n<system-reminder>\n${context}\n</system-reminder>`
86
+ : cleanText;
87
+ return {
88
+ action: 'transform',
89
+ text,
90
+ ...(images.length > 0 ? { images } : {}),
91
+ };
92
+ });
93
+ }
94
+ function extractAtMentions(content) {
95
+ const mentions = [];
96
+ const seen = new Set();
97
+ for (const match of content.matchAll(QUOTED_AT_RE)) {
98
+ const value = match[2];
99
+ if (!seen.has(value)) {
100
+ seen.add(value);
101
+ mentions.push(value);
102
+ }
103
+ }
104
+ for (const match of content.matchAll(REGULAR_AT_RE)) {
105
+ const value = match[2];
106
+ if (!seen.has(value) && !value.startsWith('http')) {
107
+ seen.add(value);
108
+ mentions.push(value);
109
+ }
110
+ }
111
+ return mentions;
112
+ }
113
+ function stripAtMentions(content) {
114
+ return content.replace(QUOTED_AT_RE, '$1').replace(REGULAR_AT_RE, '$1').trim();
115
+ }
116
+ function parseFileReference(mention) {
117
+ const hashIdx = mention.indexOf('#L');
118
+ if (hashIdx === -1) {
119
+ return { filename: mention };
120
+ }
121
+ const filename = mention.slice(0, hashIdx);
122
+ const range = mention.slice(hashIdx + 2);
123
+ const parts = range.split('-');
124
+ const lineStart = Number(parts[0]) || undefined;
125
+ const lineEnd = parts[1] ? Number(parts[1]) || undefined : undefined;
126
+ return {
127
+ filename,
128
+ ...(lineStart ? { lineStart } : {}),
129
+ ...(lineEnd ? { lineEnd } : {}),
130
+ };
131
+ }
132
+ const MIME_BY_EXT = {
133
+ png: 'image/png',
134
+ jpg: 'image/jpeg',
135
+ jpeg: 'image/jpeg',
136
+ gif: 'image/gif',
137
+ webp: 'image/webp',
138
+ svg: 'image/svg+xml',
139
+ bmp: 'image/bmp',
140
+ avif: 'image/avif',
141
+ heic: 'image/heic',
142
+ pdf: 'application/pdf',
143
+ json: 'application/json',
144
+ xml: 'application/xml',
145
+ };
146
+ function guessMimeType(name) {
147
+ const ext = name.toLowerCase().split('.').pop();
148
+ return ext ? MIME_BY_EXT[ext] : undefined;
149
+ }
150
+ //# sourceMappingURL=extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,3 @@
1
- export { type AttachmentDependencyCheck, checkAttachmentHostDependencies, } from './diagnostics.js';
2
- export { AttachmentValidationError, normalizeAttachments, } from './normalize.js';
3
- export { renderAttachmentPrompt } from './prompt.js';
4
- export { handleAttachmentRoutes } from './routes.js';
5
- export { type AttachmentService, createAttachmentService, } from './service.js';
6
- export type { AttachmentContext, AttachmentFailure, AttachmentServiceConfig, AttachmentSource, ChatAttachmentInput, NormalizedAttachment, PreparedAttachmentBundle, StoredAttachmentRecord, } from './types.js';
7
- export type { AttachmentUploadAuth } from './upload-proxy.js';
1
+ export { type AttachmentKind, type AttachmentMeta, classifyAttachment, docReadInstruction, fenceForName, renderAttachmentBlock, renderAttachmentContext, truncateText, } from './classify.js';
2
+ export { default } from './extension.js';
8
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,yBAAyB,EAC9B,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,KAAK,iBAAiB,EACtB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,qBAAqB,EACrB,uBAAuB,EACvB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,3 @@
1
- export { checkAttachmentHostDependencies, } from './diagnostics.js';
2
- export { AttachmentValidationError, normalizeAttachments, } from './normalize.js';
3
- export { renderAttachmentPrompt } from './prompt.js';
4
- export { handleAttachmentRoutes } from './routes.js';
5
- export { createAttachmentService, } from './service.js';
1
+ export { classifyAttachment, docReadInstruction, fenceForName, renderAttachmentBlock, renderAttachmentContext, truncateText, } from './classify.js';
2
+ export { default } from './extension.js';
6
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAEL,uBAAuB,GACxB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,qBAAqB,EACrB,uBAAuB,EACvB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,15 @@
1
1
  {
2
2
  "name": "@amaster.ai/pi-attachments",
3
- "version": "0.1.2-beta.1",
3
+ "version": "0.1.2-beta.11",
4
+ "description": "Pi extension for attachment processing — classifies, parses, and renders file attachments into LLM-visible prompt context",
5
+ "keywords": [
6
+ "pi-package",
7
+ "pi",
8
+ "extension",
9
+ "attachments",
10
+ "files",
11
+ "documents"
12
+ ],
4
13
  "license": "Apache-2.0",
5
14
  "type": "module",
6
15
  "sideEffects": false,
@@ -19,21 +28,35 @@
19
28
  "dist",
20
29
  "README.md"
21
30
  ],
31
+ "pi": {
32
+ "extensions": [
33
+ "./dist/index.js"
34
+ ]
35
+ },
22
36
  "publishConfig": {
23
37
  "access": "public"
24
38
  },
25
39
  "repository": {
26
40
  "type": "git",
27
41
  "url": "https://github.com/TGYD-helige/pi.git",
28
- "directory": "packages/attachments"
42
+ "directory": "packages/pi-attachments"
43
+ },
44
+ "dependencies": {},
45
+ "peerDependencies": {
46
+ "@earendil-works/pi-coding-agent": ">=0.74.0"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "@earendil-works/pi-coding-agent": {
50
+ "optional": true
51
+ }
29
52
  },
30
- "dependencies": {
31
- "@llamaindex/liteparse": "1.5.3",
32
- "jszip": "3.10.1"
53
+ "devDependencies": {
54
+ "@earendil-works/pi-coding-agent": "0.74.0",
55
+ "vitest": "^4.0.0"
33
56
  },
34
57
  "scripts": {
35
58
  "build": "tsc -b",
36
59
  "typecheck": "tsc -b --pretty false",
37
- "test": "vitest run"
60
+ "test": "vitest run src"
38
61
  }
39
62
  }