Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
86b413b
feat: migrate prompts to claude plugin and copilot skill formats
sonesuke Feb 21, 2026
a72ba3a
refactor: remove Rust CLI and transition to static plugin repository
sonesuke Feb 21, 2026
49453c3
choar: remove raw rust file
sonesuke Feb 21, 2026
4e0364c
chore: configure mise and prettier formatting without pre-commit pyth…
sonesuke Feb 22, 2026
95d3808
refactor: rename skills and enforce Agent Skills format
sonesuke Feb 22, 2026
48bad44
docs: update walkthrough with agent skills restructuring
sonesuke Feb 22, 2026
f63657a
refactor: package skill dependencies into specific skill folders
sonesuke Feb 22, 2026
e764141
refactor: move report-progress to progress skill
sonesuke Feb 22, 2026
56bd265
feat: turn constitution into skill and add setup skill
sonesuke Feb 22, 2026
c9133c3
fix: add powershell support to setup skill
sonesuke Feb 22, 2026
9313610
feat: add marketplace.json manifest
sonesuke Feb 22, 2026
da20b3e
fix: update marketplace source to root
sonesuke Feb 22, 2026
1b733cf
docs: update flat marketplace configuration in walkthrough
sonesuke Feb 22, 2026
c1061e5
refactor: move plugin into plugins/patent-kit directory
sonesuke Feb 22, 2026
e5f75f8
refactor: rename plugins directory to plugin
sonesuke Feb 22, 2026
147f36f
refactor: flatten plugin directory from plugin/patent-kit to plugin
sonesuke Feb 22, 2026
2589abb
feat(plugin): upgrade SKILL.md frontmatter and examples to official b…
sonesuke Feb 22, 2026
91148ab
feat(plugin): declare google-patent-cli and arxiv-cli as integrated M…
sonesuke Feb 22, 2026
2664183
docs: remove cargo install instructions since users should refer to C…
sonesuke Feb 22, 2026
f713d06
docs: remove references to GitHub Copilot
sonesuke Feb 22, 2026
7bc1279
docs: use github marketplace installation instructions
sonesuke Feb 22, 2026
4f9b6ea
feat(plugin): migrate all skill instructions from CLI commands to MCP…
sonesuke Feb 22, 2026
589de92
docs: add AGENTS.md and CLAUDE.md symlink for AI agent instructions
sonesuke Feb 22, 2026
8caec56
docs(agent): enforce english language for PRs, comments, and markdown…
sonesuke Feb 22, 2026
c396ecd
docs(skills): translate Japanese descriptions, examples, and mcp usag…
sonesuke Feb 22, 2026
9db4c2d
ci: add GitHub Actions for CI (Prettier) and CodeQL
sonesuke Feb 22, 2026
fb5d4ca
ci: remove python from codeql matrix
sonesuke Feb 22, 2026
85bcc1c
ci(format): add package.json and npm ci to fix prettier github action
sonesuke Feb 22, 2026
a62aeb0
ci: trigger github actions
sonesuke Feb 22, 2026
0cf1fdf
ci: run workflows on push to any branch
sonesuke Feb 22, 2026
8ee07de
style: run prettier to fix ci formatting issues
sonesuke Feb 22, 2026
11b24f0
Merge remote-tracking branch 'origin/main' into refactor/plugin-marke…
sonesuke Feb 22, 2026
b0f3572
ci: revert push trigger back to main to avoid duplicate runs
sonesuke Feb 22, 2026
acca8ca
ci: remove package.json and use npx --yes for prettier action
sonesuke Feb 22, 2026
10cc2fc
Merge remote-tracking branch 'origin/main' into refactor/plugin-marke…
sonesuke Feb 22, 2026
2e211a5
refactor: replace python merge script with shell and powershell scripts
sonesuke Feb 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions plugin/skills/targeting/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ A search result is considered **"High Noise"** if **8 or more** of the top 20 sn

