fenix-claude-plugin 0.1.3 → 0.2.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.
Files changed (52) hide show
  1. package/.claude-plugin/plugin.json +13 -13
  2. package/.mcp.json +11 -11
  3. package/README.md +33 -40
  4. package/artifacts/collections.html +149 -0
  5. package/artifacts/fenix-workspace.html +1285 -0
  6. package/artifacts/oa-editor.html +210 -0
  7. package/artifacts/patent-editor.html +325 -0
  8. package/artifacts/review-workspace.html +1135 -0
  9. package/commands/fenix-install.md +19 -11
  10. package/commands/fenix-setup.md +18 -13
  11. package/package.json +16 -16
  12. package/skills/fenix-application/SKILL.md +35 -12
  13. package/skills/fenix-application/VERSION +1 -1
  14. package/skills/fenix-application/references/claim1-method-drafting.md +1 -1
  15. package/skills/fenix-application/references/claims.md +4 -5
  16. package/skills/fenix-application/references/disclosure.md +116 -10
  17. package/skills/fenix-application/references/editors.md +222 -51
  18. package/skills/fenix-application/references/figure-description.md +1 -1
  19. package/skills/fenix-application/references/figure-strategy.md +166 -0
  20. package/skills/fenix-application/references/figures-guidance.md +1 -1
  21. package/skills/fenix-application/references/figures.md +51 -14
  22. package/skills/fenix-application/references/patent-review-checklist.md +3 -1
  23. package/skills/fenix-application/references/patent-review.md +6 -2
  24. package/skills/fenix-application/references/patent-safe.md +1 -1
  25. package/skills/fenix-application/references/patent.md +9 -9
  26. package/skills/fenix-application/references/spec-guidance.md +1 -1
  27. package/skills/fenix-application/references/spec.md +17 -7
  28. package/skills/fenix-application/scripts/figure_strategy_server.py +136 -0
  29. package/skills/fenix-diagram/SKILL.md +54 -0
  30. package/skills/fenix-diagram/VERSION +1 -0
  31. package/skills/fenix-diagram/references/diagram-svg-guide.md +271 -0
  32. package/skills/fenix-office-action/SKILL.md +6 -4
  33. package/skills/fenix-office-action/VERSION +1 -1
  34. package/skills/fenix-office-action/references/oa-analysis.md +14 -4
  35. package/skills/fenix-office-action/references/oa-drafting.md +98 -21
  36. package/skills/fenix-office-action/references/oa-response.md +13 -13
  37. package/skills/fenix-project/SKILL.md +4 -3
  38. package/skills/fenix-project/VERSION +1 -1
  39. package/skills/fenix-project/references/create-project.md +11 -1
  40. package/artifacts/claims-editor.html +0 -205
  41. package/artifacts/figures-editor.html +0 -237
  42. package/artifacts/oa-arguments-editor.html +0 -216
  43. package/artifacts/practice-dashboard.html +0 -469
  44. package/artifacts/project-overview.html +0 -481
  45. package/artifacts/sections-editor.html +0 -205
  46. package/artifacts/user-dashboard.html +0 -368
  47. package/skills/fenix-application/CUSTOMIZE.md +0 -1
  48. package/skills/fenix-application/assets/claims_editor.html +0 -86
  49. package/skills/fenix-application/assets/figures_editor.html +0 -86
  50. package/skills/fenix-application/assets/spec_editor.html +0 -86
  51. package/skills/fenix-office-action/CUSTOMIZE.md +0 -1
  52. package/skills/fenix-project/CUSTOMIZE.md +0 -1
