npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@codetreker/daynight

v0.54.0

Published

A client command toolkit for development workflows

Readme

Daynight CLI

The @codetreker/daynight package provides the daynight command and its dn alias. Use it to manage server-backed projects, tasks, discussion threads, attachments, Webhooks and Bot definitions, inspect remote Workers, install the using-daynight skill for coding agents, run foreground task workers through Herdr or browser-connected native Controllers, and run a local GitHub PR reviewer through Copilot CLI. Both command names share configuration and behavior. Supported native platforms are Linux, Windows and Apple Silicon (ARM64) macOS. Intel macOS is unsupported.

See the project overview for the browser workspace and service, and the development guide for source builds, validation, package versions and npm publication. The CLI test isolation guide describes the private test home and parent/child protection of real Daynight state (~/.daynight and the inherited DN_CONFIG_DIR) against writes and cleanup, including symbolic-link aliases. Ordinary test and installed acceptance suites exclude stress workloads. From this package, pnpm test:stress builds the CLI and runs the rendering and full Session-v2 .stress.ts suites. The command is local-only and refuses CI. The local stress guide owns selection and evidence interpretation. Each command's --help owns its exact usage. Review execution additionally requires Git, an authenticated GitHub CLI and Copilot CLI on PATH.

Install and update

Use the latest patch of Node.js 22 or newer (>=22, with no upper major-version limit). SQLite requires Node.js 22.14.0 or newer. Install the CLI with npm:

npm install --global @codetreker/daynight
dn --version

The installation provides both daynight and dn; every command works with either name, for example dn task list or dn skill install. Help and diagnostics use the canonical daynight spelling.

Update that npm global installation with:

dn update

The command checks @codetreker/daynight's latest version in the configured npm registry and installs that exact version only when it is newer. It updates the installation that is running, even if npm's current default global prefix has changed. An equal or newer installed version succeeds without installation or downgrade. User and global npm registry/authentication settings apply; the current working directory's project .npmrc does not select the update source.

daynight update --help explains the command. Self-update requires an npm-owned global package and launcher. Source checkouts, local dependencies, npx, pnpm and npm link installations receive guidance to use their original package manager. If an update is needed, run the command from outside its installation directory. The installer streams its output, enforces the target's Node.js engine requirement and reports permission, network and installation errors. It does not request administrator privileges automatically. npm owns replacement and recovery; a failed installation is not a promise that every original file remains unchanged.

The command verifies the installed manifest, launcher and a fresh invocation's version, then refreshes existing using-daynight skills from that installed package. It checks User destinations and the current Git worktree's Project destinations, including calls from subdirectories and linked worktrees. Outside Git it checks User destinations only. It does not search other projects or need agent launchers on PATH. Missing skills remain uninstalled. The same refresh runs when the CLI is already current or ahead, using its installed bundle.

Refresh replaces complete skill directories, including local edits and obsolete files. Shared physical destinations are written once. Each result identifies its agents, scope, path and package version. A skill failure exits nonzero and reports the package outcome separately; a successfully installed npm package is retained, and rerunning update retries the skill refresh. All phases must succeed before the command reports success. It requires no review configuration and does not open SQLite, modify sessions or restart a running reviewer or worker. The next CLI invocation uses the installed version. Restart any running reviewer or worker to use it; on Windows, a reviewer or worker holding a native addon open can prevent npm from replacing that file and cause the update to fail. The self-update decision records installation ownership and verification requirements.

Configuration root

DN_CONFIG_DIR selects the absolute directory containing config.yml and all Daynight user-local state. When unset, it remains ~/.daynight. Empty or relative values and paths containing control characters are rejected; use an expanded absolute path such as DN_CONFIG_DIR="$HOME/.daynight-test". Paths shown under ~/.daynight in this manual describe that default and follow the selected root.

The root includes credentials, worker identity, Worker/Review SQLite databases, locks, logs, caches, Controller launch tickets, journals, content and resume leases. Controller IPC identities are scoped to this root; long Unix socket paths use a private owner-checked temporary directory. Herdr retains its native socket length limit and reports an error for overly long roots; select a shorter root for Herdr mode. Native home and Provider session directories remain unchanged. Project .daynight bindings, Git worktrees, installed skills, npm installations and remote service data are not isolated by this setting.

Top-level agentCliAliases optionally maps daynight and/or dn to another executable for newly launched Worker/Controller Agents. It defaults to disabled. The development channel guide explains the mapping, platform limits, fixed build lifetime and shell verification.

Client commands