1. **Run Merge Command**:
- Execute the following command to combine the CSV files and remove duplicates.
- **Important**: Use `patent-kit` command, NOT `MCP tool`.
- Command: `patent-kit merge --input-dir 1-targeting/csv --output 1-targeting/target.jsonl`
- **Important**: Use `./plugin/skills/targeting/scripts/shell/merge.sh` (Mac/Linux) or `.\plugin\skills\targeting\scripts\powershell\merge.ps1` (Windows), NOT `MCP tool`.
- Command: `./plugin/skills/targeting/scripts/shell/merge.sh 1-targeting/csv 1-targeting/target.jsonl`

2. **Verify Output**:
- Check that `1-targeting/target.jsonl` has been created.
- This file contains the consolidated list of unique patents to be screened/evaluated.

3. **Check Count**:
- The `patent-kit merge` command output displays the number of unique patents (e.g., `Merged 150 unique patents...`).
- The merge command output displays the number of unique patents (e.g., `Merged 150 unique patents...`).
- Confirm this count to understand the volume of patents to be screened.

### Output
Expand Down Expand Up @@ -139,6 +139,6 @@ Actions:

# Troubleshooting

Error: "patent-kit command not found"
Cause: Python script path is incorrect or environment is not fully setup.
Solution: Ensure plugin/skills/targeting/scripts/merge.py is executable and Python 3 is installed.
Error: "Permission denied" when running merge.sh
Cause: The script lacks execution permissions.
Solution: Run `chmod +x plugin/skills/targeting/scripts/shell/merge.sh`.
72 changes: 0 additions & 72 deletions plugin/skills/targeting/scripts/merge.py

This file was deleted.

