best-geo-test 0.3.2 → 0.3.3

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.
@@ -3168,6 +3168,37 @@
3168
3168
  "additionalProperties": false
3169
3169
  }
3170
3170
  },
3171
+ {
3172
+ "name": "prompts.duplicate",
3173
+ "mode": "write",
3174
+ "guide": "article",
3175
+ "requiresPlan": true,
3176
+ "description": "把一条提示词复制到一家或多家公司,每家得到一份独立副本。**系统内置的公共模板要改,就先用这条复制一份**——公共模板本身改不了。副本和原来同名,要区分就复制完再用 prompts.update 改名。不扣费。",
3177
+ "inputSchema": {
3178
+ "type": "object",
3179
+ "properties": {
3180
+ "promptId": {
3181
+ "type": "integer",
3182
+ "minimum": 1,
3183
+ "description": "复制哪一条。公共模板也可以,但只能是文章正文/标题两类"
3184
+ },
3185
+ "companyIds": {
3186
+ "type": "array",
3187
+ "items": {
3188
+ "type": "integer",
3189
+ "minimum": 1
3190
+ },
3191
+ "minItems": 1,
3192
+ "description": "复制到哪几家公司,每家一份。只能是当前密钥授权的公司"
3193
+ }
3194
+ },
3195
+ "required": [
3196
+ "promptId",
3197
+ "companyIds"
3198
+ ],
3199
+ "additionalProperties": false
3200
+ }
3201
+ },
3171
3202
  {
3172
3203
  "name": "articles.copy",
3173
3204
  "mode": "write",
@@ -3383,7 +3414,7 @@
3383
3414
  "mode": "read",
3384
3415
  "guide": "publication",
3385
3416
  "requiresPlan": false,
3386
- "description": "媒体投稿记录:订单状态、失败原因、发布链接、退款状态。投稿是异步的,提交完要过一阵才出结果,用这条查进展。**status 和 refundStatus 是两件事**——status 说稿子发出去没有,refundStatus 说钱退没退;被拒稿的记录要把两个都念给用户。",
3417
+ "description": "媒体投稿记录:订单状态、失败原因、发布链接、退款状态、实际扣款。投稿是异步的,提交完要过一阵才出结果,用这条查进展。**status 和 refundStatus 是两件事**——status 说稿子发出去没有,refundStatus 说钱退没退;被拒稿的记录要把两个都念给用户。报「这笔花了多少」用 chargedAmount(元,来自账本的真实扣款);currentPrice 是这家媒体**现在**的挂牌价,只能用来估算再投一次的花费,媒体调过价的话它和当时扣的不是一个数。chargedAmount 为 null 表示账本里查不到这笔扣费,就说查不到,别拿 currentPrice 顶替。",
3387
3418
  "inputSchema": {
3388
3419
  "type": "object",
3389
3420
  "properties": {
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var bt=Object.defineProperty;var At=(e,t,n)=>t in e?bt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Z=(e,t,n)=>At(e,typeof t!="symbol"?t+"":t,n);var ee="https://nbgeo.aimusiclj.com",he="best-geo-test",Ie="best-geo-test",ke="bg-test-cli-",be="0.3.2";var D=1,E=be,O=Ie,l=he,Ae="dev",B=xt(St());function St(){var e;return(e=process.env.BEST_GEO_API_BASE)!=null?e:ee}var j=ke,Se=300*1e3,xe=30*1e3,_e=300*1e3;function xt(e){return e.replace(/\/+$/,"")}var Ve=require("node:child_process");var Oe=require("node:crypto"),G=require("node:os");var p=require("node:fs"),ve=require("node:os"),L=require("node:path");var we=require("node:crypto");var A=class extends Error{constructor(n,r,i){super(i);Z(this,"reason",n);Z(this,"path",r);this.name="LocalConfigError"}},_t={schemaVersion:1,device:null,activeCredential:null,pendingCredential:null};function U(){var e;return(e=process.env.BEST_GEO_CONFIG_DIR)!=null?e:(0,L.join)((0,ve.homedir)(),`.${l}`)}function w(){return(0,L.join)(U(),"config.json")}function x(){var n,r,i;let e=w(),t;try{if(!(0,p.existsSync)(e))return null;wt(e),t=(0,p.readFileSync)(e,"utf8")}catch(s){throw s instanceof A?s:Ce(s,e)}try{let s=JSON.parse(t);if(typeof s!="object"||s==null||s.schemaVersion!==1)throw new Error("unexpected shape");return{schemaVersion:1,device:(n=s.device)!=null?n:null,activeCredential:(r=s.activeCredential)!=null?r:null,pendingCredential:(i=s.pendingCredential)!=null?i:null}}catch{throw new A("corrupted",e,`\u672C\u673A\u914D\u7F6E\u6587\u4EF6\u5185\u5BB9\u4E0D\u5B8C\u6574\u6216\u683C\u5F0F\u4E0D\u5BF9\uFF1A${e}`)}}function vt(e){let t=U(),n=w(),r=(0,L.join)(t,`.config.json.${(0,we.randomBytes)(6).toString("hex")}.tmp`);try{(0,p.existsSync)(t)||(0,p.mkdirSync)(t,{recursive:!0,mode:448});let i=(0,p.openSync)(r,"wx",384);try{(0,p.writeSync)(i,`${JSON.stringify(e,null,2)}
2
+ "use strict";var bt=Object.defineProperty;var At=(e,t,n)=>t in e?bt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Z=(e,t,n)=>At(e,typeof t!="symbol"?t+"":t,n);var ee="https://nbgeo.aimusiclj.com",he="best-geo-test",Ie="best-geo-test",ke="bg-test-cli-",be="0.3.3";var D=1,E=be,O=Ie,l=he,Ae="dev",B=xt(St());function St(){var e;return(e=process.env.BEST_GEO_API_BASE)!=null?e:ee}var j=ke,Se=300*1e3,xe=30*1e3,_e=300*1e3;function xt(e){return e.replace(/\/+$/,"")}var Ve=require("node:child_process");var Oe=require("node:crypto"),G=require("node:os");var p=require("node:fs"),ve=require("node:os"),L=require("node:path");var we=require("node:crypto");var A=class extends Error{constructor(n,r,i){super(i);Z(this,"reason",n);Z(this,"path",r);this.name="LocalConfigError"}},_t={schemaVersion:1,device:null,activeCredential:null,pendingCredential:null};function U(){var e;return(e=process.env.BEST_GEO_CONFIG_DIR)!=null?e:(0,L.join)((0,ve.homedir)(),`.${l}`)}function w(){return(0,L.join)(U(),"config.json")}function x(){var n,r,i;let e=w(),t;try{if(!(0,p.existsSync)(e))return null;wt(e),t=(0,p.readFileSync)(e,"utf8")}catch(s){throw s instanceof A?s:Ce(s,e)}try{let s=JSON.parse(t);if(typeof s!="object"||s==null||s.schemaVersion!==1)throw new Error("unexpected shape");return{schemaVersion:1,device:(n=s.device)!=null?n:null,activeCredential:(r=s.activeCredential)!=null?r:null,pendingCredential:(i=s.pendingCredential)!=null?i:null}}catch{throw new A("corrupted",e,`\u672C\u673A\u914D\u7F6E\u6587\u4EF6\u5185\u5BB9\u4E0D\u5B8C\u6574\u6216\u683C\u5F0F\u4E0D\u5BF9\uFF1A${e}`)}}function vt(e){let t=U(),n=w(),r=(0,L.join)(t,`.config.json.${(0,we.randomBytes)(6).toString("hex")}.tmp`);try{(0,p.existsSync)(t)||(0,p.mkdirSync)(t,{recursive:!0,mode:448});let i=(0,p.openSync)(r,"wx",384);try{(0,p.writeSync)(i,`${JSON.stringify(e,null,2)}
3
3
  `),(0,p.fsyncSync)(i)}finally{(0,p.closeSync)(i)}(0,p.renameSync)(r,n)}catch(i){if((0,p.existsSync)(r))try{(0,p.unlinkSync)(r)}catch{}throw Ce(i,n)}}function _(e){var n;let t=e((n=x())!=null?n:{..._t});return vt(t),t}function wt(e){var r;if(process.platform==="win32")return;let t=(0,p.statSync)(e),n=(r=process.getuid)==null?void 0:r.call(process);if(n!=null&&t.uid!==n)throw new A("not_owner",e,`\u672C\u673A\u914D\u7F6E\u6587\u4EF6\u4E0D\u5C5E\u4E8E\u5F53\u524D\u7528\u6237\uFF1A${e}`);if((t.mode&63)!==0)throw new A("permissions_too_open",e,`\u672C\u673A\u914D\u7F6E\u6587\u4EF6\u6743\u9650\u8FC7\u5BBD\uFF08\u540C\u673A\u5176\u4ED6\u7528\u6237\u53EF\u8BFB\uFF09\uFF1A${e}`)}function Ce(e,t){let n=e==null?void 0:e.code;return n==="EACCES"||n==="EPERM"||n==="EROFS"?new A("denied",t,`\u6CA1\u6709\u6743\u9650\u8BFB\u5199\u672C\u673A\u914D\u7F6E\uFF1A${t}`):e instanceof Error?e:new Error(String(e))}var Ct=3600*1e3;function Re(){return(0,L.join)(U(),"pending-uploads.json")}function M(){let e=Re();if(!(0,p.existsSync)(e))return{};try{let t=JSON.parse((0,p.readFileSync)(e,"utf8")),n=Date.now();return Object.fromEntries(Object.entries(t).filter(([,r])=>{var i;return n-((i=r==null?void 0:r.createdAt)!=null?i:0)<Ct}))}catch{return{}}}function te(e){(0,p.mkdirSync)(U(),{recursive:!0,mode:448}),(0,p.writeFileSync)(Re(),JSON.stringify(e),{mode:384})}function $e(){var t,n;let e=(t=x())==null?void 0:t.device;return(n=e==null?void 0:e.deviceId)!=null&&n.startsWith(j)?e.deviceId:null}function H(){var r,i;let e={deviceName:(0,G.hostname)().slice(0,50),platform:`${(0,G.platform)()}-${process.arch}`},t=(r=x())==null?void 0:r.device;if((i=t==null?void 0:t.deviceId)!=null&&i.startsWith(j))return t.deviceName===e.deviceName&&t.platform===e.platform?t:_(s=>({...s,device:{...t,...e}})).device;let n={deviceId:`${j}${(0,Oe.randomUUID)()}`,...e};return _(s=>({...s,device:n})).device}function Ne(){return`cli_${Date.now().toString(36)}${Math.random().toString(36).slice(2,8)}`}function h(e,t=Ne()){return{ok:!0,code:"OK",requestId:t,data:e}}function c(e,t,n={}){var r;return{ok:!1,code:e,message:t,requestId:(r=n.requestId)!=null?r:Ne(),...n.data==null?{}:{data:n.data},...n.nextAction==null?{}:{nextAction:n.nextAction}}}function a(e){process.stdout.write(`${JSON.stringify(e)}
4
4
  `),e.ok||(process.exitCode=1)}async function y(e,t={}){var s,o;let n=new URL(`${B}/v1/agent-cli${e}`);for(let[d,m]of Object.entries((s=t.query)!=null?s:{}))if(m!=null)for(let u of Array.isArray(m)?m:[m])n.searchParams.append(d,String(u));let r={"X-GEO-CLI-Version":E,"X-GEO-Protocol-Version":String(D),"X-GEO-CLI-Package":O},i=null;try{i=$e()}catch{}i&&(r["X-Device-ID"]=i),t.apiKey&&(r.Authorization=`Bearer ${t.apiKey}`),t.body!=null&&(r["Content-Type"]="application/json");try{let d=await fetch(n,{method:(o=t.method)!=null?o:"GET",headers:r,body:t.body==null?void 0:JSON.stringify(t.body),signal:AbortSignal.timeout(t.isWrite?_e:xe)}),m=await d.text();try{let u=JSON.parse(m);return Rt(u)?u:c("SERVER_ERROR",`\u670D\u52A1\u7AEF\u8FD4\u56DE\u4E86\u975E\u9884\u671F\u5185\u5BB9\uFF08HTTP ${d.status}\uFF09`,{data:{transportFailure:!0}})}catch{return c("SERVER_ERROR",`\u670D\u52A1\u7AEF\u8FD4\u56DE\u4E86\u975E\u9884\u671F\u5185\u5BB9\uFF08HTTP ${d.status}\uFF09`,{data:{transportFailure:!0}})}}catch(d){return d instanceof Error&&(d.name==="TimeoutError"||d.name==="AbortError")?c("SERVER_ERROR",t.isWrite?"\u670D\u52A1\u7AEF\u5904\u7406\u8D85\u65F6,\u8FD9\u6B21\u5199\u5165\u7ED3\u679C\u672A\u77E5":"\u670D\u52A1\u7AEF\u54CD\u5E94\u8D85\u65F6",{data:{transportFailure:!0},nextAction:t.isWrite?{type:"ask_user",message:"\u8D85\u65F6\u4E0D\u4EE3\u8868\u6CA1\u5199\u8FDB\u53BB \u2014\u2014 \u670D\u52A1\u7AEF\u53EF\u80FD\u8FD8\u5728\u5904\u7406\u3002**\u5148\u7528\u5BF9\u5E94\u7684\u67E5\u8BE2\u80FD\u529B\u786E\u8BA4\u4E00\u904D**,\u786E\u5B9E\u6CA1\u6709\u518D\u91CD\u65B0 plan;\u76F4\u63A5\u91CD\u8BD5\u4F1A\u5EFA\u51FA\u91CD\u590D\u7684\u4E00\u4EFD,\u800C\u4E14\u4F1A\u518D\u6263\u4E00\u6B21\u8D39\u3002"}:{type:"ask_user",message:"\u670D\u52A1\u7AEF\u54CD\u5E94\u592A\u6162\u3002\u7A0D\u540E\u91CD\u8BD5\u540C\u4E00\u6761\u547D\u4EE4\u5373\u53EF,\u67E5\u8BE2\u4E0D\u4F1A\u4EA7\u751F\u4EFB\u4F55\u5199\u5165"}}):c("SERVER_ERROR",`\u65E0\u6CD5\u8FDE\u63A5\u670D\u52A1\u7AEF\uFF1A${d instanceof Error?d.message:String(d)}`,{data:{transportFailure:!0},nextAction:{type:"ask_user",message:"\u8BF7\u786E\u8BA4\u7F51\u7EDC\u53EF\u7528\uFF0C\u4EE5\u53CA\u670D\u52A1\u7AEF\u5730\u5740\u914D\u7F6E\u6B63\u786E"}})}}function Rt(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.ok=="boolean"&&typeof t.code=="string"}function Ot(e){var t;return!e.ok&&((t=e.data)==null?void 0:t.transportFailure)===!0}function ne(e){return e.ok||Ot(e)?!1:["AUTH_EXPIRED","DEVICE_MISMATCH","ACCESS_DENIED","AUTH_REQUIRED","VALIDATION_FAILED"].includes(e.code)}function $(){var e,t,n;return(n=(t=(e=x())==null?void 0:e.activeCredential)==null?void 0:t.apiKey)!=null?n:null}function J(){var e,t;return(t=(e=x())==null?void 0:e.activeCredential)!=null?t:null}function Te(){var e,t;return(t=(e=x())==null?void 0:e.pendingCredential)!=null?t:null}function Pe(e){_(t=>({...t,pendingCredential:{apiKey:e,startedAt:new Date().toISOString()}}))}function re(){_(e=>({...e,pendingCredential:null}))}function ie(e){return _(t=>{let n=t.pendingCredential;return n?{...t,activeCredential:{apiKey:n.apiKey,...e},pendingCredential:null}:t}).activeCredential}function De(){_(e=>({...e,activeCredential:null,pendingCredential:null}))}var v=require("node:crypto"),Ue=require("node:http");function Le(e){let t=`
5
5
  (function () {
@@ -19,7 +19,7 @@
19
19
  "step": 2,
20
20
  "action": "用 prompts.list 查写作方向,念给用户选",
21
21
  "capability": "prompts.list",
22
- "note": "type=1 是写作方向(必选),type=2 是标题风格(可以不选,不选就让模型按问题自拟标题)。这两样在任务跑起来之后就改不了了。"
22
+ "note": "type=1 是写作方向(必选),type=2 是标题风格(可以不选,不选就让模型按问题自拟标题)。这两样在任务跑起来之后就改不了了。用户想改某条公共模板时,公共模板本身改不了——用 prompts.duplicate 复制一份到他的公司,再改副本。"
23
23
  },
24
24
  {
25
25
  "step": 3,
@@ -46,7 +46,7 @@
46
46
  "step": 7,
47
47
  "action": "要停下来用 publicationTasks.pause,改主意了用 delete",
48
48
  "capability": "publicationTasks.pause",
49
- "note": "两个都只对**还没发出去**的记录有效。已经发成功的稿子留在平台上,CLI 撤不回来——用户要撤那些,只能去各平台自己删,这一点必须说明白,别让他以为暂停就等于撤回。"
49
+ "note": "两个都只对**还没发出去**的记录有效(删除会连暂停中的一起删掉)。已经发成功的稿子留在平台上,CLI 撤不回来——用户要撤那些,只能去各平台自己删,这一点必须说明白,别让他以为暂停就等于撤回。另外建任务时费用就按记录条数扣过了,删除不改变这笔扣费,用户点删除前得知道。"
50
50
  },
51
51
  {
52
52
  "step": 8,
@@ -81,6 +81,7 @@
81
81
  "不要用列表里的媒体价格给用户报价,必须用 mediaPlatforms.get 的实时价",
82
82
  "不要给自媒体发布的失败编造原因,也不要去读 errorMessage——那个字段不存在",
83
83
  "不要把 refund_pending 说成「已退款」——那笔钱现在还在用户账外,说错了他就不会再追",
84
+ "不要拿 currentPrice 当这笔的花费念——那是媒体现在的挂牌价,实际扣了多少看 chargedAmount",
84
85
  "不要把 status 数值念给用户,用 statusLabel",
85
86
  "不要说「暂停」或「删除任务」能撤回已经发出去的稿子——撤不了",
86
87
  "不要拿未审核或没封面的文章去发布/投稿,会被拒。挑文章时就用 status=1 + mustHaveCover=true 筛掉"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "best-geo-test",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Best GEO CLI — 给本地 AI 助手调用的 GEO 命令行工具",
5
5
  "bin": {
6
6
  "best-geo-test": "dist/index.cjs"