opencode-froggy 0.11.0 → 1.0.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 +29 -9
- package/command/diff-summary.md +27 -8
- package/command/doc-changes.md +1 -0
- package/command/linear-stale-check.md +199 -0
- package/command/review-changes.md +1 -0
- package/command/review-pr.md +1 -0
- package/command/simplify-changes.md +1 -0
- package/dist/command-installer.d.ts +6 -0
- package/dist/command-installer.js +49 -0
- package/dist/command-installer.test.d.ts +1 -0
- package/dist/command-installer.test.js +58 -0
- package/dist/config-paths.d.ts +2 -0
- package/dist/config-paths.js +6 -0
- package/dist/config-paths.test.js +16 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +326 -259
- package/dist/index.test.js +3 -3
- package/dist/loaders.d.ts +2 -0
- package/dist/loaders.js +1 -0
- package/dist/session-children.d.ts +14 -0
- package/dist/session-children.js +27 -0
- package/dist/session-children.test.d.ts +1 -0
- package/dist/session-children.test.js +25 -0
- package/dist/skill-activation.js +1 -1
- package/dist/tools/agent-promote.d.ts +38 -11
- package/dist/tools/agent-promote.js +35 -33
- package/dist/tools/blockchain/eth-address-balance.d.ts +18 -8
- package/dist/tools/blockchain/eth-address-balance.js +15 -14
- package/dist/tools/blockchain/eth-address-txs.d.ts +22 -10
- package/dist/tools/blockchain/eth-address-txs.js +19 -18
- package/dist/tools/blockchain/eth-token-transfers.d.ts +22 -10
- package/dist/tools/blockchain/eth-token-transfers.js +19 -18
- package/dist/tools/blockchain/eth-transaction.d.ts +30 -14
- package/dist/tools/blockchain/eth-transaction.js +24 -21
- package/dist/tools/gitingest.d.ts +27 -15
- package/dist/tools/gitingest.js +28 -21
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/list-child-sessions.d.ts +11 -7
- package/dist/tools/list-child-sessions.js +22 -17
- package/dist/tools/pdf-to-markdown.d.ts +18 -8
- package/dist/tools/pdf-to-markdown.js +20 -13
- package/dist/tools/prompt-session.d.ts +26 -11
- package/dist/tools/prompt-session.js +23 -28
- package/package.json +13 -5
- package/tui.ts +24 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool to get Ethereum transaction details by hash
|
|
3
3
|
*/
|
|
4
|
-
import { tool } from "@opencode-ai/plugin";
|
|
5
4
|
import { EtherscanClient, EtherscanClientError, validateTxHash, weiToEth } from "./etherscan-client";
|
|
6
5
|
import { getTransactionReceipt, getBlock, getTokenMetadata } from "./viem-client";
|
|
7
6
|
import { CHAIN_ID_DESCRIPTION, DEFAULT_CHAIN_ID, } from "./types";
|
|
@@ -164,40 +163,44 @@ export async function getTransactionDetails(hash, chainId, options = {}) {
|
|
|
164
163
|
}
|
|
165
164
|
return result;
|
|
166
165
|
}
|
|
167
|
-
export const ethTransactionTool =
|
|
166
|
+
export const ethTransactionTool = {
|
|
167
|
+
name: "eth-transaction",
|
|
168
168
|
description: "Get Ethereum transaction details by transaction hash. " +
|
|
169
169
|
"Returns status, block, addresses, gas costs in JSON format. " +
|
|
170
170
|
"Use optional parameters to include internal transactions, token transfers, and decoded event logs.",
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
171
|
+
input: {
|
|
172
|
+
type: "object",
|
|
173
|
+
properties: {
|
|
174
|
+
hash: { type: "string", description: "Transaction hash (0x...)" },
|
|
175
|
+
chainId: { type: "string", description: CHAIN_ID_DESCRIPTION },
|
|
176
|
+
includeInternalTxs: {
|
|
177
|
+
type: "boolean",
|
|
178
|
+
description: "Include internal transactions (ETH transfers between contracts)",
|
|
179
|
+
},
|
|
180
|
+
includeTokenTransfers: { type: "boolean", description: "Include ERC-20 token transfers" },
|
|
181
|
+
decodeLogs: {
|
|
182
|
+
type: "boolean",
|
|
183
|
+
description: "Decode event logs (Transfer, Approval, Deposit, Withdrawal)",
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
required: ["hash"],
|
|
187
|
+
additionalProperties: false,
|
|
186
188
|
},
|
|
187
|
-
async execute(
|
|
189
|
+
async execute(input) {
|
|
190
|
+
const args = input;
|
|
188
191
|
try {
|
|
189
192
|
const result = await getTransactionDetails(args.hash, args.chainId, {
|
|
190
193
|
includeInternalTxs: args.includeInternalTxs,
|
|
191
194
|
includeTokenTransfers: args.includeTokenTransfers,
|
|
192
195
|
decodeLogs: args.decodeLogs,
|
|
193
196
|
});
|
|
194
|
-
return JSON.stringify(result, null, 2);
|
|
197
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
195
198
|
}
|
|
196
199
|
catch (error) {
|
|
197
200
|
if (error instanceof EtherscanClientError) {
|
|
198
|
-
return JSON.stringify({ error: error.message });
|
|
201
|
+
return { content: JSON.stringify({ error: error.message }) };
|
|
199
202
|
}
|
|
200
203
|
throw error;
|
|
201
204
|
}
|
|
202
205
|
},
|
|
203
|
-
}
|
|
206
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type ToolContext } from "@opencode-ai/plugin";
|
|
2
1
|
export interface GitingestArgs {
|
|
3
2
|
url: string;
|
|
4
3
|
maxFileSize?: number;
|
|
@@ -7,20 +6,33 @@ export interface GitingestArgs {
|
|
|
7
6
|
}
|
|
8
7
|
export declare function fetchGitingest(args: GitingestArgs): Promise<string>;
|
|
9
8
|
export declare const gitingestTool: {
|
|
9
|
+
name: string;
|
|
10
10
|
description: string;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
input: {
|
|
12
|
+
type: string;
|
|
13
|
+
properties: {
|
|
14
|
+
url: {
|
|
15
|
+
type: string;
|
|
16
|
+
description: string;
|
|
17
|
+
};
|
|
18
|
+
maxFileSize: {
|
|
19
|
+
type: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
pattern: {
|
|
23
|
+
type: string;
|
|
24
|
+
description: string;
|
|
25
|
+
};
|
|
26
|
+
patternType: {
|
|
27
|
+
type: string;
|
|
28
|
+
enum: string[];
|
|
29
|
+
description: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
required: string[];
|
|
33
|
+
additionalProperties: boolean;
|
|
19
34
|
};
|
|
20
|
-
execute(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
pattern?: string | undefined;
|
|
24
|
-
patternType?: "include" | "exclude" | undefined;
|
|
25
|
-
}, context: ToolContext): Promise<string>;
|
|
35
|
+
execute(input: unknown): Promise<{
|
|
36
|
+
content: string;
|
|
37
|
+
}>;
|
|
26
38
|
};
|
package/dist/tools/gitingest.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tool } from "@opencode-ai/plugin";
|
|
2
1
|
export async function fetchGitingest(args) {
|
|
3
2
|
const response = await fetch("https://gitingest.com/api/ingest", {
|
|
4
3
|
method: "POST",
|
|
@@ -16,26 +15,34 @@ export async function fetchGitingest(args) {
|
|
|
16
15
|
const data = (await response.json());
|
|
17
16
|
return `${data.summary}\n\n${data.tree}\n\n${data.content}`;
|
|
18
17
|
}
|
|
19
|
-
export const gitingestTool =
|
|
18
|
+
export const gitingestTool = {
|
|
19
|
+
name: "gitingest",
|
|
20
20
|
description: "Fetch a GitHub repository's full content via gitingest.com. Returns summary, directory tree, and file contents optimized for LLM analysis. Use when you need to understand an external repository's structure or code.",
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
21
|
+
input: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
url: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "GitHub repository URL (e.g., https://github.com/owner/repo)",
|
|
27
|
+
},
|
|
28
|
+
maxFileSize: {
|
|
29
|
+
type: "number",
|
|
30
|
+
description: "Maximum file size in bytes to include (default: 50000)",
|
|
31
|
+
},
|
|
32
|
+
pattern: {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "Glob pattern to filter files (e.g., '*.py' or 'src/*')",
|
|
35
|
+
},
|
|
36
|
+
patternType: {
|
|
37
|
+
type: "string",
|
|
38
|
+
enum: ["include", "exclude"],
|
|
39
|
+
description: "Whether pattern includes or excludes matching files (default: exclude)",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
required: ["url"],
|
|
43
|
+
additionalProperties: false,
|
|
37
44
|
},
|
|
38
|
-
async execute(
|
|
39
|
-
return fetchGitingest(
|
|
45
|
+
async execute(input) {
|
|
46
|
+
return { content: await fetchGitingest(input) };
|
|
40
47
|
},
|
|
41
|
-
}
|
|
48
|
+
};
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export { convertPdfToMarkdown, type PdfToMarkdownArgs } from "./pdf-to-markdown-
|
|
|
3
3
|
export { pdfToMarkdownTool } from "./pdf-to-markdown";
|
|
4
4
|
export { createPromptSessionTool, type PromptSessionArgs } from "./prompt-session";
|
|
5
5
|
export { createListChildSessionsTool } from "./list-child-sessions";
|
|
6
|
-
export { createAgentPromoteTool, getPromotedAgents, type AgentPromoteArgs } from "./agent-promote";
|
|
6
|
+
export { createAgentPromoteTool, getPromotedAgents, setPromotedAgent, validateGrade, validateAgentName, VALID_GRADES, AGENT_PROMOTE_STORAGE_KEY, type AgentMode, type AgentPromoteArgs, } from "./agent-promote";
|
|
7
7
|
export { ethTransactionTool, ethAddressTxsTool, ethAddressBalanceTool, ethTokenTransfersTool, EtherscanClient, EtherscanClientError, weiToEth, formatTimestamp, shortenAddress, type EthTransactionArgs, type EthAddressTxsArgs, type EthAddressBalanceArgs, type EthTokenTransfersArgs, } from "./blockchain";
|
package/dist/tools/index.js
CHANGED
|
@@ -3,5 +3,5 @@ export { convertPdfToMarkdown } from "./pdf-to-markdown-core";
|
|
|
3
3
|
export { pdfToMarkdownTool } from "./pdf-to-markdown";
|
|
4
4
|
export { createPromptSessionTool } from "./prompt-session";
|
|
5
5
|
export { createListChildSessionsTool } from "./list-child-sessions";
|
|
6
|
-
export { createAgentPromoteTool, getPromotedAgents } from "./agent-promote";
|
|
6
|
+
export { createAgentPromoteTool, getPromotedAgents, setPromotedAgent, validateGrade, validateAgentName, VALID_GRADES, AGENT_PROMOTE_STORAGE_KEY, } from "./agent-promote";
|
|
7
7
|
export { ethTransactionTool, ethAddressTxsTool, ethAddressBalanceTool, ethTokenTransfersTool, EtherscanClient, EtherscanClientError, weiToEth, formatTimestamp, shortenAddress, } from "./blockchain";
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export declare function createListChildSessionsTool(client: Client): {
|
|
1
|
+
import type { ChildSessionTracker } from "../session-children";
|
|
2
|
+
export declare function createListChildSessionsTool(tracker: ChildSessionTracker): {
|
|
3
|
+
name: string;
|
|
5
4
|
description: string;
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
input: {
|
|
6
|
+
type: string;
|
|
7
|
+
properties: {};
|
|
8
|
+
additionalProperties: boolean;
|
|
9
|
+
};
|
|
10
|
+
execute(_input: unknown, context: unknown): Promise<{
|
|
11
|
+
content: string;
|
|
12
|
+
}>;
|
|
8
13
|
};
|
|
9
|
-
export {};
|
|
@@ -1,24 +1,29 @@
|
|
|
1
|
-
import { tool } from "@opencode-ai/plugin";
|
|
2
1
|
import { log } from "../logger";
|
|
3
|
-
export function createListChildSessionsTool(
|
|
4
|
-
return
|
|
2
|
+
export function createListChildSessionsTool(tracker) {
|
|
3
|
+
return {
|
|
4
|
+
name: "list-child-sessions",
|
|
5
5
|
description: "List all child sessions (subagents) of the current session",
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
input: {
|
|
7
|
+
type: "object",
|
|
8
|
+
properties: {},
|
|
9
|
+
additionalProperties: false,
|
|
10
|
+
},
|
|
11
|
+
async execute(_input, context) {
|
|
12
|
+
const ctx = context;
|
|
13
|
+
const childList = tracker.listChildren(ctx.sessionID);
|
|
12
14
|
if (childList.length === 0) {
|
|
13
|
-
return "No child sessions found";
|
|
15
|
+
return { content: "No child sessions found" };
|
|
14
16
|
}
|
|
15
17
|
log("[list-child-sessions] Found child sessions", { count: childList.length });
|
|
16
|
-
const formatted = childList
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const formatted = childList
|
|
19
|
+
.map((child, index) => {
|
|
20
|
+
const created = new Date(child.created).toISOString();
|
|
21
|
+
const updated = new Date(child.updated).toISOString();
|
|
22
|
+
const title = child.title ? ` ${child.title}` : "";
|
|
23
|
+
return `${index + 1}. [${child.id}]${title}\n Created: ${created} | Updated: ${updated}`;
|
|
24
|
+
})
|
|
25
|
+
.join("\n\n");
|
|
26
|
+
return { content: `Child sessions (${childList.length}):\n\n${formatted}` };
|
|
22
27
|
},
|
|
23
|
-
}
|
|
28
|
+
};
|
|
24
29
|
}
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
import { type ToolContext } from "@opencode-ai/plugin";
|
|
2
1
|
export declare const pdfToMarkdownTool: {
|
|
2
|
+
name: string;
|
|
3
3
|
description: string;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
input: {
|
|
5
|
+
type: string;
|
|
6
|
+
properties: {
|
|
7
|
+
filePath: {
|
|
8
|
+
type: string;
|
|
9
|
+
description: string;
|
|
10
|
+
};
|
|
11
|
+
maxPages: {
|
|
12
|
+
type: string;
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
required: string[];
|
|
17
|
+
additionalProperties: boolean;
|
|
7
18
|
};
|
|
8
|
-
execute(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}, context: ToolContext): Promise<string>;
|
|
19
|
+
execute(input: unknown): Promise<{
|
|
20
|
+
content: string;
|
|
21
|
+
}>;
|
|
12
22
|
};
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import { tool } from "@opencode-ai/plugin";
|
|
2
1
|
import { convertPdfToMarkdown } from "./pdf-to-markdown-core";
|
|
3
|
-
export const pdfToMarkdownTool =
|
|
2
|
+
export const pdfToMarkdownTool = {
|
|
3
|
+
name: "pdf-to-markdown",
|
|
4
4
|
description: "Convert a text-based PDF into enriched Markdown (headings, paragraphs, lists). Returns Markdown as plain text.",
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
input: {
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {
|
|
8
|
+
filePath: {
|
|
9
|
+
type: "string",
|
|
10
|
+
description: "Absolute path to the PDF file to convert",
|
|
11
|
+
},
|
|
12
|
+
maxPages: {
|
|
13
|
+
type: "number",
|
|
14
|
+
description: "Limit the number of pages to convert",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
required: ["filePath"],
|
|
18
|
+
additionalProperties: false,
|
|
13
19
|
},
|
|
14
|
-
async execute(
|
|
15
|
-
|
|
20
|
+
async execute(input) {
|
|
21
|
+
const args = input;
|
|
22
|
+
return { content: await convertPdfToMarkdown(args.filePath, { maxPages: args.maxPages }) };
|
|
16
23
|
},
|
|
17
|
-
}
|
|
24
|
+
};
|
|
@@ -1,19 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { createOpencodeClient } from "@opencode-ai/sdk";
|
|
3
|
-
type Client = ReturnType<typeof createOpencodeClient>;
|
|
1
|
+
import type { ChildSessionTracker } from "../session-children";
|
|
4
2
|
export interface PromptSessionArgs {
|
|
5
3
|
message: string;
|
|
6
4
|
sessionId?: string;
|
|
7
5
|
}
|
|
8
|
-
|
|
6
|
+
interface SessionPrompter {
|
|
7
|
+
prompt(input: {
|
|
8
|
+
sessionID: string;
|
|
9
|
+
text: string;
|
|
10
|
+
}): Promise<unknown>;
|
|
11
|
+
}
|
|
12
|
+
export declare function createPromptSessionTool(session: SessionPrompter, tracker: ChildSessionTracker): {
|
|
13
|
+
name: string;
|
|
9
14
|
description: string;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
input: {
|
|
16
|
+
type: string;
|
|
17
|
+
properties: {
|
|
18
|
+
message: {
|
|
19
|
+
type: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
sessionId: {
|
|
23
|
+
type: string;
|
|
24
|
+
description: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
required: string[];
|
|
28
|
+
additionalProperties: boolean;
|
|
13
29
|
};
|
|
14
|
-
execute(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}, context: ToolContext): Promise<string>;
|
|
30
|
+
execute(input: unknown, context: unknown): Promise<{
|
|
31
|
+
content: string;
|
|
32
|
+
}>;
|
|
18
33
|
};
|
|
19
34
|
export {};
|
|
@@ -1,39 +1,34 @@
|
|
|
1
|
-
import { tool } from "@opencode-ai/plugin";
|
|
2
1
|
import { log } from "../logger";
|
|
3
|
-
export function createPromptSessionTool(
|
|
4
|
-
return
|
|
2
|
+
export function createPromptSessionTool(session, tracker) {
|
|
3
|
+
return {
|
|
4
|
+
name: "prompt-session",
|
|
5
5
|
description: "Send a message to a child session (subagent) to continue the conversation",
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
input: {
|
|
7
|
+
type: "object",
|
|
8
|
+
properties: {
|
|
9
|
+
message: { type: "string", description: "The message to send to the child session" },
|
|
10
|
+
sessionId: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "The child session ID to target (optional - uses last child if not provided)",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
required: ["message"],
|
|
16
|
+
additionalProperties: false,
|
|
9
17
|
},
|
|
10
|
-
async execute(
|
|
11
|
-
|
|
18
|
+
async execute(input, context) {
|
|
19
|
+
const args = input;
|
|
20
|
+
const ctx = context;
|
|
21
|
+
const targetSessionId = args.sessionId ?? tracker.lastChild(ctx.sessionID)?.id;
|
|
12
22
|
if (!targetSessionId) {
|
|
13
|
-
|
|
14
|
-
path: { id: context.sessionID },
|
|
15
|
-
});
|
|
16
|
-
const lastChild = (children.data ?? []).at(-1);
|
|
17
|
-
if (!lastChild) {
|
|
18
|
-
return "Error: No child session found for current session";
|
|
19
|
-
}
|
|
20
|
-
targetSessionId = lastChild.id;
|
|
23
|
+
return { content: "Error: No child session found for current session" };
|
|
21
24
|
}
|
|
22
25
|
log("[prompt-session] Sending message to child session", {
|
|
23
|
-
parentSessionID:
|
|
26
|
+
parentSessionID: ctx.sessionID,
|
|
24
27
|
childSessionID: targetSessionId,
|
|
25
28
|
messagePreview: args.message.slice(0, 100),
|
|
26
29
|
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
body: { parts: [{ type: "text", text: args.message }] },
|
|
30
|
-
});
|
|
31
|
-
const parts = response.data?.parts ?? [];
|
|
32
|
-
const textContent = parts
|
|
33
|
-
.filter((p) => p.type === "text" && p.text)
|
|
34
|
-
.map((p) => p.text)
|
|
35
|
-
.join("\n");
|
|
36
|
-
return textContent || "Message sent to child session";
|
|
30
|
+
await session.prompt({ sessionID: targetSessionId, text: args.message });
|
|
31
|
+
return { content: `Message sent to child session ${targetSessionId}` };
|
|
37
32
|
},
|
|
38
|
-
}
|
|
33
|
+
};
|
|
39
34
|
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-froggy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "OpenCode plugin with a hook layer (tool.before.*, session.idle...), agents (code-reviewer, doc-writer), and commands (/review-pr, /commit)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./tui": {
|
|
13
|
+
"import": "./tui.ts",
|
|
14
|
+
"types": "./tui.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
7
17
|
"type": "module",
|
|
8
18
|
"files": [
|
|
9
19
|
"dist",
|
|
10
20
|
"agent",
|
|
11
21
|
"command",
|
|
12
22
|
"skill",
|
|
23
|
+
"tui.ts",
|
|
13
24
|
"images",
|
|
14
25
|
"README.md"
|
|
15
26
|
],
|
|
@@ -38,19 +49,16 @@
|
|
|
38
49
|
"url": "https://github.com/smartfrog/opencode-froggy"
|
|
39
50
|
},
|
|
40
51
|
"dependencies": {
|
|
52
|
+
"@opencode/plugin": "^2.0.2",
|
|
41
53
|
"js-yaml": "^4.1.0",
|
|
42
54
|
"pdfjs-dist": "^4.8.69",
|
|
43
55
|
"viem": "^2.44.1"
|
|
44
56
|
},
|
|
45
57
|
"devDependencies": {
|
|
46
|
-
"@opencode-ai/plugin": "^1.4.6",
|
|
47
58
|
"@types/bun": "latest",
|
|
48
59
|
"@types/js-yaml": "^4.0.9",
|
|
49
60
|
"@vitest/coverage-v8": "^4.0.17",
|
|
50
61
|
"typescript": "^5.7.0",
|
|
51
62
|
"vitest": "^4.0.16"
|
|
52
|
-
},
|
|
53
|
-
"peerDependencies": {
|
|
54
|
-
"@opencode-ai/plugin": "*"
|
|
55
63
|
}
|
|
56
64
|
}
|
package/tui.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Plugin } from "@opencode/plugin/tui"
|
|
2
|
+
|
|
3
|
+
export default Plugin.define({
|
|
4
|
+
id: "opencode-froggy.cli",
|
|
5
|
+
setup(context) {
|
|
6
|
+
const location = context.location ?? context.data.location.default()
|
|
7
|
+
|
|
8
|
+
const refreshAgents = () => {
|
|
9
|
+
context.data.location.agent.invalidate(location)
|
|
10
|
+
void context.data.location.agent.sync(location).catch(() => {})
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const stopAgents = context.data.on("agent.updated", refreshAgents)
|
|
14
|
+
const stopCommands = context.data.on("command.updated", () => {
|
|
15
|
+
context.data.location.command.invalidate(location)
|
|
16
|
+
void context.data.location.command.sync(location).catch(() => {})
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
return () => {
|
|
20
|
+
stopAgents()
|
|
21
|
+
stopCommands()
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
})
|