* feat: add wmill protection-rules pull/push CLI commands Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor: use directional keys for protection-rules pull --json diff Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address review — exit non-zero on failure, resolve override workspace key - failure paths in pull/push now exit 1 so CI/scripts detect failed reconciles - --override writes under the resolved workspace key (findWorkspaceByGitBranch), not the raw branch, so gitBranch-mapped entries aren't left inert - pull --replace clears a shadowing protectionRules override so top-level takes effect (was an infinite pull --diff loop) - push reports applied create/update/delete counts on partial failure and warns loudly when an empty list would wipe all backend rules Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address review — dry-run pull --diff no longer writes; --promotion coherent - pull --diff returns before the no-wmill.yaml bootstrap, so a dry run never creates/mutates wmill.yaml - pull --promotion now writes/clears the promotion target's promotionOverrides (the same block getEffectiveSettings reads), instead of the current branch's regular overrides — read and write are now coherent Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor: move protection rules to a per-workspace protection-rules.yaml Replaces the wmill.yaml/SyncOptions integration (top-level + overrides + promotionOverrides) with a dedicated protection-rules.yaml keyed by workspace name. This removes the getEffectiveSettings layering that caused the override shadowing / promotion-coherence / dry-run bugs entirely. - protection-rules.yaml: { <workspace>: ProtectionRuleEntry[] }, keys must match wmill.yaml 'workspaces' (source of truth for backend id/baseUrl/token) - commands reduced to: pull/push [workspace] | --all, with --dry-run - per-workspace auth resolved via tryResolveBranchWorkspace + setClient - push remains a full reconcile (create/update/delete) with delete confirm, empty-list wipe warning, partial-failure reporting, non-zero exit on failure - conf.ts reverted to main; SyncOptions no longer carries protectionRules Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address review — honor explicit --base-url/--token in protection-rules configureClientForWorkspace bypassed the credential precedence other commands use: explicit --base-url/--token now work for stateless CI (no stored profile or wmill.yaml baseUrl needed), and an explicit --token overrides a stored profile's token. The backend workspace id still derives from the wmill.yaml mapping (feature invariant). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address cubic review — consistent status on partial --all failure cubic found that pull/push reported success:true while exiting non-zero on partial --all failures, and that the push command description was missing from the generated CLI docs. - pull/push now report success:false + partialFailure:true (and exit 1) when any --all workspace fails; success:true only on full success - .description() calls use single string literals (not + concatenation) so system_prompts/generate.py parses them; regenerated CLI docs Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address review — --json-output must emit only JSON on stdout Codex flagged that workspace resolution (tryResolveBranchWorkspace's log.info) and push's empty-list delete warning print to stdout before the JSON payload, breaking machine callers. Silence human logs via log.setSilent(true) as the first action when --json-output is set (before readConfigFile / resolution); log.error still goes to stderr. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
System Prompts
This directory contains the single source of truth for AI system prompts used by both the frontend copilot and CLI guidance.
Structure
system_prompts/
├── base/ # Core instruction templates (manually written)
│ ├── flow-base.md # Shared OpenFlow structure guidance
│ └── flow-cli.md # CLI/local-agent workflow guidance for write-flow skill
├── languages/ # Language-specific instructions (manually written)
└── auto-generated/ # Auto-generated files (DO NOT EDIT)
├── sdks/ # SDK documentation
├── cli/ # CLI command documentation
├── prompts.ts # TypeScript exports
└── index.ts # Helper functions
Usage
Regenerating Prompts
When SDK methods or the OpenFlow schema change, run:
python system_prompts/generate.py
To also refresh the standalone skills in a Claude plugin checkout:
python system_prompts/generate.py --plugin-dir ~/windmill-claude-plugin
--plugin-dir accepts:
- the
windmill-claude-pluginrepo root - a plugin root such as
plugins/windmill-code-plugin - a direct
skills/directory
To regenerate the public docs repo (consumed by context7):
python system_prompts/generate.py --context7-dir ~/windmill-cli-docs
--context7-dir writes a fully-rendered snapshot (AGENTS.md,
cli-commands.md, skills/<name>/SKILL.md, README.md, manifest.json
with the Windmill version) with all template placeholders resolved —
suitable for ingestion by docs aggregators. In CI this runs from
.github/workflows/publish-cli-docs.yml on every release tag. The
generator refuses to wipe the target directory unless it's empty or has
a context7 marker (context7.json, manifest.json, or a
windmill-cli-docs git remote), so a typo can't delete unrelated files.
This will:
- Parse TypeScript and Python SDK files to extract function signatures
- Parse the OpenFlow YAML schema
- Parse the CLI commands
- Assemble complete prompts from markdown files
- Generate TypeScript exports in
auto-generated/ - Optionally refresh plugin-ready standalone
SKILL.mdfiles in the target directory
Scope
These system prompts contain ONLY:
- How to write Windmill scripts (language syntax, conventions, SDK usage)
- How to structure Windmill flows (OpenFlow schema, module types, data flow)
- Resource type handling, S3 operations
They DO NOT contain:
- Tool usage instructions (edit_code, set_flow_json, etc.)
- IDE/editor specific commands
- Testing tool invocations
Tool instructions are added separately by the frontend and CLI.
CLI-only workflow instructions live in base/flow-cli.md and are included in the
generated write-flow skill for wmill init. They are intentionally excluded
from the frontend flow chat prompt.
Integration
Frontend
Uses Vite path alias $system_prompts pointing to auto-generated/:
import { FLOW_GUIDANCE } from "$system_prompts/flow";
import { getLangContext } from "$system_prompts/languages";
CLI
Generates /cli/src/guidance/skills.gen.ts with embedded skill content for wmill init.
Editing Guidelines
- Edit markdown files in
base/,languages/ - Never edit files in
auto-generated/directly - After editing, run
generate.pyto update exports