@cychien/ezdesign 0.9.1 → 0.9.2

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 (24) hide show
  1. package/dist/cli.mjs +59 -27
  2. package/dist/constants.d.ts +2 -0
  3. package/dist/extension/g/0.9.2-d9aee83dae/dialog.js +1 -0
  4. package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/media.js +1 -1
  5. package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/page.js +3 -3
  6. package/dist/extension/manifest.json +12 -12
  7. package/dist/native-host.mjs +36 -17
  8. package/dist/shell.css +3 -0
  9. package/dist/shell.js +16 -3
  10. package/dist/vite.mjs +1 -0
  11. package/package.json +1 -1
  12. package/skills/ezdesign/SKILL.md +1 -1
  13. package/dist/extension/g/0.9.1-16d05e759b/dialog.js +0 -1
  14. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/dialog.css +0 -0
  15. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/dialog.html +0 -0
  16. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/icon-128.png +0 -0
  17. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/icon-16.png +0 -0
  18. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/icon-32.png +0 -0
  19. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/icon-48.png +0 -0
  20. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/media.html +0 -0
  21. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/setup.css +0 -0
  22. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/setup.html +0 -0
  23. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/setup.js +0 -0
  24. /package/dist/extension/g/{0.9.1-16d05e759b → 0.9.2-d9aee83dae}/worker.js +0 -0
package/dist/cli.mjs CHANGED
@@ -18,6 +18,7 @@ var SESSIONS_DIR = join(DATA_DIR, "sessions");
18
18
  var LEGACY_SESSIONS_DIR = join(DATA_DIR, "sessions-legacy");
19
19
  var REGISTRY_FILE = join(DATA_DIR, "daemon.json");
20
20
  var DAEMON_LOG = join(DATA_DIR, "daemon.log");
21
+ var ACP_NPM_PREFIX = join(DATA_DIR, "acp");
21
22
  var VERSIONS_DIR = join(DATA_DIR, "versions");
22
23
  var UPDATE_CHECK_FILE = join(DATA_DIR, "update-check.json");
23
24
  var libraryDir = (dataDir = DATA_DIR) => join(dataDir, "library");
@@ -147,20 +148,30 @@ var IDLE_CHECK_MS = 6e4;
147
148
  var SHELL_RETRY_MS = 1e3;
148
149
  var SHELL_RETURN_MS = 2e3;
149
150
 