@@ -1,216 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>OA Arguments Editor</title>
6
- <style>
7
- *{box-sizing:border-box;margin:0;padding:0}
8
- body{font-family:system-ui,-apple-system,sans-serif;background:#fff7ed;min-height:100vh;padding:20px 16px}
9
- .card{background:#fff;max-width:900px;margin:0 auto;border-radius:10px;box-shadow:0 1px 4px rgba(0,0,0,.12);overflow:hidden}
10
- .hdr{display:flex;align-items:center;gap:12px;padding:14px 20px;border-bottom:1px solid #fed7aa}
11
- .hdr h1{font-size:15px;font-weight:600;color:#1e293b}.hdr .rev{font-size:12px;color:#94a3b8}
12
- .hdr .toggle-all{margin-left:auto;flex-shrink:0}
13
- .bdy{padding:20px}.sub{font-size:13px;color:#64748b;margin-bottom:14px}
14
- input,select,textarea{font-family:inherit;font-size:13px;border:1.5px solid #fed7aa;border-radius:5px;padding:6px 10px;outline:none;width:100%;transition:border-color .15s;background:#fff}
15
- input:focus,select:focus,textarea:focus{border-color:#ea580c}
16
- .field{margin-bottom:12px}label{display:block;font-size:12px;font-weight:600;color:#374151;margin-bottom:4px}
17
- .ctx{font-size:12px;color:#64748b;background:#fffbf5;border:1px solid #fed7aa;border-radius:5px;padding:8px 10px;margin-bottom:12px;line-height:1.5;white-space:pre-wrap}
18
- .acc{border:1px solid #fed7aa;overflow:hidden;margin-bottom:-1px}
19
- .acc-hd{display:flex;align-items:center;gap:10px;padding:11px 14px;cursor:pointer;background:#fffbf5;user-select:none}
20
- .acc-hd:hover{background:#fff7ed}
21
- .acc-hd .chev{color:#ea580c;font-size:12px;transition:transform .15s;flex-shrink:0}
22
- .acc.open .chev{transform:rotate(90deg)}
23
- .acc-hd .ttl{font-weight:600;font-size:13px;color:#1e293b;flex-shrink:0}
24
- .acc-hd .prev{font-size:12px;color:#94a3b8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
25
- .acc-bd{display:none;padding:14px;border-top:1px solid #fed7aa;background:#fff}
26
- .acc.open .acc-bd{display:block}
27
- .btn-sm{padding:4px 12px;background:#fff;border:1.5px solid #fed7aa;border-radius:5px;font-size:12px;cursor:pointer;color:#374151}
28
- .btn-sm:hover{border-color:#ea580c}
29
- .bar{margin-top:16px;display:flex;align-items:center;gap:14px}
30
- .cta{padding:9px 24px;background:#ea580c;color:#fff;border:none;border-radius:6px;font-size:14px;font-weight:600;cursor:pointer;transition:background .15s}
31
- .cta:hover{background:#c2410c}.cta:disabled{opacity:.5;cursor:default}
32
- #st{font-size:13px;font-weight:500}#st.ok{color:#16a34a}#st.err{color:#dc2626}#st.busy{color:#64748b}
33
- textarea.arg{min-height:160px;line-height:1.6;resize:vertical}
34
- .diff{display:none;margin-top:16px;border:1px solid #fed7aa;border-radius:6px;overflow:hidden}
35
- .diff.show{display:block}
36
- .diff-hd{display:flex;align-items:center;gap:10px;padding:8px 12px;background:#fff7ed;font-size:12px;font-weight:600;color:#c2410c}
37
- .diff pre{margin:0;padding:12px;font-size:12px;font-family:Menlo,Consolas,monospace;line-height:1.5;white-space:pre-wrap;max-height:240px;overflow:auto;color:#1e293b}
38
- .ftr{padding:9px 20px;border-top:1px solid #fed7aa;font-size:11px;color:#94a3b8;display:flex;justify-content:space-between}
39
- </style>
40
- </head>
41
- <body>
42
- <div class="card">
43
- <div class="hdr"><h1>OA Arguments Editor</h1><span class="rev" id="revLbl"></span><button class="btn-sm toggle-all" id="toggleAll" onclick="toggleAll()" style="display:none">Expand all</button></div>
44
- <div class="bdy">
45
- <p class="sub" id="sub">Loading the Office Action rejections from Fenix…</p>
46
- <div id="acc"></div>
47
- <div class="bar"><button class="cta" id="saveBtn" onclick="save()" disabled>Save to Fenix</button><span id="st"></span></div>
48
- <div class="diff" id="diffPanel">
49
- <div class="diff-hd"><span>Saved. Paste this summary into chat so the assistant stays in sync:</span><button class="btn-sm" style="margin-left:auto" onclick="copyDiff()">Copy summary</button></div>
50
- <pre id="diffText"></pre>
51
- </div>
52
- </div>
53
- <div class="ftr"><span>Fenix Patent Assistant — live editor</span><span>v1</span></div>
54
- </div>
55
- <script>
56
- // The assistant replaces __PROJECT_ID__ with the real Fenix project id before opening this artifact.
57
- var PROJECT_ID = "__PROJECT_ID__";
58
- // The assistant also substitutes this connector's MCP tool prefix here, e.g. "mcp__<connector-id>__".
59
- var SERVER_PREFIX = "__SERVER_PREFIX__";
60
-
61
- // Baseline = the full oa_data object last loaded from / saved to Fenix. We edit only the per-rejection
62
- // argument + response_strategy and write the WHOLE merged oa_data back (read-merge-write), so every
63
- // other key (rejections' other fields, dispositions, original_claims, references) is preserved.
64
- var baseOaData = null;
65
- var baseRejections = [];
66
-
67
- // ---- Cowork MCP plumbing ----
68
- function unwrap(res){
69
- if(res==null) return res;
70
- if(typeof res==="string"){ try{ return JSON.parse(res); }catch(e){ return res; } }
71
- if(Array.isArray(res)) return res;
72
- if(typeof res==="object" && Array.isArray(res.content)){
73
- var t=res.content.map(function(c){ return (c&&c.text)||""; }).join("");
74
- try{ return JSON.parse(t); }catch(e){ return res; }
75
- }
76
- if(res && res.result!==undefined) return unwrap(res.result);
77
- return res;
78
- }
79
- function toolName(n){ return (SERVER_PREFIX && SERVER_PREFIX.indexOf("__SERVER")!==0) ? SERVER_PREFIX + n : n; }
80
- async function call(name,args){
81
- var tries=[toolName(name)]; if(tries[0]!==name) tries.push(name);
82
- var err; for(var i=0;i<tries.length;i++){ try{ return unwrap(await window.cowork.callMcpTool(tries[i],args||{})); }catch(e){ err=e; } }
83
- throw err;
84
- }
85
-
86
- // ---- Accordion editor (one per rejection) ----
87
- function elt(tag,cls,txt){ var e=document.createElement(tag); if(cls)e.className=cls; if(txt!=null)e.textContent=txt; return e; }
88
- function rejLabel(r,i){
89
- var t=(r.status_type||"rejection"); var st=/^\d/.test(t)?("§"+t):t;
90
- var cl=Array.isArray(r.status_claims)&&r.status_claims.length?(" — claims "+r.status_claims.join(", ")):"";
91
- return "Rejection "+(i+1)+": "+st+cl;
92
- }
93
- function ctxText(r){
94
- var parts=[];
95
- if(r.match) parts.push(String(r.match).replace(/\s+/g," ").trim().slice(0,400));
96
- var meta=[];
97
- if(r.page) meta.push("OA p."+r.page);
98
- if(Array.isArray(r.status_refs)&&r.status_refs.length) meta.push(r.status_refs.length+" reference(s)");
99
- if(r.response_strategy) meta.push("strategy: "+r.response_strategy);
100
- if(meta.length) parts.push(meta.join(" · "));
101
- return parts.join("\n\n");
102
- }
103
- function addRejection(r,i){
104
- var acc=document.getElementById("acc");
105
- var wrap=elt("div","acc"); var hd=elt("div","acc-hd");
106
- hd.appendChild(elt("span","chev","▶")); hd.appendChild(elt("span","ttl",rejLabel(r,i)));
107
- var prev=elt("span","prev",(r.argument||"(no argument yet)").replace(/\s+/g," ").slice(0,80)); hd.appendChild(prev);
108
- hd.onclick=function(){ wrap.classList.toggle("open"); syncToggle(); };
109
- var bd=elt("div","acc-bd");
110
- bd.appendChild(elt("div","ctx",ctxText(r)));
111
- var fs=elt("div","field"); fs.appendChild(elt("label",null,"Response strategy"));
112
- var sel=document.createElement("select"); sel.className="r-strat";
113
- ["","amend","argue","both"].forEach(function(v){ var o=document.createElement("option"); o.value=v; o.textContent=v||"(unset)"; if((r.response_strategy||"")===v)o.selected=true; sel.appendChild(o); });
114
- fs.appendChild(sel); bd.appendChild(fs);
115
- var fa=elt("div","field"); fa.appendChild(elt("label",null,"Argument"));
116
- var ta=document.createElement("textarea"); ta.className="r-arg arg"; ta.value=r.argument||"";
117
- ta.oninput=function(){ prev.textContent=(ta.value||"(no argument yet)").replace(/\s+/g," ").slice(0,80); };
118
- fa.appendChild(ta); bd.appendChild(fa);
119
- wrap.appendChild(hd); wrap.appendChild(bd); acc.appendChild(wrap);
120
- }
121
- function syncToggle(){ var btn=document.getElementById("toggleAll"); var accs=document.querySelectorAll("#acc .acc"); if(!accs.length){ btn.style.display="none"; return; } btn.style.display=""; var anyClosed=Array.from(accs).some(function(a){ return !a.classList.contains("open"); }); btn.textContent=anyClosed?"Expand all":"Collapse all"; }
122
- function toggleAll(){ var accs=document.querySelectorAll("#acc .acc"); var anyClosed=Array.from(accs).some(function(a){ return !a.classList.contains("open"); }); accs.forEach(function(a){ if(anyClosed){ a.classList.add("open"); } else { a.classList.remove("open"); } }); syncToggle(); }
123
-
124
- // Read the editor back into an array of { argument, response_strategy } aligned to baseRejections by index.
125
- function collect(){
126
- var out=[]; document.querySelectorAll("#acc .acc").forEach(function(a){
127
- out.push({ argument:a.querySelector(".r-arg").value, response_strategy:a.querySelector(".r-strat").value });
128
- }); return out;
129
- }
130
-
131
- function setStatus(msg,cls){ var s=document.getElementById("st"); s.textContent=msg||""; s.className=cls||""; }
132
-
133
- async function load(){
134
- if(!(window.cowork && typeof window.cowork.callMcpTool==="function")){
135
- document.getElementById("sub").textContent="";
136
- setStatus("⚠ Open this as a LIVE ARTIFACT, not a file preview — it needs the Cowork bridge (window.cowork) to read and save Fenix data. Ask the assistant to open it as a live artifact.","err");
137
- return;
138
- }
139
- try{
140
- var data=await call("get_project",{ projectId:PROJECT_ID, include:["oa_data"] });
141
- baseOaData=(data&&data.oa_data)||{};
142
- baseRejections=Array.isArray(baseOaData.oa_rejections)?baseOaData.oa_rejections:[];
143
- document.getElementById("acc").innerHTML="";
144
- if(!baseRejections.length){
145
- document.getElementById("sub").textContent="No rejections found on this project. Populate it from USPTO first.";
146
- return;
147
- }
148
- baseRejections.forEach(function(r,i){ addRejection(r,i); });
149
- document.getElementById("sub").textContent="Open each rejection to edit its argument and response strategy, then Save to Fenix.";
150
- document.getElementById("saveBtn").disabled=false;
151
- syncToggle();
152
- }catch(e){
153
- document.getElementById("sub").textContent="";
154
- setStatus("Could not load rejections: "+((e&&e.message)||e),"err");
155
- }
156
- }
157
-
158
- function summaryText(edited){
159
- var lines=["[OA ARGUMENTS SAVED]"]; var changed=[], unchanged=0;
160
- edited.forEach(function(e,i){
161
- var b=baseRejections[i]||{};
162
- if((e.argument||"")!==(b.argument||"") || (e.response_strategy||"")!==(b.response_strategy||"")){
163
- changed.push({ i:i, e:e, b:b });
164
- } else { unchanged++; }
165
- });
166
- if(!changed.length){ lines.push("No argument changes (re-saved identical)."); return lines.join("\n"); }
167
- changed.forEach(function(c){
168
- lines.push(""); lines.push(rejLabel(baseRejections[c.i],c.i)+":");
169
- if((c.e.response_strategy||"")!==(c.b.response_strategy||"")) lines.push(" strategy: "+(c.b.response_strategy||"(unset)")+" -> "+(c.e.response_strategy||"(unset)"));
170
- lines.push(" argument (full new text): "+((c.e.argument||"").trim()||"(cleared)"));
171
- });
172
- if(unchanged) { lines.push(""); lines.push("Unchanged rejections: "+unchanged); }
173
- return lines.join("\n");
174
- }
175
-
176
- async function save(){
177
- var btn=document.getElementById("saveBtn"); btn.disabled=true; setStatus("Saving…","busy");
178
- document.getElementById("diffPanel").classList.remove("show");
179
- var edited=collect();
180
- try{
181
- // Read-merge-write: overlay the edited argument/strategy onto a deep copy of the loaded oa_data,
182
- // preserving every other field, then save the whole object.
183
- var merged=JSON.parse(JSON.stringify(baseOaData));
184
- merged.oa_rejections=(merged.oa_rejections||[]).map(function(r,i){
185
- var e=edited[i]||{}; var out=Object.assign({}, r, { argument:e.argument });
186
- if(e.response_strategy) out.response_strategy=e.response_strategy; else delete out.response_strategy;
187
- return out;
188
- });
189
- var res=await call("save_project",{ projectId:PROJECT_ID, fields:{ oa_data:merged } });
190
- if(res && res.isError){ throw new Error(res.error||"save failed"); }
191
- if(res && res.success===false){ throw new Error("save failed"); }
192
- var summary=summaryText(edited);
193
- // Advance the baseline to what we just saved.
194
- baseOaData=merged; baseRejections=merged.oa_rejections;
195
- var nChanged=summary.split("\n").filter(function(l){ return /:$/.test(l); }).length;
196
- setStatus("✓ Saved to Fenix"+(nChanged?" — "+nChanged+" argument(s) changed":""),"ok");
197
- document.getElementById("diffText").textContent=summary;
198
- document.getElementById("diffPanel").classList.add("show");
199
- document.getElementById("diffPanel").__summary=summary;
200
- try{ if(window.cowork && typeof window.cowork.sendPrompt==="function"){ window.cowork.sendPrompt(summary); } }catch(e){}
201
- }catch(e){
202
- setStatus("Save failed: "+((e&&e.message)||e),"err");
203
- }finally{ btn.disabled=false; }
204
- }
205
-
206
- function copyDiff(){
207
- var txt=document.getElementById("diffPanel").__summary||document.getElementById("diffText").textContent;
208
- var done=function(){ setStatus("Summary copied — paste it into chat.","ok"); };
209
- if(navigator.clipboard){ navigator.clipboard.writeText(txt).then(done).catch(fb); } else { fb(); }
210
- function fb(){ var el=document.createElement("textarea"); el.value=txt; el.style.cssText="position:fixed;top:0;left:0;opacity:0;"; document.body.appendChild(el); el.select(); try{ document.execCommand("copy"); done(); }catch(e){} document.body.removeChild(el); }
211
- }
212
-
213
- window.onload=load;
214
- </script>
215
- </body>
216
- </html>