Skip to content

Commit a8a2089

Browse files
committed
feat: Add CI, publish, and release workflows; update LICENSE and version in package.json
1 parent db16359 commit a8a2089

6 files changed

Lines changed: 205 additions & 22 deletions

File tree

.github/workflows/ci.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, master, trunk]
6+
pull_request:
7+
branches: [main, master, trunk]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
node-version: [18, 20, 22]
15+
steps:
16+
- uses: actions/checkout@v4
17+
18+
- uses: actions/setup-node@v4
19+
with:
20+
node-version: ${{ matrix.node-version }}
21+
22+
- run: npm ci
23+
24+
- run: npm run typecheck
25+
26+
- run: npm run build
27+
28+
- run: ls -la dist/

.github/workflows/publish.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Publish to npm
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: read
13+
id-token: write
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- uses: actions/setup-node@v4
18+
with:
19+
node-version: '20'
20+
registry-url: 'https://registry.npmjs.org'
21+
22+
- run: npm ci
23+
24+
- run: npm run build
25+
26+
- run: npm publish --provenance --access public
27+
env:
28+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.github/workflows/release.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Version bump type'
8+
required: true
9+
type: choice
10+
options:
11+
- patch
12+
- minor
13+
- major
14+
15+
jobs:
16+
release:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: write
20+
id-token: write
21+
steps:
22+
- uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0
25+
token: ${{ secrets.GITHUB_TOKEN }}
26+
27+
- uses: actions/setup-node@v4
28+
with:
29+
node-version: '20'
30+
registry-url: 'https://registry.npmjs.org'
31+
32+
- run: npm ci
33+
34+
- run: npm run build
35+
36+
- name: Configure Git
37+
run: |
38+
git config user.name "github-actions[bot]"
39+
git config user.email "github-actions[bot]@users.noreply.github.com"
40+
41+
- name: Bump version
42+
id: version
43+
run: |
44+
NEW_VERSION=$(npm version ${{ inputs.version }} --no-git-tag-version)
45+
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
46+
echo "version_number=${NEW_VERSION#v}" >> $GITHUB_OUTPUT
47+
48+
- name: Commit and push
49+
run: |
50+
git add package.json
51+
git commit -m "chore: bump version to ${{ steps.version.outputs.new_version }}"
52+
git tag ${{ steps.version.outputs.new_version }}
53+
git push origin main --tags
54+
55+
- name: Publish to npm
56+
run: npm publish --provenance --access public
57+
env:
58+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
59+
60+
- name: Create GitHub Release
61+
uses: actions/create-release@v1
62+
env:
63+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
64+
with:
65+
tag_name: ${{ steps.version.outputs.new_version }}
66+
release_name: Release ${{ steps.version.outputs.new_version }}
67+
draft: false
68+
prerelease: false

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2025 JRedeker
3+
Copyright (c) 2025 tickernelz
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

index.ts

