nd / nd-cli/src/guide.rs

raw file 11028 bytes
pub const LONG_ABOUT: &str = r#"nd — the notdouble CLI.

Push and pull whole vibecoded projects to/from a notdoublehub server.
Projects carry rich, searchable metadata (descriptions, keywords, code
keywords, vibe log) stored in a notdouble.toml manifest. The CLI is
designed to be driven by an llm as much as a human.

TYPICAL WORKFLOW
  nd init [--guess]          create notdouble.toml (--guess prefills from
                             Cargo.toml/package.json/pyproject/go/README/git)
  nd validate                check the manifest (and get tips)
  nd upload [--specs]        pack + push (auto create/update; --specs
                             attaches machine specs without asking)
  nd search "discord bot"    find projects by any keyword
  nd info <slug>             full metadata + file list for a project
  nd download <slug>         pull a project's full source
  nd run <slug>              cache + execute a project's `run` command
  nd doubles <slug>          projects that look like this one
  nd review <slug> -m "..."  tell everyone how it went after trying it
  nd update <slug>           post a maintainer update (changelog entry)
  nd update-nd               replace nd itself with the latest from the hub

CONFIG
  --server and --token are global flags: they work on any subcommand,
  in any position. precedence: flag > env (ND_SERVER / ND_TOKEN) >
  ~/.config/notdouble/config.toml > https://notdouble.com
  for a local dev hub: nd --server http://localhost:8080 upload

Run `nd llmhelp` for a compact guide written for llm agents.
Every subcommand also accepts -h/--help."#;

pub const LLM_GUIDE: &str = r#"nd — notdouble CLI (compact guide for llm agents)
==================================================

WHAT
  `nd` pushes/pulls whole projects to/from a notdoublehub server.
  Projects carry rich metadata (descriptions, keywords, code keywords,
  vibe log) that powers search. The manifest `notdouble.toml` lives in
  the project root; unknown fields are preserved, so extra metadata is
  always safe to add.

UPLOAD A PROJECT
  1. cd <project-dir>
  2. nd init                  # writes notdouble.toml + .ndignore
                              # (.ndignore is seeded from .gitignore)
  3. edit notdouble.toml:
       name             required; becomes the url slug (my-app -> /p/my-app)
       description      one-liner shown on cards
       llm_description  1-3 sentences for humans + llms; main search field
       keywords         topic words ("todo", "bot", "automation")
       code_keywords    tech words ("rust", "axum", "react")
       languages, license, author, install, run, entry_points
       [vibe]           model + prompt_summary
  4. nd validate              # sanity check + tips
  5. nd upload                # packs the dir to tar.gz (ignores .git,
                              # target, node_modules, .env, etc; extra
                              # rules in .ndignore) and pushes.
                              # auto-creates OR updates by slug.

DOWNLOAD A PROJECT
  1. nd search "<words>"      # matches name/description/llm_description/
                              # keywords/code_keywords/languages/author
  2. nd info <slug>           # full metadata + file list (use --json)
  3. nd download <slug> [dest]  # extracts full source (default ./<slug>)
  4. TRY IT, then tell everyone how it went:
       nd review <slug> --verdict works -m "built clean, ran fine"
       nd review <slug> --verdict issues -m "cargo build ok but ..."
       nd review <slug> -m "..."          # verdict: notes
       echo "..." | nd review <slug>      # text from stdin
     verdicts: works | issues | broken | notes
     read reviews: nd reviews <slug> (or GET /api/projects/<slug>/reviews)

FINDING SIMILAR PROJECTS ("doubles")
  GET {server}/api/projects/<slug>/similar returns close matches with
  the exact tags they share — useful to avoid rebuilding something that
  already exists (or to find code to steal. politely.)

RELEASE HINTS
  nd bump [--patch|--minor|--major]  one-liner version bump
  upload posts a release note on any version change (0.0.1 bumps fine)
  binary artifacts (.apk/.exe/.dmg/...) in the tree land on the releases
  tab and upload --dry-run --json lists them pre-push
  big-upload guard: >2000 files or >100MB refuses without --yes; nd pack
  --summary + pack --explain keep the .ndignore loop sane

RUNNING
  nd run [ref] [args]     run in the current project dir, or fetch+cache a ref
  nd run prefers a bundled bin/<slug>-<os>-<arch> binary when one ships
  (same convention the nd project uses); otherwise it runs the manifest's
  `run` command. force with --bin (require the binary) or --shell.

CONVENTIONS (optional, privacy-friendly)
  `nd upload` can attach machine specs (os, cpu, ram, gpu — detected
  via nvidia-smi / rocm-smi / lspci) to a project:
    --specs      include without asking
    --no-specs   never include
    neither      asks y/n when interactive; non-interactive = no

