@surething/cockpit 1.0.232 → 1.0.234
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next-prod/BUILD_ID +1 -1
- package/.next-prod/build-manifest.json +3 -3
- package/.next-prod/prerender-manifest.json +3 -3
- package/.next-prod/react-loadable-manifest.json +7 -0
- package/.next-prod/server/app/_global-error/page.js.nft.json +1 -1
- package/.next-prod/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/_global-error.html +1 -1
- package/.next-prod/server/app/_global-error.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next-prod/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next-prod/server/app/_not-found/page.js.nft.json +1 -1
- package/.next-prod/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/_not-found.html +2 -2
- package/.next-prod/server/app/_not-found.rsc +3 -3
- package/.next-prod/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/.next-prod/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next-prod/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/.next-prod/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next-prod/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next-prod/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next-prod/server/app/api/agent/test/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/bash/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/codex/route.js +1 -1
- package/.next-prod/server/app/api/chat/codex/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/deepseek/route.js +1 -1
- package/.next-prod/server/app/api/chat/deepseek/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/kimi/route.js +1 -1
- package/.next-prod/server/app/api/chat/kimi/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/ollama/route.js +1 -1
- package/.next-prod/server/app/api/chat/ollama/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/pty-input/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/route.js +1 -1
- package/.next-prod/server/app/api/chat/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/chat/stop/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/claude-stats/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/commands/route.js +1 -1
- package/.next-prod/server/app/api/commands/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/comments/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/columns/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/connect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/disconnect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/export/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/query/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/db/schemas/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/dev/spans/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/extension/version/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/file/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/blame/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/clipboard/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/copy/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/delete/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/expanded/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/index/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/init/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/paste/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/read/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/readdir/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/recent/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/save/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/search/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/stat/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/files/text/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/branch-diff/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/branches/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/commit-diff/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/commits/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/current-branch/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/diff/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/discard/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/stage/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/status/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/unstage/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/git/worktree/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/global-state/route.js +1 -1
- package/.next-prod/server/app/api/global-state/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/health/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/jupyter/load/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/jupyter/save/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/jupyter/shutdown/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/lsp/definition/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/lsp/hover/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/lsp/references/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/lsp/status/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/lsp/warmup/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/columns/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/connect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/disconnect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/export/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/query/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/mysql/schemas/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/neo4j/connect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/neo4j/disconnect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/neo4j/query/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/neo4j/schema/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/note/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/ollama/models/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/ollama/start/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/open-cursor/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/open-vscode/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/pick-folder/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/pinned-sessions/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/project-settings/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/project-state/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/affected/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/callees/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/callers/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/coedit/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/context/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/file/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/file-functions/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/impact/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/related/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/risk/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projectGraph/search/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/projects/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/push/public-key/route.js +1 -1
- package/.next-prod/server/app/api/push/public-key/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/push/subscribe/route.js +1 -1
- package/.next-prod/server/app/api/push/subscribe/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/push/unsubscribe/route.js +1 -1
- package/.next-prod/server/app/api/push/unsubscribe/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/command/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/connect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/delete/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/disconnect/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/get/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/keys/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/redis/set/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/[id]/comments/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/[id]/replies/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/[id]/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/identify/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/order/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/share-info/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/review/users/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/scheduled-tasks/route.js +2 -2
- package/.next-prod/server/app/api/scheduled-tasks/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/services/config/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/services/scripts/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/session/[sessionId]/fork/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/session/[sessionId]/history/route.js +1 -1
- package/.next-prod/server/app/api/session/[sessionId]/history/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/session-by-path/route.js +1 -1
- package/.next-prod/server/app/api/session-by-path/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/sessions/projects/[encodedPath]/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/sessions/projects/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/sessions/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/settings/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/skills/[id]/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/skills/content/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/skills/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/terminal/aliases/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/terminal/autocomplete/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/terminal/bubble-order/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/terminal/env/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/terminal/history/route.js.nft.json +1 -1
- package/.next-prod/server/app/api/version/route.js.nft.json +1 -1
- package/.next-prod/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next-prod/server/app/m/page.js +2 -2
- package/.next-prod/server/app/m/page.js.nft.json +1 -1
- package/.next-prod/server/app/m/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/manifest.webmanifest/route.js.nft.json +1 -1
- package/.next-prod/server/app/page.js +1 -1
- package/.next-prod/server/app/page.js.nft.json +1 -1
- package/.next-prod/server/app/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/project/page.js +1 -1
- package/.next-prod/server/app/project/page.js.nft.json +1 -1
- package/.next-prod/server/app/project/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/app/review/[id]/page.js +2 -2
- package/.next-prod/server/app/review/[id]/page.js.nft.json +1 -1
- package/.next-prod/server/app/review/[id]/page_client-reference-manifest.js +1 -1
- package/.next-prod/server/chunks/3863.js +2 -2
- package/.next-prod/server/chunks/{3633.js → 5897.js} +373 -3
- package/.next-prod/server/chunks/9658.js +26 -26
- package/.next-prod/server/chunks/9830.js +1 -1
- package/.next-prod/server/middleware-build-manifest.js +1 -1
- package/.next-prod/server/middleware-react-loadable-manifest.js +1 -1
- package/.next-prod/server/pages/404.html +2 -2
- package/.next-prod/server/pages/500.html +1 -1
- package/.next-prod/server/server-reference-manifest.json +1 -1
- package/.next-prod/static/chunks/{2625-bc4748f0cd7db618.js → 1332-5e141e2acf28015a.js} +10 -10
- package/.next-prod/static/chunks/{217-4f8250a204080159.js → 217-e929c46c0bd599a7.js} +4 -4
- package/.next-prod/static/chunks/2502-fb8682bc7a61e04d.js +4 -0
- package/.next-prod/static/chunks/{2576-6420f6bad0b8ffb3.js → 2576-11e41242c7dd98f1.js} +2 -2
- package/.next-prod/static/chunks/4523.3f277a24fbcfde6d.js +138 -0
- package/.next-prod/static/chunks/9304-ddde9008da31b2ce.js +1 -0
- package/.next-prod/static/chunks/app/{layout-ac2f1f67df01cc89.js → layout-d202f8e0bcc90661.js} +1 -1
- package/.next-prod/static/chunks/app/m/page-71570a066f3eacf8.js +1 -0
- package/.next-prod/static/chunks/app/{page-1f0a6f49656a4c52.js → page-814b50b5b440249d.js} +1 -1
- package/.next-prod/static/chunks/app/project/{page-1f0a6f49656a4c52.js → page-814b50b5b440249d.js} +1 -1
- package/.next-prod/static/chunks/app/review/[id]/{page-39fa3a843adf617e.js → page-0c5d03d65758c7dc.js} +1 -1
- package/.next-prod/static/chunks/webpack-2c71a79c277961bc.js +1 -0
- package/.next-prod/static/css/fa7218e60ff464b5.css +1 -0
- package/.next-prod/trace +13 -13
- package/.next-prod/trace-build +1 -1
- package/bin/cock-browser.mjs +12 -9
- package/bin/cock.mjs +5 -5
- package/bin/postinstall.mjs +6 -6
- package/chrome-extension/automation.js +45 -40
- package/chrome-extension/background.js +70 -67
- package/chrome-extension/content.js +38 -38
- package/chrome-extension/disguise.js +4 -4
- package/chrome-extension/network-capture.js +16 -16
- package/dist/{chunk-VHFWPI2X.mjs → chunk-3M3JSZ5R.mjs} +28 -1
- package/dist/scheduledTasks.mjs +437 -3
- package/dist/wsServer.mjs +6 -31
- package/package.json +1 -1
- package/server.mjs +122 -26
- package/.next-prod/server/chunks/7003.js +0 -1
- package/.next-prod/static/chunks/471-504b396c8302f4f2.js +0 -4
- package/.next-prod/static/chunks/app/m/page-8b1af6f31b60c485.js +0 -1
- package/.next-prod/static/chunks/webpack-dbba7fa77ee1faa4.js +0 -1
- package/.next-prod/static/css/2a854655f4108c3a.css +0 -1
- /package/.next-prod/static/{Z3Em1C_kM7x4RjcH7E7v2 → JfwcuC5YjyhQWeQD-4Gvn}/_buildManifest.js +0 -0
- /package/.next-prod/static/{Z3Em1C_kM7x4RjcH7E7v2 → JfwcuC5YjyhQWeQD-4Gvn}/_ssgManifest.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";exports.id=3863,exports.ids=[3863],exports.modules={3863:(a,b,c)=>{c.d(b,{FP:()=>n,Yp:()=>m});var d=c(29021),e=c(21820),f=c(33873),g=c(55511),h=c(14566),i=c(79646);let j=a=>`'${a.replace(/'/g,"'\\''")}'`;function k(a){try{return(0,i.execSync)(`command -v ${a}`,{stdio:"ignore"}),!0}catch{return!1}}let l=new Map;function m(a,b){let c=l.get(a);if(!c)return!1;try{return c(b),!0}catch{return!1}}function n(a){let{cwd:b,prompt:c,onJsonlLine:m,onPtyData:n,onSubmit:o,onComplete:p,onQuestionEsc:q,
|
|
1
|
+
"use strict";exports.id=3863,exports.ids=[3863],exports.modules={3863:(a,b,c)=>{c.d(b,{FP:()=>n,Yp:()=>m});var d=c(29021),e=c(21820),f=c(33873),g=c(55511),h=c(14566),i=c(79646);let j=a=>`'${a.replace(/'/g,"'\\''")}'`;function k(a){try{return(0,i.execSync)(`command -v ${a}`,{stdio:"ignore"}),!0}catch{return!1}}let l=new Map;function m(a,b){let c=l.get(a);if(!c)return!1;try{return c(b),!0}catch{return!1}}function n(a){let{cwd:b,prompt:c,onJsonlLine:m,onPtyData:n,onSubmit:o,onComplete:p,onQuestionEsc:q,onTurnBoundary:r,signal:s,debug:t=!1,idleMs:u=3e3,timeoutMs:v,cols:w=80,rows:x=24,stuckMs:y=1e4,graceMs:z=3e4,onStuck:A}=a,B=a.sessionId||g.randomUUID(),C=!0===a.resume,D=f.join(function(a){let b=a;try{b=d.realpathSync(a)}catch{}let c=b.replace(/\//g,"-");return f.join(e.homedir(),".claude","projects",c)}(b),`${B}.jsonl`),E=function(){let a=f.join(e.tmpdir(),"cockpit-claude-hooks-v2.json"),b=JSON.stringify({hooks:{Stop:[{hooks:[{type:"command",command:"true"}]}],PreToolUse:[{matcher:"AskUserQuestion",hooks:[{type:"command",command:`echo ${j("Interactive questions cannot be displayed in this session. Do NOT retry this tool. Instead, present your questions as plain text in your reply - each question with its options and your recommended choice - then end your turn and wait for the user to answer in the next message.")} >&2; exit 2`}]}]}});try{if(d.readFileSync(a,"utf8")===b)return a}catch{}let c=`${a}.${process.pid}.tmp`;return d.writeFileSync(c,b),d.renameSync(c,a),a}(),F=(...a)=>{t&&console.error("[driver]",...a)},G={"image/png":"png","image/jpeg":"jpg","image/webp":"webp","image/gif":"gif"},H=[];for(let b of a.images||[])try{let a=f.join(e.tmpdir(),`cockpit-pty-img-${g.randomUUID()}.${G[b.media_type]||"png"}`);d.writeFileSync(a,Buffer.from(b.data,"base64")),H.push({path:a,isPng:"image/png"===b.media_type})}catch{}let I=H.length>0&&("darwin"===process.platform||"linux"===process.platform&&(k("wl-copy")||k("xclip"))),J=!I&&H.length?`${c}
|
|
2
2
|
|
|
3
3
|
[Attached image(s)]:
|
|
4
|
-
${
|
|
4
|
+
${H.map(a=>a.path).join("\n")}`:c,K=()=>{for(let a of H){try{d.unlinkSync(a.path)}catch{}try{d.unlinkSync(`${a.path}.png`)}catch{}}};return new Promise(a=>{let c,e=0;try{e=d.readFileSync(D,"utf8").split("\n").filter(Boolean).length}catch{}let f=C?["-r",B,"--dangerously-skip-permissions"]:["--session-id",B,"--dangerously-skip-permissions"];f.push("--settings",E);let g=`claude ${f.join(" ")}`;F("spawn:",g,"| jsonl:",D,"| baseline:",e);let t=process.env.SHELL||("darwin"===process.platform?"/bin/zsh":"/bin/bash");try{c=h.spawn(t,["--login","-c",g],{name:"xterm-256color",cols:w,rows:x,cwd:b,env:process.env})}catch(b){K(),a({sessionId:B,jsonlPath:D,completed:!1,completedVia:null,exitCode:null,crashed:!0,crashError:`spawn failed: ${String(b)}`,newLines:[]});return}l.set(B,a=>{try{c.write(a)}catch{}});let G="",L=Date.now(),M=!1,N=!1,O=0,P=!1,Q=!1,R=null,S=!1,T=!1,U=e,V=0,W=!1,X=!1,Y="",Z=!1,$=[],_=new Set,aa=!1;c.onData(a=>{if((G+=a).length>2e5&&(G=G.slice(-15e4)),L=Date.now(),n?.(a),!X&&/claude-code\/cli\.js:\d+:\d+/.test(G)){X=!0;let a=G.match(/Cannot read properties of [^\n\x1b]+/);F("CRASH detected:",Y=(a?a[0]:"claude-code internal crash").trim()),setTimeout(()=>{if(!T)try{c.kill()}catch{}},100),setTimeout(()=>{if(!T)try{c.kill("SIGKILL")}catch{}},1e3);return}!M&&/Bypass Permissions mode|Yes, I accept/i.test(G)&&(M=!0,F("accept menu → Down + Enter"),setTimeout(()=>c.write("\x1b[B"),400),setTimeout(()=>c.write("\r"),700)),!N&&P&&!Q&&/Enter to select.*Esc to cancel/i.test(G)&&(N=!0,F("AskUserQuestion UI detected → ESC + end turn"),q?.(),setTimeout(()=>{try{c.write("\x1b")}catch{}},300),setTimeout(()=>al("question_esc"),600))});let ab=0,ac=setInterval(()=>{if(P||T)return;let a=/bypass permissions on|shift\+tab/i.test(G);if(a&&!ab&&(ab=Date.now()),!a)return;let b=Date.now()-L>2200,c=Date.now()-ab>4e3;(b||c)&&ai()},300),ad=null,ae=setTimeout(()=>{P||T||(F(`not ready after ${y}ms → prompt for manual handling, grace ${z}ms`),A?.(),ad=setTimeout(()=>{if(!P&&!T){Z=!0,F("grace window elapsed and still not ready → kill");try{c.kill()}catch{}setTimeout(()=>{if(!T)try{c.kill("SIGKILL")}catch{}},1500)}},z))},y),af=()=>{clearTimeout(ae),ad&&clearTimeout(ad)},ag=null,ah=a=>new Promise(b=>{let c=Date.now(),d=setInterval(()=>{((G.match(/\[Image/g)||[]).length>=a||Date.now()-c>2500||T)&&(clearInterval(d),b())},100)});async function ai(){if(!P){if(P=!0,af(),I){ag=function(){try{if("darwin"===process.platform)return(0,i.execSync)("pbpaste",{encoding:"utf8"});if(k("wl-paste"))return(0,i.execSync)("wl-paste -n",{encoding:"utf8"});if(k("xclip"))return(0,i.execSync)("xclip -o -selection clipboard",{encoding:"utf8"})}catch{}return null}();for(let a=0;a<H.length&&!T;a++){if(!function(a,b){try{if("darwin"===process.platform){let c=a;return b||(c=`${a}.png`,(0,i.execSync)(`sips -s format png ${j(a)} --out ${j(c)}`,{stdio:"ignore"})),(0,i.execSync)(`osascript -e 'set the clipboard to (read (POSIX file ${JSON.stringify(c)}) as \xabclass PNGf\xbb)'`,{stdio:"ignore"}),!0}if("linux"===process.platform){if(k("wl-copy"))return(0,i.execSync)(`wl-copy --type image/png < ${j(a)}`,{shell:"/bin/bash",stdio:"ignore"}),!0;if(k("xclip"))return(0,i.execSync)(`xclip -selection clipboard -t image/png -i ${j(a)}`,{stdio:"ignore"}),!0}}catch{}return!1}(H[a].path,H[a].isPng)){F("clipboard set failed, skipping this image");continue}c.write("\x16"),await ah(a+1)}}F("paste prompt + Enter"+(H.length?` (${I?"clipboard":"path"} x${H.length} img)`:"")),c.write("\x1b[200~"+J+"\x1b[201~"),setTimeout(()=>c.write("\r"),250),null!=ag&&setTimeout(()=>{null!=ag&&function(a){try{if("darwin"===process.platform)return void(0,i.execSync)("pbcopy",{input:a});if(k("wl-copy"))return void(0,i.execSync)("wl-copy",{input:a});k("xclip")&&(0,i.execSync)("xclip -selection clipboard",{input:a})}catch{}}(ag)},800),o?.()}}let aj=setInterval(()=>{let a;try{a=d.readFileSync(D,"utf8")}catch{return}let b=a.split("\n").filter(Boolean);for(let a=U;a<b.length;a++){let c;try{c=JSON.parse(b[a])}catch{continue}$.push(c),V=Date.now(),function(a,b){let c=a.message?.content;if("user"===a.type&&Array.isArray(c)){for(let a of c)if("tool_result"===a.type&&"string"==typeof a.content){let c=a.content.match(/Command running in background with ID:\s*([A-Za-z0-9_-]+)/);c&&b.add(c[1])}}let d=a.origin;if("user"===a.type&&d?.kind==="task-notification"){let a="string"==typeof c?c:Array.isArray(c)?c.filter(a=>"text"===a.type).map(a=>a.text||"").join(""):"",d=a.match(/<task-id>([\s\S]*?)<\/task-id>/)?.[1]?.trim();d&&b.delete(d)}}(c,_),aa&&"assistant"===c.type&&(aa=!1,r?.("init")),m?.(c);let d=Array.isArray(c.message?.content)?c.message.content.map(a=>a.type).join(","):"";"assistant"===c.type&&d.includes("text")&&(W=!0),"assistant"===c.type&&Array.isArray(c.message?.content)&&(O+=c.message.content.filter(a=>"tool_use"===a.type&&"AskUserQuestion"===a.name).length)>=3&&!Q&&(F(`AskUserQuestion x${O} → break retry loop, end turn`),q?.(),al("question_loop")),"system"!==c.type||"stop_hook_summary"!==c.subtype||Q||(0===_.size?al("stop_hook_summary"):(F("stop_hook with background task(s) pending → staying resident",[..._]),r?.("result"),aa=!0))}U=b.length},150),ak=setInterval(()=>{!Q&&P&&W&&0===_.size&&Date.now()-V>u&&Date.now()-L>u&&al("idle")},300);function al(a){Q||(Q=!0,R=a,F("complete via",a),p?.(a),setTimeout(am,200))}function am(){if(!S){S=!0,F("exit: Ctrl+C x2 → SIGHUP → SIGKILL");try{c.write("\x03")}catch{}setTimeout(()=>{try{c.write("\x03")}catch{}},150),setTimeout(()=>{if(!T)try{c.kill()}catch{}},900),setTimeout(()=>{if(!T)try{c.kill("SIGKILL")}catch{}},2e3)}}let an=()=>{F("aborted → interrupt + guaranteed kill");try{c.write("\x1b"),c.write("\x03")}catch{}setTimeout(()=>{if(!T)try{c.kill()}catch{}},500),setTimeout(()=>{if(!T)try{c.kill("SIGKILL")}catch{}},1500)},ao=!1;s&&(s.aborted?an():(s.addEventListener("abort",an,{once:!0}),ao=!0));let ap=v?setTimeout(()=>{if(!T){F("TIMEOUT, killing");try{c.kill()}catch{}setTimeout(()=>{if(!T)try{c.kill("SIGKILL")}catch{}},1500)}},v):null;c.onExit(({exitCode:b})=>{T=!0,clearInterval(aj),clearInterval(ac),clearInterval(ak),af(),ap&&clearTimeout(ap),l.delete(B),K(),ao&&s?.removeEventListener("abort",an),F("exit code",b,"completed",Q,"via",R),a({sessionId:B,jsonlPath:D,completed:Q,completedVia:R,exitCode:b,crashed:X,crashError:Y,timedOut:Z,newLines:$})})})}}};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";exports.id=
|
|
1
|
+
"use strict";exports.id=5897,exports.ids=[5897],exports.modules={51035:(a,b,c)=>{c.d(b,{T:()=>n});var d=c(79830),e=c(82940),f=c(29021),g=c(33873),h=c(7939);let i={qa:{zh:`---
|
|
2
2
|
name: qa
|
|
3
3
|
description: "进入需求澄清讨论模式:理解并复述需求,对不明确点回问确认,只输出理解不改代码,遵循 KISS。"
|
|
4
4
|
---
|
|
@@ -953,11 +953,381 @@ Output confirmation: branch name, current HEAD commit, and sync status against o
|
|
|
953
953
|
|
|
954
954
|
- **Start from the latest**: always base on \`origin/main\`, never on a possibly stale local main.
|
|
955
955
|
- **Never lose changes**: confirm before any operation that could lose the user's work.
|
|
956
|
-
- **Verify right after cutting**: use rev-list to confirm actual sync; never assume.`,labelZh:"需求:",labelEn:"Intent: "}
|
|
956
|
+
- **Verify right after cutting**: use rev-list to confirm actual sync; never assume.`,labelZh:"需求:",labelEn:"Intent: "},skillify:{zh:`---
|
|
957
|
+
name: skillify
|
|
958
|
+
description: "把一次成功的处理流程 / 调研方式 / 工具组合 / 习惯,沉淀成一个可复用的 Skill。先分析历史会话有没有值得提取的知识,再提炼,最后按指定目录保存。"
|
|
959
|
+
argument-hint: "[放置目录] [要 skillify 的对象]"
|
|
960
|
+
---
|
|
961
|
+
|
|
962
|
+
# Skillify
|
|
963
|
+
|
|
964
|
+
把"刚刚做成的一件事"抽象成一个可复用 skill。这是一个 **分析 → 提取 → 保存** 的流程:
|
|
965
|
+
|
|
966
|
+
- **第一步永远是分析**:先判断历史会话 / 最近上下文里有没有值得沉淀成 skill 的知识。没有就直接说明并停下,不要硬凑。
|
|
967
|
+
- 放置目录等参数**只在最后保存那一步才需要**,不要一上来就追问目录。
|
|
968
|
+
|
|
969
|
+
适用于用户说:"把这个能力抽象成 skill""把刚刚的经验教训写成 skill""以后遇到类似情况自动这样做""skillify 一下""把这个工作流沉淀下来"。
|
|
970
|
+
|
|
971
|
+
核心目标:**把一次成功经验变成稳定流程,而不是把临时对话复制进 prompt。**
|
|
972
|
+
|
|
973
|
+
## 参数(都可选,保存时才用)
|
|
974
|
+
|
|
975
|
+
- **尾随文本**(\`目标:\`后面那段)= 想 skillify 的对象 / 线索;不给就从最近上下文里自动提炼。
|
|
976
|
+
- **放置目录 \`<skills-dir>\`** = skill 落盘位置,canonical source 写到 \`<skills-dir>/<slug>/SKILL.md\`。**到"保存"那一步才需要**;用户没给再问,不要在分析前就先问。
|
|
977
|
+
|
|
978
|
+
## 第 1 步:分析 —— 有没有值得沉淀的知识(扫描 → 闸门)
|
|
979
|
+
|
|
980
|
+
先回答"**该不该提**"。大多数候选死在这一步,而不是写作。
|
|
981
|
+
|
|
982
|
+
### 1a. 三相扫描:别漏掉隐形 skill
|
|
983
|
+
|
|
984
|
+
复盘刚做完的事,按三相各扫一遍,每相只问一句:**这里有没有一个"非显然的动作 / 判断"?**
|
|
985
|
+
|
|
986
|
+
| 相 | 扫什么 | 为什么容易被漏 |
|
|
987
|
+
|---|---|---|
|
|
988
|
+
| 发现 | 怎么定位 / 触发 / 诊断出真问题的?triage 用了哪个信号? | 没有可见交付物,最常被漏 |
|
|
989
|
+
| 决策 | 卡点上那个判断 call 凭什么?有没有可复用的判据? | 当成"凭经验",没意识到能固化 |
|
|
990
|
+
| 解决 | 执行骨架 / 工具组合 / 验证方式能复用吗? | 看得见、最容易只盯着它 |
|
|
991
|
+
|
|
992
|
+
扫描的目的是**铺开、防漏**:人天然只注意到"解决"类(有交付物),而"发现 / 决策"类——诊断和判断的 move——才是高价值又隐形的。
|
|
993
|
+
|
|
994
|
+
> 三相只用来**扫描候选**,不写进 SKILL.md 当章节。skill 正文要按**失败模式 / 调查动作**组织,不是按这三类分章。
|
|
995
|
+
|
|
996
|
+
### 1b. 真闸门:别滥提
|
|
997
|
+
|
|
998
|
+
对每个候选,四问全过才提:
|
|
999
|
+
|
|
1000
|
+
- [ ] **会复发**:以后还会遇到同类场景?(一次性的 → 写备忘就够,别提 skill)
|
|
1001
|
+
- [ ] **非显然**:里面有一个"不查就不会"的动作 / 判断?(显然的事不值得固化)
|
|
1002
|
+
- [ ] **代价**:做错 / 漏做的代价大?
|
|
1003
|
+
- [ ] **稳定**:流程稳定,不绑死在这次的临时上下文 / 数据上?
|
|
1004
|
+
|
|
1005
|
+
缺"非显然"或"会复发"基本就别提了。
|
|
1006
|
+
|
|
1007
|
+
**如果分析下来没有任何候选通过闸门 → 直接告诉用户"这次不值得做 skill"并说明原因,然后停下。** 不要为了产出而硬凑,也不要在这一步追问放置目录。
|
|
1008
|
+
|
|
1009
|
+
### 1c. 合并还是拆分:边界问题
|
|
1010
|
+
|
|
1011
|
+
如果一个场景里发现 / 决策 / 解决三相**都**蹦出了候选,要决定它们装进**一个闭环 skill**还是**拆成几个组合**。按三问判:
|
|
1012
|
+
|
|
1013
|
+
- **会单独调用某一相吗?** 会 → 拆;永远从头进 → 倾向合并。
|
|
1014
|
+
- **价值在相内还是相间交接?** 在交接(上游期望状态 / 契约要带给下游做验证)→ 合并;每相自成动作、交接没信息量 → 可拆。
|
|
1015
|
+
- **合并会让一个执行单元同时扛正交的失败模式吗?** 会(如静态广度 vs 动态推演深度)→ 拆。
|
|
1016
|
+
- **这一相在别的问题里也先跑吗?** 扇出 ≥2~3 → 拆成可复用的 leaf。
|
|
1017
|
+
|
|
1018
|
+
**第三态(两者都要)**:闭环不能断、但相又要深度 / 复用时,用 **orchestrator + leaf** —— 一个闭环 skill 持有契约与验证,把正交的相委派给可复用的 sub-skill。
|
|
1019
|
+
|
|
1020
|
+
**默认先按一个闭环 skill 写**。只有出现实测信号(某相被第二个场景复用,或注意力被摊薄导致深度不够)才拆。
|
|
1021
|
+
|
|
1022
|
+
### 1d. 归类:决定怎么写,不决定提不提
|
|
1023
|
+
|
|
1024
|
+
| 类型 | 示例 | Skill 重点 |
|
|
1025
|
+
|---|---|---|
|
|
1026
|
+
| 调研流程 | 拉数据源 → 建时间线 → 定位问题 | 证据源、步骤、输出模板 |
|
|
1027
|
+
| Debug 流程 | 复现 bug → 红测 → 修复 → 验证 | 不变量、测试、验收 |
|
|
1028
|
+
| 工具组合 | 多个日志/监控/分析工具串联 | 查询顺序、关联 ID |
|
|
1029
|
+
| 习惯/规范 | 目录结构、命名、放置规则 | 路径规则、命名规则 |
|
|
1030
|
+
| 写作模板 | issue / PR / 复盘报告 | 结构、语气、禁止项 |
|
|
1031
|
+
|
|
1032
|
+
**不要**把一次性的细节写进 skill(某个临时 session、某次具体 chat 的完整内容、临时验证码等)。
|
|
1033
|
+
|
|
1034
|
+
## 第 2 步:提取 —— 提炼稳定原则并起草
|
|
1035
|
+
|
|
1036
|
+
> 若 1c 判定为拆分或 orchestrator + leaf,对**每个**要落地的 skill 各跑一遍第 2 步(各自独立目录)。
|
|
1037
|
+
|
|
1038
|
+
### 2a. 提炼稳定原则
|
|
1039
|
+
|
|
1040
|
+
把经验拆成:
|
|
1041
|
+
|
|
1042
|
+
- **触发条件**:什么时候应该用这个 skill
|
|
1043
|
+
- **输入**:用户可能提供什么,缺什么时问什么
|
|
1044
|
+
- **证据源 / 工具**:需要查哪些 source、文件、CLI、日志
|
|
1045
|
+
- **步骤**:稳定可复用的执行顺序
|
|
1046
|
+
- **输出**:最终给用户什么,或创建什么 artifact
|
|
1047
|
+
- **边界**:不要做什么,什么情况下停止/询问
|
|
1048
|
+
- **验证**:如何确认 skill 有效
|
|
1049
|
+
|
|
1050
|
+
写原则,不写流水账。
|
|
1051
|
+
|
|
1052
|
+
### 2b. 选 slug
|
|
1053
|
+
|
|
1054
|
+
Slug 要 lowercase、alphanumeric + hyphen、简短清楚、动词/任务或主题导向。起草前先 \`ls <skills-dir>/\` 看一眼,避免冲突并与已有命名风格一致(保存目录已知时)。
|
|
1055
|
+
|
|
1056
|
+
### 2c. 起草 SKILL.md
|
|
1057
|
+
|
|
1058
|
+
Frontmatter 用通用兼容格式:
|
|
1059
|
+
|
|
1060
|
+
\`\`\`yaml
|
|
1061
|
+
---
|
|
1062
|
+
name: <slug-or-display-name>
|
|
1063
|
+
description: "一句话说明 skill 做什么,什么时候用。"
|
|
1064
|
+
argument-hint: "<可选,描述参数>"
|
|
1065
|
+
alwaysAllow: ["Bash"] # 可选
|
|
1066
|
+
requiredSources: [] # 可选
|
|
1067
|
+
---
|
|
1068
|
+
\`\`\`
|
|
1069
|
+
|
|
1070
|
+
正文建议结构:
|
|
1071
|
+
|
|
1072
|
+
\`\`\`markdown
|
|
1073
|
+
# <Skill Name>
|
|
1074
|
+
|
|
1075
|
+
一句话目标。
|
|
1076
|
+
|
|
1077
|
+
## 触发场景 / 适用情况
|
|
1078
|
+
## 前置条件
|
|
1079
|
+
## 工作流 / 步骤
|
|
1080
|
+
## 输出格式
|
|
1081
|
+
## 边界和禁止项
|
|
1082
|
+
## 验证
|
|
1083
|
+
## 示例
|
|
1084
|
+
\`\`\`
|
|
1085
|
+
|
|
1086
|
+
写作风格:
|
|
1087
|
+
|
|
1088
|
+
- 指令要可执行,不要泛泛而谈。
|
|
1089
|
+
- 不要写"已读后告诉用户规则已加载"这类无效行为。
|
|
1090
|
+
- 动作型 skill 默认继续执行;只有缺关键参数才提问。
|
|
1091
|
+
- 保留具体路径、API、命令示例,但抹掉一次性敏感数据。
|
|
1092
|
+
- 语言与目标 skill 库的现有风格保持一致。
|
|
1093
|
+
|
|
1094
|
+
### 2d. icon(可选)
|
|
1095
|
+
|
|
1096
|
+
- 优先 3D / color / 拟物风格,和现有视觉一致。
|
|
1097
|
+
- 推荐来源:Microsoft Fluent Emoji。
|
|
1098
|
+
- 文件名必须是 \`icon.svg\`/\`icon.png\`/\`icon.jpg\`/\`icon.jpeg\`,放在 skill 目录里。
|
|
1099
|
+
- 不允许临时手绘 SVG 顶替,除非用户明确要求。找不到就先问,别硬凑。
|
|
1100
|
+
|
|
1101
|
+
## 第 3 步:保存 —— 落盘到指定目录
|
|
1102
|
+
|
|
1103
|
+
**到这一步才需要放置目录 \`<skills-dir>\`:**
|
|
1104
|
+
|
|
1105
|
+
- 用户一开始就给了目录 → 直接用。
|
|
1106
|
+
- 没给 → **现在**问用户放哪,不要擅自选目录。
|
|
1107
|
+
|
|
1108
|
+
约定:
|
|
1109
|
+
|
|
1110
|
+
1. **一个 skill 一个目录**:\`<skills-dir>/<slug>/SKILL.md\`(必需)+ 可选 \`icon.svg\` / \`references/\` / 辅助脚本。
|
|
1111
|
+
2. **不要在 \`<skills-dir>\` 根目录直接放 SKILL.md**:即使单文件 skill 也要建自己的子目录。
|
|
1112
|
+
3. **辅助数据/脚本放同目录**,让 skill 自包含。
|
|
1113
|
+
|
|
1114
|
+
\`\`\`bash
|
|
1115
|
+
mkdir -p <skills-dir>/<slug>
|
|
1116
|
+
# 写 SKILL.md 到该目录;如有辅助脚本/数据一并放入
|
|
1117
|
+
\`\`\`
|
|
1118
|
+
|
|
1119
|
+
\`<skills-dir>/\` 就是 canonical source,不需要再 symlink 到别处。
|
|
1120
|
+
|
|
1121
|
+
## 验证
|
|
1122
|
+
|
|
1123
|
+
\`\`\`bash
|
|
1124
|
+
ls -la <skills-dir>/<slug>/
|
|
1125
|
+
\`\`\`
|
|
1126
|
+
|
|
1127
|
+
- [ ] \`SKILL.md\` 存在且 frontmatter 合法,\`name\`/\`description\` 非空
|
|
1128
|
+
- [ ] 正文非空、有可执行步骤
|
|
1129
|
+
- [ ] 没有写死敏感信息(账号、token、临时 session id)
|
|
1130
|
+
- [ ] slug 不与已有冲突
|
|
1131
|
+
|
|
1132
|
+
## 输出给用户
|
|
1133
|
+
|
|
1134
|
+
完成后简短说明:skill slug、源文件路径(\`<skills-dir>/<slug>/SKILL.md\`)、是否加了 icon、是否含辅助脚本/数据。不要粘贴完整 SKILL.md,除非用户要求。
|
|
1135
|
+
|
|
1136
|
+
## 关键原则
|
|
1137
|
+
|
|
1138
|
+
- 用户要的是**能力沉淀**,不是复制对话。
|
|
1139
|
+
- **分析在先**:先判断有没有值得沉淀的知识,没有就停,别硬凑,也别提前问目录。
|
|
1140
|
+
- canonical source 永远在 \`<skills-dir>/<slug>/\`,单文件 skill 也要有自己的子目录。
|
|
1141
|
+
- 区分事实 / 推测 / 待确认,不要过早把解决方案写死。`,en:`---
|
|
1142
|
+
name: skillify
|
|
1143
|
+
description: "Distil a successful workflow / investigation / tool-combo / habit into a reusable Skill. First analyze whether the conversation holds knowledge worth extracting, then distil it, and finally save it to the given directory."
|
|
1144
|
+
argument-hint: "[placement directory] [target to skillify]"
|
|
1145
|
+
---
|
|
1146
|
+
|
|
1147
|
+
# Skillify
|
|
1148
|
+
|
|
1149
|
+
Abstract "the thing you just pulled off" into a reusable skill. This is an **analyze → extract → save** flow:
|
|
1150
|
+
|
|
1151
|
+
- **Step 1 is always analysis**: first decide whether the conversation / recent context holds knowledge worth distilling into a skill. If not, say so and stop — never force it.
|
|
1152
|
+
- The placement directory and other args are **only needed at the final save step** — do NOT front-load a "where should it go?" question.
|
|
1153
|
+
|
|
1154
|
+
Applies when the user says: "abstract this into a skill", "write up what we just learned as a skill", "do this automatically next time", "skillify this", "capture this workflow".
|
|
1155
|
+
|
|
1156
|
+
Core goal: **turn a one-time success into a stable procedure, not copy a transient chat into a prompt.**
|
|
1157
|
+
|
|
1158
|
+
## Arguments (all optional; used only at save time)
|
|
1159
|
+
|
|
1160
|
+
- **Trailing text** (after \`Target: \`) = the object / lead to skillify; if omitted, distil from recent context.
|
|
1161
|
+
- **Placement directory \`<skills-dir>\`** = where the skill lands; the canonical source goes to \`<skills-dir>/<slug>/SKILL.md\`. **Only needed at the "save" step**; ask only if the user hasn't provided it — never ask before analysis.
|
|
1162
|
+
|
|
1163
|
+
## Step 1: Analyze — is there knowledge worth capturing (scan → gate)
|
|
1164
|
+
|
|
1165
|
+
Answer "**should this even be extracted**" first. Most candidates die here, not in the writing.
|
|
1166
|
+
|
|
1167
|
+
### 1a. Three-phase scan: don't miss invisible skills
|
|
1168
|
+
|
|
1169
|
+
Review what you just did, sweeping each phase once, asking one question per phase: **is there a "non-obvious action / judgement" here?**
|
|
1170
|
+
|
|
1171
|
+
| Phase | What to scan | Why it's easily missed |
|
|
1172
|
+
|---|---|---|
|
|
1173
|
+
| Discovery | How did you locate / trigger / diagnose the real problem? Which signal did triage use? | No visible deliverable — most often missed |
|
|
1174
|
+
| Decision | What justified the judgement call at the sticking point? Any reusable criterion? | Treated as "intuition", not realized it can be codified |
|
|
1175
|
+
| Solution | Is the execution skeleton / tool-combo / verification reusable? | Visible — easiest to fixate on |
|
|
1176
|
+
|
|
1177
|
+
The scan is about **breadth, anti-omission**: people naturally notice only "solution" (it has deliverables), while "discovery / decision" — the diagnosing and judging moves — are high-value yet invisible.
|
|
1178
|
+
|
|
1179
|
+
> The three phases are only for **scanning candidates**, not chapters in SKILL.md. The body should be organized by **failure mode / investigation action**, not by these three categories.
|
|
1180
|
+
|
|
1181
|
+
### 1b. The real gate: don't over-extract
|
|
1182
|
+
|
|
1183
|
+
For each candidate, all four must pass:
|
|
1184
|
+
|
|
1185
|
+
- [ ] **Recurs**: will you hit this kind of scenario again? (One-off → a note is enough, no skill.)
|
|
1186
|
+
- [ ] **Non-obvious**: is there an action / judgement you "wouldn't know without looking it up"? (Obvious things aren't worth codifying.)
|
|
1187
|
+
- [ ] **Cost**: is the cost of getting it wrong / missing it high?
|
|
1188
|
+
- [ ] **Stable**: is the procedure stable, not bound to this session's transient context / data?
|
|
1189
|
+
|
|
1190
|
+
Missing "non-obvious" or "recurs" → basically drop it.
|
|
1191
|
+
|
|
1192
|
+
**If nothing passes the gate → tell the user "not worth a skill this time", explain why, and stop.** Do not force a deliverable, and do not ask for a placement directory at this step.
|
|
1193
|
+
|
|
1194
|
+
### 1c. Merge or split: the boundary question
|
|
1195
|
+
|
|
1196
|
+
If discovery / decision / solution **all** surface candidates in one scenario, decide whether they go into **one closed-loop skill** or **split into a combination**:
|
|
1197
|
+
|
|
1198
|
+
- **Will any single phase be invoked alone?** Yes → split; always entered from the top → lean merge.
|
|
1199
|
+
- **Is the value inside a phase or at the handoff?** At the handoff (upstream expected-state / contract must reach downstream for verification) → merge; each phase self-contained, handoff carries no info → splittable.
|
|
1200
|
+
- **Would merging make one unit carry orthogonal failure modes?** Yes (e.g. static breadth vs dynamic-reasoning depth) → split.
|
|
1201
|
+
- **Does this phase run first in other problems too?** Fan-out ≥2–3 → split into a reusable leaf.
|
|
1202
|
+
|
|
1203
|
+
**Third state (need both)**: when the loop must stay intact but a phase needs depth / reuse, use **orchestrator + leaf** — one closed-loop skill holds the contract and verification, delegating orthogonal phases to reusable sub-skills.
|
|
1204
|
+
|
|
1205
|
+
**Default to one closed-loop skill.** Split only on a real signal (a phase reused by a second scenario, or attention spread too thin for depth).
|
|
1206
|
+
|
|
1207
|
+
### 1d. Classify: decides how to write, not whether to extract
|
|
1208
|
+
|
|
1209
|
+
| Type | Example | Skill focus |
|
|
1210
|
+
|---|---|---|
|
|
1211
|
+
| Investigation | pull sources → build timeline → locate issue | evidence sources, steps, output template |
|
|
1212
|
+
| Debug | reproduce → red test → fix → verify | invariants, tests, acceptance |
|
|
1213
|
+
| Tool-combo | chain multiple log/monitor/analysis tools | query order, correlation IDs |
|
|
1214
|
+
| Habit/convention | directory structure, naming, placement | path rules, naming rules |
|
|
1215
|
+
| Writing template | issue / PR / retro report | structure, tone, prohibitions |
|
|
1216
|
+
|
|
1217
|
+
**Do NOT** write one-off details into the skill (a transient session, a full specific chat, a temporary verification code, etc.).
|
|
1218
|
+
|
|
1219
|
+
## Step 2: Extract — distil stable principles and draft
|
|
1220
|
+
|
|
1221
|
+
> If 1c decided on a split or orchestrator + leaf, run Step 2 once for **each** skill to land (each its own directory).
|
|
1222
|
+
|
|
1223
|
+
### 2a. Distil stable principles
|
|
1224
|
+
|
|
1225
|
+
Break the experience into:
|
|
1226
|
+
|
|
1227
|
+
- **Trigger**: when this skill should be used
|
|
1228
|
+
- **Input**: what the user might provide, what to ask when it's missing
|
|
1229
|
+
- **Evidence sources / tools**: which sources, files, CLIs, logs to check
|
|
1230
|
+
- **Steps**: the stable, reusable execution order
|
|
1231
|
+
- **Output**: what to hand the user, or what artifact to create
|
|
1232
|
+
- **Boundaries**: what NOT to do, when to stop / ask
|
|
1233
|
+
- **Verification**: how to confirm the skill worked
|
|
1234
|
+
|
|
1235
|
+
Write principles, not a play-by-play.
|
|
1236
|
+
|
|
1237
|
+
### 2b. Choose a slug
|
|
1238
|
+
|
|
1239
|
+
Slug: lowercase, alphanumeric + hyphen, short and clear, verb/task- or topic-oriented. Before drafting, \`ls <skills-dir>/\` to avoid collisions and match existing naming style (when the save dir is known).
|
|
1240
|
+
|
|
1241
|
+
### 2c. Draft SKILL.md
|
|
1242
|
+
|
|
1243
|
+
Use the generic-compatible frontmatter:
|
|
1244
|
+
|
|
1245
|
+
\`\`\`yaml
|
|
1246
|
+
---
|
|
1247
|
+
name: <slug-or-display-name>
|
|
1248
|
+
description: "One line: what the skill does and when to use it."
|
|
1249
|
+
argument-hint: "<optional, describe args>"
|
|
1250
|
+
alwaysAllow: ["Bash"] # optional
|
|
1251
|
+
requiredSources: [] # optional
|
|
1252
|
+
---
|
|
1253
|
+
\`\`\`
|
|
1254
|
+
|
|
1255
|
+
Suggested body structure:
|
|
1256
|
+
|
|
1257
|
+
\`\`\`markdown
|
|
1258
|
+
# <Skill Name>
|
|
1259
|
+
|
|
1260
|
+
One-line goal.
|
|
1261
|
+
|
|
1262
|
+
## Trigger / When to use
|
|
1263
|
+
## Preconditions
|
|
1264
|
+
## Workflow / Steps
|
|
1265
|
+
## Output format
|
|
1266
|
+
## Boundaries & prohibitions
|
|
1267
|
+
## Verification
|
|
1268
|
+
## Examples
|
|
1269
|
+
\`\`\`
|
|
1270
|
+
|
|
1271
|
+
Writing style:
|
|
1272
|
+
|
|
1273
|
+
- Instructions must be executable, not vague.
|
|
1274
|
+
- Don't write dead behaviors like "after reading, tell the user the rules are loaded".
|
|
1275
|
+
- Action-type skills proceed by default; ask only when a key argument is missing.
|
|
1276
|
+
- Keep concrete paths, APIs, command examples, but scrub one-off sensitive data.
|
|
1277
|
+
- Match the existing style of the target skill library.
|
|
1278
|
+
|
|
1279
|
+
### 2d. Icon (optional)
|
|
1280
|
+
|
|
1281
|
+
- Prefer 3D / color / skeuomorphic style, consistent with existing visuals.
|
|
1282
|
+
- Recommended source: Microsoft Fluent Emoji.
|
|
1283
|
+
- Filename must be \`icon.svg\`/\`icon.png\`/\`icon.jpg\`/\`icon.jpeg\`, placed in the skill directory.
|
|
1284
|
+
- No ad-hoc hand-drawn SVG stand-ins unless the user explicitly asks. If none fits, ask first — don't force one.
|
|
1285
|
+
|
|
1286
|
+
## Step 3: Save — land it in the given directory
|
|
1287
|
+
|
|
1288
|
+
**Only now do you need the placement directory \`<skills-dir>\`:**
|
|
1289
|
+
|
|
1290
|
+
- User gave a directory up front → use it directly.
|
|
1291
|
+
- Not given → ask **now** where to put it; do not pick a directory on your own.
|
|
1292
|
+
|
|
1293
|
+
Conventions:
|
|
1294
|
+
|
|
1295
|
+
1. **One skill, one directory**: \`<skills-dir>/<slug>/SKILL.md\` (required) + optional \`icon.svg\` / \`references/\` / helper scripts.
|
|
1296
|
+
2. **Never drop a SKILL.md directly in the \`<skills-dir>\` root**: even a single-file skill gets its own subdirectory.
|
|
1297
|
+
3. **Keep helper data/scripts in the same directory** so the skill is self-contained.
|
|
1298
|
+
|
|
1299
|
+
\`\`\`bash
|
|
1300
|
+
mkdir -p <skills-dir>/<slug>
|
|
1301
|
+
# write SKILL.md into that dir; include helper scripts/data if any
|
|
1302
|
+
\`\`\`
|
|
1303
|
+
|
|
1304
|
+
\`<skills-dir>/\` IS the canonical source — no need to symlink elsewhere.
|
|
1305
|
+
|
|
1306
|
+
## Verification
|
|
1307
|
+
|
|
1308
|
+
\`\`\`bash
|
|
1309
|
+
ls -la <skills-dir>/<slug>/
|
|
1310
|
+
\`\`\`
|
|
1311
|
+
|
|
1312
|
+
- [ ] \`SKILL.md\` exists, frontmatter valid, \`name\`/\`description\` non-empty
|
|
1313
|
+
- [ ] Body non-empty with executable steps
|
|
1314
|
+
- [ ] No hardcoded sensitive info (accounts, tokens, transient session ids)
|
|
1315
|
+
- [ ] Slug doesn't collide with an existing one
|
|
1316
|
+
|
|
1317
|
+
## Output to the user
|
|
1318
|
+
|
|
1319
|
+
When done, briefly report: skill slug, source path (\`<skills-dir>/<slug>/SKILL.md\`), whether an icon was added, whether helper scripts/data are included. Don't paste the full SKILL.md unless asked.
|
|
1320
|
+
|
|
1321
|
+
## Key principles
|
|
1322
|
+
|
|
1323
|
+
- The user wants a **captured capability**, not a copied conversation.
|
|
1324
|
+
- **Analysis first**: decide whether there's knowledge worth capturing; if not, stop — don't force it, and don't ask for a directory early.
|
|
1325
|
+
- The canonical source always lives in \`<skills-dir>/<slug>/\`; even a single-file skill gets its own subdirectory.
|
|
1326
|
+
- Distinguish fact / hypothesis / to-be-confirmed; don't hardcode a solution too early.`,labelZh:"目标:",labelEn:"Target: "}},j=(0,g.join)(h.Kv,"skills"),k=/^\s*([/@])([a-zA-Z][a-zA-Z0-9-]*)(?:\s+|$)/;function l(a,b){return"zh"===b?`请读取这个 skill 文件:
|
|
957
1327
|
${a}`:`Please read this skill file:
|
|
958
1328
|
${a}`}var m=c(55511);async function n(a,b,c){let{sessionId:n,images:o,cwd:p,language:q}=b;if(n&&(0,e.yQ)(n))return{ok:!1,status:409,error:"session is already running"};let r=b.prompt,s="string"==typeof r?function(a,b="en"){let c,d=b.startsWith("zh")?"zh":"en",e=function(){try{let a=JSON.parse((0,f.readFileSync)(h.GB,"utf-8")),b=[];for(let c of a.skills??[]){let a=function(a){try{let b=(0,f.readFileSync)(a,"utf-8"),c=b.match(/^---\r?\n([\s\S]*?)\r?\n---/),d=(c?c[1]:b).match(/^name:\s*["']?([^"'\n]+?)["']?\s*$/m);return d?d[1].trim():null}catch{return null}}(c.path);a&&b.push({name:a,path:c.path})}return b}catch{return[]}}(),m=a.split("\n"),n=[];if(m.forEach((a,b)=>{let c,d=a.match(k);d&&(i[c=d[2]]||e.some(a=>a.name===c))&&n.push({i:b,marker:d[1],cmd:d[2],rest:a.slice(d[0].length)})}),0===n.length)return a;let o=m.slice(0,n[0].i).join("\n").trim(),p=n.map((a,b)=>{let c=b+1<n.length?n[b+1].i:m.length,d=[a.rest,...m.slice(a.i+1,c)].join("\n").trim();return{marker:a.marker,cmd:a.cmd,body:d}}),q=(c=process.env.COCKPIT_PORT||process.env.PORT||"3457",`http://localhost:${c}`),r=p.map(a=>(function(a,b,c,d){var e,h;let k,m=d.find(b=>b.name===a.cmd);if(m)return{marker:a.marker,body:a.body,label:"",pointer:l(m.path,b)};let n=i[a.cmd],o=n[b].replaceAll("{{BASE_URL}}",c),p=function(a,b){try{let c=(0,g.join)(j,a);(0,f.mkdirSync)(c,{recursive:!0});let d=(0,g.join)(c,"SKILL.md");return(0,f.writeFileSync)(d,b.endsWith("\n")?b:`${b}
|
|
959
1329
|
`,"utf-8"),d}catch{return null}}(a.cmd,o),q=p?l(p,b):o;return{marker:a.marker,body:a.body,label:(e=n,(k="zh"===(h=b)?e.labelZh:e.labelEn)||("zh"===h?"问题:":"Question: ")),pointer:q}})(a,d,q,e));if(1===r.length&&"/"===r[0].marker&&!o){let a=r[0];return a.body?`${a.pointer}
|
|
960
1330
|
|
|
961
1331
|
${a.label}${a.body}`:a.pointer}let s=r.map((a,b)=>{var c,e;let f=(c=b+1,e=a.marker,"zh"===d?"@"===e?`步骤 ${c}(用 subagent 执行):`:`步骤 ${c}(主会话执行):`:"@"===e?`Step ${c} (run in a subagent): `:`Step ${c} (run in the main session): `),g=a.body?`
|
|
962
1332
|
${a.label}${a.body}`:"";return`${f}
|
|
963
|
-
${a.pointer}${g}`}),t=[];return o&&t.push(o),t.push("zh"===d?"请按以下步骤依次完成:":"Complete the following steps in order:",s.join("\n\n")),t.join("\n\n")}(r,q):r;if(!(s&&"string"==typeof s||o&&o.length>0))return{ok:!1,status:400,error:"Missing prompt or images"};if(a.preflight){let c=await a.preflight(b);if(!c.ok)return c}let t="string"==typeof s?s:void 0,u=new AbortController,v="string"==typeof b.runId&&b.runId||(0,m.randomUUID)(),w=n||v,x=n,y=!1;if(!(0,e.AD)(w,p||"",t))return{ok:!1,status:409,error:"run already active"};(0,e.e5)(w,()=>{y=!0,u.abort()}),p&&n&&(0,d.CS)(p,n,"loading",void 0,t).catch(()=>{});let z={prompt:t,images:o,cwd:p||"",sessionId:n,params:b,signal:u.signal,emit(a){y||(0,e.ah)(w,a)},rekey(a){a&&((0,e.GS)(w,a),w=a,x=a,p&&(0,d.CS)(p,a,"loading",void 0,t).catch(()=>{}))},currentKey:()=>w};return(async()=>{try{await a.runner.run(z)}catch(b){if(u.signal.aborted){y=!0,(0,e.HS)(w,"idle");return}if(console.error(`[engine:${a.name}] run error:`,b),z.emit({type:"error",error:b instanceof Error?b.message:String(b)}),(0,e.HS)(w,"error"),y=!0,p&&x){let a=await (0,d.Pn)(p,x).catch(()=>void 0);await (0,d.CS)(p,x,"unread",a).catch(()=>{})}return}if(p&&x){let b=await (a.runner.resolveTitle?a.runner.resolveTitle(p,x).catch(()=>void 0):Promise.resolve(void 0));await (0,d.CS)(p,x,"unread",b).catch(()=>{})}y=!0,(0,e.HS)(w,"idle")})(),{ok:!0,runKey:w,sessionId:x??null}}}};
|
|
1333
|
+
${a.pointer}${g}`}),t=[];return o&&t.push(o),t.push("zh"===d?"请按以下步骤依次完成:":"Complete the following steps in order:",s.join("\n\n")),t.join("\n\n")}(r,q):r;if(!(s&&"string"==typeof s||o&&o.length>0))return{ok:!1,status:400,error:"Missing prompt or images"};if(a.preflight){let c=await a.preflight(b);if(!c.ok)return c}let t="string"==typeof s?s:void 0,u=new AbortController,v="string"==typeof b.runId&&b.runId||(0,m.randomUUID)(),w=n||v,x=n,y=!1;if(!(0,e.AD)(w,p||"",t))return{ok:!1,status:409,error:"run already active"};(0,e.e5)(w,()=>{y=!0,u.abort()}),p&&n&&(0,d.CS)(p,n,"loading",void 0,t).catch(()=>{});let z={prompt:t,images:o,cwd:p||"",sessionId:n,params:b,signal:u.signal,emit(a){y||(0,e.ah)(w,a)},rekey(a){a&&((0,e.GS)(w,a),w=a,x=a,p&&(0,d.CS)(p,a,"loading",void 0,t).catch(()=>{}))},currentKey:()=>w};return(async()=>{try{await a.runner.run(z)}catch(b){if(u.signal.aborted){y=!0,(0,e.HS)(w,"idle");return}if(console.error(`[engine:${a.name}] run error:`,b),z.emit({type:"error",error:b instanceof Error?b.message:String(b)}),(0,e.HS)(w,"error"),y=!0,p&&x){let a=await (0,d.Pn)(p,x).catch(()=>void 0);await (0,d.CS)(p,x,"unread",a).catch(()=>{})}return}if(p&&x){let b=await (a.runner.resolveTitle?a.runner.resolveTitle(p,x).catch(()=>void 0):Promise.resolve(void 0));await (0,d.CS)(p,x,"unread",b).catch(()=>{})}y=!0,(0,e.HS)(w,"idle")})(),{ok:!0,runKey:w,sessionId:x??null}}},72891:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{OZ:()=>o,RL:()=>n,k9:()=>p,ok:()=>l});var e=c(37625),f=c(52693),g=c(18412),h=c(89705),i=c(94506),j=c(770),k=a([i]);i=(k.then?(await k)():k)[0];let l=(a,b=200)=>new Response(JSON.stringify(a),{status:b,headers:{"content-type":"application/json"}}),m=a=>{let b=e.od(a);if(f.Ru(b)){let a=b.value,c=(0,j.Sh)(a);return new Response(JSON.stringify({error:(a=>{let b=a.message;if("string"==typeof b&&b.length>0)return b;let c=a.cause;if(c instanceof Error&&c.message.length>0)return c.message;switch(a._tag){case"ValidationError":return`Invalid ${a.field}: ${a.reason}`;case"NotFoundError":return`${a.resource} not found: ${a.id}`;case"PermissionError":return`Permission denied: ${a.action} on ${a.resource}`;case"DBError":return`${a.db} ${a.op} failed`;case"FSError":return`${a.op} ${a.path} failed`;case"WSError":return`${a.proto} ${a.kind} failed`;case"AgentError":return`${a.provider} ${a.kind} failed`;default:return a._tag}})(a),tag:a._tag}),{status:c,headers:{"content-type":"application/json"}})}return console.error("[handler] uncaught defect:\n"+e.j9(a)),new Response(JSON.stringify({error:"Internal Server Error",tag:"InternalError"}),{status:500,headers:{"content-type":"application/json"}})},n=a=>async b=>{let c=await i.s9.runPromiseExit(a(b));return g.YW(c,{onFailure:a=>m(a),onSuccess:a=>a})},o=a=>async(b,c)=>{let d=await c.params,e=await i.s9.runPromiseExit(a(b,d));return g.YW(e,{onFailure:a=>m(a),onSuccess:a=>a})},p=a=>h.$mh({try:()=>a.json(),catch:()=>new j.yI({field:"body",reason:"invalid JSON"})});d()}catch(a){d(a)}})},82940:(a,b,c)=>{c.d(b,{AD:()=>j,GS:()=>l,HS:()=>m,Si:()=>n,Y6:()=>r,ah:()=>k,e5:()=>q,j$:()=>p,yQ:()=>o});let d=globalThis,e=d.__cockpitRunRegistry??(d.__cockpitRunRegistry=new Map),f=d.__cockpitRunListeners??(d.__cockpitRunListeners=new Map),g=d.__cockpitRunSeqByKey??(d.__cockpitRunSeqByKey=new Map);function h(a){for(let b of(a.seq+=1,a.keys))g.set(b,a.seq);return a.seq}function i(a,b){for(let c of a.keys){let a=f.get(c);if(a)for(let c of a)try{c(b)}catch{}}}function j(a,b,c){let d=e.get(a);if(d?.status==="running")return!1;let f=d?.seq??g.get(a)??0;if(d)for(let a of(d.evictTimer&&clearTimeout(d.evictTimer),d.keys))e.delete(a);return e.set(a,{keys:new Set([a]),cwd:b,status:"running",seq:f,events:[],updatedAt:Date.now()}),c&&k(a,{type:"user",_human:!0,message:{role:"user",content:c}}),!0}function k(a,b){let c=e.get(a);c&&"running"===c.status&&(h(c),c.events.push(b),c.updatedAt=Date.now(),i(c,{seq:c.seq,message:b}))}function l(a,b){let c=e.get(a);c&&(c.sessionId=b,a!==b&&(c.keys.add(b),e.set(b,c)))}function m(a,b="idle"){let c=e.get(a);if(c){if("running"!==c.status){"idle"===c.status&&"error"===b&&(c.status="error");return}c.status=b,c.updatedAt=Date.now(),h(c),i(c,{seq:c.seq,message:{type:"run-ended",status:b}}),c.evictTimer&&clearTimeout(c.evictTimer),c.evictTimer=setTimeout(()=>{for(let a of c.keys)e.delete(a)},6e4)}}function n(a){let b=e.get(a);return b?{status:b.status,seq:b.seq,events:b.events.slice()}:null}function o(a){return e.get(a)?.status==="running"}function p(a){return e.get(a)?.sessionId??null}function q(a,b){let c=e.get(a);c&&(c.abort=b)}function r(a){let b=e.get(a);if(!b)return!1;try{b.abort?.()}catch{}return k(a,{type:"result",subtype:"stopped"}),m(a,"idle"),!0}}};
|