@petercjl/taobao-ai-ops 0.4.6 → 0.4.7

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 CHANGED
@@ -101,3 +101,13 @@ Each component is an independent `@petercjl` npm package with its own canonical
101
101
  当前Agent通过 `dmp-product-report` 节点加载独立报告Skill,按需确认本店锚点。商品资料从橙色淘宝买家浏览器读取,DMP统计从蓝色商家电商浏览器读取;报告包含5张主图、店铺与页面指标,以及经营、推广、人群的四周期对比和8周趋势。子应用负责分析方法、独立模板、原始证据与最终校验。套件统一管理报告包和tbcli,保留独立包的升级边界。
102
102
 
103
103
  开发者入口:`taobao-ai-ops doctor --node dmp-product-report --json`、`taobao-ai-ops component run dmp-product-report ...`。
104
+
105
+ ## Skill 创建与维护
106
+
107
+ 独立组件 `@petercjl/portable-skill-creator` 提供Skill创建、更新、审查、测试与迁移方法,台账按用户业务流程图展示。当前Agent需要Node.js 22+、Python 3.10+及可动态加载的基础 `skill-creator`。套件管理独立包的安装和显式更新。
108
+
109
+ > 用 portable-skill-creator 创建一个Skill:【说明业务目标与流程】。
110
+
111
+ > 用 portable-skill-creator 优化这个Skill:【说明本次调整目标】。
112
+
113
+ 开发者入口:`taobao-ai-ops doctor --node portable-skill-creator --json`、`skill source --name portable-skill-creator --json` 与 `component run portable-skill-creator ...`。组件业务方法和资源由其独立包拥有;套件安装生成完整的独立运行副本。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@petercjl/taobao-ai-ops",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
4
4
  "description": "Independent Taobao AI operations SOP skills with a managed suite lifecycle",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,7 +9,8 @@ Input: an operator's goal, supplied workbooks or authorized data sources, option
9
9
 
10
10
  ## Main line
11
11
 
12
- 1. For a Taobao/Tmall item ID requiring operating, promotion and new/returning-customer analysis, select `dmp-product-report`; its method and standalone report contract are below. Resolve other requested business results with `taobao-ai-ops nodes list --json`. A category/monthly market question uses `category-research`; a search-result workbook and concrete research object use `product-research`. Existing product scope can enter product research directly. If no supported node covers the request, report the missing node.
12
+ 1. For creating, updating, reviewing, testing or porting an Agent Skill, select `portable-skill-creator` and follow its exact current main line. Resolve other business requests below.
13
+ For a Taobao/Tmall item ID requiring operating, promotion and new/returning-customer analysis, select `dmp-product-report`; its method and standalone report contract are below. Resolve other requested business results with `taobao-ai-ops nodes list --json`. A category/monthly market question uses `category-research`; a search-result workbook and concrete research object use `product-research`. Existing product scope can enter product research directly. If no supported node covers the request, report the missing node.
13
14
  An explicit request to use `procli` for project/task information, SOP progression, knowledge reuse or result publication uses `project-management`. Preserve this child's explicit-trigger contract; offering project integration does not authorize service reads or writes. For an authorized project-backed research request, resolve the project and read its task context and compiled Wiki before selecting the business research node. Preserve the target profile, exact project/task identities, observation windows, provenance and unresolved questions in the handoff.
14
15
  A supplied analysis or compatible ViewModel requiring a reusable HTML report uses `html-report`, whose exact Skill is `compact-commerce-ui`. It supplies reporting methods, not business conclusions; existing category/product outputs keep their own declared contracts.
15
16
  A Cloud Hug brand conversion request for supplied detail pages, photography, main KV or SKU images uses `cloud-hug-style-transfer`; its brand-production contract is below.
@@ -108,3 +109,13 @@ For explicit Boardmix file, media or object operations, select `boardmix-tools`.
108
109
  ### DMP配套版本迁移
109
110
 
