import { Wiki } from './lib/wiki.js'
export { Wiki }
// CLI entry point
const isMain = typeof Pear !== 'undefined' || process.argv[1]?.includes('hyper-wiki')
if (isMain && process.argv.length > 2) {
const args = parseArgs(typeof Pear !== 'undefined' ? Pear.config.args : process.argv.slice(2))
if (args.help) {
console.log(`
hyper-wiki — P2P wiki with Hyperdrive storage
Usage:
hyper-wiki create <slug> --title "Page Title" --content "Markdown content"
hyper-wiki read <slug>
hyper-wiki update <slug> --content "Updated content"
hyper-wiki delete <slug>
hyper-wiki list
hyper-wiki search <query>
Options:
--storage <path> Storage directory (default: ./wiki-data)
--title <title> Page title
--content <content> Page content (markdown)
--author <name> Author name
--replicate Enable P2P replication via Hyperswarm
--help Show this help
`)
process.exit(0)
}
run(args).catch((err) => {
console.error('Error:', err.message)
process.exit(1)
})
}
async function run (args) {
const storage = args.storage || './wiki-data'
const wiki = new Wiki(storage, { replicate: args.replicate })
await wiki.ready()
const cmd = args._[0]
const slug = args._[1]
switch (cmd) {
case 'create':
case 'update': {
if (!slug) throw new Error('Usage: hyper-wiki create <slug>')
const content = args.content || ''
const meta = await wiki.create(slug, content, {
title: args.title || slug,
author: args.author || ''
})
console.log(`${cmd === 'create' ? 'Created' : 'Updated'}: ${slug} (v${meta.version})`)
break
}
case 'read': {
if (!slug) throw new Error('Usage: hyper-wiki read <slug>')
const page = await wiki.read(slug)
if (!page) {
console.log(`Page not found: ${slug}`)
} else {
console.log(`# ${page.title} (v${page.version})`)
console.log(`Author: ${page.author || 'unknown'} | Updated: ${new Date(page.updated).toISOString()}`)
console.log('---')
console.log(page.content)
}
break
}
case 'delete': {
if (!slug) throw new Error('Usage: hyper-wiki delete <slug>')
await wiki.remove(slug)
console.log(`Deleted: ${slug}`)
break
}
case 'list': {
const pages = await wiki.list()
if (pages.length === 0) {
console.log('No pages yet.')
} else {
for (const p of pages) {
console.log(` ${p.slug.padEnd(30)} v${p.version} ${new Date(p.updated).toISOString().slice(0, 10)} ${p.title}`)
}
}
break
}
case 'search': {
const query = args._.slice(1).join(' ')
if (!query) throw new Error('Usage: hyper-wiki search <query>')
const results = await wiki.search(query)
if (results.length === 0) {
console.log(`No results for: ${query}`)
} else {
for (const r of results) {
console.log(` ${r.slug.padEnd(30)} score:${r.score} ${r.title}`)
}
}
break
}
default:
console.error(`Unknown command: ${cmd}`)
console.error('Run with --help for usage')
process.exit(1)
}
await wiki.close()
}
function parseArgs (argv) {
const result = { _: [] }
for (let i = 0; i < argv.length; i++) {
const arg = argv[i]
if (arg === '--help') {
result.help = true
} else if (arg === '--replicate') {
result.replicate = true
} else if (arg.startsWith('--')) {
const key = arg.slice(2)
const next = argv[i + 1]
if (next && !next.startsWith('--')) {
result[key] = next
i++
} else {
result[key] = true
}
} else {
result._.push(arg)
}
}
return result
}