opencode-froggy 0.9.1 → 0.10.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.
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  <a href="https://www.npmjs.com/package/opencode-froggy"><img src="https://badge.fury.io/js/opencode-froggy.svg" alt="npm version"></a>
8
8
  </p>
9
9
 
10
- OpenCode plugin providing hooks, specialized agents (architect, doc-writer, rubber-duck, partner, code-reviewer, code-simplifier), skills (ask-questions-if-underspecified), and tools (gitingest, pdf-to-markdown, blockchain queries, agent-promote).
10
+ OpenCode plugin providing hooks, specialized agents (architect, doc-writer, rubber-duck, partner, code-reviewer, code-simplifier), skills (ask-questions-if-underspecified, tdd), and tools (gitingest, pdf-to-markdown, blockchain queries, agent-promote).
11
11
 
12
12
  ---
13
13
 
@@ -134,6 +134,7 @@ Skills are contextual instructions loaded on demand via the `skill` tool. The ag
134
134
  | Skill | Description |
135
135
  |-------|-------------|
136
136
  | `ask-questions-if-underspecified` | Clarify requirements before implementing. Use when serious doubts arise. |
137
+ | `tdd` | Apply Test-Driven Development workflow for new features and bugfixes. |
137
138
 
138
139
  #### Example: ask-questions-if-underspecified
139
140
 
@@ -164,6 +165,40 @@ After the user selects "JWT tokens", the agent confirms:
164
165
 
165
166
  Then implementation begins.
166
167
 
168
+ #### Example: tdd
169
+
170
+ **User request:**
171
+ > "Add a function to calculate the total price with tax"
172
+
173
+ **Agent response (after loading the skill):**
174
+
175
+ The agent follows the TDD workflow:
176
+
177
+ 1. **Requirement Synthesis:**
178
+ > "I'll create a function that calculates total price with tax. It should accept a price and tax rate, returning the total."
179
+
180
+ 2. **Test Specification:**
181
+ ```typescript
182
+ describe("calculateTotalWithTax", () => {
183
+ it("should add tax to the base price", () => {
184
+ expect(calculateTotalWithTax(100, 0.2)).toBe(120)
185
+ })
186
+
187
+ it("should handle zero tax rate", () => {
188
+ expect(calculateTotalWithTax(100, 0)).toBe(100)
189
+ })
190
+ })
191
+ ```
192
+
193
+ 3. **Implementation:**
194
+ ```typescript
195
+ function calculateTotalWithTax(price: number, taxRate: number): number {
196
+ return price * (1 + taxRate)
197
+ }
198
+ ```
199
+
200
+ The tests are written first (red), then the minimal implementation to pass them (green).
201
+
167
202
  ### Discovery Locations
168
203
 
169
204
  Skills are discovered from the following locations, in order of increasing priority:
@@ -4,8 +4,7 @@ description: Prepare and execute a release with version bumping, changelog updat
4
4
 
5
5
  ## Context
6
6
 
7
- - Current version: !`node -p "require('./package.json').version"`
8
- - Latest tag: !`git describe --tags --abbrev=0 2>/dev/null || echo "none"`
7
+ - Current version: !`git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0"`
9
8
  - Commits since last tag: !`git log $(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~10")..HEAD --oneline 2>/dev/null || git log --oneline -10`
10
9
 
11
10
  ## CRITICAL CONSTRAINT
@@ -20,8 +19,8 @@ Any destructive or remote action requires confirmation, including:
20
19
 
21
20
  ### Step 1: Determine last released version
22
21
 
23
- 1. Prefer the latest Git tag that matches `v<semver>`.
24
- 2. If no matching tag exists, use the version in `package.json`.
22
+ 1. Use the latest Git tag that matches `v<semver>` or `<semver>`.
23
+ 2. If no tag exists, consider this the first release (`0.0.0`).
25
24
  3. Collect commits since the last version (tag to `HEAD`).
26
25
 
27
26
  ### Step 2: Propose version bump
@@ -35,10 +34,16 @@ Present the recommendation and ask the user to confirm before changing any files
35
34
 
36
35
  ### Step 3: Update release artifacts (after confirmation)
37
36
 
38
- - Update the version in `package.json`.
39
37
  - Update `CHANGELOG` with a new section for the version.
