@yeyuan98/opencode-bioresearcher-plugin 1.5.0-alpha.0 → 1.5.1

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 (133) hide show
  1. package/README.md +48 -36
  2. package/dist/index.js +8 -6
  3. package/dist/skills/bioresearcher-tests/README.md +90 -0
  4. package/dist/skills/bioresearcher-tests/SKILL.md +255 -0
  5. package/dist/skills/bioresearcher-tests/pyproject.toml +6 -0
  6. package/dist/skills/bioresearcher-tests/resources/json_samples/in_markdown.md.gz +0 -0
  7. package/dist/skills/bioresearcher-tests/resources/json_samples/nested_object.json.gz +0 -0
  8. package/dist/skills/bioresearcher-tests/resources/json_samples/schema_draft7.json.gz +0 -0
  9. package/dist/skills/bioresearcher-tests/resources/json_samples/simple_array.json.gz +0 -0
  10. package/dist/skills/bioresearcher-tests/resources/json_samples/simple_object.json.gz +0 -0
  11. package/dist/skills/bioresearcher-tests/resources/obo_sample.obo.gz +0 -0
  12. package/dist/skills/bioresearcher-tests/resources/pubmed_sample.xml.gz +0 -0
  13. package/dist/skills/bioresearcher-tests/resources/table_sample.xlsx.gz +0 -0
  14. package/dist/skills/bioresearcher-tests/test_cases/json_tests.md +137 -0
  15. package/dist/skills/bioresearcher-tests/test_cases/misc_tests.md +141 -0
  16. package/dist/skills/bioresearcher-tests/test_cases/parser_tests.md +80 -0
  17. package/dist/skills/bioresearcher-tests/test_cases/skill_tests.md +59 -0
  18. package/dist/skills/bioresearcher-tests/test_cases/table_tests.md +194 -0
  19. package/dist/skills/bioresearcher-tests/test_runner.py +607 -0
  20. package/dist/skills/env-jsonc-setup/SKILL.md +206 -206
  21. package/dist/skills/long-table-summary/SKILL.md +224 -153
  22. package/dist/skills/long-table-summary/combine_outputs.py +55 -9
  23. package/dist/skills/long-table-summary/generate_prompts.py +9 -0
  24. package/dist/skills/pubmed-weekly/pubmed_weekly.py +130 -29
  25. package/dist/{db-tools → tools/db}/backends/mysql/translator.js +23 -23
  26. package/dist/{db-tools → tools/db}/tools.js +34 -34
  27. package/dist/{misc-tools → tools/misc}/json-validate.js +4 -5
  28. package/dist/tools/parser/obo/index.d.ts +2 -0
  29. package/dist/tools/parser/obo/index.js +2 -0
  30. package/dist/tools/parser/obo/obo.d.ts +17 -0
  31. package/dist/tools/parser/obo/obo.js +216 -0
  32. package/dist/tools/parser/obo/types.d.ts +166 -0
  33. package/dist/tools/parser/obo/utils.d.ts +21 -0
  34. package/dist/tools/parser/obo/utils.js +411 -0
  35. package/dist/tools/parser/pubmed/types.js +1 -0
  36. package/dist/{skill-tools → tools/skill}/registry.js +1 -1
  37. package/package.json +1 -1
  38. package/dist/db-tools/executor.d.ts +0 -13
  39. package/dist/db-tools/executor.js +0 -54
  40. package/dist/db-tools/pool.d.ts +0 -8
  41. package/dist/db-tools/pool.js +0 -49
  42. package/dist/db-tools/tools/index.d.ts +0 -27
  43. package/dist/db-tools/tools/index.js +0 -191
  44. package/dist/db-tools/types.d.ts +0 -94
  45. package/dist/db-tools/types.js +0 -40
  46. package/dist/misc-tools/json-tools.d.ts +0 -33
  47. package/dist/misc-tools/json-tools.js +0 -187
  48. package/dist/skill/frontmatter.d.ts +0 -2
  49. package/dist/skill/frontmatter.js +0 -65
  50. package/dist/skill/index.d.ts +0 -3
  51. package/dist/skill/index.js +0 -2
  52. package/dist/skill/registry.d.ts +0 -11
  53. package/dist/skill/registry.js +0 -64
  54. package/dist/skill/tool.d.ts +0 -9
  55. package/dist/skill/tool.js +0 -115
  56. package/dist/skill/types.d.ts +0 -22
  57. package/dist/skill/types.js +0 -7
  58. /package/dist/{db-tools → tools/db}/backends/index.d.ts +0 -0
  59. /package/dist/{db-tools → tools/db}/backends/index.js +0 -0
  60. /package/dist/{db-tools → tools/db}/backends/mongodb/backend.d.ts +0 -0
  61. /package/dist/{db-tools → tools/db}/backends/mongodb/backend.js +0 -0
  62. /package/dist/{db-tools → tools/db}/backends/mongodb/connection.d.ts +0 -0
  63. /package/dist/{db-tools → tools/db}/backends/mongodb/connection.js +0 -0
  64. /package/dist/{db-tools → tools/db}/backends/mongodb/index.d.ts +0 -0
  65. /package/dist/{db-tools → tools/db}/backends/mongodb/index.js +0 -0
  66. /package/dist/{db-tools → tools/db}/backends/mongodb/translator.d.ts +0 -0
  67. /package/dist/{db-tools → tools/db}/backends/mongodb/translator.js +0 -0
  68. /package/dist/{db-tools → tools/db}/backends/mysql/backend.d.ts +0 -0
  69. /package/dist/{db-tools → tools/db}/backends/mysql/backend.js +0 -0
  70. /package/dist/{db-tools → tools/db}/backends/mysql/connection.d.ts +0 -0
  71. /package/dist/{db-tools → tools/db}/backends/mysql/connection.js +0 -0
  72. /package/dist/{db-tools → tools/db}/backends/mysql/index.d.ts +0 -0
  73. /package/dist/{db-tools → tools/db}/backends/mysql/index.js +0 -0
  74. /package/dist/{db-tools → tools/db}/backends/mysql/translator.d.ts +0 -0
  75. /package/dist/{db-tools → tools/db}/core/base.d.ts +0 -0
  76. /package/dist/{db-tools → tools/db}/core/base.js +0 -0
  77. /package/dist/{db-tools → tools/db}/core/config-loader.d.ts +0 -0
  78. /package/dist/{db-tools → tools/db}/core/config-loader.js +0 -0
  79. /package/dist/{db-tools → tools/db}/core/index.d.ts +0 -0
  80. /package/dist/{db-tools → tools/db}/core/index.js +0 -0
  81. /package/dist/{db-tools → tools/db}/core/jsonc-parser.d.ts +0 -0
  82. /package/dist/{db-tools → tools/db}/core/jsonc-parser.js +0 -0
  83. /package/dist/{db-tools → tools/db}/core/validator.d.ts +0 -0
  84. /package/dist/{db-tools → tools/db}/core/validator.js +0 -0
  85. /package/dist/{db-tools → tools/db}/index.d.ts +0 -0
  86. /package/dist/{db-tools → tools/db}/index.js +0 -0
  87. /package/dist/{db-tools → tools/db}/interface/backend.d.ts +0 -0
  88. /package/dist/{db-tools → tools/db}/interface/backend.js +0 -0
  89. /package/dist/{db-tools → tools/db}/interface/connection.d.ts +0 -0
  90. /package/dist/{db-tools → tools/db}/interface/connection.js +0 -0
  91. /package/dist/{db-tools → tools/db}/interface/index.d.ts +0 -0
  92. /package/dist/{db-tools → tools/db}/interface/index.js +0 -0
  93. /package/dist/{db-tools → tools/db}/interface/query.d.ts +0 -0
  94. /package/dist/{db-tools → tools/db}/interface/query.js +0 -0
  95. /package/dist/{db-tools → tools/db}/interface/schema.d.ts +0 -0
  96. /package/dist/{db-tools → tools/db}/interface/schema.js +0 -0
  97. /package/dist/{db-tools → tools/db}/tools.d.ts +0 -0
  98. /package/dist/{db-tools → tools/db}/utils.d.ts +0 -0
  99. /package/dist/{db-tools → tools/db}/utils.js +0 -0
  100. /package/dist/{misc-tools → tools/misc}/calculator.d.ts +0 -0
  101. /package/dist/{misc-tools → tools/misc}/calculator.js +0 -0
  102. /package/dist/{misc-tools → tools/misc}/index.d.ts +0 -0
  103. /package/dist/{misc-tools → tools/misc}/index.js +0 -0
  104. /package/dist/{misc-tools → tools/misc}/json-extract.d.ts +0 -0
  105. /package/dist/{misc-tools → tools/misc}/json-extract.js +0 -0
  106. /package/dist/{misc-tools → tools/misc}/json-infer.d.ts +0 -0
  107. /package/dist/{misc-tools → tools/misc}/json-infer.js +0 -0
  108. /package/dist/{misc-tools → tools/misc}/json-validate.d.ts +0 -0
  109. /package/dist/{misc-tools → tools/misc}/timer.d.ts +0 -0
  110. /package/dist/{misc-tools → tools/misc}/timer.js +0 -0
  111. /package/dist/{parser-tools/pubmed → tools/parser/obo}/types.js +0 -0
  112. /package/dist/{parser-tools → tools/parser}/pubmed/index.d.ts +0 -0
  113. /package/dist/{parser-tools → tools/parser}/pubmed/index.js +0 -0
  114. /package/dist/{parser-tools → tools/parser}/pubmed/pubmed.d.ts +0 -0
  115. /package/dist/{parser-tools → tools/parser}/pubmed/pubmed.js +0 -0
  116. /package/dist/{parser-tools → tools/parser}/pubmed/types.d.ts +0 -0
  117. /package/dist/{parser-tools → tools/parser}/pubmed/utils.d.ts +0 -0
  118. /package/dist/{parser-tools → tools/parser}/pubmed/utils.js +0 -0
  119. /package/dist/{skill-tools → tools/skill}/frontmatter.d.ts +0 -0
  120. /package/dist/{skill-tools → tools/skill}/frontmatter.js +0 -0
  121. /package/dist/{skill-tools → tools/skill}/index.d.ts +0 -0
  122. /package/dist/{skill-tools → tools/skill}/index.js +0 -0
  123. /package/dist/{skill-tools → tools/skill}/registry.d.ts +0 -0
  124. /package/dist/{skill-tools → tools/skill}/tool.d.ts +0 -0
  125. /package/dist/{skill-tools → tools/skill}/tool.js +0 -0
  126. /package/dist/{skill-tools → tools/skill}/types.d.ts +0 -0
  127. /package/dist/{skill-tools → tools/skill}/types.js +0 -0
  128. /package/dist/{table-tools → tools/table}/index.d.ts +0 -0
  129. /package/dist/{table-tools → tools/table}/index.js +0 -0
  130. /package/dist/{table-tools → tools/table}/tools.d.ts +0 -0
  131. /package/dist/{table-tools → tools/table}/tools.js +0 -0
  132. /package/dist/{table-tools → tools/table}/utils.d.ts +0 -0
  133. /package/dist/{table-tools → tools/table}/utils.js +0 -0
