mosage 0.1.0 → 0.8.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/LICENSE +1 -0
- package/README.md +16 -217
- package/bin.js +2 -0
- package/dist/build-C7NW_3Pk.js +14 -0
- package/dist/check-CP4873Wx.js +41 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +228 -0
- package/dist/config-DPm1BBAb.js +2619 -0
- package/dist/config-TlTe7Ona.d.ts +24 -0
- package/dist/context-BqsdSrAQ.js +1084 -0
- package/dist/dev-Biz42qlu.js +17 -0
- package/dist/diagram-xlVDekYk.js +763 -0
- package/dist/export-Bi6nuxjT.js +31 -0
- package/dist/import-D2jNB07F.js +25 -0
- package/dist/index.d.ts +455 -0
- package/dist/index.js +693 -0
- package/dist/init-Bbtj2pxF.js +262 -0
- package/dist/preview-CLm51aRt.js +19 -0
- package/dist/sdk-DjpX6mCv.js +51 -0
- package/dist/vite/index.d.ts +25 -0
- package/dist/vite/index.js +2 -0
- package/env.d.ts +83 -0
- package/package.json +84 -64
- package/skills/apply-comments/SKILL.md +43 -56
- package/skills/create-doc/SKILL.md +106 -0
- package/skills/create-theme/SKILL.md +184 -0
- package/skills/current-doc/SKILL.md +120 -0
- package/skills/doc-authoring/SKILL.md +434 -0
- package/skills/doc-authoring/references/assets.md +47 -0
- package/skills/doc-authoring/references/design-system.md +81 -0
- package/skills/doc-authoring/references/long-form.md +131 -0
- package/skills/doc-authoring/references/pagination.md +118 -0
- package/skills/doc-authoring/references/tables-and-charts.md +161 -0
- package/src/app/app.tsx +42 -0
- package/src/app/components/data-table.tsx +196 -0
- package/src/app/components/design-panel/design-panel.tsx +318 -0
- package/src/app/components/design-panel/design-provider.tsx +121 -0
- package/src/app/components/design-panel/use-design.ts +85 -0
- package/src/app/components/diagram.tsx +76 -0
- package/src/app/components/doc-assets.tsx +129 -0
- package/src/app/components/doc-search.tsx +248 -0
- package/src/app/components/doc-sidebar.tsx +162 -0
- package/src/app/components/flow-page.tsx +93 -0
- package/src/app/components/footnote.tsx +204 -0
- package/src/app/components/image-placeholder.tsx +50 -0
- package/src/app/components/inspector/inspector.tsx +518 -0
- package/src/app/components/numbering.tsx +224 -0
- package/src/app/components/page-frame.tsx +70 -0
- package/src/app/components/sidebar/folder-item.tsx +212 -0
- package/src/app/components/sidebar/icon-picker.tsx +99 -0
- package/src/app/components/sidebar/sidebar.tsx +252 -0
- package/src/app/components/table-of-contents.tsx +93 -0
- package/src/app/components/theme-toggle.tsx +50 -0
- package/src/app/components/themes/markdown.tsx +249 -0
- package/src/app/components/themes/theme-preview.tsx +74 -0
- package/src/app/components/ui/menu.tsx +143 -0
- package/src/app/index.html +12 -0
- package/src/app/lib/agent-bridge.ts +140 -0
- package/src/app/lib/assets.ts +151 -0
- package/src/app/lib/design-presets.ts +109 -0
- package/src/app/lib/design.ts +88 -0
- package/src/app/lib/diagnostics.ts +282 -0
- package/src/app/lib/doc-preview.tsx +29 -0
- package/src/app/lib/docs.ts +26 -0
- package/src/app/lib/docx/extract.ts +1623 -0
- package/src/app/lib/docx/fonts.test.ts +136 -0
- package/src/app/lib/docx/fonts.ts +166 -0
- package/src/app/lib/docx/media.ts +102 -0
- package/src/app/lib/docx/model.ts +206 -0
- package/src/app/lib/docx/paragraph.test.ts +92 -0
- package/src/app/lib/docx/paragraph.ts +107 -0
- package/src/app/lib/docx/props.ts +187 -0
- package/src/app/lib/docx/styles.ts +306 -0
- package/src/app/lib/docx/units.ts +35 -0
- package/src/app/lib/docx/write.test.ts +507 -0
- package/src/app/lib/docx/write.ts +581 -0
- package/src/app/lib/docx/xml.ts +39 -0
- package/src/app/lib/export-docx.ts +289 -0
- package/src/app/lib/export-dom.ts +318 -0
- package/src/app/lib/export-html.ts +156 -0
- package/src/app/lib/export-image.ts +70 -0
- package/src/app/lib/export-pdf.ts +165 -0
- package/src/app/lib/flow-measure.test.ts +31 -0
- package/src/app/lib/flow-measure.ts +183 -0
- package/src/app/lib/flow.test.ts +110 -0
- package/src/app/lib/flow.ts +136 -0
- package/src/app/lib/folders.ts +192 -0
- package/src/app/lib/footnotes.test.tsx +102 -0
- package/src/app/lib/footnotes.ts +94 -0
- package/src/app/lib/inspector/fiber.ts +99 -0
- package/src/app/lib/labels.test.ts +18 -0
- package/src/app/lib/labels.ts +181 -0
- package/src/app/lib/outline.ts +118 -0
- package/src/app/lib/page-context.tsx +43 -0
- package/src/app/lib/page-range.test.ts +95 -0
- package/src/app/lib/page-range.ts +90 -0
- package/src/app/lib/print-ready.ts +69 -0
- package/src/app/lib/rasterize.ts +173 -0
- package/src/app/lib/scan.ts +26 -0
- package/src/app/lib/sdk.test.ts +32 -0
- package/src/app/lib/sdk.ts +115 -0
- package/src/app/lib/themes.ts +31 -0
- package/src/app/lib/use-doc-module.ts +53 -0
- package/src/app/lib/use-doc-pages.ts +147 -0
- package/src/app/lib/utils.ts +6 -0
- package/src/app/lib/view-mode.test.ts +91 -0
- package/src/app/lib/view-mode.ts +104 -0
- package/src/app/main.tsx +14 -0
- package/src/app/routes/assets.tsx +257 -0
- package/src/app/routes/doc.tsx +877 -0
- package/src/app/routes/home-shell.tsx +203 -0
- package/src/app/routes/home.tsx +269 -0
- package/src/app/routes/themes.tsx +121 -0
- package/src/app/styles.css +97 -0
- package/src/app/virtual.d.ts +30 -0
- package/template/AGENTS.md +27 -0
- package/template/README.md +39 -0
- package/template/docs/getting-started/index.tsx +230 -0
- package/template/mosage.config.ts +5 -0
- package/template/package.json +24 -0
- package/template/tsconfig.json +17 -0
- package/README.en.md +0 -57
- package/dist/cli.js +0 -4545
- package/dist/web/assets/index-Czg2WeHe.js +0 -182
- package/dist/web/assets/index-DKAyt92W.css +0 -1
- package/dist/web/index.html +0 -15
- package/skills/current-position/SKILL.md +0 -65
- package/skills/kickoff/SKILL.md +0 -105
- package/skills/mosage-reference/SKILL.md +0 -164
- package/skills/outline/SKILL.md +0 -79
- package/skills/review/SKILL.md +0 -64
- package/skills/write-chapter/SKILL.md +0 -58
- package/template/book/STYLE.md +0 -6
- package/template/book/assets/.gitkeep +0 -0
- package/template/book/book.yaml +0 -42
- package/template/book/brief.md +0 -6
- package/template/book/chapters/.gitkeep +0 -0
- package/template/book/notes/README.md +0 -7
- package/template/project/AGENTS.md +0 -82
- package/template/project/CLAUDE.md +0 -1
- package/template/project/README.md +0 -48
- package/template/project/books/.gitkeep +0 -0
- package/template/project/gitignore +0 -5
- package/template/project/mosage.yaml +0 -23
- package/template/project/notes/README.md +0 -8
- package/template/project/package.json +0 -14
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { n as packageRoot, r as readCoreVersion, t as syncSkills } from "./cli/bin.js";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { cp, mkdir, readFile, readdir, rm, symlink, writeFile } from "node:fs/promises";
|
|
6
|
+
import { spawn } from "node:child_process";
|
|
7
|
+
import prompts from "prompts";
|
|
8
|
+
//#region src/cli/git.ts
|
|
9
|
+
const IS_WINDOWS$1 = process.platform === "win32";
|
|
10
|
+
async function run(cmd, args, cwd) {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
const child = spawn(cmd, args, {
|
|
13
|
+
cwd,
|
|
14
|
+
stdio: [
|
|
15
|
+
"ignore",
|
|
16
|
+
"pipe",
|
|
17
|
+
"pipe"
|
|
18
|
+
],
|
|
19
|
+
shell: IS_WINDOWS$1
|
|
20
|
+
});
|
|
21
|
+
let stdout = "";
|
|
22
|
+
let stderr = "";
|
|
23
|
+
child.stdout?.on("data", (d) => {
|
|
24
|
+
stdout += d.toString();
|
|
25
|
+
});
|
|
26
|
+
child.stderr?.on("data", (d) => {
|
|
27
|
+
stderr += d.toString();
|
|
28
|
+
});
|
|
29
|
+
child.on("error", reject);
|
|
30
|
+
child.on("close", (code) => resolve({
|
|
31
|
+
code,
|
|
32
|
+
stdout,
|
|
33
|
+
stderr
|
|
34
|
+
}));
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async function isGitAvailable() {
|
|
38
|
+
try {
|
|
39
|
+
return (await run("git", ["--version"], process.cwd())).code === 0;
|
|
40
|
+
} catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function isInsideWorkTree(cwd) {
|
|
45
|
+
try {
|
|
46
|
+
const res = await run("git", ["rev-parse", "--is-inside-work-tree"], cwd);
|
|
47
|
+
return res.code === 0 && res.stdout.trim() === "true";
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function gitInitAndCommit(target) {
|
|
53
|
+
if (!await isGitAvailable()) return {
|
|
54
|
+
status: "skipped-no-git",
|
|
55
|
+
message: "git binary not found on PATH"
|
|
56
|
+
};
|
|
57
|
+
if (await isInsideWorkTree(target)) return {
|
|
58
|
+
status: "skipped-nested",
|
|
59
|
+
message: "target is already inside a git work tree; leaving parent repo alone"
|
|
60
|
+
};
|
|
61
|
+
for (const [args, label] of [
|
|
62
|
+
[["init"], "git init"],
|
|
63
|
+
[["add", "-A"], "git add"],
|
|
64
|
+
[[
|
|
65
|
+
"commit",
|
|
66
|
+
"-m",
|
|
67
|
+
"chore: init MoSage project"
|
|
68
|
+
], "git commit"]
|
|
69
|
+
]) {
|
|
70
|
+
const res = await run("git", [...args], target);
|
|
71
|
+
if (res.code !== 0) return {
|
|
72
|
+
status: "failed",
|
|
73
|
+
message: `${label} failed: ${res.stderr.trim() || res.stdout.trim()}`
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return { status: "committed" };
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/cli/package-manager.ts
|
|
80
|
+
const PACKAGE_MANAGERS = [
|
|
81
|
+
"npm",
|
|
82
|
+
"pnpm",
|
|
83
|
+
"yarn",
|
|
84
|
+
"bun"
|
|
85
|
+
];
|
|
86
|
+
function detectPackageManager() {
|
|
87
|
+
const ua = process.env.npm_config_user_agent ?? "";
|
|
88
|
+
if (ua.startsWith("pnpm")) return "pnpm";
|
|
89
|
+
if (ua.startsWith("yarn")) return "yarn";
|
|
90
|
+
if (ua.startsWith("bun")) return "bun";
|
|
91
|
+
return "npm";
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/cli/init.ts
|
|
95
|
+
const IS_WINDOWS = process.platform === "win32";
|
|
96
|
+
function sanitizeDirName(value) {
|
|
97
|
+
const trimmed = value.trim();
|
|
98
|
+
if (trimmed === "." || trimmed === "..") return trimmed;
|
|
99
|
+
const cleaned = trimmed.replace(/\s+/g, "-").replace(/[^\\\p{L}\p{N}_./-]/gu, "-").replace(/-+/g, "-").replace(/(^-|-$)/g, "").replace(/-*([/\\])-*/g, "$1");
|
|
100
|
+
if (cleaned === "" || /^[/\\]+$/.test(cleaned)) return "my-docs";
|
|
101
|
+
return cleaned;
|
|
102
|
+
}
|
|
103
|
+
async function isDirNonEmpty(target) {
|
|
104
|
+
if (!existsSync(target)) return false;
|
|
105
|
+
return (await readdir(target)).some((e) => !e.startsWith("."));
|
|
106
|
+
}
|
|
107
|
+
async function linkOrCopy(relSrc, dst) {
|
|
108
|
+
await rm(dst, {
|
|
109
|
+
recursive: true,
|
|
110
|
+
force: true
|
|
111
|
+
});
|
|
112
|
+
if (IS_WINDOWS) {
|
|
113
|
+
await cp(resolve(dirname(dst), relSrc), dst, { recursive: true });
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
await symlink(relSrc, dst);
|
|
117
|
+
}
|
|
118
|
+
async function linkClaudeMd(target) {
|
|
119
|
+
const claudeMd = join(target, "CLAUDE.md");
|
|
120
|
+
if (!existsSync(claudeMd) && existsSync(join(target, "AGENTS.md"))) await linkOrCopy("AGENTS.md", claudeMd);
|
|
121
|
+
}
|
|
122
|
+
async function runInstall(pm, cwd) {
|
|
123
|
+
await new Promise((res, rej) => {
|
|
124
|
+
const child = spawn(pm, ["install"], {
|
|
125
|
+
cwd,
|
|
126
|
+
stdio: "inherit",
|
|
127
|
+
shell: IS_WINDOWS
|
|
128
|
+
});
|
|
129
|
+
child.on("error", rej);
|
|
130
|
+
child.on("close", (code) => code === 0 ? res() : rej(/* @__PURE__ */ new Error(`${pm} install exited with code ${code}`)));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
async function init(opts) {
|
|
134
|
+
const { dir, force, name, packageManager, install, git } = opts;
|
|
135
|
+
const root = packageRoot();
|
|
136
|
+
const templateDir = root ? join(root, "template") : "";
|
|
137
|
+
if (!root || !existsSync(templateDir)) throw new Error("Project template not found — reinstall mosage.");
|
|
138
|
+
const target = resolve(process.cwd(), dir);
|
|
139
|
+
await mkdir(target, { recursive: true });
|
|
140
|
+
if (await isDirNonEmpty(target) && !force) throw new Error(`Target ${target} is not empty. Pass --force to scaffold into it anyway.`);
|
|
141
|
+
await cp(templateDir, target, { recursive: true });
|
|
142
|
+
await linkClaudeMd(target);
|
|
143
|
+
await syncSkills(join(root, "skills"), { quiet: true }, target);
|
|
144
|
+
const pkgPath = join(target, "package.json");
|
|
145
|
+
if (existsSync(pkgPath)) {
|
|
146
|
+
const pkg = JSON.parse(await readFile(pkgPath, "utf8"));
|
|
147
|
+
pkg.name = name ?? basename(target);
|
|
148
|
+
pkg.version = "0.0.0";
|
|
149
|
+
pkg.private = true;
|
|
150
|
+
if (pkg.dependencies?.mosage) pkg.dependencies.mosage = `^${await readCoreVersion()}`;
|
|
151
|
+
await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
152
|
+
}
|
|
153
|
+
await writeFile(join(target, ".gitignore"), "node_modules\ndist\n.DS_Store\n");
|
|
154
|
+
await writeFile(join(target, "pnpm-workspace.yaml"), [
|
|
155
|
+
"# Vite needs esbuild to unpack its platform binary during postinstall,",
|
|
156
|
+
"# which pnpm only runs for packages listed here.",
|
|
157
|
+
"allowBuilds:",
|
|
158
|
+
" esbuild: true",
|
|
159
|
+
" rolldown: true",
|
|
160
|
+
""
|
|
161
|
+
].join("\n"));
|
|
162
|
+
const cdTarget = dir === "." ? basename(target) : dir;
|
|
163
|
+
process.stdout.write(`\n${chalk.green.bold("✔ Created MoSage workspace")} ${chalk.dim(`in ${target}`)}\n`);
|
|
164
|
+
let installed = false;
|
|
165
|
+
if (install) {
|
|
166
|
+
process.stdout.write(`\n${chalk.bold(`Installing dependencies with ${packageManager}…`)}\n\n`);
|
|
167
|
+
try {
|
|
168
|
+
await runInstall(packageManager, target);
|
|
169
|
+
installed = true;
|
|
170
|
+
} catch (err) {
|
|
171
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
172
|
+
process.stdout.write(`\n${chalk.yellow("! Dependency install failed:")} ${chalk.dim(msg)}\n` + chalk.dim(` You can retry manually with \`${packageManager} install\`.\n`));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (git) {
|
|
176
|
+
const result = await gitInitAndCommit(target);
|
|
177
|
+
if (result.status === "committed") process.stdout.write(`${chalk.green("✔")} Initialized git repository with first commit.\n`);
|
|
178
|
+
else process.stdout.write(`${chalk.yellow("!")} Git setup skipped: ${chalk.dim(result.message ?? "")}\n`);
|
|
179
|
+
}
|
|
180
|
+
process.stdout.write(`\n${chalk.bold("Next steps:")}\n`);
|
|
181
|
+
process.stdout.write(` ${chalk.cyan(`cd ${cdTarget}`)}\n`);
|
|
182
|
+
if (!installed && install) process.stdout.write(` ${chalk.cyan(`${packageManager} install`)}\n`);
|
|
183
|
+
else if (!install) process.stdout.write(` ${chalk.cyan(`${packageManager} install`)} ${chalk.dim("# install was skipped")}\n`);
|
|
184
|
+
const devCommand = packageManager === "npm" ? "npm run dev" : `${packageManager} dev`;
|
|
185
|
+
process.stdout.write(` ${chalk.cyan(devCommand)}\n`);
|
|
186
|
+
}
|
|
187
|
+
function onCancel() {
|
|
188
|
+
process.stdout.write(chalk.dim("\nCancelled.\n"));
|
|
189
|
+
process.exit(130);
|
|
190
|
+
}
|
|
191
|
+
function packageManagerFromFlags(flags) {
|
|
192
|
+
const picks = [];
|
|
193
|
+
if (flags.useNpm) picks.push("npm");
|
|
194
|
+
if (flags.usePnpm) picks.push("pnpm");
|
|
195
|
+
if (flags.useYarn) picks.push("yarn");
|
|
196
|
+
if (flags.useBun) picks.push("bun");
|
|
197
|
+
if (picks.length > 1) throw new Error(`Only one of --use-npm / --use-pnpm / --use-yarn / --use-bun may be specified (got ${picks.map((p) => `--use-${p}`).join(", ")}).`);
|
|
198
|
+
return picks[0];
|
|
199
|
+
}
|
|
200
|
+
async function runInit(dirArg, flags) {
|
|
201
|
+
const isTTY = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
202
|
+
let dir = dirArg;
|
|
203
|
+
let force = flags.force ?? false;
|
|
204
|
+
let packageManager = packageManagerFromFlags(flags);
|
|
205
|
+
if (isTTY && dir === void 0) dir = (await prompts({
|
|
206
|
+
type: "text",
|
|
207
|
+
name: "dir",
|
|
208
|
+
message: "Target directory",
|
|
209
|
+
initial: "."
|
|
210
|
+
}, { onCancel })).dir;
|
|
211
|
+
if (dir !== void 0) {
|
|
212
|
+
const safe = sanitizeDirName(dir);
|
|
213
|
+
if (safe !== dir) {
|
|
214
|
+
if (!isTTY) throw new Error(`Target directory "${dir}" contains characters that break shell commands (spaces, quotes, etc.). Try "${safe}" instead.`);
|
|
215
|
+
dir = sanitizeDirName((await prompts({
|
|
216
|
+
type: "text",
|
|
217
|
+
name: "dir",
|
|
218
|
+
message: "Directory name",
|
|
219
|
+
initial: safe
|
|
220
|
+
}, { onCancel })).dir ?? safe);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (isTTY && packageManager === void 0 && flags.install !== false) {
|
|
224
|
+
const detected = detectPackageManager();
|
|
225
|
+
packageManager = (await prompts({
|
|
226
|
+
type: "select",
|
|
227
|
+
name: "packageManager",
|
|
228
|
+
message: "Package manager",
|
|
229
|
+
choices: PACKAGE_MANAGERS.map((pm) => ({
|
|
230
|
+
title: pm,
|
|
231
|
+
value: pm
|
|
232
|
+
})),
|
|
233
|
+
initial: PACKAGE_MANAGERS.indexOf(detected)
|
|
234
|
+
}, { onCancel })).packageManager;
|
|
235
|
+
}
|
|
236
|
+
const resolvedDir = dir ?? ".";
|
|
237
|
+
const target = resolve(process.cwd(), resolvedDir);
|
|
238
|
+
if (!force && await isDirNonEmpty(target)) {
|
|
239
|
+
if (!isTTY) throw new Error(`Target ${target} is not empty. Pass --force to scaffold into it anyway.`);
|
|
240
|
+
const { overwrite } = await prompts({
|
|
241
|
+
type: "confirm",
|
|
242
|
+
name: "overwrite",
|
|
243
|
+
message: `${chalk.yellow(target)} is not empty. Scaffold into it anyway?`,
|
|
244
|
+
initial: false
|
|
245
|
+
}, { onCancel });
|
|
246
|
+
if (!overwrite) {
|
|
247
|
+
process.stdout.write(chalk.dim("Aborted.\n"));
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
force = true;
|
|
251
|
+
}
|
|
252
|
+
await init({
|
|
253
|
+
dir: resolvedDir,
|
|
254
|
+
force,
|
|
255
|
+
name: flags.name,
|
|
256
|
+
packageManager: packageManager ?? detectPackageManager(),
|
|
257
|
+
install: flags.install !== false,
|
|
258
|
+
git: flags.git !== false
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
//#endregion
|
|
262
|
+
export { runInit };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { t as createViteConfig } from "./config-DPm1BBAb.js";
|
|
2
|
+
import { mergeConfig, preview as preview$1 } from "vite";
|
|
3
|
+
//#region src/cli/preview.ts
|
|
4
|
+
async function preview(opts = {}) {
|
|
5
|
+
const base = await createViteConfig({
|
|
6
|
+
userCwd: process.cwd(),
|
|
7
|
+
mode: "build"
|
|
8
|
+
});
|
|
9
|
+
const config = mergeConfig(base, { preview: {
|
|
10
|
+
...opts.port !== void 0 ? { port: opts.port } : {},
|
|
11
|
+
...opts.host !== void 0 ? { host: opts.host } : {},
|
|
12
|
+
...opts.open !== void 0 ? { open: opts.open } : {}
|
|
13
|
+
} });
|
|
14
|
+
const server = await preview$1(config);
|
|
15
|
+
server.printUrls();
|
|
16
|
+
server.bindCLIShortcuts({ print: true });
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { preview };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region src/app/lib/sdk.ts
|
|
2
|
+
/** The only sheets a document may be laid out on. */
|
|
3
|
+
const PAGE_SIZE_NAMES = [
|
|
4
|
+
"A4",
|
|
5
|
+
"B4",
|
|
6
|
+
"A3"
|
|
7
|
+
];
|
|
8
|
+
const ORIENTATIONS = ["portrait", "landscape"];
|
|
9
|
+
/**
|
|
10
|
+
* Portrait dimensions in CSS pixels at 96dpi — the unit authors write in —
|
|
11
|
+
* paired with the physical millimetres used when printing. Keeping both means a
|
|
12
|
+
* page laid out at 794×1123 on screen maps to a real A4 sheet with no rescaling.
|
|
13
|
+
*/
|
|
14
|
+
const PAGE_SIZES = {
|
|
15
|
+
A4: {
|
|
16
|
+
width: 794,
|
|
17
|
+
height: 1123,
|
|
18
|
+
mm: [210, 297]
|
|
19
|
+
},
|
|
20
|
+
B4: {
|
|
21
|
+
width: 971,
|
|
22
|
+
height: 1376,
|
|
23
|
+
mm: [257, 364]
|
|
24
|
+
},
|
|
25
|
+
A3: {
|
|
26
|
+
width: 1123,
|
|
27
|
+
height: 1587,
|
|
28
|
+
mm: [297, 420]
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const DEFAULT_PAGE_SIZE = "A4";
|
|
32
|
+
const DEFAULT_ORIENTATION = "portrait";
|
|
33
|
+
function isPageSizeName(value) {
|
|
34
|
+
return typeof value === "string" && value in PAGE_SIZES;
|
|
35
|
+
}
|
|
36
|
+
function isOrientation(value) {
|
|
37
|
+
return value === "portrait" || value === "landscape";
|
|
38
|
+
}
|
|
39
|
+
function resolvePageGeometry(meta) {
|
|
40
|
+
const size = PAGE_SIZES[meta?.pageSize ?? "A4"] ?? PAGE_SIZES["A4"];
|
|
41
|
+
const landscape = meta?.orientation === "landscape";
|
|
42
|
+
const [across, down] = landscape ? [size.mm[1], size.mm[0]] : size.mm;
|
|
43
|
+
return {
|
|
44
|
+
width: landscape ? size.height : size.width,
|
|
45
|
+
height: landscape ? size.width : size.height,
|
|
46
|
+
mm: [across, down],
|
|
47
|
+
css: `${across}mm ${down}mm`
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { PAGE_SIZE_NAMES as a, resolvePageGeometry as c, PAGE_SIZES as i, DEFAULT_PAGE_SIZE as n, isOrientation as o, ORIENTATIONS as r, isPageSizeName as s, DEFAULT_ORIENTATION as t };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { n as MoSageConfig } from "../config-TlTe7Ona.js";
|
|
2
|
+
import { InlineConfig, Plugin } from "vite";
|
|
3
|
+
//#region src/vite/mosage-plugin.d.ts
|
|
4
|
+
type MoSagePluginOptions = {
|
|
5
|
+
userCwd: string;
|
|
6
|
+
config: MoSageConfig;
|
|
7
|
+
coreVersion: string;
|
|
8
|
+
};
|
|
9
|
+
declare function mosagePlugin(opts: MoSagePluginOptions): Plugin;
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/vite/config.d.ts
|
|
12
|
+
type CreateViteConfigOptions = {
|
|
13
|
+
userCwd: string;
|
|
14
|
+
config?: MoSageConfig;
|
|
15
|
+
mode?: 'serve' | 'build';
|
|
16
|
+
/**
|
|
17
|
+
* Drive the app from a headless browser rather than a person. Leaves out the
|
|
18
|
+
* plugins that exist to serve a reader — chiefly the one publishing the
|
|
19
|
+
* reading position, which an export would otherwise overwrite.
|
|
20
|
+
*/
|
|
21
|
+
headless?: boolean;
|
|
22
|
+
};
|
|
23
|
+
declare function createViteConfig(opts: CreateViteConfigOptions): Promise<InlineConfig>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { createViteConfig, mosagePlugin };
|
package/env.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Ambient module declarations for assets imported from `docs/<id>/assets/`
|
|
2
|
+
// and for the data files the framework parses at build time.
|
|
3
|
+
// Mirrors Vite's default asset handling (default export = resolved URL).
|
|
4
|
+
//
|
|
5
|
+
// Consumers opt in via tsconfig:
|
|
6
|
+
//
|
|
7
|
+
// { "compilerOptions": { "types": ["mosage/env"] } }
|
|
8
|
+
|
|
9
|
+
declare module '*.svg' {
|
|
10
|
+
const src: string;
|
|
11
|
+
export default src;
|
|
12
|
+
}
|
|
13
|
+
declare module '*.png' {
|
|
14
|
+
const src: string;
|
|
15
|
+
export default src;
|
|
16
|
+
}
|
|
17
|
+
declare module '*.jpg' {
|
|
18
|
+
const src: string;
|
|
19
|
+
export default src;
|
|
20
|
+
}
|
|
21
|
+
declare module '*.jpeg' {
|
|
22
|
+
const src: string;
|
|
23
|
+
export default src;
|
|
24
|
+
}
|
|
25
|
+
declare module '*.webp' {
|
|
26
|
+
const src: string;
|
|
27
|
+
export default src;
|
|
28
|
+
}
|
|
29
|
+
declare module '*.gif' {
|
|
30
|
+
const src: string;
|
|
31
|
+
export default src;
|
|
32
|
+
}
|
|
33
|
+
declare module '*.avif' {
|
|
34
|
+
const src: string;
|
|
35
|
+
export default src;
|
|
36
|
+
}
|
|
37
|
+
declare module '*.woff' {
|
|
38
|
+
const src: string;
|
|
39
|
+
export default src;
|
|
40
|
+
}
|
|
41
|
+
declare module '*.woff2' {
|
|
42
|
+
const src: string;
|
|
43
|
+
export default src;
|
|
44
|
+
}
|
|
45
|
+
declare module '*.ttf' {
|
|
46
|
+
const src: string;
|
|
47
|
+
export default src;
|
|
48
|
+
}
|
|
49
|
+
declare module '*.otf' {
|
|
50
|
+
const src: string;
|
|
51
|
+
export default src;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Parsed by the `mosage:data` Vite plugin — the default export is the rows.
|
|
55
|
+
declare module '*.csv' {
|
|
56
|
+
type CellValue = string | number | null;
|
|
57
|
+
export const columns: string[];
|
|
58
|
+
export const rows: Array<Record<string, CellValue>>;
|
|
59
|
+
export default rows;
|
|
60
|
+
}
|
|
61
|
+
declare module '*.tsv' {
|
|
62
|
+
type CellValue = string | number | null;
|
|
63
|
+
export const columns: string[];
|
|
64
|
+
export const rows: Array<Record<string, CellValue>>;
|
|
65
|
+
export default rows;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Compiled by the `mosage:diagram` Vite plugin — the default export is the
|
|
69
|
+
// themed SVG and its natural size, ready for `<Diagram chart={…} />`.
|
|
70
|
+
declare module '*.mmd' {
|
|
71
|
+
export const svg: string;
|
|
72
|
+
export const width: number;
|
|
73
|
+
export const height: number;
|
|
74
|
+
const chart: { svg: string; width: number; height: number };
|
|
75
|
+
export default chart;
|
|
76
|
+
}
|
|
77
|
+
declare module '*.mermaid' {
|
|
78
|
+
export const svg: string;
|
|
79
|
+
export const width: number;
|
|
80
|
+
export const height: number;
|
|
81
|
+
const chart: { svg: string; width: number; height: number };
|
|
82
|
+
export default chart;
|
|
83
|
+
}
|
package/package.json
CHANGED
|
@@ -1,90 +1,110 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mosage",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Write documents with your coding agent — MoSage scaffolds the workspace and handles the pages, print layout, and export (PDF, HTML, Word).",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"./vite": {
|
|
12
|
+
"types": "./dist/vite/index.d.ts",
|
|
13
|
+
"import": "./dist/vite/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./env": {
|
|
16
|
+
"types": "./env.d.ts"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
6
19
|
"bin": {
|
|
7
|
-
"mosage": "
|
|
20
|
+
"mosage": "./bin.js"
|
|
8
21
|
},
|
|
9
22
|
"files": [
|
|
23
|
+
"bin.js",
|
|
10
24
|
"dist",
|
|
11
|
-
"
|
|
25
|
+
"env.d.ts",
|
|
26
|
+
"src/app",
|
|
12
27
|
"skills",
|
|
13
|
-
"
|
|
14
|
-
"README.
|
|
28
|
+
"template",
|
|
29
|
+
"README.md"
|
|
15
30
|
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"build": "npm run build:web && npm run build:cli",
|
|
18
|
-
"build:cli": "tsup",
|
|
19
|
-
"build:web": "vite build",
|
|
20
|
-
"dev:web": "vite",
|
|
21
|
-
"typecheck": "tsc --noEmit",
|
|
22
|
-
"check": "biome check .",
|
|
23
|
-
"check:fix": "biome check --write .",
|
|
24
|
-
"test": "vitest run",
|
|
25
|
-
"test:watch": "vitest",
|
|
26
|
-
"prepack": "npm run build",
|
|
27
|
-
"test:e2e": "node scripts/e2e.mjs",
|
|
28
|
-
"dev:cli": "tsx src/cli/index.ts"
|
|
29
|
-
},
|
|
30
31
|
"engines": {
|
|
31
|
-
"node": ">=
|
|
32
|
+
"node": ">=18"
|
|
32
33
|
},
|
|
33
34
|
"keywords": [
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"ai",
|
|
37
|
-
"markdown",
|
|
35
|
+
"agent",
|
|
36
|
+
"document",
|
|
38
37
|
"docx",
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
38
|
+
"pdf",
|
|
39
|
+
"react",
|
|
40
|
+
"report",
|
|
41
|
+
"scaffold",
|
|
42
|
+
"vite",
|
|
43
|
+
"word"
|
|
42
44
|
],
|
|
43
45
|
"license": "MIT",
|
|
44
|
-
"author":
|
|
46
|
+
"author": {
|
|
47
|
+
"name": "CHENBOHAN",
|
|
48
|
+
"url": "https://github.com/nickchen1998"
|
|
49
|
+
},
|
|
45
50
|
"homepage": "https://github.com/nickchen1998/MoSage",
|
|
46
51
|
"repository": {
|
|
47
52
|
"type": "git",
|
|
48
|
-
"url": "git+https://github.com/nickchen1998/MoSage.git"
|
|
53
|
+
"url": "git+https://github.com/nickchen1998/MoSage.git",
|
|
54
|
+
"directory": "packages/core"
|
|
49
55
|
},
|
|
50
56
|
"bugs": {
|
|
51
57
|
"url": "https://github.com/nickchen1998/MoSage/issues"
|
|
52
58
|
},
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public"
|
|
61
|
+
},
|
|
53
62
|
"dependencies": {
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
63
|
+
"@babel/parser": "^8.0.4",
|
|
64
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
65
|
+
"@vitejs/plugin-react": "^6.0.5",
|
|
66
|
+
"chalk": "^6.0.0",
|
|
67
|
+
"clsx": "^2.1.1",
|
|
68
|
+
"commander": "^15.0.0",
|
|
69
|
+
"fast-glob": "^3.3.2",
|
|
70
|
+
"fflate": "^0.8.3",
|
|
71
|
+
"lucide-react": "^1.25.0",
|
|
72
|
+
"next-themes": "^0.4.6",
|
|
73
|
+
"react": "^18.3.1",
|
|
74
|
+
"react-dom": "^18.3.1",
|
|
75
|
+
"react-router-dom": "^7.18.1",
|
|
76
|
+
"tailwind-merge": "^3.5.0",
|
|
77
|
+
"tailwindcss": "^4.2.2",
|
|
78
|
+
"vite": "^8.2.1",
|
|
79
|
+
"prompts": "^2.4.2"
|
|
68
80
|
},
|
|
69
81
|
"devDependencies": {
|
|
70
|
-
"@
|
|
71
|
-
"@
|
|
72
|
-
"@
|
|
73
|
-
"@
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"@types/
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
"@playwright/test": "~1.56.1",
|
|
83
|
+
"@types/node": "^22.19.17",
|
|
84
|
+
"@types/react": "^18.3.12",
|
|
85
|
+
"@types/react-dom": "^18.3.1",
|
|
86
|
+
"playwright": "~1.56.1",
|
|
87
|
+
"tsdown": "^0.22.14",
|
|
88
|
+
"typescript": "^5.9.3",
|
|
89
|
+
"@types/prompts": "^2.4.9"
|
|
90
|
+
},
|
|
91
|
+
"peerDependencies": {
|
|
92
|
+
"playwright": "*"
|
|
93
|
+
},
|
|
94
|
+
"peerDependenciesMeta": {
|
|
95
|
+
"playwright": {
|
|
96
|
+
"optional": true
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"contributors": [
|
|
100
|
+
{
|
|
101
|
+
"name": "Simon Liu",
|
|
102
|
+
"url": "https://github.com/LiuYuWei"
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
"scripts": {
|
|
106
|
+
"build": "tsdown",
|
|
107
|
+
"typecheck": "tsc --noEmit",
|
|
108
|
+
"test:e2e": "pnpm run build && playwright test"
|
|
89
109
|
}
|
|
90
|
-
}
|
|
110
|
+
}
|