nia-opencode 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/README.md ADDED
@@ -0,0 +1,130 @@
1
+ # nia-opencode
2
+
3
+ OpenCode plugin that integrates [Nia Knowledge Agent](https://trynia.ai) for research, documentation, and codebase exploration.
4
+
5
+ ## Features
6
+
7
+ - **Keyword Detection**: Automatically detects research-related queries and prompts the agent to use Nia tools
8
+ - **MCP Integration**: Connects to Nia's MCP server for semantic search, documentation indexing, and AI research
9
+ - **Zero Config**: Works out of the box with automatic MCP server setup
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ bunx nia-opencode@latest install
15
+ ```
16
+
17
+ The installer will:
18
+ 1. Prompt for your Nia API key
19
+ 2. Create `~/.config/opencode/nia.json` with your config
20
+ 3. Add the plugin and MCP server to your OpenCode config
21
+
22
+ ### Non-Interactive Installation
23
+
24
+ ```bash
25
+ bunx nia-opencode@latest install --no-tui --api-key nk_your_api_key
26
+ ```
27
+
28
+ ### Manual Setup
29
+
30
+ 1. Add to your `~/.config/opencode/opencode.json`:
31
+
32
+ ```json
33
+ {
34
+ "plugin": ["nia-opencode@latest"],
35
+ "mcp": {
36
+ "nia": {
37
+ "type": "remote",
38
+ "url": "https://apigcp.trynia.ai/mcp",
39
+ "headers": {
40
+ "Authorization": "Bearer nk_your_api_key"
41
+ },
42
+ "oauth": false
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ 2. Set your API key (choose one):
49
+
50
+ **Environment variable:**
51
+ ```bash
52
+ export NIA_API_KEY="nk_your_api_key"
53
+ ```
54
+
55
+ **Config file** (`~/.config/opencode/nia.json`):
56
+ ```json
57
+ {
58
+ "apiKey": "nk_your_api_key"
59
+ }
60
+ ```
61
+
62
+ ## Usage
63
+
64
+ Once installed, the plugin automatically detects research-related queries and prompts the agent to use Nia tools.
65
+
66
+ ### Trigger Keywords
67
+
68
+ The plugin activates when you say things like:
69
+ - "Research how React hooks work"
70
+ - "Look up the Next.js documentation"
71
+ - "Search the codebase for authentication"
72
+ - "Find docs for Prisma migrations"
73
+ - "Grep for error handling patterns"
74
+ - "Index this repo"
75
+
76
+ ### Available Nia Tools
77
+
78
+ When triggered, the agent has access to:
79
+
80
+ | Tool | Description |
81
+ |------|-------------|
82
+ | `nia.search` | Semantic search across indexed repos, docs, papers |
83
+ | `nia.nia_research` | Web search (quick) or deep AI research (deep/oracle) |
84
+ | `nia.index` | Index GitHub repos, docs sites, or arXiv papers |
85
+ | `nia.nia_read` | Read files from indexed sources |
86
+ | `nia.nia_grep` | Regex search across codebases |
87
+ | `nia.nia_explore` | Browse file trees |
88
+ | `nia.manage_resource` | List/manage indexed sources |
89
+
90
+ ## Configuration
91
+
92
+ ### `~/.config/opencode/nia.json`
93
+
94
+ ```json
95
+ {
96
+ "apiKey": "nk_...",
97
+ "mcpUrl": "https://apigcp.trynia.ai/mcp",
98
+ "keywords": {
99
+ "enabled": true,
100
+ "patterns": [
101
+ "my custom pattern"
102
+ ]
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### Options
108
+
109
+ | Option | Default | Description |
110
+ |--------|---------|-------------|
111
+ | `apiKey` | - | Your Nia API key |
112
+ | `mcpUrl` | `https://apigcp.trynia.ai/mcp` | MCP server URL |
113
+ | `keywords.enabled` | `true` | Enable/disable keyword detection |
114
+ | `keywords.patterns` | `[]` | Additional regex patterns to trigger Nia |
115
+
116
+ ## Debugging
117
+
118
+ Enable debug logging:
119
+
120
+ ```bash
121
+ NIA_DEBUG=true opencode
122
+ ```
123
+
124
+ ## Get Your API Key
125
+
126
+ Get your Nia API key at [trynia.ai/api-keys](https://trynia.ai/api-keys)
127
+
128
+ ## License
129
+
130
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,272 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import { mkdirSync, writeFileSync, readFileSync, existsSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { homedir } from "node:os";
7
+ import * as readline from "node:readline";
8
+ var OPENCODE_CONFIG_DIR = join(homedir(), ".config", "opencode");
9
+ var NIA_CONFIG_PATH = join(OPENCODE_CONFIG_DIR, "nia.json");
10
+ var PLUGIN_NAME = "nia-opencode@latest";
11
+ function stripJsoncComments(content) {
12
+ return content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
13
+ }
14
+ function createReadline() {
15
+ return readline.createInterface({
16
+ input: process.stdin,
17
+ output: process.stdout
18
+ });
19
+ }
20
+ async function confirm(rl, question) {
21
+ return new Promise((resolve) => {
22
+ rl.question(`${question} (y/n) `, (answer) => {
23
+ resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
24
+ });
25
+ });
26
+ }
27
+ async function prompt(rl, question) {
28
+ return new Promise((resolve) => {
29
+ rl.question(question, (answer) => {
30
+ resolve(answer.trim());
31
+ });
32
+ });
33
+ }
34
+ function findOpencodeConfig() {
35
+ const candidates = [
36
+ join(OPENCODE_CONFIG_DIR, "opencode.jsonc"),
37
+ join(OPENCODE_CONFIG_DIR, "opencode.json")
38
+ ];
39
+ for (const path of candidates) {
40
+ if (existsSync(path)) {
41
+ return path;
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+ function addPluginToConfig(configPath) {
47
+ try {
48
+ const content = readFileSync(configPath, "utf-8");
49
+ if (content.includes("nia-opencode")) {
50
+ console.log(" Plugin already registered in config");
51
+ return true;
52
+ }
53
+ const jsonContent = stripJsoncComments(content);
54
+ let config;
55
+ try {
56
+ config = JSON.parse(jsonContent);
57
+ } catch {
58
+ console.error(" Failed to parse config file");
59
+ return false;
60
+ }
61
+ const plugins = config.plugin || [];
62
+ plugins.push(PLUGIN_NAME);
63
+ config.plugin = plugins;
64
+ if (configPath.endsWith(".jsonc")) {
65
+ if (content.includes('"plugin"')) {
66
+ const newContent = content.replace(/("plugin"\s*:\s*\[)([^\]]*?)(\])/, (_match, start, middle, end) => {
67
+ const trimmed = middle.trim();
68
+ if (trimmed === "") {
69
+ return `${start}
70
+ "${PLUGIN_NAME}"
71
+ ${end}`;
72
+ }
73
+ return `${start}${middle.trimEnd()},
74
+ "${PLUGIN_NAME}"
75
+ ${end}`;
76
+ });
77
+ writeFileSync(configPath, newContent);
78
+ } else {
79
+ const newContent = content.replace(/^(\s*\{)/, `$1
80
+ "plugin": ["${PLUGIN_NAME}"],`);
81
+ writeFileSync(configPath, newContent);
82
+ }
83
+ } else {
84
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
85
+ }
86
+ console.log(` Added plugin to ${configPath}`);
87
+ return true;
88
+ } catch (err) {
89
+ console.error(" Failed to update config:", err);
90
+ return false;
91
+ }
92
+ }
93
+ function addMcpServerToConfig(configPath, apiKey) {
94
+ try {
95
+ const content = readFileSync(configPath, "utf-8");
96
+ const jsonContent = stripJsoncComments(content);
97
+ let config;
98
+ try {
99
+ config = JSON.parse(jsonContent);
100
+ } catch {
101
+ console.error(" Failed to parse config file");
102
+ return false;
103
+ }
104
+ const mcp = config.mcp || {};
105
+ if (mcp.nia) {
106
+ console.log(" MCP server 'nia' already configured");
107
+ return true;
108
+ }
109
+ mcp.nia = {
110
+ type: "remote",
111
+ url: "https://apigcp.trynia.ai/mcp",
112
+ headers: {
113
+ Authorization: `Bearer ${apiKey}`
114
+ },
115
+ oauth: false
116
+ };
117
+ config.mcp = mcp;
118
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
119
+ console.log(" Added MCP server 'nia' to config");
120
+ return true;
121
+ } catch (err) {
122
+ console.error(" Failed to add MCP server:", err);
123
+ return false;
124
+ }
125
+ }
126
+ function createNewConfig(apiKey) {
127
+ mkdirSync(OPENCODE_CONFIG_DIR, { recursive: true });
128
+ const configPath = join(OPENCODE_CONFIG_DIR, "opencode.json");
129
+ const config = {
130
+ plugin: [PLUGIN_NAME],
131
+ mcp: {
132
+ nia: {
133
+ type: "remote",
134
+ url: "https://apigcp.trynia.ai/mcp",
135
+ headers: {
136
+ Authorization: `Bearer ${apiKey}`
137
+ },
138
+ oauth: false
139
+ }
140
+ }
141
+ };
142
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
143
+ console.log(` Created ${configPath}`);
144
+ return true;
145
+ }
146
+ function createNiaConfig(apiKey) {
147
+ mkdirSync(OPENCODE_CONFIG_DIR, { recursive: true });
148
+ const config = {
149
+ apiKey,
150
+ keywords: {
151
+ enabled: true
152
+ }
153
+ };
154
+ writeFileSync(NIA_CONFIG_PATH, JSON.stringify(config, null, 2));
155
+ console.log(` Created ${NIA_CONFIG_PATH}`);
156
+ return true;
157
+ }
158
+ async function install(options) {
159
+ console.log(`
160
+ Nia OpenCode Plugin Installer
161
+ `);
162
+ const rl = options.tui ? createReadline() : null;
163
+ console.log("Step 1: Configure API Key");
164
+ let apiKey = options.apiKey || process.env.NIA_API_KEY || "";
165
+ if (!apiKey && options.tui && rl) {
166
+ console.log(`Get your API key from: https://trynia.ai/api-keys
167
+ `);
168
+ apiKey = await prompt(rl, "Enter your Nia API key (nk_...): ");
169
+ }
170
+ if (!apiKey) {
171
+ console.log(" No API key provided. You can set NIA_API_KEY environment variable later.");
172
+ console.log(` Get your API key at: https://trynia.ai/api-keys
173
+ `);
174
+ } else if (!apiKey.startsWith("nk_")) {
175
+ console.log(" Warning: API key should start with 'nk_'");
176
+ } else {
177
+ console.log(" API key configured");
178
+ }
179
+ console.log(`
180
+ Step 2: Create Nia Config`);
181
+ if (apiKey) {
182
+ createNiaConfig(apiKey);
183
+ } else {
184
+ console.log(" Skipped (no API key)");
185
+ }
186
+ console.log(`
187
+ Step 3: Configure OpenCode`);
188
+ const configPath = findOpencodeConfig();
189
+ if (configPath) {
190
+ if (options.tui && rl) {
191
+ const shouldModify = await confirm(rl, `Modify ${configPath}?`);
192
+ if (shouldModify) {
193
+ addPluginToConfig(configPath);
194
+ if (apiKey) {
195
+ addMcpServerToConfig(configPath, apiKey);
196
+ }
197
+ } else {
198
+ console.log(" Skipped.");
199
+ }
200
+ } else {
201
+ addPluginToConfig(configPath);
202
+ if (apiKey) {
203
+ addMcpServerToConfig(configPath, apiKey);
204
+ }
205
+ }
206
+ } else {
207
+ if (options.tui && rl) {
208
+ const shouldCreate = await confirm(rl, "No OpenCode config found. Create one?");
209
+ if (shouldCreate && apiKey) {
210
+ createNewConfig(apiKey);
211
+ } else {
212
+ console.log(" Skipped.");
213
+ }
214
+ } else if (apiKey) {
215
+ createNewConfig(apiKey);
216
+ }
217
+ }
218
+ console.log(`
219
+ ` + "-".repeat(50));
220
+ console.log(`
221
+ Setup Complete!
222
+ `);
223
+ if (!apiKey) {
224
+ console.log("Next steps:");
225
+ console.log("1. Get your API key from: https://trynia.ai/api-keys");
226
+ console.log("2. Set the environment variable:");
227
+ console.log(' export NIA_API_KEY="nk_..."');
228
+ console.log(" Or edit ~/.config/opencode/nia.json");
229
+ } else {
230
+ console.log("Nia is configured and ready to use!");
231
+ }
232
+ console.log(`
233
+ Keyword triggers enabled:`);
234
+ console.log(' - "research...", "look up...", "find docs..."');
235
+ console.log(' - "search codebase...", "grep for..."');
236
+ console.log(' - "index this repo", "add to nia"');
237
+ console.log(`
238
+ Restart OpenCode to activate the plugin.
239
+ `);
240
+ if (rl)
241
+ rl.close();
242
+ return 0;
243
+ }
244
+ function printHelp() {
245
+ console.log(`
246
+ nia-opencode - Nia Knowledge Agent plugin for OpenCode
247
+
248
+ Commands:
249
+ install Install and configure the plugin
250
+ --no-tui Non-interactive mode
251
+ --api-key <key> Provide API key directly
252
+
253
+ Examples:
254
+ bunx nia-opencode@latest install
255
+ bunx nia-opencode@latest install --no-tui --api-key nk_xxx
256
+ `);
257
+ }
258
+ var args = process.argv.slice(2);
259
+ if (args.length === 0 || args[0] === "help" || args[0] === "--help" || args[0] === "-h") {
260
+ printHelp();
261
+ process.exit(0);
262
+ }
263
+ if (args[0] === "install") {
264
+ const noTui = args.includes("--no-tui");
265
+ const apiKeyIndex = args.indexOf("--api-key");
266
+ const apiKey = apiKeyIndex !== -1 ? args[apiKeyIndex + 1] : undefined;
267
+ install({ tui: !noTui, apiKey }).then((code) => process.exit(code));
268
+ } else {
269
+ console.error(`Unknown command: ${args[0]}`);
270
+ printHelp();
271
+ process.exit(1);
272
+ }
@@ -0,0 +1,11 @@
1
+ export declare const NIA_API_KEY: string | undefined;
2
+ export declare const NIA_MCP_URL: string;
3
+ export declare const CONFIG: {
4
+ mcpUrl: string;
5
+ keywords: {
6
+ enabled: boolean;
7
+ customPatterns: string[];
8
+ };
9
+ };
10
+ export declare function isConfigured(): boolean;
11
+ export declare function getConfigDir(): string;
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ export declare const NiaPlugin: Plugin;
3
+ export default NiaPlugin;
package/dist/index.js ADDED
@@ -0,0 +1,171 @@
1
+ // src/config.ts
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { homedir } from "node:os";
5
+ var CONFIG_DIR = join(homedir(), ".config", "opencode");
6
+ var CONFIG_FILES = [
7
+ join(CONFIG_DIR, "nia.jsonc"),
8
+ join(CONFIG_DIR, "nia.json")
9
+ ];
10
+ var DEFAULTS = {
11
+ mcpUrl: "https://apigcp.trynia.ai/mcp",
12
+ keywords: {
13
+ enabled: true,
14
+ patterns: []
15
+ }
16
+ };
17
+ function stripJsoncComments(content) {
18
+ return content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
19
+ }
20
+ function loadConfig() {
21
+ for (const path of CONFIG_FILES) {
22
+ if (existsSync(path)) {
23
+ try {
24
+ const content = readFileSync(path, "utf-8");
25
+ const json = stripJsoncComments(content);
26
+ return JSON.parse(json);
27
+ } catch {}
28
+ }
29
+ }
30
+ return {};
31
+ }
32
+ var fileConfig = loadConfig();
33
+ var NIA_API_KEY = fileConfig.apiKey ?? process.env.NIA_API_KEY;
34
+ var NIA_MCP_URL = fileConfig.mcpUrl ?? process.env.NIA_MCP_URL ?? DEFAULTS.mcpUrl;
35
+ var CONFIG = {
36
+ mcpUrl: NIA_MCP_URL,
37
+ keywords: {
38
+ enabled: fileConfig.keywords?.enabled ?? DEFAULTS.keywords.enabled,
39
+ customPatterns: fileConfig.keywords?.patterns ?? []
40
+ }
41
+ };
42
+ function isConfigured() {
43
+ return !!NIA_API_KEY;
44
+ }
45
+
46
+ // src/keywords.ts
47
+ var CODE_BLOCK_PATTERN = /```[\s\S]*?```/g;
48
+ var INLINE_CODE_PATTERN = /`[^`]+`/g;
49
+ var DEFAULT_PATTERNS = [
50
+ /\b(research|look\s*up|find\s*docs?)\b/i,
51
+ /\b(search\s+for|search\s+codebase|search\s+repo|search\s+docs?)\b/i,
52
+ /\b(grep\s+for|grep\s+in)\b/i,
53
+ /\b(index\s+(this\s+)?repo|add\s+to\s+nia)\b/i,
54
+ /\b(what\s+is|how\s+does|explain)\s+\w+\s+(library|package|framework|module)/i,
55
+ /\bcheck\s+(the\s+)?(docs?|documentation)\s+(for|about|on)\b/i,
56
+ /\bfind\s+(examples?|usage)\s+(of|for)\b/i
57
+ ];
58
+ function removeCodeBlocks(text) {
59
+ return text.replace(CODE_BLOCK_PATTERN, "").replace(INLINE_CODE_PATTERN, "");
60
+ }
61
+ function compileCustomPatterns() {
62
+ return CONFIG.keywords.customPatterns.map((pattern) => {
63
+ try {
64
+ return new RegExp(pattern, "i");
65
+ } catch {
66
+ return null;
67
+ }
68
+ }).filter((p) => p !== null);
69
+ }
70
+ function detectResearchKeyword(text) {
71
+ if (!CONFIG.keywords.enabled) {
72
+ return { detected: false };
73
+ }
74
+ const textWithoutCode = removeCodeBlocks(text);
75
+ const allPatterns = [...DEFAULT_PATTERNS, ...compileCustomPatterns()];
76
+ for (const pattern of allPatterns) {
77
+ const match = textWithoutCode.match(pattern);
78
+ if (match) {
79
+ return { detected: true, match: match[0] };
80
+ }
81
+ }
82
+ return { detected: false };
83
+ }
84
+ var NIA_NUDGE_MESSAGE = `[NIA KNOWLEDGE TRIGGER]
85
+ The user is asking for research, documentation, or codebase exploration. You have access to **Nia** tools via MCP.
86
+
87
+ **Available Nia tools:**
88
+ - \`nia.search\` - Semantic search across indexed repos, docs, and papers
89
+ - \`nia.nia_research\` - Web search (quick) or deep AI research (deep/oracle modes)
90
+ - \`nia.index\` - Index new GitHub repos, documentation sites, or arXiv papers
91
+ - \`nia.nia_read\` - Read specific files from indexed sources
92
+ - \`nia.nia_grep\` - Regex search across indexed codebases
93
+ - \`nia.nia_explore\` - Browse file trees of indexed repos/docs
94
+ - \`nia.manage_resource\` - List/check status of indexed sources
95
+
96
+ **Workflow:**
97
+ 1. Check what's indexed: \`nia.manage_resource(action: "list")\`
98
+ 2. Search or research based on the user's question
99
+ 3. Read specific files if needed for deeper context
100
+
101
+ Use these tools to provide accurate, up-to-date information instead of relying solely on training data.`;
102
+
103
+ // src/services/logger.ts
104
+ var DEBUG = process.env.NIA_DEBUG === "true" || process.env.NIA_DEBUG === "1";
105
+ function log(message, data) {
106
+ if (!DEBUG)
107
+ return;
108
+ const timestamp = new Date().toISOString();
109
+ const prefix = `[nia-opencode ${timestamp}]`;
110
+ if (data) {
111
+ console.log(prefix, message, JSON.stringify(data, null, 2));
112
+ } else {
113
+ console.log(prefix, message);
114
+ }
115
+ }
116
+
117
+ // src/index.ts
118
+ var NiaPlugin = async (ctx) => {
119
+ const { directory } = ctx;
120
+ const injectedSessions = new Set;
121
+ log("Plugin initialized", { directory, configured: isConfigured() });
122
+ if (!isConfigured()) {
123
+ log("Plugin disabled - NIA_API_KEY not set");
124
+ }
125
+ return {
126
+ "chat.message": async (input, output) => {
127
+ if (!isConfigured())
128
+ return;
129
+ const start = Date.now();
130
+ try {
131
+ const textParts = output.parts.filter((p) => p.type === "text");
132
+ if (textParts.length === 0) {
133
+ log("chat.message: no text parts found");
134
+ return;
135
+ }
136
+ const userMessage = textParts.map((p) => p.text).join(`
137
+ `);
138
+ if (!userMessage.trim()) {
139
+ log("chat.message: empty message, skipping");
140
+ return;
141
+ }
142
+ log("chat.message: processing", {
143
+ messagePreview: userMessage.slice(0, 100),
144
+ partsCount: output.parts.length
145
+ });
146
+ const { detected, match } = detectResearchKeyword(userMessage);
147
+ if (detected) {
148
+ log("chat.message: research keyword detected", { match });
149
+ const nudgePart = {
150
+ id: `nia-nudge-${Date.now()}`,
151
+ sessionID: input.sessionID,
152
+ messageID: output.message.id,
153
+ type: "text",
154
+ text: NIA_NUDGE_MESSAGE,
155
+ synthetic: true
156
+ };
157
+ output.parts.push(nudgePart);
158
+ const duration = Date.now() - start;
159
+ log("chat.message: nudge injected", { duration, match });
160
+ }
161
+ } catch (error) {
162
+ log("chat.message: ERROR", { error: String(error) });
163
+ }
164
+ }
165
+ };
166
+ };
167
+ var src_default = NiaPlugin;
168
+ export {
169
+ src_default as default,
170
+ NiaPlugin
171
+ };
@@ -0,0 +1,5 @@
1
+ export declare function detectResearchKeyword(text: string): {
2
+ detected: boolean;
3
+ match?: string;
4
+ };
5
+ export declare const NIA_NUDGE_MESSAGE = "[NIA KNOWLEDGE TRIGGER]\nThe user is asking for research, documentation, or codebase exploration. You have access to **Nia** tools via MCP.\n\n**Available Nia tools:**\n- `nia.search` - Semantic search across indexed repos, docs, and papers\n- `nia.nia_research` - Web search (quick) or deep AI research (deep/oracle modes)\n- `nia.index` - Index new GitHub repos, documentation sites, or arXiv papers\n- `nia.nia_read` - Read specific files from indexed sources\n- `nia.nia_grep` - Regex search across indexed codebases\n- `nia.nia_explore` - Browse file trees of indexed repos/docs\n- `nia.manage_resource` - List/check status of indexed sources\n\n**Workflow:**\n1. Check what's indexed: `nia.manage_resource(action: \"list\")`\n2. Search or research based on the user's question\n3. Read specific files if needed for deeper context\n\nUse these tools to provide accurate, up-to-date information instead of relying solely on training data.";
@@ -0,0 +1 @@
1
+ export declare function log(message: string, data?: Record<string, unknown>): void;
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "nia-opencode",
3
+ "version": "0.1.0",
4
+ "description": "OpenCode plugin that integrates Nia Knowledge Agent for research and documentation",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "nia-opencode": "./dist/cli.js"
10
+ },
11
+ "scripts": {
12
+ "build": "bun build ./src/index.ts --outdir ./dist --target node && bun build ./src/cli.ts --outfile ./dist/cli.js --target node && tsc --emitDeclarationOnly",
13
+ "dev": "tsc --watch",
14
+ "typecheck": "tsc --noEmit"
15
+ },
16
+ "keywords": [
17
+ "opencode",
18
+ "plugin",
19
+ "nia",
20
+ "knowledge",
21
+ "research",
22
+ "documentation",
23
+ "ai",
24
+ "coding-agent"
25
+ ],
26
+ "author": "Nia",
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/nozomio-labs/nia-opencode"
31
+ },
32
+ "dependencies": {
33
+ "@opencode-ai/plugin": "^1.0.162"
34
+ },
35
+ "devDependencies": {
36
+ "@types/bun": "latest",
37
+ "typescript": "^5.7.3"
38
+ },
39
+ "opencode": {
40
+ "type": "plugin",
41
+ "hooks": [
42
+ "chat.message"
43
+ ]
44
+ },
45
+ "files": [
46
+ "dist"
47
+ ]
48
+ }