opencode-codeindex 0.1.0
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/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +99 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/file-reader.d.ts +7 -0
- package/dist/lib/file-reader.d.ts.map +1 -0
- package/dist/lib/file-reader.js +62 -0
- package/dist/lib/file-reader.js.map +1 -0
- package/dist/lib/output-formatter.d.ts +3 -0
- package/dist/lib/output-formatter.d.ts.map +1 -0
- package/dist/lib/output-formatter.js +82 -0
- package/dist/lib/output-formatter.js.map +1 -0
- package/dist/lib/tree-builder.d.ts +18 -0
- package/dist/lib/tree-builder.d.ts.map +1 -0
- package/dist/lib/tree-builder.js +142 -0
- package/dist/lib/tree-builder.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +55 -0
- package/src/commands/index.md +10 -0
- package/src/version.ts +1 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Plugin } from '@opencode-ai/plugin';
|
|
2
|
+
interface IndexArgs {
|
|
3
|
+
path: string;
|
|
4
|
+
maxFileSize?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function indexDirectory(args: IndexArgs): Promise<string>;
|
|
7
|
+
export declare const CodeIndexPlugin: Plugin;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAqBlD,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAmDD,wBAAsB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBrE;AAED,eAAO,MAAM,eAAe,EAAE,MAkC7B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { tool } from '@opencode-ai/plugin';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { buildTree } from './lib/tree-builder';
|
|
5
|
+
import { readFileContent } from './lib/file-reader';
|
|
6
|
+
import { formatOutput } from './lib/output-formatter';
|
|
7
|
+
function parseFrontmatter(content) {
|
|
8
|
+
const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
|
|
9
|
+
const match = content.match(frontmatterRegex);
|
|
10
|
+
if (!match) {
|
|
11
|
+
return { frontmatter: {}, body: content.trim() };
|
|
12
|
+
}
|
|
13
|
+
const [, yamlContent, body] = match;
|
|
14
|
+
const frontmatter = {};
|
|
15
|
+
for (const line of yamlContent.split('\n')) {
|
|
16
|
+
const colonIndex = line.indexOf(':');
|
|
17
|
+
if (colonIndex === -1)
|
|
18
|
+
continue;
|
|
19
|
+
const key = line.slice(0, colonIndex).trim();
|
|
20
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
21
|
+
if (key === 'description')
|
|
22
|
+
frontmatter.description = value;
|
|
23
|
+
if (key === 'agent')
|
|
24
|
+
frontmatter.agent = value;
|
|
25
|
+
if (key === 'model')
|
|
26
|
+
frontmatter.model = value;
|
|
27
|
+
if (key === 'subtask')
|
|
28
|
+
frontmatter.subtask = value === 'true';
|
|
29
|
+
}
|
|
30
|
+
return { frontmatter, body: body.trim() };
|
|
31
|
+
}
|
|
32
|
+
async function loadCommands() {
|
|
33
|
+
const commands = [];
|
|
34
|
+
const commandDir = path.join(import.meta.dir, 'commands');
|
|
35
|
+
const glob = new Bun.Glob('**/*.md');
|
|
36
|
+
for await (const file of glob.scan({ cwd: commandDir, absolute: true })) {
|
|
37
|
+
const content = await Bun.file(file).text();
|
|
38
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
39
|
+
const relativePath = path.relative(commandDir, file);
|
|
40
|
+
const name = relativePath.replace(/\.md$/, '').replace(/\//g, '-');
|
|
41
|
+
commands.push({
|
|
42
|
+
name,
|
|
43
|
+
frontmatter,
|
|
44
|
+
template: body,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return commands;
|
|
48
|
+
}
|
|
49
|
+
export async function indexDirectory(args) {
|
|
50
|
+
const targetPath = path.resolve(args.path);
|
|
51
|
+
const stat = await fs.stat(targetPath);
|
|
52
|
+
if (!stat.isDirectory()) {
|
|
53
|
+
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
54
|
+
}
|
|
55
|
+
const tree = await buildTree(targetPath);
|
|
56
|
+
const rootFiles = (tree.children ?? []).filter((node) => node.type === 'file');
|
|
57
|
+
for (const file of rootFiles) {
|
|
58
|
+
const result = await readFileContent(file.path, args.maxFileSize);
|
|
59
|
+
file.content = result.content;
|
|
60
|
+
if (result.error)
|
|
61
|
+
file.error = result.error;
|
|
62
|
+
file.size = result.size;
|
|
63
|
+
}
|
|
64
|
+
return formatOutput(tree, targetPath);
|
|
65
|
+
}
|
|
66
|
+
export const CodeIndexPlugin = async () => {
|
|
67
|
+
const commands = await loadCommands();
|
|
68
|
+
const treeIndexerTool = tool({
|
|
69
|
+
description: 'Generate a directory tree with root file contents',
|
|
70
|
+
args: {
|
|
71
|
+
path: tool.schema.string().describe('Root path to index'),
|
|
72
|
+
maxFileSize: tool.schema.number().optional().describe('Max file size in bytes'),
|
|
73
|
+
},
|
|
74
|
+
async execute(args) {
|
|
75
|
+
return indexDirectory({
|
|
76
|
+
path: args.path,
|
|
77
|
+
maxFileSize: args.maxFileSize,
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
tool: {
|
|
83
|
+
tree_indexer: treeIndexerTool,
|
|
84
|
+
},
|
|
85
|
+
async config(config) {
|
|
86
|
+
config.command = config.command ?? {};
|
|
87
|
+
for (const cmd of commands) {
|
|
88
|
+
config.command[cmd.name] = {
|
|
89
|
+
template: cmd.template,
|
|
90
|
+
description: cmd.frontmatter.description,
|
|
91
|
+
agent: cmd.frontmatter.agent,
|
|
92
|
+
model: cmd.frontmatter.model,
|
|
93
|
+
subtask: cmd.frontmatter.subtask,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-reader.d.ts","sourceRoot":"","sources":["../../src/lib/file-reader.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmCD,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,MAA8B,GAC1C,OAAO,CAAC,cAAc,CAAC,CA2BzB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import isBinaryPath from 'is-binary-path';
|
|
3
|
+
const DEFAULT_MAX_FILE_SIZE = 100 * 1024;
|
|
4
|
+
const PROBE_LENGTH = 8000;
|
|
5
|
+
function formatSize(bytes) {
|
|
6
|
+
if (bytes < 1024)
|
|
7
|
+
return `${bytes} B`;
|
|
8
|
+
if (bytes < 1024 * 1024)
|
|
9
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
10
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
11
|
+
}
|
|
12
|
+
async function readProbe(filePath) {
|
|
13
|
+
const handle = await fs.open(filePath, 'r');
|
|
14
|
+
try {
|
|
15
|
+
const buffer = Buffer.alloc(PROBE_LENGTH);
|
|
16
|
+
const { bytesRead } = await handle.read(buffer, 0, PROBE_LENGTH, 0);
|
|
17
|
+
return buffer.subarray(0, bytesRead);
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
await handle.close();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function isBinaryBuffer(buffer) {
|
|
24
|
+
return buffer.includes(0);
|
|
25
|
+
}
|
|
26
|
+
function formatError(err, fallback) {
|
|
27
|
+
if (err && typeof err === 'object' && 'code' in err) {
|
|
28
|
+
const code = String(err.code ?? '');
|
|
29
|
+
if (code === 'EACCES' || code === 'EPERM')
|
|
30
|
+
return 'Permission denied';
|
|
31
|
+
}
|
|
32
|
+
if (err instanceof Error)
|
|
33
|
+
return err.message;
|
|
34
|
+
return fallback;
|
|
35
|
+
}
|
|
36
|
+
export async function readFileContent(filePath, maxFileSize = DEFAULT_MAX_FILE_SIZE) {
|
|
37
|
+
try {
|
|
38
|
+
const stat = await fs.stat(filePath);
|
|
39
|
+
const size = stat.size;
|
|
40
|
+
if (size > maxFileSize) {
|
|
41
|
+
return {
|
|
42
|
+
size,
|
|
43
|
+
content: `[File too large: ${formatSize(size)}]`,
|
|
44
|
+
error: 'File too large',
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const probe = await readProbe(filePath);
|
|
48
|
+
if (isBinaryPath(filePath) || isBinaryBuffer(probe)) {
|
|
49
|
+
return { size, content: '[Binary file]', error: 'Binary file' };
|
|
50
|
+
}
|
|
51
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
52
|
+
return { size, content };
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
return {
|
|
56
|
+
size: 0,
|
|
57
|
+
content: `[${formatError(err, 'Read error')}]`,
|
|
58
|
+
error: formatError(err, 'Read error'),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=file-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-reader.js","sourceRoot":"","sources":["../../src/lib/file-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-formatter.d.ts","sourceRoot":"","sources":["../../src/lib/output-formatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAmD/C,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA8BrE"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
function formatSize(bytes) {
|
|
3
|
+
if (bytes === undefined)
|
|
4
|
+
return '';
|
|
5
|
+
if (bytes < 1024)
|
|
6
|
+
return `${bytes} B`;
|
|
7
|
+
if (bytes < 1024 * 1024)
|
|
8
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
9
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
10
|
+
}
|
|
11
|
+
function formatLanguage(filename) {
|
|
12
|
+
const ext = path.extname(filename).toLowerCase();
|
|
13
|
+
if (ext === '.md')
|
|
14
|
+
return 'markdown';
|
|
15
|
+
if (ext === '.json')
|
|
16
|
+
return 'json';
|
|
17
|
+
if (ext === '.ts')
|
|
18
|
+
return 'typescript';
|
|
19
|
+
if (ext === '.tsx')
|
|
20
|
+
return 'tsx';
|
|
21
|
+
if (ext === '.js')
|
|
22
|
+
return 'javascript';
|
|
23
|
+
if (ext === '.yml' || ext === '.yaml')
|
|
24
|
+
return 'yaml';
|
|
25
|
+
return 'text';
|
|
26
|
+
}
|
|
27
|
+
function renderTree(root) {
|
|
28
|
+
const lines = [];
|
|
29
|
+
const rootLabel = `${path.basename(root.path) || root.path}/`;
|
|
30
|
+
lines.push(rootLabel);
|
|
31
|
+
const children = root.children ?? [];
|
|
32
|
+
const renderChildren = (nodes, prefix) => {
|
|
33
|
+
nodes.forEach((node, index) => {
|
|
34
|
+
const isLast = index === nodes.length - 1;
|
|
35
|
+
const connector = isLast ? '└── ' : '├── ';
|
|
36
|
+
const name = node.type === 'directory' ? `${node.name}/` : node.name;
|
|
37
|
+
const size = node.type === 'file' ? ` (${formatSize(node.size)})` : '';
|
|
38
|
+
const error = node.error ? ` [${node.error}]` : '';
|
|
39
|
+
lines.push(`${prefix}${connector}${name}${size}${error}`);
|
|
40
|
+
if (node.type === 'directory' && node.children && node.children.length > 0) {
|
|
41
|
+
const nextPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
42
|
+
renderChildren(node.children, nextPrefix);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const ordered = [...children].sort((a, b) => {
|
|
47
|
+
if (a.type !== b.type)
|
|
48
|
+
return a.type === 'directory' ? -1 : 1;
|
|
49
|
+
return a.name.localeCompare(b.name);
|
|
50
|
+
});
|
|
51
|
+
renderChildren(ordered, '');
|
|
52
|
+
return lines;
|
|
53
|
+
}
|
|
54
|
+
export function formatOutput(root, rootPath) {
|
|
55
|
+
const lines = [];
|
|
56
|
+
lines.push(`# Directory Index: ${rootPath}`);
|
|
57
|
+
lines.push('');
|
|
58
|
+
lines.push('## File Structure');
|
|
59
|
+
lines.push('');
|
|
60
|
+
lines.push('```');
|
|
61
|
+
lines.push(...renderTree(root));
|
|
62
|
+
lines.push('```');
|
|
63
|
+
lines.push('');
|
|
64
|
+
lines.push('## Root Level Files');
|
|
65
|
+
lines.push('');
|
|
66
|
+
const rootFiles = (root.children ?? []).filter((node) => node.type === 'file');
|
|
67
|
+
if (rootFiles.length === 0) {
|
|
68
|
+
lines.push('_No root-level files found._');
|
|
69
|
+
return lines.join('\n');
|
|
70
|
+
}
|
|
71
|
+
for (const file of rootFiles) {
|
|
72
|
+
const content = file.content ?? (file.error ? `[${file.error}]` : '[No content]');
|
|
73
|
+
const language = formatLanguage(file.name);
|
|
74
|
+
lines.push(`### ${file.name}`);
|
|
75
|
+
lines.push('```' + language);
|
|
76
|
+
lines.push(content);
|
|
77
|
+
lines.push('```');
|
|
78
|
+
lines.push('');
|
|
79
|
+
}
|
|
80
|
+
return lines.join('\n');
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=output-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-formatter.js","sourceRoot":"","sources":["../../src/lib/output-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface TreeNode {
|
|
2
|
+
name: string;
|
|
3
|
+
path: string;
|
|
4
|
+
type: 'file' | 'directory';
|
|
5
|
+
depth: number;
|
|
6
|
+
children?: TreeNode[];
|
|
7
|
+
content?: string;
|
|
8
|
+
size?: number;
|
|
9
|
+
error?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface TreeBuilderOptions {
|
|
12
|
+
skipNames?: string[];
|
|
13
|
+
skipExtensions?: string[];
|
|
14
|
+
respectGitignore?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const DEFAULT_SKIP_NAMES: Set<string>;
|
|
17
|
+
export declare function buildTree(rootPath: string, options?: TreeBuilderOptions): Promise<TreeNode>;
|
|
18
|
+
//# sourceMappingURL=tree-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-builder.d.ts","sourceRoot":"","sources":["../../src/lib/tree-builder.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,kBAAkB,aAM7B,CAAC;AAsIH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,QAAQ,CAAC,CA6BnB"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import ignore from 'ignore';
|
|
4
|
+
export const DEFAULT_SKIP_NAMES = new Set([
|
|
5
|
+
'.git',
|
|
6
|
+
'node_modules',
|
|
7
|
+
'.opencode',
|
|
8
|
+
'dist',
|
|
9
|
+
'build',
|
|
10
|
+
]);
|
|
11
|
+
const DEFAULT_SKIP_EXTENSIONS = new Set(['.log']);
|
|
12
|
+
function normalizeGitignorePath(relativePath) {
|
|
13
|
+
return relativePath.split(path.sep).join('/');
|
|
14
|
+
}
|
|
15
|
+
function formatError(err, fallback) {
|
|
16
|
+
if (err && typeof err === 'object' && 'code' in err) {
|
|
17
|
+
const code = String(err.code ?? '');
|
|
18
|
+
if (code === 'EACCES' || code === 'EPERM')
|
|
19
|
+
return 'Permission denied';
|
|
20
|
+
if (code === 'ENOENT')
|
|
21
|
+
return 'Path not found';
|
|
22
|
+
}
|
|
23
|
+
if (err instanceof Error)
|
|
24
|
+
return err.message;
|
|
25
|
+
return fallback;
|
|
26
|
+
}
|
|
27
|
+
async function loadGitignore(rootPath, enabled) {
|
|
28
|
+
if (!enabled)
|
|
29
|
+
return null;
|
|
30
|
+
const gitignorePath = path.join(rootPath, '.gitignore');
|
|
31
|
+
try {
|
|
32
|
+
const content = await fs.readFile(gitignorePath, 'utf8');
|
|
33
|
+
return ignore().add(content);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function shouldSkip(name, skipNames, skipExtensions) {
|
|
40
|
+
if (skipNames.has(name))
|
|
41
|
+
return true;
|
|
42
|
+
for (const ext of skipExtensions) {
|
|
43
|
+
if (name.endsWith(ext))
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
async function walkDirectory(absolutePath, relativePath, depth, ignoreRules, skipNames, skipExtensions, visited) {
|
|
49
|
+
let entries = [];
|
|
50
|
+
try {
|
|
51
|
+
entries = await fs.readdir(absolutePath, { withFileTypes: true });
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
return [
|
|
55
|
+
{
|
|
56
|
+
name: path.basename(absolutePath),
|
|
57
|
+
path: absolutePath,
|
|
58
|
+
type: 'directory',
|
|
59
|
+
depth,
|
|
60
|
+
error: formatError(err, 'Read error'),
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
const nodes = [];
|
|
65
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
66
|
+
if (shouldSkip(entry.name, skipNames, skipExtensions))
|
|
67
|
+
continue;
|
|
68
|
+
const entryPath = path.join(absolutePath, entry.name);
|
|
69
|
+
const entryRelative = normalizeGitignorePath(path.join(relativePath, entry.name));
|
|
70
|
+
if (ignoreRules?.ignores(entryRelative))
|
|
71
|
+
continue;
|
|
72
|
+
try {
|
|
73
|
+
const stat = await fs.lstat(entryPath);
|
|
74
|
+
if (stat.isSymbolicLink()) {
|
|
75
|
+
const resolved = await fs.realpath(entryPath);
|
|
76
|
+
const resolvedStat = await fs.stat(entryPath);
|
|
77
|
+
if (resolvedStat.isDirectory()) {
|
|
78
|
+
if (visited.has(resolved)) {
|
|
79
|
+
nodes.push({
|
|
80
|
+
name: entry.name,
|
|
81
|
+
path: entryPath,
|
|
82
|
+
type: 'directory',
|
|
83
|
+
depth,
|
|
84
|
+
error: 'Circular reference',
|
|
85
|
+
});
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
visited.add(resolved);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (stat.isDirectory()) {
|
|
92
|
+
const children = await walkDirectory(entryPath, entryRelative, depth + 1, ignoreRules, skipNames, skipExtensions, visited);
|
|
93
|
+
nodes.push({
|
|
94
|
+
name: entry.name,
|
|
95
|
+
path: entryPath,
|
|
96
|
+
type: 'directory',
|
|
97
|
+
depth,
|
|
98
|
+
children,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
nodes.push({
|
|
103
|
+
name: entry.name,
|
|
104
|
+
path: entryPath,
|
|
105
|
+
type: 'file',
|
|
106
|
+
depth,
|
|
107
|
+
size: stat.size,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
nodes.push({
|
|
113
|
+
name: entry.name,
|
|
114
|
+
path: entryPath,
|
|
115
|
+
type: entry.isDirectory() ? 'directory' : 'file',
|
|
116
|
+
depth,
|
|
117
|
+
error: formatError(err, 'Read error'),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return nodes;
|
|
122
|
+
}
|
|
123
|
+
export async function buildTree(rootPath, options = {}) {
|
|
124
|
+
const resolvedRoot = path.resolve(rootPath);
|
|
125
|
+
const stat = await fs.stat(resolvedRoot);
|
|
126
|
+
if (!stat.isDirectory()) {
|
|
127
|
+
throw new Error(`Path is not a directory: ${resolvedRoot}`);
|
|
128
|
+
}
|
|
129
|
+
const ignoreRules = await loadGitignore(resolvedRoot, options.respectGitignore !== false);
|
|
130
|
+
const skipNames = new Set(options.skipNames ?? Array.from(DEFAULT_SKIP_NAMES));
|
|
131
|
+
const skipExtensions = new Set(options.skipExtensions ?? Array.from(DEFAULT_SKIP_EXTENSIONS));
|
|
132
|
+
const visited = new Set([resolvedRoot]);
|
|
133
|
+
const children = await walkDirectory(resolvedRoot, '', 0, ignoreRules, skipNames, skipExtensions, visited);
|
|
134
|
+
return {
|
|
135
|
+
name: path.basename(resolvedRoot) || resolvedRoot,
|
|
136
|
+
path: resolvedRoot,
|
|
137
|
+
type: 'directory',
|
|
138
|
+
depth: -1,
|
|
139
|
+
children,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=tree-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-builder.js","sourceRoot":"","sources":["../../src/lib/tree-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "opencode-codeindex",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "OpenCode plugin that indexes directories with root file contents.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "OpenCode",
|
|
7
|
+
"email": "dev@opencode.ai"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/your-org/opencode-codeindex"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public",
|
|
22
|
+
"provenance": true
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"src/version.ts",
|
|
27
|
+
"src/commands"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "bunx tsc -p tsconfig.build.json",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"lint": "bunx eslint .",
|
|
33
|
+
"lint:fix": "bunx eslint . --fix",
|
|
34
|
+
"format": "bunx prettier -w .",
|
|
35
|
+
"typecheck": "bunx tsc -p tsconfig.json --noEmit"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@opencode-ai/plugin": "1.0.85",
|
|
39
|
+
"ignore": "^5.3.2",
|
|
40
|
+
"is-binary-path": "^2.1.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@eslint/js": "^9.39.1",
|
|
44
|
+
"@types/node": "^20.11.5",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "8.47.0",
|
|
46
|
+
"@typescript-eslint/parser": "8.47.0",
|
|
47
|
+
"bun-types": "latest",
|
|
48
|
+
"eslint": "^9.39.1",
|
|
49
|
+
"eslint-config-prettier": "10.1.8",
|
|
50
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
51
|
+
"prettier": "^3.2.4",
|
|
52
|
+
"typescript-eslint": "^8.47.0",
|
|
53
|
+
"vitest": "^3.2.4"
|
|
54
|
+
}
|
|
55
|
+
}
|
package/src/version.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const VERSION = '0.1.0';
|