110
111
  用户授权更新DMP报告和取数链路时,检查当前集合的blocked成员。若报告包0.2与tbcli 0.12因跨兼容版本而保留旧版,使用旧回执和 `collection prepare --accept-component-upgrades tbcli,dmp-product-report` 明确迁移这两个组件;其他不兼容组件维持原选择。核对候选DMP doctor及真实版本后再切换宿主入口。该操作按用户已授权的组件范围执行,不扩大到其他Agent或未选组件。
112
+
113
+ ## Skill 创建与维护
114
+
115
+ 用户要求创建、更新、审查、测试或迁移Skill时,选择 `portable-skill-creator` 节点。独立拥有包为 `@petercjl/portable-skill-creator`(0.2.1+);创建方法、策略来源、可移植性、业务流程台账和验证规则由该包维护。
116
+
117
+ 通过 `taobao-ai-ops skill source --name portable-skill-creator --json` 解析准确来源,完整读取当前SKILL.md。运行 `taobao-ai-ops doctor --node portable-skill-creator --json` 核对Node、Python及组件版本;当前Agent另外解析并完整读取系统提供的准确逻辑名 `skill-creator`,其缺失返回DEPENDENCY_MISSING,不由套件复制替代。宿主基础Creator解析是运行前置能力,doctor的本地成功不证明它存在。
118
+
119
+ 规范来源在组件npm包内,可使用 `taobao-ai-ops component run portable-skill-creator ...` 运行其实际CLI;本机受管安装副本带有自身 `.runtime`。输入是本次创建/维护意图、可选自然语言流程或脑图、既有资源与知识;输出是子Skill约定的规划、完整资源和验证证据。尊重子Skill当前的规划确认、隐私、独立回归授权和失败恢复规则;来源或能力缺失时停止相应阶段并保留原错误。完成后回到套件主线第4步保留成果、第6步交付。
120
+
121
+ 套件只登记并管理独立组件,普通业务调用保持已安装版本;用户显式更新时获取正式latest。台账按用户熟悉的业务流程图展示。基础Skill创建器仍由当前宿主动态提供。
@@ -0,0 +1,16 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import {spawnSync} from 'node:child_process';
4
+ import {fail} from './core.mjs';
5
+ // Only explicitly registered components delegate complete Skill/runtime materialization.
6
+ // The suite owns selection/transaction recovery; the component owns its installation contract.
7
+ export async function materializeComponentSkill(record,name,destination){
8
+ if(name!=='portable-skill-creator'||record.package!=='@petercjl/portable-skill-creator')throw fail('UNSUPPORTED_COMPONENT_INSTALLER',name);
9
+ destination=path.join(await fs.realpath(path.dirname(destination)),path.basename(destination));
10
+ try{const existing=await fs.readdir(destination);if(existing.length)throw fail('UNMANAGED_TARGET','Component destination must be absent or an empty suite stage');await fs.rmdir(destination);}catch(e){if(e.code!=='ENOENT')throw e;}
11
+ const result=spawnSync(process.execPath,[record.entry,'skill','install','--agent','suite-managed','--target',destination,'--json'],{encoding:'utf8',timeout:60000,env:{...process.env,PORTABLE_SKILL_UPDATE_CHECK:'0'}});
12
+ let data;try{data=JSON.parse(result.stdout);}catch{}
13
+ if(result.status!==0||data?.ok!==true||data.package!==record.package||data.name!==name||data.version!==record.version||data.current!==true||data.verification?.verified!==true)throw fail('COMPONENT_SKILL_INSTALL_FAILED',name,{child:data??result.stderr});
14
+ await fs.access(path.join(destination,'.runtime','bin','portable-skill-creator.mjs'));
15
+ return data;
16
+ }
package/src/runtime.mjs CHANGED
@@ -9,7 +9,7 @@ export function componentEnvironment(id,env=process.env,records=componentRecords
9
9
  let reportEntries={};
10
10
  if(id==='dmp-product-report'){if(!records.tbcli?.entry)throw fail('COMPONENT_NOT_INSTALLED','DMP report requires the registered tbcli component');reportEntries={DMP_REPORT_TBCLI_ENTRY:records.tbcli.entry,AGENT_PACKAGE_UPDATE_CHECK:'0'};}
11
11
  const canvasEntries=id==='competitor-visual-canvas'?Object.fromEntries([['tbcli','TBCLI_ENTRY'],['sealseek-media','SEALSEEK_MEDIA_ENTRY'],['boardmixcli','BOARDMIXCLI_ENTRY']].filter(([key])=>records[key]?.entry).map(([key,variable])=>[variable,records[key].entry])):{};
12
- return {...env,...canvasEntries,...reportEntries,BOARDMIXCLI_UPDATE_CHECK:'0',TBCLI_UPDATE_CHECK:'0',SYCMCLI_DISABLE_AUTO_UPDATE:'1',SEEDAUDIO_AUTO_UPDATE:'0',SEALSEEK_MEDIA_AUTO_UPDATE:'0',COMPETITOR_CANVAS_AUTO_UPDATE:'0',...(id==='cloud-hug-style-transfer'&&media&&!env.CLOUD_HUG_MEDIA_ROOT?{CLOUD_HUG_MEDIA_ROOT:media.root}:{})};
12
+ return {...env,...(id==='portable-skill-creator'?{PORTABLE_SKILL_UPDATE_CHECK:'0'}:{}),...canvasEntries,...reportEntries,BOARDMIXCLI_UPDATE_CHECK:'0',TBCLI_UPDATE_CHECK:'0',SYCMCLI_DISABLE_AUTO_UPDATE:'1',SEEDAUDIO_AUTO_UPDATE:'0',SEALSEEK_MEDIA_AUTO_UPDATE:'0',COMPETITOR_CANVAS_AUTO_UPDATE:'0',...(id==='cloud-hug-style-transfer'&&media&&!env.CLOUD_HUG_MEDIA_ROOT?{CLOUD_HUG_MEDIA_ROOT:media.root}:{})};
13
13
  }