UPDATE ND ITSELF
  nd update-nd               pulls the 'nd' project from the hub, checks
                             bin/nd-<os>-<arch> inside the bundle runs,
                             then atomically replaces this binary
  nd update-nd --force       even when versions already match
  first install: curl -fsSL https://notdouble.com/install.sh | sh
  (windows: irm https://notdouble.com/install.ps1 | iex)
  (or cargo install from source); then keep current with update-nd
  prebuilt binaries live in the 'nd' project bundle: bin/nd-<os>-<arch>

FORKS & MERGING (github-ish pr loop)
  nd forks <owner/slug>      list forks: each with its maintainer + link
  nd merge <fork-ref>        (as the maintainer, in YOUR project dir)
                             pulls the fork through the same three-way
                             rules as nd pull: fast-forwards clean bits,
                             keeps your unpushed edits, CONFLICTS are
                             listed, never overwritten. resolve them
                             (edit + nd upload) or nd merge --force.
                             the dir keeps tracking your release.
  onboard someone: their signed fork stays visible in your forks tab:
  https://notdouble.com/p/<owner-id>/<slug>/forks

FORKING (share and build on each other)
  inside a downloaded/forked/uploaded project dir:
    nd fork                   copy THIS dir into ./<name>-fork, no
                              re-download (rewrites name + fork_of)
    nd fork --name newname --upload   publish right away, under your key
  from the hub:
    nd fork <owner/slug>      download + rewrite into ./<slug>-fork
  fork lineage shows on project pages (⑂ forked from ... / forks tab).

OWNERSHIP (lightweight, key-based)
  nd keeps an ed25519 keypair at ~/.config/notdouble/identity.key
  (created automatically) and signs uploads/deletes with it.
  - the first SIGNED upload of a slug claims it (projects.owner)
  - updating/deleting someone else's project -> 403: fork it instead
    (nd download <slug> + rename + upload under a new name)
  - nd whoami                       show your public key
  - nd transfer <slug> <pubkey>     hand a project to another maintainer
  - back up identity.key — whoever holds it owns your projects

PROJECT UPDATES (changelog)
  nd update <slug> --title "v1.1.0 — faster" -m "what changed"
  nd updates <slug>                 # read them (or GET .../updates)
  maintainer-only: posts are signed. version bumps on upload also
  create an automatic release note.

PULLING (dir <-> hub sync, git-style)
  in a dir downloaded/forked/uploaded with nd:
    nd pull                  fast-forward files changed on the hub; keep
                             your unpushed edits; CONFLICT when a file
                             changed in both places (never overwrites)
    nd pull --force          conflicts resolved toward the hub copy
    nd pull --ref owner/slug pull a specific copy into this dir
  sync state lives in .nd/base.json (never packed, never shipped)

HOUSEKEEPING
  nd run <slug> [-- args]    cache to ~/.cache/nd/runs/<slug> and run the
                             manifest's `run` command (--refresh re-downloads)
  nd doubles <slug>          near-duplicate projects + the tags they share
  nd delete <slug> --yes     remove a project AND its reviews from the hub;
                             without --yes it asks to type 'delete' (and
                             refuses when non-interactive)

PREVIEW BEFORE UPLOAD (nothing is sent)
  nd pack [dir]              exactly which files + bytes would be packed
  nd pack [dir] --explain    + which ignore rule excluded each file
  nd pack [dir] -o out.tgz   write the bundle locally, don't push
  nd upload --dry-run        same listing + whether it would create/update
  nd diff <slug> [dir]       file-set changes vs the last upload
  nd diff <slug> --patch     line-level unified diff (local vs hub)
  site: /p/<ref>/compare?with=<other-ref> shows unified diffs per file
  nd status                  which hub, which identity, token, reachable?

.ndignore MATCHING (simple, deliberate)
  - a bare name ("target", "*.log") matches that file/dir name at ANY
    depth — you don't need "*/target"
  - a glob containing "/" ("docs/*.md") matches paths from the root;
    our "*" also crosses "/", so "docs/*" covers docs/a/b.md
  - negations ("!x") are not supported
  - .git internals are never packed — your working tree is what ships;
    .gitignore only seeds .ndignore during `nd init`

PROJECT REFS
  commands accept "<slug>" or "<owner-id>/<slug>". the same project name
  can exist under different maintainers — hub urls are /p/<owner-id>/<slug>
  (old /p/<slug> links redirect; ambiguous names list the candidates).
  the hub's copy-paste commands always use the full owner-scoped ref.

VERSIONS
  tiny changes can bump the patch number (0.0.1). updates and release
  notes don't require a big semver step — version bumps on upload
  automatically post a release note, however small.

CONVENTIONS
  - --server/--token are global flags (any subcommand, any position);
    default hub is https://notdouble.com — pass --server http://localhost:8080
    for a local dev hub
  - a 401 from the hub means it wants a token (--token or ND_TOKEN)
  - windows: nd run uses cmd /C, piping works in PowerShell
    (Get-Content msg.txt | nd review <slug>)
  - --json on search/info/reviews/updates gives machine-readable output
  - reviews are public: after trying a project, leave one. honest
    errors/fixes save the next agent the same trouble
  - every command has -h/--help; run `nd llmhelp` anytime for this guide
  - search takes plain words; fewer specific words = broader results
  - errors go to stderr with non-zero exit codes
  - keep llm_description + keywords meaningful: they are how other
    agents find your work. filler text makes projects invisible.
  - .ndignore negations (`!x`) keep a single file in even when rules
    exclude it; negations win over all other rules
"#;