daynight                            # Show root help
daynight --help                      # Also -h
daynight --version                   # Also -v
daynight --skill                    # Print the CLI usage manual
daynight update
daynight login [--no-browser]         # Authorize CLI access through the browser
daynight logout                      # Revoke and remove the current CLI credential
daynight worker                     # Show worker help
daynight worker list [--json]        # Query this account's remote Workers
daynight worker show <worker-id> [--json]
daynight worker setup               # Check prerequisites and choose an agent and Projects
daynight worker run                 # Run until interrupted
daynight worker attach              # Connect to an existing Herdr task runtime
daynight worker repo list [--json]
daynight worker repo add [--project <project-id>]
daynight worker repo remove [--project <project-id>]
daynight worker resources list       # Inspect retained Herdr recordings and stop evidence
daynight worker retry <task-id> --claim-id <claim-id> [--project <project-id>]
daynight worker release <task-id> --claim-id <claim-id> --if-version <version> [--project <project-id>]
daynight review                     # Show review help
daynight review run
daynight review list                 # Also review ls
daynight review add-repo <remote> [--path <path>]
daynight completion                 # Show completion help
daynight completion bash
daynight completion zsh
daynight completion setup [--shell bash|zsh] [--rc-file <path>]
daynight skill                      # Show skill help
daynight skill install              # Select Agents, then User or Project scope
daynight project
daynight project create <name> [--repo <repo>] [--team <uuid|personal>] [--confirm]
daynight project list [--json]
daynight project show <project-id> [--json]
daynight project transfer --to-team <uuid|same-service-link> [--project <uuid>] [--if-version <version>] [--confirm] [--json]
daynight project delete [--project <uuid>] [--confirm] [--json]
daynight team list [--json]
daynight team show [--team <uuid|personal>] [--json]
daynight team create <name> [--confirm] [--json]
daynight team rename <name> [--team <uuid|personal>] [--if-version <version>] [--confirm] [--json]
daynight team delete [--team <uuid|personal>] [--if-version <version>] [--confirm] [--json]
daynight team invitation create [--team <uuid|personal>] [--confirm] [--json]
daynight team invitation list [--team <uuid|personal>] [--json]
daynight team invitation revoke <invite-id> [--team <uuid|personal>] [--confirm] [--json]
daynight team member list [--team <uuid|personal>] [--json]
daynight team member set-role <user-id> <member|admin> [--team <uuid|personal>] [--if-version <version>] [--confirm] [--json]
daynight team member remove <user-id> [--team <uuid|personal>] [--if-version <version>] [--confirm] [--json]
daynight team leave [--team <uuid|personal>] [--if-version <version>] [--confirm] [--json]
daynight team projects [--team <uuid|personal>] [--json]
daynight team default show [--json]
daynight team default set <uuid|personal> [--confirm] [--json]
daynight invitation inspect [--stdin] [--json]
daynight invitation accept [--stdin] [--confirm] [--json]
daynight webhook                         # Show Webhook help
daynight webhook catalog [--json]
daynight webhook list --personal [--json]
daynight webhook show <endpoint-id> --team <team-id> [--json]
daynight webhook create --personal --file <path> --confirm [--json]
daynight webhook subscription --help
daynight webhook secret --help
daynight webhook delivery --help
daynight webhook attempt --help
daynight webhook operation --help
daynight bot list [--json]
daynight bot show <bot-id> [--json]
daynight bot create --name <name> [--worker <worker-id>] [--cwd <path>] [--agent <codex|claude|copilot>] [--request-id <uuid>] [--json]
daynight bot delete <bot-id> --if-version <version> [--request-id <uuid>] [--json]
daynight task
daynight task create --title <title> [options]
daynight task list [--all | --status <status>] [--ready] [--assigned-to <assignee>] [--json] [--project <project-id>]
daynight task list --status in_progress --group-by chain [--assigned-to <uuid|me>] [--limit <1-50>] [--cursor <cursor> | --group-id <group-id> --targets-cursor <cursor>] [--json] [--project <project-id>]
daynight task search <expression> [--status <status>] [--assigned-to <assignee>] [--ready] [--allow-agents <true|false>] [--compatible-platform <platform>] [--json] [--project <project-id>]
daynight task ready [--limit <N>] [--json] [--project <project-id>]
daynight task show <task-id> [--json] [--project <project-id>]
daynight task step
daynight task step list <task-id> [--json] [--project <project-id>]
daynight task step show <task-id> <step-id> [--json] [--project <project-id>]
daynight task step add <task-id> --title <text> [--id <step-id>] [--description <markdown>] [--status <todo|in_progress|done|skipped>] [--before <step-id> | --after <step-id>] [--if-version <version>] [--json] [--project <project-id>]
daynight task step update <task-id> <step-id> [--title <text>] [--description <markdown>] [--if-version <version>] [--json] [--project <project-id>]
daynight task step set-status <task-id> <step-id> <todo|in_progress|done|skipped> [--if-version <version>] [--json] [--project <project-id>]
daynight task step move <task-id> <step-id> (--before <step-id> | --after <step-id> | --first | --last) [--if-version <version>] [--json] [--project <project-id>]
daynight task step delete <task-id> <step-id> [--if-version <version>] [--json] [--project <project-id>]
daynight task update <task-id> [options]
daynight task set-status <task-id> <status> [--claim-id <claim-id>] [--if-version <version>] [--force] [--project <project-id>]
daynight task delete <task-id> [--remove-depends] [--if-version <version>] [--force] [--project <project-id>]
daynight task graph <task-id> [--depends-only] [--json] [--project <project-id>]
daynight task thread read <task-id> [--before-id <message-id> | --after-id <message-id>] [--count=N] [--details] [--project <project-id>]
daynight task thread post <task-id> --body <text> [--reply-to <message-id>] [--claim-id <claim-id>] [--project <project-id>]
daynight task attachment
daynight task attachment put <task-id> <file> [--path <relative-path>] [--project <project-id>]
daynight task attachment list <task-id> [--tree | --json] [--project <project-id>]
daynight task attachment read <task-id> <relative-path> [--project <project-id>]
daynight task attachment remove <task-id> <relative-path> [--project <project-id>]

Groups and operations show help when --help or -h is their sole argument. Help, version, usage-manual output and completion generation do not resolve the user home, load review configuration, open SQLite or require review tools. review add-repo accepts one --path <path> before or after its remote; --path=value and -- are invalid. Unknown commands and invalid arguments exit with status 2; operation failures exit with status 1 and retain their cause. Task reads with partial Session observations print the available result and exit with status 3. Explicit Session read commands exit 130 on user signal cancellation. The old --daemon-review and root add-repo forms are invalid. The client design owns command composition and lazy loading; the composition decision records module ownership and the preserved data layout.

CLI usage manual

daynight --skill
dn --skill

--skill prints the complete standalone English CLI usage manual from the current package. The build generates it from the same topic sources installed with using-daynight, in a fixed order with topic and section links converted to internal anchors. It covers connection and Projects, Tasks, Steps, materials, write safety, Session reads and messages, Webhooks and Worker operations. Exact arguments remain in each subcommand's help. The output preserves the generated artifact's bytes, including YAML frontmatter and the final newline. The document has no package-relative references to read separately and requires no installed skill or individual topic files.

The option must be the sole argument. Extra arguments or another option exit with status 2 and empty stdout before the manual is read. A missing file, read failure, blank content or invalid UTF-8 exits with status 1 and retains its cause. Reading and validation complete before output; an output failure can leave partial stdout. The command requires no login, Git repository, configuration, launcher or interactive terminal, and creates no files.