151
+ // src/shell-quote.ts
152
+ function shellQuote(arg) {
153
+ if (process.platform === "win32") return /[\s"]/.test(arg) ? `"${arg.replace(/"/g, '""')}"` : arg;
154
+ return /^[A-Za-z0-9_@%+=:,./-]+$/.test(arg) ? arg : `'${arg.replace(/'/g, `'\\''`)}'`;
155
+ }
156
+
150
157
  // src/agents.ts
158
+ var CLAUDE_ADAPTER = "@agentclientprotocol/claude-agent-acp";
159
+ var CODEX_ADAPTER = "@agentclientprotocol/codex-acp";
151
160
  var AGENT_PROFILES = [
152
161
  {
153
162
  id: "claude",
154
163
  name: "Claude Code",
155
- command: "npx -y @agentclientprotocol/claude-agent-acp",
164
+ command: `npx -y ${CLAUDE_ADAPTER}`,
156
165
  binary: "claude",
166
+ adapter: CLAUDE_ADAPTER,
157
167
  brand: "claude"
158
168
  },
159
169
  {
160
170
  id: "codex",
161
171
  name: "Codex",
162
- command: "npx -y @agentclientprotocol/codex-acp",
172
+ command: `npx -y ${CODEX_ADAPTER}`,
163
173
  binary: "codex",
174
+ adapter: CODEX_ADAPTER,
164
175
  brand: "openai"
165
176
  },
166
177
  { id: "gemini", name: "Gemini CLI", command: "gemini --experimental-acp", binary: "gemini" }
@@ -171,6 +182,10 @@ function agentCommand(agent) {
171
182
  function agentProfileFor(command) {
172
183
  return AGENT_PROFILES.find((p) => p.command === command);
173
184
  }
185
+ function launchCommand(command, npmPrefix) {
186
+ const adapter = agentProfileFor(command)?.adapter;
187
+ return adapter ? `npx -y --prefix ${shellQuote(npmPrefix)} ${adapter}` : command;
188
+ }
174
189
  function agentBrandFor(command) {
175
190
  return agentProfileFor(command)?.brand;
176
191
  }
@@ -770,7 +785,7 @@ function forget(key, file) {
770
785
  // src/daemon.ts
771
786
  import { createHash as createHash8, randomBytes as randomBytes8, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
772
787
  import { EventEmitter } from "node:events";
773
- import { accessSync, constants, readFileSync as readFileSync14, statSync as statSync4 } from "node:fs";
788
+ import { accessSync, constants, mkdirSync as mkdirSync16, readFileSync as readFileSync14, statSync as statSync4 } from "node:fs";
774
789
  import { createServer } from "node:http";
775
790
  import { delimiter, dirname as dirname8, join as join19 } from "node:path";
776
791
  import { fileURLToPath } from "node:url";
@@ -4104,7 +4119,7 @@ var AcpAgent = class {
4104
4119
  constructor(opts) {
4105
4120
  this.opts = opts;
4106
4121
  this.limit = opts.rememberedLimit?.() ?? null;
4107
- this.child = spawn3(opts.command, {
4122
+ this.child = spawn3(opts.launch ?? opts.command, {
4108
4123
  shell: true,
4109
4124
  detached: true,
4110
4125
  cwd: opts.cwd,
@@ -6113,8 +6128,26 @@ function pngSize(bytes) {
6113
6128
  return { width: view.getUint32(16), height: view.getUint32(20) };
6114
6129
  }
6115
6130
 
6131
+ // src/library/policy.ts
6132
+ var VIDEO_CAP_BYTES = 2e8;
6133
+ var THUMBNAIL_LONG_SIDE = 400;
6134
+ var TAG_MAX_LENGTH = 64;
6135
+ function normalizeTag(raw) {
6136
+ const name = raw.normalize("NFC").trim().replace(/\s+/g, " ");
6137
+ if (name === "" || name.length > TAG_MAX_LENGTH || /[,,]/.test(name)) return null;
6138
+ return lowercaseInitial(name);
6139
+ }
6140
+ function lowercaseInitial(name) {
6141
+ const [first = "", second = ""] = name;
6142
+ if (second !== second.toLowerCase()) return name;
6143
+ return first.toLowerCase() + name.slice(first.length);
6144
+ }
6145
+ function tagKey(name) {
6146
+ return name.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
6147
+ }
6148
+
6116
6149
  // src/library/internal/store.ts
6117
- var SCHEMA = { epoch: 1, version: 1 };
6150
+ var SCHEMA = { epoch: 1, version: 2 };
6118
6151
  var NODE_FLOOR = "22.13.0";
6119
6152
  var TRIGRAM_MIN_CHARS = 3;
6120
6153
  var MIGRATIONS = [
@@ -6190,8 +6223,17 @@ var MIGRATIONS = [
6190
6223
  INSERT INTO items_text (items_text, rowid, page_title, note) VALUES ('delete', old.seq, old.page_title, old.note);
6191
6224
  INSERT INTO items_text (rowid, page_title, note) VALUES (new.seq, new.page_title, new.note);
6192
6225
  END;
6193
- `
6226
+ `,
6227
+ renormalizeTagNames
6194
6228
  ];
6229
+ function renormalizeTagNames(db) {
6230
+ const rename = db.prepare("UPDATE tags SET name = ?, updated_at = ?, rev = rev + 1 WHERE id = ?");
6231
+ const now = Date.now();
6232
+ for (const { id, name } of db.prepare("SELECT id, name FROM tags").all()) {
6233
+ const normalized = normalizeTag(name);
6234
+ if (normalized !== null && normalized !== name) rename.run(normalized, now, id);
6235
+ }
6236
+ }
6195
6237
  function atLeast(version, floor) {
6196
6238
  const [a, b] = [version, floor].map((v) => v.replace(/^v/, "").split(".").map(Number));
6197
6239
  for (let i = 0; i < 3; i++) {
@@ -6252,7 +6294,11 @@ function migrate(db) {
6252
6294
  );
6253
6295
  }
6254
6296
  }
6255
- for (let v = version; v < MIGRATIONS.length; v++) db.exec(MIGRATIONS[v]);
6297
+ for (let v = version; v < MIGRATIONS.length; v++) {
6298
+ const migration = MIGRATIONS[v];
6299
+ if (typeof migration === "string") db.exec(migration);
6300
+ else migration(db);
6301
+ }
6256
6302
  if (version < MIGRATIONS.length) {
6257
6303
  db.exec(`PRAGMA user_version = ${MIGRATIONS.length}`);
6258
6304
  db.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES ('schema_epoch', ?)").run(String(SCHEMA.epoch));
@@ -6495,19 +6541,6 @@ function toRecord(row) {
6495
6541
  };
6496
6542
  }
6497
6543
 
6498
- // src/library/policy.ts
6499
- var VIDEO_CAP_BYTES = 2e8;
6500
- var THUMBNAIL_LONG_SIDE = 400;
6501
- var TAG_MAX_LENGTH = 64;
6502
- function normalizeTag(raw) {
6503
- const name = raw.normalize("NFC").trim().replace(/\s+/g, " ");
6504
- if (name === "" || name.length > TAG_MAX_LENGTH || /[,,]/.test(name)) return null;
6505
- return name;
6506
- }
6507
- function tagKey(name) {
6508
- return name.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
6509
- }
6510
-
6511
6544
  // src/library/index.ts
6512
6545
  var SUGGEST_LIMIT = 8;
6513
6546
  var FIND_LIMIT = 50;
@@ -7359,10 +7392,6 @@ function run(label, command, args, opts = {}) {
7359
7392
  });
7360
7393
  });
7361
7394
  }
7362
- function shellQuote(arg) {
7363
- if (process.platform === "win32") return /[\s"]/.test(arg) ? `"${arg.replace(/"/g, '""')}"` : arg;
7364
- return /^[A-Za-z0-9_@%+=:,./-]+$/.test(arg) ? arg : `'${arg.replace(/'/g, `'\\''`)}'`;
7365
- }
7366
7395
  async function npm(label, args) {
7367
7396
  const cli = npmCli();
7368
7397
  if (cli) {
@@ -8181,8 +8210,10 @@ var SessionRuntime = class {
8181
8210
  return this.acp.snapshot().agent === command;
8182
8211
  }
8183
8212
  this.store.setAgent(command);
8213
+ mkdirSync16(ACP_NPM_PREFIX, { recursive: true });
8184
8214
  this.acp = new AcpAgent({
8185
8215
  command,
8216
+ launch: launchCommand(command, ACP_NPM_PREFIX),
8186
8217
  cwd: this.project,
8187
8218
  // The figure outlives the process that was told it: it only ever arrives
8188
8219
  // pushed, so a daemon that forgot it would show nothing until the review's
@@ -8236,7 +8267,8 @@ var SessionRuntime = class {
8236
8267
  this.deliverToAcp();
8237
8268
  this.broadcast();
8238
8269
  },
8239
- onExit: () => {
8270
+ onExit: (error) => {
8271
+ console.error(`agent for ${this.project} stopped: ${error}`);
8240
8272
  this.agentBusy = false;
8241
8273
  this.activeBatch = null;
8242
8274
  this.activeSkills = [];
@@ -9442,7 +9474,7 @@ async function daemonMain(version, opts = {}) {
9442
9474
  }
9443
9475
 
9444
9476
  // src/inspire.ts
9445
- import { existsSync as existsSync11, mkdirSync as mkdirSync16, writeFileSync as writeFileSync11 } from "node:fs";
9477
+ import { existsSync as existsSync11, mkdirSync as mkdirSync17, writeFileSync as writeFileSync11 } from "node:fs";
9446
9478
  import { dirname as dirname9, join as join20 } from "node:path";
9447
9479
  var DEFAULT_INSPIRE_URL = "https://inspire.ezdesign.dev";
9448
9480
  var INSPIRE_URL_ENV = `${APP_NAME.toUpperCase()}_INSPIRE_URL`;
@@ -9543,7 +9575,7 @@ async function download(url, path, fetchImpl) {
9543
9575
  try {
9544
9576
  const res = await fetchImpl(url, { signal: AbortSignal.timeout(IMAGE_TIMEOUT_MS) });
9545
9577
  if (!res.ok) return false;
9546
- mkdirSync16(dirname9(path), { recursive: true });
9578
+ mkdirSync17(dirname9(path), { recursive: true });
9547
9579
  writeFileSync11(path, Buffer.from(await res.arrayBuffer()));
9548
9580
  return true;
9549
9581
  } catch {
@@ -8,6 +8,8 @@ export declare const SESSIONS_DIR: string;
8
8
  export declare const LEGACY_SESSIONS_DIR: string;
9
9
  export declare const REGISTRY_FILE: string;
10
10
  export declare const DAEMON_LOG: string;
11
+ /** The npm prefix ACP adapters are fetched under, apart from any project's. */
12
+ export declare const ACP_NPM_PREFIX: string;
11
13
  /** Where a self-updating daemon installs the version it hands over to. */
12
14
  export declare const VERSIONS_DIR: string;
13
15
  export declare const UPDATE_CHECK_FILE: string;
@@ -0,0 +1 @@
1
+ "use strict";(()=>{function B(e,t,n){let r=n.width/t.width,o=n.height/t.height,c=(ae,oe)=>Math.min(oe,Math.max(0,ae)),s=c(Math.floor(e.x*r+1e-6),n.width),m=c(Math.floor(e.y*o+1e-6),n.height),ie=c(Math.ceil((e.x+e.width)*r-1e-6),n.width),re=c(Math.ceil((e.y+e.height)*o-1e-6),n.height);return{x:s,y:m,width:ie-s,height:re-m}}var K="dialog:";function I(e){let t=e.normalize("NFC").trim().replace(/\s+/g," ");return t===""||t.length>64||/[,,]/.test(t)?null:se(t)}function se(e){let[t="",n=""]=e;return n!==n.toLowerCase()?e:t.toLowerCase()+e.slice(t.length)}function y(e){return e.normalize("NFKC").trim().replace(/\s+/g," ").toLowerCase()}var W={locked:[],chips:[],draft:"",highlighted:null},le=/[,,]/;function T(e){return[...e.locked,...e.chips]}function M(e,t){let n=I(t);return n===null||T(e).some(r=>y(r)===y(n))?e:{...e,chips:[...e.chips,n]}}function p(e,t,n){switch(t.type){case"input":{let r=t.value.split(le),o=r.pop()??"";return{...r.reduce(M,e),draft:o,highlighted:null}}case"enter":{let r=e.highlighted===null?e.draft:n[e.highlighted];return{...M(e,r??e.draft),draft:"",highlighted:null}}case"backspace":return e.draft===""&&e.chips.length?{...e,chips:e.chips.slice(0,-1),highlighted:null}:e;case"arrow":{if(n.length===0)return{...e,highlighted:null};let r=e.highlighted??(t.delta===1?-1:n.length);return{...e,highlighted:(r+t.delta+n.length)%n.length}}case"pick":return{...M(e,t.name),draft:"",highlighted:null};case"remove":return{...e,chips:e.chips.filter((r,o)=>o!==t.index)};case"lock":{let r=[];for(let c of t.names){let s=I(c);s&&!r.some(m=>y(m)===y(s))&&r.push(s)}let o=e.chips.filter(c=>!r.some(s=>y(s)===y(c)));return{...e,locked:r,chips:o}}}}var ce=location.hash.slice(1),A=window.top===window;document.documentElement.dataset.where=A?"window":"page";var N=chrome.runtime.connect({name:K+ce}),h=e=>N.postMessage(e),X=()=>performance.timeOrigin+performance.now(),j="\u53EF\u7559\u7A7A\u6216\u591A\u500B\uFF0C\u4EE5 Enter \u6216\u9017\u865F\u9694\u958B",de="\u4E32\u6D41\u5F71\u7247\u53EA\u6703\u5132\u5B58\u9023\u7D50\u3001\u76EE\u524D\u6642\u9593\u548C\u756B\u9762",pe="\u5F71\u7247\u8D85\u904E 200 MB\uFF0C\u53EA\u6703\u5132\u5B58\u9023\u7D50\u548C\u756B\u9762";function a(e,t={},...n){let r=document.createElement(e);for(let[o,c]of Object.entries(t))r.setAttribute(o,c);return r.append(...n),r}var S=a("div",{class:"overlay"}),O=a("section",{class:"card",role:"dialog","aria-modal":"true","aria-labelledby":"ez-title"}),ue=a("h1",{id:"ez-title"},"\u5132\u5B58\u81F3 ezdesign"),R=a("p",{class:"source"}),u=a("figure",{class:"preview",hidden:""}),U=a("span",{class:"chips"}),l=a("input",{type:"text",role:"combobox","aria-label":"\u6A19\u7C64","aria-autocomplete":"list","aria-expanded":"false","aria-controls":"ez-suggestions","data-testid":"ez-capture-tag-input",placeholder:j,autocomplete:"off",spellcheck:"false"}),ge=a("div",{class:"tags"},U,l),v=a("ul",{id:"ez-suggestions",role:"listbox","aria-label":"\u6A19\u7C64\u5EFA\u8B70","data-testid":"ez-capture-tag-suggestions",hidden:""}),L=a("textarea",{"aria-label":"\u70BA\u4EC0\u9EBC\u597D","data-testid":"ez-capture-note",rows:"3",placeholder:"\u53EF\u7559\u7A7A"}),P=a("p",{class:"status",role:"status","data-testid":"ez-capture-status"}),F=a("code"),k=a("button",{type:"button",class:"quiet"},"\u8907\u88FD"),Q=a("div",{class:"install","data-testid":"ez-capture-install",hidden:""},F,k),g=a("button",{type:"button",class:"grant",hidden:""}),Y=a("button",{type:"button","data-testid":"ez-capture-cancel"},"\u53D6\u6D88"),x=a("button",{type:"button",class:"primary","data-testid":"ez-capture-save"},"\u5132\u5B58"),$=a("header",{},ue,R);O.append(...A?[$,u]:[u,$],a("div",{class:"field"},a("span",{class:"label","aria-hidden":"true"},"\u6A19\u7C64"),a("div",{class:"combo"},ge,v)),a("div",{class:"field"},a("span",{class:"label","aria-hidden":"true"},"\u70BA\u4EC0\u9EBC\u597D"),L),P,Q,g,a("footer",{},Y,x));S.append(O);document.body.append(S);var _=null,i=W,d=[],q=!1,E=!1,C=null,w=null;function J(){if(C===null||w===null||w.nonce!==C)return;let{bitmap:e}=w;C=null,w=null,ne(e,e.width,e.height)}function f(){let e=i.locked.map(n=>a("span",{class:"chip locked",title:"\u5DF2\u6536\u85CF\u904E\u7684\u6A19\u7C64"},n)),t=i.chips.map((n,r)=>{let o=a("button",{type:"button",class:"chip","aria-label":`\u79FB\u9664\u6A19\u7C64 ${n}`},a("span",{},n),a("span",{class:"x","aria-hidden":"true"},"\xD7"));return o.addEventListener("click",()=>{i=p(i,{type:"remove",index:r},[]),f(),l.focus(),Z()}),o});U.replaceChildren(...e,...t),l.placeholder=e.length+t.length?"":j,l.value!==i.draft&&(l.value=i.draft),b()}function b(){let e=i.draft.trim()!==""&&d.length>0;v.hidden=!e,l.setAttribute("aria-expanded",String(e)),v.replaceChildren(...d.map((t,n)=>{let r=a("li",{role:"option",id:`ez-suggestion-${n}`,"aria-selected":String(n===i.highlighted)},a("span",{class:"name"},t.name),a("span",{class:"uses"},String(t.uses)));return n===i.highlighted&&(r.dataset.active=""),r.addEventListener("mousedown",o=>{o.preventDefault(),ee(t.name)}),r})),e&&i.highlighted!==null?l.setAttribute("aria-activedescendant",`ez-suggestion-${i.highlighted}`):l.removeAttribute("aria-activedescendant")}function Z(){if(i.draft.trim()===""){d=[],b();return}h({type:"suggest",prefix:i.draft.trim(),exclude:T(i)})}function ee(e){i=p(i,{type:"pick",name:e},[]),d=[],f(),l.focus()}var z=()=>d.map(e=>e.name);l.addEventListener("input",()=>{let e=i.chips.length;i=p(i,{type:"input",value:l.value},z()),i.chips.length!==e&&(d=[]),f(),Z()});l.addEventListener("keydown",e=>{e.isComposing||((e.key==="ArrowDown"||e.key==="ArrowUp")&&d.length?(e.preventDefault(),i=p(i,{type:"arrow",delta:e.key==="ArrowDown"?1:-1},z()),b()):e.key==="Enter"&&!(e.metaKey||e.ctrlKey)?(e.preventDefault(),i=p(i,{type:"enter"},z()),d=[],f()):e.key==="Tab"&&i.highlighted!==null&&!v.hidden?(e.preventDefault(),ee(d[i.highlighted].name)):e.key==="Backspace"&&l.value===""&&(i=p(i,{type:"backspace"},z()),f()))});l.addEventListener("blur",()=>{d=[],b()});function te(){E||!_||_.confirm!=="enabled"||(i.draft.trim()&&(i=p(i,{type:"enter"},[])),i={...i,highlighted:null},f(),h({type:"confirm",tags:T(i),note:L.value}))}function G(e){if(E)return;E=!0,document.documentElement.dataset.leaving=e,A||window.parent.postMessage({type:"ez-capture-leaving",how:e},"*");let t=matchMedia("(prefers-reduced-motion: reduce)").matches,n=()=>h({type:"closed"});t?setTimeout(n,120):O.addEventListener("animationend",n,{once:!0})}function H(){E||(h({type:"cancel"}),G("cancelled"))}x.addEventListener("click",te);Y.addEventListener("click",H);S.addEventListener("mousedown",e=>{e.target===S&&H()});document.addEventListener("keydown",e=>{e.key==="Escape"?(e.preventDefault(),v.hidden?H():(d=[],b())):e.key==="Enter"&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),te())});k.addEventListener("click",()=>{navigator.clipboard.writeText(F.textContent??"").then(()=>{k.textContent="\u5DF2\u8907\u88FD",setTimeout(()=>k.textContent="\u8907\u88FD",1500)})});g.addEventListener("click",()=>{let e=g.dataset.origin;e&&(g.disabled=!0,chrome.permissions.request({origins:[`${e}/*`]}).then(t=>h({type:t?"granted":"denied",origin:e}),()=>h({type:"denied",origin:e})))});function he(e){switch(e.host.type){case"missing":return"\u9084\u6C92\u6709\u5B89\u88DD ezdesign host\uFF0C\u5728\u7D42\u7AEF\u6A5F\u57F7\u884C\u9019\u884C\u6307\u4EE4\u5F8C\u518D\u5B58\u4E00\u6B21\uFF1A";case"incompatible":return e.host.older==="host"?"ezdesign host \u7248\u672C\u592A\u820A\uFF0C\u66F4\u65B0\u5F8C\u518D\u5B58\u4E00\u6B21\uFF1A":"\u9019\u500B\u64F4\u5145\u529F\u80FD\u7248\u672C\u592A\u820A\uFF0C\u66F4\u65B0\u5F8C\u518D\u5B58\u4E00\u6B21\uFF1A";case"broken":return e.host.message;default:return null}}function me(e){_=e,R.textContent=e.page.title||e.page.url,R.title=e.page.url,e.duplicate&&!q&&(q=!0,i=p(i,{type:"lock",names:e.duplicate.tags},[]),L.value===""&&(L.value=e.duplicate.note),f());let t=he(e),n=e.host.type==="missing"||e.host.type==="incompatible"?e.host.installCommand:null;Q.hidden=n===null,F.textContent=n??"";let r=e.staging.type==="needs-permission"?e.staging.origin:null;g.hidden=r===null,r&&(g.dataset.origin=r,g.textContent=`\u5141\u8A31\u8B80\u53D6 ${r}`,g.disabled=!1);let o=t??e.error??(e.staging.type==="failed"?e.staging.message:null)??(r?"\u9019\u5F35\u5716\u7247\u9700\u8981\u4F60\u5728\u9019\u500B\u7DB2\u7AD9\u7684\u767B\u5165\u72C0\u614B\u624D\u80FD\u8B80\u53D6\u3002":null)??(e.notice==="stream-link"?de:e.notice==="too-large"?pe:null)??(e.duplicate?"\u5DF2\u6536\u85CF\u904E":"");P.textContent=o,P.dataset.tone=t||e.error||e.staging.type==="failed"?"error":"info",x.disabled=e.confirm!=="enabled",x.textContent=e.confirm==="saving"?"\u5132\u5B58\u4E2D\u2026":e.confirm==="saved"?"\u5DF2\u5132\u5B58":"\u5132\u5B58",x.setAttribute("aria-busy",String(e.confirm==="saving")),e.confirm==="saved"&&G("saved")}var ye="min(300px, max(96px, 100vh - 400px))",fe=1200;function V(e,t){e.style.aspectRatio=`${t.width} / ${t.height}`,e.style.width=`min(100%, ${t.width}px, calc(${ye} * ${t.width/t.height}))`}function D(e){if(!e||u.childElementCount)return;let t=a("div",{class:"slot","aria-hidden":"true"});V(t,e),u.replaceChildren(t),u.hidden=!1}function ne(e,t,n,r){let o=r??{x:0,y:0,width:t,height:n},c=Math.min(1,fe/Math.max(o.width,o.height)),s=a("canvas",{"data-testid":"ez-capture-preview",role:"img","aria-label":"\u9810\u89BD"});V(s,o),s.width=Math.max(1,Math.round(o.width*c)),s.height=Math.max(1,Math.round(o.height*c));let m=s.getContext("2d");m.imageSmoothingQuality="high",m.drawImage(e,o.x,o.y,o.width,o.height,0,0,s.width,s.height),u.replaceChildren(s),u.hidden=!1,requestAnimationFrame(()=>h({type:"preview-shown",at:X()}))}async function be(e){switch(e.type){case"bitmap":D(e.size),C=e.nonce,J();return;case"screenshot":{D(e.rect??e.viewport);let t=new Image;t.src=e.dataUrl,await t.decode();let n={width:t.naturalWidth,height:t.naturalHeight};ne(t,n.width,n.height,e.rect?B(e.rect,e.viewport,n):void 0);return}case"url":{D(e.size);let t=a("img",{"data-testid":"ez-capture-preview",alt:"\u9810\u89BD",src:e.src});e.size&&V(t,e.size),await t.decode().catch(()=>{}),u.replaceChildren(t),u.hidden=!1,requestAnimationFrame(()=>h({type:"preview-shown",at:X()}));return}case"none":return}}window.addEventListener("message",e=>{let t=e.data;e.source!==window.parent||t?.type!=="ez-capture-preview"||(w=t,J())});N.onMessage.addListener(e=>{let t=e;t.type==="preview"?be(t.preview):t.type==="view"?me(t.view):t.type==="suggestions"&&t.prefix===i.draft.trim()&&(d=t.tags,i={...i,highlighted:null},b())});N.onDisconnect.addListener(()=>G("cancelled"));window.addEventListener("focus",()=>{!E&&(document.activeElement===document.body||document.activeElement===null)&&l.focus()});l.focus();})();
@@ -1 +1 @@
1
- "use strict";(()=>{function l(t){let r="";for(let e=0;e<t.length;e+=32768)r+=String.fromCharCode(...t.subarray(e,e+32768));return btoa(r)}function w(t){let r=atob(t),e=new Uint8Array(r.length);for(let n=0;n<r.length;n++)e[n]=r.charCodeAt(n);return e}function b(t,r,e){let n=e.width/r.width,a=e.height/r.height,i=(s,g)=>Math.min(g,Math.max(0,s)),o=i(Math.floor(t.x*n+1e-6),e.width),c=i(Math.floor(t.y*a+1e-6),e.height),h=i(Math.ceil((t.x+t.width)*n-1e-6),e.width),u=i(Math.ceil((t.y+t.height)*a-1e-6),e.height);return{x:o,y:c,width:h-o,height:u-c}}function p(t,r){let e=Math.min(1,400/Math.max(t,r));return{width:Math.max(1,Math.round(t*e)),height:Math.max(1,Math.round(r*e))}}var f="image/webp",x=.8;async function y(t,r){let e=p(r.width,r.height),n=t,{width:a,height:i}=r;for(;a/2>=e.width*2&&i/2>=e.height*2;){a=Math.round(a/2),i=Math.round(i/2);let u=new OffscreenCanvas(a,i),s=u.getContext("2d");s.imageSmoothingQuality="high",s.drawImage(n,0,0,a,i),n=u}let o=new OffscreenCanvas(e.width,e.height),c=o.getContext("2d");c.imageSmoothingQuality="high",c.drawImage(n,0,0,e.width,e.height);let h=await o.convertToBlob({type:f,quality:x});if(h.type!==f)throw new Error(`this browser encodes ${h.type}, not WebP`);return{webp:new Uint8Array(await h.arrayBuffer()),...e,source:{...r}}}async function m(t,r){let e=await y(t,r);return{...e,webp:l(e.webp)}}var d=new Map;async function E(t){let r=new Blob(t),e=await createImageBitmap(r).catch(()=>null);if(e)try{return await m(e,{width:e.width,height:e.height})}finally{e.close()}let n=URL.createObjectURL(new Blob(t,{type:"image/svg+xml"}));try{let a=new Image;return await new Promise((i,o)=>{a.onload=()=>i(),a.onerror=()=>o(new Error("cannot decode")),a.src=n}),!a.naturalWidth||!a.naturalHeight?null:await m(a,{width:a.naturalWidth,height:a.naturalHeight})}catch{return null}finally{URL.revokeObjectURL(n)}}async function v(t,r){let e=URL.createObjectURL(new Blob(t)),n=document.createElement("video");n.muted=!0,n.preload="auto";try{let a=i=>new Promise((o,c)=>{n.addEventListener(i,()=>o(),{once:!0}),n.addEventListener("error",()=>c(new Error("cannot decode the video")),{once:!0})});return n.src=e,await a("loadeddata"),n.currentTime=Math.min(r,Math.max(0,n.duration-.001)),await a("seeked"),n.videoWidth?await m(n,{width:n.videoWidth,height:n.videoHeight}):null}catch{return null}finally{n.removeAttribute("src"),n.load(),URL.revokeObjectURL(e)}}async function S(t){let r=await(await fetch(t.screenshot)).blob(),e=await createImageBitmap(r),n={width:e.width,height:e.height},a=t.rect?b(t.rect,t.viewport,n):{x:0,y:0,...n};if(a.width<1||a.height<1)return{original:null,thumb:null};let i=await createImageBitmap(e,a.x,a.y,a.width,a.height),o={width:a.width,height:a.height},c=async()=>{if(!t.original)return null;let s=new OffscreenCanvas(o.width,o.height);s.getContext("2d").drawImage(i,0,0);let g=await s.convertToBlob({type:"image/png"});return{png:l(new Uint8Array(await g.arrayBuffer())),size:o}},[h,u]=await Promise.all([m(i,o),c()]);return{original:u,thumb:h}}async function M(t){switch(t.type){case"feed":return d.set(t.job,[...d.get(t.job)??[],w(t.data)]),{};case"thumbnail":{let r=d.get(t.job)??[];return d.delete(t.job),{thumb:t.at===null?await E(r):await v(r,t.at)}}case"crop":return S(t);case"drop":return d.delete(t.job),{}}}function T(t){return t.type==="thumbnail"?{thumb:null}:t.type==="crop"?{original:null,thumb:null}:{}}chrome.runtime.onMessage.addListener((t,r,e)=>{let n=t;if(!(n?.to!=="media"||r.id!==chrome.runtime.id))return M(n).then(e,()=>e(T(n))),!0});})();
1
+ "use strict";(()=>{function l(t){let r="";for(let e=0;e<t.length;e+=32768)r+=String.fromCharCode(...t.subarray(e,e+32768));return btoa(r)}function w(t){let r=atob(t),e=new Uint8Array(r.length);for(let n=0;n<r.length;n++)e[n]=r.charCodeAt(n);return e}function b(t,r,e){let n=e.width/r.width,a=e.height/r.height,i=(s,g)=>Math.min(g,Math.max(0,s)),o=i(Math.floor(t.x*n+1e-6),e.width),c=i(Math.floor(t.y*a+1e-6),e.height),h=i(Math.ceil((t.x+t.width)*n-1e-6),e.width),u=i(Math.ceil((t.y+t.height)*a-1e-6),e.height);return{x:o,y:c,width:h-o,height:u-c}}function p(t,r){let e=Math.min(1,400/Math.max(t,r));return{width:Math.max(1,Math.round(t*e)),height:Math.max(1,Math.round(r*e))}}var f="image/webp",x=.8;async function y(t,r){let e=p(r.width,r.height),n=t,{width:a,height:i}=r;for(;a/2>=e.width*2&&i/2>=e.height*2;){a=Math.round(a/2),i=Math.round(i/2);let u=new OffscreenCanvas(a,i),s=u.getContext("2d");s.imageSmoothingQuality="high",s.drawImage(n,0,0,a,i),n=u}let o=new OffscreenCanvas(e.width,e.height),c=o.getContext("2d");c.imageSmoothingQuality="high",c.drawImage(n,0,0,e.width,e.height);let h=await o.convertToBlob({type:f,quality:x});if(h.type!==f)throw new Error(`this browser encodes ${h.type}, not WebP`);return{webp:new Uint8Array(await h.arrayBuffer()),...e,source:{...r}}}async function d(t,r){let e=await y(t,r);return{...e,webp:l(e.webp)}}var m=new Map;async function E(t){let r=new Blob(t),e=await createImageBitmap(r).catch(()=>null);if(e)try{return await d(e,{width:e.width,height:e.height})}finally{e.close()}let n=URL.createObjectURL(new Blob(t,{type:"image/svg+xml"}));try{let a=new Image;return await new Promise((i,o)=>{a.onload=()=>i(),a.onerror=()=>o(new Error("cannot decode")),a.src=n}),!a.naturalWidth||!a.naturalHeight?null:await d(a,{width:a.naturalWidth,height:a.naturalHeight})}catch{return null}finally{URL.revokeObjectURL(n)}}async function v(t,r){let e=URL.createObjectURL(new Blob(t)),n=document.createElement("video");n.muted=!0,n.preload="auto";try{let a=i=>new Promise((o,c)=>{n.addEventListener(i,()=>o(),{once:!0}),n.addEventListener("error",()=>c(new Error("cannot decode the video")),{once:!0})});return n.src=e,await a("loadeddata"),n.currentTime=Math.min(r,Math.max(0,n.duration-.001)),await a("seeked"),n.videoWidth?await d(n,{width:n.videoWidth,height:n.videoHeight}):null}catch{return null}finally{n.removeAttribute("src"),n.load(),URL.revokeObjectURL(e)}}async function S(t){let r=await(await fetch(t.screenshot)).blob(),e=await createImageBitmap(r),n={width:e.width,height:e.height},a=t.rect?b(t.rect,t.viewport,n):{x:0,y:0,...n};if(a.width<1||a.height<1)return{original:null,thumb:null};let i=await createImageBitmap(e,a.x,a.y,a.width,a.height),o={width:a.width,height:a.height},c=async()=>{if(!t.original)return null;let s=new OffscreenCanvas(o.width,o.height);s.getContext("2d").drawImage(i,0,0);let g=await s.convertToBlob({type:"image/png"});return{png:l(new Uint8Array(await g.arrayBuffer())),size:o}},[h,u]=await Promise.all([d(i,o),c()]);return{original:u,thumb:h}}async function L(t){switch(t.type){case"feed":return m.set(t.job,[...m.get(t.job)??[],w(t.data)]),{};case"thumbnail":{let r=m.get(t.job)??[];return m.delete(t.job),{thumb:t.at===null?await E(r):await v(r,t.at)}}case"crop":return S(t);case"drop":return m.delete(t.job),{}}}function M(t){return t.type==="thumbnail"?{thumb:null}:t.type==="crop"?{original:null,thumb:null}:{}}chrome.runtime.onMessage.addListener((t,r,e)=>{let n=t;if(!(n?.to!=="media"||r.id!==chrome.runtime.id))return L(n).then(e,()=>e(M(n))),!0});})();
@@ -1,4 +1,4 @@
1
- "use strict";(()=>{function b(e){let n="";for(let o=0;o<e.length;o+=32768)n+=String.fromCharCode(...e.subarray(o,o+32768));return btoa(n)}function I(e,n){let o=Math.min(1,400/Math.max(e,n));return{width:Math.max(1,Math.round(e*o)),height:Math.max(1,Math.round(n*o))}}var R="image/webp",Q=.8;async function B(e,n){let o=I(n.width,n.height),t=e,{width:r,height:a}=n;for(;r/2>=o.width*2&&a/2>=o.height*2;){r=Math.round(r/2),a=Math.round(a/2);let m=new OffscreenCanvas(r,a),h=m.getContext("2d");h.imageSmoothingQuality="high",h.drawImage(t,0,0,r,a),t=m}let u=new OffscreenCanvas(o.width,o.height),d=u.getContext("2d");d.imageSmoothingQuality="high",d.drawImage(t,0,0,o.width,o.height);let c=await u.convertToBlob({type:R,quality:Q});if(c.type!==R)throw new Error(`this browser encodes ${c.type}, not WebP`);return{webp:new Uint8Array(await c.arrayBuffer()),...o,source:{...n}}}async function N(e,n){let o=await B(e,n);return{...o,webp:b(o.webp)}}async function _(e,n){let o=new OffscreenCanvas(n.width,n.height);o.getContext("2d").drawImage(e,0,0,n.width,n.height);let t=await o.convertToBlob({type:"image/png"});return b(new Uint8Array(await t.arrayBuffer()))}var M=null;function J(e){let n=[e.currentSrc,e.getAttribute("src")?e.src:""];return e instanceof HTMLVideoElement&&n.push(...[...e.querySelectorAll("source")].map(o=>o.src)),n.filter(Boolean)}function z(e){let n=e.getBoundingClientRect(),o=Math.max(0,Math.min(n.right,innerWidth)-Math.max(n.left,0)),t=Math.max(0,Math.min(n.bottom,innerHeight)-Math.max(n.top,0));return o*t}function Z(e,n){let t=[...document.querySelectorAll(n==="image"?"img":"video")].filter(r=>J(r).includes(e));return t.length<=1?t[0]??null:t.find(r=>r.matches(":hover"))??t.sort((r,a)=>z(a)-z(r))[0]}function ee(e){let n=e.getBoundingClientRect(),o=Math.max(0,n.left),t=Math.max(0,n.top),r=Math.min(innerWidth,n.right)-o,a=Math.min(innerHeight,n.bottom)-t;return r>0&&a>0?{x:o,y:t,width:r,height:a}:null}async function te(e,n){if(e.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||!e.videoWidth)return{type:"empty"};if(e.mediaKeys)return{type:"protected"};let o={width:e.videoWidth,height:e.videoHeight};try{let[t,r]=await Promise.all([N(e,o),n?_(e,o):null]);return{type:"encoded",thumb:t,png:r}}catch(t){if(t.name==="SecurityError")return{type:"tainted"};throw t}}async function D(e,n,o){let t=Z(e,n);M=t;let r={width:innerWidth,height:innerHeight};if(!t)return{found:!1,viewport:r,rect:null,natural:null,video:null};let a=t instanceof HTMLVideoElement?{width:t.videoWidth,height:t.videoHeight}:{width:t.naturalWidth,height:t.naturalHeight};return{found:!0,viewport:r,rect:ee(t),natural:a.width&&a.height?a:null,video:t instanceof HTMLVideoElement?{currentTime:t.currentTime,frame:await te(t,o)}:null}}function O(){return M?.isConnected?M:null}async function U(e){try{return b(new Uint8Array(await(await fetch(e)).arrayBuffer()))}catch{return null}}var ne=`
1
+ "use strict";(()=>{function b(e){let n="";for(let o=0;o<e.length;o+=32768)n+=String.fromCharCode(...e.subarray(o,o+32768));return btoa(n)}function H(e,n){let o=Math.min(1,400/Math.max(e,n));return{width:Math.max(1,Math.round(e*o)),height:Math.max(1,Math.round(n*o))}}var R="image/webp",Q=.8;async function B(e,n){let o=H(n.width,n.height),t=e,{width:r,height:a}=n;for(;r/2>=o.width*2&&a/2>=o.height*2;){r=Math.round(r/2),a=Math.round(a/2);let m=new OffscreenCanvas(r,a),h=m.getContext("2d");h.imageSmoothingQuality="high",h.drawImage(t,0,0,r,a),t=m}let u=new OffscreenCanvas(o.width,o.height),d=u.getContext("2d");d.imageSmoothingQuality="high",d.drawImage(t,0,0,o.width,o.height);let c=await u.convertToBlob({type:R,quality:Q});if(c.type!==R)throw new Error(`this browser encodes ${c.type}, not WebP`);return{webp:new Uint8Array(await c.arrayBuffer()),...o,source:{...n}}}async function N(e,n){let o=await B(e,n);return{...o,webp:b(o.webp)}}async function _(e,n){let o=new OffscreenCanvas(n.width,n.height);o.getContext("2d").drawImage(e,0,0,n.width,n.height);let t=await o.convertToBlob({type:"image/png"});return b(new Uint8Array(await t.arrayBuffer()))}var M=null;function J(e){let n=[e.currentSrc,e.getAttribute("src")?e.src:""];return e instanceof HTMLVideoElement&&n.push(...[...e.querySelectorAll("source")].map(o=>o.src)),n.filter(Boolean)}function z(e){let n=e.getBoundingClientRect(),o=Math.max(0,Math.min(n.right,innerWidth)-Math.max(n.left,0)),t=Math.max(0,Math.min(n.bottom,innerHeight)-Math.max(n.top,0));return o*t}function Z(e,n){let t=[...document.querySelectorAll(n==="image"?"img":"video")].filter(r=>J(r).includes(e));return t.length<=1?t[0]??null:t.find(r=>r.matches(":hover"))??t.sort((r,a)=>z(a)-z(r))[0]}function ee(e){let n=e.getBoundingClientRect(),o=Math.max(0,n.left),t=Math.max(0,n.top),r=Math.min(innerWidth,n.right)-o,a=Math.min(innerHeight,n.bottom)-t;return r>0&&a>0?{x:o,y:t,width:r,height:a}:null}async function te(e,n){if(e.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||!e.videoWidth)return{type:"empty"};if(e.mediaKeys)return{type:"protected"};let o={width:e.videoWidth,height:e.videoHeight};try{let[t,r]=await Promise.all([N(e,o),n?_(e,o):null]);return{type:"encoded",thumb:t,png:r}}catch(t){if(t.name==="SecurityError")return{type:"tainted"};throw t}}async function D(e,n,o){let t=Z(e,n);M=t;let r={width:innerWidth,height:innerHeight};if(!t)return{found:!1,viewport:r,rect:null,natural:null,video:null};let a=t instanceof HTMLVideoElement?{width:t.videoWidth,height:t.videoHeight}:{width:t.naturalWidth,height:t.naturalHeight};return{found:!0,viewport:r,rect:ee(t),natural:a.width&&a.height?a:null,video:t instanceof HTMLVideoElement?{currentTime:t.currentTime,frame:await te(t,o)}:null}}function O(){return M?.isConnected?M:null}async function U(e){try{return b(new Uint8Array(await(await fetch(e)).arrayBuffer()))}catch{return null}}var ne=`
2
2
  :host { all: initial; }
3
3
  .pill {
4
4
  position: fixed; top: 16px; left: 50%; z-index: 2147483647;
@@ -17,7 +17,7 @@
17
17
  @media (prefers-reduced-motion: reduce) {
18
18
  @keyframes in { from { opacity: 0; } }
19
19
  }
20
- `,G="http://www.w3.org/2000/svg";function oe(){let e=document.createElementNS(G,"svg");for(let[o,t]of Object.entries({width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":"true"}))e.setAttribute(o,t);let n=document.createElementNS(G,"path");for(let[o,t]of Object.entries({d:"M5 12.5 10 17.5 19 7",stroke:"currentColor","stroke-width":"2.2","stroke-linecap":"round","stroke-linejoin":"round"}))n.setAttribute(o,t);return e.append(n),e}var l=null,W=()=>new Promise(e=>requestAnimationFrame(e));function F(){l&&(clearTimeout(l.timer),l.host.remove());let e=document.createElement("div");e.setAttribute("data-ez-capture-saved",""),e.style.cssText="all: initial; position: fixed; z-index: 2147483647";let n=e.attachShadow({mode:"closed"}),o=document.createElement("style");o.textContent=ne;let t=document.createElement("div");t.className="pill",t.setAttribute("role","status");let r=document.createElement("span");r.textContent="\u5DF2\u5132\u5B58",t.append(oe(),r),n.append(o,t),document.documentElement.append(e);let a=setTimeout(()=>{t.dataset.leaving="",t.addEventListener("animationend",()=>{e.remove(),l?.host===e&&(l=null)},{once:!0})},1600);l={host:e,timer:a}}async function S(){l&&(clearTimeout(l.timer),l.host.remove(),l=null,await W(),await W())}var A=new Map,re=["position: fixed","inset: 0","width: 100vw","height: 100vh","margin: 0","padding: 0","border: 0","background: transparent","color-scheme: light","backdrop-filter: blur(0px)","transition: backdrop-filter 0.22s cubic-bezier(0.23, 1, 0.32, 1)","z-index: 2147483647"].join("; "),ie="blur(4px)";async function K(e){let n=document.createElement("div");n.setAttribute("data-ez-capture",""),n.style.cssText="all: initial; position: fixed; inset: 0; z-index: 2147483647";let o=n.attachShadow({mode:"closed"}),t=document.createElement("iframe");t.setAttribute("style",re),t.setAttribute("allow","clipboard-write"),t.src=chrome.runtime.getURL(e.dialogPath),o.append(t);let r=new Promise(c=>{t.addEventListener("load",()=>c(!0),{once:!0}),t.addEventListener("error",()=>c(!1),{once:!0})}),a=new AbortController;if(document.documentElement.append(n),A.set(e.captureId,{host:n,listening:a}),!await r||!t.contentWindow)return T(e.captureId),{mounted:!1,handedOff:!1};t.focus(),requestAnimationFrame(()=>t.style.backdropFilter=ie),addEventListener("message",c=>{let m=c.data;c.source!==t.contentWindow||m?.type!=="ez-capture-leaving"||(t.style.backdropFilter="blur(0px)",m.how==="saved"&&F())},{signal:a.signal});let u=e.bitmap?O():null,d=u&&await createImageBitmap(u).catch(()=>null);if(!d)return{mounted:!0,handedOff:!1};try{let c={type:"ez-capture-preview",nonce:e.nonce,bitmap:d};return t.contentWindow.postMessage(c,"*",[d]),{mounted:!0,handedOff:!0}}catch{return d.close(),{mounted:!0,handedOff:!1}}}function T(e){let n=A.get(e);n?.listening.abort(),n?.host.remove(),A.delete(e)}function L(e,n){return{x:Math.round(Math.min(e.x,n.x)),y:Math.round(Math.min(e.y,n.y)),width:Math.round(Math.abs(n.x-e.x)),height:Math.round(Math.abs(n.y-e.y))}}function C(e){return e.width>=8||e.height>=8}var ae="#e56d41",se=`
20
+ `,G="http://www.w3.org/2000/svg";function oe(){let e=document.createElementNS(G,"svg");for(let[o,t]of Object.entries({width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":"true"}))e.setAttribute(o,t);let n=document.createElementNS(G,"path");for(let[o,t]of Object.entries({d:"M5 12.5 10 17.5 19 7",stroke:"currentColor","stroke-width":"2.2","stroke-linecap":"round","stroke-linejoin":"round"}))n.setAttribute(o,t);return e.append(n),e}var l=null,W=()=>new Promise(e=>requestAnimationFrame(e));function F(){l&&(clearTimeout(l.timer),l.host.remove());let e=document.createElement("div");e.setAttribute("data-ez-capture-saved",""),e.style.cssText="all: initial; position: fixed; z-index: 2147483647";let n=e.attachShadow({mode:"closed"}),o=document.createElement("style");o.textContent=ne;let t=document.createElement("div");t.className="pill",t.setAttribute("role","status");let r=document.createElement("span");r.textContent="\u5DF2\u5132\u5B58",t.append(oe(),r),n.append(o,t),document.documentElement.append(e);let a=setTimeout(()=>{t.dataset.leaving="",t.addEventListener("animationend",()=>{e.remove(),l?.host===e&&(l=null)},{once:!0})},1600);l={host:e,timer:a}}async function S(){l&&(clearTimeout(l.timer),l.host.remove(),l=null,await W(),await W())}var A=new Map,re=["position: fixed","inset: 0","width: 100vw","height: 100vh","margin: 0","padding: 0","border: 0","background: transparent","color-scheme: light","backdrop-filter: blur(0px)","transition: backdrop-filter 0.22s cubic-bezier(0.23, 1, 0.32, 1)","z-index: 2147483647"].join("; "),ie="blur(4px)";async function K(e){let n=document.createElement("div");n.setAttribute("data-ez-capture",""),n.style.cssText="all: initial; position: fixed; inset: 0; z-index: 2147483647";let o=n.attachShadow({mode:"closed"}),t=document.createElement("iframe");t.setAttribute("style",re),t.setAttribute("allow","clipboard-write"),t.src=chrome.runtime.getURL(e.dialogPath),o.append(t);let r=new Promise(c=>{t.addEventListener("load",()=>c(!0),{once:!0}),t.addEventListener("error",()=>c(!1),{once:!0})}),a=new AbortController;if(document.documentElement.append(n),A.set(e.captureId,{host:n,listening:a}),!await r||!t.contentWindow)return L(e.captureId),{mounted:!1,handedOff:!1};t.focus(),requestAnimationFrame(()=>t.style.backdropFilter=ie),addEventListener("message",c=>{let m=c.data;c.source!==t.contentWindow||m?.type!=="ez-capture-leaving"||(t.style.backdropFilter="blur(0px)",m.how==="saved"&&F())},{signal:a.signal});let u=e.bitmap?O():null,d=u&&await createImageBitmap(u).catch(()=>null);if(!d)return{mounted:!0,handedOff:!1};try{let c={type:"ez-capture-preview",nonce:e.nonce,bitmap:d};return t.contentWindow.postMessage(c,"*",[d]),{mounted:!0,handedOff:!0}}catch{return d.close(),{mounted:!0,handedOff:!1}}}function L(e){let n=A.get(e);n?.listening.abort(),n?.host.remove(),A.delete(e)}function T(e,n){return{x:Math.round(Math.min(e.x,n.x)),y:Math.round(Math.min(e.y,n.y)),width:Math.round(Math.abs(n.x-e.x)),height:Math.round(Math.abs(n.y-e.y))}}function C(e){return e.width>=8||e.height>=8}var ae="#e56d41",se=`
21
21
  :host { all: initial; }
22
22
  .layer { position: fixed; inset: 0; cursor: crosshair; touch-action: none; }
23
23
  .shade { position: fixed; background: oklch(0% 0 0 / 0.35); pointer-events: none; }
@@ -36,4 +36,4 @@
36
36
  font: 500 12px/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans TC', sans-serif;
37
37
  }
38
38
  [hidden] { display: none; }
39
- `,ce=()=>performance.timeOrigin+performance.now(),V=()=>new Promise(e=>requestAnimationFrame(e));function w(e,n,o,t,r){e.style.left=`${n}px`,e.style.top=`${o}px`,e.style.width=`${Math.max(0,t)}px`,e.style.height=`${Math.max(0,r)}px`}function j(){let e=document.createElement("div");e.setAttribute("data-ez-capture",""),e.style.cssText="all: initial; position: fixed; inset: 0; z-index: 2147483647";let n=e.attachShadow({mode:"closed"}),o=document.createElement("style");o.textContent=se;let t=document.createElement("div");t.className="layer";let r=()=>{let x=document.createElement("div");return x.className="shade",x.hidden=!0,x},[a,u,d,c]=[r(),r(),r(),r()],m=[a,u,d,c],h=document.createElement("div");h.className="box",h.hidden=!0;let p=document.createElement("div");p.className="size",p.hidden=!0;let g=document.createElement("div");return g.className="hint",g.textContent="\u62D6\u66F3\u6846\u51FA\u8981\u5B58\u7684\u5340\u57DF\uFF0CEsc \u53D6\u6D88",n.append(o,t,...m,h,p,g),document.documentElement.append(e),new Promise(x=>{let y=null,P=!1,q=s=>{let i=L(y,s),f=C(i);for(let X of m)X.hidden=!f;if(h.hidden=p.hidden=!f,g.hidden=f||g.hidden,!f)return;w(a,0,0,innerWidth,i.y),w(u,0,i.y+i.height,innerWidth,innerHeight-i.y-i.height),w(d,0,i.y,i.x,i.height),w(c,i.x+i.width,i.y,innerWidth-i.x-i.width,i.height),w(h,i.x,i.y,i.width,i.height),p.textContent=`${i.width} \xD7 ${i.height}`;let E=i.y+i.height+28<innerHeight;p.style.left=`${i.x}px`,p.style.top=`${E?i.y+i.height+6:Math.max(0,i.y-26)}px`},k=async s=>{P||(P=!0,removeEventListener("keydown",H,!0),removeEventListener("wheel",v,!0),removeEventListener("touchmove",v,!0),e.remove(),await V(),await V(),x(s))},H=s=>{s.key==="Escape"&&(s.preventDefault(),s.stopPropagation(),k({type:"cancelled"}))},v=s=>s.preventDefault();t.addEventListener("pointerdown",s=>{s.button===0&&(s.preventDefault(),t.setPointerCapture(s.pointerId),y={x:s.clientX,y:s.clientY})}),t.addEventListener("pointermove",s=>{y&&q({x:s.clientX,y:s.clientY})}),t.addEventListener("pointerup",s=>{if(!y)return;let i=ce(),f=L(y,{x:s.clientX,y:s.clientY}),E={width:innerWidth,height:innerHeight};k(C(f)?{type:"rect",rect:f,viewport:E,pickedAt:i}:{type:"viewport",viewport:E,pickedAt:i})}),addEventListener("keydown",H,!0),addEventListener("wheel",v,{capture:!0,passive:!1}),addEventListener("touchmove",v,{capture:!0,passive:!1})})}var $=Symbol.for("ezdesign.capture.page-agent"),de={"select-region":()=>S().then(j),inspect:e=>S().then(()=>D(e.srcUrl,e.mediaType,e.fullFrame)),read:async e=>({data:await U(e.url)}),present:e=>K(e),dismiss:async e=>(T(e.captureId),{})},Y=globalThis;Y[$]||(Y[$]=!0,chrome.runtime.onMessage.addListener((e,n,o)=>{let t=e;if(t?.to!=="page"||n.id!==chrome.runtime.id)return;let r=de[t.type];return r(t).then(o,a=>o({error:String(a)})),!0}));})();
39
+ `,ce=()=>performance.timeOrigin+performance.now(),V=()=>new Promise(e=>requestAnimationFrame(e));function w(e,n,o,t,r){e.style.left=`${n}px`,e.style.top=`${o}px`,e.style.width=`${Math.max(0,t)}px`,e.style.height=`${Math.max(0,r)}px`}function j(){let e=document.createElement("div");e.setAttribute("data-ez-capture",""),e.style.cssText="all: initial; position: fixed; inset: 0; z-index: 2147483647";let n=e.attachShadow({mode:"closed"}),o=document.createElement("style");o.textContent=se;let t=document.createElement("div");t.className="layer";let r=()=>{let x=document.createElement("div");return x.className="shade",x.hidden=!0,x},[a,u,d,c]=[r(),r(),r(),r()],m=[a,u,d,c],h=document.createElement("div");h.className="box",h.hidden=!0;let p=document.createElement("div");p.className="size",p.hidden=!0;let g=document.createElement("div");return g.className="hint",g.textContent="\u62D6\u66F3\u6846\u51FA\u8981\u5B58\u7684\u5340\u57DF\uFF0CEsc \u53D6\u6D88",n.append(o,t,...m,h,p,g),document.documentElement.append(e),new Promise(x=>{let y=null,P=!1,q=s=>{let i=T(y,s),f=C(i);for(let X of m)X.hidden=!f;if(h.hidden=p.hidden=!f,g.hidden=f||g.hidden,!f)return;w(a,0,0,innerWidth,i.y),w(u,0,i.y+i.height,innerWidth,innerHeight-i.y-i.height),w(d,0,i.y,i.x,i.height),w(c,i.x+i.width,i.y,innerWidth-i.x-i.width,i.height),w(h,i.x,i.y,i.width,i.height),p.textContent=`${i.width} \xD7 ${i.height}`;let E=i.y+i.height+28<innerHeight;p.style.left=`${i.x}px`,p.style.top=`${E?i.y+i.height+6:Math.max(0,i.y-26)}px`},k=async s=>{P||(P=!0,removeEventListener("keydown",I,!0),removeEventListener("wheel",v,!0),removeEventListener("touchmove",v,!0),e.remove(),await V(),await V(),x(s))},I=s=>{s.key==="Escape"&&(s.preventDefault(),s.stopPropagation(),k({type:"cancelled"}))},v=s=>s.preventDefault();t.addEventListener("pointerdown",s=>{s.button===0&&(s.preventDefault(),t.setPointerCapture(s.pointerId),y={x:s.clientX,y:s.clientY})}),t.addEventListener("pointermove",s=>{y&&q({x:s.clientX,y:s.clientY})}),t.addEventListener("pointerup",s=>{if(!y)return;let i=ce(),f=T(y,{x:s.clientX,y:s.clientY}),E={width:innerWidth,height:innerHeight};k(C(f)?{type:"rect",rect:f,viewport:E,pickedAt:i}:{type:"viewport",viewport:E,pickedAt:i})}),addEventListener("keydown",I,!0),addEventListener("wheel",v,{capture:!0,passive:!1}),addEventListener("touchmove",v,{capture:!0,passive:!1})})}var $=Symbol.for("ezdesign.capture.page-agent"),de={"select-region":()=>S().then(j),inspect:e=>S().then(()=>D(e.srcUrl,e.mediaType,e.fullFrame)),read:async e=>({data:await U(e.url)}),present:e=>K(e),dismiss:async e=>(L(e.captureId),{})},Y=globalThis;Y[$]||(Y[$]=!0,chrome.runtime.onMessage.addListener((e,n,o)=>{let t=e;if(t?.to!=="page"||n.id!==chrome.runtime.id)return;let r=de[t.type];return r(t).then(o,a=>o({error:String(a)})),!0}));})();
@@ -2,14 +2,14 @@
2
2
  "manifest_version": 3,
3
3
  "name": "ezdesign capture",
4
4
  "description": "把網頁上的圖片、影片和截圖存進 ezdesign 的設計收藏",
5
- "version": "0.9.1",
5
+ "version": "0.9.2",
6
6
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlzPjnyRVvSB2AjSq+2QWTRzxUAqXp52c1XP3C9YSNVNzzOIpt6gnnoaOikfn0wcNWQCV7Llp9giVbhRrQRwTiWj24U3cAM0NNGLZoBByBQtB45T9mM7NNdUpNT6ITtpELVCylsUF5LcEzbB/DjUDVmXAiN3cncH5ZFP2XPb+c8Nr89UmDFyjAfONfkNzY7dYkzIb32w+GNX8P2UhsT73+g3jtT7YJvV0SziLzn+xSl1KEBTPcIZcsZDc4tIdIvzsb2K8GSrvTNY2ACRu77gtiSCMjfAgk83OxSrS6QZfp3Q3jse7E6CPvqM2C1FPS7HkcRTejBORO1tewvU9VJbUiQIDAQAB",
7
7
  "minimum_chrome_version": "116",
8
8
  "icons": {
9
- "16": "g/0.9.1-16d05e759b/icon-16.png",
10
- "32": "g/0.9.1-16d05e759b/icon-32.png",
11
- "48": "g/0.9.1-16d05e759b/icon-48.png",
12
- "128": "g/0.9.1-16d05e759b/icon-128.png"
9
+ "16": "g/0.9.2-d9aee83dae/icon-16.png",
10
+ "32": "g/0.9.2-d9aee83dae/icon-32.png",
11
+ "48": "g/0.9.2-d9aee83dae/icon-48.png",
12
+ "128": "g/0.9.2-d9aee83dae/icon-128.png"
13
13
  },
14
14
  "permissions": [
15
15
  "activeTab",
@@ -20,13 +20,13 @@
20
20
  "storage"
21
21
  ],
22
22
  "background": {
23
- "service_worker": "g/0.9.1-16d05e759b/worker.js"
23
+ "service_worker": "g/0.9.2-d9aee83dae/worker.js"
24
24
  },
25
25
  "action": {
26
26
  "default_title": "截取區域存至 ezdesign",
27
27
  "default_icon": {
28
- "16": "g/0.9.1-16d05e759b/icon-16.png",
29
- "32": "g/0.9.1-16d05e759b/icon-32.png"
28
+ "16": "g/0.9.2-d9aee83dae/icon-16.png",
29
+ "32": "g/0.9.2-d9aee83dae/icon-32.png"
30
30
  }
31
31
  },
32
32
  "optional_host_permissions": [
@@ -43,9 +43,9 @@
43
43
  "web_accessible_resources": [
44
44
  {
45
45
  "resources": [
46
- "g/0.9.1-16d05e759b/dialog.html",
47
- "g/0.9.1-16d05e759b/dialog.js",
48
- "g/0.9.1-16d05e759b/dialog.css"
46
+ "g/0.9.2-d9aee83dae/dialog.html",
47
+ "g/0.9.2-d9aee83dae/dialog.js",
48
+ "g/0.9.2-d9aee83dae/dialog.css"
49
49
  ],
50
50
  "matches": [
51
51
  "<all_urls>"
@@ -53,5 +53,5 @@
53
53
  "use_dynamic_url": true
54
54
  }
55
55
  ],
56
- "version_name": "0.9.1"
56
+ "version_name": "0.9.2"
57
57
  }
@@ -21,6 +21,7 @@ var SESSIONS_DIR = join(DATA_DIR, "sessions");
21
21
  var LEGACY_SESSIONS_DIR = join(DATA_DIR, "sessions-legacy");
22
22
  var REGISTRY_FILE = join(DATA_DIR, "daemon.json");
23
23
  var DAEMON_LOG = join(DATA_DIR, "daemon.log");
24
+ var ACP_NPM_PREFIX = join(DATA_DIR, "acp");
24
25
  var VERSIONS_DIR = join(DATA_DIR, "versions");
25
26
  var UPDATE_CHECK_FILE = join(DATA_DIR, "update-check.json");
26
27
  var libraryDir = (dataDir = DATA_DIR) => join(dataDir, "library");
@@ -293,8 +294,26 @@ function pngSize(bytes) {
293
294
  return { width: view.getUint32(16), height: view.getUint32(20) };
294
295
  }
295
296
 
297
+ // src/library/policy.ts
298
+ var VIDEO_CAP_BYTES = 2e8;
299
+ var THUMBNAIL_LONG_SIDE = 400;
300
+ var TAG_MAX_LENGTH = 64;
301
+ function normalizeTag(raw) {
302
+ const name = raw.normalize("NFC").trim().replace(/\s+/g, " ");
303
+ if (name === "" || name.length > TAG_MAX_LENGTH || /[,,]/.test(name)) return null;
304
+ return lowercaseInitial(name);
305
+ }
306
+ function lowercaseInitial(name) {
307
+ const [first = "", second = ""] = name;
308
+ if (second !== second.toLowerCase()) return name;
309
+ return first.toLowerCase() + name.slice(first.length);
310
+ }
311
+ function tagKey(name) {
312
+ return name.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
313
+ }
314
+
296
315
  // src/library/internal/store.ts
297
- var SCHEMA = { epoch: 1, version: 1 };
316
+ var SCHEMA = { epoch: 1, version: 2 };
298
317
  var NODE_FLOOR = "22.13.0";
299
318
  var TRIGRAM_MIN_CHARS = 3;
300
319
  var MIGRATIONS = [
@@ -370,8 +389,17 @@ var MIGRATIONS = [
370
389
  INSERT INTO items_text (items_text, rowid, page_title, note) VALUES ('delete', old.seq, old.page_title, old.note);
371
390
  INSERT INTO items_text (rowid, page_title, note) VALUES (new.seq, new.page_title, new.note);
372
391
  END;
373
- `
392
+ `,
393
+ renormalizeTagNames
374
394
  ];
395
+ function renormalizeTagNames(db) {
396
+ const rename = db.prepare("UPDATE tags SET name = ?, updated_at = ?, rev = rev + 1 WHERE id = ?");
397
+ const now = Date.now();
398
+ for (const { id, name } of db.prepare("SELECT id, name FROM tags").all()) {
399
+ const normalized = normalizeTag(name);
400
+ if (normalized !== null && normalized !== name) rename.run(normalized, now, id);
401
+ }
402
+ }
375
403
  function atLeast(version2, floor) {
376
404
  const [a, b] = [version2, floor].map((v) => v.replace(/^v/, "").split(".").map(Number));
377
405
  for (let i = 0; i < 3; i++) {
@@ -432,7 +460,11 @@ function migrate(db) {
432
460
  );
433
461
  }
434
462
  }
435
- for (let v = version2; v < MIGRATIONS.length; v++) db.exec(MIGRATIONS[v]);
463
+ for (let v = version2; v < MIGRATIONS.length; v++) {
464
+ const migration = MIGRATIONS[v];
465
+ if (typeof migration === "string") db.exec(migration);
466
+ else migration(db);
467
+ }
436
468
  if (version2 < MIGRATIONS.length) {
437
469
  db.exec(`PRAGMA user_version = ${MIGRATIONS.length}`);
438
470
  db.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES ('schema_epoch', ?)").run(String(SCHEMA.epoch));
@@ -675,19 +707,6 @@ function toRecord(row) {
675
707
  };
676
708
  }
677
709
 
678
- // src/library/policy.ts
679
- var VIDEO_CAP_BYTES = 2e8;
680
- var THUMBNAIL_LONG_SIDE = 400;
681
- var TAG_MAX_LENGTH = 64;
682
- function normalizeTag(raw) {
683
- const name = raw.normalize("NFC").trim().replace(/\s+/g, " ");
684
- if (name === "" || name.length > TAG_MAX_LENGTH || /[,,]/.test(name)) return null;
685
- return name;
686
- }
687
- function tagKey(name) {
688
- return name.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
689
- }
690
-
691
710
  // src/library/index.ts
692
711
  var SUGGEST_LIMIT = 8;
693
712
  var FIND_LIMIT = 50;
@@ -20552,7 +20571,7 @@ function toWireError(error61) {
20552
20571
  }
20553
20572
 
20554
20573
  // src/native-host/main.ts
20555
- var HOST_VERSION = true ? "0.9.1" : "dev";
20574
+ var HOST_VERSION = true ? "0.9.2" : "dev";
20556
20575
  async function run(stdout2) {
20557
20576
  const caller = checkCaller(process.argv);
20558
20577
  if (!caller.ok) {
package/dist/shell.css CHANGED
@@ -516,6 +516,9 @@ body.ez-arranging .ez-frame {
516
516
  .ez-badge.ez-online::before {
517
517
  background: oklch(62% 0.15 150);
518
518
  }
519
+ .ez-badge.ez-offline::before {
520
+ background: var(--danger);
521
+ }
519
522
  .ez-badge.ez-working::before {
520
523
  background: oklch(70% 0.16 70);
521
524
  animation: ez-pulse 1.2s ease-in-out infinite;
package/dist/shell.js CHANGED
@@ -155,19 +155,23 @@
155
155
  }
156
156
 
157
157
  // src/agents.ts
158
+ var CLAUDE_ADAPTER = "@agentclientprotocol/claude-agent-acp";
159
+ var CODEX_ADAPTER = "@agentclientprotocol/codex-acp";
158
160
  var AGENT_PROFILES = [
159
161
  {
160
162
  id: "claude",
161
163
  name: "Claude Code",
162
- command: "npx -y @agentclientprotocol/claude-agent-acp",
164
+ command: `npx -y ${CLAUDE_ADAPTER}`,
163
165
  binary: "claude",
166
+ adapter: CLAUDE_ADAPTER,
164
167
  brand: "claude"
165
168
  },
166
169
  {
167
170
  id: "codex",
168
171
  name: "Codex",
169
- command: "npx -y @agentclientprotocol/codex-acp",
172
+ command: `npx -y ${CODEX_ADAPTER}`,
170
173
  binary: "codex",
174
+ adapter: CODEX_ADAPTER,
171
175
  brand: "openai"
172
176
  },
173
177
  { id: "gemini", name: "Gemini CLI", command: "gemini --experimental-acp", binary: "gemini" }
@@ -2793,7 +2797,12 @@
2793
2797
  function normalizeTag(raw) {
2794
2798
  const name = raw.normalize("NFC").trim().replace(/\s+/g, " ");
2795
2799
  if (name === "" || name.length > TAG_MAX_LENGTH || /[,,]/.test(name)) return null;
2796
- return name;
2800
+ return lowercaseInitial(name);
2801
+ }
2802
+ function lowercaseInitial(name) {
2803
+ const [first = "", second = ""] = name;
2804
+ if (second !== second.toLowerCase()) return name;
2805
+ return first.toLowerCase() + name.slice(first.length);
2797
2806
  }
2798
2807
  function tagKey(name) {
2799
2808
  return name.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
@@ -7768,6 +7777,9 @@
7768
7777
  } else if (s.acp?.state === "starting") {
7769
7778
  agentStatus.className = "ez-badge ez-working";
7770
7779
  agentStatus.textContent = "Agent \u6E96\u5099\u4E2D";
7780
+ } else if (s.acp?.state === "exited") {
7781
+ agentStatus.className = "ez-badge ez-offline";
7782
+ agentStatus.textContent = "Agent \u5DF2\u96E2\u7DDA";
7771
7783
  } else if (s.agentOnline) {
7772
7784
  agentStatus.className = "ez-badge ez-online";
7773
7785
  agentStatus.textContent = "Agent \u5DF2\u9023\u7DDA";
@@ -7775,6 +7787,7 @@
7775
7787
  agentStatus.className = "ez-badge";
7776
7788
  agentStatus.textContent = "Agent \u672A\u9023\u7DDA";
7777
7789
  }
7790
+ agentStatus.title = s.acp?.state === "exited" && s.acp.error || "";
7778
7791
  reviewPanelBtn.toggleAttribute("data-working", agentStatus.classList.contains("ez-working"));
7779
7792
  paintQueue(s.annotations);
7780
7793
  convList.textContent = "";
package/dist/vite.mjs CHANGED
@@ -13,6 +13,7 @@ var SESSIONS_DIR = join(DATA_DIR, "sessions");
13
13
  var LEGACY_SESSIONS_DIR = join(DATA_DIR, "sessions-legacy");
14
14
  var REGISTRY_FILE = join(DATA_DIR, "daemon.json");
15
15
  var DAEMON_LOG = join(DATA_DIR, "daemon.log");
16
+ var ACP_NPM_PREFIX = join(DATA_DIR, "acp");
16
17
  var VERSIONS_DIR = join(DATA_DIR, "versions");
17
18
  var UPDATE_CHECK_FILE = join(DATA_DIR, "update-check.json");
18
19
  var LIBRARY_HOME_ENV = `${ENV_PREFIX}_LIBRARY_HOME`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cychien/ezdesign",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "Annotate your live dev app in the browser; feedback flows to your local coding agent, which edits the source. Review, iterate, repeat.",
5
5
  "type": "module",
6
6
  "author": "Justin Chien",
@@ -2,7 +2,7 @@
2
2
  name: ezdesign
3
3
  description: Open an ezdesign review session on a running web page. The user annotates the page in the browser, and each batch reaches the coding agent with exact source locations. Use when the user invokes /ezdesign, or asks to review, annotate or give visual feedback on a running page, or to explore designs on a canvas.
4
4
  metadata:
5
- version: 0.9.1
5
+ version: 0.9.2
6
6
  ---
7
7
 
8
8
  # ezdesign
@@ -1 +0,0 @@
1
- "use strict";(()=>{function B(e,t,n){let r=n.width/t.width,o=n.height/t.height,c=(ae,oe)=>Math.min(oe,Math.max(0,ae)),s=c(Math.floor(e.x*r+1e-6),n.width),m=c(Math.floor(e.y*o+1e-6),n.height),ie=c(Math.ceil((e.x+e.width)*r-1e-6),n.width),re=c(Math.ceil((e.y+e.height)*o-1e-6),n.height);return{x:s,y:m,width:ie-s,height:re-m}}var K="dialog:";function M(e){let t=e.normalize("NFC").trim().replace(/\s+/g," ");return t===""||t.length>64||/[,,]/.test(t)?null:t}function y(e){return e.normalize("NFKC").trim().replace(/\s+/g," ").toLowerCase()}var W={locked:[],chips:[],draft:"",highlighted:null},se=/[,,]/;function T(e){return[...e.locked,...e.chips]}function I(e,t){let n=M(t);return n===null||T(e).some(r=>y(r)===y(n))?e:{...e,chips:[...e.chips,n]}}function p(e,t,n){switch(t.type){case"input":{let r=t.value.split(se),o=r.pop()??"";return{...r.reduce(I,e),draft:o,highlighted:null}}case"enter":{let r=e.highlighted===null?e.draft:n[e.highlighted];return{...I(e,r??e.draft),draft:"",highlighted:null}}case"backspace":return e.draft===""&&e.chips.length?{...e,chips:e.chips.slice(0,-1),highlighted:null}:e;case"arrow":{if(n.length===0)return{...e,highlighted:null};let r=e.highlighted??(t.delta===1?-1:n.length);return{...e,highlighted:(r+t.delta+n.length)%n.length}}case"pick":return{...I(e,t.name),draft:"",highlighted:null};case"remove":return{...e,chips:e.chips.filter((r,o)=>o!==t.index)};case"lock":{let r=[];for(let c of t.names){let s=M(c);s&&!r.some(m=>y(m)===y(s))&&r.push(s)}let o=e.chips.filter(c=>!r.some(s=>y(s)===y(c)));return{...e,locked:r,chips:o}}}}var le=location.hash.slice(1),A=window.top===window;document.documentElement.dataset.where=A?"window":"page";var N=chrome.runtime.connect({name:K+le}),h=e=>N.postMessage(e),X=()=>performance.timeOrigin+performance.now(),j="\u53EF\u7559\u7A7A\u6216\u591A\u500B\uFF0C\u4EE5 Enter \u6216\u9017\u865F\u9694\u958B",ce="\u4E32\u6D41\u5F71\u7247\u53EA\u6703\u5132\u5B58\u9023\u7D50\u3001\u76EE\u524D\u6642\u9593\u548C\u756B\u9762",de="\u5F71\u7247\u8D85\u904E 200 MB\uFF0C\u53EA\u6703\u5132\u5B58\u9023\u7D50\u548C\u756B\u9762";function a(e,t={},...n){let r=document.createElement(e);for(let[o,c]of Object.entries(t))r.setAttribute(o,c);return r.append(...n),r}var S=a("div",{class:"overlay"}),O=a("section",{class:"card",role:"dialog","aria-modal":"true","aria-labelledby":"ez-title"}),pe=a("h1",{id:"ez-title"},"\u5132\u5B58\u81F3 ezdesign"),R=a("p",{class:"source"}),u=a("figure",{class:"preview",hidden:""}),U=a("span",{class:"chips"}),l=a("input",{type:"text",role:"combobox","aria-label":"\u6A19\u7C64","aria-autocomplete":"list","aria-expanded":"false","aria-controls":"ez-suggestions","data-testid":"ez-capture-tag-input",placeholder:j,autocomplete:"off",spellcheck:"false"}),ue=a("div",{class:"tags"},U,l),v=a("ul",{id:"ez-suggestions",role:"listbox","aria-label":"\u6A19\u7C64\u5EFA\u8B70","data-testid":"ez-capture-tag-suggestions",hidden:""}),L=a("textarea",{"aria-label":"\u70BA\u4EC0\u9EBC\u597D","data-testid":"ez-capture-note",rows:"3",placeholder:"\u53EF\u7559\u7A7A"}),P=a("p",{class:"status",role:"status","data-testid":"ez-capture-status"}),F=a("code"),k=a("button",{type:"button",class:"quiet"},"\u8907\u88FD"),Q=a("div",{class:"install","data-testid":"ez-capture-install",hidden:""},F,k),g=a("button",{type:"button",class:"grant",hidden:""}),Y=a("button",{type:"button","data-testid":"ez-capture-cancel"},"\u53D6\u6D88"),x=a("button",{type:"button",class:"primary","data-testid":"ez-capture-save"},"\u5132\u5B58"),$=a("header",{},pe,R);O.append(...A?[$,u]:[u,$],a("div",{class:"field"},a("span",{class:"label","aria-hidden":"true"},"\u6A19\u7C64"),a("div",{class:"combo"},ue,v)),a("div",{class:"field"},a("span",{class:"label","aria-hidden":"true"},"\u70BA\u4EC0\u9EBC\u597D"),L),P,Q,g,a("footer",{},Y,x));S.append(O);document.body.append(S);var _=null,i=W,d=[],q=!1,E=!1,z=null,w=null;function J(){if(z===null||w===null||w.nonce!==z)return;let{bitmap:e}=w;z=null,w=null,ne(e,e.width,e.height)}function f(){let e=i.locked.map(n=>a("span",{class:"chip locked",title:"\u5DF2\u6536\u85CF\u904E\u7684\u6A19\u7C64"},n)),t=i.chips.map((n,r)=>{let o=a("button",{type:"button",class:"chip","aria-label":`\u79FB\u9664\u6A19\u7C64 ${n}`},a("span",{},n),a("span",{class:"x","aria-hidden":"true"},"\xD7"));return o.addEventListener("click",()=>{i=p(i,{type:"remove",index:r},[]),f(),l.focus(),Z()}),o});U.replaceChildren(...e,...t),l.placeholder=e.length+t.length?"":j,l.value!==i.draft&&(l.value=i.draft),b()}function b(){let e=i.draft.trim()!==""&&d.length>0;v.hidden=!e,l.setAttribute("aria-expanded",String(e)),v.replaceChildren(...d.map((t,n)=>{let r=a("li",{role:"option",id:`ez-suggestion-${n}`,"aria-selected":String(n===i.highlighted)},a("span",{class:"name"},t.name),a("span",{class:"uses"},String(t.uses)));return n===i.highlighted&&(r.dataset.active=""),r.addEventListener("mousedown",o=>{o.preventDefault(),ee(t.name)}),r})),e&&i.highlighted!==null?l.setAttribute("aria-activedescendant",`ez-suggestion-${i.highlighted}`):l.removeAttribute("aria-activedescendant")}function Z(){if(i.draft.trim()===""){d=[],b();return}h({type:"suggest",prefix:i.draft.trim(),exclude:T(i)})}function ee(e){i=p(i,{type:"pick",name:e},[]),d=[],f(),l.focus()}var C=()=>d.map(e=>e.name);l.addEventListener("input",()=>{let e=i.chips.length;i=p(i,{type:"input",value:l.value},C()),i.chips.length!==e&&(d=[]),f(),Z()});l.addEventListener("keydown",e=>{e.isComposing||((e.key==="ArrowDown"||e.key==="ArrowUp")&&d.length?(e.preventDefault(),i=p(i,{type:"arrow",delta:e.key==="ArrowDown"?1:-1},C()),b()):e.key==="Enter"&&!(e.metaKey||e.ctrlKey)?(e.preventDefault(),i=p(i,{type:"enter"},C()),d=[],f()):e.key==="Tab"&&i.highlighted!==null&&!v.hidden?(e.preventDefault(),ee(d[i.highlighted].name)):e.key==="Backspace"&&l.value===""&&(i=p(i,{type:"backspace"},C()),f()))});l.addEventListener("blur",()=>{d=[],b()});function te(){E||!_||_.confirm!=="enabled"||(i.draft.trim()&&(i=p(i,{type:"enter"},[])),i={...i,highlighted:null},f(),h({type:"confirm",tags:T(i),note:L.value}))}function G(e){if(E)return;E=!0,document.documentElement.dataset.leaving=e,A||window.parent.postMessage({type:"ez-capture-leaving",how:e},"*");let t=matchMedia("(prefers-reduced-motion: reduce)").matches,n=()=>h({type:"closed"});t?setTimeout(n,120):O.addEventListener("animationend",n,{once:!0})}function H(){E||(h({type:"cancel"}),G("cancelled"))}x.addEventListener("click",te);Y.addEventListener("click",H);S.addEventListener("mousedown",e=>{e.target===S&&H()});document.addEventListener("keydown",e=>{e.key==="Escape"?(e.preventDefault(),v.hidden?H():(d=[],b())):e.key==="Enter"&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),te())});k.addEventListener("click",()=>{navigator.clipboard.writeText(F.textContent??"").then(()=>{k.textContent="\u5DF2\u8907\u88FD",setTimeout(()=>k.textContent="\u8907\u88FD",1500)})});g.addEventListener("click",()=>{let e=g.dataset.origin;e&&(g.disabled=!0,chrome.permissions.request({origins:[`${e}/*`]}).then(t=>h({type:t?"granted":"denied",origin:e}),()=>h({type:"denied",origin:e})))});function ge(e){switch(e.host.type){case"missing":return"\u9084\u6C92\u6709\u5B89\u88DD ezdesign host\uFF0C\u5728\u7D42\u7AEF\u6A5F\u57F7\u884C\u9019\u884C\u6307\u4EE4\u5F8C\u518D\u5B58\u4E00\u6B21\uFF1A";case"incompatible":return e.host.older==="host"?"ezdesign host \u7248\u672C\u592A\u820A\uFF0C\u66F4\u65B0\u5F8C\u518D\u5B58\u4E00\u6B21\uFF1A":"\u9019\u500B\u64F4\u5145\u529F\u80FD\u7248\u672C\u592A\u820A\uFF0C\u66F4\u65B0\u5F8C\u518D\u5B58\u4E00\u6B21\uFF1A";case"broken":return e.host.message;default:return null}}function he(e){_=e,R.textContent=e.page.title||e.page.url,R.title=e.page.url,e.duplicate&&!q&&(q=!0,i=p(i,{type:"lock",names:e.duplicate.tags},[]),L.value===""&&(L.value=e.duplicate.note),f());let t=ge(e),n=e.host.type==="missing"||e.host.type==="incompatible"?e.host.installCommand:null;Q.hidden=n===null,F.textContent=n??"";let r=e.staging.type==="needs-permission"?e.staging.origin:null;g.hidden=r===null,r&&(g.dataset.origin=r,g.textContent=`\u5141\u8A31\u8B80\u53D6 ${r}`,g.disabled=!1);let o=t??e.error??(e.staging.type==="failed"?e.staging.message:null)??(r?"\u9019\u5F35\u5716\u7247\u9700\u8981\u4F60\u5728\u9019\u500B\u7DB2\u7AD9\u7684\u767B\u5165\u72C0\u614B\u624D\u80FD\u8B80\u53D6\u3002":null)??(e.notice==="stream-link"?ce:e.notice==="too-large"?de:null)??(e.duplicate?"\u5DF2\u6536\u85CF\u904E":"");P.textContent=o,P.dataset.tone=t||e.error||e.staging.type==="failed"?"error":"info",x.disabled=e.confirm!=="enabled",x.textContent=e.confirm==="saving"?"\u5132\u5B58\u4E2D\u2026":e.confirm==="saved"?"\u5DF2\u5132\u5B58":"\u5132\u5B58",x.setAttribute("aria-busy",String(e.confirm==="saving")),e.confirm==="saved"&&G("saved")}var me="min(300px, max(96px, 100vh - 400px))",ye=1200;function V(e,t){e.style.aspectRatio=`${t.width} / ${t.height}`,e.style.width=`min(100%, ${t.width}px, calc(${me} * ${t.width/t.height}))`}function D(e){if(!e||u.childElementCount)return;let t=a("div",{class:"slot","aria-hidden":"true"});V(t,e),u.replaceChildren(t),u.hidden=!1}function ne(e,t,n,r){let o=r??{x:0,y:0,width:t,height:n},c=Math.min(1,ye/Math.max(o.width,o.height)),s=a("canvas",{"data-testid":"ez-capture-preview",role:"img","aria-label":"\u9810\u89BD"});V(s,o),s.width=Math.max(1,Math.round(o.width*c)),s.height=Math.max(1,Math.round(o.height*c));let m=s.getContext("2d");m.imageSmoothingQuality="high",m.drawImage(e,o.x,o.y,o.width,o.height,0,0,s.width,s.height),u.replaceChildren(s),u.hidden=!1,requestAnimationFrame(()=>h({type:"preview-shown",at:X()}))}async function fe(e){switch(e.type){case"bitmap":D(e.size),z=e.nonce,J();return;case"screenshot":{D(e.rect??e.viewport);let t=new Image;t.src=e.dataUrl,await t.decode();let n={width:t.naturalWidth,height:t.naturalHeight};ne(t,n.width,n.height,e.rect?B(e.rect,e.viewport,n):void 0);return}case"url":{D(e.size);let t=a("img",{"data-testid":"ez-capture-preview",alt:"\u9810\u89BD",src:e.src});e.size&&V(t,e.size),await t.decode().catch(()=>{}),u.replaceChildren(t),u.hidden=!1,requestAnimationFrame(()=>h({type:"preview-shown",at:X()}));return}case"none":return}}window.addEventListener("message",e=>{let t=e.data;e.source!==window.parent||t?.type!=="ez-capture-preview"||(w=t,J())});N.onMessage.addListener(e=>{let t=e;t.type==="preview"?fe(t.preview):t.type==="view"?he(t.view):t.type==="suggestions"&&t.prefix===i.draft.trim()&&(d=t.tags,i={...i,highlighted:null},b())});N.onDisconnect.addListener(()=>G("cancelled"));window.addEventListener("focus",()=>{!E&&(document.activeElement===document.body||document.activeElement===null)&&l.focus()});l.focus();})();