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.
@@ -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,7 @@
1
+ export interface FileReadResult {
2
+ content: string;
3
+ size: number;
4
+ error?: string;
5
+ }
6
+ export declare function readFileContent(filePath: string, maxFileSize?: number): Promise<FileReadResult>;
7
+ //# sourceMappingURL=file-reader.d.ts.map
@@ -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,3 @@
1
+ import type { TreeNode } from './tree-builder';
2
+ export declare function formatOutput(root: TreeNode, rootPath: string): string;
3
+ //# sourceMappingURL=output-formatter.d.ts.map
@@ -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,2 @@
1
+ export declare const VERSION = "0.1.0";
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const VERSION = '0.1.0';
2
+ //# sourceMappingURL=version.js.map
@@ -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
+ }
@@ -0,0 +1,10 @@
1
+ ---
2
+ description: Index current directory with root file contents
3
+ agent: executor
4
+ ---
5
+
6
+ Use the `tree_indexer` tool to index the current working directory.
7
+ - path: `.`
8
+ - maxFileSize: `102400`
9
+
10
+ Return the markdown output directly.
package/src/version.ts ADDED
@@ -0,0 +1 @@
1
+ export const VERSION = '0.1.0';