The topic files are the only edited product-manual source; there is no separately maintained aggregate. Repository workflow and Worker execution constraints remain separate from this manual.

Agent skill installation

The public skill contains a short navigation entry and independently readable topic files. The entry directs an Agent to the files needed for its requested operation; writes also require the common write-safety rules and the target resource's conditions and recovery rules. daynight --skill exposes the complete generated manual offline. Installation validates every required topic and its internal file and section links before replacing a target. Whole-directory replacement removes obsolete references as well as local edits.

The Worker supplies its execution constraints and original assignment in its prompt; each repository's rules and actual authorization govern delivery.

Install the skill through an interactive terminal:

daynight skill install

The command detects available codex, copilot and claude launchers without starting them or checking login. Select one or more detected Agents with Space, then Enter; the initial selection is empty. Next select User or Project, with User initially selected. Installation starts after the scope is submitted. Repeating the command refreshes the full bundle from the running package. daynight update automatically refreshes existing User and current-worktree Project copies with the same replacement semantics; it also repairs existing skill directories whose entrypoint was removed and replaces dangling leaf links. A regular file at the expected skill-directory path is an error. See CLI updates for package ownership and failure handling.

| Agent | User destination | Project destination | |---|---|---| | Codex | ~/.agents/skills/using-daynight/ | <worktree>/.agents/skills/using-daynight/ | | Copilot CLI | ~/.agents/skills/using-daynight/ | <worktree>/.agents/skills/using-daynight/ | | Claude Code | ~/.claude/skills/using-daynight/ | <worktree>/.claude/skills/using-daynight/ |

User scope works outside Git. Project scope uses the current Git worktree root, including calls from subdirectories or linked worktrees, without requiring an origin, server configuration or project association. Installing the skill and associating a project remain separate operations. Terminal stdin and stderr are required; prompts use stderr and installation results use stdout. Help and installation do not depend on review configuration or credentials.

Each installation replaces the complete using-daynight leaf, including local edits and obsolete files. It then removes the legacy daynight leaf in the same selected physical skill root. The old name is retained until publication succeeds. Other skills, opposite-scope copies and parent-directory links are preserved; leaf links are replaced or removed without following their targets. Several Agent paths resolving to one physical root share one write. Destructive nesting involving an installation or legacy-cleanup path is rejected before writing. Discovery paths may be shared with unselected Agents, and host precedence continues to govern copies at other scopes.

The command reports per-Agent destinations and results. Failure stops later targets, retains earlier completed installations and exits nonzero. If legacy cleanup fails after publication, the new bundle stays installed and the command reports the incomplete migration. Replacement failure after removing an existing using-daynight leaf may leave that destination absent; diagnostics preserve the actual phase and reason. Rerunning installs the complete packaged bundle. Cancellation before publication cleans its stage and newly created empty parents.

Codex normally discovers changed skills automatically; restart its session if needed. For Copilot CLI run /skills reload and inspect /skills info using-daynight. Claude Code watches existing roots; use /reload-skills when a top-level skills directory was created during the session. The skill design owns mechanisms, routing and the simulated-launcher native installation matrix.

Shell completion

Bash 4.2 or newer and zsh have native completion scripts. Install startup configuration with:

daynight completion setup

Setup detects the calling shell from its direct parent process. If it cannot identify Bash or zsh reliably, select one explicitly:

daynight completion setup --shell bash
daynight completion setup --shell zsh

The login-shell preference in SHELL does not establish which shell is running. For a custom startup file, use --rc-file; only that file is managed:

daynight completion setup --shell bash --rc-file /path/to/bashrc

Bash setup manages .bashrc and the first readable existing login file in the order .bash_profile, .bash_login, .profile. It creates .bash_profile only when none of those files exists; if existing profiles are all unreadable, it reports an error. The login block runs only in interactive Bash and can safely appear in a .profile shared with other POSIX shells. It does not make the login shell load the rest of .bashrc.

zsh setup uses $ZDOTDIR/.zshrc, or $HOME/.zshrc when ZDOTDIR is unset. An exported empty ZDOTDIR selects /.zshrc; setup resolves a relative value from its current working directory. A later zsh started in another directory resolves that relative value from its own startup directory. A value set only inside zsh is not visible to the installer; use --rc-file in that case. The managed block reuses an initialized completion system or runs compinit with its normal security checks before loading daynight.

Setup recognizes its managed block and the documented standalone manual loading statement. Repeating it leaves an installed file unchanged. A managed block checks that both daynight and dn use the expected callable completion function before skipping loading. A missing or replaced registration for either command reloads the shared script and restores both commands. Complete registrations are reused, including when startup files load each other. Preserved manual loading statements keep their unconditional behavior: if one runs after a managed block, it generates and loads the script again. Existing content, line endings, permissions and startup-file symbolic links are retained. Added blocks use LF line endings because a carriage return is shell token data. Malformed managed blocks, invalid targets and file access failures produce explicit errors. Setup does not migrate blocks from earlier templates. If an earlier block is reported as unrecognized, remove its marked section and rerun setup, or use the source command below to activate the current script directly.

Setup reports the startup files it handled. It installs persistent configuration; an ordinary CLI child process cannot inspect or change its parent shell's loaded completion functions. Use the existing loading command to enable completion in the current session:

source <(daynight completion bash)

For zsh, initialize its completion system first if the session has not already done so:

autoload -Uz compinit
compinit
source <(daynight completion zsh)

The bash and zsh generation operations write only scripts to stdout and do not change startup files. Loading the zsh script without initialized compinit fails with a diagnostic. The outputs are designed for source; using the same output directly as an fpath autoload file is outside the loading contract. Setup checks file contents without executing them. Custom early returns or later commands that remove registrations can prevent a startup file from enabling completion; verify such configuration by starting the shell.

The generated scripts register completion for both daynight and dn. Completion suggests commands, nested operations, aliases, options, shell names and local directories for review add-repo --path. zsh also displays descriptions. The scripts run in the shell on each Tab without starting Node or reading review configuration, SQLite or the network. Directory suggestions preserve quoted and special-character paths; an uncreated target directory remains valid input.