14
14
  export function pythonEnvironment(env=process.env){
15
15
  return {...env,PYTHONUTF8:'1',PYTHONIOENCODING:'utf-8',PYTHONDONTWRITEBYTECODE:'1'};
@@ -108,6 +108,14 @@ export async function doctor(id,mode='excel'){
108
108
  checks.push({id:'dmp-report-capabilities',ok:result.status===0&&detail.ok===true&&detail.tbcliSnapshot===2&&detail.subjectMode==='target-only'&&detail.tbcliItemSummary===1,value:detail});
109
109
  }catch(e){checks.push({id:'dmp-report-dependencies',ok:false,code:e.code??'CAPABILITY_UNAVAILABLE',message:e.message});}
110
110
  }
111
+ if(n.component==='portable-skill-creator'){
112
+ const record=componentRecord(n.component);
113
+ const result=spawnSync(process.execPath,[record.entry,'doctor','--json'],{encoding:'utf8',timeout:30000,env:componentEnvironment(n.component)});
114
+ let detail;try{detail=JSON.parse(result.stdout||result.stderr);}catch{detail={ok:false,code:'COMPONENT_DOCTOR_FAILED'};}
115
+ const version=record.version?.split('.').map(Number);const supported=version?.length===3&&version.every(Number.isInteger)&&(version[0]>0||version[1]>2||version[1]===2&&version[2]>=1);
116
+ checks.push({id:'creator-version',ok:Boolean(supported),value:record.version,minimum:'0.2.1'});
117
+ checks.push({id:'creator-runtime',ok:result.status===0&&detail.ok===true&&detail.package===MANIFEST.components[n.component].package&&detail.version===record.version&&detail.python?.version?.length>=2,value:detail});
118
+ }
111
119
  if(n.component==='competitor-visual-canvas'){
112
120
  const record=componentRecord(n.component);
113
121
  const result=spawnSync(process.execPath,[record.entry,'doctor','--json'],{encoding:'utf8',timeout:30000,env:componentEnvironment(n.component)});
@@ -2,7 +2,8 @@ import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import os from 'node:os';
4
4
  import {randomUUID,createHash} from 'node:crypto';
5
- import {PACKAGE,source,nodeVersion,closure,json,stat,fileHashes,digest,fail,stateRoot} from './core.mjs';
5
+ import {materializeComponentSkill} from './component-skill-install.mjs';
6
+ import {MANIFEST,componentRecord,PACKAGE,source,nodeVersion,closure,json,stat,fileHashes,digest,fail,stateRoot} from './core.mjs';
6
7
 
7
8
  const OWNER='.taobao-ai-ops-managed.json';
8
9
  export function targetRoot(opts){
@@ -39,9 +40,11 @@ export async function status(root,n){
39
40
  return {...base,mode:'copy',managed:true,state:!same?'modified':meta.sourceDigest===base.sourceDigest?'current':'stale'};
40
41
  }
41
42
  async function makeCopy(dest,n){
42
- const files=await fileHashes(source(n));await fs.mkdir(dest,{recursive:true});
43
- for(const relative of Object.keys(files)){const d=path.join(dest,relative);await fs.mkdir(path.dirname(d),{recursive:true});await fs.copyFile(path.join(source(n),relative),d);}
44
- await fs.writeFile(path.join(dest,'.suite-install.json'),JSON.stringify({package:PACKAGE.name,skill:n.skill,version:nodeVersion(n),sourceDigest:digest(files),files}),{flag:'wx'});
43
+ const canonical=await fileHashes(source(n));
44
+ if(MANIFEST.components[n.component]?.skill_installation==='component-managed')await materializeComponentSkill(componentRecord(n.component),n.skill,dest);
45
+ else{await fs.mkdir(dest,{recursive:true});for(const relative of Object.keys(canonical)){const d=path.join(dest,relative);await fs.mkdir(path.dirname(d),{recursive:true});await fs.copyFile(path.join(source(n),relative),d);}}
46
+ const files=await fileHashes(dest);
47
+ await fs.writeFile(path.join(dest,'.suite-install.json'),JSON.stringify({package:PACKAGE.name,skill:n.skill,version:nodeVersion(n),sourceDigest:digest(canonical),files}),{flag:'wx'});
45
48
  await fs.writeFile(path.join(dest,'.install-meta.json'),JSON.stringify({title:n.skill,description:`Taobao AI operations: ${n.id}`}),{flag:'wx'});
46
49
  }
47
50
  async function restore(backup,dest,inPlace){
@@ -67,7 +70,7 @@ export async function install(opts,options={}){
67
70
  if(inPlace)await fs.cp(dest,backup,{recursive:true,errorOnExist:true,force:false});
68
71
  }
69
72
  const record={dest,backup:await stat(backup)?backup:null,inPlace};changed.push(record);
70
- const mode=item.mode==='copy'&&item.managed?'copy':(opts.mode||'auto')==='auto'?(process.platform==='win32'?'copy':'link'):opts.mode;
73
+ const mode=MANIFEST.components[n.component]?.skill_installation==='component-managed'?'copy':item.mode==='copy'&&item.managed?'copy':(opts.mode||'auto')==='auto'?(process.platform==='win32'?'copy':'link'):opts.mode;
71
74
  if(!['link','copy'].includes(mode))throw fail('USAGE','Mode must be auto, link or copy');
72
75
  if(inPlace){for(const e of await fs.readdir(dest))await fs.rm(path.join(dest,e),{recursive:true,force:true});}
73
76
  if(mode==='link')await fs.symlink(source(n),dest,process.platform==='win32'?'junction':'dir');else await makeCopy(dest,n);
@@ -1,6 +1,7 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import {spawn} from 'node:child_process';
4
+ import {materializeComponentSkill} from './component-skill-install.mjs';
4
5
  import {componentEnvironment} from './runtime.mjs';
5
6
  import {ROOT,PACKAGE,MANIFEST,fail,stat,fileHashes} from './core.mjs';
6
7
 
@@ -84,7 +85,7 @@ export async function collectionPrepare(opts,services={}){
84
85
  const installed=[],records={};
85
86
  async function copySkill(name,source,entry,member){
86
87
  if(installed.some(s=>s.name===name))throw fail('DUPLICATE_SKILL',name);
87
- const destination=path.join(skills,name);await fileHashes(source);await fs.cp(source,destination,{recursive:true,dereference:true});
88
+ const destination=path.join(skills,name);await fileHashes(source);if(MANIFEST.components[member.id]?.skill_installation==='component-managed')await materializeComponentSkill({entry,package:member.package,version:member.version},name,destination);else await fs.cp(source,destination,{recursive:true,dereference:true});
88
89
  installed.push({name,package:member.package,version:member.version,source,directory:destination,runtimeEntry:entry});
89
90
  }
90
91
  for(const member of plan.members){
@@ -18,7 +18,8 @@
18
18
  "competitor-visual-canvas",
19
19
  "cloud-hug-style-transfer",
20
20
  "boardmix-tools",
21
- "dmp-product-report"
21
+ "dmp-product-report",
22
+ "portable-skill-creator"
22
23
  ]
23
24
  },
24
25
  "nodes": [
@@ -50,7 +51,8 @@
50
51
  "1688-product-sourcing",
51
52
  "1688-opportunity-sourcing-research",
52
53
  "cloud-hug-style-transfer",
53
- "dmp-product-report"
54
+ "dmp-product-report",
55
+ "portable-skill-creator"
54
56
  ],
55
57
  "python_imports": [],
56
58
  "scripts": [],
@@ -307,6 +309,36 @@
307
309
  "tbcli": "0.12.0+; dmp snapshot version 2 target-only subject, automatic owned-item execution context and itemSummary version 1"
308
310
  },
309
311
  "contract_resolution": "Resolve current exact child Skill and CLI capabilities; preserve the selected merchant/buyer endpoints and returned data availability."
312
+ },
313
+ {
314
+ "id": "portable-skill-creator",
315
+ "skill": "portable-skill-creator",
316
+ "component": "portable-skill-creator",
317
+ "stage": "skill-authoring",
318
+ "method_version": "portable-skill-creator@0.2",
319
+ "requires_skills": [],
320
+ "python_imports": [],
321
+ "scripts": [],
322
+ "native_requirements": [
323
+ "agent.skill.base-creator.resolve"
324
+ ],
325
+ "input_contract": {
326
+ "required": [
327
+ "Skill creation, update, review or test intent"
328
+ ],
329
+ "optional": [
330
+ "business flow in natural language or diagram",
331
+ "existing Skill and knowledge sources"
332
+ ]
333
+ },
334
+ "output_contract": {
335
+ "result": "child-scoped design, complete Skill resources and verification evidence",
336
+ "state": "child owns business flow, strategies, privacy, run ledger and confirmation boundaries"
337
+ },
338
+ "required_component_contracts": {
339
+ "portable-skill-creator": "0.2.1+; business-flow ledger presentation; Node 22+ and Python 3.10+"
340
+ },
341
+ "contract_resolution": "Resolve the exact current child Skill and live CLI; dynamically load the host-provided base skill-creator, preserving the child confirmation and regression boundaries."
310
342
  }
311
343
  ],
312
344
  "tools": {
@@ -382,6 +414,11 @@
382
414
  "package": "@petercjl/dmp-product-report",
383
415
  "component": "dmp-product-report",
384
416
  "role": "DMP product performance, promotion and customer composition report with buyer-page product identity"
417
+ },
418
+ "portable-skill-creator": {
419
+ "package": "@petercjl/portable-skill-creator",
420
+ "component": "portable-skill-creator",
421
+ "role": "Skill creation, maintenance, portability QA and business-flow run ledger design"
385
422
  }
386
423
  },
387
424
  "targets": {
@@ -509,6 +546,14 @@
509
546
  "skills": [
510
547
  "dmp-product-report"
511
548
  ]
549
+ },
550
+ "portable-skill-creator": {
551
+ "package": "@petercjl/portable-skill-creator",
552
+ "bin": "portable-skill-creator",
553
+ "skills": [
554
+ "portable-skill-creator"
555
+ ],
556
+ "skill_installation": "component-managed"
512
557
  }
513
558
  }
514
559
  }