datajunction 0.0.76__tar.gz → 0.0.78__tar.gz
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.
- {datajunction-0.0.76 → datajunction-0.0.78}/PKG-INFO +1 -1
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/__about__.py +1 -1
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/cli.py +49 -8
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/mcp/server.py +124 -24
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/mcp/tools.py +257 -30
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/skills/datajunction.md +103 -116
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/mcp/test_server_tools.py +133 -9
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/mcp/test_tools.py +817 -13
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test_cli.py +143 -5
- {datajunction-0.0.76 → datajunction-0.0.78}/.coveragerc +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/.gitignore +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/.isort.cfg +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/.pre-commit-config.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/LICENSE.txt +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/Makefile +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/README.md +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/claude_desktop_config.example.json +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/__init__.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/_base.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/_internal.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/admin.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/builder.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/client.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/compile.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/deployment.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/exceptions.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/mcp/__init__.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/mcp/cli.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/mcp/config.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/mcp/formatters.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/models.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/nodes.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/init_system_nodes.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/date.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/dimension_link.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/is_active.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/materialization.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/node_type.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/node_without_description.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/nodes.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/number_of_materializations.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/number_of_nodes.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/seed/nodes/user.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/datajunction/tags.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/pyproject.toml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/setup.cfg +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/__init__.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/conftest.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/deploy0/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/deploy0/roads/companies.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/deploy0/roads/companies_dim.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/deploy0/roads/contractor.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/deploy0/roads/contractors.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/deploy0/roads/us_state.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/deploy0/roads/us_states.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/avg_length_of_employment.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/avg_repair_price.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/avg_time_to_dispatch.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/date.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/date_dim.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/dispatcher.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/dispatchers.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/hard_hat.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/hard_hat_state.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/hard_hats.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/local_hard_hats.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/municipality.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/municipality_dim.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/municipality_municipality_type.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/municipality_type.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/national_level_agg.transform.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/num_repair_orders.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/regional_level_agg.transform.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/regional_repair_efficiency.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/repair_order.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/repair_order_details.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/repair_order_transform.transform.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/repair_orders.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/repair_orders_cube.cube.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/repair_type.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/total_repair_cost.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/total_repair_order_discounts.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/us_region.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/us_state.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project1/roads/us_states.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project10/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/avg_length_of_employment.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/avg_repair_price.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/avg_time_to_dispatch.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/contractor.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/contractors.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/date.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/date_dim.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/dispatcher.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/dispatchers.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/hard_hat.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/hard_hat_state.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/hard_hats.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/local_hard_hats.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/municipality.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/municipality_dim.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/municipality_municipality_type.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/municipality_type.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/national_level_agg.transform.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/num_repair_orders.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/regional_level_agg.transform.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/regional_repair_efficiency.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/repair_order.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/repair_order_details.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/repair_order_transform.transform.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/repair_orders.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/repair_orders_cube.cube.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/repair_type.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/total_repair_cost.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/total_repair_order_discounts.metric.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/us_region.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/us_state.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project11/us_states.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project12/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project12/roads/companies.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project12/roads/companies_dim.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project12/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project12/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project12/roads/us_state.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project12/roads/us_states.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project2/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project2/some_node.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project3/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project3/some_node.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project4/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project4/very/very/deeply/nested/namespace/some_node.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project5/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project5/some_node.a.b.c.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project6/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project6/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project6/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project7/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project7/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project7/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project8/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project9/dj.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project9/roads/companies.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project9/roads/companies_dim.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project9/roads/contractor.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project9/roads/contractors.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project9/roads/us_state.dimension.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples/project9/roads/us_states.source.yaml +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/examples.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/mcp/README.md +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/mcp/__init__.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/mcp/test_cli.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/mcp/test_formatters.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/mcp/test_visualize_metrics.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test__internal.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test_admin.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test_base.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test_builder.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test_client.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test_compile.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test_deploy.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test_generated_client.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test_integration.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tests/test_models.py +0 -0
- {datajunction-0.0.76 → datajunction-0.0.78}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datajunction
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.78
|
|
4
4
|
Summary: DataJunction client library for connecting to a DataJunction server
|
|
5
5
|
Project-URL: repository, https://github.com/DataJunction/dj
|
|
6
6
|
Author-email: DataJunction Authors <yian.shang@gmail.com>
|
|
@@ -1266,6 +1266,18 @@ class DJCLI:
|
|
|
1266
1266
|
dest="mcp",
|
|
1267
1267
|
help="Skip MCP server configuration",
|
|
1268
1268
|
)
|
|
1269
|
+
setup_claude_parser.add_argument(
|
|
1270
|
+
"--agents",
|
|
1271
|
+
action="store_true",
|
|
1272
|
+
default=True,
|
|
1273
|
+
help="Install DJ subagent to ~/.claude/agents/ (default: True)",
|
|
1274
|
+
)
|
|
1275
|
+
setup_claude_parser.add_argument(
|
|
1276
|
+
"--no-agents",
|
|
1277
|
+
action="store_false",
|
|
1278
|
+
dest="agents",
|
|
1279
|
+
help="Skip subagent installation",
|
|
1280
|
+
)
|
|
1269
1281
|
|
|
1270
1282
|
return parser
|
|
1271
1283
|
|
|
@@ -1356,6 +1368,7 @@ class DJCLI:
|
|
|
1356
1368
|
output_dir=Path(args.output),
|
|
1357
1369
|
skills=args.skills,
|
|
1358
1370
|
mcp=args.mcp,
|
|
1371
|
+
agents=args.agents,
|
|
1359
1372
|
)
|
|
1360
1373
|
else:
|
|
1361
1374
|
parser.print_help() # pragma: no cover
|
|
@@ -1377,6 +1390,7 @@ class DJCLI:
|
|
|
1377
1390
|
output_dir: Path,
|
|
1378
1391
|
skills: bool = True,
|
|
1379
1392
|
mcp: bool = True,
|
|
1393
|
+
agents: bool = True,
|
|
1380
1394
|
):
|
|
1381
1395
|
"""Configure Claude Code integration with DJ."""
|
|
1382
1396
|
import json
|
|
@@ -1464,23 +1478,50 @@ class DJCLI:
|
|
|
1464
1478
|
"[red]✗ Bundled skill not found. Please ensure datajunction is properly installed.[/red]",
|
|
1465
1479
|
)
|
|
1466
1480
|
|
|
1481
|
+
# Install subagent if requested
|
|
1482
|
+
if agents:
|
|
1483
|
+
agents_dir = Path.home() / ".claude" / "agents"
|
|
1484
|
+
agents_dir.mkdir(parents=True, exist_ok=True)
|
|
1485
|
+
agent_file = agents_dir / "dj.md"
|
|
1486
|
+
|
|
1487
|
+
console.print("[bold]🤖 Installing DJ subagent[/bold]\n")
|
|
1488
|
+
|
|
1489
|
+
subagent_content = """\
|
|
1490
|
+
---
|
|
1491
|
+
name: dj
|
|
1492
|
+
description: >
|
|
1493
|
+
DataJunction semantic layer expert. Use proactively for any DataJunction
|
|
1494
|
+
or DJ work — querying metrics, exploring nodes and dimensions, building
|
|
1495
|
+
SQL, understanding lineage, and semantic layer design.
|
|
1496
|
+
skills:
|
|
1497
|
+
- datajunction
|
|
1498
|
+
model: inherit
|
|
1499
|
+
---
|
|
1500
|
+
"""
|
|
1501
|
+
with open(agent_file, "w") as f:
|
|
1502
|
+
f.write(subagent_content)
|
|
1503
|
+
|
|
1504
|
+
console.print(f"[green]✓ Installed subagent to {agent_file}[/green]\n")
|
|
1505
|
+
|
|
1467
1506
|
# Setup MCP if requested
|
|
1468
1507
|
if mcp:
|
|
1469
1508
|
self._setup_mcp_server(console)
|
|
1470
1509
|
|
|
1471
1510
|
# Final success message
|
|
1472
|
-
|
|
1511
|
+
anything_installed = skills or mcp or agents
|
|
1512
|
+
if anything_installed: # pragma: no branch
|
|
1473
1513
|
console.print(
|
|
1474
1514
|
"\n[bold green]✓ Claude Code integration complete[/bold green]",
|
|
1475
1515
|
)
|
|
1516
|
+
parts = []
|
|
1517
|
+
if skills:
|
|
1518
|
+
parts.append("skill")
|
|
1519
|
+
if agents:
|
|
1520
|
+
parts.append("subagent")
|
|
1521
|
+
if mcp:
|
|
1522
|
+
parts.append("MCP server")
|
|
1476
1523
|
console.print(
|
|
1477
|
-
"[dim]
|
|
1478
|
-
)
|
|
1479
|
-
elif skills:
|
|
1480
|
-
console.print("\n[dim]Skills are now available in Claude Code.[/dim]")
|
|
1481
|
-
elif mcp: # pragma: no branch
|
|
1482
|
-
console.print(
|
|
1483
|
-
"\n[dim]MCP server configured. Restart Claude Code to load changes.[/dim]",
|
|
1524
|
+
f"[dim]{', '.join(parts).capitalize()} installed. Restart Claude Code to load changes.[/dim]",
|
|
1484
1525
|
)
|
|
1485
1526
|
|
|
1486
1527
|
except Exception as e: # pragma: no cover
|
|
@@ -42,38 +42,63 @@ async def list_tools() -> list[types.Tool]:
|
|
|
42
42
|
types.Tool(
|
|
43
43
|
name="search_nodes",
|
|
44
44
|
description=(
|
|
45
|
-
"Search for DataJunction nodes (metrics, dimensions, cubes, sources, transforms) "
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"TIP: Use
|
|
49
|
-
"
|
|
45
|
+
"Search for DataJunction nodes (metrics, dimensions, cubes, sources, transforms). "
|
|
46
|
+
"All filters are optional and combinable: name fragment, node type, namespace, tags, "
|
|
47
|
+
"status (valid/invalid), mode (published/draft), owner, and materialization. "
|
|
48
|
+
"TIP: Use 'namespace' to narrow searches to a domain. "
|
|
49
|
+
"Use 'statuses: [invalid]' to find broken nodes. "
|
|
50
|
+
"Use 'mode: draft' to see in-progress work on a branch. "
|
|
51
|
+
"Use 'has_materialization: true' to find cubes with materializations."
|
|
50
52
|
),
|
|
51
53
|
inputSchema={
|
|
52
54
|
"type": "object",
|
|
53
55
|
"properties": {
|
|
54
56
|
"query": {
|
|
55
57
|
"type": "string",
|
|
56
|
-
"description": "
|
|
58
|
+
"description": "Optional: Fragment of node name to search for (e.g., 'revenue', 'user'). Can be omitted when filtering by tag.",
|
|
57
59
|
},
|
|
58
60
|
"node_type": {
|
|
59
61
|
"type": "string",
|
|
60
62
|
"enum": ["metric", "dimension", "cube", "source", "transform"],
|
|
61
|
-
"description": "Optional: Filter results to specific node type",
|
|
63
|
+
"description": "Optional: Filter results to a specific node type",
|
|
62
64
|
},
|
|
63
65
|
"namespace": {
|
|
64
66
|
"type": "string",
|
|
65
67
|
"description": (
|
|
66
|
-
"Optional: Filter results to specific namespace (e.g., 'demo.metrics', 'common.dimensions'). "
|
|
67
|
-
"HIGHLY RECOMMENDED - namespaces are the primary way to organize nodes in DJ.
|
|
68
|
-
"Use this to narrow search results to a specific domain or area."
|
|
68
|
+
"Optional: Filter results to a specific namespace (e.g., 'demo.metrics', 'common.dimensions'). "
|
|
69
|
+
"HIGHLY RECOMMENDED - namespaces are the primary way to organize nodes in DJ."
|
|
69
70
|
),
|
|
70
71
|
},
|
|
72
|
+
"tags": {
|
|
73
|
+
"type": "array",
|
|
74
|
+
"items": {"type": "string"},
|
|
75
|
+
"description": "Optional: Filter to nodes tagged with ALL of these tag names (e.g., ['revenue', 'core'])",
|
|
76
|
+
},
|
|
77
|
+
"statuses": {
|
|
78
|
+
"type": "array",
|
|
79
|
+
"items": {"type": "string", "enum": ["valid", "invalid"]},
|
|
80
|
+
"description": "Optional: Filter by node status (e.g., ['valid'] for healthy nodes, ['invalid'] to find broken ones)",
|
|
81
|
+
},
|
|
82
|
+
"mode": {
|
|
83
|
+
"type": "string",
|
|
84
|
+
"enum": ["published", "draft"],
|
|
85
|
+
"description": "Optional: Filter by mode — 'published' for production nodes, 'draft' for in-progress work on a branch",
|
|
86
|
+
},
|
|
87
|
+
"owned_by": {
|
|
88
|
+
"type": "string",
|
|
89
|
+
"description": "Optional: Filter to nodes owned by this username or email",
|
|
90
|
+
},
|
|
91
|
+
"has_materialization": {
|
|
92
|
+
"type": "boolean",
|
|
93
|
+
"default": False,
|
|
94
|
+
"description": "Optional: If true, return only nodes that have materializations configured",
|
|
95
|
+
},
|
|
71
96
|
"limit": {
|
|
72
97
|
"type": "integer",
|
|
73
98
|
"default": 100,
|
|
74
99
|
"minimum": 1,
|
|
75
100
|
"maximum": 1000,
|
|
76
|
-
"description": "Maximum number of results to return (default: 100
|
|
101
|
+
"description": "Maximum number of results to return (default: 100)",
|
|
77
102
|
},
|
|
78
103
|
"prefer_main_branch": {
|
|
79
104
|
"type": "boolean",
|
|
@@ -81,11 +106,9 @@ async def list_tools() -> list[types.Tool]:
|
|
|
81
106
|
"description": (
|
|
82
107
|
"When true and namespace is provided, automatically searches the .main branch "
|
|
83
108
|
"(e.g., 'finance' becomes 'finance.main'). Set to false to search all branches."
|
|
84
|
-
"Default: true."
|
|
85
109
|
),
|
|
86
110
|
},
|
|
87
111
|
},
|
|
88
|
-
"required": ["query"],
|
|
89
112
|
},
|
|
90
113
|
),
|
|
91
114
|
types.Tool(
|
|
@@ -107,22 +130,27 @@ async def list_tools() -> list[types.Tool]:
|
|
|
107
130
|
},
|
|
108
131
|
),
|
|
109
132
|
types.Tool(
|
|
110
|
-
name="
|
|
133
|
+
name="get_common",
|
|
111
134
|
description=(
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
"
|
|
135
|
+
"Bidirectional semantic compatibility lookup. "
|
|
136
|
+
"Pass 'metrics' to find which dimensions are shared across all those metrics (i.e. what can I slice these metrics by?). "
|
|
137
|
+
"Pass 'dimensions' to find which metrics can be queried by all those dimensions (i.e. what can I analyze by this dimension?). "
|
|
138
|
+
"Provide exactly one of metrics or dimensions."
|
|
115
139
|
),
|
|
116
140
|
inputSchema={
|
|
117
141
|
"type": "object",
|
|
118
142
|
"properties": {
|
|
119
|
-
"
|
|
143
|
+
"metrics": {
|
|
144
|
+
"type": "array",
|
|
145
|
+
"items": {"type": "string"},
|
|
146
|
+
"description": "List of metric node names — returns the dimensions common across all of them",
|
|
147
|
+
},
|
|
148
|
+
"dimensions": {
|
|
120
149
|
"type": "array",
|
|
121
150
|
"items": {"type": "string"},
|
|
122
|
-
"description": "List of
|
|
151
|
+
"description": "List of dimension attribute names — returns metrics compatible with all of them",
|
|
123
152
|
},
|
|
124
153
|
},
|
|
125
|
-
"required": ["metric_names"],
|
|
126
154
|
},
|
|
127
155
|
),
|
|
128
156
|
types.Tool(
|
|
@@ -264,6 +292,58 @@ async def list_tools() -> list[types.Tool]:
|
|
|
264
292
|
"required": ["node_name"],
|
|
265
293
|
},
|
|
266
294
|
),
|
|
295
|
+
types.Tool(
|
|
296
|
+
name="get_query_plan",
|
|
297
|
+
description=(
|
|
298
|
+
"Get the query execution plan for a set of metrics, showing how DJ decomposes them "
|
|
299
|
+
"into grain groups and atomic aggregation components. "
|
|
300
|
+
"A grain group is a set of metrics that share a common dimensional grain and can be "
|
|
301
|
+
"computed together in a single SQL query. "
|
|
302
|
+
"Each component is an atomic aggregation (e.g., SUM(amount), COUNT(*)) that feeds "
|
|
303
|
+
"into the final metric formula. "
|
|
304
|
+
"Use this to understand multi-metric query structure, debug unexpected results, "
|
|
305
|
+
"validate semantic model design, or explain how a metric is computed."
|
|
306
|
+
),
|
|
307
|
+
inputSchema={
|
|
308
|
+
"type": "object",
|
|
309
|
+
"properties": {
|
|
310
|
+
"metrics": {
|
|
311
|
+
"type": "array",
|
|
312
|
+
"items": {"type": "string"},
|
|
313
|
+
"description": "List of metric node names to analyze (e.g., ['finance.daily_revenue', 'growth.new_users'])",
|
|
314
|
+
},
|
|
315
|
+
"dimensions": {
|
|
316
|
+
"type": "array",
|
|
317
|
+
"items": {"type": "string"},
|
|
318
|
+
"description": "Optional: List of dimensions to group by — affects grain group assignment",
|
|
319
|
+
},
|
|
320
|
+
"filters": {
|
|
321
|
+
"type": "array",
|
|
322
|
+
"items": {"type": "string"},
|
|
323
|
+
"description": "Optional: SQL filter conditions",
|
|
324
|
+
},
|
|
325
|
+
"dialect": {
|
|
326
|
+
"type": "string",
|
|
327
|
+
"description": "Optional: Target SQL dialect (e.g., 'spark', 'trino', 'postgres')",
|
|
328
|
+
},
|
|
329
|
+
"use_materialized": {
|
|
330
|
+
"type": "boolean",
|
|
331
|
+
"default": True,
|
|
332
|
+
"description": "Optional: Whether to use materialized tables when available (default: true)",
|
|
333
|
+
},
|
|
334
|
+
"include_temporal_filters": {
|
|
335
|
+
"type": "boolean",
|
|
336
|
+
"default": False,
|
|
337
|
+
"description": "Optional: Include temporal partition filters if the metrics resolve to a cube with partitions",
|
|
338
|
+
},
|
|
339
|
+
"lookback_window": {
|
|
340
|
+
"type": "string",
|
|
341
|
+
"description": "Optional: Lookback window for temporal filters (e.g., '3 DAY', '1 WEEK'). Only used when include_temporal_filters is true.",
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
"required": ["metrics"],
|
|
345
|
+
},
|
|
346
|
+
),
|
|
267
347
|
types.Tool(
|
|
268
348
|
name="visualize_metrics",
|
|
269
349
|
description=(
|
|
@@ -350,9 +430,14 @@ async def call_tool(name: str, arguments: dict) -> list[types.TextContent]:
|
|
|
350
430
|
|
|
351
431
|
elif name == "search_nodes":
|
|
352
432
|
result = await tools.search_nodes(
|
|
353
|
-
query=arguments
|
|
433
|
+
query=arguments.get("query", ""),
|
|
354
434
|
node_type=arguments.get("node_type"),
|
|
355
435
|
namespace=arguments.get("namespace"),
|
|
436
|
+
tags=arguments.get("tags"),
|
|
437
|
+
statuses=arguments.get("statuses"),
|
|
438
|
+
mode=arguments.get("mode"),
|
|
439
|
+
owned_by=arguments.get("owned_by"),
|
|
440
|
+
has_materialization=arguments.get("has_materialization", False),
|
|
356
441
|
limit=arguments.get("limit", 100),
|
|
357
442
|
prefer_main_branch=arguments.get("prefer_main_branch", True),
|
|
358
443
|
)
|
|
@@ -362,9 +447,10 @@ async def call_tool(name: str, arguments: dict) -> list[types.TextContent]:
|
|
|
362
447
|
name=arguments["name"],
|
|
363
448
|
)
|
|
364
449
|
|
|
365
|
-
elif name == "
|
|
366
|
-
result = await tools.
|
|
367
|
-
|
|
450
|
+
elif name == "get_common":
|
|
451
|
+
result = await tools.get_common(
|
|
452
|
+
metrics=arguments.get("metrics"),
|
|
453
|
+
dimensions=arguments.get("dimensions"),
|
|
368
454
|
)
|
|
369
455
|
|
|
370
456
|
elif name == "build_metric_sql":
|
|
@@ -387,6 +473,20 @@ async def call_tool(name: str, arguments: dict) -> list[types.TextContent]:
|
|
|
387
473
|
limit=arguments.get("limit"),
|
|
388
474
|
)
|
|
389
475
|
|
|
476
|
+
elif name == "get_query_plan":
|
|
477
|
+
result = await tools.get_query_plan(
|
|
478
|
+
metrics=arguments["metrics"],
|
|
479
|
+
dimensions=arguments.get("dimensions"),
|
|
480
|
+
filters=arguments.get("filters"),
|
|
481
|
+
dialect=arguments.get("dialect"),
|
|
482
|
+
use_materialized=arguments.get("use_materialized", True),
|
|
483
|
+
include_temporal_filters=arguments.get(
|
|
484
|
+
"include_temporal_filters",
|
|
485
|
+
False,
|
|
486
|
+
),
|
|
487
|
+
lookback_window=arguments.get("lookback_window"),
|
|
488
|
+
)
|
|
489
|
+
|
|
390
490
|
elif name == "get_node_lineage":
|
|
391
491
|
result = await tools.get_node_lineage(
|
|
392
492
|
node_name=arguments["node_name"],
|