New shells generate definitions from the currently installed package. After an update, run the applicable source command again to refresh an existing shell. A saved generated script must be regenerated after updating. The completion design explains the shared grammar and shell integration. The completion decision records compatibility and execution trade-offs; the setup decision records startup-file ownership and installation limits.

Configuration setup

The shared configuration file is ~/.daynight/config.yml. The complete config.example.yml covers service access, Team defaults, review and worker settings with their defaults and optional overrides. It is included at the root of the npm package. For an npm global installation, locate it with:

npm root --global

Open @codetreker/daynight/config.example.yml beneath that directory. Select the sections needed for your commands and replace the example repositories and local paths. For a new configuration, save the selected settings to ~/.daynight/config.yml; for an existing file, merge them while preserving its credential, generated workerId and unrelated settings. The example itself is not loaded automatically. Repository paths resolve from the configuration directory, with the rules in the worker and review guides.

Unknown fields at the root, in review or worker, and in their repository entries are ignored at runtime and preserved by CLI configuration edits. Known fields retain their type and value checks. Invalid YAML, duplicate keys and invalid mapping structures remain errors. Every CLI configuration write, including first-time workerId creation, preserves decoded values outside the fields it owns. If shared YAML aliases would change an unrelated value, the write fails and retains the original file; separate those aliases before retrying. Unaffected aliases remain valid.

Project and task commands use https://daynight.cc when the configuration file or serverUrl is absent. A production connection needs no server configuration. Run daynight login to display an authorization code and open the verification page. Check that the page's code matches the terminal, confirm the account and approve access. The CLI saves the resulting credential without displaying its secret. daynight login --no-browser displays the URL and code for authorization in another browser. The device authorization expires after ten minutes; rejection, expiry and cancellation leave an existing saved credential unchanged.

The CLI credential is named Daynight CLI (<hostname>), using the machine that runs daynight login, including when another device approves access. Hostnames longer than 85 Unicode characters are shortened to their first 85 characters to keep the credential name within 100 characters. The credential never expires by default. The Web account's token manager can set a future expiration, restore “Never expires”, or revoke it. Changing expiration keeps the same credential, so the saved CLI login continues without replacing its secret. Expired or revoked credentials cannot be revived. A credential represents the account's current project permissions. daynight logout revokes the current credential and removes its local value after a confirmed response; an already invalid credential is removed locally. Network or unconfirmed failures remain visible. Configuration changes made during login or logout cannot overwrite another service origin or another saved credential. A lost successful login response requires a fresh login; the account token list can revoke a credential whose response was lost.

Without a local credential, a service command fails before dispatch and directs the user to daynight login. A server 401 gives the same guidance. Business commands do not start login, follow redirects with credentials, or automatically repeat a write. Reconcile an unconfirmed business mutation before another one.

The first review run, review list or review ls asks for a repository when the file, review section or review.repositories field is absent. To configure one in advance, run:

daynight review add-repo https://github.com/OWNER/REPO.git
daynight review add-repo [email protected]:OWNER/OTHER.git --path ./review-other

Interactive guidance requires terminal stdin and stderr. Prompts and save messages use stderr so stdout retains its normal text or JSON format. Noninteractive missing review configuration fails with a review add-repo command. Shared YAML/schema errors, invalid selected values, explicit empty review lists and read failures retain their errors. Unrelated capability values remain outside the current command's validation. Help, version, usage-manual output, completion, update and invalid arguments do not prompt.

Test services and noninteractive automation use the existing ~/.daynight/config.yml fields. For a test service, provision its origin before running daynight login:

serverUrl: http://127.0.0.1:8787

For unattended access, a secret-provisioning process can write serverToken together with its intended serverUrl; omit serverUrl only when the credential belongs to https://daynight.cc. Keep that file private, with mode 0600 on POSIX, and never put credentials in command arguments, logs or repository files. Provisioners must preserve unrelated settings and pair the origin with its own credential. Replacing serverUrl manually does not clear an old token; remove or replace it before sending another request. External editors and provisioners do not participate in the CLI's configuration lock.

Tokens are opaque visible ASCII and require HTTPS except for HTTP origins whose host is literal localhost, a numeric IPv4 address in 127.0.0.0/8, or ::1. Invalid explicit origins and credentials remain errors. Normal CLI use requires no manual PAT creation. There is no top-level daynight setup command; shell startup installation remains available through daynight completion setup.

Review guidance collects values before one atomic save under the configuration write lock, preserving comments, unrelated settings and completed concurrent changes to unrelated fields. A selected review-field conflict requires a fresh decision. Login and logout check the observed origin and credential together under the same lock. Credential-bearing files use POSIX mode 0600, including review writes; files without a token retain existing permissions. Symlink rejection and atomic replacement apply to CLI configuration writers. Ctrl+C, termination signals or EOF cancel prompts without partial saves or business execution. Human input consumes no business timeout. Review guidance saves configuration without network, login or authentication checks; cloning and review state initialization belong to the business operation.

The configuration decision records the review-guidance and persistence choices; the device-login decision records the rationale for the default service, explicit login/logout and credential lifecycle. The top-level setup removal decision records the command removal and configuration-file provisioning boundary.

Project management

After daynight login, create, list or inspect projects on https://daynight.cc. To use a test server, set serverUrl in ~/.daynight/config.yml:

serverUrl: http://127.0.0.1:8787

The origin includes its protocol, host and optional port; the client adds /api/v1. When changing the origin externally, remove the old serverToken before logging in to the new service; manual edits do not run CLI credential cleanup. Then use the same commands:

daynight project create "Example"
daynight project create "Example" --repo https://github.com/OWNER/REPO.git --team personal --confirm
daynight project list
daynight project list --json
daynight project show <project-id> --json

Creation requires one positional name; quote names containing spaces. Omit --repo to use the current Git worktree's effective origin, including Git insteadOf expansion. Supply --repo to use that address without inspecting Git; this form, listing and details work outside Git repositories. For a name beginning with -, use daynight project create -- -name or put an explicit repository option before the terminator: daynight project create --repo <repo> -- -name. The name is sent unchanged.