Lines changed: 79 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ const FAST_APPLY_TIMEOUT = parseInt(process.env.FAST_APPLY_TIMEOUT || "30000", 1
2121
const FAST_APPLY_TEMPERATURE = parseFloat(process.env.FAST_APPLY_TEMPERATURE || "0.05")
2222
const FAST_APPLY_MAX_TOKENS = parseInt(process.env.FAST_APPLY_MAX_TOKENS || "8000", 10)
2323

24-
const PLUGIN_VERSION = "2.0.0"
25-
2624
const FAST_APPLY_SYSTEM_PROMPT = "Merge code edits into original files. Preserve structure, indentation, and comments exactly."
2725

2826
const FAST_APPLY_USER_PROMPT = `Task: {instruction}
@@ -177,6 +175,74 @@ function countChanges(diff: string): { added: number; removed: number } {
177175
return { added, removed }
178176
}
179177

178+
function formatTokenCount(tokens: number): string {
179+
if (tokens >= 1000) {
180+
return `${(tokens / 1000).toFixed(1)}K`.replace(".0K", "K")
181+
}
182+
return tokens.toString()
183+
}
184+
185+
function shortenPath(filePath: string, workingDir: string): string {
186+
if (filePath.startsWith(workingDir + "/")) {
187+
return filePath.slice(workingDir.length + 1)
188+
}
189+
if (filePath === workingDir) {
190+
return "."
191+
}
192+
return filePath
193+
}
194+
195+
function truncate(str: string, maxLen: number = 80): string {
196+
if (str.length <= maxLen) return str
197+
return str.slice(0, maxLen - 3) + "..."
198+
}
199+
200+
function estimateTokens(text: string): number {
201+
return Math.ceil(text.length / 4)
202+
}
203+
204+
function formatFastApplyResult(
205+
filePath: string,
206+
workingDir: string,
207+
insertions: number,
208+
deletions: number,
209+
diffPreview: string,
210+
modifiedTokens: number
211+
): string {
212+
const shortPath = shortenPath(filePath, workingDir)
213+
const tokenStr = formatTokenCount(modifiedTokens)
214+
215+
const diffLines = diffPreview.split("\n")
216+
const previewLines = diffLines.slice(0, 10)
217+
const truncatedDiff = previewLines.join("\n")
218+
const hasMore = diffLines.length > 10
219+
220+
const lines = [
221+
"✓ Fast Apply complete",
222+
"",
223+
"Applied changes:",
224+
`→ ${shortPath}`,
225+
` +${insertions} lines, -${deletions} lines (~${tokenStr} tokens modified)`,
226+
"",
227+
"Diff preview (first 10 lines):",
228+
truncatedDiff + (hasMore ? "\n..." : "")
229+
]
230+
231+
return lines.join("\n")
232+
}
233+
234+
function formatErrorOutput(error: string, filePath: string, workingDir: string): string {
235+
const shortPath = shortenPath(filePath, workingDir)
236+
return [
237+
"✗ Fast Apply failed",
238+
"",
239+
`→ ${shortPath}`,
240+
` Error: ${truncate(error, 100)}`,
241+
"",
242+
"Fallback: Use native 'edit' tool with exact string matching"
243+
].join("\n")
244+
}
245+
180246
/**
181247
* Call OpenAI's Fast Apply API to merge code edits
182248
*/
@@ -353,42 +419,35 @@ write({
353419
)
354420

355421
if (!result.success || !result.content) {
356-
// Return error with suggestion to use native edit
357-
return `OpenAI Fast Apply API failed: ${result.error}
358-
359-
Suggestion: Try using the native 'edit' tool instead with exact string replacement.
360-
The edit tool requires matching the exact text in the file.`
422+
return formatErrorOutput(result.error || "Unknown error", target_filepath, directory)
361423
}
362424

363425
const mergedCode = result.content
364426

365-
// Write the merged result
366427
try {
367428
await writeFile(filepath, mergedCode, "utf-8")
368429
} catch (err) {
369430
const error = err as Error
370-
return `Error writing file ${target_filepath}: ${error.message}`
431+
return formatErrorOutput(error.message, target_filepath, directory)
371432
}
372433

373-
// Generate unified diff
374434
const diff = generateUnifiedDiff(
375435
target_filepath,
376436
originalCode,
377437
mergedCode
378438
)
379439

380-
// Calculate change stats
381440
const { added, removed } = countChanges(diff)
382-
const originalLines = originalCode.split("\n").length
383-
const mergedLines = mergedCode.split("\n").length
384-
385-
return `Applied edit to ${target_filepath}
441+
const modifiedTokens = estimateTokens(diff)
386442

387-
+${added} -${removed} lines | ${originalLines} -> ${mergedLines} total
388-
389-
\`\`\`diff
390-
${diff.slice(0, 3000)}${diff.length > 3000 ? "\n... (truncated)" : ""}
391-
\`\`\``
443+
return formatFastApplyResult(
444+
target_filepath,
445+
directory,
446+
added,
447+
removed,
448+
diff,
449+
modifiedTokens
450+
)
392451
},
393452
}),
394453
},

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "opencode-fast-apply",
3-
"version": "2.0.0",
3+
"version": "2.1.0",
44
"description": "OpenCode plugin for Fast Apply - High-performance code editing with OpenAI-compatible APIs (LM Studio, Ollama)",
55
"type": "module",
66
"main": "dist/index.js",

0 commit comments

Comments
 (0)