From 03274532ec5097307ef44daab8a406950edb39f2 Mon Sep 17 00:00:00 2001 From: Dov Benyomin Sohacheski Date: Wed, 1 Jul 2026 14:02:41 +0300 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=A8=20Generate=20ws-cli=20command=20m?= =?UTF-8?q?anifest=20for=20ws-docs=20distribution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Walk the cobra tree into a single nested, alphabetically-sorted commands.yaml via a tools/gen-commands generator (internals/docs); golden + twice-serialize determinism tests pin the artifact. Add sync-commands.yaml to push it to ws-meta as a new distribution origin. Sort GetTemplateNames so template help and the manifest are stable. --- .github/workflows/sync-commands.yaml | 19 ++ cmd/commands_test.go | 31 +++ cmd/root.go | 4 + commands.yaml | 368 +++++++++++++++++++++++++++ internals/docs/serialize.go | 73 ++++++ internals/template/template.go | 3 + tools/gen-commands/main.go | 22 ++ 7 files changed, 520 insertions(+) create mode 100644 .github/workflows/sync-commands.yaml create mode 100644 cmd/commands_test.go create mode 100644 commands.yaml create mode 100644 internals/docs/serialize.go create mode 100644 tools/gen-commands/main.go diff --git a/.github/workflows/sync-commands.yaml b/.github/workflows/sync-commands.yaml new file mode 100644 index 0000000..d0a33c5 --- /dev/null +++ b/.github/workflows/sync-commands.yaml @@ -0,0 +1,19 @@ +--- +name: 🔄 Sync commands to ws-meta +on: + push: + branches: + - main + paths: + - commands.yaml + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: 🔄 Sync to ws-meta + uses: kloudkit/ws-meta/.github/actions/sync@main + with: + token: ${{ secrets.KLOUD_BOT_ORG_PAT }} + files: | + commands.yaml diff --git a/cmd/commands_test.go b/cmd/commands_test.go new file mode 100644 index 0000000..9010611 --- /dev/null +++ b/cmd/commands_test.go @@ -0,0 +1,31 @@ +package cmd_test + +import ( + "os" + "path/filepath" + "testing" + + "github.com/kloudkit/ws-cli/cmd" + "github.com/kloudkit/ws-cli/internals/docs" + "gotest.tools/v3/assert" +) + +func TestCommandsManifestMatchesCommittedFile(t *testing.T) { + want, err := os.ReadFile(filepath.Join("..", "commands.yaml")) + assert.NilError(t, err) + + got, err := docs.Serialize(cmd.RootCmd()) + assert.NilError(t, err) + + assert.Equal(t, string(got), string(want)) +} + +func TestSerializeIsDeterministic(t *testing.T) { + first, err := docs.Serialize(cmd.RootCmd()) + assert.NilError(t, err) + + second, err := docs.Serialize(cmd.RootCmd()) + assert.NilError(t, err) + + assert.Equal(t, string(first), string(second)) +} diff --git a/cmd/root.go b/cmd/root.go index 1027623..93fddf2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -32,6 +32,10 @@ var rootCmd = &cobra.Command{ }, } +func RootCmd() *cobra.Command { + return rootCmd +} + func Execute() { ctx := context.Background() diff --git a/commands.yaml b/commands.yaml new file mode 100644 index 0000000..687967b --- /dev/null +++ b/commands.yaml @@ -0,0 +1,368 @@ +name: ws-cli +synopsis: ⚡ CLI companion to charge the workspace batteries +aliases: + - ws +commands: + - name: ws-cli clip + synopsis: Interact with the native clipboard + commands: + - name: ws-cli clip paste + synopsis: Paste clipboard content + usage: ws-cli clip paste + - name: ws-cli editor + synopsis: Inspect and drive the active editor session + options: + - name: raw + default: "false" + usage: Output the raw JSON response without styling + commands: + - name: ws-cli editor diagnostics + synopsis: Show language diagnostics for the workspace (or a single file) + usage: ws-cli editor diagnostics [flags] + options: + - name: uri + usage: Filter to a single file (URI or absolute path) + - name: ws-cli editor list + synopsis: List the currently open editor tabs + usage: ws-cli editor list + - name: ws-cli editor open + synopsis: Open a file in the editor + usage: ws-cli editor open [flags] + options: + - name: new-window + default: "false" + usage: Open in a new window + - name: preview + default: "false" + usage: Open as a preview tab (reuse-window only) + - name: reuse-window + default: "false" + usage: Open in the current window as a tab (default) + - name: selection + usage: 'Select a range: LINE:COL[-LINE:COL] (1-based)' + - name: ws-cli editor selection + synopsis: Show the active editor's current selection + usage: ws-cli editor selection + - name: ws-cli feature + synopsis: Install additional pre-configured features + options: + - name: root + default: /usr/share/workspace/features.d + usage: Root directory of additional features + commands: + - name: ws-cli feature info + synopsis: Show detailed information about a feature + usage: ws-cli feature info + - name: ws-cli feature install + synopsis: Install additional pre-configured features + usage: ws-cli feature install [flags] + options: + - name: opt + default: '[]' + usage: Optional variables to use during installation + - name: skip-completion + default: "false" + usage: Skip configuring shell completion + - name: skip-extensions + default: "false" + usage: Skip installing VSCode extensions + - name: skip-repository + default: "false" + usage: Skip enabling the vendor APT repository + - name: ws-cli feature list + synopsis: List available features that can be installed + usage: ws-cli feature list + aliases: + - ls + - name: ws-cli feature new + synopsis: Print boilerplate for a custom feature playbook + description: |- + Print a starter feature playbook to stdout. + + Redirect it into ~/.ws/features.d/.yaml, then extend it and install + with "ws-cli feature install ": + + ws-cli feature new redis > ~/.ws/features.d/redis.yaml + usage: ws-cli feature new [name] + - name: ws-cli feature store + synopsis: List packages available in the feature store + usage: ws-cli feature store + - name: ws-cli info + synopsis: Display workspace information + commands: + - name: ws-cli info env + synopsis: Display effective workspace environment variables + usage: ws-cli info env + - name: ws-cli info extensions + synopsis: Display installed extensions + usage: ws-cli info extensions + - name: ws-cli info metrics + synopsis: Display workspace metrics + usage: ws-cli info metrics [flags] + options: + - name: gpu + default: "false" + usage: Include GPU metrics + - name: ws-cli info uptime + synopsis: Display the workspace uptime + usage: ws-cli info uptime + - name: ws-cli info version + synopsis: Display installed workspace version + usage: ws-cli info version [flags] + options: + - name: all + default: "false" + usage: Show all version information + - name: ws-cli log + synopsis: Log messages + options: + - name: pipe + shorthand: p + default: "false" + usage: Loop through piped output + commands: + - name: ws-cli log debug + synopsis: Log debugging messages + usage: ws-cli log debug message [flags] + options: + - name: indent + shorthand: i + default: "0" + usage: Desired prefixed indentation + - name: stamp + shorthand: s + default: "false" + usage: Prefix message with current timestamp + - name: ws-cli log error + synopsis: Log error messages + usage: ws-cli log error message [flags] + options: + - name: indent + shorthand: i + default: "0" + usage: Desired prefixed indentation + - name: stamp + shorthand: s + default: "false" + usage: Prefix message with current timestamp + - name: ws-cli log info + synopsis: Log information messages + usage: ws-cli log info message [flags] + options: + - name: indent + shorthand: i + default: "0" + usage: Desired prefixed indentation + - name: stamp + shorthand: s + default: "false" + usage: Prefix message with current timestamp + - name: ws-cli log stamp + synopsis: Log the current timestamp + usage: ws-cli log stamp + - name: ws-cli log warn + synopsis: Log warning messages + usage: ws-cli log warn message [flags] + options: + - name: indent + shorthand: i + default: "0" + usage: Desired prefixed indentation + - name: stamp + shorthand: s + default: "false" + usage: Prefix message with current timestamp + - name: ws-cli logs + synopsis: Retrieve workspace logs + usage: ws-cli logs [flags] + options: + - name: follow + shorthand: f + default: "false" + usage: Follow log output in real-time + - name: level + shorthand: l + usage: Filter by log level (debug|info|warn|error) + - name: tail + shorthand: t + default: "0" + usage: Number of lines to show from the end (0 for all) + - name: target + default: main + usage: Log target to read (main|metrics|docker|auth_proxy|cloudflared) + - name: ws-cli secrets + synopsis: Manage encryption and decryption of secrets + options: + - name: force + default: "false" + usage: Overwrite existing files + - name: master + usage: Master key or path to key file + - name: mode + usage: File permissions (e.g., 0o600, 384), only when --output is used + - name: output + usage: Write output to file instead of stdout + - name: raw + default: "false" + usage: Output without styling + commands: + - name: ws-cli secrets decrypt + synopsis: Decrypt an encrypted value + usage: ws-cli secrets decrypt + - name: ws-cli secrets encrypt + synopsis: Encrypt a plaintext value + usage: ws-cli secrets encrypt + - name: ws-cli secrets generate + synopsis: Generate master keys or login password hashes + commands: + - name: ws-cli secrets generate login + synopsis: Generate a workspace password hash for authentication + usage: ws-cli secrets generate login + - name: ws-cli secrets generate master + synopsis: Generate a cryptographically secure master key + usage: ws-cli secrets generate master [flags] + options: + - name: length + default: "32" + usage: Key length in bytes + - name: ws-cli seed + synopsis: Project declarative content onto the filesystem + options: + - name: source + usage: Seed source directory + commands: + - name: ws-cli seed apply + synopsis: Project seed content onto the filesystem + usage: ws-cli seed apply [dest...] [flags] + options: + - name: force + default: "false" + usage: Overwrite existing destinations + - name: master + usage: Master key or path to key file + - name: ws-cli seed ls + synopsis: List seed destinations and their behaviors + usage: ws-cli seed ls + - name: ws-cli seed rotate + synopsis: Re-encrypt managed secrets under a new master key + usage: ws-cli seed rotate [flags] + options: + - name: master + usage: Current master key or path to key file + - name: new-master + usage: New master key or path to key file + - name: ws-cli serve + synopsis: Serve internal assets + options: + - name: bind + default: 0.0.0.0 + usage: Bind address + - name: port + shorthand: p + default: "38080" + usage: Port to serve assets on + commands: + - name: ws-cli serve current + synopsis: Serve current directory as a static site + usage: ws-cli serve current + - name: ws-cli serve current + synopsis: Serve current directory as a static site + usage: ws-cli serve current [flags] + - name: ws-cli serve font + synopsis: Serve fonts for local download + usage: ws-cli serve font + - name: ws-cli serve font + synopsis: Serve fonts for local download + usage: ws-cli serve font [flags] + - name: ws-cli serve metrics + synopsis: Start the Prometheus metrics server + usage: ws-cli serve metrics [flags] + options: + - name: collectors + default: '[*]' + usage: Comma-separated list of collectors to enable (e.g., workspace,container.cpu,gpu) + - name: port + shorthand: p + default: "9100" + usage: Port to serve metrics on + - name: ws-cli show + synopsis: Display information about the current workspace instance + options: + - name: raw + default: "false" + usage: Output raw value without styling + commands: + - name: ws-cli show env + synopsis: Display the resolved value of a workspace environment variable + usage: ws-cli show env [flags] + options: + - name: as + usage: 'Validate and emit as one of: bool, int, list (mutex with --value)' + - name: check + default: "false" + usage: Check whether the variable (or its --deprecated alias) is set + - name: delimiter + usage: Override delimiter for --as=list (defaults to YAML delimiter or space) + - name: deprecated + usage: Deprecated alias paired with --check + - name: or-skip + default: "false" + usage: Exit 1 (not error) on the natural absence of the chosen projection + - name: validate + usage: Anchored regex each --as=list token must full-match; rejects fail-closed + - name: value + default: "false" + usage: Emit the raw resolved value as a single line + - name: ws-cli show ip + synopsis: Display IP addresses + commands: + - name: ws-cli show ip internal + synopsis: Display the internal IP address + usage: ws-cli show ip internal + - name: ws-cli show ip node + synopsis: Display the node/host IP address + usage: ws-cli show ip node + - name: ws-cli show path + synopsis: Display various paths + commands: + - name: ws-cli show path home + synopsis: Display the workspace home path + usage: ws-cli show path home + - name: ws-cli show path vscode-settings + synopsis: Display the VS Code settings path + usage: ws-cli show path vscode-settings [flags] + options: + - name: workspace + default: "false" + usage: Get the workspace settings + - name: ws-cli template + synopsis: Manage static configuration files + description: Copy and manage configuration files stored in global locations + commands: + - name: ws-cli template apply + synopsis: Apply a configuration template to the current project + usage: ws-cli template apply