Creation first scans every accessible project page and compares canonical repository identities. With one match it reports Project already exists. and the existing project, without resolving a Team, confirming or writing. Multiple matches fail with their IDs. With no match, --team <uuid|personal> selects the target; without it, the CLI uses the configured default for the current service and account, or Personal when no default is configured. An invalid or inaccessible default fails without falling back. The target must be accessible to the current user.

Creation requires confirmation: --confirm skips the interactive prompt, and a noninteractive invocation without it fails before writing. The CLI binds the request and response to the current user and submits the original name and repository address. The creator receives a direct admin grant. An unknown write is not automatically replayed. Lookup failures and exhausted command budgets stop before creation. This client preflight does not provide atomic uniqueness against concurrent creators, and the service continues to allow duplicate repository registrations. Project commands do not write repository bindings or ignore rules. Lists traverse all pages. Human output uses complete labeled project blocks with visible terminal-control escapes. JSON preserves resource fields and nanosecond timestamp strings; a later-page failure produces an error with empty stdout. The project/task requirements own the complete behavior and remaining task-command scope.

project transfer moves a Project to a Team identified by UUID or a same-service /teams/<uuid> link. It resolves the explicit Project or current repository without changing its binding or default Team. Only the current owner Team admin can transfer; destination membership is not required. The preview identifies the source, destination and expected access before confirmation. --confirm skips the prompt but retains the preview's exact versions and identity checks. An optional --if-version rejects a preview with a different ownership version. A successful receipt may report no remaining access. Conflicts require a fresh preview and decision; a lost receipt remains unknown even if a later read is 404. Project grants and invitations are preserved.

project delete selects an explicit Project or the current repository's Project, then reads the complete deletion preview. Only an administrator of the current owner Team can delete it. The Project becomes unavailable without a product recovery option; server history and files are retained. Active Worker claims block deletion. Interactive use requires the displayed JSON string literal of the Project name, even with --confirm; noninteractive use requires --confirm. The preview is an observation, not a condition on the deletion. JSON output contains only the confirmed receipt; preview text goes to stderr. An unknown outcome is never automatically retried, and a later 404 cannot prove success.

Team context

team list reads all Teams joined by the current account. team show and team projects use --team <uuid|personal> when supplied; otherwise they use the configured teamDefaults entry for the normalized service origin and current account, or the account's Personal Team when that entry is absent. team default show verifies and displays the resolved target. An invalid or inaccessible configured target fails explicitly; team list and an explicit --team remain available. These read commands do not change configuration or remote resources. Lists finish and validate every page before producing output. Use --json for complete resources. Project discovery and project list still use all accessible projects, independently of this default.

team default set <uuid|personal> validates the target and current membership, then saves it for the current service and account. It does not depend on the old default, so it can repair an invalid or inaccessible selection. personal saves the account's actual Personal Team UUID. Without --confirm, an interactive confirmation shows the target and role; non-interactive calls fail before writing. Cancellation or an identity mismatch leaves the configuration unchanged. The command does not alter remote preferences or repository bindings.

The saved map uses canonical UUIDs and the normalized service origin as keys:

teamDefaults:
  https://daynight.cc:
    80be22c3-96d8-4ed1-bcd3-b820f2508c62: b95baeff-1522-4d99-a9b4-dfcb58392eca

team default show --json and team default set --json return configured (the saved ID, or null for an absent entry on show) and the verified team resource. A token rotation for the same account retains its selection; other accounts and services have independent entries. The write preserves comments, unknown fields and other entries. It refuses to overwrite a changed credential or current entry, or to change unrelated settings through YAML aliases. Resolve the conflict or separate the aliases before retrying. When a local replacement result is uncertain, the command reads the current entry and does not replay the write automatically.

team create creates an ordinary Team, team rename changes its name, and team delete removes an empty ordinary Team. Names preserve their original characters and whitespace and may be duplicated. Rename and delete resolve the explicit or default Team and use an observed version; --if-version retains the specified positive int64 version, rejecting a mismatch with the observed version before submission. Personal Teams cannot be renamed or deleted.

Each write requires interactive confirmation or the boolean --confirm flag. Without it, non-interactive calls fail before writing. Delete prompts for the displayed JSON string literal and compares its decoded value exactly with the raw Team name; create and rename accept y or yes case-insensitively. Cancellation, refusal or a mismatch does not submit. Even with --confirm, delete sends the real name and version; the service still checks identity, authority and preconditions. Success uses the validated receipt; conflicts require a fresh decision, and unknown outcomes are never replayed. Reading current facts does not recover a lost receipt. A later output or cleanup failure retains a confirmed receipt. Use --json for the confirmed resource or deletion receipt.

team invitation create creates a single-use link for an ordinary Team. The link is disclosed once on stdout; save it securely before sharing it. Listing invitations returns metadata only and cannot recover the link. revoke disables an invitation; an unchanged receipt can also mean it was already revoked, consumed, or absent. Create and revoke require confirmation or --confirm, and use the explicit or default Team context. Personal Teams cannot have invitations. An unknown create result does not cause a replacement invitation to be created automatically. team member list reads the selected Team's complete member directory, including nullable profile fields, roles and membership versions. team member set-role changes an existing member's role; team member remove removes one, and team leave removes the current user. Only a Team admin can manage other members or change roles; any member can leave. Personal membership is immutable and an ordinary Team must retain an admin. These operations do not change Project grants or the configured default Team.

Membership writes use the target member's observed positive int64 membership version, not the Team or Project grant version. Supply its exact digits with --if-version to retain an earlier decision; a mismatch with the current observation is rejected before submission. Writes require interactive confirmation or --confirm, and bind the current user to the request and response. A validated receipt reports the actor's remaining Team role, including null after leaving; a successful self-exit uses that receipt without a follow-up Team read. Unknown outcomes are not automatically replayed. A later read only establishes current facts and cannot recover a lost receipt.

Accept an invitation

