promptfigure 0.2.0 → 0.3.1
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 +29 -15
- package/adapters/claude-code/install.mjs +7 -6
- package/adapters/claude-code/promptfigure-api/INSTALL.md +45 -0
- package/adapters/claude-code/promptfigure-api/SKILL.md +291 -0
- package/adapters/claude-code/promptfigure-api/references/api-contract.md +319 -0
- package/adapters/claude-code/promptfigure-api/references/deliverables-ledger.md +119 -0
- package/adapters/claude-code/promptfigure-api/references/document-workflow.md +231 -0
- package/adapters/claude-code/promptfigure-api/references/figure-upgrade-workflow.md +201 -0
- package/adapters/claude-code/promptfigure-api/references/proactive-upgrade.md +120 -0
- package/adapters/claude-code/promptfigure-api/references/prompt-cookbook.md +223 -0
- package/adapters/claude-code/promptfigure-api/references/prompt-review-workflow.md +265 -0
- package/adapters/claude-code/promptfigure-api/references/setup-guide.md +151 -0
- package/adapters/claude-code/promptfigure-api/references/troubleshooting.md +204 -0
- package/adapters/claude-code/{SKILL.md → promptfigure-local/SKILL.md} +31 -0
- package/adapters/codex/promptfigure/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/promptfigure/skills/promptfigure-api/INSTALL.md +45 -0
- package/adapters/codex/promptfigure/skills/promptfigure-api/SKILL.md +291 -0
- package/adapters/codex/promptfigure/skills/promptfigure-api/references/api-contract.md +319 -0
- package/adapters/codex/promptfigure/skills/promptfigure-api/references/deliverables-ledger.md +119 -0
- package/adapters/codex/promptfigure/skills/promptfigure-api/references/document-workflow.md +231 -0
- package/adapters/codex/promptfigure/skills/promptfigure-api/references/figure-upgrade-workflow.md +201 -0
- package/adapters/codex/promptfigure/skills/promptfigure-api/references/proactive-upgrade.md +120 -0
- package/adapters/codex/promptfigure/skills/promptfigure-api/references/prompt-cookbook.md +223 -0
- package/adapters/codex/promptfigure/skills/promptfigure-api/references/prompt-review-workflow.md +265 -0
- package/adapters/codex/promptfigure/skills/promptfigure-api/references/setup-guide.md +151 -0
- package/adapters/codex/promptfigure/skills/promptfigure-api/references/troubleshooting.md +204 -0
- package/adapters/codex/promptfigure/skills/promptfigure-local/SKILL.md +31 -0
- package/bin/pf.mjs +37 -0
- package/package.json +2 -2
- package/scripts/build-adapters.mjs +31 -18
- package/skill/promptfigure-api/INSTALL.md +45 -0
- package/skill/promptfigure-api/SKILL.md +291 -0
- package/skill/promptfigure-api/references/api-contract.md +319 -0
- package/skill/promptfigure-api/references/deliverables-ledger.md +119 -0
- package/skill/promptfigure-api/references/document-workflow.md +231 -0
- package/skill/promptfigure-api/references/figure-upgrade-workflow.md +201 -0
- package/skill/promptfigure-api/references/proactive-upgrade.md +120 -0
- package/skill/promptfigure-api/references/prompt-cookbook.md +223 -0
- package/skill/promptfigure-api/references/prompt-review-workflow.md +265 -0
- package/skill/promptfigure-api/references/setup-guide.md +151 -0
- package/skill/promptfigure-api/references/troubleshooting.md +204 -0
- package/skill/promptfigure-local/SKILL.md +31 -0
- package/web/app.js +9 -3
- package/web/style.css +5 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# 常见问题与排障
|
|
2
|
+
|
|
3
|
+
## 错误码速查
|
|
4
|
+
|
|
5
|
+
| 码 | error 值 | 原因 | 处置 |
|
|
6
|
+
|---|---|---|---|
|
|
7
|
+
| 400 | `prompt_required` / `prompt_too_long` | prompt 空或 >8000 字符 | 检查请求体 |
|
|
8
|
+
| 401 | `invalid_api_key` | key 无效/已吊销/漏了 `Bearer ` 前缀 | 检查 header;无效则重建 key |
|
|
9
|
+
| 402 | `insufficient_balance` | 余额不足 | 控制台充值($1 起,整数) |
|
|
10
|
+
| 403 | `error code: 1010` | **CF WAF 拦了客户端 UA**(仅 `Python-urllib/*` 默认 UA) | 切 Node / Go / Python `requests` / 浏览器;或给 urllib 加 `User-Agent: Mozilla/5.0` |
|
|
11
|
+
| 429 | `rate_limited` | 超 RPM | 已退款,串行 + 退避重试(1s → 2s → 4s) |
|
|
12
|
+
| 502 | `generation_failed` | 生图通道异常 | **已自动退款**,看 `detail` 后重试;最常见是 `orchestration_failed: empty or truncated polish output` |
|
|
13
|
+
| 405 | `method_not_allowed` | 用了 GET | 必须 POST |
|
|
14
|
+
|
|
15
|
+
> 注意 RPM 限制是**账号级**,与网页端工作台共享同一个分钟窗口。网页上刚连续出过图,API 立刻报 429 属正常。
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🔧 502 `orchestration_failed: empty or truncated polish output`
|
|
20
|
+
|
|
21
|
+
**上游 Agnes 文本模型间歇性限频**。限频期间默认管线可能 502(约 35 秒后返回),`refunded` 标明退还金额,无需补款。服务端已内置回落:主模型 agnes-2.5-flash 撞 429 时会自动用 agnes-2.0-flash 整体重试一次;两层都撞上才会 502。
|
|
22
|
+
|
|
23
|
+
⚠️ 重要:**这是上游运维状态,不是产品形态。** `/api/v1/generate` 的设计就是默认走完整润色管线,与网页同款。不要把 `polish:false` 当常态。
|
|
24
|
+
|
|
25
|
+
### 真实根因(2026-09-09 实证,已修订)
|
|
26
|
+
|
|
27
|
+
上游返回 **`429 "Too many requests. Please try again in a moment."`**——**与本方用量完全无关**(实测窗口内仅 7 次调用 / 配额 7500,依然 429;数小时后自行恢复)。重要线索:同 key 同模型从本机直连不限流、只有站点出口被限 → **疑似 Agnes 按出口 IP 频控**,换模型未必躲得开,等服务端回落+稍后重试是正解。
|
|
28
|
+
|
|
29
|
+
**已修复的误导**:此前四种不同失败(配额耗尽/key 冷却/上游空响应/被上游拒绝)统一报成 `empty or truncated polish output`。**现在错误 detail 里带 `last_text_failure:` 字段**,直接给出上游真实状态码和响应片段——看到它就不用再猜。
|
|
30
|
+
|
|
31
|
+
### 如何区分「平台故障」vs「我自己的问题」
|
|
32
|
+
|
|
33
|
+
| 特征 | 平台限频(本次) | 自己的问题 |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| 错误 detail | 含 `upstream 429` | 含 `prompt`/参数类提示 |
|
|
36
|
+
| 耗时 | 恒定 ~35s(重试耗尽) | 秒级返回 |
|
|
37
|
+
| `polish:false` 同参数重试 | ✅ 能出图 | 也失败 |
|
|
38
|
+
| 隔一段时间重试 | ✅ 自愈 | 仍失败 |
|
|
39
|
+
|
|
40
|
+
### 处置
|
|
41
|
+
|
|
42
|
+
**首选:等几分钟到几小时后原样重试**(限频会自行解除;2026-09-09 实测当天恢复,默认管线 42–90s 成功出图)。
|
|
43
|
+
|
|
44
|
+
赶时间时的临时绕过:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{ "prompt": "<完整英文提示词>", "polish": false, "model": "standard" }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
⚠️ `polish:false` 时服务端**不润色不扩写**,prompt 原样进图模型——所以必须自己写完整英文提示词(写法见 `prompt-cookbook.md` 的「降级模式」)。
|
|
51
|
+
|
|
52
|
+
### 何时回到正常
|
|
53
|
+
|
|
54
|
+
无需操作——限频解除后默认管线自动恢复(响应里 `crafted: true`)。`polish:false` 仅作为绕过手段保留。
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 🔴 CF WAF 403 `error code: 1010`
|
|
59
|
+
|
|
60
|
+
实测拦截列表(2026-09-09):
|
|
61
|
+
|
|
62
|
+
| 客户端 | UA | 结果 |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| curl | `curl/7.x` | ✅ 200 |
|
|
65
|
+
| Node fetch | `node` | ✅ 200 |
|
|
66
|
+
| Python `requests` | `python-requests/2.x` | ✅ 200 |
|
|
67
|
+
| Go `net/http` | `Go-http-client/1.1` | ✅ 200 |
|
|
68
|
+
| 浏览器 fetch | `Mozilla/5.0 ...` | ✅ 200 |
|
|
69
|
+
| Python `urllib.request` | **`Python-urllib/3.x`** | ❌ 403 |
|
|
70
|
+
|
|
71
|
+
**修法**:
|
|
72
|
+
- Python `urllib`:手动加 `User-Agent: Mozilla/5.0`
|
|
73
|
+
- 或换 `requests` / `httpx` / Node / Go
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 🔴 `balance` 字段滞后
|
|
78
|
+
|
|
79
|
+
`/api/login` 和 `/api/me` 返回的 `balance` **不等于真实余额**(实测:`me` 返回 0,扣费 0.02 后真实余额 0.09,扣费仍成功)。
|
|
80
|
+
|
|
81
|
+
可能解释:这两接口里 `balance` 字段没同步 D1,或来自一个非权威缓存层。
|
|
82
|
+
|
|
83
|
+
**操作规则**:
|
|
84
|
+
- 不要因为 `balance` 看起来够而**预先估算**余额
|
|
85
|
+
- 看到 `402` 不要立即判定没钱,先看 D1 控制台 https://promptfigure.top/console#account-balance
|
|
86
|
+
- 用户报告「明明有钱却被 402」时,先核对控制台余额(不是接口返回的)
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 注册 / key 相关
|
|
91
|
+
|
|
92
|
+
**Q:注册要收邮箱验证码吗?**
|
|
93
|
+
不用。邮箱 + 密码(≥8 位)提交即完成,session token 立即可用。
|
|
94
|
+
|
|
95
|
+
**Q:key 明文丢了怎么办?**
|
|
96
|
+
找不回来。库内只存 SHA-256 哈希。吊销旧的重建:
|
|
97
|
+
`POST /api/keys/revoke {"id":"..."}` → `POST /api/keys {"name":"..."}`。
|
|
98
|
+
|
|
99
|
+
**Q:余额和会员额度是一回事吗?**
|
|
100
|
+
不是。API 只从**余额**扣,与订阅赠送的额度完全独立。有会员但余额为 0 → 调用仍会 402。反过来,只充值不订阅也能一直用 API(免费层 5 RPM)。
|
|
101
|
+
|
|
102
|
+
**Q:能创建几把 key?**
|
|
103
|
+
每人最多 10 把未吊销。按用途命名便于追溯。
|
|
104
|
+
|
|
105
|
+
**Q:为什么会 401 但我明明没吊销?**
|
|
106
|
+
先查 `Authorization` header —— 必须是 `Bearer pf_xxx`。写成 `Token pf_xxx` 或直接裸 key 都会 401。
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 参考图
|
|
111
|
+
|
|
112
|
+
**Q:`refIgnored: true` 是什么意思?**
|
|
113
|
+
参考图缺失/非法/拉取失败,**已被忽略,当次照常出图并计费**。按序排查:
|
|
114
|
+
|
|
115
|
+
1. URL 是图片**直链**吗?(浏览器打开直接显示图片,不是含图的网页)
|
|
116
|
+
2. 是 PNG 吗?(某些 .webp/.jpg 后缀但实际格式不符会失败)
|
|
117
|
+
3. 超过 8MB 吗?
|
|
118
|
+
4. 是私网/本地地址吗?(会被拒绝)
|
|
119
|
+
5. 图床是否还在?(免费图床政策常变)
|
|
120
|
+
|
|
121
|
+
**Q:参考图端点是不是有问题?**
|
|
122
|
+
**是**。上游 `/images/edits` 自 2026-09-07 起持续 503。`refUrl`/`refDataUrl` 当前经常 `refIgnored: true`。
|
|
123
|
+
**绕开方案**:暂时改用「纯文字精确描述」——把参考图的特征(方向/panel 数/图表类型/图标风格/数据标注密度/色分布)全部写进 prompt。修复后第一时间回写到本文件。
|
|
124
|
+
|
|
125
|
+
**Q:有既稳定又省事的方案吗?**
|
|
126
|
+
图在公网 → 用 `refUrl`(服务器代取,你不用下载也不用转 base64)。
|
|
127
|
+
图在本地且较小 → 用 `refDataUrl`。
|
|
128
|
+
图在本地且较大 → 先挂免费图床:
|
|
129
|
+
`curl -F "file=@ref.png" https://x0.at`
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 出图质量
|
|
134
|
+
|
|
135
|
+
**Q:图里的文字糊/有乱码英文?**
|
|
136
|
+
polish:false 直出时图模型对英文文字标签渲染差(实测出 "Mcıuacy" 这种乱码)。
|
|
137
|
+
**修法**:prompt 里**逐字写对**所有英文标签,加一句 "All on-figure text labels in English, spelled correctly"。重要场合用 `premium`(gpt-image 文字渲染显著优于 Agnes standard)。
|
|
138
|
+
|
|
139
|
+
**Q:数值和我给的不一致?**
|
|
140
|
+
polish:false 时图模型会忠实画你给的数值,但也可能把"上下文中相似数字"画错。关键数值在 prompt 里重复一次并显式绑定单位。⚠️ 没有真实数据就别写——补出来的数值会被当成事实印到图上。
|
|
141
|
+
|
|
142
|
+
**Q:配色太单调,全是一个色系?**
|
|
143
|
+
prompt 里写了单一色相约束(如 `"muted steel-blue fills"`)。改用语义化多色(详见 `prompt-cookbook.md` 的配色小节)。
|
|
144
|
+
|
|
145
|
+
**Q:机制图被画成了 3D?**
|
|
146
|
+
prompt 里加 `2D flat`, `white background`, `no gradients, no photorealism`。
|
|
147
|
+
|
|
148
|
+
**Q:构图和我给的参考图差很远?**
|
|
149
|
+
「参考风格」不拆特征是必返工的。拆到特征级——方向、panel 数、图表类型、图标风格、标注密度、色分布——逐条写进 prompt 正文。参考图只是补充(且当前参考图端点 503)。
|
|
150
|
+
|
|
151
|
+
**Q:prompt 很长但出图反而更差?**
|
|
152
|
+
超 400 词后信息超载。压到 150–300 词,只保留核心实体与结构。
|
|
153
|
+
|
|
154
|
+
**Q:为什么图快/出图秒成但像样?**
|
|
155
|
+
polish:false 直出时快(~11s)但少了编排层润色,**质量低于正常管线是预期**,不是异常。正常管线应看到 `crafted: true` 的更慢但更好的结果。
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 计费
|
|
160
|
+
|
|
161
|
+
**Q:既然 premium 1K 和 2K 同价,为什么还要选 1K?**
|
|
162
|
+
基本不用选,默认 2K。仅当需要快速迭代或尺寸受限时用 1K。
|
|
163
|
+
|
|
164
|
+
**Q:失败会扣钱吗?**
|
|
165
|
+
不会。502、429 都会自动原路退款(响应里看 `refunded`)。只有成功出图才真扣费。
|
|
166
|
+
|
|
167
|
+
**Q:RPM 不够用怎么办?**
|
|
168
|
+
提升订阅档(Lite 10 / Plus 15 / Pro 40 / Ultra 80 RPM)。短期也可以:错峰、把批量任务摊到不同分钟。
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 时效
|
|
173
|
+
|
|
174
|
+
**Q:响应要多久?**
|
|
175
|
+
polish:false 实测 ~11s(standard)/ 60–120s(premium 2K 偶尔更长)。**客户端 timeout ≥ 300s**。
|
|
176
|
+
⚠️ 别设 30s/60s 就以为服务挂了——通常是你自己先断开了。
|
|
177
|
+
|
|
178
|
+
**Q:网页工作台和 API 一样慢/卡吗?**
|
|
179
|
+
管线正常时网页与 API 同速(都在服务端润色)。网页端**没有 `polish:false` 等价开关**——上游限频期网页会卡在 polishing,急用请走 API 路径 A。
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 仍然解决不了
|
|
184
|
+
|
|
185
|
+
- 线上文档(权威,比本文件更新):https://promptfigure.top/docs/zh-CN/faq
|
|
186
|
+
- 在线调试台(隔离是代码问题还是账号问题):https://promptfigure.top/docs/zh-CN/api-playground
|
|
187
|
+
- 服务状态/更新:https://promptfigure.top/news
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## premium 被内容审核误伤(502 `content moderation`,2026-09-10 CVPR 实测)
|
|
192
|
+
|
|
193
|
+
现象:502 + `detail.error = premium channel rejected` + 上游报 "rejected by content moderation",**自动退款**。
|
|
194
|
+
|
|
195
|
+
关键实测结论(二分验证):
|
|
196
|
+
|
|
197
|
+
- 触发是**整段组合判断,不是单词命中**——把整段 prompt 里的词逐个/分组喂给极简探针全部通过,合在一起就被拒。密集的「检测/候选框/过滤/一致性」类 CV 术语组合(如 …Candidate Boxes + Consensus + Filtering + 本地化器… 同屏多个)容易触发
|
|
198
|
+
- 单个可疑缩写也可能命中(实测 `WBF` 被拒,全称 Weighted Box Fusion 反而通过)——先用极简探针 + 可疑词单独测,拒=免费,通过=正常扣费,别拿整段 prompt 反复烧钱试
|
|
199
|
+
|
|
200
|
+
处置顺序:
|
|
201
|
+
|
|
202
|
+
1. 拒了就换措辞重试**最多 2 次**(每次拒绝免费);去掉标题/缩写、把检测类词汇换成中性词(Estimator/Candidate)常能过
|
|
203
|
+
2. 还不过 → **不要继续试探**:改走 standard 出图(Agnes 通道审核宽松,同样内容能过),拼写/小字问题用 PIL 本地修补(采样盒底色覆盖 + Arial 按原字号重写标签),成本为零且拼写百分百正确
|
|
204
|
+
3. 台账里记 `moderation_blocked: true` 与被拒 prompt,便于服务端侧后续排查
|
|
@@ -375,6 +375,37 @@ pf craft --at "§3.2 ¶2" --figure-type pipeline \
|
|
|
375
375
|
- **路径写法**:Git Bash 的 `/c/...`、Windows 的 `C:\...`、POSIX 的 `/home/...` 都能用;
|
|
376
376
|
但 craft --out 建议用相对路径(当前目录下),最不容易踩环境差异。
|
|
377
377
|
|
|
378
|
+
## 每轮交付与台账(每轮结束必交,CLI 优先)
|
|
379
|
+
|
|
380
|
+
**CLI 优先**:出图、核验、审批、定稿全走 `pf` 命令(`pf next` 永远告诉你下一步);
|
|
381
|
+
GUI 只留给人两件事——亲眼看图、点审批。插件的门禁与留痕都挂在 CLI 上,
|
|
382
|
+
走 CLI 的每一步在 `events.jsonl` 里可审计;无头环境(SSH/容器/CI)本来就全 CLI。
|
|
383
|
+
|
|
384
|
+
每轮交付在**用户工作目录**建 `promptfigure-out/`,每轮一个新版本文件夹 `vN/`(v1 → v2…):
|
|
385
|
+
|
|
386
|
+
```
|
|
387
|
+
promptfigure-out/
|
|
388
|
+
├── vN/
|
|
389
|
+
│ ├── round-vN.md ← 本轮反馈(下面的必含项)
|
|
390
|
+
│ └── figures/ ← 本轮图(副本或引用,文件名带 -vN)
|
|
391
|
+
├── paper-with-figures.md ← 论文+已插图的演进版(无关段落省略,每次更新同一个)
|
|
392
|
+
└── final/paper-final.md + 格式副本 ← 最终论文版本(定稿时才建)
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**round-vN.md 必含**(与 promptfigure-api skill 的 deliverables-ledger.md 同一协议):
|
|
396
|
+
1. **本轮清单**:每张图——figureId / 图种 / 档位 / 版本 / 本机真实路径(本插件即
|
|
397
|
+
`~/.promptfigure/projects/<docId>/figures/<figureId>/vN.png`)/ 插入位置(§¶)
|
|
398
|
+
2. **插入位置(两段边界)**:上一段最后一句 + 「……」 + 下一段第一句,用户一眼定位
|
|
399
|
+
3. **所用上下文**:用了哪几段明确到 §¶;上下文只放**首句 + 「……」 + 尾句**;
|
|
400
|
+
数据/表格/代码文件一律给引用链接,不内联内容
|
|
401
|
+
4. **图片版本**:每张图的每个版本独立文件(vN),旧版永不覆盖
|
|
402
|
+
5. **优化前→优化后**(优化任务):原图路径 vs 新图路径 + 改了什么 + 所用上下文(首尾句)
|
|
403
|
+
|
|
404
|
+
**最终成稿流程**(用户说「定稿」):提醒核对数据是否更新 → 用户确认后才 premium 定稿 →
|
|
405
|
+
定稿后必问矢量图(本地 AI 重绘、token 贵、速度慢;比赛/数模默认不做;确认做则按元素
|
|
406
|
+
分层重绘成可编辑矢量,PPT/WPS 按用户偏好)——完整协议见 promptfigure-api skill 的
|
|
407
|
+
`references/deliverables-ledger.md`。
|
|
408
|
+
|
|
378
409
|
## 事件回放
|
|
379
410
|
|
|
380
411
|
`~/.promptfigure/projects/<docId>/events.jsonl` 只追加不改写 —— 审批历史、
|
package/bin/pf.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import fs from "node:fs";
|
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import http from "node:http";
|
|
8
8
|
import net from "node:net";
|
|
9
|
+
import os from "node:os";
|
|
9
10
|
import { fileURLToPath } from "node:url";
|
|
10
11
|
|
|
11
12
|
import {
|
|
@@ -121,6 +122,13 @@ promptFigure 本地插件 v${VERSION} —— 在你的 AI 宿主里为论文配
|
|
|
121
122
|
+ 计费兜底 + 排练留痕,每条带理由——可疑版本可直接打回
|
|
122
123
|
pf setup-tex 下载便携 tectonic(没有 TeX 环境时用,~20MB 免安装)
|
|
123
124
|
pf doc compile [--doc <id>] 重新编译 LaTeX → PDF(改了源文件后用)
|
|
125
|
+
|
|
126
|
+
skill(npm 装的插件自带,一条命令装进宿主):
|
|
127
|
+
pf skill install 把随包的两个 skill 装进宿主技能目录(默认 ~/.claude/skills/)
|
|
128
|
+
· promptfigure-local —— 插件工作流(文档预览/锚点/审批 GUI)
|
|
129
|
+
· promptfigure-api —— 纯 REST 出图(任何能跑 curl 的宿主)
|
|
130
|
+
[--dir <路径>] 可指定其他技能目录;两者按宿主环境二选一或都装
|
|
131
|
+
pf skill path 只看两个 skill 在插件包里的路径(手动拷贝/排查用)
|
|
124
132
|
`;
|
|
125
133
|
|
|
126
134
|
function die(msg, hintCmd) {
|
|
@@ -1890,6 +1898,35 @@ async function main() {
|
|
|
1890
1898
|
return;
|
|
1891
1899
|
}
|
|
1892
1900
|
|
|
1901
|
+
case "skill": {
|
|
1902
|
+
// 随包发行的两个 skill 一键装进宿主(npm i -g promptfigure 后的落地步骤)
|
|
1903
|
+
const PKG_ROOT = path.resolve(__dirname, "..");
|
|
1904
|
+
const SKILLS = ["promptfigure-local", "promptfigure-api"];
|
|
1905
|
+
const sub = rest[0] || "install";
|
|
1906
|
+
if (sub === "path" || sub === "list") {
|
|
1907
|
+
for (const s of SKILLS) console.log(path.join(PKG_ROOT, "skill", s));
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1910
|
+
if (sub !== "install") {
|
|
1911
|
+
die(`用法:pf skill install [--dir <技能目录>]|pf skill path 只看路径`, "pf skill install");
|
|
1912
|
+
}
|
|
1913
|
+
const destRoot = arg("--dir") || path.join(os.homedir(), ".claude", "skills");
|
|
1914
|
+
for (const s of SKILLS) {
|
|
1915
|
+
if (!fs.existsSync(path.join(PKG_ROOT, "skill", s, "SKILL.md"))) {
|
|
1916
|
+
die(`找不到 skill 源:${path.join(PKG_ROOT, "skill", s)} —— 插件包不完整?`, "重装:npm i -g promptfigure");
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
fs.mkdirSync(destRoot, { recursive: true });
|
|
1920
|
+
for (const s of SKILLS) {
|
|
1921
|
+
const dest = path.join(destRoot, s);
|
|
1922
|
+
fs.cpSync(path.join(PKG_ROOT, "skill", s), dest, { recursive: true });
|
|
1923
|
+
console.log(`✅ ${s} → ${dest}`);
|
|
1924
|
+
}
|
|
1925
|
+
console.log(`⏭ 其他宿主:Codex 把 ${path.join(PKG_ROOT, "adapters", "codex", "promptfigure")} 拷进 plugins 目录;`);
|
|
1926
|
+
console.log(` 无技能目录的宿主(任意 Agent),把某个 skill 的 SKILL.md 内容追加进 AGENTS.md / CLAUDE.md 末尾。`);
|
|
1927
|
+
return;
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1893
1930
|
case "serve": {
|
|
1894
1931
|
const { startServer } = await import("../src/server.mjs");
|
|
1895
1932
|
const port = Number(arg("--port")) || loadConfig().port || (await import("../src/config.mjs")).DEFAULT_PORT;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "promptfigure",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "promptFigure 本地插件:在你的 AI 宿主(Codex / Claude Code 等)里为论文配科研图。开文档(LaTeX 本地编译)、画锚点、本地规则层组装提示词、调出图、收审批。",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "promptFigure 本地插件:在你的 AI 宿主(Codex / Claude Code 等)里为论文配科研图。开文档(LaTeX 本地编译)、画锚点、本地规则层组装提示词、调出图、收审批。npm 安装即附带 promptfigure-local / promptfigure-api 两个 Agent Skill。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"pf": "bin/pf.mjs"
|
|
@@ -1,31 +1,41 @@
|
|
|
1
|
-
// build-adapters.mjs —
|
|
1
|
+
// build-adapters.mjs — skill 源 → 各 AI 宿主包装产物
|
|
2
2
|
// 🔴 adapters/ 下全部由本脚本生成,勿手改
|
|
3
|
-
// 🔴 skill
|
|
3
|
+
// 🔴 skill 源在 skill/ 下,一份内容两个 skill:
|
|
4
|
+
// promptfigure-local(依赖 pf CLI 的本地工作流)/ promptfigure-api(纯 REST)
|
|
5
|
+
// 两者随插件一起发行(zip 与 npm 包同此结构):装插件 = 同时拿到两个 skill。
|
|
4
6
|
import fs from "node:fs";
|
|
5
7
|
import path from "node:path";
|
|
6
8
|
import { fileURLToPath } from "node:url";
|
|
7
9
|
|
|
8
10
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
11
|
const ROOT = path.resolve(__dirname, "..");
|
|
10
|
-
const
|
|
12
|
+
const SKILLS = path.join(ROOT, "skill");
|
|
11
13
|
const ADAPTERS = path.join(ROOT, "adapters");
|
|
14
|
+
const PKG = JSON.parse(fs.readFileSync(path.join(ROOT, "package.json"), "utf8"));
|
|
15
|
+
const VERSION = PKG.version;
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
// 复制整个 skill 目录(SKILL.md + references/),目标不存在时建
|
|
18
|
+
function copySkillDir(name, destDir) {
|
|
19
|
+
fs.cpSync(path.join(SKILLS, name), destDir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const fs_rmSync = fs.rmSync;
|
|
23
|
+
fs_rmSync(ADAPTERS, { recursive: true, force: true });
|
|
15
24
|
|
|
16
25
|
// ---- Codex:plugin 目录(.codex-plugin/plugin.json + skills/ + marketplace.json)----
|
|
17
26
|
const codex = path.join(ADAPTERS, "codex", "promptfigure");
|
|
18
27
|
fs.mkdirSync(path.join(codex, ".codex-plugin"), { recursive: true });
|
|
19
|
-
|
|
20
|
-
|
|
28
|
+
for (const name of ["promptfigure-local", "promptfigure-api"]) {
|
|
29
|
+
copySkillDir(name, path.join(codex, "skills", name));
|
|
30
|
+
}
|
|
21
31
|
|
|
22
32
|
fs.writeFileSync(
|
|
23
33
|
path.join(codex, ".codex-plugin", "plugin.json"),
|
|
24
34
|
JSON.stringify(
|
|
25
35
|
{
|
|
26
36
|
name: "promptfigure",
|
|
27
|
-
version:
|
|
28
|
-
description: "promptFigure 本地插件:为论文配科研图(锚点定位 + 出图 +
|
|
37
|
+
version: VERSION,
|
|
38
|
+
description: "promptFigure 本地插件:为论文配科研图(锚点定位 + 出图 + 审批闭环),随包附带 promptfigure-api / promptfigure-local 两个 skill",
|
|
29
39
|
skills: "./skills/",
|
|
30
40
|
},
|
|
31
41
|
null,
|
|
@@ -51,25 +61,28 @@ fs.writeFileSync(
|
|
|
51
61
|
),
|
|
52
62
|
);
|
|
53
63
|
|
|
54
|
-
// ---- Claude Code:skill
|
|
64
|
+
// ---- Claude Code:skill 目录拷贝脚本(两个 skill 都装)----
|
|
55
65
|
const claude = path.join(ADAPTERS, "claude-code");
|
|
56
66
|
fs.mkdirSync(claude, { recursive: true });
|
|
57
|
-
|
|
67
|
+
for (const name of ["promptfigure-local", "promptfigure-api"]) {
|
|
68
|
+
copySkillDir(name, path.join(claude, name));
|
|
69
|
+
}
|
|
58
70
|
fs.writeFileSync(
|
|
59
71
|
path.join(claude, "install.mjs"),
|
|
60
|
-
`// 安装到 ~/.claude/skills
|
|
72
|
+
`// 安装到 ~/.claude/skills/(promptfigure-local + promptfigure-api 两个都装)
|
|
61
73
|
import fs from "node:fs";
|
|
62
74
|
import path from "node:path";
|
|
63
75
|
import os from "node:os";
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
fs.
|
|
68
|
-
console.log("✅ 已安装到 " + dest);
|
|
76
|
+
const here = (p) => new URL(p, import.meta.url).pathname.replace(/^\\/([A-Za-z]:)/, "$1");
|
|
77
|
+
for (const name of ["promptfigure-local", "promptfigure-api"]) {
|
|
78
|
+
const dest = path.join(os.homedir(), ".claude", "skills", name);
|
|
79
|
+
fs.cpSync(here("./" + name), dest, { recursive: true });
|
|
80
|
+
console.log("✅ 已安装到 " + dest);
|
|
81
|
+
}
|
|
69
82
|
`,
|
|
70
83
|
);
|
|
71
84
|
|
|
72
|
-
console.log("✅ adapters/
|
|
85
|
+
console.log("✅ adapters/ 已生成(v" + VERSION + ",两个 skill):");
|
|
73
86
|
for (const p of walk(ADAPTERS)) console.log(" " + path.relative(ROOT, p));
|
|
74
87
|
|
|
75
88
|
function walk(dir) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# 安装这个技能(AI Agent Skill)
|
|
2
|
+
|
|
3
|
+
> **版本 1.6.10**(2026-09-24)。下载页:https://promptfigure.top/skill 。查最新版:`curl -s https://promptfigure.top/downloads/promptfigure-api.version.json`;本地已装版本看 `SKILL.md` frontmatter 的 `version`。版本语义:主版本=接口不兼容改动(需重读 SKILL.md),次版本=新增能力,修订号=勘误。
|
|
4
|
+
|
|
5
|
+
把 `promptfigure-api/` 整个文件夹放进你的 AI 工具的技能目录即可:
|
|
6
|
+
|
|
7
|
+
| 工具 | 技能目录(复制到此处) |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Claude Code | `~/.claude/skills/promptfigure-api/` |
|
|
10
|
+
| Claude Desktop(Agent Skills) | 设置 → Skills → 导入本 zip,或放 `~/.claude/skills/` |
|
|
11
|
+
| WorkBuddy / OpenClaw | `~/.workbuddy/skills/promptfigure-api/` |
|
|
12
|
+
| Codex / Cursor / Cline 等任意 Agent | 无技能目录的,把 `SKILL.md` 内容追加到 `AGENTS.md` / `CLAUDE.md` / 规则文件末尾 |
|
|
13
|
+
|
|
14
|
+
安装后对 AI 说「帮我用 promptFigure 画一张 XXX 图」,它会自动读取 `SKILL.md` 并按流程执行:
|
|
15
|
+
注册/登录 → 拿 key(或复用你已有的 `PROMPTFIGURE_KEY`)→ 调 API 出图。
|
|
16
|
+
|
|
17
|
+
## 本包还附带本地插件(plugin/)
|
|
18
|
+
|
|
19
|
+
一个 zip 两样东西:根目录的 `SKILL.md` 是纯 REST 技能(上面的装法即用);
|
|
20
|
+
`plugin/` 是本地插件(`pf` CLI + promptfigure-local skill + 托盘)。想要「文档只读预览 /
|
|
21
|
+
锚点定位 / GUI 审批 / 本地规则层 / 矢量导出」这些本机能力时再装它:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
cd plugin && npm install && npm link # 之后 pf 命令全局可用
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
详见 [PLUGIN.md](PLUGIN.md);纯 REST 用户完全不用碰 plugin/。
|
|
28
|
+
|
|
29
|
+
## 需要准备
|
|
30
|
+
|
|
31
|
+
- 一个账号:https://promptfigure.top 注册(邮箱 + 密码 ≥8 位,无需邮箱验证)
|
|
32
|
+
- 余额:控制台充值($1 起整数,每满 $50 赠 $1);API 按次计费 standard $0.02 / premium $0.15
|
|
33
|
+
- API key:控制台「API 密钥」创建,`pf_` 开头明文只显示一次
|
|
34
|
+
|
|
35
|
+
## 保持最新
|
|
36
|
+
|
|
37
|
+
技能会过期。程序化查最新版本(不用下载整个包):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
curl -s https://promptfigure.top/downloads/promptfigure-api.version.json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
本地 `version` 低于线上 `version` → 到下载页取最新包:https://promptfigure.top/skill
|
|
44
|
+
(直链:https://promptfigure.top/downloads/promptfigure-api.zip ,或 GitHub Release 资产 promptfigure-api-1.6.10.zip)
|
|
45
|
+
安装说明与 API 文档:https://promptfigure.top/docs/zh-CN/api
|