codebee 0.1.87 → 0.1.88
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/CHANGELOG.md +5 -0
- package/README.md +3 -4
- package/app/main.py +11 -0
- package/app/ui/app.js +45 -3
- package/app/ui/i18n.js +3 -0
- package/app/ui/style.css +12 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,11 @@ README 元数据带回,供老版本在「发现新版本」时展示新版更
|
|
|
6
6
|
|
|
7
7
|
## 未发布
|
|
8
8
|
|
|
9
|
+
## v0.1.88(2026-10-06)
|
|
10
|
+
|
|
11
|
+
- **封面生成前提示词预览确认**:「生成封面」先只读展示将使用的图像提示词(新增 GET /api/tasks/{id}/cover/prompt,不触发任何模型/图像调用),确认后才走付费生成链——防误触花钱、封面元素所见即所得;取消零请求。
|
|
12
|
+
- **调研沉淀**:09-13 时班全类型竞品雷达(批2 学习记忆/批5 检索知识/批6 框架生态)与封面预览 12 项回归测试入库。
|
|
13
|
+
|
|
9
14
|
## v0.1.87(2026-10-06)
|
|
10
15
|
|
|
11
16
|
- **全类型注册表对账**:任务类型注册表(18 型)与调度维度表、跑前耗时预估表逐一对账——修复「禅道工单」改型「缺陷复盘」后调度维度漏配(长期靠兜底回落)与一处死映射;补齐演示文稿/标书/缺陷复盘三型的跑前耗时预估(此前一律回落统一档,预估失真)。日后加型漏配、删型留尸会在测试先红。
|
package/README.md
CHANGED
|
@@ -33,11 +33,10 @@ Trae Agent、OpenClaw……),提供
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
35
|
<!-- relnotes:start -->
|
|
36
|
-
### 最新版更新内容(v0.1.
|
|
36
|
+
### 最新版更新内容(v0.1.88)
|
|
37
37
|
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
- 插件市场外部目录提示行补 CocoLoop,六源与实现一致
|
|
38
|
+
- 封面生成前提示词预览确认:点「生成封面」先只读展示图像提示词,确认后才调用图像接口——防误触付费、所见即所得
|
|
39
|
+
- 调研沉淀与封面预览 12 项回归测试入库
|
|
41
40
|
<!-- relnotes:end -->
|
|
42
41
|
|
|
43
42
|
|
package/app/main.py
CHANGED
|
@@ -623,6 +623,17 @@ class Handler(BaseHTTPRequestHandler):
|
|
|
623
623
|
p: store.chain_book_meta(task, p)
|
|
624
624
|
for p in ("fanqie", "qimao")
|
|
625
625
|
if store.chain_book_meta(task, p)}})
|
|
626
|
+
m = re.match(r"^/api/tasks/([^/]+)/cover/prompt$", path)
|
|
627
|
+
if m:
|
|
628
|
+
# 封面提示词预览(只读,drama-skills 借鉴③「先预览确认再生产」):
|
|
629
|
+
# 生成前先回 _cover_prompt 结果给前端展示,用户确认后再走
|
|
630
|
+
# POST /cover 付费链。纯只读,不触发任何模型/图像调用。
|
|
631
|
+
task = store.get_task(m.group(1))
|
|
632
|
+
if not task:
|
|
633
|
+
return self._json(404, {"error": "not found"})
|
|
634
|
+
from core import covergen
|
|
635
|
+
return self._json(200, {"ok": True,
|
|
636
|
+
"prompt": covergen._cover_prompt(task)})
|
|
626
637
|
if path == "/api/publish":
|
|
627
638
|
# 一键发布:平台连接状态 + 最近台账(详情页发布面板)
|
|
628
639
|
from core.publish import manager as pub
|
package/app/ui/app.js
CHANGED
|
@@ -10,7 +10,7 @@ function codebeeDocumentTitle(lang) {
|
|
|
10
10
|
document.title = codebeeDocumentTitle((localStorage.getItem("orch.lang") || "zh").toLowerCase());
|
|
11
11
|
|
|
12
12
|
const $ = (id) => document.getElementById(id);
|
|
13
|
-
const S = { state: null, catalog: null, catSig: "", providers: null, bindings: null, modelsSig: "", bindSig: "", tab: "tasks", mainPage: "", /* 主栏正显示的全局页("" = 新建任务表单);左栏是任务树还是设置导航看 body.settings-mode */ detailRunId: null, pollTimer: null, showArchived: false, /* 会话内开关:每次加载默认隐藏已归档、图标不选中(不持久化,见 btn-side-arch) */ selProvs: {}, selModels: {}, selRuns: {}, provStatus: "enabled", mlistStatus: "enabled", /* 供应商/模型列表状态过滤:默认只看启用,停用的点对应 chip 才现身 */ bindSel: {}, catalogChecking: false, updateCheckAt: 0, control: null, sseLive: false, es: null, flows: null, orch: null, skills: null, orchSig: "", settings: null, sessionAgents: new Set(), atts: [], gitInfo: null, gitWb: null, gitWbKey: "", gitWbAt: 0, gitWbBusy: false, creatingTask: false, inspKey: null, inspData: null, inspSig: "", inspAt: 0, inspTab: "git", inspAutoSig: "", rdTab: null, rdTabSig: "", rdTabPin: false, rdHiveFirst: false, _rdCtx: {}, taskContracts: {}, lastPrefs: null, prefsApplied: false, sideUsage: null, sideUsageAt: 0, ovUsage: null, ovDays: undefined };
|
|
13
|
+
const S = { state: null, catalog: null, catSig: "", providers: null, bindings: null, modelsSig: "", bindSig: "", tab: "tasks", mainPage: "", /* 主栏正显示的全局页("" = 新建任务表单);左栏是任务树还是设置导航看 body.settings-mode */ detailRunId: null, pollTimer: null, showArchived: false, /* 会话内开关:每次加载默认隐藏已归档、图标不选中(不持久化,见 btn-side-arch) */ selProvs: {}, selModels: {}, selRuns: {}, provStatus: "enabled", mlistStatus: "enabled", /* 供应商/模型列表状态过滤:默认只看启用,停用的点对应 chip 才现身 */ bindSel: {}, catalogChecking: false, updateCheckAt: 0, control: null, sseLive: false, es: null, flows: null, orch: null, skills: null, orchSig: "", settings: null, sessionAgents: new Set(), atts: [], gitInfo: null, gitWb: null, gitWbKey: "", gitWbAt: 0, gitWbBusy: false, creatingTask: false, inspKey: null, inspData: null, inspSig: "", inspAt: 0, inspTab: "git", inspAutoSig: "", rdTab: null, rdTabSig: "", rdTabPin: false, rdHiveFirst: false, _rdCtx: {}, taskContracts: {}, lastPrefs: null, prefsApplied: false, sideUsage: null, sideUsageAt: 0, ovUsage: null, ovDays: undefined, coverPrompt: null };
|
|
14
14
|
|
|
15
15
|
/* ---------------------------------------------------------- 内置浏览器工作区 */
|
|
16
16
|
const BROWSER_STORAGE_KEY = "orch.browser.workspace.v1";
|
|
@@ -5812,10 +5812,24 @@ function renderBookMetaPanel(task) {
|
|
|
5812
5812
|
cgBody = '<div class="bm-empty">' + esc(t("生成竖版封面插画,产出 cover.png")) + "</div>";
|
|
5813
5813
|
}
|
|
5814
5814
|
const cgBusy = taskBusy || cgSt === "running";
|
|
5815
|
+
// 生成前提示词预览确认(drama-skills 借鉴③「先预览确认再生产」):点
|
|
5816
|
+
// 「生成封面」先只读拉提示词展示,确认后才走 coverGen 的 POST 付费链;
|
|
5817
|
+
// S.coverPrompt 让预览态跨轮询重绘保持(同 bmRenaming 模式)
|
|
5818
|
+
// 排除 running(生成中不出确认钮)与 done(已出图预览无意义,挂回 done 卡误导)
|
|
5819
|
+
const cgPrev = (S.coverPrompt && S.coverPrompt.taskId === task.id
|
|
5820
|
+
&& cgSt !== "running" && cgSt !== "done") ? S.coverPrompt : null;
|
|
5815
5821
|
const cgAction = cgSt === "running"
|
|
5816
5822
|
? '<button class="ghost" disabled><svg class="ico spin" aria-hidden="true"><use href="#i-refresh"/></svg>' + t("生成中…") + "</button>"
|
|
5817
|
-
:
|
|
5818
|
-
|
|
5823
|
+
: cgPrev
|
|
5824
|
+
? '<button class="primary" onclick="coverConfirm(\'' + jsq(task.id) + '\')">' + t("确认生成") + "</button>" +
|
|
5825
|
+
'<button class="ghost" onclick="coverCancel(\'' + jsq(task.id) + '\')">' + t("取消") + "</button>"
|
|
5826
|
+
: '<button class="primary" onclick="coverPreview(\'' + jsq(task.id) + '\')">' +
|
|
5827
|
+
(cgSt === "failed" ? t("重试") : t("生成封面")) + "</button>";
|
|
5828
|
+
if (cgPrev) {
|
|
5829
|
+
cgBody += '<div class="bm-cover-preview"><div class="bm-cover-preview-hint">' +
|
|
5830
|
+
esc(t("生成前请确认图像提示词(确认后才调用图像接口):")) + "</div>" +
|
|
5831
|
+
'<div class="bm-cover-preview-text">' + esc(cgPrev.prompt || "") + "</div></div>";
|
|
5832
|
+
}
|
|
5819
5833
|
html += '<div class="bm-cards"><div class="bm-card st-' + (cgSt || "new") + '">' +
|
|
5820
5834
|
'<div class="bm-card-head"><span class="bm-plat-name"><svg class="ico" aria-hidden="true"><use href="#i-book-open"/></svg>' + esc(t("封面图")) + "</span>" +
|
|
5821
5835
|
bmStatusChip(cgSt) + '<span class="flex1"></span>' + cgAction + "</div>" + cgBody + "</div></div>";
|
|
@@ -5880,6 +5894,34 @@ window.coverGen = async function (taskId) {
|
|
|
5880
5894
|
} catch (e) { toast(t("封面生成失败:") + e.message, true); }
|
|
5881
5895
|
};
|
|
5882
5896
|
|
|
5897
|
+
/* 生成前提示词预览(drama-skills 借鉴③「先预览确认再生产」):只读拉取
|
|
5898
|
+
* 后端 _cover_prompt 结果展示,不发图像请求;「确认生成」才走既有 coverGen
|
|
5899
|
+
* 的 POST /cover 付费链,「取消」只清预览态重绘、零请求。
|
|
5900
|
+
* 三个处理器都作废详情签名再 render:S.coverPrompt 不在 drawTaskDetail/
|
|
5901
|
+
* renderRunDetail 的数据签名里,服务端数据没变时守卫会整帧跳过重绘
|
|
5902
|
+
* (bmRename 同陷阱,见其 :5877 注释)——不作废则预览框不上屏、取消后残留。 */
|
|
5903
|
+
function coverInvalidateDetail() {
|
|
5904
|
+
S.taskSig = "";
|
|
5905
|
+
S.runDetailSig = "";
|
|
5906
|
+
render();
|
|
5907
|
+
}
|
|
5908
|
+
window.coverPreview = async function (taskId) {
|
|
5909
|
+
try {
|
|
5910
|
+
const r = await api("/api/tasks/" + encodeURIComponent(taskId) + "/cover/prompt");
|
|
5911
|
+
S.coverPrompt = { taskId: taskId, prompt: r.prompt || "" };
|
|
5912
|
+
coverInvalidateDetail();
|
|
5913
|
+
} catch (e) { toast(t("封面提示词获取失败:") + e.message, true); }
|
|
5914
|
+
};
|
|
5915
|
+
window.coverConfirm = function (taskId) {
|
|
5916
|
+
S.coverPrompt = null;
|
|
5917
|
+
coverInvalidateDetail(); // 先归位成单按钮再发 POST,失败时界面不留旧预览框
|
|
5918
|
+
window.coverGen(taskId);
|
|
5919
|
+
};
|
|
5920
|
+
window.coverCancel = function (taskId) {
|
|
5921
|
+
if (S.coverPrompt && S.coverPrompt.taskId === taskId) S.coverPrompt = null;
|
|
5922
|
+
coverInvalidateDetail();
|
|
5923
|
+
};
|
|
5924
|
+
|
|
5883
5925
|
window.bmCopyBtn = function (btn) {
|
|
5884
5926
|
// 只在真实复制成功后报「已复制」——剪贴板不可用时 fallbackCopy 会弹失败提示
|
|
5885
5927
|
copyText(btn.dataset.text || "", () => toast(t("已复制:") + (btn.dataset.label || "")));
|
package/app/ui/i18n.js
CHANGED
|
@@ -2134,6 +2134,9 @@
|
|
|
2134
2134
|
"生成竖版封面插画,产出 cover.png": "Generate a portrait cover illustration → cover.png",
|
|
2135
2135
|
"封面生成失败:": "Cover generation failed: ",
|
|
2136
2136
|
"已开始生成封面,完成后这里会自动更新": "Cover generation started — this panel updates automatically when done",
|
|
2137
|
+
"确认生成": "Confirm & generate",
|
|
2138
|
+
"生成前请确认图像提示词(确认后才调用图像接口):": "Confirm the image prompt before generating (the image API is only called after confirmation):",
|
|
2139
|
+
"封面提示词获取失败:": "Failed to fetch cover prompt: ",
|
|
2137
2140
|
"已开始生成,完成后这里会自动更新": "Generation started — this panel updates automatically when done",
|
|
2138
2141
|
"来源:": "Source: ",
|
|
2139
2142
|
"(待补充)": "(to fill)",
|
package/app/ui/style.css
CHANGED
|
@@ -7084,3 +7084,15 @@ main.browser-page-active #page-settings > #sub-browser .browser-shell {
|
|
|
7084
7084
|
.foot-btn.kill { color: var(--bad); }
|
|
7085
7085
|
.foot-btn.kill:hover { color: #fff; background: var(--bad); }
|
|
7086
7086
|
.foot-btn.kill.busy { opacity: .5; pointer-events: none; }
|
|
7087
|
+
|
|
7088
|
+
/* 封面提示词预览框(生成前确认,drama-skills 借鉴③「先预览确认再生产」;
|
|
7089
|
+
* 追加尾防并行重排):面板内换行展示将使用的提示词,限高可滚动,取消不落任何请求 */
|
|
7090
|
+
.bm-cover-preview {
|
|
7091
|
+
margin: 0 18px 14px; border: 1px solid var(--border); border-radius: 10px;
|
|
7092
|
+
background: var(--panel); padding: 10px 12px;
|
|
7093
|
+
}
|
|
7094
|
+
.bm-cover-preview-hint { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
|
|
7095
|
+
.bm-cover-preview-text {
|
|
7096
|
+
font-size: 12.5px; line-height: 1.65; white-space: pre-wrap; word-break: break-word;
|
|
7097
|
+
max-height: 180px; overflow: auto; color: var(--text);
|
|
7098
|
+
}
|
package/package.json
CHANGED