Use invitation inspect to preview a Project or Team invitation without consuming it. Use invitation accept to accept for the currently signed-in account; neither command resolves the configured default Team. Supply the same-service invitation link through the hidden terminal prompt, or through standard input with --stdin. Standard input is read to EOF, accepts up to 4096 bytes and may end in one LF or CRLF. Do not put links or tokens in arguments, flags, shell history, or logs. The CLI does not persist the secret. The link fragment is sent only in the request body.

Acceptance displays the target and current account for confirmation. A non-interactive acceptance requires --confirm; without confirmation it does not write. An existing direct Project grant or Team membership retains its role and does not consume the invitation. Inherited-only Project access does not replace a direct grant: accepting creates a direct member grant. Invalid, expired, revoked, consumed or deleted-target invitations are unavailable.

Identity mismatch is a refusal. A lost or malformed acceptance response may follow a commit and is reported as an unknown outcome; the CLI does not replay it automatically. Reading current membership cannot recover the original receipt. Use --json for the validated preview or acceptance receipt.

Webhook management

webhook manages event types, endpoints, subscriptions, signing secrets, delivery history, payloads, redelivery and operation receipts through the authenticated service. Run daynight webhook --help and each leaf's --help for the complete command and option list. The dn alias has the same commands.

Every leaf except catalog requires exactly one explicit owner: --personal selects the authenticated User, and --team <team-id> selects a Team UUID. The current Git directory and default Team do not select an owner; --team personal is not accepted. The CLI verifies the authenticated user once and checks the response identity throughout the command. IDs are canonical UUIDs; versions and generations are positive decimal int64 values, preserved exactly.

daynight webhook catalog --json
daynight webhook list --personal --json
daynight webhook create --personal --file ./endpoint.json --confirm --json
daynight webhook update <endpoint-id> --team <team-id> --if-version <version> --file ./patch.json --confirm --json
daynight webhook subscription reconfirm <endpoint-id> --personal --if-version <version> --project <project-id> --confirm
daynight webhook secret show <endpoint-id> --personal --reveal
daynight webhook delivery list <endpoint-id> --personal --limit 50 --json
daynight webhook delivery payload <endpoint-id> <delivery-id> --personal --output ./payload.json
daynight webhook delivery redeliver <endpoint-id> <delivery-id> --personal --if-version <version> --if-generation <generation> --confirm --json
daynight webhook operation show <operation-id> --personal --json

Create, update and subscription replacement take exactly one of --file or --stdin. Inputs are strict UTF-8 JSON with no duplicate or unknown keys, at most 32 levels and 256 KiB; the final request including control fields is also limited to 256 KiB. Files must be regular files. Supply URL and adapter configuration in the JSON, not command arguments. Update is a nonempty partial object; subscription replacement is a complete array. Reconfirmation accepts one or more distinct --project values. All writes except create require the observed --if-version; redelivery also requires --if-generation. No write implicitly reads the latest version or retries a conflict. Noninteractive and stdin writes require --confirm; an interactive confirmation contains only the owner, operation, opaque targets and versions.

Writes preserve an operation ID and original issued time. Supply both --operation-id and --issued-at, or let the CLI generate both after confirmation. --operation-out <path> exclusively creates a private prepared record before sending; it contains the scope, versions and request hash, but no body, URL, credentials or secret. Private prepared-file creation is unavailable on Windows and fails before sending. An unknown result retains the original identity and is never automatically replayed. Inspect the original receipt with operation show; current resource values or a missing receipt do not establish the original outcome. To resume, use --resume-operation <path> on the original write command and supply the same owner, targets, versions, mode and input. It verifies the record and exact request hash before reading the receipt. A matching receipt confirms the original operation without another write. The CLI rejects a receipt whose expiry is at or before the local clock. The service also enforces expiry with its database clock: expired receipt reads return 404 not_found, and matching retained expired replays return 410 operation_expired. Rotation receipts retain their original keyId and nullable overlapUntil even after later rotations or endpoint deletion. A missing receipt permits at most one identical submission only with --confirm, complete original input and an issued time within the service's admission window (five minutes past and sixty seconds future). An inaccessible receipt or expired window leaves the outcome unknown. A prepared record alone cannot reconstruct the body.

Endpoint list validates every page before producing a complete result; delivery and attempt lists return one page, defaulting to 50 items, with --limit from 1 to 100 and an explicit --cursor for continuation. History can be incomplete because of retention. Secret show reports metadata unless --reveal is explicitly requested; rotation does not reveal the new secret. A successful redelivery only registers it and does not mean delivery has completed.

Payload output defaults to the exact original bytes without an added newline. --json returns its validated Base64 wrapper; --output <path> writes a private file after validation and never overwrites an existing target. File publication requires Linux with procfs and glibc; it fails when inode-bound publication is unavailable. These two options are mutually exclusive. Payload access and retention are independently enforced by the service. Normal JSON output is one value followed by LF. Runtime errors with --json go to stderr and distinguish invocation from original operation outcomes; a confirmed write remains confirmed if local output fails. Exit status is 0 for success, 2 for usage errors and 1 for runtime failures or unknown results.

Task management

daynight task search <expression> searches Task IDs, complete titles and Markdown descriptions in one project, including completed Tasks by default. Supply the entire expression as one shell argument; -- permits an expression beginning with a dash. For example:

daynight task search 'title:缓存 AND NOT description:废弃' --status done
daynight task search -- '-worker'

Words and quoted phrases match literal substrings, with ASCII case folding. ID queries match the canonical hyphenated UUID, including prefixes and middle fragments. A positive exact full ID match ranks before a title match; fragments do not. Uppercase NOT, AND, and OR, parentheses, implicit AND, and the id:, title: and description: fields form expressions. Inside quotes, \" and \\ escape a quote and a backslash. --status, --assigned-to, --ready, --allow-agents, --compatible-platform, --type, and --parent intersect the expression; search does not accept --all. Explicit --project searches that project directly; otherwise the current repository resolves the project.

