feat: add `docs create` CLI with smart piping detection
Major improvements to docs:create UX for both Claude Code and external tool integration: **New `docs` CLI command:** - Add scripts/docs-cli.js - main CLI with subcommand routing - Add bin field to package.json for `docs` command - Usage: `docs create` and `docs edit` (cleaner than yarn commands) **Smart piping detection:** - Auto-detect when stdout is piped (\!process.stdout.isTTY) - When piping: automatically output prompt text (no flag needed) - When interactive: output prompt file path - --print-prompt flag now optional (auto-enabled when piping) **Updated help text:** - Show `docs create` syntax first, yarn as alternative - Simplify examples with new CLI - Document smart piping behavior - Focus on two main workflows: Claude Code vs external agents **Usage examples:** # Inside Claude Code - automatic execution docs create drafts/new-feature.md # Pipe to external AI - prompt auto-detected docs create FILE --products X | claude -p docs create FILE --products X | copilot -p # Pipe from stdin echo 'content' | docs create --products X | claude -p Benefits: - Cleaner syntax (no yarn --silent needed) - No manual --print-prompt flag when piping - Consistent with industry tools (git, npm, etc.) - Backward compatible with yarn commandsjts-multifile-plugins-guide
parent
e4a659b269
commit
19f1b19d72
|
|
@ -4,6 +4,9 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "InfluxDB documentation",
|
"description": "InfluxDB documentation",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"docs": "scripts/docs-cli.js"
|
||||||
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"serialize-javascript": "^6.0.2"
|
"serialize-javascript": "^6.0.2"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main CLI entry point for docs tools
|
||||||
|
* Supports subcommands: create, edit, etc.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* docs create <draft-path> [options]
|
||||||
|
* docs edit <url> [options]
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import { dirname, join } from 'path';
|
||||||
|
import { spawn } from 'child_process';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
|
// Get subcommand and remaining arguments
|
||||||
|
const subcommand = process.argv[2];
|
||||||
|
const args = process.argv.slice(3);
|
||||||
|
|
||||||
|
// Map subcommands to script files
|
||||||
|
const subcommands = {
|
||||||
|
create: 'docs-create.js',
|
||||||
|
edit: 'docs-edit.js',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print usage information
|
||||||
|
*/
|
||||||
|
function printUsage() {
|
||||||
|
console.log(`
|
||||||
|
Usage: docs <command> [options]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
create <draft-path> Create new documentation from draft
|
||||||
|
edit <url> Edit existing documentation
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
docs create drafts/new-feature.md --products influxdb3_core
|
||||||
|
docs edit https://docs.influxdata.com/influxdb3/core/admin/
|
||||||
|
|
||||||
|
For command-specific help:
|
||||||
|
docs create --help
|
||||||
|
docs edit --help
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle no subcommand or help
|
||||||
|
if (!subcommand || subcommand === '--help' || subcommand === '-h') {
|
||||||
|
printUsage();
|
||||||
|
process.exit(subcommand ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate subcommand
|
||||||
|
if (!subcommands[subcommand]) {
|
||||||
|
console.error(`Error: Unknown command '${subcommand}'`);
|
||||||
|
console.error(`Run 'docs --help' for usage information`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the appropriate script
|
||||||
|
const scriptPath = join(__dirname, subcommands[subcommand]);
|
||||||
|
const child = spawn('node', [scriptPath, ...args], {
|
||||||
|
stdio: 'inherit',
|
||||||
|
env: process.env,
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('exit', (code) => {
|
||||||
|
process.exit(code || 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('error', (err) => {
|
||||||
|
console.error(`Failed to execute ${subcommand}:`, err.message);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
@ -73,10 +73,16 @@ function isClaudeCode() {
|
||||||
/**
|
/**
|
||||||
* Output prompt for use with external tools
|
* Output prompt for use with external tools
|
||||||
* @param {string} prompt - The generated prompt text
|
* @param {string} prompt - The generated prompt text
|
||||||
* @param {boolean} printPrompt - If true, print to stdout; else save to file
|
* @param {boolean} printPrompt - If true, force print to stdout
|
||||||
*/
|
*/
|
||||||
function outputPromptForExternalUse(prompt, printPrompt = false) {
|
function outputPromptForExternalUse(prompt, printPrompt = false) {
|
||||||
if (printPrompt) {
|
// Auto-detect if stdout is being piped
|
||||||
|
const isBeingPiped = !process.stdout.isTTY;
|
||||||
|
|
||||||
|
// Print prompt text if explicitly requested OR if being piped
|
||||||
|
const shouldPrintText = printPrompt || isBeingPiped;
|
||||||
|
|
||||||
|
if (shouldPrintText) {
|
||||||
// Output prompt text to stdout
|
// Output prompt text to stdout
|
||||||
console.log(prompt);
|
console.log(prompt);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -167,8 +173,12 @@ function printUsage() {
|
||||||
${colors.bright}Documentation Content Scaffolding${colors.reset}
|
${colors.bright}Documentation Content Scaffolding${colors.reset}
|
||||||
|
|
||||||
${colors.bright}Usage:${colors.reset}
|
${colors.bright}Usage:${colors.reset}
|
||||||
yarn docs:create <draft-path> Create from draft
|
docs create <draft-path> Create from draft
|
||||||
yarn docs:create --url <url> --from-draft <path> Create at URL with draft
|
docs create --url <url> --from-draft <path> Create at URL with draft
|
||||||
|
|
||||||
|
# Or use with yarn:
|
||||||
|
yarn docs:create <draft-path>
|
||||||
|
yarn docs:create --url <url> --from-draft <path>
|
||||||
|
|
||||||
${colors.bright}Options:${colors.reset}
|
${colors.bright}Options:${colors.reset}
|
||||||
<draft-path> Path to draft markdown file (positional argument)
|
<draft-path> Path to draft markdown file (positional argument)
|
||||||
|
|
@ -181,8 +191,7 @@ ${colors.bright}Options:${colors.reset}
|
||||||
only local documentation links are followed.
|
only local documentation links are followed.
|
||||||
--context-only Stop after context preparation
|
--context-only Stop after context preparation
|
||||||
(for non-Claude tools)
|
(for non-Claude tools)
|
||||||
--print-prompt Output prompt text to stdout instead of file path
|
--print-prompt Force prompt text output (auto-enabled when piping)
|
||||||
(when running outside Claude Code)
|
|
||||||
--proposal <path> Import and execute proposal from JSON file
|
--proposal <path> Import and execute proposal from JSON file
|
||||||
--dry-run Show what would be created without creating
|
--dry-run Show what would be created without creating
|
||||||
--yes Skip confirmation prompt
|
--yes Skip confirmation prompt
|
||||||
|
|
@ -191,8 +200,8 @@ ${colors.bright}Options:${colors.reset}
|
||||||
${colors.bright}Stdin Support:${colors.reset}
|
${colors.bright}Stdin Support:${colors.reset}
|
||||||
When piping content from stdin, you must specify target products:
|
When piping content from stdin, you must specify target products:
|
||||||
|
|
||||||
cat draft.md | yarn docs:create --products influxdb3_core
|
cat draft.md | docs create --products influxdb3_core
|
||||||
echo "# Content" | yarn docs:create --products influxdb3_core,influxdb3_enterprise
|
echo "# Content" | docs create --products influxdb3_core,influxdb3_enterprise
|
||||||
|
|
||||||
${colors.bright}Link Following:${colors.reset}
|
${colors.bright}Link Following:${colors.reset}
|
||||||
By default, the script extracts links from your draft and prompts you
|
By default, the script extracts links from your draft and prompts you
|
||||||
|
|
@ -204,69 +213,54 @@ ${colors.bright}Link Following:${colors.reset}
|
||||||
Local documentation links are always available for selection.
|
Local documentation links are always available for selection.
|
||||||
Use --follow-external to also include external URLs (GitHub, etc.)
|
Use --follow-external to also include external URLs (GitHub, etc.)
|
||||||
|
|
||||||
${colors.bright}Workflow (Create from draft):${colors.reset}
|
${colors.bright}Workflow (Inside Claude Code):${colors.reset}
|
||||||
1. Create a draft markdown file with your content
|
1. Create a draft markdown file with your content
|
||||||
2. Run: yarn docs:create drafts/new-feature.md
|
2. Run: docs create drafts/new-feature.md
|
||||||
3. Script runs all agents automatically
|
3. Script runs all agents automatically
|
||||||
4. Review and confirm to create files
|
4. Review and confirm to create files
|
||||||
|
|
||||||
${colors.bright}Workflow (Create at specific URL):${colors.reset}
|
${colors.bright}Workflow (Pipe to external agent):${colors.reset}
|
||||||
1. Create draft: vim drafts/new-feature.md
|
1. Create draft: vim drafts/new-feature.md
|
||||||
2. Run: yarn docs:create \\
|
2. Pipe to your AI tool (prompt auto-detected):
|
||||||
--url https://docs.influxdata.com/influxdb3/core/admin/new-feature/ \\
|
docs create drafts/new-feature.md --products X | claude -p
|
||||||
--from-draft drafts/new-feature.md
|
docs create drafts/new-feature.md --products X | copilot -p
|
||||||
3. Script determines structure from URL and uses draft content
|
3. AI generates files based on prompt
|
||||||
4. Review and confirm to create files
|
|
||||||
|
|
||||||
${colors.bright}Workflow (Manual - for non-Claude tools):${colors.reset}
|
|
||||||
1. Prepare context:
|
|
||||||
yarn docs:create --context-only drafts/new-feature.md
|
|
||||||
2. Run your AI tool with templates from scripts/templates/
|
|
||||||
3. Save proposal to .tmp/scaffold-proposal.json
|
|
||||||
4. Execute:
|
|
||||||
yarn docs:create --proposal .tmp/scaffold-proposal.json
|
|
||||||
|
|
||||||
${colors.bright}Examples:${colors.reset}
|
${colors.bright}Examples:${colors.reset}
|
||||||
# Create from draft (AI determines location)
|
# Inside Claude Code - automatic execution
|
||||||
|
docs create drafts/new-feature.md
|
||||||
|
|
||||||
|
# Pipe to external AI tools - prompt auto-detected
|
||||||
|
docs create drafts/new-feature.md --products influxdb3_core | claude -p
|
||||||
|
docs create drafts/new-feature.md --products influxdb3_core | copilot -p
|
||||||
|
|
||||||
|
# Pipe from stdin
|
||||||
|
cat drafts/quick-note.md | docs create --products influxdb3_core | claude -p
|
||||||
|
echo "# Quick note" | docs create --products influxdb3_core | copilot -p
|
||||||
|
|
||||||
|
# Get prompt file path (when not piping)
|
||||||
|
docs create drafts/new-feature.md # Outputs: .tmp/scaffold-prompt.txt
|
||||||
|
|
||||||
|
# Still works with yarn
|
||||||
yarn docs:create drafts/new-feature.md
|
yarn docs:create drafts/new-feature.md
|
||||||
|
|
||||||
# Create at specific URL with draft content
|
# Include external links for context selection
|
||||||
yarn docs:create --url /influxdb3/core/admin/new-feature/ \\
|
docs create --follow-external drafts/api-guide.md
|
||||||
--from-draft drafts/new-feature.md
|
|
||||||
|
|
||||||
# Create with linked context (prompts for link selection)
|
${colors.bright}Smart Behavior:${colors.reset}
|
||||||
yarn docs:create drafts/new-feature.md
|
INSIDE Claude Code:
|
||||||
|
→ Automatically runs Task() agent to generate files
|
||||||
|
|
||||||
# Include external links for selection
|
PIPING to another tool:
|
||||||
yarn docs:create --follow-external drafts/api-guide.md
|
→ Auto-detects piping and outputs prompt text
|
||||||
|
→ No --print-prompt flag needed
|
||||||
|
|
||||||
# Pipe content from stdin (requires --products)
|
INTERACTIVE (not piping):
|
||||||
cat drafts/quick-note.md | yarn docs:create --products influxdb3_core
|
→ Outputs prompt file path: .tmp/scaffold-prompt.txt
|
||||||
echo "# Test Content" | yarn docs:create --products influxdb3_core
|
→ Use with: code .tmp/scaffold-prompt.txt
|
||||||
|
|
||||||
# Output prompt for use with other AI tools
|
|
||||||
# (Outside Claude Code: outputs file path by default)
|
|
||||||
yarn docs:create drafts/new-feature.md # Outputs: .tmp/scaffold-prompt.txt
|
|
||||||
|
|
||||||
# Use --print-prompt to output prompt text to stdout
|
|
||||||
yarn docs:create --print-prompt drafts/new-feature.md | llm -m gpt-4
|
|
||||||
yarn docs:create --print-prompt drafts/new-feature.md > prompt.txt
|
|
||||||
|
|
||||||
# Preview changes
|
|
||||||
yarn docs:create --from-draft drafts/new-feature.md --dry-run
|
|
||||||
|
|
||||||
${colors.bright}Environment-Aware Behavior:${colors.reset}
|
|
||||||
When running INSIDE Claude Code:
|
|
||||||
- Automatically runs AI analysis with Task() agent
|
|
||||||
- Creates file structure based on AI recommendations
|
|
||||||
|
|
||||||
When running OUTSIDE Claude Code:
|
|
||||||
- Outputs prompt file path to stdout by default
|
|
||||||
- Use --print-prompt to output prompt text instead
|
|
||||||
- Use the prompt with other AI tools (llm, ChatGPT, etc.)
|
|
||||||
|
|
||||||
${colors.bright}Note:${colors.reset}
|
${colors.bright}Note:${colors.reset}
|
||||||
To edit existing pages, use: yarn docs:edit <url>
|
To edit existing pages, use: docs edit <url>
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue