@malloy-publisher/skills 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,8 +50,9 @@ skill points to for detail it does not inline. Start with `malloy-getting-starte
50
50
  A few skills (`malloy-modeling`, `malloy-publish`, `malloy-document`, `malloy-getting-started`, and
51
51
  the `malloy` index) are written for a Publisher host and name Publisher's `malloy_*` MCP tools
52
52
  directly. The rest describe Malloy itself and refer to tools by bare name (`get_context`,
53
- `execute_query`, `search_malloy_docs`), because the prefix depends on the host. On Publisher those
54
- are `malloy_getContext`, `malloy_executeQuery`, and `malloy_searchDocs`.
53
+ `execute_query`, `search_malloy_docs`), because the prefix depends on the
54
+ host. `search_database_schema` maps the same way if a shared skill starts using it. On Publisher those are `malloy_getContext`, `malloy_executeQuery`, `malloy_searchDocs`, and
55
+ `malloy_searchDatabaseSchema`.
55
56
 
56
57
  ## Versioning
57
58
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@malloy-publisher/skills",
3
3
  "description": "Agent skills for Malloy and the Malloy Publisher",
4
- "version": "0.1.3",
4
+ "version": "0.1.4",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -26,7 +26,8 @@
26
26
  ],
27
27
  "repository": {
28
28
  "type": "git",
29
- "url": "https://github.com/malloydata/publisher.git"
29
+ "url": "https://github.com/malloydata/publisher.git",
30
+ "directory": "packages/skills"
30
31
  },
31
32
  "publishConfig": {
32
33
  "access": "public"
@@ -43,6 +43,8 @@ The result is JSON. Charts and dashboards defined in the model render in the Pub
43
43
 
44
44
  Use `malloy_searchDocs` for language questions (filters, aggregates, joins, nesting, renderers).
45
45
 
46
+ If the data you want is in a connected database but not yet in any package, use `malloy_searchDatabaseSchema` instead of `malloy_getContext`: it walks a connection's schemas and tables and ranks them against a plain-English description, and hands back the `source:` line to start a model from. It returns names and types only, so to see what a column actually contains run `malloy_executeQuery` against a model in a package that uses the same connection, with an ad-hoc query like `run: my_conn.table('sales.orders') -> { group_by: order_status }`. That tool needs an existing model to run against, so a table you have not modelled yet has none of its own.
47
+
46
48
  ## 4. What else you can do here
47
49
 
48
50
  Answering questions is the start, not the whole surface. When the user asks what is possible, say so rather than offering queries alone. Switch skills for the deeper work:
@@ -293,7 +293,7 @@ source: orders is duckdb.table('orders.parquet') extend {
293
293
  ```
294
294
 
295
295
  - **Source-level** `#(authorize) "<expr>"` gates that one source. **File-level** `##(authorize) "<expr>"` applies to every source in the file. Multiple gates combine as an OR, access is granted if any one is true, so a permissive file-level gate is a **model-wide override**, not an added restriction.
296
- - **Not inherited, not joined.** The gate applies only to the source a query directly runs against. A source that `extend`s a locked base does **not** inherit the base's gate, and a gate on a source reached only via `join_*` never fires. Pair a locked base (`#(authorize) "false"`) with curated extension sources, using access modifiers (`include { public: …, private: * }`), so an extension re-exposes only a curated column surface instead of leaking the base's data through the join or extend.
296
+ - **Entry point only: not joined, but inherited through `extend`.** The gate applies to the source a query enters through. A gate on a source reached only via `join_*` **never fires**, at any depth, so anything ungated that joins a locked base hands the base's rows to every caller. A source that `extend`s a locked base and declares no gate of its own **does** carry the base's gate; declaring its own replaces it. Pair a locked base (`#(authorize) "false"`) with curated extension sources, using access modifiers (`include { public: …, private: * }`), so an extension re-exposes only a curated column surface, and keep sensitive sources out of ungated joins.
297
297
  - The expression may reference only givens and literals, never a column of the gated source; the check runs against a synthetic probe row, not your data.
298
298
 
299
299
  > **Trust caveat.** Givens are **caller-asserted**, anyone who can reach the query API can claim a favorable given, e.g. `{"ROLE":"admin"}`. `#(authorize)` is only a real boundary when it sits behind a trusted tier that sets givens from its own verified context, never directly from an untrusted caller. It is not, on its own, end-user authentication.
@@ -9,7 +9,10 @@ description: Build semantic models with Malloy for the Malloy Publisher. Read th
9
9
 
10
10
  ## Pre-Flight Checklist
11
11
 
12
- 1. **Discover first**: ground yourself with `malloy_getContext` before writing ANY code. It returns the package's sources, views, and fields (with their docs), so you build on what actually exists. Never guess field names.
12
+ 1. **Discover first**: ground yourself before writing ANY code, with the tool that matches what you are modelling.
13
+ - Modelling data **already in a package**: `malloy_getContext` returns that package's sources, views, and fields (with their docs).
14
+ - Modelling **a database with no package yet**: `malloy_getContext` has nothing to return, so use `malloy_searchDatabaseSchema` instead. It walks the connection's schemas and tables, ranks them against a plain-English description, and gives you each table's columns plus the `source:` line to start from. Take those names verbatim into step 5.
15
+ Never guess field names either way.
13
16
  2. **Search docs proactively**: call `malloy_searchDocs` BEFORE writing unfamiliar patterns (window functions, query-based sources, pipelines). Don't guess. Malloy syntax is specific and SQL intuition is often wrong.
14
17
  3. **Use `skill:malloy-patterns`** to discover available doc topics (YoY, cohorts, rendering, window functions).
15
18
  4. **Check diagnostics** after writing: fix the FIRST error first, errors cascade.
@@ -43,7 +46,7 @@ DISCOVER → SCOPE → SOURCES → DEFINITIONS → BUILD BASE → BUILD JOINED
43
46
 
44
47
  | Step | Skill | What Happens |
45
48
  |------|-------|-------------|
46
- | 1. Discover | `skill:malloy-discover` | Read the model and data; scan sources, fields, distributions; detect prior art |
49
+ | 1. Discover | `skill:malloy-discover` | Read the model and data; scan sources, fields, distributions; detect prior art. With no package yet, start from `malloy_searchDatabaseSchema` to find the tables in the connection |
47
50
  | 2. Propose Scope | `skill:malloy-scope` | Present findings, user selects focus |
48
51
  | 3. Propose Sources | `skill:malloy-define` | Propose source plan, user confirms architecture |
49
52
  | 4. Propose Definitions | `skill:malloy-define` | Propose fields per base source, user confirms logic |
@@ -102,6 +105,7 @@ Ensure the Publisher MCP tools are configured before modeling.
102
105
  | `malloy_compile` | Compile-check a change and get diagnostics back without running a query |
103
106
  | `malloy_reloadPackage` | Recompile a package from disk so a saved edit becomes queryable by name |
104
107
  | `malloy_searchDocs` | Search Malloy docs (call BEFORE unfamiliar patterns) |
108
+ | `malloy_searchDatabaseSchema` | Find the tables in a database connection by plain-English description, when modelling data that is not in a package yet. Returns each table's columns and the `source:` line to start from. Names and types only: no row value is returned |
105
109
 
106
110
  Never guess field names. Ground yourself with `malloy_getContext` to see the sources and fields a package defines.
107
111