Search reads and validates every page before producing output, preserving the server's order. Text shows the full Task ID and title, type, parent, status, actual parent Goal or none, positive match fields, and a description snippet when present. A negative-only match is identified as such; text escapes terminal controls. --json emits one newline-terminated array whose entries contain only id, type, parentId, projectId, title, status, cancelledAt, context, and match. Both formats omit the assignee and update time; use task show for complete Task details. An empty result is No matching tasks. in text or [] in JSON. Invalid arguments and expression syntax exit 2; read, permission, protocol, cancellation, budget and search_changed failures exit 1. Errors go to stderr, and a failed search emits no partial results on stdout. A changed search must be started again.

Task commands use the same serverUrl configuration as project commands:

daynight task create --title "Implement sign-in" --description '## Sign-in

Implement OAuth sign-in for the web workspace. Deliver the callback flow and
visible failure recovery; preserve the existing session and provider rules.
Complete when a valid login opens the workspace and a rejected login can retry.'
daynight task create --title "Build the sign-in page" --depends-on <design-task-id> --external-depends-on <authentication-task-id>
daynight task create --type goal --title "Improve installation"
daynight task create --type goal --title "Unassigned Goal" --clear-assigned-to
daynight task create --title "Document prerequisites" --parent <goal-id> --status todo
daynight task ready
daynight task ready --parent <goal-id> --limit 5 --json
daynight task ready --allow-agents true --compatible-platform linux --json
daynight task list --allow-agents false --ready
daynight task list --ready
daynight task list --all --json
daynight task list --type goal --json
daynight task list --parent none --json
daynight task list --status in_progress --json
daynight task list --status in_progress --group-by chain --assigned-to me --json
daynight task list --ready --assigned-to me --json
daynight task list --assigned-to unassigned --json
daynight task show <task-id> --json
daynight task properties <task-id> --json
daynight task properties --schema --json
daynight task set-property <task-id> pullRequests '[{"url":"https://github.com/owner/repo/pull/123","title":"Fix synchronization"}]' --if-version <observed-version>
daynight task remove-property <task-id> pullRequests --if-version <observed-version>
daynight task update <task-id> --parent <goal-id> --if-version <version>
daynight task update <task-id> --parent none --if-version <version>
daynight task update <task-id> --description=
daynight task update <task-id> --allow-agents true --if-version <version>
daynight task create --title "Check Windows build" --required-platform windows
daynight task update <task-id> --required-platform macos --if-version <version>
daynight task update <task-id> --clear-required-platform --if-version <version>
daynight task create --title "Review installation" --assigned-to <user-uuid>
daynight task update <task-id> --assigned-to <user-uuid> --if-version <version>
daynight task update <task-id> --clear-assigned-to --if-version <version>
daynight task set-status <task-id> <status> [--claim-id <claim-id>] [--if-version <version>] [--force] [--project <project-id>]
daynight task update <task-id> --depends-on <task-a> --depends-on <task-b>
daynight task update <task-id> --clear-dependencies
daynight task graph <task-id> --json
daynight task graph <task-id> --depends-only
daynight task graph <task-id> --depends-only --json

task graph requires a task ID. It returns every member of that task's ordinary undirected dependency component, including completed tasks and sibling branches, plus one layer of external prerequisites declared by those members. External tasks that depend on the chain do not enter the result. Added external tasks do not expand their own prerequisites or chain. The service applies its 1,000-task and 5,000-dependency-reference limits to this returned set; unrelated chains do not count toward this query's limits.

Every returned task retains its full dependsOn, externalDependsOn, blockedBy and ready. An external context task can therefore reference an ID with no task row in this response. Those references remain available for dependency audits. The ordinary graph output includes the project, statistics for all returned nodes, compact node facts and each node's Session observation. relation marks ordinary members and external context; sessionSummary aggregates only in-progress ordinary members. Its observation time is independent of the graph snapshot's observedAt. --depends-only does not request Session observations; it uses the same tasks but prints only ID, Depends on and External dependencies, with full UUIDs and none for empty sets. With --json, this mode returns a bare array of objects containing only id, dependsOn and externalDependsOn.

Project-scoped operations accept --project <project-id>, which selects a project for one invocation without reading Git or local bindings. task properties --schema uses only the authenticated service and rejects project selection. Otherwise, the CLI reads the current worktree's effective origin, normalizes equivalent HTTPS/SSH/SCP addresses, and matches the configured server's projects. A missing match fails with Project does not exist; multiple matches require explicit selection. A unique discovery is saved in the worktree's .daynight/project.yml with the server origin and repository identity, after ensuring /.daynight/ is effective in the root .gitignore. A cached binding is verified against the server on each use and remains stable if another project later shares that repository.

Task resources require type (task or goal) and a nullable parentId. Create, list and search default to task; --type goal selects a Goal. List, search and ready accept --parent <goal-id|none>: omission does not filter by parent, none selects Tasks without a Goal, and a Goal UUID selects its direct children. Filters apply before pagination and persist across pages. Create defaults to no parent; on update, omission preserves the current parent. --parent none sends null, and a Goal UUID sets the parent. A Goal cannot have a parent. Membership does not change Task identity, status, assignee, materials, dependencies or their classifications.

A Goal uses todo, in_progress, done or cancelled and is never ready. Full Goal reads include progress; its Session registration is not_applicable. Graph nodes are ordinary Tasks, and dependency IDs may refer to unavailable resources without exposing their details. Ready remains a dependency fact; it does not apply the additional parent-state restrictions used for automatic claims.

Before creating a Goal in done or cancelled, or setting a Goal to either status, the CLI explains on stderr that child Task states are retained and future automatic claims are excluded. Before deleting a Goal, it explains that the Goal and all its Tasks become invisible, membership remains, and running Tasks stop through the existing process after a successful observation. Confirm interactively or supply --force; noninteractive calls without it do not submit. Status and delete read the target type and identity even with --if-version, and retain the caller’s exact version for the write. --force skips only the Goal prompt; the service still applies its business and version checks.

