From bc70ac7455a71bdf5e88fc2844e8e3e884e95484 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 03:29:59 +0000 Subject: [PATCH 1/7] Initial plan From e9112242dc89a781bd4727ebb3ee40d1d1a5fd14 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 03:32:32 +0000 Subject: [PATCH 2/7] Add init command and update dev/build/start to use content/.objectdocs Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com> --- .gitignore | 5 +- examples/starter/.gitignore | 3 + packages/cli/bin/cli.mjs | 2 + packages/cli/src/commands/build.mjs | 14 ++--- packages/cli/src/commands/dev.mjs | 14 ++--- packages/cli/src/commands/init.mjs | 89 +++++++++++++++++++++++++++++ packages/cli/src/commands/start.mjs | 13 +++-- 7 files changed, 119 insertions(+), 21 deletions(-) create mode 100644 packages/cli/src/commands/init.mjs diff --git a/.gitignore b/.gitignore index 3e14da3..9727bcb 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,7 @@ next-env.d.ts # fumadocs .source -.next \ No newline at end of file +.next + +# objectdocs +content/.objectdocs \ No newline at end of file diff --git a/examples/starter/.gitignore b/examples/starter/.gitignore index 7933a4d..241fc8a 100644 --- a/examples/starter/.gitignore +++ b/examples/starter/.gitignore @@ -34,3 +34,6 @@ pnpm-debug.log* # TypeScript *.tsbuildinfo next-env.d.ts + +# ObjectDocs +content/.objectdocs diff --git a/packages/cli/bin/cli.mjs b/packages/cli/bin/cli.mjs index 99728d7..194a7bf 100755 --- a/packages/cli/bin/cli.mjs +++ b/packages/cli/bin/cli.mjs @@ -9,6 +9,7 @@ import { cac } from 'cac'; import 'dotenv/config'; +import { registerInitCommand } from '../src/commands/init.mjs'; import { registerTranslateCommand } from '../src/commands/translate.mjs'; import { registerDevCommand } from '../src/commands/dev.mjs'; import { registerBuildCommand } from '../src/commands/build.mjs'; @@ -16,6 +17,7 @@ import { registerStartCommand } from '../src/commands/start.mjs'; const cli = cac('objectdocs'); +registerInitCommand(cli); registerTranslateCommand(cli); registerDevCommand(cli); registerBuildCommand(cli); diff --git a/packages/cli/src/commands/build.mjs b/packages/cli/src/commands/build.mjs index 0de11b0..ab4969d 100644 --- a/packages/cli/src/commands/build.mjs +++ b/packages/cli/src/commands/build.mjs @@ -23,13 +23,13 @@ export function registerBuildCommand(cli) { // 1. Resolve user's docs directory const docsDir = dir ? path.resolve(process.cwd(), dir) : path.resolve(process.cwd(), 'content/docs'); - // 2. Resolve the Next.js App directory - let nextAppDir; - try { - nextAppDir = path.dirname(require.resolve('@objectdocs/site/package.json')); - } catch (e) { - // Fallback for local development - nextAppDir = path.resolve(__dirname, '../../../site'); + // 2. Resolve the Next.js App directory - use local .objectdocs first + let nextAppDir = path.resolve(process.cwd(), 'content/.objectdocs'); + + if (!fs.existsSync(nextAppDir)) { + console.log('⚠️ ObjectDocs site not found at content/.objectdocs'); + console.log(' Run "objectdocs init" first to initialize the site.\n'); + process.exit(1); } // Copy user config and assets to nextAppDir diff --git a/packages/cli/src/commands/dev.mjs b/packages/cli/src/commands/dev.mjs index 144a1a4..3da1697 100644 --- a/packages/cli/src/commands/dev.mjs +++ b/packages/cli/src/commands/dev.mjs @@ -24,13 +24,13 @@ export function registerDevCommand(cli) { // 1. Resolve user's docs directory (Absolute path) const docsDir = dir ? path.resolve(process.cwd(), dir) : path.resolve(process.cwd(), 'content/docs'); - // 2. Resolve the Next.js App directory - let nextAppDir; - try { - nextAppDir = path.dirname(require.resolve('@objectdocs/site/package.json')); - } catch (e) { - // Fallback for local development - nextAppDir = path.resolve(__dirname, '../../../site'); + // 2. Resolve the Next.js App directory - use local .objectdocs first + let nextAppDir = path.resolve(process.cwd(), 'content/.objectdocs'); + + if (!fs.existsSync(nextAppDir)) { + console.log('⚠️ ObjectDocs site not found at content/.objectdocs'); + console.log(' Run "objectdocs init" first to initialize the site.\n'); + process.exit(1); } console.log(`Starting docs server...`); diff --git a/packages/cli/src/commands/init.mjs b/packages/cli/src/commands/init.mjs new file mode 100644 index 0000000..e13277d --- /dev/null +++ b/packages/cli/src/commands/init.mjs @@ -0,0 +1,89 @@ +/** + * ObjectDocs + * Copyright (c) 2026-present ObjectStack Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { spawn } from 'child_process'; +import path from 'path'; +import fs from 'fs'; +import { fileURLToPath } from 'url'; +import { createRequire } from 'module'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const require = createRequire(import.meta.url); + +export function registerInitCommand(cli) { + cli + .command('init', 'Initialize ObjectDocs site in content/.objectdocs') + .action(async (options) => { + console.log('Initializing ObjectDocs...\n'); + + const targetDir = path.resolve(process.cwd(), 'content/.objectdocs'); + + // Check if already initialized + if (fs.existsSync(targetDir)) { + console.log(`⚠️ ObjectDocs already initialized at ${targetDir}`); + console.log(' Delete the directory if you want to reinitialize.\n'); + return; + } + + // Resolve the site package directory + let siteDir; + try { + siteDir = path.dirname(require.resolve('@objectdocs/site/package.json')); + } catch (e) { + // Fallback for local development + siteDir = path.resolve(__dirname, '../../../site'); + } + + console.log(`📦 Copying site from: ${siteDir}`); + console.log(`📁 Target directory: ${targetDir}\n`); + + // Create target directory + fs.mkdirSync(targetDir, { recursive: true }); + + // Copy site files to target directory + fs.cpSync(siteDir, targetDir, { + recursive: true, + filter: (source) => { + const basename = path.basename(source); + // Skip node_modules, .next, and other build artifacts + if (basename === 'node_modules' || + basename === '.next' || + basename === 'out' || + basename === '.turbo' || + basename === 'dist') { + return false; + } + return true; + } + }); + + console.log('✅ ObjectDocs site copied successfully!\n'); + + // Install dependencies in the target directory + console.log('📦 Installing dependencies...\n'); + + const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'; + const installProcess = spawn(npmCmd, ['install'], { + cwd: targetDir, + stdio: 'inherit' + }); + + installProcess.on('close', (code) => { + if (code === 0) { + console.log('\n✅ Dependencies installed successfully!'); + console.log('\n🎉 ObjectDocs initialized! You can now run:'); + console.log(' pnpm dev - Start development server'); + console.log(' pnpm build - Build for production\n'); + } else { + console.error('\n❌ Failed to install dependencies'); + process.exit(code); + } + }); + }); +} diff --git a/packages/cli/src/commands/start.mjs b/packages/cli/src/commands/start.mjs index ddb7219..3101798 100644 --- a/packages/cli/src/commands/start.mjs +++ b/packages/cli/src/commands/start.mjs @@ -19,12 +19,13 @@ const require = createRequire(import.meta.url); export function registerStartCommand(cli) { cli.command('start [dir]', 'Start the production server') .action((dir) => { - // 1. Resolve Next.js App directory - let nextAppDir; - try { - nextAppDir = path.dirname(require.resolve('@objectdocs/site/package.json')); - } catch (e) { - nextAppDir = path.resolve(__dirname, '../../../site'); + // 1. Resolve Next.js App directory - use local .objectdocs first + let nextAppDir = path.resolve(process.cwd(), 'content/.objectdocs'); + + if (!fs.existsSync(nextAppDir)) { + console.log('⚠️ ObjectDocs site not found at content/.objectdocs'); + console.log(' Run "objectdocs init" first to initialize the site.\n'); + process.exit(1); } // 2. Check config From 8b4686db75a3e3384d67c1a6e22cd3b0f2b0ef14 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 03:36:43 +0000 Subject: [PATCH 3/7] Changes before error encountered Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com> --- README.md | 17 +++++++++++++++-- examples/starter/README.md | 15 ++++++++++++++- packages/cli/README.md | 14 ++++++++++++++ packages/cli/src/commands/init.mjs | 2 +- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9c3914c..6d86534 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,20 @@ Add the following scripts to your `package.json`: } ``` -### 3. Add content +### 3. Initialize ObjectDocs + +Run the init command to set up the site engine: + +```bash +pnpm objectdocs init +``` + +This will: +- Copy the site engine to `content/.objectdocs` +- Install necessary dependencies +- Prepare your project for development + +### 4. Add content Create the basic directory structure: @@ -109,7 +122,7 @@ Create `content/docs/meta.json`: } ``` -### 4. Start the server +### 5. Start the server ```bash pnpm dev diff --git a/examples/starter/README.md b/examples/starter/README.md index e599351..a4f84fa 100644 --- a/examples/starter/README.md +++ b/examples/starter/README.md @@ -23,6 +23,7 @@ This starter template serves multiple purposes: ``` examples/starter/ ├── content/ +│ ├── .objectdocs/ # Site engine (created by init command) │ ├── docs.site.json # Global site configuration │ └── docs/ │ ├── meta.json # Sidebar navigation structure @@ -55,7 +56,18 @@ cd examples/starter pnpm install ``` -This will install `@objectdocs/cli` from the workspace, which in turn will use `@objectdocs/site` as a dependency. +This will install `@objectdocs/cli` from the workspace. + +3. Initialize ObjectDocs: + +```bash +pnpm objectdocs init +``` + +This command will: +- Copy the `@objectdocs/site` engine to `content/.objectdocs` +- Install necessary dependencies +- Prepare your project for development ### Development @@ -139,6 +151,7 @@ For more details on Vercel deployment, see [VERCEL.md](./VERCEL.md). Use this checklist to validate the starter works correctly: - [ ] `pnpm install` completes without errors +- [ ] `pnpm objectdocs init` initializes the site successfully - [ ] `pnpm dev` starts the development server - [ ] All pages load correctly in the browser - [ ] Navigation works (sidebar, header links) diff --git a/packages/cli/README.md b/packages/cli/README.md index 08e2908..3843dd8 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -23,6 +23,20 @@ pnpm install ## Usage +### Initialize Site + +Before using the development or build commands, you need to initialize the site: + +```bash +# Initialize ObjectDocs site in content/.objectdocs +pnpm objectdocs init +``` + +This command: +- Copies the `@objectdocs/site` package to `content/.objectdocs` +- Installs necessary dependencies +- Prepares your project for local development + ### Site Management The CLI can also be used to run the documentation site locally with a VitePress-like experience. diff --git a/packages/cli/src/commands/init.mjs b/packages/cli/src/commands/init.mjs index e13277d..52007e3 100644 --- a/packages/cli/src/commands/init.mjs +++ b/packages/cli/src/commands/init.mjs @@ -69,7 +69,7 @@ export function registerInitCommand(cli) { console.log('📦 Installing dependencies...\n'); const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'; - const installProcess = spawn(npmCmd, ['install'], { + const installProcess = spawn(npmCmd, ['install', '--legacy-peer-deps'], { cwd: targetDir, stdio: 'inherit' }); From 82f6f7018dada4f7281343328d1f976ccdb1d6cb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 03:46:49 +0000 Subject: [PATCH 4/7] Update project structure in README to show .objectdocs directory Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6d86534..929c5f1 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ ObjectDocs enforces a clear directory structure to ensure maintainability at sca ```text . ├── content/ # [Data Layer] Raw Content +│ ├── .objectdocs/ # Site engine (auto-generated by init) │ ├── docs.site.json # Global settings (Nav, Logo, Branding) │ └── docs/ │ ├── meta.json # Directory structure & sorting control From aff642c03f3a9449394ab6bf7f9c00ce1a135e6c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 03:51:23 +0000 Subject: [PATCH 5/7] Add automatic .gitignore update in init command Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- README.md | 1 + packages/cli/README.md | 1 + packages/cli/src/commands/init.mjs | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/README.md b/README.md index 929c5f1..6f06663 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ pnpm objectdocs init This will: - Copy the site engine to `content/.objectdocs` - Install necessary dependencies +- Automatically add `content/.objectdocs` to `.gitignore` - Prepare your project for development ### 4. Add content diff --git a/packages/cli/README.md b/packages/cli/README.md index 3843dd8..1690bae 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -35,6 +35,7 @@ pnpm objectdocs init This command: - Copies the `@objectdocs/site` package to `content/.objectdocs` - Installs necessary dependencies +- Automatically adds `content/.objectdocs` to `.gitignore` - Prepares your project for local development ### Site Management diff --git a/packages/cli/src/commands/init.mjs b/packages/cli/src/commands/init.mjs index 52007e3..90a68cb 100644 --- a/packages/cli/src/commands/init.mjs +++ b/packages/cli/src/commands/init.mjs @@ -65,6 +65,28 @@ export function registerInitCommand(cli) { console.log('✅ ObjectDocs site copied successfully!\n'); + // Add to .gitignore + const gitignorePath = path.resolve(process.cwd(), '.gitignore'); + const gitignoreEntry = 'content/.objectdocs'; + + try { + let gitignoreContent = ''; + if (fs.existsSync(gitignorePath)) { + gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8'); + } + + // Check if the entry already exists + if (!gitignoreContent.includes(gitignoreEntry)) { + // Add the entry with a comment + const separator = gitignoreContent.trim() ? '\n\n' : ''; + const newContent = gitignoreContent.trim() + separator + '# ObjectDocs\n' + gitignoreEntry + '\n'; + fs.writeFileSync(gitignorePath, newContent); + console.log('📝 Added content/.objectdocs to .gitignore\n'); + } + } catch (e) { + console.warn('⚠️ Could not update .gitignore:', e.message); + } + // Install dependencies in the target directory console.log('📦 Installing dependencies...\n'); From 572d486d235615f7d222573fb0a584559e463e7e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 03:52:24 +0000 Subject: [PATCH 6/7] Improve .gitignore entry detection to check complete lines Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- packages/cli/src/commands/init.mjs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/commands/init.mjs b/packages/cli/src/commands/init.mjs index 90a68cb..75e97a3 100644 --- a/packages/cli/src/commands/init.mjs +++ b/packages/cli/src/commands/init.mjs @@ -75,11 +75,12 @@ export function registerInitCommand(cli) { gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8'); } - // Check if the entry already exists - if (!gitignoreContent.includes(gitignoreEntry)) { + // Check if the entry already exists (as a complete line) + const lines = gitignoreContent.split('\n').map(line => line.trim()); + if (!lines.includes(gitignoreEntry)) { // Add the entry with a comment const separator = gitignoreContent.trim() ? '\n\n' : ''; - const newContent = gitignoreContent.trim() + separator + '# ObjectDocs\n' + gitignoreEntry + '\n'; + const newContent = `${gitignoreContent.trim()}${separator}# ObjectDocs\n${gitignoreEntry}\n`; fs.writeFileSync(gitignorePath, newContent); console.log('📝 Added content/.objectdocs to .gitignore\n'); } From 3ad745282cf06b87b967157fc295782c0cbe3aad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 04:28:09 +0000 Subject: [PATCH 7/7] Fix CI build by using build:site command for monorepo Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0934d08..f379dc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: # run: pnpm exec tsc --noEmit - name: Build - run: pnpm run build + run: pnpm run build:site env: NODE_ENV: production