dogsbay 0.2.0-beta.0 → 0.2.0-beta.2

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.
@@ -244,8 +244,9 @@ export async function siteBuild(cwd, options) {
244
244
  }
245
245
  console.log("");
246
246
  console.log(pc.cyan("Next:"));
247
- console.log(" npm run build # Astro build dist/");
248
- console.log(" dogsbay site dev # local preview with hot reload");
247
+ console.log(" dogsbay site dev # live preview at http://localhost:4321");
248
+ console.log(" dogsbay site preview # production build dist/ + serve");
249
+ console.log(" dogsbay site check # run audit rules");
249
250
  }
250
251
  // ─── Helpers ─────────────────────────────────────────────────────────────
251
252
  function resolveConfigPath(startDir, explicit) {
@@ -32,6 +32,36 @@ const defaultRunner = (siteRoot, args) => new Promise((resolve) => {
32
32
  resolve(1);
33
33
  });
34
34
  });
35
+ /**
36
+ * Pick the first available package manager from a preference list.
37
+ * Defaults to pnpm (matches the dogsbay tooling chain); falls back
38
+ * to npm so machines without pnpm don't dead-end.
39
+ */
40
+ function pickPackageManager() {
41
+ const onPath = (cmd) => {
42
+ try {
43
+ const { execSync } = require("node:child_process");
44
+ execSync(`command -v ${cmd}`, { stdio: "ignore" });
45
+ return true;
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ };
51
+ if (onPath("pnpm"))
52
+ return "pnpm";
53
+ return "npm";
54
+ }
55
+ function runPackageManagerInstall(pm, cwd) {
56
+ return new Promise((resolve) => {
57
+ const child = spawn(pm, ["install"], { cwd, stdio: "inherit" });
58
+ child.on("exit", (code) => resolve(code ?? 0));
59
+ child.on("error", (err) => {
60
+ console.error(pc.red(`Error: failed to spawn ${pm}: ${err.message}`));
61
+ resolve(1);
62
+ });
63
+ });
64
+ }
35
65
  export async function siteDev(cwd, options, runner = defaultRunner) {
36
66
  const siteRoot = await prepareForAstro(cwd, options);
37
67
  const code = await runner(siteRoot, ["dev"]);
@@ -61,9 +91,18 @@ async function prepareForAstro(cwd, options) {
61
91
  process.exit(1);
62
92
  }
63
93
  if (!existsSync(join(outputDir, "node_modules"))) {
64
- console.error(pc.red(`Error: dependencies not installed at ${outputDir}.`));
65
- console.error(` Run \`pnpm install\` (or \`npm install\`) in ${outputDir}.`);
66
- process.exit(1);
94
+ // First-run: install scaffolded site's deps automatically. Picks
95
+ // pnpm if available, otherwise npm. Friendly users shouldn't have
96
+ // to know this is a separate project under the hood — the
97
+ // dogsbay command should Just Work the first time.
98
+ const pm = pickPackageManager();
99
+ console.log(pc.cyan(`Installing scaffolded site deps (one-time, ~30s) — using ${pm}...`));
100
+ const installCode = await runPackageManagerInstall(pm, outputDir);
101
+ if (installCode !== 0) {
102
+ console.error(pc.red(`Error: ${pm} install failed in ${outputDir} (exit ${installCode}).`));
103
+ console.error(` Try running \`${pm} install\` manually in that directory.`);
104
+ process.exit(installCode);
105
+ }
67
106
  }
68
107
  // Refresh content / config-derived / agent-readiness files before
69
108
  // handing off to Astro. Skip with --no-build for fast iteration when
@@ -15,7 +15,7 @@
15
15
  * `dogsbay site build`.
16
16
  */
17
17
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
18
- import { join, resolve } from "node:path";
18
+ import { isAbsolute, join, resolve } from "node:path";
19
19
  import pc from "picocolors";
20
20
  import prompts from "prompts";
21
21
  import { emitSiteScaffold } from "@dogsbay/format-astro";
@@ -107,7 +107,55 @@ export async function siteInit(targetDir, options) {
107
107
  if (options.local)
108
108
  astroOpts.local = true;
109
109
  emitSiteScaffold(outputDir, config.site.name, astroOpts, true);
110
- printNextSteps(absTarget, outputDir, config);
110
+ // Seed starter content so the first `dogsbay site build` succeeds
111
+ // without manual intervention. Only writes when this is a fresh
112
+ // init (writeConfig=true; scaffold-only consumers already have
113
+ // content) and the content dir doesn't exist yet — never
114
+ // overwrites user files. See plans/beta-launch-followups.md.
115
+ let starterContentPath = null;
116
+ if (writeConfig) {
117
+ starterContentPath = seedStarterContent(absTarget, config);
118
+ }
119
+ printNextSteps(absTarget, outputDir, config, starterContentPath);
120
+ }
121
+ /**
122
+ * Create a starter `<content>/index.md` if the content dir doesn't
123
+ * already exist. Returns the path written, or null when nothing
124
+ * was created (dir already populated). Never overwrites.
125
+ */
126
+ function seedStarterContent(absTarget, config) {
127
+ const sources = config.content.sources ?? [];
128
+ const first = sources[0];
129
+ if (!first?.path)
130
+ return null;
131
+ const contentDir = isAbsolute(first.path)
132
+ ? first.path
133
+ : join(absTarget, first.path);
134
+ if (existsSync(contentDir))
135
+ return null; // user already has content
136
+ mkdirSync(contentDir, { recursive: true });
137
+ const indexPath = join(contentDir, "index.md");
138
+ writeFileSync(indexPath, `---
139
+ title: ${config.site.name || "Welcome"}
140
+ description: Edit content/index.md to get started.
141
+ ---
142
+
143
+ # ${config.site.name || "Welcome"}
144
+
145
+ This is your starter page. Replace this content with your own
146
+ markdown — every \`.md\` file under \`content/\` becomes a page.
147
+
148
+ ## What's next
149
+
150
+ - Edit this file (\`content/index.md\`) to change the home page.
151
+ - Add more \`.md\` files alongside it for additional pages.
152
+ - Run \`dogsbay site dev\` to preview live as you edit.
153
+ - See \`dogsbay.config.yml\` for site-wide settings (theme, agent
154
+ readiness, deploy target, etc.).
155
+
156
+ For the full reference, see https://github.com/dogsbay/dogsbay.
157
+ `);
158
+ return indexPath;
111
159
  }
112
160
  // ─── Resolution: flags + prompts → DogsbayConfig ─────────────────────────
113
161
  async function resolveConfig(opts, interactive) {
@@ -353,12 +401,15 @@ function findExistingConfig(dir) {
353
401
  }
354
402
  return null;
355
403
  }
356
- function printNextSteps(absTarget, outputDir, config) {
404
+ function printNextSteps(absTarget, outputDir, config, starterContentPath) {
357
405
  void config;
358
406
  const sameDir = absTarget === outputDir;
359
407
  console.log("");
360
408
  console.log(pc.green("Wrote:"));
361
409
  console.log(` ${absTarget}/dogsbay.config.yml`);
410
+ if (starterContentPath) {
411
+ console.log(` ${starterContentPath}`);
412
+ }
362
413
  console.log(` ${outputDir}/package.json`);
363
414
  console.log(` ${outputDir}/astro.config.mjs`);
364
415
  console.log(` ${outputDir}/src/styles/theme.css`);
@@ -366,11 +417,14 @@ function printNextSteps(absTarget, outputDir, config) {
366
417
  console.log(` ${outputDir}/src/components/ui/`);
367
418
  console.log("");
368
419
  console.log(pc.cyan("Next steps:"));
369
- console.log(` cd ${outputDir}`);
370
- console.log(" pnpm install");
371
420
  if (!sameDir)
372
421
  console.log(` cd ${absTarget}`);
373
- console.log(" dogsbay site build");
374
- console.log(" dogsbay site dev # local preview");
422
+ console.log(" dogsbay site dev # build + live preview at http://localhost:4321");
423
+ console.log(" (auto-installs scaffolded deps on first run)");
424
+ console.log("");
425
+ console.log("Other commands:");
426
+ console.log(" dogsbay site build # generate Astro source from content");
427
+ console.log(" dogsbay site preview # production build + serve from dist/");
428
+ console.log(" dogsbay site check # run audit rules against built content");
375
429
  console.log("");
376
430
  }
package/dist/index.js CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import { dirname, join } from "node:path";
2
5
  import { Command } from "commander";
3
6
  import { init } from "./commands/init.js";
4
7
  import { add, list } from "./commands/add.js";
@@ -12,11 +15,18 @@ import { siteInit } from "./commands/site-init.js";
12
15
  import { siteBuild } from "./commands/site-build.js";
13
16
  import { siteCheck } from "./commands/site-check.js";
14
17
  import { siteDev, sitePreview } from "./commands/site-dev.js";
18
+ // Read version from the runtime package.json so `dogsbay --version`
19
+ // never drifts from what's published. Walks one level up from
20
+ // `dist/index.js` to `package.json` (works in both monorepo dev and
21
+ // the published tarball — pnpm/npm both keep package.json next to
22
+ // dist/).
23
+ const __dirname = dirname(fileURLToPath(import.meta.url));
24
+ const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
15
25
  const program = new Command();
16
26
  program
17
27
  .name("dogsbay")
18
28
  .description("Documentation site generator + Astro component library")
19
- .version("0.1.0");
29
+ .version(pkg.version);
20
30
  // ── `dogsbay astro` — drop Dogsbay components into an existing Astro project ──
21
31
  const astro = program
22
32
  .command("astro")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dogsbay",
3
- "version": "0.2.0-beta.0",
3
+ "version": "0.2.0-beta.2",
4
4
  "description": "CLI for Dogsbay — scaffold, build, and serve documentation sites with markdown / MkDocs / Obsidian / OpenAPI sources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,14 +30,14 @@
30
30
  "picocolors": "^1.1.0",
31
31
  "prompts": "^2.4.2",
32
32
  "yaml": "^2.8.3",
33
- "@dogsbay/format-mkdocs": "0.2.0-beta.0",
34
- "@dogsbay/format-astro": "0.2.0-beta.0",
35
- "@dogsbay/format-obsidian": "0.2.0-beta.0",
36
- "@dogsbay/format-mdx": "0.2.0-beta.0",
37
- "@dogsbay/format-starlight": "0.2.0-beta.0",
38
- "@dogsbay/format-dogsbay-md": "0.2.0-beta.0",
39
- "@dogsbay/format-openapi": "0.2.0-beta.0",
40
- "@dogsbay/types": "0.2.0-beta.0"
33
+ "@dogsbay/format-mkdocs": "0.2.0-beta.2",
34
+ "@dogsbay/format-astro": "0.2.0-beta.2",
35
+ "@dogsbay/format-mdx": "0.2.0-beta.2",
36
+ "@dogsbay/format-obsidian": "0.2.0-beta.2",
37
+ "@dogsbay/format-starlight": "0.2.0-beta.2",
38
+ "@dogsbay/format-dogsbay-md": "0.2.0-beta.2",
39
+ "@dogsbay/types": "0.2.0-beta.2",
40
+ "@dogsbay/format-openapi": "0.2.0-beta.2"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "^22.0.0",