Ordinary Task creation defaults to proposed; --status proposed|todo explicitly selects the initial state, so confirmed internal multi-step work can start in todo. Goal creation defaults to todo and accepts todo, in_progress, done and cancelled. Both default to the signed-in assignee; --assigned-to <user-uuid> overrides it, and --clear-assigned-to explicitly creates an unassigned resource. These two options conflict. Ordinary creation uses allowAgents=false and unrestricted requiredPlatform=null unless explicitly set. Goal execution fields are not applicable. Unset properties remain absent; creation does not inject a PR array or worker null. task set-status <id> <status> sets proposed, todo, in_progress, done or cancelled for ordinary Tasks. The nonterminal states and done allow direct setting without a mandatory proposed or todo stage, retaining reopening and direct completion; ordinary Task cancellation is irreversible and does not prove delivery. Goal-specific lifecycle effects remain subject to the service's business checks. Cancelled records and materials remain readable unless effective parent deletion hides them. Every project member may use ordinary status setting. Active worker completion requires the current owner and an explicit --claim-id <claim-id> with target done; the CLI uses the existing typed completion operation. The option is validated before configuration or network access, is rejected for other targets, and is never inferred from a task or environment. Without it, ordinary status setting is unchanged. Release uses its protected operation; a later execution uses ordinary claim eligibility. Status does not grant execution or delivery authority. Generic updates cannot write status; old lifecycle commands and routes are removed without aliases. --if-version uses the exact reviewed int64 value; without it, the CLI reads the target before submitting. No write retries occur. A controller-bounded worker assignment executes its supplied claim in the provided worktree, finishes with the explicit claim ID after delivery, and leaves system worktree cleanup and next-task selection to its controller. Version is checked before same-state handling: current same-state keeps version, update time and timing unchanged; actual changes increment once. Actual cancellation records required nullable cancelledAt, preserves existing execution times and materials, and satisfies dependencies without deleting edges. Active ownership must first be released; cancelled tasks cannot be claimed or withdrawn back to todo.

Entering in_progress or done requires all direct prerequisites, ordinary and external, to be done or cancelled. Reopening done requires no direct in-progress or done dependents; cancelled dependents do not add a reopen restriction. Refusals return sorted blocking task IDs without cascading changes. The project transaction serializes status and dependency writes and preserves materials, assignedTo, properties/PRs, permission, both dependency sets and attachments.

Migration 014_task_status_assignment.sql converts historical proposed rows to todo, increments only those versions and updates their update time while preserving every other field, including requiredPlatform and historical execution timestamps. Default, data, CHECK and ledger change atomically. Other rows and applied migrations remain unchanged; restart does not repeat the conversion. A subsequent migration restores proposed as a current status and the creation default without changing existing rows or historical migrations.

Task resources expose required nullable startedAt, completedAt and cancelledAt. Cancellation preserves both execution endpoints and records its own database time; a cancelled task never resumes execution or starts a new duration. Actual entry into in_progress starts a new interval and clears the end; return to proposed or todo clears both. In-progress to done preserves a nullable start and records a real end; proposed/todo to done records only an end, leaving duration unknown. Metadata and same-state writes preserve time. Task-graph and task-sync responses supply a database observedAt sample; Web synchronization updates its separate clock without rebuilding unchanged graph/index data. Read-only timing fields remain in JSON; human CLI output keeps its field choices. The status requirements and architecture own the complete rules.

Task and graph resources also require externalDependsOn, a sorted, duplicate-free subset of all dependsOn IDs. CLI JSON preserves it and the shared human dependency block shows External dependencies (N): .... Current API dependency fields are independently optional: a dependsOn-only PATCH retains classification on surviving edges, while an externalDependsOn-only PATCH replaces the exact external subset. CLI --depends-on and --external-depends-on compile both complete sets whenever either option is supplied; ordinary-only clears the external subset and external-only replaces all relationships. Omit both CLI options to preserve them. Metadata and lifecycle actions retain unmodified classification. Every edge still participates in blocking and cycles.

Every Project resource includes settings with an exact positive int64 version and executionWarningMinutes from 1 through 2147483647, initially 60. Project create/read/list, the project in graph responses, and a successful settings PATCH return this same shape. The member-readable settings page lets administrators save or cancel a draft; ordinary members see the saved value without editing. The server checks current administrator authority after the project lock, then the observed settings version. An equal-value save preserves version and updatedAt; a real change increments version and updates updatedAt. Migration preserves historical project timestamps. CLI JSON preserves settings and nested versions without rounding; human output keeps its established fields.

An unconfirmed settings PATCH response requires a Project and membership reread before another write. Failed reconciliation keeps Save blocked and offers read retry; network, protocol, 5xx or navigation cancellation never prove rollback. Confirmed refusals and unsaved/canceled drafts do not apply local settings. Project-only changes update graph metadata while retaining the task index and layout when tasks and summary are unchanged. Running known-start tasks subscribe to one visible-page ticker; completed duration uses stored endpoints and unknown starts show no inferred duration. Warnings use an unrounded strict comparison and disappear on completion without changing task status. The server-sample clock avoids client wall-clock skew but does not remove network sampling delay.

The Web shared status row offers todo, in progress, done and cancelled on every material tab. Cancelled tasks retain readable status and materials without reopen, resume or withdraw actions. The current original-state item remains selectable. Cancellation uses the existing confirmation with the task name, transition, irreversibility, retained readability and dependency consequence. Active claims mark cancellation unavailable and expose the existing release requirement on hover or keyboard focus without submitting. Dismissing the confirmation or pressing Escape sends no write.

Status, Automatic execution / 自动执行 and platform confirmation share one per-task mutation owner. Pending, stale or unknown results block conflicting writes. Current-version same-state responses confirm no stored change; actual cancellation requires cancelledAt and preserves both execution endpoints and other Task fields. Confirmed changes refresh the normal graph, retaining the cancelled node and materials. Unknown outcomes use GET-only reconciliation, preserving errors and never attributing observed state to the uncertain request. Closing details does not roll back a submission.

Task details use one platform select in the left status group to display the confirmed requirement and offer Any platform, Windows, Linux and macOS. Choosing a different value opens confirmation showing the current and target platforms; only confirmation submits the reviewed exact task version. Choosing the saved value, Cancel, close, backdrop dismissal and Escape send no request. Cancellation returns focus to the select. The confirmed value remains displayed until success, and Any platform clears requiredPlatform. Overview has no se