77 changes: 71 additions & 6 deletions plugin/skills/targeting/scripts/powershell/merge.ps1
Original file line number Diff line number Diff line change
@@ -1,9 +1,74 @@
param (
[string]$InputPath = "1-targeting/csv",
[string]$OutputPath = "1-targeting/target.jsonl"
param(
[string]$InputDir = "1-targeting\csv",
[string]$OutputFile = "1-targeting\target.jsonl"
)

$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$MergePy = Join-Path $ScriptDir "..\merge.py"
if (-not (Test-Path $InputDir)) {
Write-Host "Directory not found: $InputDir. Please create it and place CSV files there."
exit
}

python3 $MergePy $InputPath $OutputPath
$UniquePatents = @{}
$FileCount = 0

Get-ChildItem -Path $InputDir -Filter "*.csv" | ForEach-Object {
$FilePath = $_.FullName
Write-Host "Processing $($_.Name)"
$FileCount++

$Lines = Get-Content -Path $FilePath -Encoding UTF8

$CsvStartIndex = 0
for ($i = 0; $i -lt $Lines.Count; $i++) {
$Line = $Lines[$i].Trim()
if ($Line -ne "" -and -not $Line.StartsWith("search URL:")) {
$CsvStartIndex = $i
break
}
}

if ($CsvStartIndex -lt $Lines.Count) {
$CsvData = $Lines[$CsvStartIndex..($Lines.Count - 1)] | ConvertFrom-Csv

foreach ($Row in $CsvData) {
if (-not [string]::IsNullOrWhiteSpace($Row.id)) {
$UniquePatents[$Row.id] = $Row
}
}
}
}

if ($FileCount -eq 0) {
Write-Host "No CSV files found in $InputDir"
exit
}

$OutputDir = Split-Path $OutputFile -Parent
if ($OutputDir -and -not (Test-Path $OutputDir)) {
New-Item -ItemType Directory -Force -Path $OutputDir | Out-Null
}

$OutFileStream = [System.IO.StreamWriter]::new((Resolve-Path -Path ".").ProviderPath + "\" + $OutputFile, $false, [System.Text.Encoding]::UTF8)

foreach ($Record in $UniquePatents.Values) {
$FilteredRecord = [ordered]@{}
foreach ($Prop in $Record.PSObject.Properties) {
$K = $Prop.Name
$V = $Prop.Value
if (-not [string]::IsNullOrEmpty($K) -and $K -notmatch 'link' -and $K -ne 'inventor/author') {
$FilteredRecord[$K] = $V
}
}

if ($FilteredRecord.Contains('id')) {
$FilteredRecord['id'] = $FilteredRecord['id'] -replace '-', ''
}

$Json = $FilteredRecord | ConvertTo-Json -Depth 5 -Compress
$OutFileStream.WriteLine($Json)
}

$OutFileStream.Close()

$PatentCount = $UniquePatents.Count
Write-Host "Merged $PatentCount unique patents from $FileCount files into $OutputFile"
131 changes: 128 additions & 3 deletions plugin/skills/targeting/scripts/shell/merge.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,130 @@
#!/bin/bash
set -e
INPUT_DIR="${1:-1-targeting/csv}"
OUTPUT_FILE="${2:-1-targeting/target.jsonl}"

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
python3 "$DIR/../merge.py" "$@"
if [ ! -d "$INPUT_DIR" ]; then
echo "Directory not found: $INPUT_DIR. Please create it and place CSV files there."
exit 0
fi

mkdir -p "$(dirname "$OUTPUT_FILE")"

# Use Node.js to safely parse CSV and output JSONL
node -e "
const fs = require('fs');
const path = require('path');

const inputDir = process.argv[1];
const outputFile = process.argv[2];

let uniquePatents = {};
let fileCount = 0;

const files = fs.readdirSync(inputDir).filter(f => f.endsWith('.csv'));

function parseCSV(csvText) {
const lines = [];
let currentLine = [];
let currentCell = '';
let inQuotes = false;

for (let i = 0; i < csvText.length; i++) {
const char = csvText[i];
const nextChar = csvText[i+1];

if (inQuotes) {
if (char === '\\\"' && nextChar === '\\\"') {
currentCell += '\\\"';
i++;
} else if (char === '\\\"') {
inQuotes = false;
} else {
currentCell += char;
}
} else {
if (char === '\\\"') {
inQuotes = true;
} else if (char === ',') {
currentLine.push(currentCell);
currentCell = '';
} else if (char === '\\n' || char === '\\r') {
if (char === '\\r' && nextChar === '\\n') i++;
currentLine.push(currentCell);
lines.push(currentLine);
currentLine = [];
currentCell = '';
} else {
currentCell += char;
}
}
}
if (currentCell !== '' || currentLine.length > 0) {
currentLine.push(currentCell);
lines.push(currentLine);
}
return lines;
}

for (const file of files) {
const filePath = path.join(inputDir, file);
console.log('Processing ' + file);
fileCount++;

const content = fs.readFileSync(filePath, 'utf8');
const textLines = content.split(/\r?\n/);

let csvStartIndex = 0;
for (let i = 0; i < textLines.length; i++) {
const line = textLines[i].trim();
if (line && !line.startsWith('search URL:')) {
csvStartIndex = i;
break;
}
}

const csvContent = textLines.slice(csvStartIndex).join('\n');
const parsed = parseCSV(csvContent);
if (parsed.length < 2) continue;

const headers = parsed[0];

for (let i = 1; i < parsed.length; i++) {
const row = parsed[i];
if (row.length === 0 || (row.length === 1 && !row[0])) continue;

const obj = {};
for (let j = 0; j < headers.length; j++) {
obj[headers[j]] = row[j] || '';
}

if (obj['id']) {
uniquePatents[obj['id']] = obj;
}
}
}

if (fileCount === 0) {
console.log('No CSV files found in ' + inputDir);
process.exit(0);
}

const outData = [];
for (const key in uniquePatents) {
const record = uniquePatents[key];
const filteredRecord = {};

for (const k in record) {
if (k && !k.includes('link') && k !== 'inventor/author') {
filteredRecord[k] = record[k];
}
}

if (filteredRecord['id']) {
filteredRecord['id'] = filteredRecord['id'].replace(/-/g, '');
}
outData.push(JSON.stringify(filteredRecord));
}

fs.writeFileSync(outputFile, outData.join('\\n') + '\\n', 'utf8');
console.log('Merged ' + Object.keys(uniquePatents).length + ' unique patents from ' + fileCount + ' files into ' + outputFile);
" "$INPUT_DIR" "$OUTPUT_FILE"