40
38
  - Summarize changes based on the commit range.
41
39
  - Preserve the existing changelog format.
40
+ - Auto-detect and update the version file if present:
41
+ - Node.js: `package.json`
42
+ - Python: `pyproject.toml` or `setup.py`
43
+ - Rust: `Cargo.toml`
44
+ - PHP: `composer.json`
45
+ - Ruby: `*.gemspec`
46
+ - Go: tags only (no version file)
42
47
 
43
48
  ### Step 4: Tag and publish (after confirmation)
44
49
 
package/dist/index.js CHANGED
@@ -198,7 +198,7 @@ const SmartfrogPlugin = async (ctx) => {
198
198
  }
199
199
  }
200
200
  if (Object.keys(loadedAgents).length > 0) {
201
- config.agent = { ...(config.agent ?? {}), ...loadedAgents };
201
+ config.agent = { ...loadedAgents, ...(config.agent ?? {}) };
202
202
  }
203
203
  if (Object.keys(commands).length > 0) {
204
204
  config.command = { ...(config.command ?? {}), ...commands };
@@ -33,7 +33,15 @@ export function createAgentPromoteTool(client, pluginAgentNames) {
33
33
  duration: 3000,
34
34
  },
35
35
  });
36
- await client.instance.dispose();
36
+ setTimeout(() => {
37
+ void client.instance.dispose().catch((error) => {
38
+ log("[agent-promote] Delayed dispose failed", {
39
+ name,
40
+ grade,
41
+ error: String(error),
42
+ });
43
+ });
44
+ }, 0);
37
45
  return `Agent "${name}" changed to type "${grade}". Use Tab or <leader>a to select it.`;
38
46
  },
39
47
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-froggy",
3
- "version": "0.9.1",
3
+ "version": "0.10.1",
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",
@@ -43,7 +43,7 @@
43
43
  "viem": "^2.44.1"
44
44
  },
45
45
  "devDependencies": {
46
- "@opencode-ai/plugin": "latest",
46
+ "@opencode-ai/plugin": "^1.4.6",
47
47
  "@types/bun": "latest",
48
48
  "@types/js-yaml": "^4.0.9",
49
49
  "@vitest/coverage-v8": "^4.0.17",
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: tdd
3
+ description: Apply Test-Driven Development workflow for new features and bugfixes.
4
+ ---
5
+
6
+ # TDD Protocol
7
+
8
+ ## Core Principle
9
+
10
+ - **TDD First**: Test-Driven Development is the default approach.
11
+ - **Goal**: Prioritize behavioral correctness and regression safety over formal compliance.
12
+
13
+ ## Workflow
14
+
15
+ 1. **Requirement Synthesis**: Briefly summarize the requirements before coding.
16
+ 2. **Test Specification**: Write tests describing the expected behavior (unit, integration, or E2E).
17
+ 3. **Implementation**: Update the logic only to the extent required to satisfy those tests.
18
+
19
+ ## Mandatory Rules
20
+
21
+ - **No Test, No Code**: Every new feature or bugfix must include relevant test coverage.
22
+ - **Black-Box Testing**: Validate observable behavior, not internal implementation details.
23
+ - **Merge Requirement**: Tests are mandatory for completion unless an explicit exception is documented.
24
+
25
+ ## Preferred Practice
26
+
27
+ - **Red-Green-Refactor**: Start with a failing test whenever practical.
28
+ - **Right-Sized Testing**:
29
+ - **Unit Tests**: For pure logic and isolated functions.
30
+ - **Integration Tests**: For system interactions and API boundaries.
31
+ - **E2E Tests**: For critical user journeys and "happy paths."
32
+
33
+ ## Explicit Exceptions (Must be justified)
34
+
35
+ - Pure refactoring (where behavior remains identical).
36
+ - Exploratory spikes or R&D.
37
+ - UI/Styling iterations where unit tests offer diminishing returns.
38
+ - Complex integrations where mocking is counterproductive.
39
+ - Emergency hotfixes (requires a follow-up ticket for test debt).
40
+
41
+ ## Quality Bar
42
+
43
+ - **Readability**: Tests must serve as documentation for the feature.
44
+ - **Reliability**: Tests must be deterministic (no flakes) and decoupled from implementation internals.