diff --git a/.agents/skills/dev-workflow/SKILL.md b/.agents/skills/dev-workflow/SKILL.md deleted file mode 100644 index 812a78f..0000000 --- a/.agents/skills/dev-workflow/SKILL.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -name: dev-workflow -description: How to develop the nddev-zcode-app repository — the daily workflow, conventions, and quality gates. Covers making changes, running the doctor check, testing in a temp directory, and cutting releases. Use when starting work on this repo, before committing changes, or when unsure about the development process. ---- - -# dev-workflow - -The daily workflow for developing `nddev-zcode-app`. Read this after -`repo-orientation` (which explains what the repo IS). - -## Step 1: Understand the scope - -Before making changes, read: -1. `.agents/skills/repo-orientation/SKILL.md` — the repository map. -2. `AGENTS.md` — the workspace rules. -3. The specific area you're changing (e.g. a marketplace, the installer, docs). - -## Step 2: Make changes - -Follow the architecture: edit source files in `zcode_tools/marketplaces//` -(for setup content) or `cli-tools/` (for installer logic) or `build/` (for -version/secrets). Never edit rendered `~/.zcode` files directly. - -### Conventions - -- **English only** for all content. -- **Conventional commits**: `type(scope): description` (imperative, lowercase, 72 chars). -- **Plugin manifests are metadata-only** — no component arrays. -- **Convention discovery**: skills/commands/agents are found by directory structure. -- **Secrets never committed** — `${VAR}` placeholders + `build/.env` (gitignored). - -## Step 3: Validate (run before every commit) - -```bash -# Quick: JSON validity + plan passes + no secrets tracked -python3 -c "import json,glob; [json.load(open(f)) for f in glob.glob('**/*.json', recursive=True)]" -cli-tools/scripts/install.sh install --marketplace --platform macos --plan -cli-tools/scripts/install.sh install --marketplace --platform ubuntu --plan -git ls-files | grep -E '\.env$' # must be empty -``` - -For a deep check, follow the `doctor` skill (in `nddev-builder/plugins/core/skills/doctor/`) -— it checks 8 axes: versions, ZCode spec, stale paths, broken commands, JSON, -secrets, installer plan, cross-references. - -## Step 3b: Run the test suite (31 pytest tests) - -The centralized test suite lives in the **parent control-plane repo** -(`validation/nddev-zcode-app/`), NOT inside this module. Run it from the -parent root: - -```bash -cd -python3 -m pytest -q validation/nddev-zcode-app/ -v --rootdir=validation/nddev-zcode-app -``` - -Or use the fast lane: `bash validation/nddev-zcode-app/scripts/validate_fast.sh`. -Follow the `run-tests` skill for details. - -## Step 4: Test in a temp directory (safe, isolated) - -Never test `--apply` against the live `~/.zcode` while ZCode is running. Use a -temp target: - -```bash -# Full lifecycle test (install → update → switch → restore → remove): -NDDEV_TARGET=/tmp/zcode-test NDDEV_BACKUPS_DIR=/tmp/zcode-test-backups \ - cli-tools/scripts/install.sh install --marketplace --platform macos --apply -``` - -This builds into `/tmp/zcode-test` without touching the real `~/.zcode`. - -## Step 5: Commit and push - -```bash -git add -A -git commit -m "type(scope): description" -git push -``` - -The repo has branch protection (blocks force-push and deletion). Direct pushes -to `main` are allowed for the solo maintainer. - -## Step 6: Release (when behavior changes) - -Follow the `release-build` skill (in `nddev-builder/plugins/core/skills/release-build/`): -1. Bump `build/version.json` + `VERSION` + `pyproject.toml` + `build/manifest.json` - (default: patch `+0.0.1`). -2. Add a CHANGELOG entry. -3. Validate (Step 3) + run tests (Step 3b). -4. Tag + push (`git tag X.Y.Z && git push --tags`). - -The `release.yml` workflow verifies tag == VERSION and publishes a GitHub Release. - -## How to add new things - -| You want to… | Read this skill (in nddev-builder core plugin) | -|---|---| -| Add a marketplace | `add-marketplace` | -| Add a plugin | `add-plugin` | -| Add a skill | `add-skill` | -| Add a command | `add-command` | -| Add an agent | `add-agent` | -| Add a hook | `add-hook` | -| Add an MCP/CLI tool | `add-mcp-server` | -| Add a model provider | `add-provider` | -| Add a reference doc | `add-reference` | -| Add a CLI tool | `add-tool` | -| Enable a plugin | `enable-plugin` | -| List components | `list-components` | -| Remove a component | `remove-component` | -| Run tests | `run-tests` | -| Add a test | `add-test` | -| Run benchmarks | `run-benchmarks` | -| Cut a release | `release-build` | -| Check consistency | `doctor` | - -These skills are in `zcode_tools/marketplaces/nddev-builder/plugins/core/skills/`. -They are also installed as slash commands: `/nddev-add-plugin`, `/nddev-doctor`, etc. - -## Common pitfalls - -- **Don't hardcode marketplace names** in docs or architecture — the system is generic. -- **Don't edit `~/.zcode` directly** — always change source and re-run the installer. -- **Don't forget `hooks.events.`** (not `hooks.`) in cli-config templates. -- **Don't use `cp -R src dest`** for restore when dest exists (nesting bug) — use - the `restore.sh` script which handles file vs dir correctly. -- **Don't run `--apply` inside a live ZCode session** — it moves `~/.zcode` out from - under the running process. diff --git a/.agents/skills/repo-orientation/SKILL.md b/.agents/skills/repo-orientation/SKILL.md deleted file mode 100644 index cc28c07..0000000 --- a/.agents/skills/repo-orientation/SKILL.md +++ /dev/null @@ -1,204 +0,0 @@ ---- -name: repo-orientation -description: Map of the nddev-zcode-app repository — read it FIRST when starting a new session or working anywhere inside this repo. Explains the three-layer architecture, the self-contained marketplace model, the full installer lifecycle, the nddev-builder toolkit (18 skills for building marketplaces/plugins/components), where every kind of file lives, where tests live (parent repo), and the rules that keep the repo consistent. Use when unsure what a directory is for, where to add something, or how the system fits together. ---- - -# nddev-zcode-app — repository map - -This is a **build system + installer** for ZCode, not a runtime. It recreates a -complete, version-stamped `~/.zcode` from source on macOS and Ubuntu. - -**Read this skill first**, then `AGENTS.md` for the rules, then `dev-workflow` -for the daily process. - -## What this repo does (in one paragraph) - -The repo holds one or more **marketplaces** — each is a self-contained `~/.zcode` -setup (AGENTS.md, config templates, skills, plugins). The installer selects ONE -marketplace and builds a clean `~/.zcode` from it. It can also download and -install the ZCode app itself (bootstrap), back up and restore versions, and -switch between different setups. - -## Current marketplaces (3) - -| Marketplace | Purpose | Status | -|---|---|---| -| **nddev-builder** | Meta-tooling for building marketplaces, plugins, and components. Contains the `core` plugin with **18 skills, 18 commands, 1 agent** covering the full development lifecycle (create, list, modify, remove, validate, test, benchmark, release). | Complete | -| **nddev-designer** | Designer-oriented setup (placeholder scaffold). | Placeholder | -| **nddev-developer** | Developer-oriented setup for full-stack engineering (placeholder scaffold). | Placeholder | - -## Repository structure - -``` -zcode_tools/marketplaces// SOURCE: each marketplace = one complete ~/.zcode setup -cli-tools/ INSTALLER: bootstrap + install + remove + restore -build/ ARTIFACTS: version pins, secrets, manifest (shared) -.agents/skills/ WORKSPACE SKILLS: repo-orientation + dev-workflow -config/ CONTRACT: nddev-contract.json -references/ BASELINE: zcode-baseline.json -docs/ DOCS: install, architecture, secrets -.serena/ SERENA: project config + memory -.github/ CI: workflows, templates, branch protection -``` - -## What lives where (inside a marketplace) - -``` -zcode_tools/marketplaces// - AGENTS.md → ~/.zcode/AGENTS.md - marketplace.json → ~/.zcode/marketplaces// - cli-config.template.json → ~/.zcode/cli/config.json (rendered: hooks.events, mcp.servers, plugins) - v2-config.template.json → ~/.zcode/v2/config.json (rendered: provider defs, ${API_KEY}) - v2-setting.template.json → ~/.zcode/v2/setting.json (rendered: prefs, ${HOME}) - mcp.json → merged into cli/config.json (mcp.servers) - hooks.json → merged into cli/config.json (hooks.events) - skills/ commands/ agents/ → ~/.zcode/{skills,commands,agents}/ (user-scope) - plugins// → plugin bundles (convention-discovered) - .zcode-plugin/plugin.json ← metadata only (no component arrays) - skills//SKILL.md - commands/.md - agents/.md - references/.md - tools// ← CLI tools for the CLI+skill pattern -``` - -## The nddev-builder toolkit (18 skills) - -The `nddev-builder` marketplace's `core` plugin is the **development toolkit**. -Use these skills (via slash commands like `/nddev-add-skill`) to build and -maintain any marketplace: - -| Category | Skills | -|---|---| -| **CREATE** | add-marketplace, add-plugin, add-skill, add-command, add-agent, add-hook, add-mcp-server, add-provider, add-reference, add-tool | -| **LIST** | list-components | -| **MODIFY** | enable-plugin | -| **REMOVE** | remove-component | -| **TEST** | run-tests, add-test, run-benchmarks | -| **VALIDATE** | doctor (8 structural axes + Step 9 test suite) | -| **RELEASE** | release-build | - -All skills are in `zcode_tools/marketplaces/nddev-builder/plugins/core/skills/`. - -## The full installer lifecycle - -```bash -# 0. Download + install the ZCode app itself (from official CDN, pinned version): -cli-tools/scripts/install.sh bootstrap --apply - -# 1. List available setups: -cli-tools/scripts/install.sh list - -# 2. Build ~/.zcode from a marketplace: -cli-tools/scripts/install.sh install --marketplace --plan -cli-tools/scripts/install.sh install --marketplace --apply - -# 3. Update (re-run install with same marketplace — old is backed up, state restored): -cli-tools/scripts/install.sh install --marketplace --apply - -# 4. Switch to a different marketplace: -cli-tools/scripts/install.sh install --marketplace --apply - -# 5. List backups: -cli-tools/scripts/install.sh list --backups - -# 6. Restore from a backup slot: -cli-tools/scripts/install.sh restore --slot <0-9> --apply - -# 7. Remove (back up + delete): -cli-tools/scripts/install.sh remove --apply -``` - -Target directory: `--target ` or `ZCODE_TARGET` in `build/.env` (default `~/.zcode`). -Mode: `--plan` (dry-run, default) or `--apply`. - -### Backup convention - -- 10 slots (`0-9`), named `--old.zcode`. -- When all 10 are full, the oldest (by mtime) is overwritten. -- Each install/update/switch/remove backs up the current target first. - -### Restore policy - -- **Always restored**: `v2/credentials.json`, `v2/certs/`, `cli/agents/`, `cli/db/`, `cli/artifacts/`. -- **Never restored**: logs, crash dumps, plugin cache (regenerated by ZCode). - -## Version files (keep in sync — 4 files) - -The build version is tracked in **4 files** that must always agree: - -- `VERSION` (root, single line) -- `build/version.json` → `build_version` -- `build/manifest.json` → `build_version` -- `pyproject.toml` → `[project]` → `version` - -The core plugin version (in `marketplace.json` plugins[] entry and `plugin.json`) -is independent — it bumps only when the plugin's content changes. - -ZCode runtime pins (`zcode_app_version`, `zcode_cli_version`) are in -`build/version.json` and must match `references/zcode-baseline.json`. - -## Tests and benchmarks (in parent repo) - -Tests live in the **parent control-plane repo** (`rldyour-ai-cli-tools`), NOT -inside this module — by design, to keep the implementation clean: - -``` -rldyour-ai-cli-tools/validation/nddev-zcode-app/ - conftest.py + _helpers.py ← fixtures + helpers - test_*.py (7 files, 31 tests) ← pytest (marketplace structure, lifecycle, - restore safety, backup rotation, config - rendering, version parity, validation scripts) - benchmarks/bench_lifecycle.py ← performance timing - scripts/validate_fast.sh ← quick lane (<60s) - scripts/validate_release.sh ← full lane (<300s) -``` - -Run: `python3 -m pytest -q validation/nddev-zcode-app/ --rootdir=validation/nddev-zcode-app` - -## Secrets - -- `build/.env.example` — committed template (keys only, no values). -- `build/.env` — gitignored real values. Loaded by the installer at runtime. -- MCP servers get `${VAR}` rendered at install time. -- CLI tools get `~/.zcode/.env` (chmod 600, rendered from `build/.env` at install). - -## Workspace skills (in `.agents/skills/`) - -These are read by ZCode when working inside this repo. They are NOT shipped to -`~/.zcode` — they exist only for developing this repo. - -| Skill | Purpose | -|---|---| -| `repo-orientation` (this skill) | What the repo is and how it's structured. Read FIRST. | -| `dev-workflow` | How to develop: make changes, validate, test, commit, release. | - -## Where rules live - -- `AGENTS.md` (repo root) — workspace rules for editing this repo. -- `marketplaces//AGENTS.md` — the system instructions installed into `~/.zcode`. -- `config/nddev-contract.json` — the product contract (format, policy refs). -- `build/manifest.json` — machine-readable layout, backup/restore policy. -- `references/zcode-baseline.json` — verified ZCode runtime baseline. -- `docs/` — install, architecture, and secrets documentation. - -## ZCode native format reminders - -- **Each marketplace is self-contained** — AGENTS.md and config templates live inside it. -- Plugin components are **convention-discovered** (`skills//SKILL.md`, `commands/.md`, - `agents/.md`). The manifest is metadata-only. -- Hooks live under `hooks.events.` in `cli/config.json` (requires `hooks.enabled: true`; - exactly 7 events). Config-file hooks do NOT use `hooks.` directly. -- MCP servers use `{"mcpServers":{}}` in `.mcp.json` (plugin form) or `mcp.servers` in - `cli/config.json`. Config-file servers do NOT expand `${VAR}` — the installer does it. -- Secrets are **never committed** — only `${VAR}` placeholders. - -## Key principles (timeless) - -- **This repo evolves.** Marketplaces, plugins, and skills are added over time. The - architecture scales: new marketplace = new directory, new plugin = new bundle inside it. -- **No hardcoded marketplace names in the architecture docs.** The system works for any - marketplace, not just the current ones. -- **The installer is the only way to modify `~/.zcode`.** Never hand-edit rendered files. -- **English only** — all content, including skill descriptions. -- **Conventional-commit style** — `type(scope): description`. diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md deleted file mode 100644 index dba71e9..0000000 --- a/.claude/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -@../AGENTS.md diff --git a/.claude/skills/dev-workflow b/.claude/skills/dev-workflow deleted file mode 120000 index 17e0135..0000000 --- a/.claude/skills/dev-workflow +++ /dev/null @@ -1 +0,0 @@ -../../.agents/skills/dev-workflow \ No newline at end of file diff --git a/.claude/skills/repo-orientation b/.claude/skills/repo-orientation deleted file mode 120000 index 2c5d043..0000000 --- a/.claude/skills/repo-orientation +++ /dev/null @@ -1 +0,0 @@ -../../.agents/skills/repo-orientation \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f5a65e0..2a1d5a7 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,15 +1,20 @@ +# Pull request + ## Scope Describe the `zcode_tools/`, `cli-tools/`, `build/`, or documentation surface changed. ## Validation -- [ ] JSON files valid (`python3 -c "import json,glob; [json.load(open(f)) for f in glob.glob('**/*.json', recursive=True)]"`) -- [ ] `cli-tools/scripts/install.sh install --marketplace --plan` runs clean +- [ ] JSON files validate with Python's standard library +- [ ] Installer plan runs clean for the affected marketplace on macOS and Ubuntu - [ ] No `.env` tracked (`git ls-files | grep -E '(^|/)\.env$'` returns nothing) +- [ ] No development-only agent, test, validation, benchmark, or runtime + artifacts added - [ ] Targeted smoke/checks for the touched scope ## Release -- [ ] `build/version.json` and `VERSION` bumped when release behavior changes +- [ ] The three build-version sources match for release behavior changes +- [ ] Core-plugin versions match between `marketplace.json` and `plugin.json` - [ ] `CHANGELOG.md` entry added for release behavior changes diff --git a/.github/workflows/README.md b/.github/workflows/README.md index ca4cd72..64ce7df 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -1,29 +1,30 @@ # GitHub workflows -The free OSS security suite reuses public workflows from +The public repository keeps release automation, repository labeling, and generic +security checks. Implementation validation, platform matrices, tests, and +benchmarks run from the maintainers' private `nddev-harnesses` control plane +against a pinned submodule revision. + +Reusable workflows are sourced from [`NDDev-it-com/nddev-ci-workflows`](https://github.com/NDDev-it-com/nddev-ci-workflows) -@ `0.3.0` (`f4b2971...`), pinned by full SHA. +release `0.3.0`, pinned to commit +`1acba687361415b3f5942acceb40b228bb0387fd`. ## Workflows -- **`validate.yml`** *(custom)* — JSON validation, secret-leak guard, ShellCheck, - and the installer `--plan` dry-run. Runs on push/PR to `main`. -- **`codeql.yml`** — GitHub CodeQL analysis (Python + Actions, security-and-quality). - Delegates to `nddev-ci-workflows/public-codeql.yml`. Runs on push/PR + weekly. -- **`dependency-review.yml`** — blocks PRs that introduce high-severity - vulnerabilities or incompatible licenses. Delegates to `public-dependency-review.yml`. -- **`secret-scan.yml`** — scans tracked files for leaked credentials. - Delegates to `nddev-ci-workflows/secret-scan.yml`. -- **`scorecard.yml`** — OpenSSF Scorecard analysis (JSON artifact/check mode). - Delegates to `public-scorecard-json.yml`. Runs on push to `main` + weekly. -- **`cross-platform.yml`** — JSON validation + installer `--plan` on Ubuntu and - macOS runners. Delegates to `cross-platform-smoke.yml`. -- **`security-static.yml`** *(custom)* — enforces all GitHub Actions are pinned to - full commit SHAs. Runs on push/PR + weekly. -- **`release.yml`** *(custom)* — tag-driven: on a SemVer tag, verifies it matches - `VERSION`, extracts the matching `CHANGELOG.md` section, publishes a GitHub Release. -- **`labeler.yml`** *(custom)* — applies area labels based on changed paths. +- **`codeql.yml`** runs CodeQL for GitHub Actions on pushes, pull requests, and + the weekly schedule through `public-codeql.yml`. +- **`dependency-review.yml`** checks pull-request dependency changes through + `public-dependency-review.yml`. +- **`secret-scan.yml`** scans tracked content for exposed credentials through + `secret-scan.yml`. +- **`scorecard.yml`** runs the public OpenSSF Scorecard JSON workflow on pushes + and the weekly schedule. +- **`release.yml`** verifies a SemVer tag against all three build-version + sources, checks core-plugin version parity, extracts the matching changelog + section, and publishes the GitHub Release. +- **`labeler.yml`** labels pull requests from `.github/labeler.yml`. -All external actions are pinned to full commit SHAs; `security-static.yml` -enforces this. The secret-leak guard in `validate.yml` fails CI if any `.env` -is ever tracked. +All external actions and reusable workflows are pinned to immutable commit SHAs. +The private harness validates those pins and the public/private repository +boundary before a module revision is released. diff --git a/.github/workflows/cross-platform.yml b/.github/workflows/cross-platform.yml deleted file mode 100644 index 1256e75..0000000 --- a/.github/workflows/cross-platform.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: cross-platform - -on: - push: - branches: [main] - pull_request: - branches: [main] - -permissions: - contents: read - -concurrency: - group: cross-platform-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -jobs: - cross-platform-smoke: - name: Cross-platform smoke - uses: NDDev-it-com/nddev-ci-workflows/.github/workflows/cross-platform-smoke.yml@1acba687361415b3f5942acceb40b228bb0387fd # 0.3.0 - with: - os_list: '["ubuntu-latest", "macos-latest"]' - python_version: "3.13" - command: | - set -euo pipefail - for f in \ - build/version.json \ - build/manifest.json \ - config/nddev-contract.json \ - references/zcode-baseline.json; do - python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$f" - done - for f in \ - zcode_tools/marketplaces/*/marketplace.json \ - zcode_tools/marketplaces/*/cli-config.template.json \ - zcode_tools/marketplaces/*/v2-config.template.json \ - zcode_tools/marketplaces/*/v2-setting.template.json \ - zcode_tools/marketplaces/*/plugins/*/.zcode-plugin/plugin.json; do - [ -f "$f" ] && python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$f" - done - MP="$(ls zcode_tools/marketplaces | head -1)" - cli-tools/scripts/install.sh install --marketplace "$MP" --platform "$([ "$(uname -s)" = "Darwin" ] && echo macos || echo ubuntu)" --plan diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4b1d7a2..550b9f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,16 +24,25 @@ jobs: with: fetch-depth: 0 - - name: Verify tag matches VERSION + - name: Verify tag and version contracts run: | set -euo pipefail tag="${GITHUB_REF_NAME}" version="$(cat VERSION)" - if [ "$tag" != "$version" ]; then - echo "::error::Tag '$tag' does not match VERSION '$version'" + version_json="$(python3 -c 'import json; print(json.load(open("build/version.json"))["build_version"])')" + manifest_json="$(python3 -c 'import json; print(json.load(open("build/manifest.json"))["build_version"])')" + marketplace_plugin="$(python3 -c 'import json; plugins=json.load(open("zcode_tools/marketplaces/nddev-builder/marketplace.json"))["plugins"]; print(next(plugin["version"] for plugin in plugins if plugin["name"] == "core"))')" + plugin_manifest="$(python3 -c 'import json; print(json.load(open("zcode_tools/marketplaces/nddev-builder/plugins/core/.zcode-plugin/plugin.json"))["version"])')" + if [ "$tag" != "$version" ] || [ "$version" != "$version_json" ] || [ "$version" != "$manifest_json" ]; then + echo "::error::Tag and build versions differ: tag=$tag VERSION=$version version.json=$version_json manifest.json=$manifest_json" exit 1 fi - echo "ok: tag $tag == VERSION $version" + if [ "$marketplace_plugin" != "$plugin_manifest" ]; then + echo "::error::Core plugin versions differ: marketplace=$marketplace_plugin plugin.json=$plugin_manifest" + exit 1 + fi + echo "ok: tag and build versions match $version" + echo "ok: core plugin versions match $plugin_manifest" - name: Extract changelog section id: changelog diff --git a/.github/workflows/security-static.yml b/.github/workflows/security-static.yml deleted file mode 100644 index 001b749..0000000 --- a/.github/workflows/security-static.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: security-static - -on: - push: - branches: [main] - pull_request: - branches: [main] - schedule: - - cron: "30 6 * * 1" - -permissions: - contents: read - -concurrency: - group: security-static-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -jobs: - action-pins: - name: Action pins (full SHA) - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - fetch-depth: 0 - - - name: Check GitHub Actions are pinned to full SHAs - run: | - set -euo pipefail - bad=0 - while IFS= read -r line; do - uses=$(printf '%s' "$line" | sed -E 's/.*uses:\s*//; s/@.*//; s/#.*//') - ref=$(printf '%s' "$line" | sed -E 's/.*@//; s/\s.*//; s/#.*//') - # Skip local actions (./...) and reusable-workflow calls (no @version). - case "$uses" in ./*) continue ;; esac - if [ -n "$ref" ] && ! printf '%s' "$ref" | grep -Eq '^[0-9a-f]{40}$'; then - echo "::warning::$uses is pinned to '$ref' (not a full SHA)" - bad=1 - fi - done < <(grep -rnE '^\s*uses:\s' .github/workflows/ 2>/dev/null || true) - if [ "$bad" -ne 0 ]; then - echo "::error::One or more actions are not pinned to a full commit SHA." - exit 1 - fi - echo "ok: all actions pinned to full SHAs" diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml deleted file mode 100644 index 5748544..0000000 --- a/.github/workflows/validate.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: validate - -on: - push: - branches: [main] - pull_request: - branches: [main] - workflow_dispatch: - -permissions: - contents: read - -concurrency: - group: validate-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -jobs: - validate: - name: Validate (ubuntu) - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.0.0 - with: - python-version: "3.13" - - - name: Validate JSON files - run: | - set -euo pipefail - echo "::group::Validate JSON" - # Repo-level static config files. - for f in \ - build/version.json \ - build/manifest.json \ - config/nddev-contract.json \ - references/zcode-baseline.json; do - if [ -f "$f" ]; then - python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$f" - echo "ok: $f" - fi - done - # All marketplace-scoped JSON (config templates, marketplace manifests, plugins). - for f in \ - zcode_tools/marketplaces/*/marketplace.json \ - zcode_tools/marketplaces/*/cli-config.template.json \ - zcode_tools/marketplaces/*/v2-config.template.json \ - zcode_tools/marketplaces/*/v2-setting.template.json \ - zcode_tools/marketplaces/*/hooks.json \ - zcode_tools/marketplaces/*/mcp.json \ - zcode_tools/marketplaces/*/plugins/*/.zcode-plugin/plugin.json; do - if [ -f "$f" ]; then - python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$f" - echo "ok: $f" - fi - done - echo "::endgroup::" - - - name: No secrets tracked - run: | - set -euo pipefail - if git ls-files | grep -E '(^|/)\.env$'; then - echo "::error::An .env file is tracked by git — secrets must never be committed." - exit 1 - fi - echo "ok: no .env tracked" - - - name: ShellCheck installer - uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0 - with: - severity: warning - additional_paths: cli-tools/scripts - - - name: Installer plan (dry-run) - run: | - cli-tools/scripts/install.sh install --marketplace "$(ls zcode_tools/marketplaces | head -1)" --platform ubuntu --plan diff --git a/.gitignore b/.gitignore index 9f3ad70..1c3f6ba 100644 --- a/.gitignore +++ b/.gitignore @@ -5,15 +5,6 @@ build/.env # macOS .DS_Store -# Python -__pycache__/ -*.pyc -.venv/ -.pytest_cache/ -.coverage -coverage.xml -pytest.xml - # Editor / IDE *.swp .idea/ diff --git a/.serena/.gitignore b/.serena/.gitignore deleted file mode 100644 index a19aa4b..0000000 --- a/.serena/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -/cache -/project.local.yml -/.auto_sync_head -/.dirty_stop_ack -/.flow_blocker_ack.json -/.flow_post_task_state.json -/.flow_sync_marker -/.serena_sync_state.json -/.stop_lifecycle_timeout_marker -/.sync_marker diff --git a/.serena/memories/INDEX-01-OVERVIEW.md b/.serena/memories/INDEX-01-OVERVIEW.md deleted file mode 100644 index 239aeee..0000000 --- a/.serena/memories/INDEX-01-OVERVIEW.md +++ /dev/null @@ -1,60 +0,0 @@ -# nddev-zcode-app — project memory index - -> Serena durable project memory. Add domain-specific memories as -> `--.md` siblings. This index is the entry point. - -Last updated: 2026-07-09 -Last commit: 08f5e7b - -## Project - -`nddev-zcode-app` — build system + installer that recreates a complete, -version-stamped `~/.zcode` from source on macOS (desktop) and Ubuntu -(desktop/server). Not a runtime; produces `~/.zcode`. - -## Architecture (three layers) - -- `zcode_tools/marketplaces/` — SOURCE: the complete desired `~/.zcode` as editable files. -- `cli-tools/` — INSTALLER: renders `zcode_tools/` into `~/.zcode`. -- `build/` — ARTIFACTS: version.json, manifest.json, system/, secrets templates. - -## Current marketplaces (3) - -- **nddev-builder** — development toolkit (core plugin: 18 skills, 18 commands, 1 agent). - Used to build and maintain all other marketplaces. -- **nddev-designer** — designer setup (placeholder). -- **nddev-developer** — full-stack developer setup (placeholder). - -## Key facts - -- Build version source (4 files, must always agree): `VERSION`, `build/version.json`, - `build/manifest.json`, `pyproject.toml`. -- Core plugin version (2 files, independent of build version): `marketplace.json` - plugins[] entry + `plugins/core/.zcode-plugin/plugin.json`. -- Backup convention: `~/.zcode-backups/--old.zcode` (10 slots 0-9; - oldest overwritten when full, regardless of version). -- Secrets: `build/.env.example` (committed) → `build/.env` (gitignored); `${VAR}` - placeholders rendered at install time. -- ZCode plugin components are convention-discovered (skills/commands/agents); - MCP uses `{"mcpServers":{}}`; hooks need `hooks.enabled: true` + `hooks.events.`. -- Tests (31 pytest) + benchmarks live in the PARENT repo (`rldyour-ai-cli-tools/ - validation/nddev-zcode-app/`), NOT inside this module. The suite includes - validation helper coverage for `validate_fast.sh`. -- Restore hardening (1.0.1): C1 (temp-copy staging prevents source self-destruction), - C2 (BUILD-VERSION guard), C3 (no silenced failures). - -## nddev-builder toolkit (18 skills) - -CREATE (10): add-marketplace, add-plugin, add-skill, add-command, add-agent, -add-hook, add-mcp-server, add-provider, add-reference, add-tool -LIST (1): list-components -MODIFY (1): enable-plugin -REMOVE (1): remove-component -TEST (3): run-tests, add-test, run-benchmarks -VALIDATE (1): doctor (8 axes + Step 9 test suite) -RELEASE (1): release-build - -## Memory domains - -(Add new memories here as they are written. Example domains: RELEASE, TECHDEBT, -INSTALLER, PLUGINS.) diff --git a/.serena/project.yml b/.serena/project.yml deleted file mode 100644 index f10deb3..0000000 --- a/.serena/project.yml +++ /dev/null @@ -1,24 +0,0 @@ -# Serena project config for nddev-zcode-app. -# Canonical project memory lives under .serena/memories/. Only project.yml, -# memories/, and this .gitignore are tracked; cache/ and project.local.yml are -# runtime artifacts and ignored. -project_name: "nddev-zcode-app" - -# Language servers started by Serena. This repo is shell + JSON/YAML/TOML config -# plus markdown docs. bash covers the installer scripts; the rest gives symbol -# navigation for the config templates. -languages: - - bash - - json - - yaml - - toml - - markdown - -encoding: "utf-8" - -ignore_all_files_in_gitignore: true - -# Keep Serena out of the rendered ~/.zcode target and the secrets file. -ignored_paths: - - node_modules - - .venv diff --git a/.shellcheckrc b/.shellcheckrc deleted file mode 100644 index 55e3346..0000000 --- a/.shellcheckrc +++ /dev/null @@ -1,12 +0,0 @@ -# ShellCheck configuration for nddev-zcode-app. -# https://github.com/koalaman/shellcheck/wiki/Directives - -# Sourced library files (install.sh sources these; SC1090/SC1091 expected). -disable=SC1090,SC1091 - -# Variables set in other sourced files (libs set vars used by callers; SC2154 expected). -disable=SC2154 - -# The exec boundary in install.sh intentionally builds args dynamically; -# array expansion now handles this, but SC2086 may still flag optional args. -disable=SC2086 diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index bc4ae5b..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,108 +0,0 @@ -# AGENTS.md - -## Purpose - -`nddev-zcode-app` is a build system + installer that recreates a complete, -version-stamped `~/.zcode` from source on macOS (desktop) and Ubuntu -(desktop/server). It is **not** a runtime — it produces the `~/.zcode` directory -that the ZCode client reads. - -GitHub repository: `https://github.com/NDDev-it-com/nddev-zcode-app` (`PUBLIC`). -Author: Danil Silantyev (github:rldyourmnd), CEO NDDev. License: AGPL-3.0-or-later. - -## Quick orientation - -**Read `.agents/skills/repo-orientation/SKILL.md` first** — it's the full -repository map. Then `.agents/skills/dev-workflow/SKILL.md` for the daily -development process. - -## Current state (3 marketplaces) - -| Marketplace | Purpose | Status | -|---|---|---| -| **nddev-builder** | Development toolkit (`core` plugin: 18 skills, 18 commands, 1 agent). Use this to build and maintain all other marketplaces. | Complete | -| **nddev-designer** | Designer-oriented setup (placeholder). | Placeholder | -| **nddev-developer** | Full-stack developer setup (placeholder — to be filled). | Placeholder | - -## Source of truth - -- `zcode_tools/marketplaces//` — each marketplace is a **self-contained - setup** (its own AGENTS.md, config templates, mcp/hooks, skills/commands/agents, - plugins). The installer selects ONE and builds `~/.zcode` from it. -- `cli-tools/scripts/install.sh` — the installer entry point (`--marketplace `). -- `cli-tools/scripts/lib/{common,version,build}.sh` — shared installer logic. -- `cli-tools/scripts/{macos,ubuntu}/install.sh` — platform runners. -- `cli-tools/scripts/restore.sh` — selective runtime-state restore. -- `config/nddev-contract.json` — the product contract (native format, secrets - policy, backup/restore refs). -- `references/zcode-baseline.json` — the verified ZCode runtime baseline. -- `build/version.json` + `VERSION` + `pyproject.toml` + `build/manifest.json` — - the **4 version files** that must always agree. -- `build/.env.example` → `build/.env` (gitignored) — secrets injected at install - (shared across all marketplaces). -- `.agents/skills/repo-orientation/` — the repository map skill (read first). -- `.claude/CLAUDE.md` — Claude Code bridge to `AGENTS.md`. - -## Tests and benchmarks - -Tests live in the **parent control-plane repo** (`rldyour-ai-cli-tools`), under -`validation/nddev-zcode-app/` — NOT inside this module. This keeps the -implementation clean. 31 pytest tests cover marketplace structure, installer -lifecycle, restore safety, backup rotation, config rendering, version parity, -and validation helper scripts. - -Run: `python3 -m pytest -q validation/nddev-zcode-app/ --rootdir=validation/nddev-zcode-app` - -## Three layers - -``` -zcode_tools/marketplaces// ← SOURCE: one self-contained ~/.zcode setup each -cli-tools/ ← INSTALLER: --marketplace → ~/.zcode -build/ ← ARTIFACTS: version, manifest, secrets (shared) -``` - -## ZCode native format (when adding components) - -ZCode discovers plugin components **by convention**, not by manifest declaration: - -- `plugins//.zcode-plugin/plugin.json` — metadata only (`name`, `version`, - `author`, `license`, `keywords`, `dependencies[]`). -- `plugins//skills//SKILL.md` — a skill. -- `plugins//commands/.md` — a slash command. -- `plugins//agents/.md` — a subagent. -- `plugins//.mcp.json` — MCP servers, shape `{"mcpServers": {...}}`. - -User-scope components live under `~/.zcode/{skills,commands,agents}/` (sourced -from the selected marketplace at `zcode_tools/marketplaces//{skills,commands,agents}/`). -Hooks and the MCP server registry live in `~/.zcode/cli/config.json` under -`hooks` (`hooks.enabled: true`) and `mcp.servers`. - -## The nddev-builder toolkit (18 skills) - -Use the `nddev-builder` marketplace's `core` plugin to build and maintain any -marketplace. Slash commands: `/nddev-add-skill`, `/nddev-doctor`, `/nddev-release`, etc. - -| Category | Skills | -|---|---| -| CREATE | add-marketplace, add-plugin, add-skill, add-command, add-agent, add-hook, add-mcp-server, add-provider, add-reference, add-tool | -| LIST | list-components | -| MODIFY | enable-plugin | -| REMOVE | remove-component | -| TEST | run-tests, add-test, run-benchmarks | -| VALIDATE | doctor | -| RELEASE | release-build | - -## Rules - -- English for code, docs, and commits (Conventional Commits). Sole author: - Danil Silantyev — no co-author trailers. -- Never commit secrets. Real values live only in `build/.env` (gitignored). The - `validate` workflow fails if any `.env` is tracked. -- To change the ZCode environment, edit the **source** in `zcode_tools/` and - re-run the installer. Do not hand-edit a rendered `~/.zcode`. -- The installer defaults to `--plan` (dry-run). `--apply` is the irreversible - step (it wipes and rebuilds `~/.zcode`, keeping a versioned backup). -- Bump **all 4** version files (`build/version.json`, `VERSION`, `pyproject.toml`, - `build/manifest.json`), and update `CHANGELOG.md`, for release behavior changes. -- After any change: validate (`install --plan`), run doctor (`/nddev-doctor`), - run tests (`/nddev-run-tests`), then release. diff --git a/CHANGELOG.md b/CHANGELOG.md index 866d509..17dde35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,43 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [2.0.0] - 2026-07-10 + +### Changed + +- **Public implementation boundary.** This repository now contains only the + reusable ZCode setup sources, installer, build contract, public references, + documentation, and public security/release automation. Development agent + context, validation, tests, and benchmarks moved to the private + `nddev-harnesses` control plane, where this repository is pinned as a + submodule. +- **Build version contract reduced to three authoritative files:** `VERSION`, + `build/version.json`, and `build/manifest.json`. +- **`nddev-builder/core` 2.0.0 is a focused reusable component toolkit** with + 13 skills, 13 matching commands, and one reviewer agent. + +### Removed + +- Removed the five development-only plugin capabilities `add-test`, + `run-tests`, `run-benchmarks`, `doctor`, and `release-build`, together with + their slash commands. These workflows now belong to `nddev-harnesses`. +- Removed repository-local agent configuration, Serena state, placeholder test + files, Python development metadata, and functional validation workflows from + the public module. + +### Fixed + +- Installer and bootstrap plan modes no longer invoke the live `zcode` binary, + create temporary download files, or report a false runtime match; runtime + discovery is explicitly logged as skipped. +- Restore and remove errors no longer suggest that `--target` bypasses the + mandatory `BUILD-VERSION` safety guard. +- `BUILD-VERSION.platform` now records the explicitly selected installer + platform instead of the host returned by `uname`, so cross-platform builds + retain the correct target provenance. +- Bootstrap now rejects unsupported explicit platform values instead of + continuing with an incomplete platform branch. + ## [1.0.9] - 2026-07-09 ### Fixed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0f5b741..70edd23 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,60 +1,69 @@ # Contributing -This repository is `nddev-zcode-app`, a build system + installer that recreates -a complete, version-stamped `~/.zcode` from source on macOS and Ubuntu. It is -maintained by [@rldyourmnd](https://github.com/rldyourmnd). Contributions are -welcome under the project's AGPL-3.0-or-later license, but the maintainer keeps -final authority on direction, plugin boundaries, the installer contract, and the -backup/restore policy. +`nddev-zcode-app` is the public, reusable implementation of the NDDev ZCode +setup installer. Contributions are welcome under AGPL-3.0-or-later. The +maintainer retains final authority over installer contracts, ZCode-native +format, setup boundaries, and backup/restore safety. -By submitting a pull request, you certify that you have the right to license the -contribution under AGPL-3.0-or-later. +By submitting a pull request, you certify that you can license the contribution +under AGPL-3.0-or-later. Participants must follow the +[Code of Conduct](CODE_OF_CONDUCT.md). -Participants must follow the [Code of Conduct](CODE_OF_CONDUCT.md). +## Repository boundary -## License +Keep this repository limited to code and public documentation required to use +or distribute the module. Do not add repository-local agent instructions, +development memories, test suites, validation implementations, benchmarks, or +generated development artifacts. -This project is licensed under the GNU Affero General Public License v3.0 or -later. See [LICENSE](LICENSE). Contributions are accepted under the same -license; downstream operators that run modified versions over a network must -comply with AGPL-3.0 Section 13. +The maintainers keep those control-plane concerns in the private +`nddev-harnesses` repository, where this module is pinned as a submodule. Public +contributors are not expected to have access to that harness; maintainers run +its full validation and platform matrix before merging or releasing changes. -## Local Setup +## Local setup -Required tools: Git, Python 3.13, and the ZCode client. +Required tools are Git, Bash, and Python 3. A local ZCode installation is not +required for plan-mode validation. ```bash -cp build/.env.example build/.env # then fill in real values -cli-tools/scripts/install.sh install --marketplace nddev-builder --plan # dry-run -cli-tools/scripts/install.sh install --marketplace nddev-builder --apply # back up, build, restore +cp build/.env.example build/.env +cli-tools/scripts/install.sh list +cli-tools/scripts/install.sh install \ + --marketplace nddev-builder --platform macos --plan +cli-tools/scripts/install.sh install \ + --marketplace nddev-builder --platform ubuntu --plan ``` -## Branches - -- `main`: primary integration branch. -- `feat/`, `fix/`, `chore/`: feature/fix/chore branches. - Open a pull request targeting `main`. +Plan mode performs no writes and does not invoke a local `zcode` binary. Never +use `--apply` against a real target merely to validate a pull request. -## Pull Requests +## Pull requests -- Open a pull request against `main` with a clear, scope-limited change. -- Title format: Conventional Commits (`type(scope): description`). Types: - `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `perf`, `style`, `ci`, - `build`. Scope is the area, lowercase. -- Description must include intent, surface touched, evidence (installer - `--plan` output, validation logs), and risks. -- Keep commits atomic. Do not rewrite already-pushed history without explicit - maintainer approval. +- Target `main` from a scope-limited feature or fix branch. +- Use a Conventional Commit title such as `fix(installer): preserve plan purity`. +- Explain intent, affected public contract, plan-mode evidence, and risks. +- Keep implementation, documentation, and version changes consistent. +- Do not rewrite pushed shared history without maintainer approval. -## Change Rules +## Change rules - Keep repository artifacts in English. -- Never commit credentials, tokens, cookies, private keys, or `build/.env`. - The `validate` workflow enforces this. -- Bump `build/version.json` and `VERSION`, and add a `CHANGELOG.md` entry for - release behavior changes. -- When adding ZCode components, follow the native format: plugin components are - convention-discovered (`skills//SKILL.md`, `commands/.md`, - `agents/.md`); MCP servers use `{"mcpServers":{}}` in - `plugins//.mcp.json`; hooks and the MCP registry live in - `cli/config.json`. +- Never commit credentials, tokens, cookies, private keys, `build/.env`, runtime + state, caches, or generated ZCode output. +- Preserve ZCode convention discovery: plugin components live under + `skills/`, `commands/`, `agents/`, and `references/`; metadata stays in + `.zcode-plugin/plugin.json`. +- Keep the build version identical in `VERSION`, `build/version.json`, and + `build/manifest.json`. +- Keep the `nddev-builder/core` plugin version identical in its marketplace + entry and `.zcode-plugin/plugin.json`. +- Add a `CHANGELOG.md` entry for release behavior changes. +- Treat backup, restore, remove, target resolution, and plan purity as safety + contracts. Changes to them require regression coverage in the private harness. + +## License + +This project is licensed under GNU AGPL v3.0 or later. See [LICENSE](LICENSE). +Downstream operators that run modified versions over a network must comply with +AGPL-3.0 Section 13. diff --git a/README.md b/README.md index 9c6eb9a..1882146 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,85 @@ # nddev-zcode-app -A **build system + installer** that recreates a complete, version-stamped -`~/.zcode` from source on macOS (desktop) and Ubuntu (desktop/server). It backs -up the current `~/.zcode`, lays down a clean build, and selectively restores -runtime state (credentials, sessions, db) so you stay logged in. +`nddev-zcode-app` is a reusable build system and installer for complete, +version-stamped ZCode setups. It recreates `~/.zcode` from a selected local +marketplace on macOS or Ubuntu, backs up the previous installation, and +selectively restores runtime state so sessions and credentials survive setup +changes. - **Author:** Danil Silantyev (github:rldyourmnd), CEO NDDev - **License:** AGPL-3.0-or-later -- **Build version:** 1.0.0 · **Runtime baseline:** GLM-5.2 +- **Build version:** 2.0.0 +- **Verified ZCode runtime:** app 3.3.3, CLI 0.15.0, model GLM-5.2 -## What this is +## What this repository contains -`nddev-zcode-app` is **not** a runtime. It is a reproducible build for the -`~/.zcode` directory the ZCode client reads. Three layers: +This public repository contains only the distributable implementation: +```text +zcode_tools/ Marketplace sources: complete editable ZCode setups +cli-tools/ Installer and lifecycle commands for macOS and Ubuntu +build/ Version contract, manifest, system files, and secret template +references/ Public ZCode compatibility baseline +docs/ Public architecture, installation, and secrets documentation ``` -zcode_tools/ ← SOURCE: the complete desired ~/.zcode as editable files -cli-tools/ ← INSTALLER: renders zcode_tools/ into ~/.zcode (macOS + Ubuntu) -build/ ← ARTIFACTS: version, manifest, system files, secrets templates -``` -See [docs/architecture.md](docs/architecture.md) for the full design. +Development-only agent context, validation code, tests, and benchmarks are kept +outside this repository in the maintainers' private `nddev-harnesses` control +plane. This boundary keeps the public module directly reusable and free of +workspace-specific artifacts. + +See [docs/architecture.md](docs/architecture.md) for the component and repository +boundaries. -## Quick start (from zero) +## Quick start ```bash -# 1. Populate secrets (gitignored, never committed): +# Populate local secrets. build/.env is gitignored. cp build/.env.example build/.env $EDITOR build/.env -# 2. Install the ZCode app + CLI (downloads from the official CDN, pinned version): +# Install the pinned ZCode app and CLI, if needed. +cli-tools/scripts/install.sh bootstrap --plan cli-tools/scripts/install.sh bootstrap --apply -# 3. List available setups: +# Inspect and install a setup. cli-tools/scripts/install.sh list - -# 4. Configure ~/.zcode from a marketplace (plan first, then apply): cli-tools/scripts/install.sh install --marketplace nddev-builder --plan cli-tools/scripts/install.sh install --marketplace nddev-builder --apply ``` -If ZCode is already installed, `bootstrap` skips the download and only wires the -`zcode` CLI launcher. See [docs/install.md](docs/install.md) for the full lifecycle -(install / update / switch / remove) and custom target directories. - -## Backup convention +Plan mode performs no writes and does not invoke a locally installed `zcode` +binary. Apply mode checks the live runtime version, then performs the requested +lifecycle operation. See [docs/install.md](docs/install.md) for install, update, +switch, backup, restore, remove, and custom-target usage. -On `--apply`, the current `~/.zcode` is moved to a rotating pool of **10 slots**: +## Available setups -``` -~/.zcode-backups/--old.zcode (N = 0-9) -``` +Each directory under `zcode_tools/marketplaces/` is a complete setup: -- `N` — a 0–9 rotation slot (lowest free slot; the **oldest is overwritten** when all 10 are full, regardless of version). -- `VERSION` — the build version that was installed. +- `nddev-builder` provides a reusable 13-skill, 13-command toolkit for creating + and managing ZCode marketplaces, plugins, and components. +- `nddev-designer` is the designer-oriented setup. +- `nddev-developer` is the software-development setup. -**Always restored** from the backup: `v2/credentials.json`, `v2/certs/`, -`cli/agents/`, `cli/db/`, `cli/artifacts/`. -**Never restored** (regenerated by ZCode): logs, crash dumps, plugin cache. +The installer copies exactly one selected marketplace into the target ZCode +home. Marketplace content is ordinary source and can be adapted independently. -See [docs/install.md](docs/install.md) for details and how to revert. +## Backup and restore contract -## Layout +Apply operations rotate at most 10 backups under `~/.zcode-backups/`: +```text +--old.zcode N = 0..9 ``` -zcode_tools/ source of ~/.zcode (AGENTS.md, skills, commands, agents, - marketplace.json, plugins, config templates) -cli-tools/ installer (install.sh, lib/, macos/, ubuntu/, restore.sh) -build/ version.json, manifest.json, system/, .env.example -.agents/skills/ workspace skills (repo-orientation, dev-workflow) -docs/ install, architecture, secrets -tests/ test suite (currently empty) -.github/ CI workflows and issue/PR templates -``` + +Credentials, certificates, sessions, databases, and runtime artifacts are +selectively restored during an update or switch. Logs, crash data, and plugin +caches are regenerated. Destructive restore/remove operations refuse targets +that are not marked by this installer with `BUILD-VERSION`. ## Secrets -Secrets are never committed. `build/.env.example` is the template (keys only); -`build/.env` holds real values (gitignored). Config templates in `zcode_tools/` -reference secrets as `${VAR_NAME}` and are rendered at install time. See -[docs/secrets.md](docs/secrets.md). +`build/.env.example` defines supported keys; the gitignored `build/.env` holds +local values. `${VAR_NAME}` placeholders in marketplace templates are rendered +only during installation. See [docs/secrets.md](docs/secrets.md). diff --git a/SECURITY.md b/SECURITY.md index d33732c..4b57c71 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,69 +1,69 @@ # Security Policy -## Supported Surface +## Supported surface -Security reporting covers this repository's `~/.zcode` source tree -(`zcode_tools/`), the installer (`cli-tools/`), build artifacts and secret -templates (`build/`), and CI/CD workflows (`.github/`). +Security reporting covers the public implementation in this repository: -## Supported Versions +- marketplace sources under `zcode_tools/`, +- installer and lifecycle logic under `cli-tools/`, +- version, manifest, system, and secret-template data under `build/`, +- public references, documentation, and GitHub workflows. + +## Supported versions Only the current exact numeric release tag receives security fixes. | Version | Supported | -|---|---| -| Current exact tag `1.0.0` | yes | -| Older tags | no; upgrade to current exact tag | - -## Reporting a Vulnerability +| --- | --- | +| Current exact tag `2.0.0` | yes | +| Older tags | no; upgrade to the current exact tag | -Please report vulnerabilities privately. Do not open public issues or pull -requests describing them. +## Reporting a vulnerability -Preferred channel: GitHub Security Advisories. +Report vulnerabilities privately. Do not open a public issue or pull request +that contains exploit details or sensitive material. -- https://github.com/NDDev-it-com/nddev-zcode-app/security/advisories/new +Preferred channel: [GitHub Security Advisories](https://github.com/NDDev-it-com/nddev-zcode-app/security/advisories/new). -Alternative channel: contact the maintainer through their GitHub profile at -https://github.com/rldyourmnd and request a private disclosure handle. +Alternatively, contact the maintainer through +[@rldyourmnd](https://github.com/rldyourmnd) and request a private disclosure +channel. Include: -- affected path, file, installer step, or workflow, -- reproduction steps, -- expected impact and threat scenario, -- non-sensitive logs or command output, -- a suggested fix when known. - -Do not paste credentials, tokens, cookies, private keys, or sensitive logs into -reports. If a report requires sharing sensitive material, request a secure -channel before sending. - -## Response Targets - -The maintainer aims for: - -- acknowledgement within 5 business days, -- triage and severity assessment within 10 business days, -- a fix or mitigation plan for accepted reports within 30 business days, - depending on complexity. - -These targets are best-effort and not contractual. - -## Baseline Controls - -- External GitHub Actions are pinned to full commit SHAs. -- CI uses least-privilege `GITHUB_TOKEN` permissions by default. -- The `validate` workflow fails if any `.env` file (including `build/.env`) is - tracked by git. -- Secrets are rendered from a local, gitignored `build/.env` at install time; - no secret values are committed. - -## Out Of Scope - -- Findings against downstream environments running modified versions of this - software. -- Issues stemming from running the installer's `--apply` mode (which wipes and - rebuilds `~/.zcode`) without keeping the automatic backup. The installer - always creates a backup before applying; reverting is documented in - [docs/install.md](docs/install.md). +- affected path, installer step, or workflow, +- reproduction steps and expected impact, +- the relevant threat scenario, +- non-sensitive logs or output, +- a suggested fix, if known. + +Never include credentials, tokens, cookies, private keys, or sensitive runtime +logs in a report. + +## Response targets + +The maintainer aims to acknowledge reports within 5 business days, complete +triage within 10 business days, and provide a fix or mitigation plan for an +accepted report within 30 business days. These targets are best-effort. + +## Baseline controls + +- External GitHub Actions and reusable workflows are pinned to full commit SHAs. +- Workflow permissions follow least privilege. +- Generic CodeQL, dependency-review, secret-scan, and Scorecard checks run in + this public repository. +- The maintainers' private `nddev-harnesses` control plane validates module + boundaries, JSON and shell contracts, plan-mode purity, lifecycle behavior, + restore safety, platform behavior, and release consistency. +- Secrets are rendered from a local, gitignored `build/.env`; only + `build/.env.example` is tracked. +- Restore and remove refuse existing targets without the installer's + `BUILD-VERSION` marker. + +## Out of scope + +- Downstream environments running independently modified versions. +- Problems caused by bypassing the documented installer lifecycle or manually + deleting its backup pool. +- Availability or behavior of the upstream ZCode service, app, CDN, or model + provider when the module itself does not cause the issue. diff --git a/VERSION b/VERSION index 66c4c22..227cea2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.9 +2.0.0 diff --git a/build/manifest.json b/build/manifest.json index eec3d14..35ed7df 100644 --- a/build/manifest.json +++ b/build/manifest.json @@ -1,15 +1,16 @@ { "name": "nddev-zcode-app", - "build_version": "1.0.9", + "build_version": "2.0.0", "source_root": "zcode_tools/marketplaces/", "installer": "cli-tools/scripts/install.sh --marketplace ", "layout": { "zcode_tools/marketplaces//": "each marketplace is a self-contained ~/.zcode setup (AGENTS.md, config templates, mcp/hooks, skills/commands/agents, plugins)", "cli-tools/": "installer: --marketplace selects one setup and builds ~/.zcode from it (macOS + Ubuntu)", "build/": "build artifacts: version.json, manifest.json, system files, secrets templates (shared across setups)", - ".agents/skills/": "workspace skills (repo-orientation, dev-workflow) — not shipped to ~/.zcode", - "docs/": "documentation", - "tests/": "test suite (currently empty)" + "config/": "public repository and release contract metadata", + "references/": "verified public ZCode compatibility baseline", + "docs/": "public installation, architecture, and secrets documentation", + ".github/": "public security, release, and repository-automation workflows" }, "backup_policy": { "location": "~/.zcode-backups/", diff --git a/build/version.json b/build/version.json index 8510c79..a5728d4 100644 --- a/build/version.json +++ b/build/version.json @@ -1,5 +1,5 @@ { - "build_version": "1.0.9", + "build_version": "2.0.0", "zcode_app_version": "3.3.3", "zcode_cli_version": "0.15.0", "zcode_runtime": "GLM-5.2", diff --git a/cli-tools/scripts/bootstrap.sh b/cli-tools/scripts/bootstrap.sh index a70d9b0..bbf1fac 100755 --- a/cli-tools/scripts/bootstrap.sh +++ b/cli-tools/scripts/bootstrap.sh @@ -62,6 +62,10 @@ export NDDEV_DRY_RUN=$((1 - APPLY)) if [ "$PLATFORM" = "auto" ]; then PLATFORM="$(nddev::detect_platform)" || exit 1 fi +if [ "$PLATFORM" != "macos" ] && [ "$PLATFORM" != "ubuntu" ]; then + nddev::log "error" "unsupported platform: $PLATFORM (expected macos|ubuntu)" + exit 2 +fi ROOT="$(nddev::repo_root)" VERSION_JSON="$ROOT/build/version.json" @@ -90,7 +94,11 @@ nddev::log "info" "architecture: $arch" # ─── Check if already installed ────────────────────────────────────────── nddev::check_runtime_version -running_app="$(nddev::detect_app_version)" +if [ "${NDDEV_DRY_RUN:-1}" -eq 1 ]; then + running_app="skipped-plan" +else + running_app="$(nddev::detect_app_version)" +fi if [ "$running_app" = "$APP_VERSION" ]; then nddev::log "ok" "ZCode $APP_VERSION already installed; skipping app download" else @@ -103,7 +111,11 @@ if [ "$running_app" != "$APP_VERSION" ]; then macos) artifact="ZCode-${APP_VERSION}-mac-${arch}.dmg" url="${CDN_BASE}/${APP_VERSION}/${artifact}" - tmp_dmg="$(mktemp -t nddev-zcode.XXXXXX).dmg" + if [ "${NDDEV_DRY_RUN:-1}" -eq 1 ]; then + tmp_dmg="${TMPDIR:-/tmp}/nddev-zcode-${APP_VERSION}-${arch}.dmg" + else + tmp_dmg="$(mktemp -t nddev-zcode.XXXXXX)" + fi nddev::section "Download ZCode.app ($artifact)" nddev::log "info" "url: $url" @@ -126,7 +138,9 @@ if [ "$running_app" != "$APP_VERSION" ]; then hdiutil detach "$mount_point" >/dev/null 2>&1 nddev::log "ok" "installed ZCode.app to /Applications/" fi - rm -f "$tmp_dmg" + if [ "${NDDEV_DRY_RUN:-1}" -eq 0 ]; then + rm -f "$tmp_dmg" + fi app_entry="/Applications/ZCode.app/Contents/Resources/glm/zcode.cjs" ;; @@ -134,7 +148,11 @@ if [ "$running_app" != "$APP_VERSION" ]; then # Prefer .deb (cleaner uninstall); fall back to AppImage. artifact="ZCode-${APP_VERSION}-linux-${arch}.deb" url="${CDN_BASE}/${APP_VERSION}/${artifact}" - tmp_deb="$(mktemp -t nddev-zcode.XXXXXX).deb" + if [ "${NDDEV_DRY_RUN:-1}" -eq 1 ]; then + tmp_deb="${TMPDIR:-/tmp}/nddev-zcode-${APP_VERSION}-${arch}.deb" + else + tmp_deb="$(mktemp -t nddev-zcode.XXXXXX)" + fi nddev::section "Download ZCode ($artifact)" nddev::log "info" "url: $url" @@ -151,7 +169,9 @@ if [ "$running_app" != "$APP_VERSION" ]; then fi nddev::log "ok" "installed ZCode via dpkg" fi - rm -f "$tmp_deb" + if [ "${NDDEV_DRY_RUN:-1}" -eq 0 ]; then + rm -f "$tmp_deb" + fi app_entry="/opt/ZCode/resources/glm/zcode.cjs" ;; esac @@ -211,6 +231,11 @@ nddev::section "Verify" nddev::check_runtime_version nddev::section "Bootstrap complete" -nddev::log "ok" "ZCode app: $(nddev::detect_app_version)" -nddev::log "ok" "ZCode CLI: $(nddev::detect_cli_version)" +if [ "${NDDEV_DRY_RUN:-1}" -eq 1 ]; then + nddev::log "info" "ZCode app: skipped-plan" + nddev::log "info" "ZCode CLI: skipped-plan" +else + nddev::log "ok" "ZCode app: $(nddev::detect_app_version)" + nddev::log "ok" "ZCode CLI: $(nddev::detect_cli_version)" +fi nddev::log "info" "next: run 'install.sh install --marketplace --apply' to configure ~/.zcode" diff --git a/cli-tools/scripts/install.sh b/cli-tools/scripts/install.sh index e5f602e..881674f 100755 --- a/cli-tools/scripts/install.sh +++ b/cli-tools/scripts/install.sh @@ -1,16 +1,18 @@ #!/usr/bin/env bash # # nddev-zcode-app installer — manages a complete, version-stamped ~/.zcode -# built from ONE selected marketplace. Supports install, update, switch, and -# remove on macOS (desktop) or Ubuntu (desktop/server). +# built from ONE selected marketplace. Supports bootstrap, install, update, +# switch, backup inspection, restore, and removal on macOS or Ubuntu. # # Usage: # cli-tools/scripts/install.sh [options] # # Commands: +# bootstrap Download and install the pinned ZCode app and CLI. # install (default) Build ~/.zcode from a marketplace (backup → build → restore). # remove Back up and delete the installed ~/.zcode. -# list List available marketplaces. +# restore Restore ~/.zcode from a numbered backup slot. +# list List available marketplaces or backups. # # Each marketplace is a self-contained setup (its own AGENTS.md, config # templates, skills/commands/agents, and plugins). The installer selects one @@ -239,7 +241,7 @@ if [ "$COMMAND" = "restore" ]; then # (no BUILD-VERSION), same as the 'remove' command. Prevents accidental # destruction of a non-nddev directory via --target. if [ -d "$ZCODE_HOME" ] && [ ! -f "$ZCODE_HOME/BUILD-VERSION" ]; then - nddev::log "error" "refusing to restore: $ZCODE_HOME has no BUILD-VERSION (not an nddev-zcode-app install). Pass --target explicitly if you are sure." + nddev::log "error" "refusing to restore: $ZCODE_HOME has no BUILD-VERSION (not an nddev-zcode-app install). Choose an empty target or an existing stamped installation." exit 1 fi @@ -261,7 +263,7 @@ if [ "$COMMAND" = "restore" ]; then restore_source="$backup_dir" fi # Cleanup the temp dir on exit (only in APPLY mode, only if we created it). - # shellcheck disable=SC2329 # invoked indirectly by the EXIT trap below. + # shellcheck disable=SC2317,SC2329 # invoked indirectly by the EXIT trap below. _restore_cleanup() { local tmp_parent tmp_parent="$(dirname "$restore_source")" @@ -335,7 +337,7 @@ if [ "$COMMAND" = "remove" ]; then # Check it's one of ours (has BUILD-VERSION) before deleting. if [ ! -f "$ZCODE_HOME/BUILD-VERSION" ]; then - nddev::log "error" "refusing to remove: $ZCODE_HOME has no BUILD-VERSION (not an nddev-zcode-app install). Pass --target explicitly if you are sure." + nddev::log "error" "refusing to remove: $ZCODE_HOME has no BUILD-VERSION (not an nddev-zcode-app install). Only stamped installations can be removed." exit 1 fi diff --git a/cli-tools/scripts/lib/build.sh b/cli-tools/scripts/lib/build.sh index b8a6af2..0a2ab55 100644 --- a/cli-tools/scripts/lib/build.sh +++ b/cli-tools/scripts/lib/build.sh @@ -340,9 +340,7 @@ nddev::verify_build() { # marketplace. Sets NDDEV_BACKUP_PATH to the backup directory (empty on a fresh # install with no prior ~/.zcode). NDDEV_BACKUP_PATH="" -# shellcheck disable=SC2034 nddev::install_sequence() { - # shellcheck disable=SC2034 local platform=$1 local current_version backup_name backup_path @@ -359,7 +357,7 @@ nddev::install_sequence() { nddev::backup_current nddev::check_runtime_version nddev::build_clean "$ZCODE_HOME" - nddev::write_version_stamp "$ZCODE_HOME" + nddev::write_version_stamp "$ZCODE_HOME" "$platform" if [ -n "$backup_path" ]; then nddev::restore_runtime "$backup_path" "$ZCODE_HOME" @@ -367,5 +365,6 @@ nddev::install_sequence() { nddev::verify_build "$ZCODE_HOME" + # shellcheck disable=SC2034 # read by the sourced platform runner. NDDEV_BACKUP_PATH="$backup_path" } diff --git a/cli-tools/scripts/lib/common.sh b/cli-tools/scripts/lib/common.sh index 147d8e5..d2c9aa0 100644 --- a/cli-tools/scripts/lib/common.sh +++ b/cli-tools/scripts/lib/common.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash # Shared helpers for the nddev-zcode-app installer. # Sourced by install.sh and the macos/ubuntu runners. -# Conventions mirror rldyour-new-mac-or-ubuntu: set -euo pipefail at the caller, -# NDDEV_DRY_RUN=1 means plan (no writes), NDDEV_DRY_RUN=0 means apply. +# Callers enable strict shell mode. NDDEV_DRY_RUN=1 means plan (no writes), and +# NDDEV_DRY_RUN=0 means apply. # Resolve the repository root (three levels up from this file: # lib/ -> scripts/ -> cli-tools/ -> repo root). diff --git a/cli-tools/scripts/lib/version.sh b/cli-tools/scripts/lib/version.sh index e251c00..68561e0 100644 --- a/cli-tools/scripts/lib/version.sh +++ b/cli-tools/scripts/lib/version.sh @@ -83,10 +83,18 @@ nddev::check_runtime_version() { pinned_app="$(nddev::pinned_app_version)" pinned_cli="$(nddev::pinned_cli_version)" + + nddev::section "ZCode version check" + if [ "${NDDEV_DRY_RUN:-1}" -eq 1 ]; then + nddev::log "info" "pinned app: $pinned_app running: skipped-plan" + nddev::log "info" "pinned cli: $pinned_cli running: skipped-plan" + nddev::log "info" "live runtime detection is skipped in plan mode" + return 0 + fi + running_app="$(nddev::detect_app_version)" running_cli="$(nddev::detect_cli_version)" - nddev::section "ZCode version check" nddev::log "info" "pinned app: $pinned_app running: $running_app" nddev::log "info" "pinned cli: $pinned_cli running: $running_cli" @@ -105,16 +113,25 @@ nddev::check_runtime_version() { return 0 } -# Write the BUILD-VERSION stamp into the target zcode home. $1=target ~/.zcode path. +# Write the BUILD-VERSION stamp into the target ZCode home. +# $1 = target path, $2 = selected installer platform (macos|ubuntu). nddev::write_version_stamp() { local target=$1 - local build_version zcode_runtime platform installed_at app_ver cli_ver + local platform=$2 + local build_version zcode_runtime installed_at app_ver cli_ver + + case "$platform" in + macos | ubuntu) ;; + *) + nddev::log "error" "invalid platform for BUILD-VERSION: $platform" + return 2 + ;; + esac build_version="$(nddev::build_version)" zcode_runtime="$(nddev::zcode_runtime)" app_ver="$(nddev::pinned_app_version)" cli_ver="$(nddev::pinned_cli_version)" - platform="$(nddev::detect_platform)" installed_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)" if [ "${NDDEV_DRY_RUN:-1}" -eq 1 ]; then diff --git a/docs/README.md b/docs/README.md index 6605955..7f9d856 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,9 @@ # nddev-zcode-app documentation -- **[install.md](install.md)** — how the installer works: plan vs apply, backup, - build, selective restore, and the command-line usage. -- **[architecture.md](architecture.md)** — the three-layer design - (`zcode_tools/` source → `cli-tools/` installer → `build/` artifacts) and how - it maps to the ZCode native format. -- **[secrets.md](secrets.md)** — the `build/.env.example` → `build/.env` contract - and how `${VAR}` placeholders are rendered at install time. +- **[architecture.md](architecture.md)** defines implementation layers, + ZCode-native component conventions, version contracts, and the public/private + repository boundary. +- **[install.md](install.md)** covers bootstrap, plan/apply behavior, setup + selection, update, switch, backup, restore, remove, and custom targets. +- **[secrets.md](secrets.md)** defines the local `build/.env` contract and + `${VAR}` rendering behavior. diff --git a/docs/architecture.md b/docs/architecture.md index 860f25e..e2cea1c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,75 +1,96 @@ # Architecture -`nddev-zcode-app` is a build system for a ZCode environment. It does not *run* -ZCode — it produces a complete, reproducible `~/.zcode` directory from source. +`nddev-zcode-app` produces a complete, reproducible ZCode home from source. It +does not run ZCode or own ZCode runtime data. -## Three layers +## Implementation layers +```text +zcode_tools/ SOURCE: self-contained marketplace setups +cli-tools/ INSTALLER: lifecycle and rendering for macOS and Ubuntu +build/ CONTRACT: versions, manifest, system files, secret template ``` -zcode_tools/ ← SOURCE: the complete desired ~/.zcode as editable files -cli-tools/ ← INSTALLER: renders zcode_tools/ into ~/.zcode (macOS + Ubuntu) -build/ ← ARTIFACTS: version, manifest, system files, secrets templates -``` - -### zcode_tools/marketplaces// — the source - -Each marketplace directory **is** a complete, self-contained `~/.zcode` setup, -expressed as source. The installer selects ONE marketplace (`--marketplace `) -and builds `~/.zcode` entirely from it. - -| Source file (inside the marketplace) | Target | Rendered? | -|---|---|---| -| `AGENTS.md` | `~/.zcode/AGENTS.md` | copy | -| `skills/` | `~/.zcode/skills/` | copy | -| `commands/` | `~/.zcode/commands/` | copy | -| `agents/` | `~/.zcode/agents/` | copy | -| `` | `~/.zcode/marketplaces//` | copy (ZCode discovers it) | -| `cli-config.template.json` | `~/.zcode/cli/config.json` | **render** (`${VAR}`) | -| `v2-config.template.json` | `~/.zcode/v2/config.json` | **render** (`${API_KEY}`) | -| `v2-setting.template.json` | `~/.zcode/v2/setting.json` | **render** (`${HOME}`) | -| `hooks.json`, `mcp.json` | (reference, merged into cli/config.json) | reference | - -### cli-tools/ — the installer - -Entry point: `cli-tools/scripts/install.sh`. It: - -1. Parses `--platform macos|ubuntu` (auto-detect) and `--apply|--plan`. -2. Validates prerequisites. -3. Delegates to the platform runner (`macos/install.sh` or `ubuntu/install.sh`), - which sources the shared libraries and calls the install sequence. -Shared libraries under `cli-tools/scripts/lib/`: - -- `common.sh` — logging, dry-run-aware `run`/`copy`/`move`/`ensure_dir`, platform - detection, backup-name computation, and the `${VAR}` template renderer. -- `version.sh` — reads `build/version.json`, writes `~/.zcode/BUILD-VERSION`. -- `build.sh` — the backup → build → restore → verify orchestration. - -`restore.sh` is standalone: it copies the always-restore paths from a backup into -the freshly built `~/.zcode`, and never touches the never-restore paths. - -### build/ — artifacts - -- `version.json` — the build version and ZCode runtime baseline. -- `manifest.json` — the source layout, backup policy, and restore policy. -- `.env.example` → `.env` — secrets (gitignored). -- `system/macos/`, `system/ubuntu/` — reserved for per-OS system files. - -## ZCode native format +### Marketplace sources + +Each `zcode_tools/marketplaces//` directory is a complete setup. The +installer selects exactly one marketplace and builds the target from it. + +| Marketplace source | Installed target | Treatment | +| --- | --- | --- | +| `AGENTS.md` | `/AGENTS.md` | copied | +| `skills/`, `commands/`, `agents/` | same paths under target | copied | +| full marketplace directory | `/marketplaces//` | copied | +| `cli-config.template.json` | `/cli/config.json` | rendered | +| `v2-config.template.json` | `/v2/config.json` | rendered | +| `v2-setting.template.json` | `/v2/setting.json` | rendered | +| `hooks.json`, `mcp.json` | keys in `cli/config.json` | merged | + +Template rendering expands `${VAR}` values from the process environment and +the local `build/.env` file. Unknown placeholders remain unchanged so optional +provider or tool credentials can be configured later. + +### Installer + +The entry point is `cli-tools/scripts/install.sh`. Platform runners source the +shared libraries and execute the same lifecycle: + +1. resolve and validate the selected marketplace, +2. back up a prior stamped target, +3. check the live ZCode runtime in apply mode, +4. render a clean target, +5. write `BUILD-VERSION`, +6. selectively restore runtime state, +7. verify the rendered result. + +Plan mode describes the operation without writes or live `zcode` execution. + +Shared implementation: + +- `lib/common.sh` owns logging, target/platform helpers, backup naming, safe + dry-run operations, and template rendering. +- `lib/version.sh` owns the public build/runtime version contract and installed + stamp. +- `lib/build.sh` owns selection, backup, build, restore, verification, and + orchestration. +- `restore.sh` applies the explicit per-path restore modes. + +### Build contract + +- `VERSION`, `build/version.json`, and `build/manifest.json` carry the same + module build version. +- `build/version.json` also pins the verified ZCode app, CLI, runtime model, CDN, + artifacts, and launcher locations. +- `build/manifest.json` defines public layout, backup, restore, and secrets + contracts. +- The `nddev-builder/core` version is independent and must match between its + marketplace entry and `.zcode-plugin/plugin.json`. + +## ZCode-native component format + +ZCode discovers plugin components by convention: + +```text +marketplaces//marketplace.json +marketplaces//plugins//.zcode-plugin/plugin.json +marketplaces//plugins//skills//SKILL.md +marketplaces//plugins//commands/.md +marketplaces//plugins//agents/.md +marketplaces//plugins//.mcp.json +``` -ZCode discovers plugin components **by convention**, not by declaration in the -manifest. The repo supports **multiple marketplaces**, each in its own directory: +Plugin manifests are metadata, not component registries. User-scope components +live directly under `/{skills,commands,agents}/`. Hooks and MCP servers +are installed into `/cli/config.json`. -- `marketplaces//marketplace.json` — the marketplace root manifest. -- `marketplaces//plugins//.zcode-plugin/plugin.json` — metadata only - (`name`, `version`, `author`, `license`, `keywords`, `dependencies[]`). -- `marketplaces//plugins//skills//SKILL.md` — a skill. -- `marketplaces//plugins//commands/.md` — a slash command. -- `marketplaces//plugins//agents/.md` — a subagent. -- `marketplaces//plugins//.mcp.json` — MCP servers, shape `{"mcpServers": {...}}`. +## Public/private repository boundary -User-scope components live directly under `~/.zcode/{skills,commands,agents}/`. -Hooks and the MCP server registry live in `~/.zcode/cli/config.json` under `hooks` -(with `hooks.enabled: true`) and `mcp.servers`. +This repository is the public implementation module. It intentionally excludes +repository-local agent configuration, development memories, validation +implementations, tests, and benchmarks. -See the `zcode-configuration-guide` skill for the full reference. +The private `nddev-harnesses` repository is the development control plane. It +pins this module under `modules/nddev-zcode-app`, owns cross-platform and release +gates, and validates a specific public commit before release. The dependency is +one-way: the harness knows the public module; the module never requires the +harness at runtime. diff --git a/docs/install.md b/docs/install.md index ecec7ff..a78e820 100644 --- a/docs/install.md +++ b/docs/install.md @@ -20,7 +20,7 @@ Both work on macOS (desktop) and Ubuntu (desktop/server). ## From zero (fresh machine) ```bash -# 1. Clone the repo (or tools/sync.sh clone nddev-zcode-app in the estate). +# 1. Clone or download the repository. # 2. Populate secrets: cp build/.env.example build/.env $EDITOR build/.env @@ -35,8 +35,11 @@ cli-tools/scripts/install.sh install --marketplace nddev-builder --plan cli-tools/scripts/install.sh install --marketplace nddev-builder --apply ``` -After step 3, ZCode is installed and the `zcode` command is on PATH. After step 4, -`~/.zcode` is configured and ready to use. +After step 3, ZCode is installed and the `zcode` command is on PATH. After +step 4, `~/.zcode` is configured and ready to use. + +Plan mode performs no writes, downloads, target mutation, or live `zcode` +execution. Runtime detection is deferred until apply mode. ## Usage @@ -49,25 +52,34 @@ cli-tools/scripts/install.sh install --marketplace nddev-builder --plan cli-tools/scripts/install.sh install --marketplace nddev-builder --apply # Update — re-run install with the same marketplace (old ~/.zcode is backed up). -# Switch — run install with a different --marketplace (old is backed up, new is built). +# Switch — install a different marketplace (the old setup is backed up). # Remove — back up and delete the install: cli-tools/scripts/install.sh remove --apply +# Inspect and restore numbered backup slots: +cli-tools/scripts/install.sh list --backups +cli-tools/scripts/install.sh restore --slot 3 --plan +cli-tools/scripts/install.sh restore --slot 3 --apply + # Custom install directory (default is ~/.zcode): -cli-tools/scripts/install.sh install --marketplace nddev-builder --target /opt/my-zcode --apply +cli-tools/scripts/install.sh install \ + --marketplace nddev-builder --target /opt/my-zcode --apply # ...or set it once in build/.env (ZCODE_TARGET=...) and skip --target. # Force a platform (otherwise auto-detected from uname): -cli-tools/scripts/install.sh install --marketplace nddev-builder --platform macos --apply +cli-tools/scripts/install.sh install \ + --marketplace nddev-builder --platform macos --apply ``` ### Commands | Command | What it does | -|---|---| -| `install` (default) | Back up the target, build a clean `~/.zcode` from a marketplace, restore runtime state. | -| `remove` | Back up the target, then delete it. Refuses to delete a directory without `BUILD-VERSION` (safety). | -| `list` | Show available marketplaces. | +| --- | --- | +| `bootstrap` | Install the pinned ZCode app and CLI; defaults to plan mode. | +| `install` | Back up, build from one marketplace, and restore runtime state. | +| `remove` | Back up and delete a stamped target. | +| `restore` | Restore one backup slot into an empty or stamped target. | +| `list` | Show marketplaces; add `--backups` to show backup slots. | ### Target directory resolution @@ -120,9 +132,14 @@ you stay logged in. If the auth token expired, re-authenticate in the app. ## Reverting -To revert to a backup, move it back: +Use the guarded restore lifecycle instead of moving backup directories manually: ```bash -mv ~/.zcode ~/.zcode-backups/revert-$(date +%s) -mv ~/.zcode-backups/--old.zcode ~/.zcode +cli-tools/scripts/install.sh list --backups +cli-tools/scripts/install.sh restore --slot --plan +cli-tools/scripts/install.sh restore --slot --apply ``` + +If the target exists, restore first backs it up. The restore source is staged +before any backup rotation or target replacement so a full 10-slot pool cannot +invalidate the selected source. diff --git a/docs/secrets.md b/docs/secrets.md index ecbe3df..c0d47d1 100644 --- a/docs/secrets.md +++ b/docs/secrets.md @@ -39,7 +39,8 @@ Templates live inside each marketplace directory: committed. This is why backups live under `~/.zcode-backups/` (outside the repo), not inside the repository tree. -## CI guard +## Repository guards -The `validate` workflow fails if `build/.env` (or any `.env`) is ever tracked by -git. Keep real values only in your local `build/.env`. +Public secret scanning checks tracked content for exposed credentials. The +maintainers' private harness also rejects any tracked `.env` file as a module +boundary violation. Keep real values only in your local `build/.env`. diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 2f0b0ca..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,32 +0,0 @@ -[project] -name = "nddev-zcode-app" -version = "1.0.9" -description = "Build system + installer that recreates a complete, version-stamped ~/.zcode from source on macOS and Ubuntu." -readme = "README.md" -requires-python = ">=3.13,<3.14" -license = "AGPL-3.0-or-later" -license-files = ["LICENSE"] -authors = [ - { name = "Danil Silantyev", email = "rldyourmnd@users.noreply.github.com" }, -] -maintainers = [ - { name = "Danil Silantyev", email = "rldyourmnd@users.noreply.github.com" }, -] -keywords = ["zcode", "glm", "marketplace", "installer", "build-system", "agents", "plugins"] -classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", - "Topic :: Software Development", - "Topic :: System :: Installation/Setup", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.13", - "Operating System :: POSIX :: Linux", - "Operating System :: MacOS", -] - -[project.urls] -Homepage = "https://github.com/NDDev-it-com/nddev-zcode-app" -Repository = "https://github.com/NDDev-it-com/nddev-zcode-app" -Issues = "https://github.com/NDDev-it-com/nddev-zcode-app/issues" -Changelog = "https://github.com/NDDev-it-com/nddev-zcode-app/blob/main/CHANGELOG.md" diff --git a/pyrightconfig.json b/pyrightconfig.json deleted file mode 100644 index 9611d5d..0000000 --- a/pyrightconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "include": [], - "exclude": [ - "**/__pycache__", - ".venv", - "node_modules", - "**/tests/**" - ], - "pythonVersion": "3.13", - "typeCheckingMode": "basic", - "reportMissingImports": "warning", - "reportMissingTypeStubs": "none" -} diff --git a/references/zcode-baseline.json b/references/zcode-baseline.json index 8a0600e..33280e2 100644 --- a/references/zcode-baseline.json +++ b/references/zcode-baseline.json @@ -20,6 +20,6 @@ "mcp_plugin_file": ".mcp.json", "mcp_plugin_key": "mcpServers" }, - "verified_date": "2026-07-09", - "verified_against": "NDDev-it-com/nddev-zcode-app @ 1.0.0" + "verified_date": "2026-07-10", + "verified_against": "NDDev-it-com/nddev-zcode-app @ 2.0.0" } diff --git a/tests/.gitkeep b/tests/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/zcode_tools/marketplaces/nddev-builder/marketplace.json b/zcode_tools/marketplaces/nddev-builder/marketplace.json index 93066c5..971969d 100644 --- a/zcode_tools/marketplaces/nddev-builder/marketplace.json +++ b/zcode_tools/marketplaces/nddev-builder/marketplace.json @@ -4,13 +4,13 @@ "name": "Danil Silantyev (github:rldyourmnd), CEO NDDev", "url": "https://github.com/rldyourmnd" }, - "description": "Developer marketplace for building and releasing the nddev-zcode-app estate: plugin scaffolding, skill authoring, MCP management, and release tooling.", + "description": "Reusable toolkit for building ZCode marketplaces, plugins, skills, commands, agents, hooks, MCP servers, providers, references, and CLI tools.", "plugins": [ { "name": "core", "source": "./plugins/core", - "description": "Developer toolkit: skills, slash commands, and a reviewer subagent for building plugins, managing MCP servers and providers, authoring skills, listing/removing components, and cutting releases of the ~/.zcode build.", - "version": "1.2.0", + "description": "Reusable toolkit: skills, slash commands, and a reviewer subagent for building plugins, managing MCP servers and providers, authoring skills, and listing or removing components.", + "version": "2.0.0", "author": { "name": "Danil Silantyev (github:rldyourmnd), CEO NDDev" }, @@ -22,7 +22,7 @@ "plugins", "mcp", "skills", - "release", + "components", "nddev" ], "license": "AGPL-3.0-or-later" diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/.zcode-plugin/plugin.json b/zcode_tools/marketplaces/nddev-builder/plugins/core/.zcode-plugin/plugin.json index 2364346..0893c50 100644 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/.zcode-plugin/plugin.json +++ b/zcode_tools/marketplaces/nddev-builder/plugins/core/.zcode-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "core", - "version": "1.2.0", - "description": "Developer toolkit for the nddev-zcode-app estate: skills, slash commands, and subagents for building plugins, managing MCP servers and providers, authoring skills, listing/removing components, and cutting releases. The companion to the build system + installer.", + "version": "2.0.0", + "description": "Reusable ZCode toolkit: skills, slash commands, and a reviewer subagent for building plugins, managing MCP servers and providers, authoring skills, and listing or removing components.", "author": { "name": "Danil Silantyev (github:rldyourmnd), CEO NDDev", "url": "https://github.com/rldyourmnd" @@ -16,7 +16,7 @@ "plugins", "mcp", "skills", - "release", + "components", "nddev" ] } diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/README.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/README.md index ed95d2a..681a87a 100644 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/README.md +++ b/zcode_tools/marketplaces/nddev-builder/plugins/core/README.md @@ -1,53 +1,46 @@ -# core (nddev-builder marketplace) +# core (`nddev-builder` marketplace) -The `core` plugin of the **nddev-builder** marketplace — the complete toolkit for -building and maintaining everything under ZCode: plugin scaffolding, component -authoring, MCP/hook/provider registration, marketplace creation, listing, -removal, releases, and consistency checking. +The `core` plugin is a reusable ZCode-native toolkit for creating and managing +marketplaces, plugins, and convention-discovered components. -- **18 skills** — add-plugin, add-skill, add-command, add-agent, add-hook, - add-mcp-server, add-provider, add-reference, add-tool, add-marketplace, - list-components, remove-component, enable-plugin, run-tests, add-test, run-benchmarks, release-build, doctor -- **18 slash commands** — `/nddev-add-plugin`, `/nddev-add-skill`, - `/nddev-add-command`, `/nddev-add-agent`, `/nddev-add-hook`, - `/nddev-add-mcp`, `/nddev-add-provider`, `/nddev-add-reference`, - `/nddev-add-tool`, `/nddev-add-marketplace`, `/nddev-list`, `/nddev-remove`, - `/nddev-enable`, `/nddev-release`, `/nddev-doctor` -- **1 subagent** — `nddev-native-reviewer` (GLM-5.2) +- **13 skills**: `add-marketplace`, `add-plugin`, `add-skill`, `add-command`, + `add-agent`, `add-hook`, `add-mcp-server`, `add-provider`, `add-reference`, + `add-tool`, `list-components`, `remove-component`, and `enable-plugin`. +- **13 slash commands**: `/nddev-add-marketplace`, `/nddev-add-plugin`, + `/nddev-add-skill`, `/nddev-add-command`, `/nddev-add-agent`, + `/nddev-add-hook`, `/nddev-add-mcp`, `/nddev-add-provider`, + `/nddev-add-reference`, `/nddev-add-tool`, `/nddev-list`, `/nddev-remove`, + and `/nddev-enable`. +- **1 subagent**: `nddev-native-reviewer` (GLM-5.2). -## What it provides +## Capabilities | Component | Purpose | -|---|---| -| `add-marketplace` | Scaffold a brand-new self-contained marketplace | -| `add-plugin` | Scaffold a self-contained plugin bundle inside a marketplace | -| `add-skill` | Author a SKILL.md (plugin- or user-scoped) | -| `add-command` | Author a slash command (commands/.md) | -| `add-agent` | Author a subagent (agents/.md with name + model) | -| `add-hook` | Register a lifecycle hook in hooks.json | -| `add-mcp-server` | Register a tool — classic MCP OR CLI+skill alternative | -| `add-provider` | Add a model provider (LLM endpoint) to v2-config | -| `add-reference` | Add a reference doc to a plugin bundle | -| `add-tool` | Add a CLI tool (non-MCP) with a companion skill | -| `list-components` | List all components in a marketplace (read-only) | -| `remove-component` | Safely remove a component (checks references first) | -| `enable-plugin` | Enable or disable a plugin in cli-config | -| `run-tests` | Run the test suite (30 pytest tests + fast lane) | -| `add-test` | Scaffold a new test file | -| `run-benchmarks` | Run installer performance benchmarks | -| `release-build` | Bump version sources, update CHANGELOG, validate, tag | -| `doctor` | Deep consistency check (versions, ZCode-spec, stale paths, JSON, secrets) | -| `nddev-native-reviewer` | Strict reviewer for ZCode-native format correctness | +| --- | --- | +| `add-marketplace` | Scaffold a self-contained marketplace | +| `add-plugin` | Scaffold a plugin bundle inside a marketplace | +| `add-skill` | Author a plugin- or user-scoped `SKILL.md` | +| `add-command` | Author a slash command | +| `add-agent` | Author a ZCode subagent | +| `add-hook` | Register a lifecycle hook | +| `add-mcp-server` | Register an MCP server or CLI-plus-skill alternative | +| `add-provider` | Add an LLM provider to the v2 configuration | +| `add-reference` | Add a reference document to a plugin bundle | +| `add-tool` | Add a non-MCP CLI tool and optional companion skill | +| `list-components` | Inventory marketplace components without mutation | +| `remove-component` | Remove a component after reference checks | +| `enable-plugin` | Enable or disable a plugin in the CLI configuration | +| `nddev-native-reviewer` | Review ZCode-native format correctness | + +Development-only test, benchmark, release, and repository-doctor capabilities +are intentionally not shipped in this public plugin. Maintainers run them from +the private `nddev-harnesses` control plane. ## Install -Enable via **ZCode → Settings → Plugin Management** after adding the -`nddev-builder` marketplace (the local `zcode_tools/marketplaces/nddev-builder/` -directory), or let the installer lay it down into +Add the local `nddev-builder` marketplace in ZCode Plugin Management, or use the +repository installer to place it under `~/.zcode/marketplaces/nddev-builder/plugins/core/`. -## Rules - -- English only — code, docs, manifests, descriptions. -- Plugin manifests are metadata-only; components are convention-discovered. -- See the `repo-orientation` skill for the full repository map. +Plugin manifests are metadata-only; ZCode discovers skills, commands, agents, +references, and tools by convention. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-add-test.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-add-test.md deleted file mode 100644 index 1b0f623..0000000 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-add-test.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -description: Scaffold a new test file in the nddev-zcode-app test suite (lives in the parent repo validation/ dir). ---- - -Add a new test to the nddev-zcode-app test suite. - -Follow the `add-test` skill exactly: - -1. Ask the user for the test name and what it should verify. -2. Create `validation/nddev-zcode-app/test_.py` using the established fixture/helper patterns. -3. Run the test to verify it passes. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-doctor.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-doctor.md deleted file mode 100644 index 965ca79..0000000 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-doctor.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -description: Run a deep consistency check on the entire repo — read the rule-skills, then verify versions, ZCode-spec, stale paths, broken commands, JSON, secrets, and installer plan. ---- - -Run the repository health check. - -Follow the `doctor` skill exactly. This is a read-only audit — do NOT fix issues, -only report them. - -1. **Read the rules first:** `repo-orientation` skill, `zcode-native-format.md` - reference, `config/nddev-contract.json`, `build/manifest.json`. -2. **Run each step** (1-8) from the `doctor` skill: version parity, ZCode spec - compliance, stale path detection, broken command detection, JSON validity, - secrets safety, installer plan (`--plan` for both platforms), cross-reference - integrity. -3. **Output** a `DOCTOR: PASS | FAIL` verdict with `[PASS|FAIL]` findings per step. - Cite exact `file:line` for every FAIL. - -Use Bash to run the grep/find/python checks. Be thorough — this is the check we -run after every change to catch drift. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-release.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-release.md deleted file mode 100644 index f751985..0000000 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-release.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -description: Prepare a new release of the nddev-zcode-app build — bump version, update changelog, validate, and tag. ---- - -Prepare a new versioned release of the `~/.zcode` build. - -Follow the `release-build` skill exactly: - -1. Determine the bump level (default: patch `+0.0.1`; minor/major only when the owner directs). -2. Bump BOTH version sources in sync: - - `build/version.json` → `"build_version"` - - `VERSION` (root) -3. Add a `## [X.Y.Z] - YYYY-MM-DD` section to `CHANGELOG.md` (Keep a Changelog format, Added/Changed/Fixed/Security subsections). -4. Validate: - - both version files show the same number, - - `cli-tools/scripts/install.sh install --marketplace --platform macos --plan` passes, - - `cli-tools/scripts/install.sh install --marketplace --platform ubuntu --plan` passes, - - all JSON files parse. -5. Stage and show the diff for approval. Do NOT commit, tag, or push without explicit confirmation — the tag triggers the release workflow. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-run-benchmarks.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-run-benchmarks.md deleted file mode 100644 index 041d40d..0000000 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-run-benchmarks.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -description: Run performance benchmarks for the installer (install, remove, plan timing). ---- - -Run installer performance benchmarks. - -Follow the `run-benchmarks` skill exactly: - -1. Resolve the control-plane root. -2. Run `python3 validation/nddev-zcode-app/benchmarks/bench_lifecycle.py`. -3. Report the timing results as a table. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-run-tests.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-run-tests.md deleted file mode 100644 index d30a068..0000000 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/commands/nddev-run-tests.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -description: Run the nddev-zcode-app test suite (30 pytest tests + fast validation lane) from the parent repo. ---- - -Run the nddev-zcode-app test suite. - -Follow the `run-tests` skill exactly: - -1. Resolve the control-plane root (parent of the nddev-zcode-app submodule). -2. Run the fast lane: `bash validation/nddev-zcode-app/scripts/validate_fast.sh`. -3. Run the full pytest suite: `python3 -m pytest -q validation/nddev-zcode-app/ -v --rootdir=validation/nddev-zcode-app`. -4. Report passed/failed counts and any failures. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-agent/SKILL.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-agent/SKILL.md index 7f61c32..c622955 100644 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-agent/SKILL.md +++ b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-agent/SKILL.md @@ -74,5 +74,6 @@ The body IS the subagent's system prompt. Write it as a complete role definition ## After creating - Validate: `cli-tools/scripts/install.sh install --marketplace --platform macos --plan`. -- Run the doctor (`/nddev-doctor`) to check consistency. -- Bump the build version if this is a release behavior change (follow `release-build`). +- Validate the same marketplace with `--platform ubuntu --plan`. +- For a release behavior change, keep `VERSION`, `build/version.json`, and + `build/manifest.json` in sync and update `CHANGELOG.md`. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-hook/SKILL.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-hook/SKILL.md index 4a9ffff..758c6da 100644 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-hook/SKILL.md +++ b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-hook/SKILL.md @@ -147,5 +147,6 @@ a command hook but 500ms (half a second) for a process hook. Default is 60000ms ## After creating - Validate: `cli-tools/scripts/install.sh install --marketplace --platform macos --plan`. -- Run the doctor (`/nddev-doctor`) to check consistency. -- Bump the build version if this is a release behavior change (follow `release-build`). +- Validate the same marketplace with `--platform ubuntu --plan`. +- For a release behavior change, keep `VERSION`, `build/version.json`, and + `build/manifest.json` in sync and update `CHANGELOG.md`. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-marketplace/SKILL.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-marketplace/SKILL.md index 4175546..800b582 100644 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-marketplace/SKILL.md +++ b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-marketplace/SKILL.md @@ -60,8 +60,9 @@ the installer merges them into `cli/config.json` if present): cli-tools/scripts/install.sh list ``` -6. **Bump the build version** if this is a release behavior change (see - `release-build` skill). +6. **Record release behavior changes.** Keep `VERSION`, + `build/version.json`, and `build/manifest.json` in sync and update + `CHANGELOG.md` when the repository is being prepared for release. ## Rules diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-plugin/SKILL.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-plugin/SKILL.md index 3ed9145..d72a0f2 100644 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-plugin/SKILL.md +++ b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-plugin/SKILL.md @@ -94,8 +94,9 @@ zcode_tools/marketplaces// `python3 -c "import json; json.load(open('zcode_tools/marketplaces//marketplace.json'))"` and the same for the new `plugin.json`. -8. **Bump version + changelog** if this is a release behavior change (see the - `release-build` skill). +8. **Record release behavior changes.** Keep `VERSION`, + `build/version.json`, and `build/manifest.json` in sync and update + `CHANGELOG.md` when preparing a repository release. ## Rules diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-test/SKILL.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-test/SKILL.md deleted file mode 100644 index d829b01..0000000 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/add-test/SKILL.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -name: add-test -description: Scaffold a new test file for the nddev-zcode-app test suite. Tests live in the parent control-plane repo (rldyour-ai-cli-tools/validation/nddev-zcode-app/), NOT inside the module. Creates a test file using the existing fixtures (module_root, temp_target, temp_backups, marketplaces) and the run_installer helper. Use when adding a new test case for a feature, bugfix, or regression. ---- - -# add-test - -Scaffolds a new test file in the centralized test suite. - -## Where tests live - -``` -rldyour-ai-cli-tools/validation/nddev-zcode-app/test_.py -``` - -## Procedure - -1. Ask the user for: - - The test name (snake_case, e.g. `test_custom_target`, `test_switch_all_marketplaces`). - - What the test should verify (one sentence). - -2. Create the test file at - `validation/nddev-zcode-app/test_.py`. - -3. Use the established patterns: - ```python - """.""" - from _helpers import run_installer, load_json - - def test_(installer, temp_target, temp_backups): - """.""" - run_installer(installer, "install", "--marketplace", "nddev-builder", - "--platform", "macos", "--apply", - target=temp_target, backups=temp_backups) - assert (temp_target / "BUILD-VERSION").is_file() - ``` - -4. Available fixtures (from `conftest.py`): - - `module_root` — Path to `modules/nddev-zcode-app/` (session-scoped). - - `installer` — Path to `cli-tools/scripts/install.sh` (session-scoped). - - `temp_target` — Fresh temp dir for `--target` (function-scoped, auto-cleanup). - - `temp_backups` — Fresh temp dir for backups (function-scoped, auto-cleanup). - - `marketplaces` — List of all marketplace names (session-scoped). - -5. Available helpers (from `_helpers.py`): - - `run_installer(installer, *args, target=None, backups=None, expect_success=True)` — - runs install.sh with the given args, returns CompletedProcess. - - `load_json(path)` — loads and parses a JSON file. - -6. Run the test to verify it passes: - ```bash - python3 -m pytest validation/nddev-zcode-app/test_.py -v --rootdir=validation/nddev-zcode-app - ``` - -## Rules - -- Tests always use temp dirs — never the real `~/.zcode`. -- Each test should verify ONE behavior (single assertion focus). -- Use `expect_success=False` when testing error cases (guard rejections, etc.). -- English only. - -## After creating - -- Run the full suite to verify no regressions: - `python3 -m pytest -q validation/nddev-zcode-app/ --rootdir=validation/nddev-zcode-app`. -- Bump the build version if this is a release behavior change (follow `release-build`). diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/doctor/SKILL.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/doctor/SKILL.md deleted file mode 100644 index 66450db..0000000 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/doctor/SKILL.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -name: doctor -description: Deep consistency check for the entire nddev-zcode-app repo. READ THE RULE SKILLS FIRST (repo-orientation, zcode-native-format, add-plugin, add-skill), then verify everything against them — version parity, ZCode-spec compliance, stale paths, broken commands, JSON validity, secrets safety, and installer plan. Run after ANY change to the repo. Returns a pass/fail verdict with specific findings. ---- - -# doctor - -The repository health check. **Read the rule-skills first**, then verify the repo -against them. This skill is run after every change to catch drift early. - -## Step 0 — Load the rules (read these in full before checking) - -Before checking anything, read these files so you know what "correct" means: - -1. `.agents/skills/repo-orientation/SKILL.md` — the repository map, three-layer - model, where things live, the installer flow. -2. `zcode_tools/marketplaces/nddev-builder/plugins/core/references/zcode-native-format.md` - — the ZCode native format reference (marketplace shape, plugin manifests, - component convention-discovery, hooks, mcp). -3. `config/nddev-contract.json` — the product contract (source_root, native_format). -4. `build/manifest.json` — the declared layout, backup/restore policy. - -Only after reading these can you judge whether the repo matches its own rules. - -## Step 1 — Version parity - -Check that these all agree on the build version: -- `VERSION` -- `build/version.json` → `build_version` -- `build/manifest.json` → `build_version` -- `pyproject.toml` → `version` -- Each `marketplace.json` plugin entry `version` == its `plugin.json` `version` - -Check ZCode pin consistency: -- `build/version.json` `zcode_app_version` == `references/zcode-baseline.json` → `zcode.app_version` -- `build/version.json` `zcode_cli_version` == `references/zcode-baseline.json` → `zcode.cli_version` - -Report any mismatch with file + field. - -## Step 2 — ZCode spec compliance - -For EVERY marketplace under `zcode_tools/marketplaces/`: - -- **marketplace.json** — has `name`, `owner`, `description`, `plugins[]`. Each - plugin entry has `name`, `source`, `description`, `version`, `author`, - `category`, `tags`, `license`. The `name` matches the directory name. -- **plugin.json** (each plugin) — metadata-only: NO `commands`, `skills`, - `hooks`, `mcpServers`, or `agents` arrays. `name` matches - `^[a-z0-9][a-z0-9._-]{0,127}$`. Any declared component paths are **relative - and inside the plugin root** (no absolute/escaping paths). -- **SKILL.md** (each) — frontmatter `name` matches the directory name. - Frontmatter delimited by `---`. **`description` is ≤ 1024 characters** (over - = silently dropped). Recognized keys: `name`, `description`, `when_to_use`, - `license`, `metadata` (any other key is silently ignored). -- **commands/*.md** — filename matches `^[a-z0-9][a-z0-9_:-]{0,63}$`. Frontmatter - has `description` (or a non-empty body). Keys are **hyphenated** - (`allowed-tools`, not `allowed_tools`). No multi-line arrays (flat parser). -- **agents/*.md** — frontmatter has `name` and `model`. -- **cli-config.template.json** — `hooks.enabled: true`, all 7 events present, - uses `mcp.servers` (NOT top-level `mcpServers`). -- **mcp.json** — uses `mcpServers` key (correct for the plugin/reference form). -- **hooks.json** — only the 7 supported event keys (plus `_comment`). - -## Step 3 — Stale path detection - -Search ALL `.md`, `.sh`, `.json`, `.yml` files for patterns that indicate the -old pre-refactor structure (these should NOT appear outside CHANGELOG history): - -- `zcode_tools/marketplace.json` (old single-marketplace root) -- `zcode_tools/plugins/` WITHOUT a `marketplaces/` prefix -- `zcode_tools/AGENTS.md` (now inside marketplaces) -- `zcode_tools/cli-config`, `zcode_tools/v2-config`, `zcode_tools/mcp.json`, - `zcode_tools/hooks.json` (now inside marketplaces) -- bare `nddev` marketplace name (the old pre-refactor name, now `nddev-builder`). - Note: `nddev-developer` is a valid active marketplace (full-stack developer - setup) — do NOT flag it as stale. - -## Step 4 — Broken command detection - -Every documented `install.sh` invocation must use the correct syntax: -`install --marketplace `. Search docs and skills for bare -`install.sh --plan` or `install.sh --apply` without the `install` subcommand -and `--marketplace` — these will error. - -## Step 5 — JSON validity - -Validate every JSON file parses: -```bash -for f in $(find . -name '*.json' -not -path './.git/*'); do - python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$f" || echo "INVALID: $f" -done -``` - -## Step 6 — Secrets safety - -- No `.env` file tracked by git: `git ls-files | grep -E '(^|/)\.env$'` → must be empty. -- Every `${VAR}` placeholder in templates has a matching key in `build/.env.example`. - -## Step 7 — Installer plan - -EVERY marketplace must pass dry-run on both platforms: -```bash -for mp in $(ls zcode_tools/marketplaces/); do - cli-tools/scripts/install.sh install --marketplace "$mp" --platform macos --plan - cli-tools/scripts/install.sh install --marketplace "$mp" --platform ubuntu --plan -done -``` -Every run must end with `[ok] all checks passed`. - -## Step 8 — Cross-reference integrity - -- `config/nddev-contract.json` `source_root`, `installer_entry`, - `native_format.marketplace_root` match the actual structure. -- `build/manifest.json` `layout` matches reality. -- Every file path mentioned in docs (README, AGENTS, CONTRIBUTING, docs/*, the - repo-orientation skill) actually exists. - -## Step 9 — Test suite (recommended after doctor) - -Doctor checks structural consistency. For behavioral correctness, also run the -centralized test suite (30 pytest tests in the parent control-plane repo): - -```bash -cd -python3 -m pytest -q validation/nddev-zcode-app/ --rootdir=validation/nddev-zcode-app -``` - -This covers marketplace structure, installer lifecycle, restore safety, backup -rotation, config rendering, and version parity. Follow the `run-tests` skill -for details. Not a doctor axis (doctor is structural; tests are behavioral). - -## Output format - -``` -DOCTOR: PASS | FAIL - -Findings: -- [PASS|FAIL] : -... -``` - -If any step FAILs, list the exact file:line and what's wrong. Do not fix issues -during the doctor run — only report. The caller decides what to fix. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/release-build/SKILL.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/release-build/SKILL.md deleted file mode 100644 index e14486a..0000000 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/release-build/SKILL.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -name: release-build -description: Cut a new release of the nddev-zcode-app build. Bumps build/version.json, VERSION, and pyproject.toml in sync, adds a CHANGELOG.md entry, validates the installer --plan runs clean, and prepares the SemVer tag. Use when releasing a new build version. ---- - -# release-build - -Prepares a new versioned release of the `~/.zcode` build. - -## Version sources (keep in sync) - -Four files hold the build version and must always match: - -- `build/version.json` → `build_version` field -- `VERSION` (root, single line) -- `pyproject.toml` → `[project]` → `version` -- `build/manifest.json` → `build_version` - -The installer reads `build/version.json`; the `release.yml` workflow refuses to publish -a tag that does not match `VERSION`; the version-parity test asserts all four agree. - -## Procedure - -1. **Decide the bump.** - - **patch** `+0.0.1` — default, for any source/config/doc change after a release exists. - - **minor** `+0.1.0` — new backward-compatible capability (e.g. a new plugin). - - **major** `+1.0.0` — breaking change to the installer contract or `~/.zcode` layout. - The owner directs minor/major; patch is the default. - -2. **Bump all four files to the new version** (e.g. `1.0.0` → `1.0.1`): - - `build/version.json` → `"build_version": "1.0.1"` - - `VERSION` → `1.0.1` - - `pyproject.toml` → `version = "1.0.1"` (under `[project]`) - - `build/manifest.json` → `"build_version": "1.0.1"` - -3. **Add a CHANGELOG entry.** Under `## [Unreleased]` (or create it), add a new section: - ```markdown - ## [1.0.1] - YYYY-MM-DD - ### Added - - - ### Changed - - - ``` - Use `Added` / `Changed` / `Fixed` / `Security` subsections as needed. Keep a Changelog format. - -4. **Validate locally:** - ```bash - python3 -c "import json; print(json.load(open('build/version.json'))['build_version'])" - cat VERSION - python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])" - cli-tools/scripts/install.sh install --marketplace --platform macos --plan - cli-tools/scripts/install.sh install --marketplace --platform ubuntu --plan - # Validate every marketplace manifest: - for f in zcode_tools/marketplaces/*/marketplace.json; do - python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$f" - done - ``` - All version numbers must agree; both `--plan` runs must finish `[ok] all checks passed`. - -5. **Commit** with `chore(release): prepare vX.Y.Z` (or `feat`/`fix` if the release - carries a behavior change). - -6. **Tag + push** (triggers `release.yml`): - ```bash - git tag X.Y.Z - git push origin main --tags - ``` - The tag must match `VERSION` exactly. `release.yml` verifies this, extracts the - matching CHANGELOG section, and publishes the GitHub Release. - -## Rules - -- `build/version.json` and `VERSION` must be identical before tagging. -- SemVer tags only: `X.Y.Z` or `X.Y.Z-pre`. -- Never skip the `--plan` validation before tagging. -- The owner approves minor/major bumps; patch is the default. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/remove-component/SKILL.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/remove-component/SKILL.md index 067c65c..c8e6966 100644 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/remove-component/SKILL.md +++ b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/remove-component/SKILL.md @@ -51,8 +51,9 @@ Safely removes a component from a marketplace. cli-tools/scripts/install.sh install --marketplace --platform macos --plan ``` -8. Remind the user to bump the build version if this is a release behavior - change (follow the `release-build` skill). +8. If this is a release behavior change, remind the user to keep `VERSION`, + `build/version.json`, and `build/manifest.json` in sync and update + `CHANGELOG.md`. ## Rules diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/run-benchmarks/SKILL.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/run-benchmarks/SKILL.md deleted file mode 100644 index d10ca3b..0000000 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/run-benchmarks/SKILL.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -name: run-benchmarks -description: Run performance benchmarks for the nddev-zcode-app installer. Measures timing for install --plan, install --apply, remove --apply across all marketplaces. Reports min/mean/max over multiple runs. Tests live in the parent control-plane repo (rldyour-ai-cli-tools/validation/nddev-zcode-app/benchmarks/). Use when checking installer performance, comparing before/after optimizations, or establishing baseline timings. ---- - -# run-benchmarks - -Runs performance benchmarks for the installer lifecycle. - -## Where benchmarks live - -``` -rldyour-ai-cli-tools/validation/nddev-zcode-app/benchmarks/bench_lifecycle.py -``` - -## What it measures - -- **install --plan**: dry-run latency per marketplace (no writes). -- **install --apply**: full lifecycle (backup → build → restore → verify). -- **remove --apply**: backup + delete timing. - -Each operation runs N times (default 3) and reports min/mean/max in seconds. - -## Procedure - -1. Resolve the control-plane root (parent of the nddev-zcode-app submodule). - -2. Run the benchmark script: - ```bash - python3 validation/nddev-zcode-app/benchmarks/bench_lifecycle.py - ``` - For machine-readable output: - ```bash - python3 validation/nddev-zcode-app/benchmarks/bench_lifecycle.py --json - ``` - For more runs (more stable averages): - ```bash - python3 validation/nddev-zcode-app/benchmarks/bench_lifecycle.py --runs 5 - ``` - -3. Report the results as a table: - ``` - Benchmark min mean max (seconds) - plan/nddev-builder/macos 0.123 0.130 0.140 - apply/install/builder/macos 1.234 1.300 1.400 - ``` - -4. If comparing before/after a change, run benchmarks on both versions and - report the delta. A >10% regression should be investigated. - -## Rules - -- Benchmarks run in temp dirs — never against the real `~/.zcode`. -- Results are machine-specific; compare only relative deltas, not absolute values. -- The first run is often slower (cold cache); prefer `--runs 3` minimum. -- English only. diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/run-tests/SKILL.md b/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/run-tests/SKILL.md deleted file mode 100644 index 8b78508..0000000 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/skills/run-tests/SKILL.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -name: run-tests -description: Run the nddev-zcode-app test and validation suite. Tests live in the parent control-plane repo (rldyour-ai-cli-tools/validation/nddev-zcode-app/), NOT inside the module — this keeps the implementation clean. Runs pytest (30 tests covering marketplace structure, installer lifecycle, restore safety, backup rotation, config rendering, version parity) plus a fast validation lane (JSON + installer plan + ShellCheck). Use when you need to verify the system works correctly after changes, before a release, or to catch regressions. ---- - -# run-tests - -Runs the nddev-zcode-app test suite from the parent control-plane repo. - -## Where tests live - -Tests are centralized in the **parent repo** (rldyour-ai-cli-tools), NOT inside -the nddev-zcode-app submodule. This is by design: the implementation stays -clean, and test internals are hidden from users. - -``` -rldyour-ai-cli-tools/ - validation/nddev-zcode-app/ ← test suite root - conftest.py ← fixtures (module_root, temp_target, temp_backups) - _helpers.py ← run_installer(), load_json() - test_marketplace_structure.py ← marketplace JSON shapes (8 tests) - test_installer_lifecycle.py ← install→update→switch→remove (6 tests) - test_restore_safety.py ← C1/C2/C3 hardening (5 tests) - test_backup_rotation.py ← 10-slot rotation (4 tests) - test_config_rendering.py ← ${VAR} + hooks/mcp merge (4 tests) - test_version_parity.py ← 5-source version consistency (3 tests) - benchmarks/bench_lifecycle.py ← timing benchmarks - scripts/validate_fast.sh ← quick lane (<60s) - scripts/validate_release.sh ← full lane (<300s) -``` - -## Procedure - -1. Resolve the control-plane root. If you are inside the nddev-zcode-app - submodule directory, go up 2 levels to reach rldyour-ai-cli-tools. - -2. **Fast lane** (quick check, <60s): - ```bash - bash validation/nddev-zcode-app/scripts/validate_fast.sh - ``` - This runs JSON validity, installer `--plan` for all marketplaces, and - ShellCheck. Use this for rapid feedback during development. - -3. **Full pytest suite** (~30s): - ```bash - cd - python3 -m pytest -q validation/nddev-zcode-app/ -v --tb=short --rootdir=validation/nddev-zcode-app - ``` - Runs all 30 tests. Each test shells out to the installer in temp dirs, - so nothing touches the real `~/.zcode`. - -4. **Release lane** (full validation, <300s): - ```bash - bash validation/nddev-zcode-app/scripts/validate_release.sh - ``` - Runs the fast lane + the full pytest suite. Use before tagging a release. - -5. Report results: passed/failed counts, any failures with details. - -## Rules - -- Tests always run in temp directories — never against the real `~/.zcode`. -- The test suite is the gatekeeper: no release without all tests passing. -- If a test fails, fix the root cause — do not skip or weaken the test. -- English only for all output.