diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 4a14fc2..a465ff2 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,6 +1,9 @@ { "name": "cube", - "url": "https://github.com/cube-js/cube-agent-skills", + "owner": { + "name": "Cube Dev, Inc." + }, + "description": "Official Cube agent skills for operating Cube through the CLI.", "plugins": [ { "name": "cube", diff --git a/CHANGELOG.md b/CHANGELOG.md index e41890a..e1559e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,28 @@ tied to the Cube CLI or the Cube release train. skills.sh install via `npx skills add`. - `scripts/validate-skills.py` and the PR validation workflow. +### Fixed + +- Make all nine skill descriptions valid strict YAML so `npx skills add` + discovers the complete package. +- Correct Cube CLI signatures and read/write classification across + `cube-admin`, `cube-embed`, `cube-deploy`, `cube-build-model`, + `cube-explore-content`, and `cube-build-content`. + +### Verified + +- Installed all nine skills into a clean Codex project with `skills@1.5.22`. +- Validated and installed the Claude Code plugin with Claude Code 2.1.234. +- Exercised the read-only paths against d3-demo deployment 75 with Cube CLI + 1.7.21, including compiled metadata, saved content, agents, administration, + deployment state, embed eligibility, and a real aggregate query. +- Confirmed all 103 Cube command paths referenced by the skills resolve in + Cube CLI 1.7.21, and confirmed a natural-language Codex request implicitly + selects `cube-explore-model` from a clean install. + ### Not yet verified -None of the nine has been driven end to end against a live deployment. Every -command is checked against the CLI source rather than executed, so this is -release-blocking — see the smoke-test section of CONTRIBUTING.md. +Mutating paths were intentionally not executed against the shared d3-demo +tenant. Creating or changing models, content, agents, users, embed sessions, +or deployments still needs an end-to-end pass in a disposable tenant before +those write workflows can be considered verified. diff --git a/scripts/validate-skills.py b/scripts/validate-skills.py index 6c1beb1..e80026f 100644 --- a/scripts/validate-skills.py +++ b/scripts/validate-skills.py @@ -59,7 +59,19 @@ def parse_frontmatter(text: str, where: str) -> dict[str, str] | None: continue key, _, value = raw.partition(":") key = key.strip() - fields[key] = value.strip().strip("\"'") + value = value.strip() + if value in {">", ">-", "|", "|-"}: + fields[key] = "" + else: + if ( + not value.startswith(("\"", "'")) + and re.search(r":(?:[ \t]|$)", value) + ): + errors.append( + f"{where}: unquoted YAML value for {key!r} contains ': ' — " + "quote it or use a folded block" + ) + fields[key] = value.strip("\"'") return fields diff --git a/skills/cube-admin/SKILL.md b/skills/cube-admin/SKILL.md index 2bf9b0d..1dab079 100644 --- a/skills/cube-admin/SKILL.md +++ b/skills/cube-admin/SKILL.md @@ -1,6 +1,7 @@ --- name: cube-admin -description: Administer a Cube tenant — users, groups, user attributes, access policies, tenant settings, API keys, SCIM provisioning and OIDC — using the Cube CLI. Use whenever someone wants to manage who can access what: add or remove a user, create a group, grant or revoke access to a deployment or resource, set user attributes for row-level security, configure SSO, rotate an API key, or audit current permissions. Triggers on "add someone to", "give access to", "who can see", "remove this user", "set up SSO", "create an API key", "what are this user's permissions", "audit access". To manage deployments themselves use cube-deploy; for embedded end-user access use cube-embed. +description: >- + Administer a Cube tenant — users, groups, user attributes, access policies, tenant settings, API keys, SCIM provisioning and OIDC — using the Cube CLI. Use whenever someone wants to manage who can access what: add or remove a user, create a group, grant or revoke access to a deployment or resource, set user attributes for row-level security, configure SSO, rotate an API key, or audit current permissions. Triggers on "add someone to", "give access to", "who can see", "remove this user", "set up SSO", "create an API key", "what are this user's permissions", "audit access". To manage deployments themselves use cube-deploy; for embedded end-user access use cube-embed. license: Apache-2.0 --- @@ -23,11 +24,11 @@ Access questions are answered by reading, and most requests are questions even when phrased as instructions. Establish the current state first: ```bash -cube users list +cube users list cube users me -cube groups list -cube policies get ... -cube attributes list +cube groups list +cube policies get --resource-type --resource-id +cube attributes list ``` Report what you find before changing it. "Alice is already in the analysts @@ -36,20 +37,20 @@ group" resolves a lot of requests without a write. ## Users and groups ```bash -cube users create ... -cube users update ... -cube users delete +cube users create --data '' +cube users update --data '' +cube users delete -cube groups list -cube groups delete +cube groups list +cube groups delete ``` ## Access policies ```bash -cube policies get ... -cube policies set-user ... -cube policies set-group ... +cube policies get --resource-type --resource-id +cube policies set-user --resource-type --resource-id ... +cube policies set-group --resource-type --resource-id --group ... ``` Prefer `set-group` over `set-user`. Per-user grants are invisible at review @@ -60,10 +61,10 @@ them. If a request is "give Alice access to X", the better answer is usually ## User attributes and row-level security ```bash -cube attributes list -cube attributes create ... -cube attributes values get ... -cube attributes values set ... +cube attributes list +cube attributes create --name --type ... +cube attributes values get +cube attributes values set --user --attribute ``` Attributes feed the security context, which is what row-level security in the @@ -92,7 +93,7 @@ config and state what will change before touching either. To answer "who can see X", combine: 1. `cube policies get` for the resource. -2. `cube groups list` and group membership for who that resolves to. +2. `cube groups list` and the user records for who that resolves to. 3. `cube attributes values get` for any row-level filtering on top. An access answer that skips step 3 is incomplete — two users with identical @@ -113,3 +114,5 @@ policies can see different rows. | User not found | Often the wrong tenant; check `cube context list` | | Policy set but access unchanged | Group membership or an attribute is overriding it — audit all three layers | | SCIM write rejected | Provisioning is managed by the IdP; changes belong there, not here | +| API keys returns the web app instead of JSON | That endpoint is unavailable on this tenant, often because the server is older — report it as unavailable, not as an empty list | +| OIDC returns `not available` | OIDC is disabled or unsupported on this tenant — do not treat the 404 as an empty configuration | diff --git a/skills/cube-build-content/SKILL.md b/skills/cube-build-content/SKILL.md index 87af3e4..c5afec1 100644 --- a/skills/cube-build-content/SKILL.md +++ b/skills/cube-build-content/SKILL.md @@ -1,6 +1,7 @@ --- name: cube-build-content -description: Create and update saved content in Cube — workbooks, reports, dashboards, folders and scheduled notifications — using the Cube CLI. Use whenever someone wants to build or change something people will look at: make a dashboard, save a query as a report, add a chart, organize content into folders, publish a workbook, or schedule a report to go out on a cadence. Triggers on "build me a dashboard", "save this as a report", "add a chart for", "publish this workbook", "schedule this weekly", "move these into a folder", "duplicate that dashboard". To find existing content first use cube-explore-content; to check a query returns the right numbers before saving it use cube-run-query. +description: >- + Create and update saved content in Cube — workbooks, reports, dashboards, folders and scheduled notifications — using the Cube CLI. Use whenever someone wants to build or change something people will look at: make a dashboard, save a query as a report, add a chart, organize content into folders, publish a workbook, or schedule a report to go out on a cadence. Triggers on "build me a dashboard", "save this as a report", "add a chart for", "publish this workbook", "schedule this weekly", "move these into a folder", "duplicate that dashboard". To find existing content first use cube-explore-content; to check a query returns the right numbers before saving it use cube-run-query. license: Apache-2.0 --- @@ -35,6 +36,7 @@ Content hangs off a workbook, so build outward from one: cube workbooks create --name "Revenue review" cube workbooks update --name "Revenue review Q3" cube workbooks duplicate +cube workbooks dashboard --data '' cube workbooks publish # makes the dashboard cube workbooks delete ``` @@ -46,9 +48,8 @@ uses. ## Reports ```bash -cube reports create --name "Revenue by month" --json-query '' +cube reports create --workbook --name "Revenue by month" --json-query '' cube reports update --json-query '' -cube reports connect-workbook cube reports refresh cube reports delete ``` @@ -61,6 +62,13 @@ missing. Complex bodies go through `-d/--data`, which accepts inline JSON, `@file.json` or `-` for stdin. Dedicated flags override values in `--data`. +`cube reports connect-workbook` is for placing a report in an external +spreadsheet, not attaching it to a Cube workbook. For that workflow use: + +```bash +cube reports connect-workbook --external-workbook-id --result-location +``` + ## Folders ```bash diff --git a/skills/cube-build-model/SKILL.md b/skills/cube-build-model/SKILL.md index 1f6fbd5..805fe9d 100644 --- a/skills/cube-build-model/SKILL.md +++ b/skills/cube-build-model/SKILL.md @@ -94,7 +94,7 @@ perfectly. When the user has the project on disk rather than wanting file-by-file edits: ```bash -cube deploy # uploads the local directory to the deployment and builds +cube deploy # uploads the local directory to the deployment and builds ``` This is a different workflow from the dev-mode one above — it replaces the diff --git a/skills/cube-configure-agent/SKILL.md b/skills/cube-configure-agent/SKILL.md index 0a1ac5b..a694c30 100644 --- a/skills/cube-configure-agent/SKILL.md +++ b/skills/cube-configure-agent/SKILL.md @@ -1,6 +1,7 @@ --- name: cube-configure-agent -description: Inspect and tune Cube's in-product AI agent — its rules, certified queries and Agent Skills — by authoring markdown in the semantic model with the Cube CLI. Use whenever someone wants the Cube agent to answer better: teach it a business definition, stop it making a recurring mistake, certify a trusted query, capture a repeatable workflow as a skill, or find out why it answered the way it did. Triggers on "the agent keeps getting X wrong", "teach the agent that", "make the agent always", "add a certified query", "create an agent skill", "why did the agent say that", "what rules does the agent have". To change the underlying model use cube-build-model; to explore what is queryable use cube-explore-model. +description: >- + Inspect and tune Cube's in-product AI agent — its rules, certified queries and Agent Skills — by authoring markdown in the semantic model with the Cube CLI. Use whenever someone wants the Cube agent to answer better: teach it a business definition, stop it making a recurring mistake, certify a trusted query, capture a repeatable workflow as a skill, or find out why it answered the way it did. Triggers on "the agent keeps getting X wrong", "teach the agent that", "make the agent always", "add a certified query", "create an agent skill", "why did the agent say that", "what rules does the agent have". To change the underlying model use cube-build-model; to explore what is queryable use cube-explore-model. license: Apache-2.0 --- diff --git a/skills/cube-deploy/SKILL.md b/skills/cube-deploy/SKILL.md index 4fd99eb..cb483e4 100644 --- a/skills/cube-deploy/SKILL.md +++ b/skills/cube-deploy/SKILL.md @@ -22,29 +22,29 @@ cube context list ```bash cube deployments list cube deployments get -cube deployments create --bootstrap ... # scaffolds and builds a serving deployment +cube deployments create ... # scaffolds and builds a serving deployment cube deployments update ... cube deployments delete -cube regions list +cube regions ``` -`--bootstrap` does the whole first-run path — scaffold, then build. Without -it you get an empty deployment you then have to populate. +Deployment creation always scaffolds the project and runs the first build. +There is no separate bootstrap step. ## Shipping code Two different routes, and they do not mix: ```bash -cube deploy # upload the local project directory and build -cube github connect ... # link a repo; Cube builds from git +cube deploy # upload the local project directory and build +cube github connect --installation # link git and build ``` ```bash cube github status cube github installations -cube github repos -cube github branches +cube github repos +cube github branches --installation ``` `cube deploy` pushes what is on your disk. `cube github connect` makes git the @@ -67,15 +67,21 @@ anyone it shipped. ```bash cube environments list -cube environments tokens -cube environments create-token --meta-sync +cube environments tokens +cube environments create-token --security-context '' +cube environments create-token --security-context '{}' --meta-sync cube variables list cube variables set KEY=VALUE ``` -`cube variables set` upserts. Read the current value first and say what it -was — a silently overwritten database URL is hard to trace back later. +`create-token` prints a credential. Never echo it back, write it to the +repository, or include it in a transcript; report only that it was created, +for which environment, and when it expires. + +`cube variables set` upserts. Run `variables list` first and say whether the +key already exists. Secret values are masked, so never claim to know or print +the old value — a silently overwritten database URL is hard to trace later. Never print secret values into a transcript. Confirm that a variable was set without echoing what it was set to. @@ -93,7 +99,7 @@ failed, `build-status` carries the error and is the better starting point. ## Debugging a failed deployment -1. `cube deployments build-status --branch ` — read the error verbatim. +1. `cube deployments build-status --branch ` — read the error verbatim. 2. If it is a model error, hand to `cube-build-model`; that is where the fix goes. 3. If the build passed but queries fail, check `cube variables list` for diff --git a/skills/cube-embed/SKILL.md b/skills/cube-embed/SKILL.md index cf2af1d..9020e04 100644 --- a/skills/cube-embed/SKILL.md +++ b/skills/cube-embed/SKILL.md @@ -1,6 +1,7 @@ --- name: cube-embed -description: Set up and debug Cube embedded analytics — embed sessions, embed tokens, embeddable dashboards and embed tenants — using the Cube CLI. Use whenever someone is shipping Cube analytics inside their own product: mint a session for an end user, enable a dashboard for embedding, set up multi-tenant isolation so each customer sees only their data, or debug why an embedded view is empty or unauthorized. Triggers on "embed this dashboard", "embedded analytics", "our customers need to see", "multi-tenant analytics", "the iframe is blank", "embed token", "sign the embed URL", "customer-facing dashboard". For internal access control use cube-admin; for the dashboards themselves use cube-build-content. +description: >- + Set up and debug Cube embedded analytics — embed sessions, embed tokens, embeddable dashboards and embed tenants — using the Cube CLI. Use whenever someone is shipping Cube analytics inside their own product: mint a session for an end user, enable a dashboard for embedding, set up multi-tenant isolation so each customer sees only their data, or debug why an embedded view is empty or unauthorized. Triggers on "embed this dashboard", "embedded analytics", "our customers need to see", "multi-tenant analytics", "the iframe is blank", "embed token", "sign the embed URL", "customer-facing dashboard". For internal access control use cube-admin; for the dashboards themselves use cube-build-content. license: Apache-2.0 --- @@ -38,16 +39,16 @@ about. ## Commands ```bash -cube embed generate-session ... -cube embed token ... +cube embed generate-session --data '' +cube embed token --session-id -cube embed enable-dashboard -cube embed dashboard -cube embed disable-dashboard +cube embed enable-dashboard +cube embed dashboard +cube embed disable-dashboard -cube embed tenant groups ... -cube embed tenant delete ... -cube embed tenant delete-group ... +cube embed tenant groups +cube embed tenant delete +cube embed tenant delete-group ``` Sessions and tokens are minted server-side. They must never be generated in @@ -57,7 +58,8 @@ user's access until it expires. ## Setting up a new embedded dashboard 1. Build and publish the dashboard (`cube-build-content`). -2. `cube embed enable-dashboard` — until this runs, embedding it fails. +2. Get the dashboard's public id, then run `cube embed enable-dashboard` — + until this runs, embedding it fails. 3. Confirm the model has row-level security keyed on the attribute your security context carries. Check with `cube-explore-model`; if it does not, stop and fix the model first. diff --git a/skills/cube-explore-content/SKILL.md b/skills/cube-explore-content/SKILL.md index d88106a..9920f35 100644 --- a/skills/cube-explore-content/SKILL.md +++ b/skills/cube-explore-content/SKILL.md @@ -1,6 +1,7 @@ --- name: cube-explore-content -description: Find and inspect saved content in a Cube workspace — workbooks, dashboards, reports, folders and scheduled notifications — using the Cube CLI. Use whenever someone wants to know what already exists rather than build something new: locate a dashboard, list reports, see what a report queries, find who a notification goes to, or check what saved content references a model field before renaming it. Triggers on "what dashboards do we have", "find the revenue report", "where is that workbook", "what's in this folder", "who gets this scheduled report", "is anything using this field". To create or edit content use cube-build-content; to inspect the semantic model itself use cube-explore-model. +description: >- + Find and inspect saved content in a Cube workspace — workbooks, dashboards, reports, folders and scheduled notifications — using the Cube CLI. Use whenever someone wants to know what already exists rather than build something new: locate a dashboard, list reports, see what a report queries, find who a notification goes to, or check what saved content references a model field before renaming it. Triggers on "what dashboards do we have", "find the revenue report", "where is that workbook", "what's in this folder", "who gets this scheduled report", "is anything using this field". To create or edit content use cube-build-content; to inspect the semantic model itself use cube-explore-model. license: Apache-2.0 --- @@ -43,15 +44,17 @@ cube folders ancestors # where a folder sits in the tree ```bash cube workbooks list -cube workbooks get -cube workbooks dashboard # the published dashboard -cube workbooks ai-thread # the agent conversation behind it +cube workbooks get # includes draft and published dashboards cube reports list cube reports get # includes the saved query -cube reports folders +cube reports folders # folders that contain reports ``` +Despite their names, `cube workbooks dashboard` updates a dashboard draft and +`cube workbooks ai-thread` attaches a thread to a published dashboard. They +are writes owned by `cube-build-content`, not inspection commands. + `cube reports get` is the one that answers "what does this actually show" — it returns the saved query, so you can name the measures and dimensions rather than describing the chart.