@petercjl/cloud-hug-style-transfer 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/capabilities.json +87 -1
- package/npm/arguments.mjs +3 -2
- package/npm/automatic-update.mjs +82 -0
- package/npm/cli.mjs +21 -1
- package/npm/integrity.json +2 -2
- package/npm/update.mjs +2 -2
- package/package.json +2 -2
- package/skills/cloud-hug-style-transfer/SKILL.md +1 -1
- package/skills/cloud-hug-style-transfer/references/maintenance.md +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,14 @@
|
|
|
20
20
|
|
|
21
21
|
> 请更新 npm 包 @petercjl/cloud-hug-style-transfer。
|
|
22
22
|
|
|
23
|
+
启用自动更新:
|
|
24
|
+
|
|
25
|
+
> 请为 cloud-hug-style-transfer 开启兼容稳定版本的自动更新。
|
|
26
|
+
|
|
27
|
+
关闭自动更新:
|
|
28
|
+
|
|
29
|
+
> 请关闭 cloud-hug-style-transfer 的自动更新与自动检测。
|
|
30
|
+
|
|
23
31
|
检查:
|
|
24
32
|
|
|
25
33
|
> 检查 cloud-hug-style-transfer 的安装与生图能力是否可用。
|
|
@@ -28,7 +36,7 @@
|
|
|
28
36
|
|
|
29
37
|
> 请诊断并修复 cloud-hug-style-transfer 的这次报错:粘贴报错内容。
|
|
30
38
|
|
|
31
|
-
安装、更新与检查由 Agent 执行包内 CLI。包的 `skill source --json` 提供规范来源;Agent 随后调用 `skill install --agent <当前宿主>`,支持 `--root`
|
|
39
|
+
安装、更新与检查由 Agent 执行包内 CLI。包的 `skill source --json` 提供规范来源;Agent 随后调用 `skill install --agent <当前宿主>`,支持 `--root` 指定实际技能目录。业务入口自动检测更新,默认每24小时一次、2秒超时,并返回提示。可让 Agent 启用自动安装模式;兼容稳定版会在任务开始前备份、更新并同步受管 Skill,离线或本地修改时保留当前安装。0.x 自动更新限同 minor,1.x 起限同 major;其他版本由 Agent 提示处理。显式更新使用 stable latest,备份旧包并同步已登记的受管 Skill;npm 已是最新版时仍修复旧 Skill 与兼容元数据,返回安装位置、来源、校验、备份和耗时。包升级失败时恢复旧包;离线保留当前安装。已有独立安装或本地修改将停止覆盖并报告。源码或上层工具管理的包由其拥有者更新。
|
|
32
40
|
|
|
33
41
|
兼容证据分别记录安装机制与生图效果。CI 覆盖 macOS、Windows、Linux 的包管理机制;宿主实际生成需使用各自账户独立验证。品牌与输入素材须具备相应使用权;公开 npm 分发不转让商标与素材的独立再分发权。
|
|
34
42
|
|
package/capabilities.json
CHANGED
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
"skill update",
|
|
18
18
|
"update check",
|
|
19
19
|
"update install",
|
|
20
|
-
"canvas row"
|
|
20
|
+
"canvas row",
|
|
21
|
+
"update policy",
|
|
22
|
+
"update auto"
|
|
21
23
|
],
|
|
22
24
|
"requirements": {
|
|
23
25
|
"node": ">=22",
|
|
@@ -120,6 +122,10 @@
|
|
|
120
122
|
"--root": {
|
|
121
123
|
"type": "string",
|
|
122
124
|
"description": "Skill parent directory; the CLI appends cloud-hug-style-transfer. Requires --agent on doctor and update."
|
|
125
|
+
},
|
|
126
|
+
"--no-auto-update": {
|
|
127
|
+
"type": "boolean",
|
|
128
|
+
"description": "Perform diagnosis without an automatic update preflight."
|
|
123
129
|
}
|
|
124
130
|
},
|
|
125
131
|
"sideEffects": "none"
|
|
@@ -289,6 +295,66 @@
|
|
|
289
295
|
}
|
|
290
296
|
},
|
|
291
297
|
"sideEffects": "none"
|
|
298
|
+
},
|
|
299
|
+
"update policy": {
|
|
300
|
+
"sideEffects": "local-write",
|
|
301
|
+
"options": {
|
|
302
|
+
"--json": {
|
|
303
|
+
"type": "boolean",
|
|
304
|
+
"description": "Return structured JSON."
|
|
305
|
+
},
|
|
306
|
+
"--help": {
|
|
307
|
+
"type": "boolean",
|
|
308
|
+
"description": "Read-only command help."
|
|
309
|
+
},
|
|
310
|
+
"--mode": {
|
|
311
|
+
"type": "string",
|
|
312
|
+
"enum": [
|
|
313
|
+
"off",
|
|
314
|
+
"notify",
|
|
315
|
+
"auto"
|
|
316
|
+
],
|
|
317
|
+
"description": "Persist detection/installation mode; auto grants standing consent for compatible stable updates."
|
|
318
|
+
},
|
|
319
|
+
"--interval-hours": {
|
|
320
|
+
"type": "string",
|
|
321
|
+
"description": "Detection interval from 1 to 168 hours; default 24."
|
|
322
|
+
},
|
|
323
|
+
"--yes": {
|
|
324
|
+
"type": "boolean",
|
|
325
|
+
"description": "Authorize a policy change."
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
"update auto": {
|
|
330
|
+
"sideEffects": "package-and-skill-update",
|
|
331
|
+
"options": {
|
|
332
|
+
"--json": {
|
|
333
|
+
"type": "boolean",
|
|
334
|
+
"description": "Return structured JSON."
|
|
335
|
+
},
|
|
336
|
+
"--help": {
|
|
337
|
+
"type": "boolean",
|
|
338
|
+
"description": "Read-only command help."
|
|
339
|
+
},
|
|
340
|
+
"--agent": {
|
|
341
|
+
"type": "string",
|
|
342
|
+
"enum": [
|
|
343
|
+
"codex",
|
|
344
|
+
"sealseek",
|
|
345
|
+
"workbuddy"
|
|
346
|
+
],
|
|
347
|
+
"description": "Target host; defaults to codex."
|
|
348
|
+
},
|
|
349
|
+
"--root": {
|
|
350
|
+
"type": "string",
|
|
351
|
+
"description": "Skill parent directory; the CLI appends cloud-hug-style-transfer. Requires --agent on doctor and update."
|
|
352
|
+
},
|
|
353
|
+
"--force": {
|
|
354
|
+
"type": "boolean",
|
|
355
|
+
"description": "Bypass the detection cache once; installation still follows policy."
|
|
356
|
+
}
|
|
357
|
+
}
|
|
292
358
|
}
|
|
293
359
|
},
|
|
294
360
|
"maintenance": {
|
|
@@ -314,5 +380,25 @@
|
|
|
314
380
|
],
|
|
315
381
|
"sameVersion": "reconcile managed Skills and metadata; verified no-op when current",
|
|
316
382
|
"metadata": "preserve customization; remove known unsupported api product with backup; unknown invalid schema requires reconciliation"
|
|
383
|
+
},
|
|
384
|
+
"automaticUpdates": {
|
|
385
|
+
"enabledByDefault": true,
|
|
386
|
+
"defaultMode": "notify",
|
|
387
|
+
"modes": [
|
|
388
|
+
"off",
|
|
389
|
+
"notify",
|
|
390
|
+
"auto"
|
|
391
|
+
],
|
|
392
|
+
"installation": "explicit-standing-authorization",
|
|
393
|
+
"trigger": "doctor at business-task entry; update auto",
|
|
394
|
+
"intervalHours": 24,
|
|
395
|
+
"timeoutMs": 2000,
|
|
396
|
+
"offlineRetryMs": 300000,
|
|
397
|
+
"channel": "latest",
|
|
398
|
+
"compatibility": "same major; same minor for 0.x; stable versions only",
|
|
399
|
+
"configuration": "update policy; installation-scoped state outside package",
|
|
400
|
+
"disable": "update policy --mode off --yes or CLOUD_HUG_AUTO_UPDATE=0",
|
|
401
|
+
"recovery": "existing update install backup, Skill sync, ownership/edit guards and rollback",
|
|
402
|
+
"continuation": "restart CLI after package replacement; reload canonical Skill when changed"
|
|
317
403
|
}
|
|
318
404
|
}
|
package/npm/arguments.mjs
CHANGED
|
@@ -17,12 +17,13 @@ export function parse(args) {
|
|
|
17
17
|
if(!spec||flag in options)throw fail('INVALID_ARGUMENT',`Unknown or duplicate option ${flag}; use ${command} --help.`);
|
|
18
18
|
const value=spec.type==='boolean'?true:tokens.shift();
|
|
19
19
|
if(value===undefined || (spec.type==='string'&&value.startsWith('-')))throw fail('INVALID_ARGUMENT',`${flag} needs a value.`);
|
|
20
|
-
if(spec.enum&&!spec.enum.includes(value))throw fail('INVALID_AGENT',`Choose ${spec.enum.join(', ')}.`);
|
|
20
|
+
if(spec.enum&&!spec.enum.includes(value))throw fail(flag==='--agent'?'INVALID_AGENT':'INVALID_ARGUMENT',`Choose ${spec.enum.join(', ')}.`);
|
|
21
21
|
options[flag]=value;
|
|
22
22
|
}
|
|
23
23
|
if(!options['--help']) {
|
|
24
24
|
for(const [flag,spec]of Object.entries(contract.options))if(spec.required&&!options[flag])throw fail(flag==='--yes'?'PERMISSION_REQUIRED':'INVALID_ARGUMENT',`${command} requires ${flag}.`);
|
|
25
|
-
if(['doctor','update check','update install'].includes(command)&&options['--root']&&!options['--agent'])throw fail('INVALID_ARGUMENT','--root requires an explicit --agent for this command.');
|
|
25
|
+
if(['doctor','update check','update install','update auto'].includes(command)&&options['--root']&&!options['--agent'])throw fail('INVALID_ARGUMENT','--root requires an explicit --agent for this command.');
|
|
26
26
|
}
|
|
27
|
+
if(command==='update policy'&&(options['--mode']||options['--interval-hours'])&&!options['--yes']&&!options['--help'])throw fail('PERMISSION_REQUIRED','Policy changes require --yes.');
|
|
27
28
|
return {command,options,contract};
|
|
28
29
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import crypto from 'node:crypto';
|
|
4
|
+
import { root, pkg, fail } from './runtime.mjs';
|
|
5
|
+
import { stateRoot, checkUpdate, installUpdate, globalPrefix, newer } from './update.mjs';
|
|
6
|
+
|
|
7
|
+
const defaultPolicy={mode:'notify',intervalHours:24,timeoutMs:2000,offlineRetryMs:300000};
|
|
8
|
+
export const automaticPaths=()=>{
|
|
9
|
+
const key=crypto.createHash('sha256').update(root).digest('hex');
|
|
10
|
+
const dir=path.join(stateRoot(),'automatic-update',key);
|
|
11
|
+
return {dir,policy:path.join(dir,'policy.json'),cache:path.join(dir,'cache.json'),lock:path.join(dir,'check.lock')};
|
|
12
|
+
};
|
|
13
|
+
function readOwned(file) {
|
|
14
|
+
let st;try{st=fs.lstatSync(file);}catch(e){if(e.code==='ENOENT')return null;throw e;}
|
|
15
|
+
if(!st.isFile()||st.isSymbolicLink())throw fail('AUTO_STATE_INVALID','Automatic update state must be a regular managed file.');
|
|
16
|
+
let value;try{value=JSON.parse(fs.readFileSync(file,'utf8'));}catch{throw fail('AUTO_STATE_INVALID','Invalid automatic update state; preserve and reconcile it.');}
|
|
17
|
+
if(value?.package!==pkg.name||value.schemaVersion!==1)throw fail('AUTO_STATE_INVALID','Automatic update state ownership mismatch.');
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
function saveOwned(file,value) {
|
|
21
|
+
const old=readOwned(file);fs.mkdirSync(path.dirname(file),{recursive:true});let backup=null;
|
|
22
|
+
if(old){backup=file+'.backup-'+crypto.randomUUID();fs.copyFileSync(file,backup,fs.constants.COPYFILE_EXCL);if(!fs.statSync(backup).size)throw fail('AUTO_STATE_INVALID','State backup is empty.');}
|
|
23
|
+
const temporary=file+'.tmp-'+crypto.randomUUID();
|
|
24
|
+
fs.writeFileSync(temporary,JSON.stringify({schemaVersion:1,package:pkg.name,...value},null,2)+'\n',{flag:'wx',mode:0o600});
|
|
25
|
+
try{fs.renameSync(temporary,file);}finally{if(fs.existsSync(temporary))fs.unlinkSync(temporary);}
|
|
26
|
+
return backup;
|
|
27
|
+
}
|
|
28
|
+
export function updatePolicy(changes) {
|
|
29
|
+
const file=automaticPaths().policy,stored=readOwned(file);
|
|
30
|
+
const policy={...defaultPolicy,...(stored?.policy||{}),...changes};
|
|
31
|
+
if(!['off','notify','auto'].includes(policy.mode)||!Number.isFinite(policy.intervalHours)||policy.intervalHours<1||policy.intervalHours>168||policy.timeoutMs!==2000||policy.offlineRetryMs!==300000)throw fail('AUTO_POLICY_INVALID','Choose off/notify/auto and an interval between 1 and 168 hours.');
|
|
32
|
+
const authorized=policy.mode==='auto'&&(changes?.mode==='auto'||stored?.authorizedAutomaticInstall===true);
|
|
33
|
+
if(policy.mode==='auto'&&!authorized)throw fail('AUTO_POLICY_INVALID','Automatic installation needs an explicitly authorized policy.');
|
|
34
|
+
let backup=null;if(changes)backup=saveOwned(file,{policy,authorizedAutomaticInstall:authorized,updatedAt:new Date().toISOString()});
|
|
35
|
+
return {ok:true,policy,policyFile:file,backup,changed:Boolean(changes),installationScope:root};
|
|
36
|
+
}
|
|
37
|
+
export function compatibleStable(available,current) {
|
|
38
|
+
if(!newer(available,current))return false;
|
|
39
|
+
const a=available.split('.').map(Number),b=current.split('.').map(Number);
|
|
40
|
+
return a[0]===b[0]&&(b[0]!==0||a[1]===b[1]);
|
|
41
|
+
}
|
|
42
|
+
function acquire(file) {
|
|
43
|
+
try{const fd=fs.openSync(file,'wx',0o600);fs.writeFileSync(fd,JSON.stringify({schemaVersion:1,package:pkg.name,pid:process.pid}));fs.closeSync(fd);return true;}
|
|
44
|
+
catch(e){if(e.code!=='EEXIST')throw e;}
|
|
45
|
+
const old=readOwned(file);
|
|
46
|
+
if(!Number.isSafeInteger(old?.pid)||old.pid<=0)throw fail('AUTO_STATE_INVALID','Invalid automatic-check lock; inspect it before retrying.');
|
|
47
|
+
try{process.kill(old.pid,0);return false;}catch(e){if(e.code!=='ESRCH')return false;}
|
|
48
|
+
fs.unlinkSync(file);return acquire(file);
|
|
49
|
+
}
|
|
50
|
+
export async function automaticUpdate(options={},services={}) {
|
|
51
|
+
const now=(services.now||Date.now)(),paths=automaticPaths();
|
|
52
|
+
const owner=services.owner|| (globalPrefix()?'global-npm':'source-or-parent');
|
|
53
|
+
if(process.env.CLOUD_HUG_AUTO_UPDATE==='0')return {ok:true,state:'disabled',reason:'environment',changed:false};
|
|
54
|
+
let policy;
|
|
55
|
+
try{policy=updatePolicy().policy;}catch(e){return {ok:true,state:'deferred',code:e.code,message:e.message,changed:false};}
|
|
56
|
+
if(policy.mode==='off')return {ok:true,state:'disabled',policy,changed:false};
|
|
57
|
+
if(owner!=='global-npm')return {ok:true,state:'owner-managed',owner,policy,changed:false};
|
|
58
|
+
let locked=false;
|
|
59
|
+
try {
|
|
60
|
+
fs.mkdirSync(paths.dir,{recursive:true});locked=acquire(paths.lock);
|
|
61
|
+
if(!locked)return {ok:true,state:'busy',policy,changed:false};
|
|
62
|
+
const cache=readOwned(paths.cache);
|
|
63
|
+
if(cache&&(!Number.isFinite(cache.checkedAt)||cache.checkedAt>now||!cache.response||typeof cache.response.ok!=='boolean'||(cache.response.ok&&!/^\d+\.\d+\.\d+$/.test(cache.response.available))))throw fail('AUTO_STATE_INVALID','Invalid cached registry evidence; preserve and reconcile it.');
|
|
64
|
+
const ttl=cache?.response.ok?policy.intervalHours*3600000:policy.offlineRetryMs;
|
|
65
|
+
const cached=Boolean(!options.force&&cache&&now-cache.checkedAt<ttl);
|
|
66
|
+
const check=cached?{...cache.response,current:pkg.version,updateAvailable:cache.response.ok&&newer(cache.response.available,pkg.version)}:await (services.check||checkUpdate)(services.registry||fetch,{timeoutMs:policy.timeoutMs});
|
|
67
|
+
if(!cached)saveOwned(paths.cache,{checkedAt:now,response:check});
|
|
68
|
+
const result={ok:true,policy,cached,check,changed:false};
|
|
69
|
+
if(!check.ok)return {...result,state:'offline',retryAfterMs:policy.offlineRetryMs};
|
|
70
|
+
if(policy.mode==='notify')return {...result,state:check.updateAvailable?'update-available':'up-to-date',action:check.updateAvailable?'update install --yes':null};
|
|
71
|
+
if(check.updateAvailable&&!compatibleStable(check.available,pkg.version))return {...result,state:'manual-update-required',reason:'compatibility-boundary',action:'update install --yes'};
|
|
72
|
+
try{
|
|
73
|
+
const receipt=(services.install||installUpdate)(check,{resolution:options.resolution});
|
|
74
|
+
if(!receipt?.ok||!receipt.verified)throw fail('UPDATE_VERIFY_FAILED','Automatic installer did not return verified evidence.');
|
|
75
|
+
return {...result,state:receipt.changed?'updated':'up-to-date',changed:receipt.changed,packageChanged:receipt.packageChanged,receipt,reloadSkill:receipt.changed};
|
|
76
|
+
}catch(e){
|
|
77
|
+
const safe=['UPDATE_BUSY','SKILL_BUSY','SKILL_EDITED','SKILL_UNMANAGED','SKILL_METADATA_INVALID','UPDATE_OWNER_REQUIRED','SKILL_UNMANAGED_FILE'].includes(e.code);
|
|
78
|
+
return {...result,ok:safe,state:safe?'deferred':'failed',code:e.code||'UPDATE_FAILED',message:e.message,backup:e.backup||null,details:e.details||null};
|
|
79
|
+
}
|
|
80
|
+
}catch(e){return {ok:true,state:'deferred',code:e.code||'AUTO_CHECK_FAILED',message:e.message,changed:false};}
|
|
81
|
+
finally{if(locked)fs.unlinkSync(paths.lock);}
|
|
82
|
+
}
|
package/npm/cli.mjs
CHANGED
|
@@ -6,11 +6,31 @@ import { source, resolveTarget, status, install, inventory, skillMetadata } from
|
|
|
6
6
|
import { checkUpdate, installUpdate, globalPrefix } from './update.mjs';
|
|
7
7
|
import { mediaDependency } from './media-dependency.mjs';
|
|
8
8
|
import { comparisonRow } from './canvas-layout.mjs';
|
|
9
|
+
import { spawnSync } from 'node:child_process';
|
|
10
|
+
import { automaticUpdate, updatePolicy } from './automatic-update.mjs';
|
|
9
11
|
import { parse, manifest } from './arguments.mjs';
|
|
10
12
|
const started=performance.now();
|
|
11
13
|
const out=value=>console.log(JSON.stringify(value,null,2));
|
|
12
14
|
try {
|
|
13
15
|
const {command,options:o,contract}=parse(process.argv.slice(2));
|
|
16
|
+
let automatic;
|
|
17
|
+
if(command==='doctor'&&!o['--help']&&!o['--no-auto-update']) {
|
|
18
|
+
automatic=await automaticUpdate({resolution:o['--agent']?resolveTarget(o['--agent'],o['--root']):undefined});
|
|
19
|
+
if(!automatic.ok){out({ok:false,code:automatic.code,automaticUpdate:automatic});process.exit(1);}
|
|
20
|
+
if(automatic.packageChanged){
|
|
21
|
+
const resumed=spawnSync(process.execPath,[path.join(root,'npm/cli.mjs'),...process.argv.slice(2)],{encoding:'utf8',timeout:30000,env:{...process.env,CLOUD_HUG_AUTO_UPDATE:'0'}});
|
|
22
|
+
let result;try{result=JSON.parse(resumed.stdout);}catch{throw fail('UPDATE_CONTINUATION_FAILED','New CLI returned an invalid result.');}
|
|
23
|
+
if(result.version!==automatic.receipt.version)throw fail('UPDATE_CONTINUATION_FAILED','Resumed CLI version differs from the verified update.');
|
|
24
|
+
out({...result,automaticUpdate:automatic});process.exit(resumed.status??1);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if(command==='update policy'&&!o['--help']){
|
|
28
|
+
const changes=o['--mode']||o['--interval-hours']?{...(o['--mode']?{mode:o['--mode']}:{}),...(o['--interval-hours']?{intervalHours:Number(o['--interval-hours'])}:{})}:undefined;
|
|
29
|
+
out(updatePolicy(changes));process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
if(command==='update auto'&&!o['--help']){
|
|
32
|
+
const result=await automaticUpdate({force:o['--force'],resolution:o['--agent']?resolveTarget(o['--agent'],o['--root']):undefined});out(result);process.exit(result.ok?0:1);
|
|
33
|
+
}
|
|
14
34
|
const identity={package:pkg.name,version:pkg.version,source,entry:{node:process.execPath,cli:path.join(root,'npm/cli.mjs')},owner:globalPrefix()?'global-npm':'source-or-parent'};
|
|
15
35
|
if(command==='help')out({ok:true,...identity,commands:manifest.commandContracts});
|
|
16
36
|
else if(o['--help'])out({ok:true,command,...contract});
|
|
@@ -29,7 +49,7 @@ try {
|
|
|
29
49
|
const result={ok:Number(process.versions.node.split('.')[0])>=22&&!problems.length&&metadata.valid&&media.ok,...identity,node:process.versions.node,files:Object.keys(files).length,integrity:{ok:!problems.length,problems},metadata:{valid:metadata.valid},installationReady:!problems.length&&metadata.valid,dependencies:{media},hostCapabilityDependencies:manifest.requirements.host_capability_skills,generation:{provider:'@petercjl/sealseek-media-cli',state:media.ok?'requires-live-preflight':'paused',runtimeTested:false,requiredFeatures:['image-inspection','multiple-reference-edit','local-reference-input','viewable-output']}};
|
|
30
50
|
if(!media.ok){result.code=media.code;result.action='pause';result.installPrompt=media.installPrompt;}
|
|
31
51
|
if(o['--agent']){result.resolution=resolveTarget(o['--agent'],o['--root']);result.installation={...status(result.resolution.target),record:undefined};if(!result.installation.current){result.ok=false;result.code||='SKILL_RECONCILIATION_REQUIRED';}}
|
|
32
|
-
out({...result,timingsMs:{total:performance.now()-started}});if(!result.ok)process.exitCode=1;
|
|
52
|
+
out({...result,automaticUpdate:automatic,timingsMs:{total:performance.now()-started}});if(!result.ok)process.exitCode=1;
|
|
33
53
|
} else if(command.startsWith('update ')) {
|
|
34
54
|
const resolution=o['--agent']?resolveTarget(o['--agent'],o['--root']):undefined;
|
|
35
55
|
const registryStarted=performance.now();const check=await checkUpdate();const registryMs=performance.now()-registryStarted;
|
package/npm/integrity.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"SKILL.md": "
|
|
2
|
+
"SKILL.md": "6b1f0babebe65a7d98f433f59c1782fedb7d0cc7ba5c9806e758b05857da9e08",
|
|
3
3
|
"adapters/codex.json": "bea8d59e6e0dafae7439693b33356825023516a6f52be02a64c976d7ce47ce76",
|
|
4
4
|
"adapters/sealseek.json": "04ef053762fd4cfc2309573ec87425afad14b2df85a1ea8ef0aa06d98fee1aee",
|
|
5
5
|
"adapters/workbuddy.json": "cd0a1d8d5b9fcebc5a709b8c7523911f41973adb95f71af2c0f644473a43a6b4",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"references/cases.md": "9d0d2d3d210e367411d5a291fc78ef6c9c733afd79c9da76451c580fcbcd4d3e",
|
|
63
63
|
"references/detail-final-20261016.md": "d9311413420db743466bbecfe98c31b9753eeead905472d69839afec9578c557",
|
|
64
64
|
"references/kv-layout-case-20261012.md": "845b287cfc57912aabedc48e558ca661cf86bf136304ea841030205a806ef06f",
|
|
65
|
-
"references/maintenance.md": "
|
|
65
|
+
"references/maintenance.md": "f17e3fa7c74d630db5238fd366b7cd3864ba630a4dbd6e243f21e1337d082f80",
|
|
66
66
|
"references/model-generation.json": "21daa2c3bf7d2000c7ddf52ab0b980cb7ee95d6c9d345602dc59ecbc128ec147",
|
|
67
67
|
"references/model.md": "c4da688e22e2ada3f251fe0dc87effcaf5cb6ed6176f9d9c20a9661414bffab5",
|
|
68
68
|
"references/page-patterns.md": "bdd6756e303c95e432d0239be27ec5af1faf75abf71594917f2e11467255a1b4",
|
package/npm/update.mjs
CHANGED
|
@@ -20,9 +20,9 @@ export function globalPrefix(location=root, platform=process.platform) {
|
|
|
20
20
|
if(platform==='win32') return path.dirname(modules);
|
|
21
21
|
return path.basename(path.dirname(modules))==='lib' ? path.dirname(path.dirname(modules)) : null;
|
|
22
22
|
}
|
|
23
|
-
export async function checkUpdate(registry=fetch) {
|
|
23
|
+
export async function checkUpdate(registry=fetch, options={}) {
|
|
24
24
|
try {
|
|
25
|
-
const r=await registry(`https://registry.npmjs.org/${encodeURIComponent(pkg.name)}/latest`,{signal:AbortSignal.timeout(8000)});
|
|
25
|
+
const r=await registry(`https://registry.npmjs.org/${encodeURIComponent(pkg.name)}/latest`,{signal:AbortSignal.timeout(options.timeoutMs||8000)});
|
|
26
26
|
if(!r.ok) throw Error('Registry unavailable');
|
|
27
27
|
const data=await r.json();
|
|
28
28
|
if(data.name!==pkg.name || !/^\d+\.\d+\.\d+$/.test(data.version)) throw Error('Invalid stable package');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@petercjl/cloud-hug-style-transfer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "抱抱云朵社品牌风格转换 Skill,支持 Codex、SealSeek 与 WorkBuddy",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
20
20
|
"test": "node --test test/*.test.mjs",
|
|
21
|
-
"check": "node --check npm/cli.mjs && node --check npm/skills.mjs && node --check npm/update.mjs && node --check npm/arguments.mjs && node --check npm/metadata.mjs && node --check npm/pack.mjs",
|
|
21
|
+
"check": "node --check npm/cli.mjs && node --check npm/skills.mjs && node --check npm/update.mjs && node --check npm/arguments.mjs && node --check npm/metadata.mjs && node --check npm/pack.mjs && node --check npm/automatic-update.mjs",
|
|
22
22
|
"prepack": "npm run check && npm test"
|
|
23
23
|
},
|
|
24
24
|
"publishConfig": {
|
|
@@ -17,7 +17,7 @@ description: 独立把旧详情页、产品摄影、主KV或SKU转换为抱抱
|
|
|
17
17
|
|
|
18
18
|
### 入口:必需依赖检查
|
|
19
19
|
|
|
20
|
-
**每次业务任务先检查依赖,通过后才进入第 1 节;规划任务也遵守此入口。** 执行 `cloud-hug-style-transfer doctor --json
|
|
20
|
+
**每次业务任务先检查依赖,通过后才进入第 1 节;规划任务也遵守此入口。** 执行 `cloud-hug-style-transfer doctor --json`;此入口按当前策略自动检测更新,读取 `automaticUpdate`。若其 `reloadSkill` 或 `changed` 为 true,先通过 `skill source --json` 重新加载当前规范 Skill 再继续;CLI 在包替换后会自动以新入口重跑本次检查。核对 `dependencies.media.ok`。检查支持当前 npm 安装树、PATH 安装及显式配置的 `CLOUD_HUG_MEDIA_ROOT`;返回的 `dependencies.media.invocation` 是经过包身份核验的 CLI 调用入口,使用宿主当前 Node 运行时,可用于 Agent 管理的运行时或套件组件。
|
|
21
21
|
|
|
22
22
|
未检测到 `@petercjl/sealseek-media-cli` 时返回 `DEPENDENCY_MISSING` 并**暂停整个任务**,保留输入和进度,给出最简安装提示词:“请安装 npm 包 @petercjl/sealseek-media-cli。”等待安装并重新检查通过后,从本入口恢复。版本低于 0.6.1、CLI 无法执行、规范 Skill 缺失或合同不兼容同样暂停,按诊断修复后复查。不得以宿主内置生图、其他提供商或继续规划代替依赖通过;本入口不自动安装软件或提交生成。
|
|
23
23
|
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
4. 检查回执 `verified`、`packageChanged`、各 `skills` 的 `current/version/target` 和备份。完全当前即 verified no-op。未知参数报错后读取该命令的 `--help --json`;避免猜其他工具的选项。
|
|
7
7
|
5. 本地编辑或非受管目录保留原文件并报告。失败时保留回执中的 backup;先检查包版本与受管状态,再按错误恢复,避免重复升级。元数据只迁移已知不受支持的字段值,自定义展示字段保留。
|
|
8
8
|
|
|
9
|
-
`doctor --json` 同时报告安装完整性与生图依赖;媒体依赖缺失不阻止独立的 `skill` 或 `update`
|
|
9
|
+
`doctor --json` 同时报告安装完整性与生图依赖;媒体依赖缺失不阻止独立的 `skill` 或 `update` 维护操作。业务入口 `doctor` 默认每24小时自动检测稳定 latest,2秒联网超时;默认模式 notify 返回更新提示。`update policy --mode auto --yes` 保存本安装的持续自动更新授权;off 关闭检测,`CLOUD_HUG_AUTO_UPDATE=0` 可临时关闭。auto 限兼容稳定版本(0.x 同 minor,1.x+ 同 major),复用备份、保护、受管 Skill 同步和恢复;离线退避5分钟,安全冲突延期,恢复状态不确定时停止。`update auto --force --json` 可立即按策略预检。策略和缓存放在包外;源码及上层工具管理的安装由拥有者维护。更新改变 Skill 后重新解析来源并加载当前说明。
|