@@ -1,49 +0,0 @@
1
- import * as mysql from 'mysql2/promise';
2
- let pool = null;
3
- let currentConfig = null;
4
- function createPoolConfig(config) {
5
- return {
6
- host: config.host,
7
- port: config.port,
8
- user: config.user,
9
- password: config.password,
10
- database: config.database,
11
- charset: config.charset,
12
- connectTimeout: config.connectionTimeout,
13
- waitForConnections: true,
14
- connectionLimit: 10,
15
- queueLimit: 0,
16
- namedPlaceholders: true,
17
- };
18
- }
19
- export function getPool(config) {
20
- if (pool && currentConfig && isSameConfig(currentConfig, config)) {
21
- return pool;
22
- }
23
- if (pool) {
24
- pool.end().catch(err => console.error('[db-tools] Previous pool cleanup failed:', err.message));
25
- }
26
- pool = mysql.createPool(createPoolConfig(config));
27
- currentConfig = config;
28
- return pool;
29
- }
30
- function isSameConfig(a, b) {
31
- return (a.host === b.host &&
32
- a.port === b.port &&
33
- a.user === b.user &&
34
- a.password === b.password &&
35
- a.database === b.database);
36
- }
37
- export async function closePool() {
38
- if (pool) {
39
- await pool.end().catch(err => console.error('[db-tools] Pool close failed:', err.message));
40
- pool = null;
41
- currentConfig = null;
42
- }
43
- }
44
- export function getPoolStatus() {
45
- return {
46
- initialized: pool !== null,
47
- hasConfig: currentConfig !== null,
48
- };
49
- }
@@ -1,27 +0,0 @@
1
- import { ToolContext } from '@opencode-ai/plugin/tool';
2
- import { z } from 'zod';
3
- export declare const dbQuery: {
4
- description: string;
5
- args: {
6
- sql: z.ZodString;
7
- params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
8
- };
9
- execute(args: {
10
- sql: string;
11
- params?: Record<string, any> | undefined;
12
- }, context: ToolContext): Promise<string>;
13
- };
14
- export declare const dbListTables: {
15
- description: string;
16
- args: {};
17
- execute(args: Record<string, never>, context: ToolContext): Promise<string>;
18
- };
19
- export declare const dbDescribeTable: {
20
- description: string;
21
- args: {
22
- table_name: z.ZodString;
23
- };
24
- execute(args: {
25
- table_name: string;
26
- }, context: ToolContext): Promise<string>;
27
- };
@@ -1,191 +0,0 @@
1
- import { tool } from '@opencode-ai/plugin/tool';
2
- import { z } from 'zod';
3
- import { initializeBackend, getDefaultBackend } from '../backends';
4
- import { validateReadOnlyQuery, validateCollectionName } from '../core/validator';
5
- import { getConfigFromEnv } from '../core/base';
6
- async function ensureBackend() {
7
- let backend = getDefaultBackend();
8
- if (!backend) {
9
- const config = getConfigFromEnv();
10
- backend = await initializeBackend(config);
11
- }
12
- return backend;
13
- }
14
- export const dbQuery = tool({
15
- description: `Execute a SELECT query on the database with named parameters.
16
-
17
- **Examples:**
18
- - Simple query: \`SELECT * FROM users LIMIT 10\`
19
- - With named params: \`SELECT * FROM users WHERE status = :status AND created_at > :date\`
20
- - Join query: \`SELECT u.name, o.total FROM users u JOIN orders o ON u.id = o.user_id\`
21
- - MongoDB query: \`SELECT * FROM users WHERE status = 'active' LIMIT 10\`
22
-
23
- **Parameters:**
24
- - Use named placeholders like \`:paramName\` for parameters
25
- - Pass parameter values in the \`params\` object: \`{ "status": "active", "date": "2024-01-01" }\`
26
-
27
- **Note:** Only SELECT statements are allowed (read-only access).
28
-
29
- **Backend Support:**
30
- - MySQL: Native SQL execution
31
- - MongoDB: SQL is translated to MongoDB queries automatically`,
32
- args: {
33
- sql: z.string().describe('SELECT SQL query to execute. Use named placeholders like :name for parameters.'),
34
- params: z.record(z.string(), z.any()).optional().describe('Named parameters as key-value pairs (e.g., { "status": "active", "limit": 10 })'),
35
- },
36
- execute: async (args, _context) => {
37
- try {
38
- const backend = await ensureBackend();
39
- const validation = validateReadOnlyQuery(args.sql, backend.type);
40
- if (!validation.valid && validation.error) {
41
- return JSON.stringify(validation.error, null, 2);
42
- }
43
- const result = await backend.executeQuery({
44
- sql: args.sql,
45
- params: args.params,
46
- });
47
- return JSON.stringify(result, null, 2);
48
- }
49
- catch (error) {
50
- const errorMessage = error instanceof Error ? error.message : String(error);
51
- return JSON.stringify({
52
- success: false,
53
- error: {
54
- code: 'BACKEND_ERROR',
55
- message: errorMessage,
56
- },
57
- metadata: { executionTimeMs: 0, backend: 'unknown' },
58
- }, null, 2);
59
- }
60
- },
61
- });
62
- export const dbListTables = tool({
63
- description: `List all tables/collections in the current database with metadata.
64
-
65
- **Returns:**
66
- - Table/collection names and types (TABLE, VIEW, COLLECTION, etc.)
67
- - For MySQL: Storage engine (InnoDB, MyISAM, etc.), row count, creation time
68
- - For MongoDB: Collection type information
69
-
70
- **Usage:** Call this first to discover what tables/collections are available before using dbDescribeTable or dbQuery.`,
71
- args: {},
72
- execute: async (_args, _context) => {
73
- const startTime = Date.now();
74
- try {
75
- const backend = await ensureBackend();
76
- const collections = await backend.listCollections();
77
- const result = {
78
- success: true,
79
- data: {
80
- tables: collections,
81
- count: collections.length,
82
- },
83
- metadata: {
84
- executionTimeMs: Date.now() - startTime,
85
- backend: backend.type,
86
- },
87
- };
88
- return JSON.stringify(result, null, 2);
89
- }
90
- catch (error) {
91
- const backend = getDefaultBackend();
92
- const errorMessage = error instanceof Error ? error.message : String(error);
93
- return JSON.stringify({
94
- success: false,
95
- error: {
96
- code: 'LIST_TABLES_ERROR',
97
- message: errorMessage,
98
- hints: [
99
- 'Check that the database server is running',
100
- 'Verify your database credentials',
101
- ],
102
- },
103
- metadata: {
104
- executionTimeMs: Date.now() - startTime,
105
- backend: backend?.type || 'unknown',
106
- },
107
- }, null, 2);
108
- }
109
- },
110
- });
111
- export const dbDescribeTable = tool({
112
- description: `Get the column/field schema for a specific table/collection.
113
-
114
- **Returns for each column/field:**
115
- - Field name
116
- - Data type (VARCHAR, INT, TEXT, DATETIME, etc. for MySQL; BSON types for MongoDB)
117
- - Nullable status
118
- - Key type (PRI for primary key, etc.)
119
- - Default value
120
- - Extra info (auto_increment, etc.)
121
- - Comments/description
122
-
123
- **Workflow:**
124
- 1. Use \`dbListTables\` first to see available tables/collections
125
- 2. Use this tool to understand the column/field structure
126
- 3. Use \`dbQuery\` to query the data`,
127
- args: {
128
- table_name: z.string().describe('Name of the table/collection to describe. Use dbListTables to see available names.'),
129
- },
130
- execute: async (args, _context) => {
131
- const startTime = Date.now();
132
- try {
133
- const backend = await ensureBackend();
134
- const validation = validateCollectionName(args.table_name, backend.type);
135
- if (!validation.valid && validation.error) {
136
- return JSON.stringify(validation.error, null, 2);
137
- }
138
- const columns = await backend.describeCollection(args.table_name);
139
- if (!columns || columns.length === 0) {
140
- return JSON.stringify({
141
- success: false,
142
- error: {
143
- code: 'TABLE_NOT_FOUND',
144
- message: `Table/collection '${args.table_name}' not found in database`,
145
- hints: [
146
- 'Use dbListTables to see available tables/collections',
147
- 'Check the name for typos',
148
- 'Make sure you are connected to the correct database',
149
- ],
150
- },
151
- metadata: {
152
- executionTimeMs: Date.now() - startTime,
153
- backend: backend.type,
154
- },
155
- }, null, 2);
156
- }
157
- const result = {
158
- success: true,
159
- data: {
160
- table: args.table_name,
161
- columns,
162
- columnCount: columns.length,
163
- },
164
- metadata: {
165
- executionTimeMs: Date.now() - startTime,
166
- backend: backend.type,
167
- },
168
- };
169
- return JSON.stringify(result, null, 2);
170
- }
171
- catch (error) {
172
- const backend = getDefaultBackend();
173
- const errorMessage = error instanceof Error ? error.message : String(error);
174
- return JSON.stringify({
175
- success: false,
176
- error: {
177
- code: 'DESCRIBE_TABLE_ERROR',
178
- message: errorMessage,
179
- hints: [
180
- 'Use dbListTables to see available tables/collections',
181
- 'Check the table name for typos',
182
- ],
183
- },
184
- metadata: {
185
- executionTimeMs: Date.now() - startTime,
186
- backend: backend?.type || 'unknown',
187
- },
188
- }, null, 2);
189
- }
190
- },
191
- });
@@ -1,94 +0,0 @@
1
- import type { RowDataPacket } from 'mysql2/promise';
2
- export interface DbConfig {
3
- host: string;
4
- port: number;
5
- user: string;
6
- password: string;
7
- database: string;
8
- charset?: string;
9
- connectionTimeout?: number;
10
- }
11
- export interface QueryOptions {
12
- sql: string;
13
- params?: Record<string, unknown> | unknown[];
14
- }
15
- export interface FieldInfo {
16
- name: string;
17
- type: string;
18
- nullable: boolean;
19
- key: string | null;
20
- default: unknown;
21
- extra: string | null;
22
- }
23
- export interface StructuredError {
24
- code: string;
25
- message: string;
26
- details?: string;
27
- hints?: string[];
28
- }
29
- export interface ToolResponse<T> {
30
- success: boolean;
31
- data?: T;
32
- error?: StructuredError;
33
- metadata?: {
34
- executionTimeMs: number;
35
- [key: string]: unknown;
36
- };
37
- }
38
- export interface QueryResultData {
39
- rows: RowDataPacket[];
40
- rowCount: number;
41
- fields: FieldInfo[];
42
- }
43
- export interface QueryResult extends ToolResponse<QueryResultData> {
44
- success: true;
45
- data: QueryResultData;
46
- }
47
- export interface QueryError extends ToolResponse<never> {
48
- success: false;
49
- error: StructuredError;
50
- }
51
- export type QueryResponse = QueryResult | QueryError;
52
- export interface TableInfo {
53
- tableName: string;
54
- tableType: string;
55
- engine: string | null;
56
- rowCount: number | null;
57
- createdAt: string | null;
58
- comment: string | null;
59
- }
60
- export interface TablesResultData {
61
- tables: TableInfo[];
62
- count: number;
63
- }
64
- export interface ColumnSchema {
65
- field: string;
66
- type: string;
67
- nullable: boolean;
68
- key: string | null;
69
- defaultValue: unknown;
70
- extra: string | null;
71
- comment: string | null;
72
- }
73
- export interface SchemaResultData {
74
- table: string;
75
- columns: ColumnSchema[];
76
- columnCount: number;
77
- }
78
- export type MySQLError = Error & {
79
- code?: string;
80
- errno?: number;
81
- sql?: string;
82
- sqlState?: string;
83
- };
84
- export declare const DEFAULT_CONFIG: Partial<DbConfig>;
85
- export declare const ERROR_HINTS: {
86
- readonly CONNECTION: readonly ["Check that the database server is running", "Verify DB_HOST and DB_PORT environment variables", "Ensure network connectivity to the database"];
87
- readonly AUTH: readonly ["Verify DB_USER and DB_PASSWORD environment variables", "Check that the user has permissions for the database"];
88
- readonly UNKNOWN_TABLE: readonly ["Use dbListTables to see available tables", "Check the table name for typos"];
89
- readonly UNKNOWN_COLUMN: readonly ["Use dbDescribeTable to see available columns", "Check the column name for typos"];
90
- readonly SYNTAX: readonly ["Check your SQL syntax", "Ensure all identifiers are properly quoted if needed"];
91
- readonly GENERIC: readonly ["Check your query syntax", "Use dbListTables to see available tables", "Use dbDescribeTable to check column names"];
92
- };
93
- export declare function isQueryResult(response: QueryResponse): response is QueryResult;
94
- export declare function isQueryError(response: QueryResponse): response is QueryError;
@@ -1,40 +0,0 @@
1
- export const DEFAULT_CONFIG = {
2
- host: 'localhost',
3
- port: 3306,
4
- charset: 'utf8mb4',
5
- connectionTimeout: 10000,
6
- };
7
- export const ERROR_HINTS = {
8
- CONNECTION: [
9
- 'Check that the database server is running',
10
- 'Verify DB_HOST and DB_PORT environment variables',
11
- 'Ensure network connectivity to the database',
12
- ],
13
- AUTH: [
14
- 'Verify DB_USER and DB_PASSWORD environment variables',
15
- 'Check that the user has permissions for the database',
16
- ],
17
- UNKNOWN_TABLE: [
18
- 'Use dbListTables to see available tables',
19
- 'Check the table name for typos',
20
- ],
21
- UNKNOWN_COLUMN: [
22
- 'Use dbDescribeTable to see available columns',
23
- 'Check the column name for typos',
24
- ],
25
- SYNTAX: [
26
- 'Check your SQL syntax',
27
- 'Ensure all identifiers are properly quoted if needed',
28
- ],
29
- GENERIC: [
30
- 'Check your query syntax',
31
- 'Use dbListTables to see available tables',
32
- 'Use dbDescribeTable to check column names',
33
- ],
34
- };
35
- export function isQueryResult(response) {
36
- return response.success === true;
37
- }
38
- export function isQueryError(response) {
39
- return response.success === false;
40
- }
@@ -1,33 +0,0 @@
1
- import { ToolContext } from '@opencode-ai/plugin/tool';
2
- export declare const jsonValidate: {
3
- description: string;
4
- args: {
5
- data: any;
6
- schema: any;
7
- version: any;
8
- };
9
- execute(args: {
10
- [x: string]: any;
11
- }, context: ToolContext): Promise<string>;
12
- };
13
- export declare const jsonExtract: {
14
- description: string;
15
- args: {
16
- content: any;
17
- path: any;
18
- };
19
- execute(args: {
20
- [x: string]: any;
21
- }, context: ToolContext): Promise<string>;
22
- };
23
- export declare const jsonInferSchema: {
24
- description: string;
25
- args: {
26
- data: any;
27
- title: any;
28
- strict: any;
29
- };
30
- execute(args: {
31
- [x: string]: any;
32
- }, context: ToolContext): Promise<string>;
33
- };
@@ -1,187 +0,0 @@
1
- import { tool } from '@opencode-ai/plugin/tool';
2
- const zod = require('zod');
3
- function getFromJSONSchema() {
4
- if (zod.fromJSONSchema) {
5
- return zod.fromJSONSchema;
6
- }
7
- const v4classic = require('zod/v4/classic/external.js');
8
- if (v4classic.fromJSONSchema) {
9
- return v4classic.fromJSONSchema;
10
- }
11
- throw new Error('fromJSONSchema not available in zod package');
12
- }
13
- const fromJSONSchema = getFromJSONSchema();
14
- export const jsonValidate = tool({
15
- description: `Validate JSON data against a JSON Schema.
16
- Returns validation result with detailed error paths and messages.
17
- Supports JSON Schema draft-04, draft-07, draft-2020-12, and OpenAPI 3.0.`,
18
- args: {
19
- data: z.any().describe("JSON data to validate (object, array, or primitive)"),
20
- schema: z.any().describe("JSON Schema object to validate against"),
21
- version: z.enum(["draft-04", "draft-07", "draft-2020-12", "openapi-3.0"])
22
- .optional()
23
- .default("draft-2020-12")
24
- .describe("JSON Schema version (default: draft-2020-12)")
25
- },
26
- execute: async (args) => {
27
- try {
28
- const zodSchema = z.fromJSONSchema(args.schema, {
29
- defaultTarget: args.version
30
- });
31
- const result = zodSchema.safeParse(args.data);
32
- if (result.success) {
33
- return JSON.stringify({
34
- valid: true,
35
- data: result.data
36
- }, null, 2);
37
- }
38
- else {
39
- const errors = result.error.issues.map((issue) => ({
40
- path: issue.path.join('.') || '(root)',
41
- message: issue.message,
42
- code: issue.code
43
- }));
44
- return JSON.stringify({
45
- valid: false,
46
- errors,
47
- errorCount: errors.length
48
- }, null, 2);
49
- }
50
- }
51
- catch (e) {
52
- return JSON.stringify({
53
- valid: false,
54
- schemaError: e instanceof Error ? e.message : 'Unknown schema error'
55
- }, null, 2);
56
- }
57
- }
58
- });
59
- export const jsonExtract = tool({
60
- description: `Extract JSON from markdown or text content.
61
- Handles code blocks (\`\`\`json) and raw {...} or [...] patterns.
62
- Returns extracted JSON or error with details.`,
63
- args: {
64
- content: z.string().describe("Markdown or text content containing JSON"),
65
- path: z.string().optional()
66
- .describe("JSONPath to extract nested value (e.g., 'data.items.0')")
67
- },
68
- execute: async (args) => {
69
- let jsonStr = null;
70
- const codeBlockMatch = args.content.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
71
- if (codeBlockMatch) {
72
- jsonStr = codeBlockMatch[1].trim();
73
- }
74
- if (!jsonStr) {
75
- const objStart = args.content.indexOf('{');
76
- const arrStart = args.content.indexOf('[');
77
- if (objStart !== -1 || arrStart !== -1) {
78
- const startChar = objStart !== -1 && (arrStart === -1 || objStart < arrStart) ? '{' : '[';
79
- const endChar = startChar === '{' ? '}' : ']';
80
- const startIndex = args.content.indexOf(startChar);
81
- let depth = 0;
82
- let endIndex = -1;
83
- for (let i = startIndex; i < args.content.length; i++) {
84
- if (args.content[i] === startChar)
85
- depth++;
86
- if (args.content[i] === endChar)
87
- depth--;
88
- if (depth === 0) {
89
- endIndex = i + 1;
90
- break;
91
- }
92
- }
93
- if (endIndex !== -1) {
94
- jsonStr = args.content.slice(startIndex, endIndex);
95
- }
96
- }
97
- }
98
- if (!jsonStr) {
99
- return JSON.stringify({
100
- success: false,
101
- error: "No JSON found in content"
102
- }, null, 2);
103
- }
104
- try {
105
- let data = JSON.parse(jsonStr);
106
- if (args.path) {
107
- const parts = args.path.split('.');
108
- for (const part of parts) {
109
- if (data === null || data === undefined) {
110
- return JSON.stringify({
111
- success: false,
112
- error: `Path '${args.path}' not found (null/undefined at '${part}')`
113
- }, null, 2);
114
- }
115
- data = data[part];
116
- }
117
- }
118
- return JSON.stringify({
119
- success: true,
120
- data
121
- }, null, 2);
122
- }
123
- catch (e) {
124
- return JSON.stringify({
125
- success: false,
126
- error: `Invalid JSON: ${e instanceof Error ? e.message : 'Unknown error'}`,
127
- extractedText: jsonStr.length > 200 ? jsonStr.slice(0, 200) + '...' : jsonStr
128
- }, null, 2);
129
- }
130
- }
131
- });
132
- export const jsonInferSchema = tool({
133
- description: `Infer a JSON Schema from example JSON data.
134
- Useful for creating schemas from sample data.`,
135
- args: {
136
- data: z.any().describe("Example JSON data to infer schema from"),
137
- title: z.string().optional().describe("Optional schema title"),
138
- strict: z.boolean().optional().default(false)
139
- .describe("If true, set additionalProperties: false for objects")
140
- },
141
- execute: async (args) => {
142
- function inferType(value, strict) {
143
- if (value === null)
144
- return { type: "null" };
145
- if (typeof value === "string")
146
- return { type: "string" };
147
- if (typeof value === "boolean")
148
- return { type: "boolean" };
149
- if (typeof value === "number") {
150
- return Number.isInteger(value) ? { type: "integer" } : { type: "number" };
151
- }
152
- if (Array.isArray(value)) {
153
- if (value.length === 0) {
154
- return { type: "array", items: {} };
155
- }
156
- return { type: "array", items: inferType(value[0], strict) };
157
- }
158
- if (typeof value === "object" && value !== null) {
159
- const obj = value;
160
- const properties = {};
161
- const required = [];
162
- for (const [key, val] of Object.entries(obj)) {
163
- properties[key] = inferType(val, strict);
164
- required.push(key);
165
- }
166
- const schema = {
167
- type: "object",
168
- properties,
169
- required
170
- };
171
- if (strict) {
172
- schema.additionalProperties = false;
173
- }
174
- return schema;
175
- }
176
- return {};
177
- }
178
- const schema = {
179
- $schema: "https://json-schema.org/draft/2020-12/schema",
180
- ...inferType(args.data, args.strict ?? false)
181
- };
182
- if (args.title) {
183
- schema.title = args.title;
184
- }
185
- return JSON.stringify(schema, null, 2);
186
- }
187
- });
@@ -1,2 +0,0 @@
1
- import { ParsedSkill } from "./types";
2
- export declare function parseSkillFrontmatter(filePath: string): Promise<ParsedSkill | null>;
@@ -1,65 +0,0 @@
1
- import { ExtendedSkillFrontmatter } from "./types";
2
- const FRONTMATTER_REGEX = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
3
- export async function parseSkillFrontmatter(filePath) {
4
- const file = Bun.file(filePath);
5
- const content = await file.text().catch(() => null);
6
- if (!content)
7
- return null;
8
- const match = content.match(FRONTMATTER_REGEX);
9
- if (!match)
10
- return null;
11
- const [, frontmatterYaml, body] = match;
12
- let data;
13
- try {
14
- data = parseSimpleYaml(frontmatterYaml);
15
- }
16
- catch {
17
- return null;
18
- }
19
- const parsed = ExtendedSkillFrontmatter.safeParse(data);
20
- if (!parsed.success)
21
- return null;
22
- return {
23
- frontmatter: parsed.data,
24
- content: body.trim(),
25
- location: filePath,
26
- };
27
- }
28
- function parseSimpleYaml(yaml) {
29
- const result = {};
30
- let currentKey = "";
31
- let currentArray = null;
32
- for (const line of yaml.split("\n")) {
33
- const trimmed = line.trimEnd();
34
- if (!trimmed)
35
- continue;
36
- if (trimmed.startsWith(" - ")) {
37
- if (currentArray !== null) {
38
- currentArray.push(trimmed.slice(4));
39
- }
40
- continue;
41
- }
42
- if (currentArray !== null && currentKey) {
43
- result[currentKey] = currentArray;
44
- currentArray = null;
45
- }
46
- const colonIndex = trimmed.indexOf(":");
47
- if (colonIndex === -1)
48
- continue;
49
- const key = trimmed.slice(0, colonIndex).trim();
50
- const value = trimmed.slice(colonIndex + 1).trim();
51
- if (value === "") {
52
- currentKey = key;
53
- currentArray = [];
54
- }
55
- else {
56
- result[key] = value;
57
- currentKey = "";
58
- currentArray = null;
59
- }
60
- }
61
- if (currentArray !== null && currentKey) {
62
- result[currentKey] = currentArray;
63
- }
64
- return result;
65
- }