codex-work-receipt 0.7.0 → 0.7.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/CHANGELOG.md +4 -0
- package/README.en.md +11 -1
- package/README.md +11 -1
- package/docs/cli.en.md +1 -1
- package/docs/cli.md +1 -1
- package/docs/images/codex-pet-showcase.png +0 -0
- package/package.json +1 -1
- package/src/core/presentation.mjs +2 -0
- package/src/renderers/html.mjs +60 -17
package/CHANGELOG.md
CHANGED
package/README.en.md
CHANGED
|
@@ -24,6 +24,16 @@ Codex Work Receipt summarizes turns, tool calls, Tokens, duration, and models, t
|
|
|
24
24
|
|
|
25
25
|
Version `0.6.0` uses the cwr2 protocol to create stable privacy-safe facts for each session and calendar day. Overlapping today, last-seven-days, and this-week receipts can be deduplicated by the receiver, and oversized payloads are automatically split into reorderable multipart QR codes that rotate one at a time in the HTML so the camera never sees multiple data codes at once.
|
|
26
26
|
|
|
27
|
+
## Meet Ticket Buddy
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<a href="docs/codex-pet.en.md"><img src="docs/images/codex-pet-showcase.png" alt="Ticket Buddy in idle, working, needs-input, ready, and failed states" width="920"></a>
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<sub>Ticket Buddy changes expression as Codex becomes idle, runs a task, needs input, finishes, or gets blocked. Select the image for setup and state details.</sub>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
27
37
|
## Quickstart
|
|
28
38
|
|
|
29
39
|
Requires Node.js 20+ and local Codex session records. No clone required; choose today, the last 3 hours, the last 7 days, this week, or a specific session:
|
|
@@ -44,7 +54,7 @@ Summarize the last 3 hours:
|
|
|
44
54
|
npx codex-work-receipt@latest --hours 3 --lang en
|
|
45
55
|
```
|
|
46
56
|
|
|
47
|
-
HTML and structured data are written to `./codex-work-receipt-output/` by default. The generated page can save a high-resolution PNG containing the full receipt and QR
|
|
57
|
+
HTML and structured data are written to `./codex-work-receipt-output/` by default. The generated page can save a high-resolution PNG containing only the full receipt and WeChat mini-program code; data QR codes are excluded. Non-interactive options such as `--latest` and `--today` remain available; see the [CLI guide](docs/cli.en.md).
|
|
48
58
|
|
|
49
59
|
## Ask Codex directly
|
|
50
60
|
|
package/README.md
CHANGED
|
@@ -24,6 +24,16 @@
|
|
|
24
24
|
|
|
25
25
|
`0.6.0` 使用 cwr2 协议,按“会话 × 自然日”生成稳定的脱敏事实。今日、近 7 日和本周小票即使范围重叠,接收端也能识别相同工作;数据过大时会自动生成多张可重组的分片二维码,并在 HTML 中逐张自动轮播,避免镜头同时识别多个数据码。
|
|
26
26
|
|
|
27
|
+
## 认识票仔
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<a href="docs/codex-pet.md"><img src="docs/images/codex-pet-showcase.png" alt="票仔 AI 小票工的待机、打工、等待确认、完成和失败状态" width="920"></a>
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<sub>票仔会跟随 Codex 的空闲、执行、等待确认、完成和失败状态切换表情。点击图片查看安装与状态说明。</sub>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
27
37
|
## Quickstart
|
|
28
38
|
|
|
29
39
|
需要 Node.js 20 或更高版本,并且本机已经使用过 Codex。无需克隆仓库,运行后选择“今天 / 最近 3 小时 / 近 7 日 / 本周 / 指定会话”:
|
|
@@ -44,7 +54,7 @@ npx codex-work-receipt@latest --today
|
|
|
44
54
|
npx codex-work-receipt@latest --hours 3
|
|
45
55
|
```
|
|
46
56
|
|
|
47
|
-
网页和结构数据默认保存在 `./codex-work-receipt-output
|
|
57
|
+
网页和结构数据默认保存在 `./codex-work-receipt-output/`。生成的网页支持一键保存只包含完整小票和微信小程序码的高清长图,数据二维码不会进入图片。也可以继续使用 `--latest`、`--today` 等非交互参数,详见 [CLI 使用文档](docs/cli.md)。
|
|
48
58
|
|
|
49
59
|
## 直接跟 Codex 说
|
|
50
60
|
|
package/docs/cli.en.md
CHANGED
|
@@ -87,7 +87,7 @@ Default output:
|
|
|
87
87
|
|
|
88
88
|
Default filenames include the calendar range. Latest-session and selected-session receipts include a short identifier so receipts from different dates or sessions do not overwrite one another.
|
|
89
89
|
|
|
90
|
-
Open the generated HTML and click “Save full PNG” to download a high-resolution image. It
|
|
90
|
+
Open the generated HTML and click “Save full PNG” to download a high-resolution image. It contains only the complete main receipt and WeChat mini-program code in the currently selected theme. Data QR codes, multipart data codes, theme controls, the page background, and the footer note are excluded. The HTML page still presents data codes normally: a single code stays beside the mini-program code, while oversized cwr2 payloads rotate their parts after the mini program has been opened so they can be imported on the phone.
|
|
91
91
|
|
|
92
92
|
Set a timezone and output path:
|
|
93
93
|
|
package/docs/cli.md
CHANGED
|
@@ -87,7 +87,7 @@ npx codex-work-receipt@latest --latest --theme diner
|
|
|
87
87
|
|
|
88
88
|
默认文件名会携带统计日期范围;最近会话和指定会话则携带短编号,避免不同日期或会话的小票互相覆盖。
|
|
89
89
|
|
|
90
|
-
打开生成的 HTML 后,点击“保存完整长图”即可下载高清 PNG
|
|
90
|
+
打开生成的 HTML 后,点击“保存完整长图”即可下载高清 PNG。图片只包含完整主小票和微信小程序码,并自动使用当前选择的主题;数据二维码、分片数据码、主题按钮、网页背景和底部说明都不会进入图片。网页本身仍会正常展示数据二维码:单码时与小程序码并排,cwr2 超出单码安全容量时则在打开小程序后自动逐张轮播分片数据码,供用户在小程序中完成导入。
|
|
91
91
|
|
|
92
92
|
指定时区和输出路径:
|
|
93
93
|
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -142,6 +142,7 @@ const RECEIPT_COPY = {
|
|
|
142
142
|
multipartRestart: "重新显示小程序码",
|
|
143
143
|
dataQrAlt: "当前小票数据二维码",
|
|
144
144
|
miniProgramAlt: "微信小程序码",
|
|
145
|
+
exportMiniProgramLabel: "微信扫码打开小程序",
|
|
145
146
|
placeholderLabel: "小程序码",
|
|
146
147
|
placeholderValue: "待接入",
|
|
147
148
|
placeholderAria: "小程序码待接入",
|
|
@@ -215,6 +216,7 @@ const RECEIPT_COPY = {
|
|
|
215
216
|
multipartRestart: "Show mini-program code again",
|
|
216
217
|
dataQrAlt: "Current receipt data QR code",
|
|
217
218
|
miniProgramAlt: "WeChat mini-program code",
|
|
219
|
+
exportMiniProgramLabel: "Scan to open the mini program",
|
|
218
220
|
placeholderLabel: "Mini program",
|
|
219
221
|
placeholderValue: "Pending",
|
|
220
222
|
placeholderAria: "Mini-program code pending",
|
package/src/renderers/html.mjs
CHANGED
|
@@ -91,6 +91,7 @@ export function renderHtml({ record, dataQrDataUrl = null, dataQrDataUrls = null
|
|
|
91
91
|
busyLabel: copy.exportingImage,
|
|
92
92
|
successLabel: copy.exportSuccess,
|
|
93
93
|
errorLabel: copy.exportError,
|
|
94
|
+
miniProgramLabel: copy.exportMiniProgramLabel,
|
|
94
95
|
fileBase: `codex-work-receipt-${record.source.scope}-${spansMultipleDates ? `${rangeStartDate}-to-${rangeEndDate}` : `${rangeEndDate}-${record.id.slice(4, 12)}`}`,
|
|
95
96
|
}).replaceAll("<", "\\u003c");
|
|
96
97
|
const rows = [
|
|
@@ -151,7 +152,7 @@ export function renderHtml({ record, dataQrDataUrl = null, dataQrDataUrls = null
|
|
|
151
152
|
<div class="qr-grid qr-grid--export-only" hidden>
|
|
152
153
|
<div class="qr-item">
|
|
153
154
|
<div class="qr-frame">${miniProgramVisual}</div>
|
|
154
|
-
<strong>${escapeHtml(copy.openMiniProgram)}</strong>
|
|
155
|
+
<strong data-export-mini-label>${escapeHtml(copy.openMiniProgram)}</strong>
|
|
155
156
|
<span>${escapeHtml(copy.openMiniProgramHint)}</span>
|
|
156
157
|
</div>
|
|
157
158
|
${dataQrItems}
|
|
@@ -160,7 +161,7 @@ export function renderHtml({ record, dataQrDataUrl = null, dataQrDataUrls = null
|
|
|
160
161
|
<div class="qr-grid qr-grid--single">
|
|
161
162
|
<div class="qr-item">
|
|
162
163
|
<div class="qr-frame">${miniProgramVisual}</div>
|
|
163
|
-
<strong>${escapeHtml(copy.openMiniProgram)}</strong>
|
|
164
|
+
<strong data-export-mini-label>${escapeHtml(copy.openMiniProgram)}</strong>
|
|
164
165
|
<span>${escapeHtml(copy.openMiniProgramHint)}</span>
|
|
165
166
|
</div>
|
|
166
167
|
${dataQrItems}
|
|
@@ -692,6 +693,50 @@ export function renderHtml({ record, dataQrDataUrl = null, dataQrDataUrls = null
|
|
|
692
693
|
}));
|
|
693
694
|
}
|
|
694
695
|
|
|
696
|
+
function sanitizeExportNode(node) {
|
|
697
|
+
const multipartLiveNode = node.querySelector(".multipart-live");
|
|
698
|
+
if (multipartLiveNode) multipartLiveNode.remove();
|
|
699
|
+
|
|
700
|
+
const exportGridNode = node.querySelector(".qr-grid--export-only");
|
|
701
|
+
if (exportGridNode) {
|
|
702
|
+
exportGridNode.removeAttribute("hidden");
|
|
703
|
+
exportGridNode.style.display = "grid";
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
node.querySelectorAll("[data-data-qr-index]").forEach((item) => item.remove());
|
|
707
|
+
node.querySelectorAll(".qr-grid").forEach((grid) => {
|
|
708
|
+
grid.style.gridTemplateColumns = "minmax(0, 1fr)";
|
|
709
|
+
grid.style.justifyItems = "center";
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
const miniProgramLabel = node.querySelector("[data-export-mini-label]");
|
|
713
|
+
if (miniProgramLabel) miniProgramLabel.textContent = exportConfig.miniProgramLabel;
|
|
714
|
+
const transferDescription = node.querySelector(".transfer-heading p");
|
|
715
|
+
if (transferDescription) transferDescription.remove();
|
|
716
|
+
const transferNote = node.querySelector(".transfer-note");
|
|
717
|
+
if (transferNote) transferNote.remove();
|
|
718
|
+
|
|
719
|
+
node.querySelectorAll(".paper").forEach((paper) => {
|
|
720
|
+
paper.style.boxShadow = "none";
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
function createExportNode(source, paperColor) {
|
|
725
|
+
const clone = source.cloneNode(true);
|
|
726
|
+
sanitizeExportNode(clone);
|
|
727
|
+
const sourceWidth = Math.ceil(source.getBoundingClientRect().width || source.scrollWidth);
|
|
728
|
+
Object.assign(clone.style, {
|
|
729
|
+
position: "absolute",
|
|
730
|
+
left: "-100000px",
|
|
731
|
+
top: "0",
|
|
732
|
+
width: sourceWidth + "px",
|
|
733
|
+
background: paperColor,
|
|
734
|
+
pointerEvents: "none",
|
|
735
|
+
});
|
|
736
|
+
document.body.appendChild(clone);
|
|
737
|
+
return clone;
|
|
738
|
+
}
|
|
739
|
+
|
|
695
740
|
function downloadImage(dataUrl, filename) {
|
|
696
741
|
const link = document.createElement("a");
|
|
697
742
|
link.href = dataUrl;
|
|
@@ -708,15 +753,17 @@ export function renderHtml({ record, dataQrDataUrl = null, dataQrDataUrls = null
|
|
|
708
753
|
exportButton.disabled = true;
|
|
709
754
|
exportButton.textContent = exportConfig.busyLabel;
|
|
710
755
|
setExportStatus("");
|
|
756
|
+
let renderNode = null;
|
|
711
757
|
|
|
712
758
|
try {
|
|
713
759
|
if (document.fonts?.ready) await document.fonts.ready;
|
|
714
|
-
await waitForImages(exportNode);
|
|
715
|
-
const width = Math.ceil(exportNode.scrollWidth);
|
|
716
|
-
const height = Math.ceil(exportNode.scrollHeight);
|
|
717
|
-
const scale = Math.max(2, Math.min(3, 1500 / Math.max(1, width)));
|
|
718
760
|
const paperColor = getComputedStyle(document.documentElement).getPropertyValue("--paper").trim() || "#ffffff";
|
|
719
|
-
|
|
761
|
+
renderNode = createExportNode(exportNode, paperColor);
|
|
762
|
+
await waitForImages(renderNode);
|
|
763
|
+
const width = Math.ceil(renderNode.scrollWidth);
|
|
764
|
+
const height = Math.ceil(renderNode.scrollHeight);
|
|
765
|
+
const scale = Math.max(2, Math.min(3, 1500 / Math.max(1, width)));
|
|
766
|
+
const dataUrl = await domtoimage.toPng(renderNode, {
|
|
720
767
|
width,
|
|
721
768
|
height,
|
|
722
769
|
scale,
|
|
@@ -725,17 +772,12 @@ export function renderHtml({ record, dataQrDataUrl = null, dataQrDataUrls = null
|
|
|
725
772
|
cacheBust: false,
|
|
726
773
|
style: { background: paperColor },
|
|
727
774
|
onclone(clone) {
|
|
775
|
+
sanitizeExportNode(clone);
|
|
776
|
+
clone.style.position = "static";
|
|
777
|
+
clone.style.left = "auto";
|
|
778
|
+
clone.style.top = "auto";
|
|
779
|
+
clone.style.width = width + "px";
|
|
728
780
|
clone.style.background = paperColor;
|
|
729
|
-
const multipartLiveClone = clone.querySelector(".multipart-live");
|
|
730
|
-
if (multipartLiveClone) multipartLiveClone.remove();
|
|
731
|
-
const exportGridClone = clone.querySelector(".qr-grid--export-only");
|
|
732
|
-
if (exportGridClone) {
|
|
733
|
-
exportGridClone.removeAttribute("hidden");
|
|
734
|
-
exportGridClone.style.display = "grid";
|
|
735
|
-
}
|
|
736
|
-
clone.querySelectorAll(".paper").forEach((paper) => {
|
|
737
|
-
paper.style.boxShadow = "none";
|
|
738
|
-
});
|
|
739
781
|
},
|
|
740
782
|
logger: {},
|
|
741
783
|
});
|
|
@@ -748,6 +790,7 @@ export function renderHtml({ record, dataQrDataUrl = null, dataQrDataUrls = null
|
|
|
748
790
|
console.error(error);
|
|
749
791
|
setExportStatus(exportConfig.errorLabel, "error");
|
|
750
792
|
} finally {
|
|
793
|
+
if (renderNode) renderNode.remove();
|
|
751
794
|
exportButton.disabled = false;
|
|
752
795
|
exportButton.textContent = exportConfig.idleLabel;
|
|
753
796
|
}
|