@open-press/cli 0.3.0 → 0.5.0
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/dist/cli.js +20 -37
- package/package.json +1 -1
- package/template/core/CHANGELOG.md +43 -0
- package/template/core/engine/cli.mjs +6 -0
- package/template/core/engine/commands/_shared.mjs +9 -2
- package/template/core/engine/commands/deploy.mjs +3 -3
- package/template/core/engine/commands/dev.mjs +25 -2
- package/template/core/engine/commands/doctor.mjs +229 -0
- package/template/core/engine/commands/pdf.mjs +3 -3
- package/template/core/engine/commands/preview.mjs +4 -4
- package/template/core/engine/commands/upgrade.mjs +117 -0
- package/template/core/package.json +3 -1
- package/template/core/vite.config.ts +26 -11
- package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/chapters/03-agent-skills-contributors/content/01-agent-skills-contributors.mdx +2 -3
- package/template/core/.turbo/turbo-test.log +0 -341
- package/template/skills/chinese-ai-writing-polish/SKILL.md +0 -195
- package/template/skills/claude-document/SKILL.md +0 -66
- package/template/skills/editorial-monograph/SKILL.md +0 -73
- package/template/skills/openpress/SKILL.md +0 -114
- package/template/skills/openpress/references/cli-commands.md +0 -31
- package/template/skills/openpress/references/local-review.md +0 -43
- package/template/skills/openpress-deploy/SKILL.md +0 -69
- package/template/skills/openpress-deploy/references/cloudflare-pages.md +0 -51
- package/template/skills/openpress-design/SKILL.md +0 -51
- package/template/skills/openpress-design/references/pdf-safe-css.md +0 -29
- package/template/skills/openpress-design/references/responsive-fixed-layout.md +0 -48
- package/template/skills/openpress-design/references/theme-and-components.md +0 -77
- package/template/skills/openpress-diagram-drawing/SKILL.md +0 -44
- package/template/skills/openpress-diagram-drawing/references/diagram-patterns.md +0 -93
- package/template/skills/openpress-document-hierarchy/SKILL.md +0 -81
- package/template/skills/openpress-document-hierarchy/agents/openai.yaml +0 -4
- package/template/skills/openpress-document-hierarchy/references/data-structures-outline.md +0 -115
- package/template/skills/openpress-init/SKILL.md +0 -84
- package/template/skills/openpress-style-pack-contributor/SKILL.md +0 -62
- package/template/skills/openpress-style-pack-contributor/references/starter-contract.md +0 -49
- package/template/skills/openpress-update/SKILL.md +0 -88
- package/template/skills/openpress-writing/SKILL.md +0 -68
- package/template/skills/openpress-writing/references/source-and-writing-rules.md +0 -120
- package/template/skills/teaching-notes-writing/SKILL.md +0 -54
- package/template/skills/teaching-notes-writing/references/programming.md +0 -65
- package/template/skills/teaching-notes-writing/references/teaching-patterns.md +0 -60
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/chapters/01-document-shape/chapter.tsx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/chapters/01-document-shape/content/01-document-shape.mdx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/chapters/02-review-loop/chapter.tsx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/chapters/02-review-loop/content/01-review-loop.mdx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/components/ChapterOpenerVisual.tsx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/components/Page.tsx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/design.md +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/index.tsx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/media/README.md +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/openpress.config.mjs +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/README.md +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/base/page-contract.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/base/print.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/base/typography.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/fonts.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/page-surfaces/back-cover.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/page-surfaces/chapter-opener.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/page-surfaces/cover.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/page-surfaces/toc.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/patterns/_chart-frame.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/patterns/figure-grid.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/patterns/table-utilities.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/shell/reader-controls.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/tokens.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/openpress.config.mjs +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/chapters/01-product-and-use-cases/content/01-product-and-use-cases.mdx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/chapters/02-workflow/content/01-workflow.mdx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/chapters/04-validation-deploy/content/01-validation-deploy.mdx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/components/ChapterOpenerVisual/index.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/components/Page.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/components/TokenSwatchGrid/index.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/components/TokenSwatchGrid/style.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/components/TypeSpecimen/index.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/components/TypeSpecimen/style.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/design.md +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/index.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/media/README.md +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/openpress.config.mjs +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/README.md +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/base/page-contract.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/base/print.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/base/typography.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/fonts.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/page-surfaces/back-cover.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/page-surfaces/chapter-opener.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/page-surfaces/cover.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/page-surfaces/toc.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/patterns/_chart-frame.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/patterns/figure-grid.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/patterns/table-utilities.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/shell/reader-controls.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/tokens.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/openpress.config.mjs +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { diagnose } from "./doctor.mjs";
|
|
5
|
+
import { runCommand } from "./_shared.mjs";
|
|
6
|
+
|
|
7
|
+
export async function run({ root, options }) {
|
|
8
|
+
const dryRun = Boolean(options?.dryRun);
|
|
9
|
+
const skipSkills = Boolean(options?.noSkills);
|
|
10
|
+
const skipDeps = Boolean(options?.noDeps);
|
|
11
|
+
const json = Boolean(options?.json);
|
|
12
|
+
|
|
13
|
+
// 1. Fresh diagnose (force re-check, ignore cache).
|
|
14
|
+
const before = await diagnose(root, { noCache: true });
|
|
15
|
+
|
|
16
|
+
if (!before.stale) {
|
|
17
|
+
const message = "open-press is already up to date.";
|
|
18
|
+
if (json) {
|
|
19
|
+
process.stdout.write(JSON.stringify({ status: "noop", before }, null, 2) + "\n");
|
|
20
|
+
} else {
|
|
21
|
+
process.stdout.write(`✓ ${message}\n`);
|
|
22
|
+
}
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!json) {
|
|
27
|
+
process.stdout.write("○ open-press upgrade\n\n");
|
|
28
|
+
if (before.coreUpdateAvailable) {
|
|
29
|
+
process.stdout.write(
|
|
30
|
+
` @open-press/core: ${before.coreVersion} → ${before.coreLatest}\n`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
if (before.pendingMigrations.length > 0) {
|
|
34
|
+
process.stdout.write(` migration notes: ${before.pendingMigrations.join(", ")}\n`);
|
|
35
|
+
}
|
|
36
|
+
process.stdout.write("\n");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (dryRun) {
|
|
40
|
+
if (!json) {
|
|
41
|
+
process.stdout.write("dry run — nothing changed. The agent should:\n");
|
|
42
|
+
process.stdout.write(" 1. read each docs/migrations/<version>.md for document-level changes\n");
|
|
43
|
+
process.stdout.write(" 2. apply edits to document/ where needed\n");
|
|
44
|
+
process.stdout.write(" 3. re-run: npx open-press upgrade (without --dry-run)\n");
|
|
45
|
+
} else {
|
|
46
|
+
process.stdout.write(JSON.stringify({ status: "dry-run", before }, null, 2) + "\n");
|
|
47
|
+
}
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 2. Refresh framework dep (only when workspace declares @open-press/core).
|
|
52
|
+
if (!skipDeps && (await hasCoreDep(root))) {
|
|
53
|
+
if (!json) process.stdout.write("▸ updating @open-press/core via npm…\n");
|
|
54
|
+
const code = runCommand("npm", ["update", "@open-press/core"], root);
|
|
55
|
+
if (code !== 0) {
|
|
56
|
+
if (!json) process.stdout.write(" ⚠ npm update returned non-zero; continuing\n");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 3. Refresh skills (npx skills upgrade respects skills-lock.json).
|
|
61
|
+
if (!skipSkills) {
|
|
62
|
+
if (!json) process.stdout.write("▸ refreshing skills via npx skills upgrade…\n");
|
|
63
|
+
runCommand("npx", ["-y", "skills@latest", "upgrade"], root);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 4. Surface migration notes for the agent to read.
|
|
67
|
+
const migrationContents = await loadMigrations(root, before.pendingMigrations);
|
|
68
|
+
|
|
69
|
+
// 5. Re-diagnose to confirm the move.
|
|
70
|
+
const after = await diagnose(root, { noCache: true });
|
|
71
|
+
|
|
72
|
+
if (json) {
|
|
73
|
+
process.stdout.write(
|
|
74
|
+
JSON.stringify(
|
|
75
|
+
{ status: "applied", before, after, migrationContents: migrationContents.map((m) => m.path) },
|
|
76
|
+
null,
|
|
77
|
+
2,
|
|
78
|
+
) + "\n",
|
|
79
|
+
);
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
process.stdout.write("\n✓ upgrade applied. Now read these migration notes:\n\n");
|
|
84
|
+
if (migrationContents.length === 0) {
|
|
85
|
+
process.stdout.write(" (no migration docs in this version range)\n\n");
|
|
86
|
+
} else {
|
|
87
|
+
for (const m of migrationContents) {
|
|
88
|
+
process.stdout.write(` ─ ${m.path}\n`);
|
|
89
|
+
}
|
|
90
|
+
process.stdout.write(
|
|
91
|
+
"\nAgent: open each file, identify document-level changes, grep document/ for affected patterns, propose edits before applying.\n",
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
process.stdout.write("\nVerify with:\n npm run openpress:validate\n npm run openpress:render\n\n");
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function hasCoreDep(root) {
|
|
100
|
+
try {
|
|
101
|
+
const pkg = JSON.parse(await readFile(path.join(root, "package.json"), "utf8"));
|
|
102
|
+
return Boolean(pkg.dependencies?.["@open-press/core"] || pkg.devDependencies?.["@open-press/core"]);
|
|
103
|
+
} catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function loadMigrations(root, versions) {
|
|
109
|
+
const results = [];
|
|
110
|
+
for (const v of versions) {
|
|
111
|
+
const p = path.join(root, "docs", "migrations", `${v}.md`);
|
|
112
|
+
if (existsSync(p)) {
|
|
113
|
+
results.push({ version: v, path: path.relative(root, p) });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return results;
|
|
117
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-press/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "open-press core — runtime primitives, CLI, and render pipeline for AI-first fixed-layout documents.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -65,6 +65,8 @@
|
|
|
65
65
|
"js-yaml": "^4.1.1",
|
|
66
66
|
"katex": "^0.16.47",
|
|
67
67
|
"lucide-react": "^1.16.0",
|
|
68
|
+
"playwright": "^1.60.0",
|
|
69
|
+
"postcss": "^8.5.6",
|
|
68
70
|
"react": "^19.2.6",
|
|
69
71
|
"react-dom": "^19.2.6",
|
|
70
72
|
"rehype-katex": "^7.0.1",
|
|
@@ -9,13 +9,18 @@ import { loadConfig, publicPdfHref } from "./engine/config.mjs";
|
|
|
9
9
|
import { handleCommentRequest } from "./engine/react/comment-endpoint.mjs";
|
|
10
10
|
import { handleProjectAssetRequest } from "./engine/react/project-asset-endpoint.mjs";
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
const workspaceRoot =
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const frameworkRoot = fileURLToPath(new URL("./", import.meta.url));
|
|
13
|
+
const workspaceRoot = process.env.OPENPRESS_WORKSPACE_ROOT
|
|
14
|
+
? path.resolve(process.env.OPENPRESS_WORKSPACE_ROOT)
|
|
15
|
+
: frameworkRoot;
|
|
16
|
+
const sourceRoot = path.join(frameworkRoot, "src");
|
|
17
|
+
const openpressCliPath = path.join(frameworkRoot, "engine", "cli.mjs");
|
|
18
|
+
const staticServerPath = path.join(frameworkRoot, "engine", "static-server.mjs");
|
|
19
|
+
const openpressCoreEntry = path.join(frameworkRoot, "src", "openpress", "core", "index.tsx");
|
|
16
20
|
const openpressConfig = await loadConfig(workspaceRoot);
|
|
17
21
|
const outputDir = openpressConfig.paths.outputDir;
|
|
18
|
-
const reactDocumentRoot =
|
|
22
|
+
const reactDocumentRoot = openpressConfig.paths.documentRoot;
|
|
23
|
+
const reactDocumentComponentsRoot = openpressConfig.paths.componentsDir;
|
|
19
24
|
const reactDocumentEntry = path.join(reactDocumentRoot, "index.tsx");
|
|
20
25
|
const activeContentDir = await fileExists(reactDocumentEntry)
|
|
21
26
|
? path.join(reactDocumentRoot, "chapters")
|
|
@@ -48,6 +53,7 @@ export default defineConfig({
|
|
|
48
53
|
plugins: [openpressLocalDeployPlugin(), react()],
|
|
49
54
|
define: workspaceDefines,
|
|
50
55
|
resolve: {
|
|
56
|
+
dedupe: ["react", "react-dom", "@mdx-js/react"],
|
|
51
57
|
alias: {
|
|
52
58
|
"@openpress/core": openpressCoreEntry,
|
|
53
59
|
"@/components": reactDocumentComponentsRoot,
|
|
@@ -69,6 +75,9 @@ export default defineConfig({
|
|
|
69
75
|
server: {
|
|
70
76
|
host: "127.0.0.1",
|
|
71
77
|
port: 5173,
|
|
78
|
+
fs: {
|
|
79
|
+
allow: Array.from(new Set([frameworkRoot, workspaceRoot])),
|
|
80
|
+
},
|
|
72
81
|
watch: {
|
|
73
82
|
ignored: ["**/.openpress/tmp/**", `**/${openpressConfig.outputDir}/**`],
|
|
74
83
|
},
|
|
@@ -201,7 +210,7 @@ async function handleLocalPdfExportRequest(req: IncomingMessage, res: ServerResp
|
|
|
201
210
|
ok: result.code === 0 && exists,
|
|
202
211
|
code: result.code,
|
|
203
212
|
pdf: `/__openpress/local-pdf-file?ts=${Date.now()}`,
|
|
204
|
-
command: "
|
|
213
|
+
command: openpressCliCommand(["pdf", "."]),
|
|
205
214
|
stdout: result.stdout,
|
|
206
215
|
stderr: result.stderr,
|
|
207
216
|
});
|
|
@@ -266,7 +275,7 @@ async function handleLocalDeployRequest(req: IncomingMessage, res: ServerRespons
|
|
|
266
275
|
deploy_adapter: openpressConfig.deploy.adapter,
|
|
267
276
|
deploy_source: openpressConfig.deploy.source,
|
|
268
277
|
deploy_project_name: openpressConfig.deploy.projectName,
|
|
269
|
-
command: "
|
|
278
|
+
command: openpressCliCommand(["deploy", ".", "--confirm"]),
|
|
270
279
|
});
|
|
271
280
|
return;
|
|
272
281
|
}
|
|
@@ -285,7 +294,7 @@ async function handleLocalDeployRequest(req: IncomingMessage, res: ServerRespons
|
|
|
285
294
|
pdf: deployedUrl ? `${deployedUrl}/${openpressConfig.pdf.filename}` : deploymentInfo.pdf,
|
|
286
295
|
public_url: publicUrl,
|
|
287
296
|
dirty: false,
|
|
288
|
-
command: "
|
|
297
|
+
command: openpressCliCommand(["deploy", ".", "--confirm"]),
|
|
289
298
|
stdout: result.stdout,
|
|
290
299
|
stderr: result.stderr,
|
|
291
300
|
});
|
|
@@ -293,7 +302,7 @@ async function handleLocalDeployRequest(req: IncomingMessage, res: ServerRespons
|
|
|
293
302
|
|
|
294
303
|
function runLocalPdfExport() {
|
|
295
304
|
return new Promise<{ code: number; stdout: string; stderr: string }>((resolve) => {
|
|
296
|
-
const child = spawn("node", [
|
|
305
|
+
const child = spawn("node", [openpressCliPath, "pdf", "."], {
|
|
297
306
|
cwd: workspaceRoot,
|
|
298
307
|
shell: false,
|
|
299
308
|
});
|
|
@@ -316,7 +325,7 @@ function runLocalPdfExport() {
|
|
|
316
325
|
|
|
317
326
|
function runLocalDeploy() {
|
|
318
327
|
return new Promise<{ code: number; stdout: string; stderr: string }>((resolve) => {
|
|
319
|
-
const child = spawn("node", [
|
|
328
|
+
const child = spawn("node", [openpressCliPath, "deploy", ".", "--confirm"], {
|
|
320
329
|
cwd: workspaceRoot,
|
|
321
330
|
shell: false,
|
|
322
331
|
});
|
|
@@ -405,7 +414,7 @@ function getLocalDeploymentSourcePaths() {
|
|
|
405
414
|
openpressConfig.paths.themeDir,
|
|
406
415
|
openpressConfig.paths.designDoc,
|
|
407
416
|
openpressConfig.paths.componentsDir,
|
|
408
|
-
path.join(
|
|
417
|
+
path.join(frameworkRoot, "src"),
|
|
409
418
|
path.join(workspaceRoot, "index.html"),
|
|
410
419
|
path.join(workspaceRoot, "package.json"),
|
|
411
420
|
path.join(workspaceRoot, "openpress.config.mjs"),
|
|
@@ -414,6 +423,12 @@ function getLocalDeploymentSourcePaths() {
|
|
|
414
423
|
];
|
|
415
424
|
}
|
|
416
425
|
|
|
426
|
+
function openpressCliCommand(args: string[]) {
|
|
427
|
+
const relativeCliPath = path.relative(workspaceRoot, openpressCliPath).replaceAll("\\", "/");
|
|
428
|
+
const displayCliPath = relativeCliPath && !relativeCliPath.startsWith("../") ? relativeCliPath : openpressCliPath;
|
|
429
|
+
return `node ${displayCliPath} ${args.join(" ")}`;
|
|
430
|
+
}
|
|
431
|
+
|
|
417
432
|
async function findNewestLocalSourceMtime(paths: string[]) {
|
|
418
433
|
const times = await Promise.all(paths.map((sourcePath) => findNewestLocalMtime(sourcePath)));
|
|
419
434
|
return Math.max(0, ...times);
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
| 從既有資料建立文件 | 請參考這一份文件(自行上傳),使用 `openpress-writing skill` 協助整理成 8 頁產品提案。保留既有事實,不要新增未確認的數字。 |
|
|
11
11
|
| 以風格起手建立新文件 | 請以 `editorial-monograph skill` 作為風格,使用 `openpress-writing skill` 建立一份研究報告。讀者是管理層,缺少的事實請標成 placeholder。 |
|
|
12
12
|
| 開啟本機審稿 | 請使用 `openpress skill` 打開本機 workbench,讓我檢查 Document、Design System 與 Project 狀態。 |
|
|
13
|
-
| 規劃長篇文件層級 | 請使用 `openpress-
|
|
13
|
+
| 規劃長篇文件層級 | 請使用 `openpress-writing skill` 規劃 H2/H3/H4、目錄深度與附錄位置(已併入 writing skill 的 Hierarchy section)。 |
|
|
14
14
|
| 重寫章節 | 請使用 `openpress-writing skill` 重整章節,讓第一章先講問題、第二章講方案,語氣維持正式研究報告。 |
|
|
15
15
|
| 調整版面 | 請使用 `openpress-design skill` 調整 theme 與 components,讓文件維持 A4 長文閱讀節奏。 |
|
|
16
16
|
| 中文潤飾 | 請使用 `chinese-ai-writing-polish skill` 潤飾中文,保留原意,不要改成廣告文案。 |
|
|
@@ -26,8 +26,7 @@ open-press 使用 skill 讓 Agent 在不同層次工作。`openpress` 是 Core /
|
|
|
26
26
|
| --- | --- | --- |
|
|
27
27
|
| `openpress` | CLI、workspace inspect/search/replace、本機 workbench、驗證與輸出邊界 | Agent 不確定該用哪個 open-press 工具、要開本機審稿、或要選 specialist skill |
|
|
28
28
|
| `openpress-deploy` | 部署設定、preflight、dry run、公開發布確認 | 準備上線或接前端部署按鈕 |
|
|
29
|
-
| `openpress-
|
|
30
|
-
| `openpress-writing` | 章節順序、敘事結構、表格與 caption 文案 | 建立、重寫或重整內容 |
|
|
29
|
+
| `openpress-writing` | 章節順序、敘事結構、表格與 caption 文案、**H1/H2/H3/H4 結構、TOC 深度、附錄位置** | 建立、重寫或重整內容;長文骨架調整 |
|
|
31
30
|
| `openpress-design` | theme、版面、page rhythm、components | 調整視覺系統與輸出穩定性 |
|
|
32
31
|
| `openpress-style-pack-contributor` | style pack 設計、starter 契約、貢獻驗證 | 新增或改良 `skills/<pack>/starter/` |
|
|
33
32
|
| `editorial-monograph` | A4 嚴肅長文風格 | 報告、提案、白皮書、產品說明 |
|
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @open-press/core@0.2.0 test /Users/quan/Desktop/QDoc Playgorund/data structure note/packages/core
|
|
3
|
-
> pnpm run test:node && pnpm run test:react
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
> @open-press/core@0.2.0 test:node /Users/quan/Desktop/QDoc Playgorund/data structure note/packages/core
|
|
7
|
-
> node --test tests/*.test.mjs
|
|
8
|
-
|
|
9
|
-
TAP version 13
|
|
10
|
-
# Subtest: cli pdf and deploy dry runs use workspace config
|
|
11
|
-
ok 1 - cli pdf and deploy dry runs use workspace config
|
|
12
|
-
---
|
|
13
|
-
duration_ms: 1898.54
|
|
14
|
-
...
|
|
15
|
-
# Subtest: static server serves workspace pdf and exposes deployment status
|
|
16
|
-
ok 2 - static server serves workspace pdf and exposes deployment status
|
|
17
|
-
---
|
|
18
|
-
duration_ms: 459.933375
|
|
19
|
-
...
|
|
20
|
-
# Subtest: deploy gate validates public adapters require confirmation
|
|
21
|
-
ok 3 - deploy gate validates public adapters require confirmation
|
|
22
|
-
---
|
|
23
|
-
duration_ms: 860.309125
|
|
24
|
-
...
|
|
25
|
-
# Subtest: validate supports machine-readable issue report JSON
|
|
26
|
-
ok 4 - validate supports machine-readable issue report JSON
|
|
27
|
-
---
|
|
28
|
-
duration_ms: 872.810334
|
|
29
|
-
...
|
|
30
|
-
# Subtest: validate warns when React source still contains pending openpress comments
|
|
31
|
-
ok 5 - validate warns when React source still contains pending openpress comments
|
|
32
|
-
---
|
|
33
|
-
duration_ms: 867.950458
|
|
34
|
-
...
|
|
35
|
-
# Subtest: validate reports React pagination overflow warnings from exported document metadata
|
|
36
|
-
ok 6 - validate reports React pagination overflow warnings from exported document metadata
|
|
37
|
-
---
|
|
38
|
-
duration_ms: 867.326666
|
|
39
|
-
...
|
|
40
|
-
# Subtest: inspect dry run describes render and browser inspection steps
|
|
41
|
-
ok 7 - inspect dry run describes render and browser inspection steps
|
|
42
|
-
---
|
|
43
|
-
duration_ms: 733.269791
|
|
44
|
-
...
|
|
45
|
-
# Subtest: export copies theme font stylesheet and font files for nested workspaces
|
|
46
|
-
ok 8 - export copies theme font stylesheet and font files for nested workspaces
|
|
47
|
-
---
|
|
48
|
-
duration_ms: 1151.318875
|
|
49
|
-
...
|
|
50
|
-
# Subtest: export supports chapter-opener pages as no-footer page surfaces
|
|
51
|
-
ok 9 - export supports chapter-opener pages as no-footer page surfaces
|
|
52
|
-
---
|
|
53
|
-
duration_ms: 1118.779584
|
|
54
|
-
...
|
|
55
|
-
# Subtest: export includes katex stylesheet and font assets for latex math
|
|
56
|
-
ok 10 - export includes katex stylesheet and font assets for latex math
|
|
57
|
-
---
|
|
58
|
-
duration_ms: 1114.688208
|
|
59
|
-
...
|
|
60
|
-
# Subtest: inspection source scan reads React MDX chapters when document/index.tsx is present
|
|
61
|
-
ok 11 - inspection source scan reads React MDX chapters when document/index.tsx is present
|
|
62
|
-
---
|
|
63
|
-
duration_ms: 94.999084
|
|
64
|
-
...
|
|
65
|
-
# Subtest: overflow measurements become page warnings with source metadata
|
|
66
|
-
ok 12 - overflow measurements become page warnings with source metadata
|
|
67
|
-
---
|
|
68
|
-
duration_ms: 0.838333
|
|
69
|
-
...
|
|
70
|
-
# Subtest: project asset endpoint renames media and updates document references
|
|
71
|
-
ok 13 - project asset endpoint renames media and updates document references
|
|
72
|
-
---
|
|
73
|
-
duration_ms: 176.032333
|
|
74
|
-
...
|
|
75
|
-
# Subtest: project asset endpoint refuses to delete referenced media
|
|
76
|
-
ok 14 - project asset endpoint refuses to delete referenced media
|
|
77
|
-
---
|
|
78
|
-
duration_ms: 81.165209
|
|
79
|
-
...
|
|
80
|
-
# Subtest: project asset endpoint renames component support directory and literal references
|
|
81
|
-
ok 15 - project asset endpoint renames component support directory and literal references
|
|
82
|
-
---
|
|
83
|
-
duration_ms: 62.403042
|
|
84
|
-
...
|
|
85
|
-
# Subtest: project asset endpoint creates a source comment from the asset dialog
|
|
86
|
-
ok 16 - project asset endpoint creates a source comment from the asset dialog
|
|
87
|
-
---
|
|
88
|
-
duration_ms: 48.93275
|
|
89
|
-
...
|
|
90
|
-
# Subtest: insertCommentMarker writes a JSX marker before the selected MDX block line
|
|
91
|
-
ok 17 - insertCommentMarker writes a JSX marker before the selected MDX block line
|
|
92
|
-
---
|
|
93
|
-
duration_ms: 37.651084
|
|
94
|
-
...
|
|
95
|
-
# Subtest: insertCommentMarker rejects paths outside editable React document sources
|
|
96
|
-
ok 18 - insertCommentMarker rejects paths outside editable React document sources
|
|
97
|
-
---
|
|
98
|
-
duration_ms: 5.009083
|
|
99
|
-
...
|
|
100
|
-
# Subtest: listCommentMarkers returns decoded pending comments from editable React sources
|
|
101
|
-
ok 19 - listCommentMarkers returns decoded pending comments from editable React sources
|
|
102
|
-
---
|
|
103
|
-
duration_ms: 222.229375
|
|
104
|
-
...
|
|
105
|
-
# Subtest: clearCommentMarkers removes one or all pending comments
|
|
106
|
-
ok 20 - clearCommentMarkers removes one or all pending comments
|
|
107
|
-
---
|
|
108
|
-
duration_ms: 135.881
|
|
109
|
-
...
|
|
110
|
-
# Subtest: updateCommentMarker updates an existing source marker without duplicating it
|
|
111
|
-
ok 21 - updateCommentMarker updates an existing source marker without duplicating it
|
|
112
|
-
---
|
|
113
|
-
duration_ms: 44.983834
|
|
114
|
-
...
|
|
115
|
-
# Subtest: handleCommentRequest accepts React inspector targets and writes source markers
|
|
116
|
-
ok 22 - handleCommentRequest accepts React inspector targets and writes source markers
|
|
117
|
-
---
|
|
118
|
-
duration_ms: 4.229959
|
|
119
|
-
...
|
|
120
|
-
# Subtest: handleCommentRequest updates pending comments through PATCH
|
|
121
|
-
ok 23 - handleCommentRequest updates pending comments through PATCH
|
|
122
|
-
---
|
|
123
|
-
duration_ms: 50.044709
|
|
124
|
-
...
|
|
125
|
-
# Subtest: handleCommentRequest lists and clears pending comments
|
|
126
|
-
ok 24 - handleCommentRequest lists and clears pending comments
|
|
127
|
-
---
|
|
128
|
-
duration_ms: 55.842959
|
|
129
|
-
...
|
|
130
|
-
# Subtest: handleCommentRequest rejects unsupported methods
|
|
131
|
-
ok 25 - handleCommentRequest rejects unsupported methods
|
|
132
|
-
---
|
|
133
|
-
duration_ms: 0.326792
|
|
134
|
-
...
|
|
135
|
-
# Subtest: scopeChapterCss prefixes ordinary selectors and nested media rules
|
|
136
|
-
ok 26 - scopeChapterCss prefixes ordinary selectors and nested media rules
|
|
137
|
-
---
|
|
138
|
-
duration_ms: 5.827334
|
|
139
|
-
...
|
|
140
|
-
# Subtest: buildChapterScopedCss reads chapter styles in discovery order
|
|
141
|
-
ok 27 - buildChapterScopedCss reads chapter styles in discovery order
|
|
142
|
-
---
|
|
143
|
-
duration_ms: 30.566
|
|
144
|
-
...
|
|
145
|
-
# Subtest: discovers React document chapters and component scopes from filesystem structure
|
|
146
|
-
ok 28 - discovers React document chapters and component scopes from filesystem structure
|
|
147
|
-
---
|
|
148
|
-
duration_ms: 63.16425
|
|
149
|
-
...
|
|
150
|
-
# Subtest: discovers React workspace using normalized config path overrides
|
|
151
|
-
ok 29 - discovers React workspace using normalized config path overrides
|
|
152
|
-
---
|
|
153
|
-
duration_ms: 7.797125
|
|
154
|
-
...
|
|
155
|
-
# Subtest: loadReactDocumentEntry loads document/index.tsx and normalizes config defaults
|
|
156
|
-
ok 30 - loadReactDocumentEntry loads document/index.tsx and normalizes config defaults
|
|
157
|
-
---
|
|
158
|
-
duration_ms: 190.757833
|
|
159
|
-
...
|
|
160
|
-
# Subtest: loadReactDocumentEntry maps manifest path overrides into normalized config
|
|
161
|
-
ok 31 - loadReactDocumentEntry maps manifest path overrides into normalized config
|
|
162
|
-
---
|
|
163
|
-
duration_ms: 43.071958
|
|
164
|
-
...
|
|
165
|
-
# Subtest: loadReactDocumentEntry rejects obvious top-level side effects before import
|
|
166
|
-
ok 32 - loadReactDocumentEntry rejects obvious top-level side effects before import
|
|
167
|
-
---
|
|
168
|
-
duration_ms: 18.955959
|
|
169
|
-
...
|
|
170
|
-
# Subtest: loadReactDocumentEntry rejects side-effect imports and top-level browser or file IO
|
|
171
|
-
ok 33 - loadReactDocumentEntry rejects side-effect imports and top-level browser or file IO
|
|
172
|
-
---
|
|
173
|
-
duration_ms: 20.809917
|
|
174
|
-
...
|
|
175
|
-
# Subtest: Vite and TypeScript expose React document import aliases
|
|
176
|
-
ok 34 - Vite and TypeScript expose React document import aliases
|
|
177
|
-
---
|
|
178
|
-
duration_ms: 9.857875
|
|
179
|
-
...
|
|
180
|
-
# Subtest: exportReactDocument writes a reader document from React shell pages and MDX chapters
|
|
181
|
-
ok 35 - exportReactDocument writes a reader document from React shell pages and MDX chapters
|
|
182
|
-
---
|
|
183
|
-
duration_ms: 208.410208
|
|
184
|
-
...
|
|
185
|
-
# Subtest: exportReactDocument paginates MDX by measured block groups and rerenders page subtrees
|
|
186
|
-
ok 36 - exportReactDocument paginates MDX by measured block groups and rerenders page subtrees
|
|
187
|
-
---
|
|
188
|
-
duration_ms: 58.566208
|
|
189
|
-
...
|
|
190
|
-
# Subtest: exportReactDocument injects static table-of-contents entries from rendered headings
|
|
191
|
-
ok 37 - exportReactDocument injects static table-of-contents entries from rendered headings
|
|
192
|
-
---
|
|
193
|
-
duration_ms: 65.722958
|
|
194
|
-
...
|
|
195
|
-
# Subtest: exportDocument delegates to React export when document/index.tsx is present
|
|
196
|
-
ok 38 - exportDocument delegates to React export when document/index.tsx is present
|
|
197
|
-
---
|
|
198
|
-
duration_ms: 77.547709
|
|
199
|
-
...
|
|
200
|
-
# Subtest: compileMdx renders MDX with stable block ids and component wrappers
|
|
201
|
-
ok 39 - compileMdx renders MDX with stable block ids and component wrappers
|
|
202
|
-
---
|
|
203
|
-
duration_ms: 18.214959
|
|
204
|
-
...
|
|
205
|
-
# Subtest: compileMdx rejects import declarations in chapter prose
|
|
206
|
-
ok 40 - compileMdx rejects import declarations in chapter prose
|
|
207
|
-
---
|
|
208
|
-
duration_ms: 0.331958
|
|
209
|
-
...
|
|
210
|
-
# Subtest: compileMdx can render only selected block ids for pagination subtrees
|
|
211
|
-
ok 41 - compileMdx can render only selected block ids for pagination subtrees
|
|
212
|
-
---
|
|
213
|
-
duration_ms: 7.782041
|
|
214
|
-
...
|
|
215
|
-
# Subtest: compileMdx rejects inline JSX components inside prose
|
|
216
|
-
ok 42 - compileMdx rejects inline JSX components inside prose
|
|
217
|
-
---
|
|
218
|
-
duration_ms: 0.939334
|
|
219
|
-
...
|
|
220
|
-
# Subtest: compileMdx renders GitHub-flavored markdown tables as table elements
|
|
221
|
-
ok 43 - compileMdx renders GitHub-flavored markdown tables as table elements
|
|
222
|
-
---
|
|
223
|
-
duration_ms: 5.05425
|
|
224
|
-
...
|
|
225
|
-
# Subtest: compileMdx converts TableCaption components into table captions
|
|
226
|
-
ok 44 - compileMdx converts TableCaption components into table captions
|
|
227
|
-
---
|
|
228
|
-
duration_ms: 7.21325
|
|
229
|
-
...
|
|
230
|
-
# Subtest: compileMdx renders inline LaTeX math without treating braces as MDX expressions
|
|
231
|
-
ok 45 - compileMdx renders inline LaTeX math without treating braces as MDX expressions
|
|
232
|
-
---
|
|
233
|
-
duration_ms: 13.443666
|
|
234
|
-
...
|
|
235
|
-
# Subtest: compileMdx renders display LaTeX math as a paginable block
|
|
236
|
-
ok 46 - compileMdx renders display LaTeX math as a paginable block
|
|
237
|
-
---
|
|
238
|
-
duration_ms: 38.801375
|
|
239
|
-
...
|
|
240
|
-
# Subtest: compileMdx treats a whole-line double-dollar formula as display math
|
|
241
|
-
ok 47 - compileMdx treats a whole-line double-dollar formula as display math
|
|
242
|
-
---
|
|
243
|
-
duration_ms: 12.7585
|
|
244
|
-
...
|
|
245
|
-
# Subtest: paginateMeasuredBlocks groups measured block ids without splitting atomic blocks
|
|
246
|
-
ok 48 - paginateMeasuredBlocks groups measured block ids without splitting atomic blocks
|
|
247
|
-
---
|
|
248
|
-
duration_ms: 0.982167
|
|
249
|
-
...
|
|
250
|
-
# Subtest: paginateMeasuredBlocks keeps an overlong block atomic and emits an overflow warning
|
|
251
|
-
ok 49 - paginateMeasuredBlocks keeps an overlong block atomic and emits an overflow warning
|
|
252
|
-
---
|
|
253
|
-
duration_ms: 0.219083
|
|
254
|
-
...
|
|
255
|
-
# Subtest: measureBlocksInChromium derives safe height from rendered page body when no fixed height is configured
|
|
256
|
-
ok 50 - measureBlocksInChromium derives safe height from rendered page body when no fixed height is configured
|
|
257
|
-
---
|
|
258
|
-
duration_ms: 229.745917
|
|
259
|
-
...
|
|
260
|
-
# Subtest: buildReactMeasurementCss includes real theme, component and chapter scoped CSS
|
|
261
|
-
ok 51 - buildReactMeasurementCss includes real theme, component and chapter scoped CSS
|
|
262
|
-
---
|
|
263
|
-
duration_ms: 35.629459
|
|
264
|
-
...
|
|
265
|
-
# Subtest: reader page registry reports same-index DOM replacements
|
|
266
|
-
ok 52 - reader page registry reports same-index DOM replacements
|
|
267
|
-
---
|
|
268
|
-
duration_ms: 55.891958
|
|
269
|
-
...
|
|
270
|
-
# Subtest: page route serializes and validates reader page hashes
|
|
271
|
-
ok 53 - page route serializes and validates reader page hashes
|
|
272
|
-
---
|
|
273
|
-
duration_ms: 20.061375
|
|
274
|
-
...
|
|
275
|
-
# Subtest: reader runtime leaves touch gestures to scrolling instead of page turns
|
|
276
|
-
ok 54 - reader runtime leaves touch gestures to scrolling instead of page turns
|
|
277
|
-
---
|
|
278
|
-
duration_ms: 3.51525
|
|
279
|
-
...
|
|
280
|
-
# Subtest: search emits source match JSON with file, line, column and preview
|
|
281
|
-
ok 55 - search emits source match JSON with file, line, column and preview
|
|
282
|
-
---
|
|
283
|
-
duration_ms: 1006.144209
|
|
284
|
-
...
|
|
285
|
-
# Subtest: replace preview reports changes without writing files
|
|
286
|
-
ok 56 - replace preview reports changes without writing files
|
|
287
|
-
---
|
|
288
|
-
duration_ms: 822.123458
|
|
289
|
-
...
|
|
290
|
-
# Subtest: replace apply writes prose matches and skips fenced code by default
|
|
291
|
-
ok 57 - replace apply writes prose matches and skips fenced code by default
|
|
292
|
-
---
|
|
293
|
-
duration_ms: 818.346291
|
|
294
|
-
...
|
|
295
|
-
# Subtest: search reads React MDX chapter content when document/index.tsx is present
|
|
296
|
-
ok 58 - search reads React MDX chapter content when document/index.tsx is present
|
|
297
|
-
---
|
|
298
|
-
duration_ms: 825.881375
|
|
299
|
-
...
|
|
300
|
-
# Subtest: replace applies to React MDX chapter content when document/index.tsx is present
|
|
301
|
-
ok 59 - replace applies to React MDX chapter content when document/index.tsx is present
|
|
302
|
-
---
|
|
303
|
-
duration_ms: 829.073666
|
|
304
|
-
...
|
|
305
|
-
# Subtest: search all includes React document entry and chapter implementation sources
|
|
306
|
-
ok 60 - search all includes React document entry and chapter implementation sources
|
|
307
|
-
---
|
|
308
|
-
duration_ms: 826.43775
|
|
309
|
-
...
|
|
310
|
-
1..60
|
|
311
|
-
# tests 60
|
|
312
|
-
# suites 0
|
|
313
|
-
# pass 60
|
|
314
|
-
# fail 0
|
|
315
|
-
# cancelled 0
|
|
316
|
-
# skipped 0
|
|
317
|
-
# todo 0
|
|
318
|
-
# duration_ms 10037.053417
|
|
319
|
-
|
|
320
|
-
> @open-press/core@0.2.0 test:react /Users/quan/Desktop/QDoc Playgorund/data structure note/packages/core
|
|
321
|
-
> vitest run
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
[1m[30m[46m RUN [49m[39m[22m [36mv4.1.7 [39m[90m/Users/quan/Desktop/QDoc Playgorund/data structure note/packages/core[39m
|
|
325
|
-
|
|
326
|
-
[32m✓[39m tests/openpress-composer-mentions.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
327
|
-
[32m✓[39m tests/openpress-react-document-metadata.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
328
|
-
[32m✓[39m tests/openpress-frame-scheduler.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
329
|
-
[32m✓[39m tests/openpress-project-mentions.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 261[2mms[22m[39m
|
|
330
|
-
[32m✓[39m tests/openpress-pagination.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 179[2mms[22m[39m
|
|
331
|
-
[32m✓[39m tests/openpress-core-primitives.react.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 52[2mms[22m[39m
|
|
332
|
-
[32m✓[39m tests/openpress-bookmarks.react.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 145[2mms[22m[39m
|
|
333
|
-
[32m✓[39m tests/openpress-renderer.react.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 258[2mms[22m[39m
|
|
334
|
-
[32m✓[39m tests/openpress-inspector.react.test.tsx [2m([22m[2m13 tests[22m[2m)[22m[32m 105[2mms[22m[39m
|
|
335
|
-
[32m✓[39m tests/reader-runtime.react.test.tsx [2m([22m[2m7 tests[22m[2m)[22m[33m 367[2mms[22m[39m
|
|
336
|
-
|
|
337
|
-
[2m Test Files [22m [1m[32m10 passed[39m[22m[90m (10)[39m
|
|
338
|
-
[2m Tests [22m [1m[32m52 passed[39m[22m[90m (52)[39m
|
|
339
|
-
[2m Start at [22m 14:37:54
|
|
340
|
-
[2m Duration [22m 1.56s[2m (transform 947ms, setup 0ms, import 1.82s, tests 1.39s, environment 7.26s)[22m
|
|
341
|
-
|