← Dataiku HeadlessCONTENT HISTORY

Update to Dataiku Headless

Snapshot Nov 6, 2026 · 18:15 UTC · version 0.9.0

WHAT CHANGED

Package or technical metadata updated

Package or technical metadata updated

Observed in package metadata. These changes alone do not establish a new customer-facing feature.

Save Dataiku Headless and check future changes in Following.

Up to 3 plugins free · no card required.

All fields and original values.

These are saved file metadata. Open a changed file to read its text edits.

Package file

Before

Oct 24, 2026 · 13:55 UTC

Not present

After

Nov 6, 2026 · 18:15 UTC

{"sha256":"5a1a724844a602acdab8e4f6ffe307b0f7772af0b6c437d6425d8142d21b960a","size":659}

Package file

Before

Oct 24, 2026 · 13:55 UTC

df10462f2b84eab4a4a48d68b6cdeb80a402fda5fe985987292ab93635554e52

After

Nov 6, 2026 · 18:15 UTC

c142b21c6e1a8f24e5cf2dd6ce31c5c9441a58fe3a64d8f3d8efc6c2e10e7d5a

Package file

Before

Oct 24, 2026 · 13:55 UTC

556

After

Nov 6, 2026 · 18:15 UTC

603

Package file

Before

Oct 24, 2026 · 13:55 UTC

c6935b186ecc9648319eb1dafc96f223b41c556d445a54d8ec0c6ea9f360e9d9

After

Nov 6, 2026 · 18:15 UTC

932135fd42ae2b929c46b8ac93df3d2e2fb8b1d51a7a8a6057e1227edf2b5ead

Compare saved observations

Download comparison JSON

Changed files

Choose a file to see its text changes. Binary or large files show metadata only.

.agents/plugins/marketplace.json →

.claude-plugin/marketplace.json →

.claude-plugin/plugin.json →

.codex-plugin/mcp.json →

.codex-plugin/plugin.json →

.cortex-plugin/plugin.json →

.cursor-plugin/marketplace.json →

.cursor-plugin/plugin.json →

.github/plugin/marketplace.json →

.github/plugin/plugin.json →

.mcp.json →

AGENTS.md →

CHANGELOG.md →

CODING_STANDARDS_AND_STRUCTURE.md →

CONTRIBUTORS.md →

NOTICE →

README.md →

dataiku_mcp/config/stdio.py →

dataiku_mcp/instance_policy.py →

dataiku_mcp/server.py →

dataiku_mcp/setup_page.html →

dataiku_mcp/setup_server.py →

dataiku_mcp/tools/agent_reviews.py →

dataiku_mcp/tools/agents.py →

dataiku_mcp/tools/cobuild.py →

dataiku_mcp/tools/code_environments.py →

dataiku_mcp/tools/connections.py →

dataiku_mcp/tools/container_exec.py →

dataiku_mcp/tools/cross_project_sharing.py →

dataiku_mcp/tools/dashboards.py →

dataiku_mcp/tools/data_collections.py →

dataiku_mcp/tools/data_quality.py →

dataiku_mcp/tools/datasets.py →

dataiku_mcp/tools/evaluation_stores.py →

dataiku_mcp/tools/flow.py →

dataiku_mcp/tools/general_settings.py →

dataiku_mcp/tools/groups.py →

dataiku_mcp/tools/insights.py →

dataiku_mcp/tools/instances.py →

dataiku_mcp/tools/jobs.py →

dataiku_mcp/tools/licensing.py →

dataiku_mcp/tools/llms_and_knowledge_banks.py →

dataiku_mcp/tools/machine_learning/analyses.py →

dataiku_mcp/tools/machine_learning/saved_models.py →

dataiku_mcp/tools/managed_folders.py →

dataiku_mcp/tools/plugins.py →

dataiku_mcp/tools/project_folders.py →

dataiku_mcp/tools/project_libraries.py →

dataiku_mcp/tools/projects.py →

dataiku_mcp/tools/recipes.py →

dataiku_mcp/tools/scenarios.py →

dataiku_mcp/tools/semantic_models.py →

dataiku_mcp/tools/users.py →

dataiku_mcp/tools/utils/metrics.py →

dataiku_mcp/tools/utils/validation.py →

dataiku_mcp/tools/webapps.py →

dataiku_mcp/tools/wikis.py →

docs/capabilities.md →

docs/http-deployment.md →

pyproject.toml →

runtime/run_mcp.py →

runtime/run_mcp.py.lock →

scripts/build_http_plugin.py →

scripts/check_release.py →

scripts/http_plugin_assets/skills/dataiku-headless-setup/SKILL.md →

skills/dataiku-headless-setup/SKILL.md →

skills/dataiku-headless/SKILL.md →

skills/dataiku-headless/references/administration.md →

skills/dataiku-headless/references/administration/code-environments.md →

skills/dataiku-headless/references/administration/plugins.md →

skills/dataiku-headless/references/agents/agent-tools.md →

skills/dataiku-headless/references/cobuild.md →

skills/dataiku-headless/references/container-execution.md →

skills/dataiku-headless/references/dashboards.md →

skills/dataiku-headless/references/datasets.md →

skills/dataiku-headless/references/datasets/uploaded-files-datasets.md →

skills/dataiku-headless/references/insights.md →

skills/dataiku-headless/references/jobs.md →

skills/dataiku-headless/references/llms-and-knowledge-banks.md →

skills/dataiku-headless/references/managed_folders.md →

skills/dataiku-headless/references/migrations.md →

skills/dataiku-headless/references/migrations/sources/excel/guides/validate.md →

skills/dataiku-headless/references/plugin-development.md →

skills/dataiku-headless/references/plugin-development/agent-tools.md →

skills/dataiku-headless/references/plugin-development/agents.md →

skills/dataiku-headless/references/plugin-development/connectors.md →

skills/dataiku-headless/references/plugin-development/file-formats.md →

skills/dataiku-headless/references/plugin-development/guardrails.md →

skills/dataiku-headless/references/plugin-development/llms.md →

skills/dataiku-headless/references/plugin-development/machine-learning.md →

skills/dataiku-headless/references/plugin-development/macros.md →

skills/dataiku-headless/references/plugin-development/prepare-processors.md →

skills/dataiku-headless/references/plugin-development/recipes.md →

skills/dataiku-headless/references/plugin-development/settings-checks.md →

skills/dataiku-headless/references/plugin-development/structured-agent-blocks.md →

skills/dataiku-headless/references/plugin-development/webapps.md →

skills/dataiku-headless/references/project-libraries.md →

skills/dataiku-headless/references/projects.md →

skills/dataiku-headless/references/projects/settings.md →

skills/dataiku-headless/references/recipes.md →

skills/dataiku-headless/references/semantic-models.md →

tests/conftest.py →

tests/test_dataset_metrics.py →

tests/test_execution_tools.py →

tests/test_http_middleware.py →

tests/test_http_plugin_renderer.py →

tests/test_instance_pinning.py →

tests/test_instance_policy.py →

tests/test_instances.py →

tests/test_launcher_cli.py →

tests/test_onboarding_ui.py →

tests/test_plugin_futures.py →

tests/test_plugin_packaging.py →

tests/test_plugins.py →

tests/test_release.py →

tests/test_setup_server.py →

tests/test_tls_trust.py →

tests/test_tool_surface.py →

uv.lock →

tests/test_plugins.py

− removed · + added

--- before
+++ after
@@ -127,8 +127,22 @@
     def get_state(self):
         if self._pending:
             self.state = self._pending.pop(0)
+        self.read = True
         return self.state
 
+    def peek_state(self):
+        return self.peeked
+
+
+def _build_future(job_id, env_name, states):
+    """A plugin code-env build, whose peeked state names its target environment."""
+    future = FakeFuture(job_id, states)
+    future.peeked = {
+        "jobId": job_id,
+        "payload": {"action": "import_env", "displayName": f"Import env: {env_name}"},
+    }
+    return future
+
 
 class FakePluginSettings:
     def __init__(self, raw):
@@ -137,6 +151,12 @@
     def get_raw(self):
         return self.raw
 
+    def set_code_env(self, name):
+        self.raw["codeEnvName"] = name
+
+    def save(self):
+        self.saves = getattr(self, "saves", 0) + 1
+
 
 class FakeUsages:
     def __init__(self, raw):
@@ -171,11 +191,22 @@
         self.on_change()
         return self.futures["update"]
 
+    def update_from_git(self, repository_url, checkout, subpath):
+        self.git_update_args = (repository_url, checkout, subpath)
+        self.on_change()
+        return self.futures["update"]
+
     def start_update_from_zip(self, fp):
         self.uploaded = fp.read()
         self.on_change()
         return self.futures["update"]
 
+    def create_code_env(self, python_interpreter=None):
+        self.created_interpreter = python_interpreter
+        if getattr(self, "create_error", None):
+            raise self.create_error
+        return self.futures["create_code_env"]
+
     def update_code_env(self):
         return self.futures["update_code_env"]
 
@@ -187,7 +218,13 @@
 
 
 class FakeClient:
-    def __init__(self, listing=None, plugins=None, listing_after_change=None):
+    host = "https://synthetic.example.com"
+
+    def __init__(
+        self, listing=None, plugins=None, listing_after_change=None, code_envs=None
+    ):
+        self.code_envs = code_envs or []
+        self.futures = {}
         self.listing = listing or []
         self.plugins = plugins or {}
         self.listing_after_change = listing_after_change
@@ -205,6 +242,35 @@
     def get_plugin(self, plugin_id):
         return self.plugins[plugin_id]
 
+    def list_code_envs(self):
+        return self.code_envs
+
+    def install_plugin_from_store(self, plugin_id):
+        self.store_install_id = plugin_id
+        self._apply_change()
+        return self.futures["install"]
+
+    def install_plugin_from_git(self, repository_url, checkout, subpath):
+        self.git_install_args = (repository_url, checkout, subpath)
+        self._apply_change()
+        return self.futures["install"]
+
+    def start_install_plugin_from_archive(self, archive):
+        self.uploaded = archive.read()
+        self._apply_change()
+        return self.futures["install"]
+
+
+def _absent(plugin_id="geocoder", futures=None, version="1.0.0", **kwargs):
+    plugin = FakePlugin(plugin_id)
+    client = FakeClient(
+        plugins={plugin_id: plugin},
+        listing_after_change=[_listing_entry(plugin_id, version)],
+    )
+    client.futures.update(futures or {})
+    client.futures.update(kwargs)
+    return plugin, client
+
 
 def _installed(plugin_id="geocoder", version="1.0.0", **kwargs):
     """A client where ``plugin_id`` is already installed."""
@@ -239,6 +305,7 @@
     monkeypatch.setattr(tools, "_MIN_POLL_INTERVAL_SECONDS", 0)
     monkeypatch.setattr(tools, "_MAX_POLL_INTERVAL_SECONDS", 0)
     monkeypatch.setattr(tools, "get_dss_client", _no_client)
+    tools._BUILD_OWNERS.clear()
 
 
 def _patch_client(client):
@@ -265,22 +332,13 @@
     return sorted(zipfile.ZipFile(io.BytesIO(payload)).namelist())
 
 
-@pytest.mark.parametrize(
-    ("source", "plugin_id", "local_path"),
-    [("store", "my-plugin", None), ("local_path", None, "/server/plugin.zip")],
-)
-def test_update_plugin_is_unavailable_in_http_mode(source, plugin_id, local_path):
+def test_update_plugin_local_path_is_unavailable_in_http_mode():
     token = request.bind_http_identity("https://idp.example", "alice")
     try:
-        with pytest.raises(
-            ValueError, match="update_plugin is unavailable in HTTP mode"
-        ):
+        with pytest.raises(ValueError, match="unavailable in HTTP mode"):
             asyncio.run(
                 tools.update_plugin(
-                    source,
-                    FakeContext(),
-                    plugin_id=plugin_id,
-                    local_path=local_path,
+                    "local_path", FakeContext(), local_path="/server/plugin.zip"
                 )
             )
     finally:
@@ -603,8 +661,6 @@
         asyncio.run(tools.update_plugin("store", FakeContext()))
     with pytest.raises(ValueError, match="local_path"):
         asyncio.run(tools.update_plugin("local_path", FakeContext()))
-    with pytest.raises(ValueError, match="source"):
-        asyncio.run(tools.update_plugin("git", FakeContext(), plugin_id="x"))
 
 
 def test_update_plugin_zips_a_directory_and_omits_version_control_files(tmp_path):
@@ -787,8 +843,8 @@
 
     assert res["status"] == "completed"
     assert res["code_env_rebuild"]["status"] == "skipped"
-    assert "Dataiku UI" in res["code_env_rebuild"]["hint"]
-    assert "does not establish" in res["code_env_rebuild"]["hint"]
+    assert "ensure_plugin_code_env" in res["code_env_rebuild"]["hint"]
+    assert "whether the plugin needs" in res["code_env_rebuild"]["hint"]
 
 
 def test_update_plugin_keeps_a_landed_update_when_the_rebuild_fails():
@@ -813,9 +869,58 @@
     assert res["code_env_rebuild"]["status"] == "failed"
     assert "pip resolution failed" in res["code_env_rebuild"]["error"]
     assert "Dataiku UI" in res["code_env_rebuild"]["hint"]
+    assert "recreate" in res["code_env_rebuild"]["hint"]
     assert "update_plugin" not in res["code_env_rebuild"]["hint"]
 
 
+@pytest.mark.parametrize("stage", ["inspect", "start", "poll", "terminal"])
+def test_update_plugin_keeps_landed_update_after_rebuild_exception(monkeypatch, stage):
+    from requests.exceptions import Timeout
+
+    future = FakeFuture("F3", [_alive()])
+    plugin, client = _installed(
+        settings={"codeEnvName": "plugin_geocoder"},
+        listing_after_change=[_listing_entry("geocoder", version="1.4.0")],
+        futures={"update": FakeFuture("F2", [_done()]), "update_code_env": future},
+    )
+
+    def fail():
+        raise Timeout("sensitive transport detail")
+
+    if stage == "inspect":
+        monkeypatch.setattr(plugin, "get_settings", fail)
+    elif stage == "start":
+        monkeypatch.setattr(plugin, "update_code_env", fail)
+    elif stage == "poll":
+        monkeypatch.setattr(future, "get_state", fail)
+    else:
+        future.state = {"alive": False, "aborted": True, "hasResult": False}
+
+    with _patch_client(client):
+        result = _load(
+            tools.update_plugin(
+                "store",
+                FakeContext(),
+                plugin_id="geocoder",
+                rebuild_code_env=True,
+            )
+        )
+
+    assert result["status"] == "completed"
+    assert result["plugin"]["version"] == "1.4.0"
+    rebuild = result["code_env_rebuild"]
+    assert rebuild["status"] == "unknown"
+    assert "Do not repeat update_plugin" in rebuild["hint"]
+    assert "sensitive" not in json.dumps(result)
+    if stage != "inspect":
+        assert rebuild["code_env_name"] == "plugin_geocoder"
+    if stage in ("poll", "terminal"):
+        assert rebuild["future_id"] == "F3"
+        assert "get_future_status" in rebuild["hint"]
+    else:
+        assert "future_id" not in rebuild
+
+
 def test_update_plugin_timeout_says_the_requested_rebuild_never_started():
     """Absent code_env_rebuild would read as a rebuild that quietly succeeded."""
     _, client = _installed(
@@ -1124,3 +1229,811 @@
     asyncio.run(tools._wait_for_future(future, 600))
 
     assert slept and all(interval == 10 for interval in slept)
+
+
+@pytest.mark.parametrize("http", [False, True])
+def test_install_plugin_from_store_reports_completion_and_restart_need(
+    monkeypatch, http
+):
+    monkeypatch.setattr(request, "is_http_request", lambda: http)
+    _, client = _absent(
+        version="1.3.1",
+        install=FakeFuture(
+            "F1", [_alive(), _done(needsRestart=True, needsReload=True)]
+        ),
+    )
+
+    with _patch_client(client):
+        res = _load(tools.install_plugin("store", FakeContext(), plugin_id="geocoder"))
+
+    assert res["status"] == "completed"
+    assert res["operation"] == "install"
+    assert res["source"] == "store"
+    assert res["needs_restart"] is True
+    assert res["needs_reload"] is True
+    assert res["plugin"]["version"] == "1.3.1"
+    assert client.store_install_id == "geocoder"
+
+
+def test_install_plugin_refuses_an_already_installed_plugin():
+    _, client = _installed(version="1.3.1")
+
+    with _patch_client(client), pytest.raises(ValueError) as excinfo:
+        asyncio.run(tools.install_plugin("store", FakeContext(), plugin_id="geocoder"))
+
+    assert "update_plugin" in str(excinfo.value)
+
+
+# --------------------------------------------------------------------------- #
+
+
+def test_local_install_is_disabled_in_http_before_any_io(monkeypatch):
+    monkeypatch.setattr(request, "is_http_request", lambda: True)
+    monkeypatch.setattr(
+        tools, "run_blocking", lambda *args: pytest.fail("must fail before IO")
+    )
+    with pytest.raises(ValueError, match="unavailable in HTTP"):
+        _load(
+            tools.install_plugin(
+                "local_path", FakeContext(), local_path="/server/plugin.zip"
+            )
+        )
+
+
+@pytest.mark.parametrize(
+    ("directory", "language"), [("python", "python"), ("R", "r"), (None, None)]
+)
+@pytest.mark.parametrize("wrapped", [False, True])
+def test_install_reads_code_env_descriptors_in_normalized_archive(
+    tmp_path, directory, language, wrapped
+):
+    archive = tmp_path / "sample.zip"
+    prefix = "wrapper/" if wrapped else ""
+    with zipfile.ZipFile(archive, "w") as output:
+        output.writestr(prefix + "plugin.json", json.dumps({"id": "sample"}))
+        if directory:
+            output.writestr(prefix + f"code-env/{directory}/desc.json", "{}")
+    _, client = _absent("sample", {"install": FakeFuture(None, [_done()])})
+    with _patch_client(client):
+        result = _load(
+            tools.install_plugin("local_path", FakeContext(), local_path=str(archive))
+        )
+    assert result["code_env"]["status"] == ("required" if language else "not_required")
+    assert result["code_env"]["languages"] == ([language] if language else [])
+
+
+def _creation(client=None, states=None):
+    if client is None:
+        plugin, client = _installed()
+    else:
+        plugin = client.get_plugin("geocoder")
+    future = FakeFuture("F4", states or [_code_env_done("plugin_geocoder_managed")])
+    plugin.futures["create_code_env"] = future
+    return plugin, client, future
+
+
+def test_ensure_plugin_code_env_creates_and_verifies_binding():
+    plugin, client, future = _creation()
+    with _patch_client(client):
+        result = _load(
+            tools.ensure_plugin_code_env(
+                "geocoder", FakeContext(), python_interpreter="PYTHON311"
+            )
+        )
+    assert result["status"] == "completed"
+    assert result["build"]["status"] == "completed"
+    assert plugin.settings.get_raw()["codeEnvName"] == result["code_env_name"]
+    assert plugin.created_interpreter == "PYTHON311"
+
+
+def test_plugin_interpreter_schema_explains_dataiku_selection():
+    registered = asyncio.run(tools.mcp.list_tools())
+    tool = next(item for item in registered if item.name == "ensure_plugin_code_env")
+    interpreter = tool.parameters["properties"]["python_interpreter"]
+    assert "accepted versions" in interpreter["description"]
+    assert "server availability" in interpreter["description"]
+    assert interpreter["default"] is None
+
+
+@pytest.mark.parametrize(
+    "message",
+    [
+        "com.dataiku.dip.exceptions.CodedException: ERR_PLUGIN_WITHOUT_CODEENV: no specification",
+        "com.dataiku.dip.exceptions.CodedException: The plugin geocoder doesn't specify a code env, cannot create it",
+    ],
+)
+def test_store_without_code_env_is_not_required(message):
+    from dataikuapi.utils import DataikuException
+
+    plugin, client, _ = _creation()
+    plugin.create_error = DataikuException(message)
+    with _patch_client(client):
+        result = _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert result["status"] == "not_required"
+    assert "codeEnvName" not in plugin.settings.get_raw()
+
+
+@pytest.mark.parametrize(
+    "message",
+    [
+        "permission denied",
+        "ERR_PLUGIN_WITHOUT_CODEENV_EXTRA",
+        "cannot create code env for another reason",
+    ],
+)
+def test_other_creation_errors_remain_errors(message):
+    from dataikuapi.utils import DataikuException
+
+    plugin, client, _ = _creation()
+    plugin.create_error = DataikuException(message)
+    with _patch_client(client), pytest.raises(RuntimeError, match="refused") as excinfo:
+        _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert message in str(excinfo.value)
+    assert "codeEnvName" not in plugin.settings.get_raw()
+
+
+def test_failed_build_is_preserved_beside_binding():
+    plugin, client, _ = _creation(
+        states=[_code_env_done("plugin_geocoder_managed", error="pip install failed")]
+    )
+    with _patch_client(client):
+        result = _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert result["build"]["status"] == "failed"
+    assert result["code_env_name"] == plugin.settings.get_raw()["codeEnvName"]
+
+
+def test_bound_environment_does_not_create_or_claim_build_success():
+    plugin, client = _installed(settings={"codeEnvName": "already-bound"})
+    with _patch_client(client):
+        result = _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert not result["created"]
+    assert result["build"]["status"] == "unknown"
+    assert not plugin.futures
+
+
+def _with_orphan(**kwargs):
+    return _installed(
+        code_envs=[
+            {"envName": "plugin_geocoder_managed", "deploymentMode": "PLUGIN_MANAGED"}
+        ],
+        **kwargs,
+    )
+
+
+def test_orphan_is_listed_instead_of_guessed_or_duplicated():
+    plugin, client = _with_orphan()
+    with _patch_client(client):
+        result = _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert result["status"] == "recovery_required"
+    assert result["code_env_names"] == ["plugin_geocoder_managed"]
+    assert "code_env_name" in result["hint"]
+    assert not plugin.futures
+    assert "codeEnvName" not in plugin.settings.get_raw()
+
+
+def test_named_orphan_is_bound_without_claiming_a_build():
+    plugin, client = _with_orphan()
+    with _patch_client(client):
+        result = _load(
+            tools.ensure_plugin_code_env(
+                "geocoder", FakeContext(), code_env_name="plugin_geocoder_managed"
+            )
+        )
+    assert result["status"] == "completed"
+    assert result["created"] is False
+    assert result["build"]["status"] == "unknown"
+    assert plugin.settings.get_raw()["codeEnvName"] == "plugin_geocoder_managed"
+    assert not plugin.futures
+
+
+@pytest.mark.parametrize(
+    "name", ["plugin_other_managed", "plugin_geocoder_managed_1", "my-env"]
+)
+def test_named_environment_must_be_an_existing_managed_env_of_the_plugin(name):
+    plugin, client = _with_orphan()
+    with _patch_client(client), pytest.raises(ValueError, match="Candidates"):
+        _load(
+            tools.ensure_plugin_code_env("geocoder", FakeContext(), code_env_name=name)
+        )
+    assert "codeEnvName" not in plugin.settings.get_raw()
+
+
+@pytest.mark.parametrize(
+    "kwargs",
+    [{"code_env_name": "plugin_geocoder_managed"}, {"python_interpreter": "PYTHON311"}],
+)
+def test_bound_plugin_refuses_a_different_environment_request(kwargs):
+    plugin, client = _installed(settings={"codeEnvName": "already-bound"})
+    with _patch_client(client), pytest.raises(ValueError, match="already bound"):
+        _load(tools.ensure_plugin_code_env("geocoder", FakeContext(), **kwargs))
+    assert plugin.settings.get_raw()["codeEnvName"] == "already-bound"
+
+
+def test_timeout_is_resumed_by_exact_future_and_then_bound(monkeypatch):
+    plugin, client, future = _creation(states=[_alive(), _alive()])
+    with _patch_client(client), _exhausted_clock() as mock_time:
+        mock_time.monotonic.side_effect = incrementing_monotonic()
+        result = _load(
+            tools.ensure_plugin_code_env("geocoder", FakeContext(), timeout_seconds=1)
+        )
+    assert result["status"] == "still_running"
+    assert result["future_id"] == "F4"
+    assert "codeEnvName" not in plugin.settings.get_raw()
+    resumed = _build_future(
+        "F4", "plugin_geocoder_managed", [_code_env_done("plugin_geocoder_managed")]
+    )
+    monkeypatch.setattr(tools, "DSSFuture", lambda client, future_id: resumed)
+    with _patch_client(client):
+        result = _load(
+            tools.ensure_plugin_code_env("geocoder", FakeContext(), future_id="F4")
+        )
+    assert result["build"]["status"] == "completed"
+    assert result["created"] is True
+    assert plugin.settings.get_raw()["codeEnvName"] == "plugin_geocoder_managed"
+
+
+@pytest.mark.parametrize(
+    "peeked",
+    [
+        {
+            "payload": {
+                "action": "import_env",
+                "displayName": "Import env: plugin_other_managed",
+            }
+        },
+        {"payload": {"action": "update_plugin", "displayName": "Update: geocoder"}},
+        {"jobId": "wrong"},
+    ],
+)
+def test_resuming_another_operations_future_neither_reads_nor_binds(
+    monkeypatch, peeked
+):
+    plugin, client = _installed()
+    other = FakeFuture("wrong", [_code_env_done("plugin_other_managed")])
+    other.peeked = peeked
+    monkeypatch.setattr(tools, "DSSFuture", lambda *args: other)
+    with (
+        _patch_client(client),
+        pytest.raises(ValueError, match="not a code environment build"),
+    ):
+        _load(
+            tools.ensure_plugin_code_env("geocoder", FakeContext(), future_id="wrong")
+        )
+    assert not getattr(other, "read", False)
+    assert "codeEnvName" not in plugin.settings.get_raw()
+
+
+def test_forgotten_future_points_to_named_binding(monkeypatch):
+    from dataikuapi.utils import DataikuException
+
+    _, client = _installed()
+    gone = FakeFuture("F4", [_alive()])
+
+    def forgotten():
+        raise DataikuException(
+            "java.lang.IllegalArgumentException: No future by that id"
+        )
+
+    gone.peek_state = forgotten
+    monkeypatch.setattr(tools, "DSSFuture", lambda *args: gone)
+    with _patch_client(client), pytest.raises(ValueError, match="code_env_name"):
+        _load(tools.ensure_plugin_code_env("geocoder", FakeContext(), future_id="F4"))
+
+
+def test_binding_failure_reports_the_reason_and_the_name_to_bind(monkeypatch):
+    from dataikuapi.utils import DataikuException
+
+    plugin, client, _ = _creation()
+
+    def fail_save():
+        raise DataikuException(
+            "com.dataiku.dip.exceptions.UnauthorizedException: Action forbidden"
+        )
+
+    monkeypatch.setattr(plugin.settings, "save", fail_save)
+    with _patch_client(client):
+        result = _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert result["status"] == "binding_failed"
+    assert result["code_env_name"] == "plugin_geocoder_managed"
+    assert result["error"] == "Action forbidden"
+
+
+def test_changed_binding_is_preserved(monkeypatch):
+    plugin, client, future = _creation(
+        states=[_alive(), _code_env_done("plugin_geocoder_managed")]
+    )
+    original = future.get_state
+
+    def switched():
+        plugin.settings.raw["codeEnvName"] = "chosen-elsewhere"
+        return original()
+
+    monkeypatch.setattr(future, "get_state", switched)
+    with _patch_client(client):
+        result = _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert result["status"] == "binding_changed"
+    assert result["bound_code_env_name"] == "chosen-elsewhere"
+    assert plugin.settings.raw["codeEnvName"] == "chosen-elsewhere"
+
+
+@pytest.mark.parametrize("no_spec", [True, False])
+def test_code_env_contract_through_real_sdk_http_serialization(monkeypatch, no_spec):
+    """The real SDK drops errorCode; exercise that boundary instead of a fake exception."""
+    import requests
+    from dataikuapi import DSSClient
+
+    client = DSSClient("https://synthetic.example.com", "synthetic-key")
+    settings = {}
+    calls = []
+
+    def respond(method, url, **kwargs):
+        path = url.split("/dip/publicapi", 1)[1]
+        calls.append((method, path))
+        status = 200
+        if path == "/plugins/":
+            value = [_listing_entry("geocoder")]
+        elif path == "/admin/code-envs/":
+            value = []
+        elif path.endswith("/settings"):
+            if method == "POST":
+                settings.update(json.loads(kwargs["data"]))
+            value = dict(settings)
+        elif path.endswith("/code-env/actions/create"):
+            body = json.loads(kwargs["data"])
+            assert body["deploymentMode"] == "PLUGIN_MANAGED"
+            assert body["pythonInterpreter"] is None
+            if no_spec:
+                status = 400
+                value = {
+                    "errorType": "com.dataiku.dip.exceptions.CodedException",
+                    "errorCode": "ERR_PLUGIN_WITHOUT_CODEENV",
+                    "detailedMessage": "The plugin geocoder doesn't specify a code env, cannot create it",
+                }
+            else:
+                value = _code_env_done("plugin_geocoder_managed")
+        else:
+            pytest.fail(f"Unexpected SDK call {method} {path}")
+        response = requests.Response()
+        response.status_code = status
+        response._content = json.dumps(value).encode()
+        return response
+
+    monkeypatch.setattr(client._session, "request", respond)
+    with _patch_client(client):
+        result = _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert result["status"] == ("not_required" if no_spec else "completed")
+    assert ("codeEnvName" in settings) is not no_spec
+    assert ("POST", "/plugins/geocoder/settings") in calls if not no_spec else True
+
+
+def test_environment_name_without_build_report_is_not_verified_success():
+    _, client, _ = _creation(
+        states=[{"hasResult": True, "result": {"envName": "plugin_geocoder_managed"}}]
+    )
+    with _patch_client(client):
+        result = _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert result["build"]["status"] == "unknown"
+
+
+@pytest.mark.parametrize(
+    "name",
+    [
+        "plugin_geocoder-extra_managed",
+        "plugin_geocoder_managed_extra",
+        "plugin_other_managed",
+    ],
+)
+def test_similarly_named_environments_do_not_block_initial_creation(name):
+    _, client = _installed(
+        code_envs=[{"envName": name, "deploymentMode": "PLUGIN_MANAGED"}]
+    )
+    _, client, _ = _creation(client)
+    with _patch_client(client):
+        result = _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert result["created"] is True
+
+
+_GIT_URL = "https://git.example.com/team/plugin.git"
+
+
+def _git_done(**kwargs):
+    return _done(pluginDesc={"desc": {"id": "geocoder"}}, **kwargs)
+
+
+@pytest.mark.parametrize("wait", [False, True])
+def test_git_install_keeps_future_when_plugin_id_is_not_known(wait):
+    _, client = _absent(install=FakeFuture("G2", [_alive(), _alive()]))
+    with _patch_client(client), _exhausted_clock() as mock_time:
+        mock_time.monotonic.side_effect = incrementing_monotonic()
+        result = _load(
+            tools.install_plugin(
+                "git",
+                FakeContext(),
+                repository_url=_GIT_URL,
+                checkout="main",
+                wait_for_completion=wait,
+                timeout_seconds=1,
+            )
+        )
+    assert result["status"] == ("still_running" if wait else "started")
+    assert result["future_id"] == "G2"
+    assert "plugin_id" not in result
+
+
+def test_git_install_reports_uncertain_verification_without_restarting():
+    _, client = _absent(install=FakeFuture(None, [_git_done()]))
+    client.listing_after_change = []
+    with _patch_client(client):
+        result = _load(
+            tools.install_plugin(
+                "git",
+                FakeContext(),
+                repository_url=_GIT_URL,
+                checkout="main",
+            )
+        )
+    assert result["status"] == "verification_required"
+    assert "list_plugins" in result["hint"]
+
+
+@pytest.mark.parametrize("operation", ["install", "update"])
+def test_git_contract_with_real_sdk(monkeypatch, operation):
+    import requests
+    from dataikuapi import DSSClient
+
+    monkeypatch.setattr(request, "is_http_request", lambda: True)
+    client = DSSClient("https://synthetic.example.com", "synthetic-key")
+    calls = []
+    endpoint = (
+        "/plugins/actions/installFromGit"
+        if operation == "install"
+        else "/plugins/geocoder/actions/updateFromGit"
+    )
+    checkout = "v1.0" if operation == "install" else _GIT_COMMIT
+
+    def respond(method, url, **kwargs):
+        path = url.split("/dip/publicapi", 1)[1]
+        calls.append((method, path))
+        if path == endpoint:
+            assert json.loads(kwargs["data"]) == {
+                "gitRepositoryUrl": _GIT_URL,
+                "gitCheckout": checkout,
+                "gitSubpath": "plugin",
+            }
+            value = {"jobId": "G4", **_alive()}
+        elif path == "/futures/G4":
+            value = _git_done(needsReload=True)
+            value["result"]["settings"] = {"secret": "do-not-return"}
+        elif path == "/plugins/":
+            value = [_listing_entry("geocoder")]
+        else:
+            pytest.fail(f"Unexpected SDK call {method} {path}")
+        response = requests.Response()
+        response.status_code = 200
+        response._content = json.dumps(value).encode()
+        return response
+
+    monkeypatch.setattr(client._session, "request", respond)
+    with _patch_client(client):
+        result = _load(
+            getattr(tools, f"{operation}_plugin")(
+                "git",
+                FakeContext(),
+                repository_url=_GIT_URL,
+                checkout=checkout,
+                **({"plugin_id": "geocoder"} if operation == "update" else {}),
+                subpath="plugin",
+            )
+        )
+    assert result["status"] == "completed"
+    assert result["plugin_id"] == result["plugin"]["id"] == "geocoder"
+    assert result["needs_reload"] is True
+    if operation == "install":
+        assert result["code_env"] == {"status": "unknown"}
+    assert "do-not-return" not in json.dumps(result)
+    assert calls == ([("GET", "/plugins/")] if operation == "update" else []) + [
+        ("POST", endpoint),
+        ("GET", "/futures/G4"),
+        ("GET", "/plugins/"),
+    ]
+
+
+_GIT_COMMIT = "a1" * 20
+
+
+@pytest.mark.parametrize(
+    "http,rebuild,checkout,subpath",
+    [
+        (True, True, "release/1.0", "plugins/geocoder"),
+        (False, False, "v2.0", None),
+        (False, False, _GIT_COMMIT, None),
+    ],
+)
+def test_git_update_uses_chosen_revision_and_path(
+    monkeypatch, http, rebuild, checkout, subpath
+):
+    monkeypatch.setattr(request, "is_http_request", lambda: http)
+    plugin, client = _installed(
+        settings={"codeEnvName": "plugin_geocoder_managed"},
+        futures={
+            "update": FakeFuture("GU1", [_alive(), _git_done(needsReload=True)]),
+            "update_code_env": FakeFuture(
+                None, [_code_env_done("plugin_geocoder_managed")]
+            ),
+        },
+        listing_after_change=[_listing_entry("geocoder", "2.0.0")],
+    )
+    with _patch_client(client):
+        result = _load(
+            tools.update_plugin(
+                "git",
+                FakeContext(),
+                plugin_id="geocoder",
+                repository_url=_GIT_URL,
+                checkout=checkout,
+                subpath=subpath,
+                rebuild_code_env=rebuild,
+            )
+        )
+    assert plugin.git_update_args == (_GIT_URL, checkout, subpath)
+    assert result["plugin"]["version"] == "2.0.0"
+    assert result["needs_reload"] is True
+    assert result["status"] == "completed"
+    assert ("code_env_rebuild" in result) is rebuild
+    if rebuild:
+        assert result["code_env_rebuild"]["status"] == "completed"
+
+
+@pytest.mark.parametrize("wait", [False, True])
+def test_git_update_preserves_future_and_defers_rebuild(wait):
+    _, client = _installed(futures={"update": FakeFuture("GU2", [_alive(), _alive()])})
+    with _patch_client(client), _exhausted_clock() as mock_time:
+        mock_time.monotonic.side_effect = incrementing_monotonic()
+        result = _load(
+            tools.update_plugin(
+                "git",
+                FakeContext(),
+                plugin_id="geocoder",
+                repository_url=_GIT_URL,
+                checkout=_GIT_COMMIT,
+                wait_for_completion=wait,
+                rebuild_code_env=wait,
+                timeout_seconds=1,
+            )
+        )
+    assert result["future_id"] == "GU2"
+    assert result["status"] == ("still_running" if wait else "started")
+    if wait:
+        assert result["code_env_rebuild"]["status"] == "not_started"
+
+
+@pytest.mark.parametrize("actual_id", [None, "other-plugin"])
+def test_git_update_unexpected_result_requires_verification_and_skips_rebuild(
+    actual_id,
+):
+    _, client = _installed(
+        futures={
+            "update": FakeFuture(None, [_done(pluginDesc={"desc": {"id": actual_id}})])
+        }
+    )
+    with _patch_client(client):
+        result = _load(
+            tools.update_plugin(
+                "git",
+                FakeContext(),
+                plugin_id="geocoder",
+                repository_url=_GIT_URL,
+                checkout=_GIT_COMMIT,
+                rebuild_code_env=True,
+            )
+        )
+    assert result["status"] == "verification_required"
+    assert "code_env_rebuild" not in result
+    assert result.get("reported_plugin_id") == actual_id
+
+
+def test_git_update_refuses_missing_target_before_mutation():
+    _, client = _absent()
+    with _patch_client(client), pytest.raises(ValueError, match="not installed"):
+        _load(
+            tools.update_plugin(
+                "git",
+                FakeContext(),
+                plugin_id="geocoder",
+                repository_url=_GIT_URL,
+                checkout=_GIT_COMMIT,
+            )
+        )
+
+
+@pytest.mark.parametrize(
+    "operation,stage", [("install", "start"), ("install", "poll"), ("update", "result")]
+)
+def test_git_access_failure_provides_help_and_recovery(monkeypatch, operation, stage):
+    from dataikuapi.utils import DataikuException
+
+    plugin, client = _installed() if operation == "update" else _absent()
+    future = FakeFuture("G-auth", [_alive()])
+    futures = plugin.futures if operation == "update" else client.futures
+    futures[operation] = future
+    secret = "synthetic-token"
+    message = f"Authentication failed https://user:{secret}@git.example.com/plugin"
+
+    def fail(*args, **kwargs):
+        raise DataikuException(message)
+
+    if stage == "start":
+        monkeypatch.setattr(client, "install_plugin_from_git", fail)
+    elif stage == "poll":
+        monkeypatch.setattr(future, "get_state", fail)
+    else:
+        futures[operation] = FakeFuture(
+            "G-auth", [_done(success=False, installationError={"message": message})]
+        )
+    with _patch_client(client), pytest.raises(RuntimeError) as error:
+        _load(
+            getattr(tools, f"{operation}_plugin")(
+                "git",
+                FakeContext(),
+                repository_url=_GIT_URL,
+                checkout="main",
+                **({"plugin_id": "geocoder"} if operation == "update" else {}),
+            )
+        )
+    assert "Dataiku's Git settings" in str(error.value)
+    assert "Credentials on the Headless machine do not apply" in str(error.value)
+    assert secret not in str(error.value)
+    if stage != "start":
+        assert "G-auth" in str(error.value)
+
+
+def test_git_non_auth_failure_does_not_claim_missing_credentials():
+    _, client = _absent(
+        install=FakeFuture(
+            None,
+            [
+                _done(
+                    success=False,
+                    installationError={"message": "Remote branch does not exist"},
+                )
+            ],
+        )
+    )
+    with _patch_client(client), pytest.raises(RuntimeError) as error:
+        _load(
+            tools.install_plugin(
+                "git", FakeContext(), repository_url=_GIT_URL, checkout="missing"
+            )
+        )
+    assert "could not authenticate" not in str(error.value)
+    assert "checkout" in str(error.value)
+    assert "list_plugins" in str(error.value)
+
+
+@pytest.mark.parametrize(
+    "operation,source,overrides",
+    [
+        ("install", "git", {"repository_url": None}),
+        ("update", "git", {"checkout": " "}),
+        ("update", "git", {"plugin_id": None}),
+        ("install", "git", {"plugin_id": "geocoder"}),
+        ("update", "git", {"local_path": "/tmp/plugin"}),
+        ("install", "git", {"subpath": "../plugin"}),
+        ("update", "git", {"subpath": "/plugin"}),
+        (
+            "install",
+            "git",
+            {"repository_url": "https://user:synthetic-token@git.example.com/plugin"},
+        ),
+        (
+            "update",
+            "git",
+            {"repository_url": "https://git.example.com/plugin?token=synthetic-token"},
+        ),
+        ("install", "git", {"repository_url": "file:///server/plugin"}),
+        ("install", "store", {}),
+        ("update", "local_path", {}),
+    ],
+)
+def test_git_source_validation_rejects_invalid_arguments_before_io(
+    operation, source, overrides
+):
+    arguments = dict(repository_url=_GIT_URL, checkout="main")
+    if operation == "update":
+        arguments["plugin_id"] = "geocoder"
+    arguments.update(overrides)
+    with pytest.raises(ValueError) as error:
+        _load(getattr(tools, f"{operation}_plugin")(source, FakeContext(), **arguments))
+    assert "synthetic-token" not in str(error.value)
+
+
+@pytest.mark.parametrize(
+    "url",
+    [
+        "git@git.example.com:team/plugin.git",
+        "ssh://git@git.example.com/team/plugin.git",
+    ],
+)
+def test_git_ssh_remote_forms_are_accepted(url):
+    assert tools._require_git_repository_url(url) == url
+
+
+@pytest.mark.parametrize("after_save", [False, True])
+def test_binding_transport_timeout_keeps_build_and_supports_retry(
+    monkeypatch, after_save
+):
+    from requests.exceptions import Timeout
+
+    plugin, client, _ = _creation()
+    original = plugin.settings.save
+
+    def save():
+        if after_save:
+            original()
+        else:
+            plugin.settings.raw.pop("codeEnvName", None)
+        raise Timeout("sensitive transport detail")
+
+    monkeypatch.setattr(plugin.settings, "save", save)
+    with _patch_client(client):
+        result = _load(tools.ensure_plugin_code_env("geocoder", FakeContext()))
+    assert result["status"] == "binding_unknown"
+    assert result["build"]["status"] == "completed"
+    assert result["code_env_name"] == "plugin_geocoder_managed"
+    assert "sensitive" not in json.dumps(result)
+    assert bool(plugin.settings.raw.get("codeEnvName")) is after_save
+    client.code_envs = [
+        {"deploymentMode": "PLUGIN_MANAGED", "envName": result["code_env_name"]}
+    ]
+    monkeypatch.setattr(plugin.settings, "save", original)
+    with _patch_client(client):
+        result = _load(
+            tools.ensure_plugin_code_env(
+                "geocoder", FakeContext(), code_env_name=result["code_env_name"]
+            )
+        )
+    assert result["status"] == "completed"
+
+
+def test_automation_build_resumes_only_for_retained_owner(monkeypatch):
+    plugin, client, _ = _creation(states=[_alive(), _alive()])
+    with _patch_client(client), _exhausted_clock() as clock:
+        clock.monotonic.side_effect = incrementing_monotonic()
+        _load(
+            tools.ensure_plugin_code_env("geocoder", FakeContext(), timeout_seconds=1)
+        )
+    resumed = _build_future(
+        "F4", "plugin_geocoder_managed", [_code_env_done("plugin_geocoder_managed")]
+    )
+    resumed.peeked["payload"]["displayName"] = "Import env"
+    monkeypatch.setattr(tools, "DSSFuture", lambda *args: resumed)
+    with _patch_client(client):
+        result = _load(
+            tools.ensure_plugin_code_env("geocoder", FakeContext(), future_id="F4")
+        )
+    assert result["status"] == "completed"
+    assert not tools._BUILD_OWNERS
+
+
+@pytest.mark.parametrize("scope", ["plugin", "instance", "caller", "restart"])
+def test_automation_build_does_not_consume_an_unowned_future(monkeypatch, scope):
+    _, client = _installed()
+    key = tools._build_owner_key(client, "F4")
+    tools._BUILD_OWNERS[key] = "other" if scope == "plugin" else "geocoder"
+    if scope == "instance":
+        client.host = "https://other.example.com"
+    elif scope == "caller":
+        monkeypatch.setattr(request, "get_request_owner", lambda: ("oidc", "other"))
+    elif scope == "restart":
+        tools._BUILD_OWNERS.clear()
+    future = _build_future(
+        "F4", "plugin_geocoder_managed", [_code_env_done("plugin_geocoder_managed")]
+    )
+    future.peeked["payload"]["displayName"] = "Import env"
+    monkeypatch.setattr(tools, "DSSFuture", lambda *args: future)
+    with (
+        _patch_client(client),
+        pytest.raises(ValueError, match="not a code environment build"),
+    ):
+        _load(tools.ensure_plugin_code_env("geocoder", FakeContext(), future_id="F4"))
+    assert not getattr(future, "read", False)
Full technical diff · 208 changed fields

added /files/.agents~1plugins~1marketplace.json

BEFORE
Field was absent
AFTER
{
  "sha256": "5a1a724844a602acdab8e4f6ffe307b0f7772af0b6c437d6425d8142d21b960a",
  "size": 659
}

changed /files/.claude-plugin~1marketplace.json/sha256

BEFORE
"df10462f2b84eab4a4a48d68b6cdeb80a402fda5fe985987292ab93635554e52"
AFTER
"c142b21c6e1a8f24e5cf2dd6ce31c5c9441a58fe3a64d8f3d8efc6c2e10e7d5a"

changed /files/.claude-plugin~1marketplace.json/size

BEFORE
556
AFTER
603

changed /files/.claude-plugin~1plugin.json/sha256

BEFORE
"c6935b186ecc9648319eb1dafc96f223b41c556d445a54d8ec0c6ea9f360e9d9"
AFTER
"932135fd42ae2b929c46b8ac93df3d2e2fb8b1d51a7a8a6057e1227edf2b5ead"

changed /files/.claude-plugin~1plugin.json/size

BEFORE
926
AFTER
918

added /files/.codex-plugin~1mcp.json

BEFORE
Field was absent
AFTER
{
  "sha256": "ad37dba1daf5b808c8c02044c413300dd45820fe9e50aef4897fd1c29a0f41b4",
  "size": 623
}

changed /files/.codex-plugin~1plugin.json/sha256

BEFORE
"2badf002fed037383d73ccb951fb1e6c4b9657a996a9dc611fc08ad6044d8e59"
AFTER
"ef60afa841515d5c97c609ed6fdf6c2895dfda1f7e02f35c1e6dc4a61e520e44"

changed /files/.codex-plugin~1plugin.json/size

BEFORE
7118
AFTER
7131

changed /files/.cortex-plugin~1plugin.json/sha256

BEFORE
"77c7e3923d64d1ba00e330bb4f30c672499b7b0eef5d2ad291ab9b252bbdbd06"
AFTER
"3436a9f9aa992b405d9868c83114966d7537bdd3cc35ef779d29739d13b35a05"

added /files/.cursor-plugin~1marketplace.json

BEFORE
Field was absent
AFTER
{
  "sha256": "8b247aec5b9cbbbaecb9be45aabbd828f17005f8bc79500ef32df0ab8370bab5",
  "size": 578
}

changed /files/.cursor-plugin~1plugin.json/sha256

BEFORE
"e0d30697f920b3e68fba8215661af35aec877a5a88f744f9903035bcb0d3ad26"
AFTER
"ad1226956172fc34d4e500fd770c91be6613c593cc1e804dcb9ff37420f05cf0"

added /files/.github~1plugin~1marketplace.json

BEFORE
Field was absent
AFTER
{
  "sha256": "8b247aec5b9cbbbaecb9be45aabbd828f17005f8bc79500ef32df0ab8370bab5",
  "size": 578
}

added /files/.github~1plugin~1plugin.json

BEFORE
Field was absent
AFTER
{
  "sha256": "b306cbbdfc7d689560ebb27e44dbb8467d82284b822c3ae7a0a3674b5eed372a",
  "size": 848
}

removed /files/.mcp.json

BEFORE
{
  "sha256": "ad37dba1daf5b808c8c02044c413300dd45820fe9e50aef4897fd1c29a0f41b4",
  "size": 623
}
AFTER
Field is absent

changed /files/AGENTS.md/sha256

BEFORE
"78a1522ef9ec675bbcdd59930cb2579b569a502f8034dcaffac1755431ad2640"
AFTER
"dc0554d0814a0604032c2dcf555419093c590c58f3de4142d4a2fd7942caf474"

changed /files/AGENTS.md/size

BEFORE
7498
AFTER
7675

changed /files/CHANGELOG.md/sha256

BEFORE
"9070459d24cb782082b736358dac1a3c8dbf8324b16f0faf4e5ea0b957fe3416"
AFTER
"1c697b1ce71dec51b0cc9a12d96b0e426ea897b6f03106c252c8376b5be8466b"

changed /files/CHANGELOG.md/size

BEFORE
4162
AFTER
4695

changed /files/CODING_STANDARDS_AND_STRUCTURE.md/sha256

BEFORE
"42c104a39849f8ba4aba28fd4b0cd7814833d928f70679555feb9c764af14511"
AFTER
"3d3845075a21e2814e9b517f16aa85970177e8245e7ee382bb48aa9b476a802c"

changed /files/CODING_STANDARDS_AND_STRUCTURE.md/size

BEFORE
14143
AFTER
15343

added /files/CONTRIBUTORS.md

BEFORE
Field was absent
AFTER
{
  "sha256": "1b3b498a5e1fcd6ec0ecfdca936ec74581081517bc703fe3ae74f3d6e459d7be",
  "size": 938
}

added /files/NOTICE

BEFORE
Field was absent
AFTER
{
  "sha256": "14a8e7d5123c6c13f89faedf678f44edae11074936b39322c7f75269fa3b128d",
  "size": 12906
}

changed /files/README.md/sha256

BEFORE
"509079466298a4635f6b578de0252a7602c7cf602e0defa2433215f78b48f05b"
AFTER
"9ed1f335c291dfac7b440422173546299ca4e229ccc779e6bf0337150ddaa39d"

changed /files/README.md/size

BEFORE
18296
AFTER
20661

changed /files/dataiku_mcp~1config~1stdio.py/sha256

BEFORE
"a94c031a5ddd27410d558bfbf5a64140bb8d71a1fe8b0648100ba960aba07dfc"
AFTER
"1de4adbc3887895dabd136feebf47391e0885e6863980feefe7c7605ea37ba5a"

changed /files/dataiku_mcp~1config~1stdio.py/size

BEFORE
10606
AFTER
14141

added /files/dataiku_mcp~1instance_policy.py

BEFORE
Field was absent
AFTER
{
  "sha256": "a62e0be2e7aa8c9fc1e0fbc57cc60f970e78a5b80aa511cacba971d6d46483a5",
  "size": 2438
}

changed /files/dataiku_mcp~1server.py/sha256

BEFORE
"713ec23963d7bee246ef13a262153e8027275021fe1efd9d7eb00b35c5d92ba2"
AFTER
"675914e7bba7e287949ab3f8d622c27a993149f86541d293f682a1a210815145"

changed /files/dataiku_mcp~1server.py/size

BEFORE
5717
AFTER
6544

added /files/dataiku_mcp~1setup_page.html

BEFORE
Field was absent
AFTER
{
  "sha256": "788db788817813489f5b94ea72d2497368c93b3fb0307787445afa941ab4a77a",
  "size": 36742
}

changed /files/dataiku_mcp~1setup_server.py/sha256

BEFORE
"10dcf7c76477f59bf8e8ba9a18852db6ce47ca9a77c73001f7d34f63d5aef8d7"
AFTER
"1721fc394eb0e2b3417c8287fa95c3776c5580cb13c97e03a91db2548608845d"

changed /files/dataiku_mcp~1setup_server.py/size

BEFORE
20109
AFTER
20373

changed /files/dataiku_mcp~1tools~1agent_reviews.py/sha256

BEFORE
"1f0c071ec6608c80ca192dbe6d6a09f721672fa48aaf18c8b5282822fb0c2a33"
AFTER
"fcb8c88bb520dc6689b9b98045cff61387310ea0917aafa70bf2217adf11a552"

changed /files/dataiku_mcp~1tools~1agent_reviews.py/size

BEFORE
8494
AFTER
8694

changed /files/dataiku_mcp~1tools~1agents.py/sha256

BEFORE
"de80b96836ef3136d6333cc070db1a355c761bc26b246528cff329d1b207e2ec"
AFTER
"9b83b82a3197154eb647c47575c81bbb57f51d68073ef19a3139def312fad391"

changed /files/dataiku_mcp~1tools~1agents.py/size

BEFORE
8134
AFTER
8334

changed /files/dataiku_mcp~1tools~1cobuild.py/sha256

BEFORE
"bf1136330a28fe2d9cc136de9e058066524b4943e51a1553405304692576ae44"
AFTER
"c7b3f8180c280709eab3a6118b71038c61282b7c0044b67622676a978cacf33c"

changed /files/dataiku_mcp~1tools~1cobuild.py/size

BEFORE
19410
AFTER
19640

changed /files/dataiku_mcp~1tools~1code_environments.py/sha256

BEFORE
"71f6ffb36c9bb6ab39209efb74635b29161ab07ea729b14ea3286f9047dfcb55"
AFTER
"0eff238e901c71cea7ac6f567477466178dc476b9269cfffa1d4ce31e72960f8"

changed /files/dataiku_mcp~1tools~1code_environments.py/size

BEFORE
18626
AFTER
18761

changed /files/dataiku_mcp~1tools~1connections.py/sha256

BEFORE
"d112a160a4f76e81db7833ebcc97c75c80965bcfb86594e3c3464789fea0570b"
AFTER
"1572ce248bfe12e907498fe6ffeb47c4770cdddd32e47a9582518d66361563c1"

changed /files/dataiku_mcp~1tools~1connections.py/size

BEFORE
8850
AFTER
8962

changed /files/dataiku_mcp~1tools~1container_exec.py/sha256

BEFORE
"213b1f3c5019fc5db79210efbf468920a752121eecd6e82102b471e233d7c6ae"
AFTER
"43dbff406fc6948c765c39ad522d2560e05e50706740ea432b63e0bfc34c3785"

changed /files/dataiku_mcp~1tools~1container_exec.py/size

BEFORE
7582
AFTER
7662

changed /files/dataiku_mcp~1tools~1cross_project_sharing.py/sha256

BEFORE
"5c4e5780ff7faaf62ed84e568b65641fd23448c48b5fcc81dd5ad6cb19581792"
AFTER
"31714e0f338a562c2341e10c0b26bf1512a985c0274a3f32bf5a97cc8a689418"

changed /files/dataiku_mcp~1tools~1cross_project_sharing.py/size

BEFORE
2452
AFTER
2532

changed /files/dataiku_mcp~1tools~1dashboards.py/sha256

BEFORE
"d313ecf211aad832faf1bb1b79f6df04d7da9282705e8d9e025f033d5e3d2887"
AFTER
"a03074fb9b7971759c59b97d539d37a685633cf490aae32edc61cbe484d5f1a7"

changed /files/dataiku_mcp~1tools~1dashboards.py/size

BEFORE
2844
AFTER
2954

changed /files/dataiku_mcp~1tools~1data_collections.py/sha256

BEFORE
"bc34ac98f9e92fbb301633da2116e7c2f1f71d9aa6ecdd6a732771320fd7b688"
AFTER
"fd1987886cd970fa8069fa4d7a34c1d645f254e36f3a9b3a25554ddf5c7f3659"

changed /files/dataiku_mcp~1tools~1data_collections.py/size

BEFORE
2597
AFTER
2686

changed /files/dataiku_mcp~1tools~1data_quality.py/sha256

BEFORE
"c10bd394735a5e92a134f6fda4be2ab4e30cad5cef4142f0539fdf4f5e408498"
AFTER
"5cc50a9b82aec30626052e92434df3b474c8b72c982c9e885ded18e3b98b1886"

changed /files/dataiku_mcp~1tools~1data_quality.py/size

BEFORE
11343
AFTER
11543

changed /files/dataiku_mcp~1tools~1datasets.py/sha256

BEFORE
"b231a4721bc87b58e17ff7dd0b048ddc9c34ff0c992ea777cb23c065d29d1265"
AFTER
"34e500b80e817df7cdd62911cfc3337261a21815ca70e5bfb63f6d45260af83f"

changed /files/dataiku_mcp~1tools~1datasets.py/size

BEFORE
31508
AFTER
33889

changed /files/dataiku_mcp~1tools~1evaluation_stores.py/sha256

BEFORE
"cee3a0367a33532e9cdbbabd526e1b3c89e97c304c52ba2937139d86bdd0cc7e"
AFTER
"ae203a57dce4e123c411fabcf2d25bbfbc4964bba395c23b3cc2ef02c80a84f2"

changed /files/dataiku_mcp~1tools~1evaluation_stores.py/size

BEFORE
4819
AFTER
4929

changed /files/dataiku_mcp~1tools~1flow.py/sha256

BEFORE
"c5001a225a76d083bb086d1471ab3a3654925b8ad6c8a416b8c587cc86486960"
AFTER
"acba8b3c45cd4b3ffd3880e0499a5d0dc1e7d189e69d409a2f910f5ed2dcc560"

changed /files/dataiku_mcp~1tools~1flow.py/size

BEFORE
14417
AFTER
14557

changed /files/dataiku_mcp~1tools~1general_settings.py/sha256

BEFORE
"ded1b8f1d1fde94070a27b3c17fcd54774f43d44b3edc9aced97652577e40126"
AFTER
"5f3ce3ad0311df26e2836a42591b92dbd15a019a8bac33b2bdaae01b86e37d98"

changed /files/dataiku_mcp~1tools~1general_settings.py/size

BEFORE
7363
AFTER
7452

changed /files/dataiku_mcp~1tools~1groups.py/sha256

BEFORE
"bd8069621f80692c6d15efa78eb1e4d0d4f70c4daf4e2f73d999854e454d906c"
AFTER
"fc1cb99ce40b3133acdad36c2b6ac27d2a8d4a11f7d1dead3de86307d28122f7"

changed /files/dataiku_mcp~1tools~1groups.py/size

BEFORE
18994
AFTER
19129

changed /files/dataiku_mcp~1tools~1insights.py/sha256

BEFORE
"de345b96861a1f794aeeef255c10a2c6e4893522de4b47aa292c246de9fca001"
AFTER
"f62d3739378989dd6172134a7143a2f98b0e7042f5952caf2b03fce02b483d95"

changed /files/dataiku_mcp~1tools~1insights.py/size

BEFORE
2744
AFTER
2854

changed /files/dataiku_mcp~1tools~1instances.py/sha256

BEFORE
"880053a31c7aad0c8e1363dfa3e8f82fea7b8a39ce9cd1c31a24470ba9f49031"
AFTER
"2542546acc83f03b7120c30e2e552fb4b2547530bf01e0f90f8aea61f22e242b"

changed /files/dataiku_mcp~1tools~1instances.py/size

BEFORE
8016
AFTER
9830

changed /files/dataiku_mcp~1tools~1jobs.py/sha256

BEFORE
"a151c67e907b21af03b29763498bb14c692ca78954b797b9f1c6575ab13c3f5f"
AFTER
"4aa853a2a3a4d6d7ae3177283a3860a5bba8ec9a4f2d295422333d218b155e1f"

changed /files/dataiku_mcp~1tools~1jobs.py/size

BEFORE
24912
AFTER
27833

changed /files/dataiku_mcp~1tools~1licensing.py/sha256

BEFORE
"157b59ac1c40c43c743727aa8806d934c2ca4672c02ed30ea7c64a504779b938"
AFTER
"158d078a3bf1e428175bb623f544697741f7d66470f8a11c64462a62fdbcd735"

changed /files/dataiku_mcp~1tools~1licensing.py/size

BEFORE
3307
AFTER
3373

changed /files/dataiku_mcp~1tools~1llms_and_knowledge_banks.py/sha256

BEFORE
"159026a27802a96fc0d3a683b369bd3d5caf1844b6332fca4821b7ea26b2b992"
AFTER
"0b9210d7801f27cad274ec8511c383095c8e6914b48c3e399603e4b7276e9216"

changed /files/dataiku_mcp~1tools~1llms_and_knowledge_banks.py/size

BEFORE
12657
AFTER
12885

changed /files/dataiku_mcp~1tools~1machine_learning~1analyses.py/sha256

BEFORE
"e8afb818d4763d8c16222f9cd3802e97d96b5aeb348fc5032780122b99fbcc1f"
AFTER
"c049ab0ad4470741aeb664488b92d9b131b6cb736a403296edc203afb9e7de1d"

changed /files/dataiku_mcp~1tools~1machine_learning~1analyses.py/size

BEFORE
10195
AFTER
10396

changed /files/dataiku_mcp~1tools~1machine_learning~1saved_models.py/sha256

BEFORE
"aaca7be92ae2e7b03d6f054c6ab74fca745dbaaf541cfe66edd8006a84478015"
AFTER
"82092e9a574cf4512ee9e8cc90d857ce86c455ecfb49379a468ba8f194a2ea54"

changed /files/dataiku_mcp~1tools~1machine_learning~1saved_models.py/size

BEFORE
3660
AFTER
3801

changed /files/dataiku_mcp~1tools~1managed_folders.py/sha256

BEFORE
"75e035fb3682a9d1f633c31267b2152a535d9bd2823a1c0457b4fd36cb38ede3"
AFTER
"5eb8976c76a5fce07a080e71abd05307ac977561285660306f0758ef68aac7df"

changed /files/dataiku_mcp~1tools~1managed_folders.py/size

BEFORE
8623
AFTER
8857

changed /files/dataiku_mcp~1tools~1plugins.py/sha256

BEFORE
"3601e0a1d18c95c6c80da216e56115751be1c3a0bfa9201d7e3258633a9931d6"
AFTER
"d83b503026dcc3648f96eb76a440f26eb51c0d70f3203c7fa194d71a182ed446"

changed /files/dataiku_mcp~1tools~1plugins.py/size

BEFORE
32950
AFTER
54470

changed /files/dataiku_mcp~1tools~1project_folders.py/sha256

BEFORE
"8b901ae8a7c1e95d219e73b1ebdc040096ad1fed822967dd56b0f49fc439c337"
AFTER
"c4b2f5addad857b0d2cdf8375c10510d1e24218c3b166d7cdf2b8f966ab2a209"

changed /files/dataiku_mcp~1tools~1project_folders.py/size

BEFORE
7580
AFTER
7738

changed /files/dataiku_mcp~1tools~1project_libraries.py/sha256

BEFORE
"8d5f9f012353f6068d388266e299d44a9e67168c8d2bf2bcfd0ebbab95e806b9"
AFTER
"264180c250e28e5cafc5099a0db891159a0ad86c777dffd3fe07d6ee2ab5d71e"

changed /files/dataiku_mcp~1tools~1project_libraries.py/size

BEFORE
21694
AFTER
21928

changed /files/dataiku_mcp~1tools~1projects.py/sha256

BEFORE
"843fbbca160d161443d6b7220d20faea717154b45b3ad28a681164cbbb22bd2f"
AFTER
"5597b1b247cbd206fbc3123dab9c648b8adfcf37078a24e6958506343c08b194"

changed /files/dataiku_mcp~1tools~1projects.py/size

BEFORE
13439
AFTER
13767

changed /files/dataiku_mcp~1tools~1recipes.py/sha256

BEFORE
"57016cda5836d41e223b1510788a260bf1a5e0273b19e965066459f8537a331f"
AFTER
"a9212fd94149e677a595a97541338f9b0bfc9f7935c4be97f29565d33a1af224"

changed /files/dataiku_mcp~1tools~1recipes.py/size

BEFORE
4891
AFTER
5001

changed /files/dataiku_mcp~1tools~1scenarios.py/sha256

BEFORE
"a7664d79751a7a26439825bef09c5e47fb80190591815eabdb01e8fbd37ea071"
AFTER
"91b4003f37b42e388ced26044c2def414214d8e790ae821e6fbad334d0edafad"

changed /files/dataiku_mcp~1tools~1scenarios.py/size

BEFORE
14117
AFTER
14377

changed /files/dataiku_mcp~1tools~1semantic_models.py/sha256

BEFORE
"b3c2cac7424a70db0854c2842d2ca0316031bdf759d716d103652414e8cf44aa"
AFTER
"b3a583be2af3fe1344fca10e7ab56d0ff6feb1afdc7d5bf75ffad3ed9b51939f"

changed /files/dataiku_mcp~1tools~1semantic_models.py/size

BEFORE
3205
AFTER
3313

changed /files/dataiku_mcp~1tools~1users.py/sha256

BEFORE
"83987175f3b5e6311c7c96ddc545e2399225b2e0f2b96f31cdc63fe72baa5f3b"
AFTER
"4bc2453720924c1aab29317578b3d90a7921ea6701ddd0ca493f0cab2d376939"

changed /files/dataiku_mcp~1tools~1users.py/size

BEFORE
11125
AFTER
11260

changed /files/dataiku_mcp~1tools~1utils~1metrics.py/sha256

BEFORE
"382d22e6bec3077dce831411f1f5819fe6052d10e42e436be500262966626a37"
AFTER
"f04a294d50e47dbc7dcf90d2f96f9a34b1966ccc4b5ed959496f056008cd045e"

changed /files/dataiku_mcp~1tools~1utils~1metrics.py/size

BEFORE
2136
AFTER
3861

changed /files/dataiku_mcp~1tools~1utils~1validation.py/sha256

BEFORE
"4c4daef28e5040e2c48a5a8db178de769d6dc9186e84f9b302defd39d238dbab"
AFTER
"5a532dad44aa0e677992d9499eeec9245d0875d8a360394925664e7f16453915"

changed /files/dataiku_mcp~1tools~1utils~1validation.py/size

BEFORE
3807
AFTER
5272

changed /files/dataiku_mcp~1tools~1webapps.py/sha256

BEFORE
"158763a01a5b614a8f9bc9114a9bb0c9c091336433c2a5132502bca88d318f14"
AFTER
"3a07be3b7c0a921755613e5c2a5d4b2246235b5ef59c21930e8eda6bdba9b548"

changed /files/dataiku_mcp~1tools~1webapps.py/size

BEFORE
4572
AFTER
4712

changed /files/dataiku_mcp~1tools~1wikis.py/sha256

BEFORE
"6bedc0e225f95d6037804f619c7f092371c6998080de799ef8039c9071e0e8af"
AFTER
"e6abd1a316b45e55fae2d7b8450e4af9fd829080582d77eeababe74ab37257ee"

changed /files/dataiku_mcp~1tools~1wikis.py/size

BEFORE
3364
AFTER
3474

changed /files/docs~1capabilities.md/sha256

BEFORE
"5aef9f27c9d55a43294c0d889ef6c738285fd5fe29682f4bfc1776d88de6f397"
AFTER
"3fff28e62125381fcd798744d04da74ce55984d7cb2f239547ad2e5303f7f731"

changed /files/docs~1capabilities.md/size

BEFORE
8459
AFTER
10961

changed /files/docs~1http-deployment.md/sha256

BEFORE
"8c27c2a9b8c7997f16d747868d90f7756d8b61c23c8e0ad9c99a6592d5f7ab46"
AFTER
"a152442cfafd42c28b6964c339630432ad30c69bd23ca5d18c0a45415e280074"

changed /files/docs~1http-deployment.md/size

BEFORE
17076
AFTER
17920

changed /files/pyproject.toml/sha256

BEFORE
"f5f19f687d0953ea381717ceef6e6d933d681487e41affa030ecf1c0f31c1d5c"
AFTER
"fa8ceb8d6b56990d40caf62ee1bb25e8c8a2bd9b685e07c969b51c1c17cd25da"

changed /files/pyproject.toml/size

BEFORE
2442
AFTER
2538

changed /files/runtime~1run_mcp.py/sha256

BEFORE
"7b28b79d2bc16f11f87e7b04724d8ae91d232e930d9b9e663cfab8a6baa66d24"
AFTER
"d689671a0cabd01eed2598433b56eb659e58b176814b8495cb66c8df8eed1549"

changed /files/runtime~1run_mcp.py/size

BEFORE
3144
AFTER
3391

changed /files/runtime~1run_mcp.py.lock/sha256

BEFORE
"ba56a3353ee436538df59d209ee54daf1ee155c8b2cd8e04668b65f3c98e25e8"
AFTER
"9c11c8ce0209672c15406d504fdab8c59207209d4d5f0c737b65f4437c1b4497"

changed /files/runtime~1run_mcp.py.lock/size

BEFORE
440835
AFTER
460907

changed /files/scripts~1build_http_plugin.py/sha256

BEFORE
"bdf423a496c2a19bdcfc5fa78bc6e3f1e22bbb35f2eae6393a41b2783e1633c9"
AFTER
"4079975c611c70caccdf01e4935939f35a5ecb2faa0276061ad7e00fd411a527"

changed /files/scripts~1build_http_plugin.py/size

BEFORE
5535
AFTER
6263

changed /files/scripts~1check_release.py/sha256

BEFORE
"49d537a24e31f15b0c4f4070a4e3e41b9da90410ef9828897d7466319cc3503a"
AFTER
"5ba518018e051242428b314247b8a3e3da796f80dddc9db85ce1cfa28a7f577e"

changed /files/scripts~1check_release.py/size

BEFORE
4459
AFTER
4778

changed /files/scripts~1http_plugin_assets~1skills~1dataiku-headless-setup~1SKILL.md/sha256

BEFORE
"c2e46ee0337d1b02c5ab1137ab38fb8b18883450b99e2778659d9c2d2a049ccf"
AFTER
"c02b9d42a4a331f7165cbe1ab9e876eded223f46b25af8d3fbf560ef261d717d"

changed /files/scripts~1http_plugin_assets~1skills~1dataiku-headless-setup~1SKILL.md/size

BEFORE
2293
AFTER
2315

changed /files/skills~1dataiku-headless-setup~1SKILL.md/sha256

BEFORE
"2c6649bec661e37992cb07b69bbdb2bb771ab8e21209184e9a9f7481e2c2f4ea"
AFTER
"3904b563fc2b6fb8e42419b7312c304c9a6716d9b9cc047fbef07266c66fbd23"

changed /files/skills~1dataiku-headless-setup~1SKILL.md/size

BEFORE
3828
AFTER
7791

changed /files/skills~1dataiku-headless~1SKILL.md/sha256

BEFORE
"31d203c2c0e829231828aaf0b0e93d8381c7e0341d7495403a259d11cb5fcac5"
AFTER
"939d7c5ee0d34bd8ee4b8a9846b93fde4484f48ca2c71b1c9f6388602406f138"

changed /files/skills~1dataiku-headless~1SKILL.md/size

BEFORE
6657
AFTER
8178

changed /files/skills~1dataiku-headless~1references~1administration.md/sha256

BEFORE
"0824744f09f16699e9ed84b7a2b0c41451b1e432015e08eb5e48ce612cb97376"
AFTER
"305fc51f0c0d3f16b43d7da4935c044215f60b7d724f4a5cd0a3e09f2578b87a"

changed /files/skills~1dataiku-headless~1references~1administration.md/size

BEFORE
996
AFTER
1108

changed /files/skills~1dataiku-headless~1references~1administration~1code-environments.md/sha256

BEFORE
"06796494f6c410a7de502771cc04fc1f51673f756177ec36faf1822c1af26cd1"
AFTER
"69df1427dcccbf453d415dd6580e1a67f96a6cb66aba636502aa65a813e056b8"

changed /files/skills~1dataiku-headless~1references~1administration~1code-environments.md/size

BEFORE
5657
AFTER
5659

changed /files/skills~1dataiku-headless~1references~1administration~1plugins.md/sha256

BEFORE
"a3a313fc2cf19931126fe21ca0e7f5e5cbdb27dc6faa87765b5efca3978b1a01"
AFTER
"b95b340d4eaa8c4d26b8871d43ba0157d00a2a105e27e9d207e307e457bc5f76"

changed /files/skills~1dataiku-headless~1references~1administration~1plugins.md/size

BEFORE
6268
AFTER
12584

changed /files/skills~1dataiku-headless~1references~1agents~1agent-tools.md/sha256

BEFORE
"9935fb9ea715f6ef67c2880473f3fe782f55847cdfbc3d6c6ce01b3c25272864"
AFTER
"1a6cff6687627faf7d5951dfd4ea8980d9c71631a0937c7f0c9dfe3f0479d429"

changed /files/skills~1dataiku-headless~1references~1agents~1agent-tools.md/size

BEFORE
2223
AFTER
2498

changed /files/skills~1dataiku-headless~1references~1cobuild.md/sha256

BEFORE
"0c8ea21afa02a45e56f9775cb7c35d03543295a019740943b8f6100df7f6e5c9"
AFTER
"d2eddb132211b90b452f6170d9badfdfd4f08bfe7577e0a0b2dea6906cef8ebb"

changed /files/skills~1dataiku-headless~1references~1cobuild.md/size

BEFORE
8820
AFTER
9367

changed /files/skills~1dataiku-headless~1references~1container-execution.md/sha256

BEFORE
"7baf9d12146f01b0fa7765250359605650d8f84bdd3b3365fd17f1d01b59f2d8"
AFTER
"f2d59c5b9e84919c6ec60f241a9c968fc76f6febfa840f7bf67e5e34bc75c8ed"

changed /files/skills~1dataiku-headless~1references~1container-execution.md/size

BEFORE
4081
AFTER
4178

changed /files/skills~1dataiku-headless~1references~1dashboards.md/sha256

BEFORE
"718c9729c80458fb5247e3bd0ee49c256301a9fba646ff75c3b238e9a85e966e"
AFTER
"8def1d6fc7073afedaf97454159b9e2d74f4aea941d73cb4cb72684dc3c35a3e"

changed /files/skills~1dataiku-headless~1references~1dashboards.md/size

BEFORE
1716
AFTER
1990

changed /files/skills~1dataiku-headless~1references~1datasets.md/sha256

BEFORE
"f5a6c26f548c2671b23f7a54f650975008dcfe6f498cd7ae21b54c54821c5068"
AFTER
"cd564883ead74fa651bdff4e376c7f6094e17c2ed8e8d7e6895b0459fc9a5ce9"

changed /files/skills~1dataiku-headless~1references~1datasets.md/size

BEFORE
5275
AFTER
6876

changed /files/skills~1dataiku-headless~1references~1datasets~1uploaded-files-datasets.md/sha256

BEFORE
"d46fcf7b4f3e261c07198026e7e8f71ec6e1f54c6f81c8e833f6bec6e73959fc"
AFTER
"0fa5c92ff78b29b80699490b07f88f321d5f026df647f9584a7817cdf141fd9b"

changed /files/skills~1dataiku-headless~1references~1datasets~1uploaded-files-datasets.md/size

BEFORE
1870
AFTER
1958

changed /files/skills~1dataiku-headless~1references~1insights.md/sha256

BEFORE
"7685ea0f88fe9278e8f8e10b9fa19cca170d8f6dfd1773d7c35db5b743ae1f9e"
AFTER
"97fc899dafab540a877f7514683ec6649059f939038761735b6d9080f704d136"

changed /files/skills~1dataiku-headless~1references~1insights.md/size

BEFORE
2563
AFTER
2835

changed /files/skills~1dataiku-headless~1references~1jobs.md/sha256

BEFORE
"68b447c6c17d58a369ac770d1f0b334ff73e7d143a158124ef9346213b0391f7"
AFTER
"ea3ed21f5ebc0c4e906a32eebbc1389a33743d6fd5ac233e3b2948e43b62219a"

changed /files/skills~1dataiku-headless~1references~1jobs.md/size

BEFORE
3017
AFTER
4566

changed /files/skills~1dataiku-headless~1references~1llms-and-knowledge-banks.md/sha256

BEFORE
"17dbbf83558267866b54895a5adede2287a69333ef78980de881a7e1baf4e9cd"
AFTER
"29b77eecc4c4b01b17410f6bb63f23f1e4288055e5bf98a15112f9a426bcd52e"

changed /files/skills~1dataiku-headless~1references~1llms-and-knowledge-banks.md/size

BEFORE
2418
AFTER
2354

changed /files/skills~1dataiku-headless~1references~1managed_folders.md/sha256

BEFORE
"62756d70ca577ff04d3e8467212e76ad23a9234568e6daccc0abd2fb95325cc0"
AFTER
"318802c108274c6211260b1c468ee0957764b656c830a313a8cb9b1cbf888ebd"

changed /files/skills~1dataiku-headless~1references~1managed_folders.md/size

BEFORE
3058
AFTER
3177

changed /files/skills~1dataiku-headless~1references~1migrations.md/sha256

BEFORE
"dca73f35e614272dce06c4de7b62a36919c7d5133bfa593e708fbe312018b7cd"
AFTER
"e19be2d30843ebd3c1ec0ef8add516416466136d866bfcdcbaf94a3c7cf1e571"

changed /files/skills~1dataiku-headless~1references~1migrations.md/size

BEFORE
10549
AFTER
10708

changed /files/skills~1dataiku-headless~1references~1migrations~1sources~1excel~1guides~1validate.md/sha256

BEFORE
"55af8c5c5dede349232da34ce340df35dd4204ef239962b9622b5ff8a9a08393"
AFTER
"15acdd4710d69c4f025bc85226eb3b8e9b71692fdaca566db3897b53a5fa17ae"

changed /files/skills~1dataiku-headless~1references~1migrations~1sources~1excel~1guides~1validate.md/size

BEFORE
6609
AFTER
6634

added /files/skills~1dataiku-headless~1references~1plugin-development.md

BEFORE
Field was absent
AFTER
{
  "sha256": "6eb2f214ffaec11b515e98e744f4366fa7d332b0f8a68112865ccacffedea723",
  "size": 7231
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1agent-tools.md

BEFORE
Field was absent
AFTER
{
  "sha256": "192d514c4a3d45c3a0718d7ebf18f918fa581c086dc9e452f3f410842122366c",
  "size": 2878
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1agents.md

BEFORE
Field was absent
AFTER
{
  "sha256": "2c037d78e1f2a0f814db9716b9e94d65e1f948eb27534ef33fc66f9e73b3b2ae",
  "size": 655
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1connectors.md

BEFORE
Field was absent
AFTER
{
  "sha256": "d2752bdc3630933891a340c63e60157656b923c2e396be9b22deabf2db361cfd",
  "size": 2451
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1file-formats.md

BEFORE
Field was absent
AFTER
{
  "sha256": "67f6313aee6cc082510bbeae7929896eceeec52a33692f430764264b009bb263",
  "size": 868
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1guardrails.md

BEFORE
Field was absent
AFTER
{
  "sha256": "674dfb1b84c55c056e9632a17fc0f6005d6188cf9877e5bab25162302bdefd62",
  "size": 666
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1llms.md

BEFORE
Field was absent
AFTER
{
  "sha256": "7fa9d085aa7c158a813a333ce36564e39c77e952238bc35a8cec69c21aea2254",
  "size": 2141
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1machine-learning.md

BEFORE
Field was absent
AFTER
{
  "sha256": "dd583b98b540d99b42e80a461629a0ea497d31c3b50ad9b36ce903a842a16be3",
  "size": 1608
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1macros.md

BEFORE
Field was absent
AFTER
{
  "sha256": "a1303487a9da283dffc7a49ae898997bfcf374899685932f9398fc0f0b1e6ca2",
  "size": 1343
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1prepare-processors.md

BEFORE
Field was absent
AFTER
{
  "sha256": "4950cb33ed9e3448f8775ede08cfb9b36bb9fe4bd9f38a8330214364b802b8b6",
  "size": 1054
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1recipes.md

BEFORE
Field was absent
AFTER
{
  "sha256": "b59c5df3bd779a891f698d7ed3bbaa1fb38d12a57c07a5a620a714c1fa251e0c",
  "size": 2062
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1settings-checks.md

BEFORE
Field was absent
AFTER
{
  "sha256": "575e8494ebd9b93eaa0a16d0b5acc2916a4e6d0816bc79e7b61e05f918852564",
  "size": 1593
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1structured-agent-blocks.md

BEFORE
Field was absent
AFTER
{
  "sha256": "c52498e46a243de7a743a26f817bf8c9d1c838bf5a436da2f1f6d67a23d82fd6",
  "size": 735
}

added /files/skills~1dataiku-headless~1references~1plugin-development~1webapps.md

BEFORE
Field was absent
AFTER
{
  "sha256": "9cf94185bbe4df97ffe5a287057ecc0b245dc028b0a88958836f7a03b0ace14a",
  "size": 1511
}

changed /files/skills~1dataiku-headless~1references~1project-libraries.md/sha256

BEFORE
"f832d5c57ff8fc225ce92e68fef2629b72dda859fff1c4dea39f649175753067"
AFTER
"12b82f7bbd311b8acbd3a269914b6c74430da11c12258a2a3a5297720e903a0b"

changed /files/skills~1dataiku-headless~1references~1project-libraries.md/size

BEFORE
3414
AFTER
3554

changed /files/skills~1dataiku-headless~1references~1projects.md/sha256

BEFORE
"a8064e4661e2f15cf27731de84b61efed76053f4c33a830918acdb001e8d3b18"
AFTER
"0a944ee2dd5687d4691b8c4011af697989868a2bf54c843321b1c0042b5598fd"

changed /files/skills~1dataiku-headless~1references~1projects.md/size

BEFORE
3644
AFTER
3775

changed /files/skills~1dataiku-headless~1references~1projects~1settings.md/sha256

BEFORE
"8653d6bba9acc1fee41908046b555db05ae7b190cef9dc09b43866ed8e34d589"
AFTER
"bff2018748f3d1acc78a394b2f28e13cc9411c40cd821499210165f209907463"

changed /files/skills~1dataiku-headless~1references~1projects~1settings.md/size

BEFORE
6088
AFTER
6190

changed /files/skills~1dataiku-headless~1references~1recipes.md/sha256

BEFORE
"e7166e875ddbdc0569b1b36495a06e4806afeb584619dc067c28c08b723af3d9"
AFTER
"cc0f1503af28968e349fa8de9f0ff6a85c72544d2dc646897ebbb23c65def9c9"

changed /files/skills~1dataiku-headless~1references~1recipes.md/size

BEFORE
5868
AFTER
5959

changed /files/skills~1dataiku-headless~1references~1semantic-models.md/sha256

BEFORE
"5a7269b5674291b6665b471c6442bbde318ad5aaad5b23ad4ecab5cb6fccf9fe"
AFTER
"fc33502ea7a1111d2dc572e505589d01c7f78c8e09e40fe043ab53eb6c891448"

changed /files/skills~1dataiku-headless~1references~1semantic-models.md/size

BEFORE
3666
AFTER
3662

changed /files/tests~1conftest.py/sha256

BEFORE
"c1433084e3645f7b34aa8d470a3c698f8f2dad0ebd8cf40ab62b4e785f4107b4"
AFTER
"5c4629703c494648293d1cd6819145e24c125a1832c0652a953e07379b7318e8"

changed /files/tests~1conftest.py/size

BEFORE
2137
AFTER
2277

added /files/tests~1test_dataset_metrics.py

BEFORE
Field was absent
AFTER
{
  "sha256": "23e4f3a936278c8de624dc078c7a42f5950dec1be195de07c05b0eabb95e2c01",
  "size": 6955
}

changed /files/tests~1test_execution_tools.py/sha256

BEFORE
"228bde49778984188bba14a5078db4188da5e3a36335ba444a152b284eab7bbb"
AFTER
"7655056bc8d1d32611945df29bb18a901e260a3507b6bd70485d6eb68f3f9bfd"

changed /files/tests~1test_execution_tools.py/size

BEFORE
40724
AFTER
41150

changed /files/tests~1test_http_middleware.py/sha256

BEFORE
"ba5894f3d2da7251742409d20906e46ccdd671798a55bea98ce8178cd6b55991"
AFTER
"2d75ab0ff3aa2b2a9238e84d7c93670c39a37f8ed93f2a5fd4e669334dfe8db1"

changed /files/tests~1test_http_middleware.py/size

BEFORE
7367
AFTER
9590

changed /files/tests~1test_http_plugin_renderer.py/sha256

BEFORE
"fb9554fb1a91331e37588c917b7b346acc8a97b89ba1d25d8bf5702ba09f9824"
AFTER
"82110e41742086c8f16a0c007257fd21bff12d7d2dfde45cd75c607feca5e2e9"

changed /files/tests~1test_http_plugin_renderer.py/size

BEFORE
4682
AFTER
6160

changed /files/tests~1test_instance_pinning.py/sha256

BEFORE
"259c5f6fe0ff6f8d85d508f54b8a0fd4591c1cd6dff521572bc581f5588a0653"
AFTER
"51c6acd0c77948fb43f15047ad992191cd6b7afed2e998a024e5c11becb400c2"

changed /files/tests~1test_instance_pinning.py/size

BEFORE
2572
AFTER
2564

added /files/tests~1test_instance_policy.py

BEFORE
Field was absent
AFTER
{
  "sha256": "c7c5fa83139803cdb4a020def372758b8b5b26cc5d020d08aff6b8bc684c54b7",
  "size": 13875
}

changed /files/tests~1test_instances.py/sha256

BEFORE
"256a35e094d16778febf0fcda0e98bd423e01f36c71a7fc651e382cc64120eac"
AFTER
"23ea6368e1e0addacef1dc160b98cc295daa25902105562903bd6c1cd438a524"

changed /files/tests~1test_instances.py/size

BEFORE
6503
AFTER
12441

changed /files/tests~1test_launcher_cli.py/sha256

BEFORE
"a6b8bd92af98b415f72d97f1d41fbe4be901be40849c0a0a3baff43b67035347"
AFTER
"a93f9cb8377c5275d9f292285a99571dcdb0f4f2679c99afcfce9c1355945290"

changed /files/tests~1test_launcher_cli.py/size

BEFORE
4105
AFTER
4359

changed /files/tests~1test_onboarding_ui.py/sha256

BEFORE
"e9c722822b6e2981e88bd91908440bc3e3aa888c15c75c15602990687a0288ec"
AFTER
"3662fbd3ba45572fb5b532fd1669f9affb692808f50d8e32729063fe2387625b"

changed /files/tests~1test_onboarding_ui.py/size

BEFORE
1881
AFTER
1042

added /files/tests~1test_plugin_futures.py

BEFORE
Field was absent
AFTER
{
  "sha256": "75d9ed23b3eb280ddc31bde4819479b5ec190989ac09f35ec7e52b23ef2bf59b",
  "size": 4846
}

changed /files/tests~1test_plugin_packaging.py/sha256

BEFORE
"eabdcd46b95eb078904a2789791d8af9c6f37a3784753ae1cee5178e6d0ed493"
AFTER
"01bee934a7d31c3892ad729732ff4bb9d377bed0fa87ca7b847d629ed4d11d2f"

changed /files/tests~1test_plugin_packaging.py/size

BEFORE
2215
AFTER
6547

changed /files/tests~1test_plugins.py/sha256

BEFORE
"880ae32c7d6dd5e747aa19ad23635b2cff677eb337dbc2c41b2839cb37f2f893"
AFTER
"002019bb10e95a766452613ef8c972ba959d947cd80eeeed38528b37bfdd982f"

changed /files/tests~1test_plugins.py/size

BEFORE
37595
AFTER
70849

changed /files/tests~1test_release.py/sha256

BEFORE
"506f8230f600e200654cb34f03ed689670a0f4a423e39a1835c404a6a67ef3d3"
AFTER
"6c2a241bc9d697f7e30e598d7ff293283e7ea58f21ebef7ced6637be9d2e8d79"

changed /files/tests~1test_release.py/size

BEFORE
10807
AFTER
11372

changed /files/tests~1test_setup_server.py/sha256

BEFORE
"35e2d7aefb6048aa6bf64d660f5451ed5f41d2ddc1b4445a5b4fa643d05da927"
AFTER
"9a7608a6074d1f3a2cf251556dfe67d20fdc0f909653da897d33fd18f05349c5"

changed /files/tests~1test_setup_server.py/size

BEFORE
7356
AFTER
20230

added /files/tests~1test_tls_trust.py

BEFORE
Field was absent
AFTER
{
  "sha256": "33a58568d442dc2a6357db92fb04a695ee4e4c29a9627b9e6b246c0234a34791",
  "size": 5208
}

changed /files/tests~1test_tool_surface.py/sha256

BEFORE
"465e93e3ac3714e95409a3bc102d63181b7f9981a47422813c68ca79a64e8cc9"
AFTER
"285c9ebf998a189e8d9d30d1913cea7f63187bc7490c59478dc3ef789e047a80"

changed /files/tests~1test_tool_surface.py/size

BEFORE
7306
AFTER
8670

changed /files/uv.lock/sha256

BEFORE
"c4b0e88fd73ec75a00e147fd8f5cf34d432177ea9ecec36199e35d250d173c06"
AFTER
"6249f71d815813a22c5930a3480b49e59d16d6366dd3873ed87fdfff7e51ff30"

changed /files/uv.lock/size

BEFORE
418641
AFTER
419395
Full snapshot data
{
  "files": {
    ".agents/plugins/marketplace.json": {
      "sha256": "5a1a724844a602acdab8e4f6ffe307b0f7772af0b6c437d6425d8142d21b960a",
      "size": 659
    },
    ".claude-plugin/marketplace.json": {
      "sha256": "c142b21c6e1a8f24e5cf2dd6ce31c5c9441a58fe3a64d8f3d8efc6c2e10e7d5a",
      "size": 603
    },
    ".claude-plugin/plugin.json": {
      "sha256": "932135fd42ae2b929c46b8ac93df3d2e2fb8b1d51a7a8a6057e1227edf2b5ead",
      "size": 918
    },
    ".codex-plugin/mcp.json": {
      "sha256": "ad37dba1daf5b808c8c02044c413300dd45820fe9e50aef4897fd1c29a0f41b4",
      "size": 623
    },
    ".codex-plugin/plugin.json": {
      "sha256": "ef60afa841515d5c97c609ed6fdf6c2895dfda1f7e02f35c1e6dc4a61e520e44",
      "size": 7131
    },
    ".cortex-plugin/plugin.json": {
      "sha256": "3436a9f9aa992b405d9868c83114966d7537bdd3cc35ef779d29739d13b35a05",
      "size": 760
    },
    ".cursor-plugin/marketplace.json": {
      "sha256": "8b247aec5b9cbbbaecb9be45aabbd828f17005f8bc79500ef32df0ab8370bab5",
      "size": 578
    },
    ".cursor-plugin/plugin.json": {
      "sha256": "ad1226956172fc34d4e500fd770c91be6613c593cc1e804dcb9ff37420f05cf0",
      "size": 818
    },
    ".dataiku/http-config.json.entra-example": {
      "sha256": "5747e2239c76196d40e42cab566662c1bfaa8eeb9712439b15877b1fb2291878",
      "size": 602
    },
    ".dataiku/http-config.json.generic_oidc-example": {
      "sha256": "93ae065bc832b3db9bf07c154e6ce5e0dcd3944a77bc82ae566d8a695e41b6db",
      "size": 880
    },
    ".dataiku/stdio-config.json.example": {
      "sha256": "1aa6d21a8f749d2fc75cb537aca4e4a0776beedd0c813a3bfbfd800f44e1ab46",
      "size": 396
    },
    ".env.example": {
      "sha256": "a7515de1a292b930d316499c398fc32486ea9dbe53d7ab5c5cdd763e3bbb0baa",
      "size": 659
    },
    ".github/ISSUE_TEMPLATE/bug_report.yml": {
      "sha256": "af357df51db5e8f419f9bdacdb6ebcaf51b402edb8358cfe63f32db6e835045d",
      "size": 1391
    },
    ".github/ISSUE_TEMPLATE/config.yml": {
      "sha256": "55a4027c6c8659ae2796238449c127348db0403fe6c6efc4463ee0b4e4177112",
      "size": 211
    },
    ".github/ISSUE_TEMPLATE/feature_request.yml": {
      "sha256": "e6874c531ba5a4fa5f609f947a433582c3681b730e1b647334a680ed28ee8e67",
      "size": 970
    },
    ".github/ISSUE_TEMPLATE/question.yml": {
      "sha256": "e9d5f06a348eb5a10352637b3ecb1db80a4e004693aae67108263e17438aa0b4",
      "size": 706
    },
    ".github/ISSUE_TEMPLATE/rfc.yml": {
      "sha256": "4ac111ad95bbccefc563c236c073cb83d94796a5b96b4e3f1d89a3b54571ef3b",
      "size": 1298
    },
    ".github/cla/Black Dataiku Lockup Logo.svg": {
      "sha256": "01283aaa3c3f6d5b86d9a95ee4f148d6d4ff27d881ff8c4d2dfbf1b5024bffff",
      "size": 4025
    },
    ".github/cla/CLA.md": {
      "sha256": "73bbf78d5ea488b24d5651d591b72c8ecac8fad9742af8b7b8516878567762c5",
      "size": 6940
    },
    ".github/plugin/marketplace.json": {
      "sha256": "8b247aec5b9cbbbaecb9be45aabbd828f17005f8bc79500ef32df0ab8370bab5",
      "size": 578
    },
    ".github/plugin/plugin.json": {
      "sha256": "b306cbbdfc7d689560ebb27e44dbb8467d82284b822c3ae7a0a3674b5eed372a",
      "size": 848
    },
    ".github/workflows/bump.yml": {
      "sha256": "7a1bab86b7f396cd78b81bc1a41a51e89dac38de8920d4838ceb82c22f1d19b3",
      "size": 7810
    },
    ".github/workflows/ci.yml": {
      "sha256": "61d87c6627ec13adb097942805ee3a7d244b488fd0e46e05433cca99151d9cdd",
      "size": 3239
    },
    ".github/workflows/cla.yml": {
      "sha256": "e5edef1fe8d176273c561043d6248f5bf03e5c7f56855a40a709e1d38d4ece94",
      "size": 1049
    },
    ".github/workflows/pr-title.yml": {
      "sha256": "1360732d6a7925568584c1d40f315cc549ae817f1cefbfd403b8ae069432c8e2",
      "size": 754
    },
    ".github/workflows/release-source.yml": {
      "sha256": "ce60f64b5592e63eb14f6285ccf3bcbfef18b045b2290e1ea07fb24cb83ec239",
      "size": 908
    },
    ".gitignore": {
      "sha256": "f1365c8f3ab3df2aaf63c1261f08f96a8275358b00c1a91453f4579f79171309",
      "size": 1051
    },
    ".pre-commit-config.yaml": {
      "sha256": "05a96ba6d59de85c010cf61d681c98de0300e2e3805114ec49b1f26124dded2b",
      "size": 1611
    },
    "AGENTS.md": {
      "sha256": "dc0554d0814a0604032c2dcf555419093c590c58f3de4142d4a2fd7942caf474",
      "size": 7675
    },
    "CHANGELOG.md": {
      "sha256": "1c697b1ce71dec51b0cc9a12d96b0e426ea897b6f03106c252c8376b5be8466b",
      "size": 4695
    },
    "CLAUDE.md": {
      "sha256": "f8d6e95dab128219768048d6d57147a548414ee71ba70d12f710ac3b7c62e5ef",
      "size": 99
    },
    "CODING_STANDARDS_AND_STRUCTURE.md": {
      "sha256": "3d3845075a21e2814e9b517f16aa85970177e8245e7ee382bb48aa9b476a802c",
      "size": 15343
    },
    "CONTRIBUTING.md": {
      "sha256": "a9fff4493c906d596e1f03727fea0d766860c84eadacec191870335a81238931",
      "size": 2275
    },
    "CONTRIBUTORS.md": {
      "sha256": "1b3b498a5e1fcd6ec0ecfdca936ec74581081517bc703fe3ae74f3d6e459d7be",
      "size": 938
    },
    "LICENSE": {
      "sha256": "f76a6b54d58e110e873a18683fe9f6f34788b980a60278456699adaf96f88560",
      "size": 10705
    },
    "NOTICE": {
      "sha256": "14a8e7d5123c6c13f89faedf678f44edae11074936b39322c7f75269fa3b128d",
      "size": 12906
    },
    "README.md": {
      "sha256": "9ed1f335c291dfac7b440422173546299ca4e229ccc779e6bf0337150ddaa39d",
      "size": 20661
    },
    "RELEASE.md": {
      "sha256": "4a6934d9139b239651ca980e57ce04ac0ce7bca4ca9a37925f157acb3df4130c",
      "size": 9608
    },
    "dataiku_mcp/__init__.py": {
      "sha256": "32fdfa0c2ecf34e83161dd09f338358849606eb462a02ebe9c31342a339852a2",
      "size": 1486
    },
    "dataiku_mcp/auth.py": {
      "sha256": "fb58c4d71b26c6b75b56c46a208d2fa98c67d67bf1df4e543bdc1568946d3c7c",
      "size": 7376
    },
    "dataiku_mcp/config/__init__.py": {
      "sha256": "73ee44c473af185a5031332c9ae2da1c98d23611303bbdbc3f591f157e7511bc",
      "size": 641
    },
    "dataiku_mcp/config/files.py": {
      "sha256": "0edb37c148e44720cbdc6127c323156dbe31bc0f2e181dfd979c19399cff2796",
      "size": 1813
    },
    "dataiku_mcp/config/http.py": {
      "sha256": "fdaf8c5f98f8ef6dc62a4c06b0cd47055611306681f0d3adc256ab6e0ad408f2",
      "size": 4748
    },
    "dataiku_mcp/config/models.py": {
      "sha256": "d1f7e86224c8079e912297c966528aa2343c170a035d7b6cb6ed7abf1299fe6f",
      "size": 7389
    },
    "dataiku_mcp/config/request.py": {
      "sha256": "072f066b2956c6962e0b231a221ff84a0695f392844f2c92426bd6aeb26fead3",
      "size": 4773
    },
    "dataiku_mcp/config/stdio.py": {
      "sha256": "1de4adbc3887895dabd136feebf47391e0885e6863980feefe7c7605ea37ba5a",
      "size": 14141
    },
    "dataiku_mcp/executors.py": {
      "sha256": "3049b2c090e314915215841c51b2181e00e4cadad486288ddd499a006ce72bc5",
      "size": 1696
    },
    "dataiku_mcp/instance_policy.py": {
      "sha256": "a62e0be2e7aa8c9fc1e0fbc57cc60f970e78a5b80aa511cacba971d6d46483a5",
      "size": 2438
    },
    "dataiku_mcp/server.py": {
      "sha256": "675914e7bba7e287949ab3f8d622c27a993149f86541d293f682a1a210815145",
      "size": 6544
    },
    "dataiku_mcp/setup_page.html": {
      "sha256": "788db788817813489f5b94ea72d2497368c93b3fb0307787445afa941ab4a77a",
      "size": 36742
    },
    "dataiku_mcp/setup_server.py": {
      "sha256": "1721fc394eb0e2b3417c8287fa95c3776c5580cb13c97e03a91db2548608845d",
      "size": 20373
    },
    "dataiku_mcp/tools/__init__.py": {
      "sha256": "4802006383d966dd9b16dbee30e31a8a4dc6c869df53ad5d508fa59108ea0b01",
      "size": 624
    },
    "dataiku_mcp/tools/agent_reviews.py": {
      "sha256": "fcb8c88bb520dc6689b9b98045cff61387310ea0917aafa70bf2217adf11a552",
      "size": 8694
    },
    "dataiku_mcp/tools/agents.py": {
      "sha256": "9b83b82a3197154eb647c47575c81bbb57f51d68073ef19a3139def312fad391",
      "size": 8334
    },
    "dataiku_mcp/tools/cobuild.py": {
      "sha256": "c7b3f8180c280709eab3a6118b71038c61282b7c0044b67622676a978cacf33c",
      "size": 19640
    },
    "dataiku_mcp/tools/code_environments.py": {
      "sha256": "0eff238e901c71cea7ac6f567477466178dc476b9269cfffa1d4ce31e72960f8",
      "size": 18761
    },
    "dataiku_mcp/tools/connections.py": {
      "sha256": "1572ce248bfe12e907498fe6ffeb47c4770cdddd32e47a9582518d66361563c1",
      "size": 8962
    },
    "dataiku_mcp/tools/container_exec.py": {
      "sha256": "43dbff406fc6948c765c39ad522d2560e05e50706740ea432b63e0bfc34c3785",
      "size": 7662
    },
    "dataiku_mcp/tools/cross_project_sharing.py": {
      "sha256": "31714e0f338a562c2341e10c0b26bf1512a985c0274a3f32bf5a97cc8a689418",
      "size": 2532
    },
    "dataiku_mcp/tools/dashboards.py": {
      "sha256": "a03074fb9b7971759c59b97d539d37a685633cf490aae32edc61cbe484d5f1a7",
      "size": 2954
    },
    "dataiku_mcp/tools/data_collections.py": {
      "sha256": "fd1987886cd970fa8069fa4d7a34c1d645f254e36f3a9b3a25554ddf5c7f3659",
      "size": 2686
    },
    "dataiku_mcp/tools/data_quality.py": {
      "sha256": "5cc50a9b82aec30626052e92434df3b474c8b72c982c9e885ded18e3b98b1886",
      "size": 11543
    },
    "dataiku_mcp/tools/datasets.py": {
      "sha256": "34e500b80e817df7cdd62911cfc3337261a21815ca70e5bfb63f6d45260af83f",
      "size": 33889
    },
    "dataiku_mcp/tools/evaluation_stores.py": {
      "sha256": "ae203a57dce4e123c411fabcf2d25bbfbc4964bba395c23b3cc2ef02c80a84f2",
      "size": 4929
    },
    "dataiku_mcp/tools/flow.py": {
      "sha256": "acba8b3c45cd4b3ffd3880e0499a5d0dc1e7d189e69d409a2f910f5ed2dcc560",
      "size": 14557
    },
    "dataiku_mcp/tools/general_settings.py": {
      "sha256": "5f3ce3ad0311df26e2836a42591b92dbd15a019a8bac33b2bdaae01b86e37d98",
      "size": 7452
    },
    "dataiku_mcp/tools/groups.py": {
      "sha256": "fc1cb99ce40b3133acdad36c2b6ac27d2a8d4a11f7d1dead3de86307d28122f7",
      "size": 19129
    },
    "dataiku_mcp/tools/insights.py": {
      "sha256": "f62d3739378989dd6172134a7143a2f98b0e7042f5952caf2b03fce02b483d95",
      "size": 2854
    },
    "dataiku_mcp/tools/instances.py": {
      "sha256": "2542546acc83f03b7120c30e2e552fb4b2547530bf01e0f90f8aea61f22e242b",
      "size": 9830
    },
    "dataiku_mcp/tools/jobs.py": {
      "sha256": "4aa853a2a3a4d6d7ae3177283a3860a5bba8ec9a4f2d295422333d218b155e1f",
      "size": 27833
    },
    "dataiku_mcp/tools/licensing.py": {
      "sha256": "158d078a3bf1e428175bb623f544697741f7d66470f8a11c64462a62fdbcd735",
      "size": 3373
    },
    "dataiku_mcp/tools/llms_and_knowledge_banks.py": {
      "sha256": "0b9210d7801f27cad274ec8511c383095c8e6914b48c3e399603e4b7276e9216",
      "size": 12885
    },
    "dataiku_mcp/tools/machine_learning/__init__.py": {
      "sha256": "e0b2ced16330ce7ba69a22dcb37abcaea2fde6e5413f3862f914a3aa6b840033",
      "size": 611
    },
    "dataiku_mcp/tools/machine_learning/analyses.py": {
      "sha256": "c049ab0ad4470741aeb664488b92d9b131b6cb736a403296edc203afb9e7de1d",
      "size": 10396
    },
    "dataiku_mcp/tools/machine_learning/saved_models.py": {
      "sha256": "82092e9a574cf4512ee9e8cc90d857ce86c455ecfb49379a468ba8f194a2ea54",
      "size": 3801
    },
    "dataiku_mcp/tools/machine_learning/shared/__init__.py": {
      "sha256": "08cd1feaf71059731df9e246c5f3c93b5d74715a2af3d8f32adb216fc7845c8b",
      "size": 633
    },
    "dataiku_mcp/tools/machine_learning/shared/common.py": {
      "sha256": "86117cf415195e452e3f6ddb5661428be391e270819a338f23cb6377ee6292bf",
      "size": 1217
    },
    "dataiku_mcp/tools/machine_learning/shared/summaries.py": {
      "sha256": "08397363ee66e0d9f99db79287a749faee1c8c2bdcd12661f1480a76bfced68a",
      "size": 6534
    },
    "dataiku_mcp/tools/managed_folders.py": {
      "sha256": "5eb8976c76a5fce07a080e71abd05307ac977561285660306f0758ef68aac7df",
      "size": 8857
    },
    "dataiku_mcp/tools/plugins.py": {
      "sha256": "d83b503026dcc3648f96eb76a440f26eb51c0d70f3203c7fa194d71a182ed446",
      "size": 54470
    },
    "dataiku_mcp/tools/project_folders.py": {
      "sha256": "c4b2f5addad857b0d2cdf8375c10510d1e24218c3b166d7cdf2b8f966ab2a209",
      "size": 7738
    },
    "dataiku_mcp/tools/project_libraries.py": {
      "sha256": "264180c250e28e5cafc5099a0db891159a0ad86c777dffd3fe07d6ee2ab5d71e",
      "size": 21928
    },
    "dataiku_mcp/tools/projects.py": {
      "sha256": "5597b1b247cbd206fbc3123dab9c648b8adfcf37078a24e6958506343c08b194",
      "size": 13767
    },
    "dataiku_mcp/tools/recipes.py": {
      "sha256": "a9212fd94149e677a595a97541338f9b0bfc9f7935c4be97f29565d33a1af224",
      "size": 5001
    },
    "dataiku_mcp/tools/scenarios.py": {
      "sha256": "91b4003f37b42e388ced26044c2def414214d8e790ae821e6fbad334d0edafad",
      "size": 14377
    },
    "dataiku_mcp/tools/semantic_models.py": {
      "sha256": "b3a583be2af3fe1344fca10e7ab56d0ff6feb1afdc7d5bf75ffad3ed9b51939f",
      "size": 3313
    },
    "dataiku_mcp/tools/users.py": {
      "sha256": "4bc2453720924c1aab29317578b3d90a7921ea6701ddd0ca493f0cab2d376939",
      "size": 11260
    },
    "dataiku_mcp/tools/utils/__init__.py": {
      "sha256": "1bd50f36a1f96b04aad459ffcbb5d7c8ab2ea628f9f7434c087ec243b60ec515",
      "size": 601
    },
    "dataiku_mcp/tools/utils/errors.py": {
      "sha256": "d207d450d5177589dd1e298712b0fbf2fbcf399beefb730ef9f8d8c5ee21428e",
      "size": 1461
    },
    "dataiku_mcp/tools/utils/identity_sources.py": {
      "sha256": "23cd24db402ff92d85a3dfe16e7ad0c51f2dc7e14345f0a365d03b8eb6d30de7",
      "size": 796
    },
    "dataiku_mcp/tools/utils/job_summaries.py": {
      "sha256": "60f0a377d3edddf2d4561546c45cf910a3bb37c7dcb2c8620dff90b1759a0932",
      "size": 8280
    },
    "dataiku_mcp/tools/utils/metrics.py": {
      "sha256": "f04a294d50e47dbc7dcf90d2f96f9a34b1966ccc4b5ed959496f056008cd045e",
      "size": 3861
    },
    "dataiku_mcp/tools/utils/parsing.py": {
      "sha256": "50b7799fd20890cdff122c34458c26c33a603f902c5f25acb3f3f9a277b55d45",
      "size": 2551
    },
    "dataiku_mcp/tools/utils/serialization.py": {
      "sha256": "4ec4de83db5bdf5eeb8c3febf15f1bb05aa137139a74abbcdd354b5180fb12ae",
      "size": 2420
    },
    "dataiku_mcp/tools/utils/validation.py": {
      "sha256": "5a532dad44aa0e677992d9499eeec9245d0875d8a360394925664e7f16453915",
      "size": 5272
    },
    "dataiku_mcp/tools/webapps.py": {
      "sha256": "3a07be3b7c0a921755613e5c2a5d4b2246235b5ef59c21930e8eda6bdba9b548",
      "size": 4712
    },
    "dataiku_mcp/tools/wikis.py": {
      "sha256": "e6abd1a316b45e55fae2d7b8450e4af9fd829080582d77eeababe74ab37257ee",
      "size": 3474
    },
    "docs/assets/codex_composer_logo_dark.png": {
      "sha256": "b3d48177b6c10d994f260867fe87015876fe3c4590ca4503b853a46054ecd11f",
      "size": 5521
    },
    "docs/assets/codex_composer_logo_light.png": {
      "sha256": "e507bcf422922701fdba38820e45c9260124960d5cbbae22c953ad86b0e6a0c4",
      "size": 5110
    },
    "docs/assets/codex_directory_logo_dark.png": {
      "sha256": "b3d48177b6c10d994f260867fe87015876fe3c4590ca4503b853a46054ecd11f",
      "size": 5521
    },
    "docs/assets/codex_directory_logo_light.png": {
      "sha256": "2ab75e36f5b81d3f8bdbb4973bbc714564a3532e8726c0241218f608616e1e26",
      "size": 4820
    },
    "docs/assets/dataiku-lockup-black.svg": {
      "sha256": "01283aaa3c3f6d5b86d9a95ee4f148d6d4ff27d881ff8c4d2dfbf1b5024bffff",
      "size": 4025
    },
    "docs/assets/dataiku-lockup-white.svg": {
      "sha256": "bf358457d36601a9e3e31334b288571ecd50e3ac2b4d661bd2ad515c0f39218b",
      "size": 4025
    },
    "docs/assets/logo_black.png": {
      "sha256": "0efedda39a2864fe87e17559d9e99f42144579c436bc279ba4272331f3dffb83",
      "size": 11200
    },
    "docs/capabilities.md": {
      "sha256": "3fff28e62125381fcd798744d04da74ce55984d7cb2f239547ad2e5303f7f731",
      "size": 10961
    },
    "docs/http-deployment.md": {
      "sha256": "a152442cfafd42c28b6964c339630432ad30c69bd23ca5d18c0a45415e280074",
      "size": 17920
    },
    "pyproject.toml": {
      "sha256": "fa8ceb8d6b56990d40caf62ee1bb25e8c8a2bd9b685e07c969b51c1c17cd25da",
      "size": 2538
    },
    "runtime/launcher.sh": {
      "sha256": "825d32d06d2ce42f9cc3bcb7210020bafdfe60efe19995fc21d55f8f32ef9366",
      "size": 7182
    },
    "runtime/run_mcp.py": {
      "sha256": "d689671a0cabd01eed2598433b56eb659e58b176814b8495cb66c8df8eed1549",
      "size": 3391
    },
    "runtime/run_mcp.py.lock": {
      "sha256": "9c11c8ce0209672c15406d504fdab8c59207209d4d5f0c737b65f4437c1b4497",
      "size": 460907
    },
    "scripts/build_http_plugin.py": {
      "sha256": "4079975c611c70caccdf01e4935939f35a5ecb2faa0276061ad7e00fd411a527",
      "size": 6263
    },
    "scripts/check_license_headers.py": {
      "sha256": "a046de229cd4c86ffac43f13d8b52a6e32fdcf76d1a56a85c5f9252bed9b16fd",
      "size": 4286
    },
    "scripts/check_release.py": {
      "sha256": "5ba518018e051242428b314247b8a3e3da796f80dddc9db85ce1cfa28a7f577e",
      "size": 4778
    },
    "scripts/http_plugin_assets/skills/dataiku-headless-setup/SKILL.md": {
      "sha256": "c02b9d42a4a331f7165cbe1ab9e876eded223f46b25af8d3fbf560ef261d717d",
      "size": 2315
    },
    "skills/dataiku-headless-setup/SKILL.md": {
      "sha256": "3904b563fc2b6fb8e42419b7312c304c9a6716d9b9cc047fbef07266c66fbd23",
      "size": 7791
    },
    "skills/dataiku-headless/SKILL.md": {
      "sha256": "939d7c5ee0d34bd8ee4b8a9846b93fde4484f48ca2c71b1c9f6388602406f138",
      "size": 8178
    },
    "skills/dataiku-headless/references/administration.md": {
      "sha256": "305fc51f0c0d3f16b43d7da4935c044215f60b7d724f4a5cd0a3e09f2578b87a",
      "size": 1108
    },
    "skills/dataiku-headless/references/administration/code-environments.md": {
      "sha256": "69df1427dcccbf453d415dd6580e1a67f96a6cb66aba636502aa65a813e056b8",
      "size": 5659
    },
    "skills/dataiku-headless/references/administration/general-settings.md": {
      "sha256": "b358d253115b7b71ab945195671e8b3a29609faa9ae521cfb3432bc3812bfca4",
      "size": 1352
    },
    "skills/dataiku-headless/references/administration/groups.md": {
      "sha256": "882808803a62371b973bcd20070dab0335ac89920841bd15ebfde82de337b41f",
      "size": 2556
    },
    "skills/dataiku-headless/references/administration/licensing.md": {
      "sha256": "6e3a8e978ca3e54d5324f9eff41731f847f80de31089cdffcf37427e249e3a12",
      "size": 1065
    },
    "skills/dataiku-headless/references/administration/plugins.md": {
      "sha256": "b95b340d4eaa8c4d26b8871d43ba0157d00a2a105e27e9d207e307e457bc5f76",
      "size": 12584
    },
    "skills/dataiku-headless/references/administration/users.md": {
      "sha256": "56360ccf07eaa6cffd8bd3894a866d02157b00f9a1c726157dfca0977419187d",
      "size": 2187
    },
    "skills/dataiku-headless/references/agent-reviews.md": {
      "sha256": "3f170b28d595afbf1e99eaee8f0af0dba4c616b9a1492dd03d9ae1db14b495af",
      "size": 2565
    },
    "skills/dataiku-headless/references/agents.md": {
      "sha256": "89ac660ce5a8c482d310d45b98f9e53f06317f31f7baddb7932fd223821eaf83",
      "size": 2080
    },
    "skills/dataiku-headless/references/agents/agent-tools.md": {
      "sha256": "1a6cff6687627faf7d5951dfd4ea8980d9c71631a0937c7f0c9dfe3f0479d429",
      "size": 2498
    },
    "skills/dataiku-headless/references/agents/code-agent.md": {
      "sha256": "0a3d28c053b76a6821ec5a377aeadb7cc9a12f8a534c2aeebc1d210c5c3f5114",
      "size": 1380
    },
    "skills/dataiku-headless/references/agents/simple-agent.md": {
      "sha256": "24d629cf63bf00d8edf53ea1ed26c7d08dee1e65282a5021a8b79fe2a885bed1",
      "size": 1096
    },
    "skills/dataiku-headless/references/agents/structured-agent.md": {
      "sha256": "2f8cef6cdfec1c63058c6843df20dd0e4fda4a8cc848a5c35ce3d22451a6e450",
      "size": 3120
    },
    "skills/dataiku-headless/references/cobuild.md": {
      "sha256": "d2eddb132211b90b452f6170d9badfdfd4f08bfe7577e0a0b2dea6906cef8ebb",
      "size": 9367
    },
    "skills/dataiku-headless/references/connections.md": {
      "sha256": "c246523f3ebd709f60e98158493b8eed1a9a14a29f8cb84eadf2e276f2cb86ab",
      "size": 2254
    },
    "skills/dataiku-headless/references/connections/connection-types.md": {
      "sha256": "2ced54097761951cf0dc7e3c32d9d8b2ab6d8ee36676f7c843c41688230b68ef",
      "size": 1874
    },
    "skills/dataiku-headless/references/container-execution.md": {
      "sha256": "f2d59c5b9e84919c6ec60f241a9c968fc76f6febfa840f7bf67e5e34bc75c8ed",
      "size": 4178
    },
    "skills/dataiku-headless/references/cross-project-sharing.md": {
      "sha256": "cbf8e01ca6df2833b13bba1c705144081369fc28561b374c2b22dbaf87984faa",
      "size": 2706
    },
    "skills/dataiku-headless/references/dashboards.md": {
      "sha256": "8def1d6fc7073afedaf97454159b9e2d74f4aea941d73cb4cb72684dc3c35a3e",
      "size": 1990
    },
    "skills/dataiku-headless/references/data-collections.md": {
      "sha256": "06eb291085b7d8b5cf29e58655fa90398037fb6bef56feb5c18fefc0dc189efd",
      "size": 1899
    },
    "skills/dataiku-headless/references/data-quality.md": {
      "sha256": "12d02a9b30375ba7f11aaee52da36eb63daaaa0bdc7a26f60fc1614a7f6813c5",
      "size": 2409
    },
    "skills/dataiku-headless/references/data-quality/rule-types.md": {
      "sha256": "3fcc1d093352fcb0f1604804d92340c6ba728ed8f04c9cbfe0909d4224d8fda7",
      "size": 2514
    },
    "skills/dataiku-headless/references/datasets.md": {
      "sha256": "cd564883ead74fa651bdff4e376c7f6094e17c2ed8e8d7e6895b0459fc9a5ce9",
      "size": 6876
    },
    "skills/dataiku-headless/references/datasets/uploaded-files-datasets.md": {
      "sha256": "0fa5c92ff78b29b80699490b07f88f321d5f026df647f9584a7817cdf141fd9b",
      "size": 1958
    },
    "skills/dataiku-headless/references/insights.md": {
      "sha256": "97fc899dafab540a877f7514683ec6649059f939038761735b6d9080f704d136",
      "size": 2835
    },
    "skills/dataiku-headless/references/jobs.md": {
      "sha256": "ea3ed21f5ebc0c4e906a32eebbc1389a33743d6fd5ac233e3b2948e43b62219a",
      "size": 4566
    },
    "skills/dataiku-headless/references/llms-and-knowledge-banks.md": {
      "sha256": "29b77eecc4c4b01b17410f6bb63f23f1e4288055e5bf98a15112f9a426bcd52e",
      "size": 2354
    },
    "skills/dataiku-headless/references/machine-learning.md": {
      "sha256": "002346999c60ae883dfcd35e679976e74c9e97c4799b326fffff1b70ef24875e",
      "size": 3494
    },
    "skills/dataiku-headless/references/machine-learning/causal-prediction.md": {
      "sha256": "bad22eb06b85d2cdf7f03acd5d6d83b694e624476bcf513f1a08f182bbbb1a87",
      "size": 1542
    },
    "skills/dataiku-headless/references/machine-learning/clustering.md": {
      "sha256": "decd24f29ba0417e8903d104e2b853097884178d35996dc8be06d04af26c41f6",
      "size": 1523
    },
    "skills/dataiku-headless/references/machine-learning/prediction.md": {
      "sha256": "d27a221dcb9100941f5304cd9664da7320a391aaa1c727537caf012d49dc742e",
      "size": 1629
    },
    "skills/dataiku-headless/references/machine-learning/timeseries-forecasting.md": {
      "sha256": "9ea2fde92cf3e3d4ef90a81e53c0c25851402ca84e7291777b129b2ecf4590f0",
      "size": 1517
    },
    "skills/dataiku-headless/references/managed_folders.md": {
      "sha256": "318802c108274c6211260b1c468ee0957764b656c830a313a8cb9b1cbf888ebd",
      "size": 3177
    },
    "skills/dataiku-headless/references/migrations.md": {
      "sha256": "e19be2d30843ebd3c1ec0ef8add516416466136d866bfcdcbaf94a3c7cf1e571",
      "size": 10708
    },
    "skills/dataiku-headless/references/migrations/sources/excel/excel.md": {
      "sha256": "07899faf64736f5ca9950921a1240917e2d582149dcf1fe2f0e705b71b9ae46b",
      "size": 4101
    },
    "skills/dataiku-headless/references/migrations/sources/excel/guides/build.md": {
      "sha256": "fd12238c9da368e8a3f53beaba991ccaafac3616ab5100fa3f77bae62f234fe5",
      "size": 3025
    },
    "skills/dataiku-headless/references/migrations/sources/excel/guides/excel-semantics.md": {
      "sha256": "f050e37ce53f079f09f1cbd59ade3357b94381195c5579d643382fd4cd3191ce",
      "size": 3125
    },
    "skills/dataiku-headless/references/migrations/sources/excel/guides/reading-workbooks.md": {
      "sha256": "ed5b92d5a8f6264303749793ab31ee537688120b628a20386919358332737a08",
      "size": 4945
    },
    "skills/dataiku-headless/references/migrations/sources/excel/guides/validate.md": {
      "sha256": "15acdd4710d69c4f025bc85226eb3b8e9b71692fdaca566db3897b53a5fa17ae",
      "size": 6634
    },
    "skills/dataiku-headless/references/migrations/sources/excel/guides/webapp.md": {
      "sha256": "d2970e426368be6d7b951dc8ec9603defda336a7ea8579f1310ff3c356f170bb",
      "size": 5094
    },
    "skills/dataiku-headless/references/migrations/sources/excel/helpers/dump_anatomy.py": {
      "sha256": "4c4f87a015a603a37d5377882543ce3bb0d690bfa9c3541a714a38e592bbc6eb",
      "size": 14901
    },
    "skills/dataiku-headless/references/migrations/sources/excel/helpers/dump_workbook.py": {
      "sha256": "5183873597d5dd1ab4dea234a7e70785fadf8984bcceccd559c2ed6bb4d84512",
      "size": 3498
    },
    "skills/dataiku-headless/references/migrations/sources/excel/webapp/template.css": {
      "sha256": "bf6aadcc8d53344c02e17e86ab2f4be612fdb0101c641462c564704fbb1b35dc",
      "size": 5730
    },
    "skills/dataiku-headless/references/migrations/sources/excel/webapp/template.html": {
      "sha256": "8ea1d5758977bc249bc57cdd0f45a82ef612398b2ab753ebe76dc6a028ba536b",
      "size": 1212
    },
    "skills/dataiku-headless/references/migrations/sources/excel/webapp/template.js": {
      "sha256": "139154f93fbf522a445206ee5b8be9072727b8b934e62f335794ce780acc41bb",
      "size": 15230
    },
    "skills/dataiku-headless/references/migrations/sources/excel/webapp/template.py": {
      "sha256": "5347604c09a99085de808b5e2cf9c7c91aa5a9981fc41c1ebd80453837ef18a4",
      "size": 15134
    },
    "skills/dataiku-headless/references/plugin-development.md": {
      "sha256": "6eb2f214ffaec11b515e98e744f4366fa7d332b0f8a68112865ccacffedea723",
      "size": 7231
    },
    "skills/dataiku-headless/references/plugin-development/agent-tools.md": {
      "sha256": "192d514c4a3d45c3a0718d7ebf18f918fa581c086dc9e452f3f410842122366c",
      "size": 2878
    },
    "skills/dataiku-headless/references/plugin-development/agents.md": {
      "sha256": "2c037d78e1f2a0f814db9716b9e94d65e1f948eb27534ef33fc66f9e73b3b2ae",
      "size": 655
    },
    "skills/dataiku-headless/references/plugin-development/connectors.md": {
      "sha256": "d2752bdc3630933891a340c63e60157656b923c2e396be9b22deabf2db361cfd",
      "size": 2451
    },
    "skills/dataiku-headless/references/plugin-development/file-formats.md": {
      "sha256": "67f6313aee6cc082510bbeae7929896eceeec52a33692f430764264b009bb263",
      "size": 868
    },
    "skills/dataiku-headless/references/plugin-development/guardrails.md": {
      "sha256": "674dfb1b84c55c056e9632a17fc0f6005d6188cf9877e5bab25162302bdefd62",
      "size": 666
    },
    "skills/dataiku-headless/references/plugin-development/llms.md": {
      "sha256": "7fa9d085aa7c158a813a333ce36564e39c77e952238bc35a8cec69c21aea2254",
      "size": 2141
    },
    "skills/dataiku-headless/references/plugin-development/machine-learning.md": {
      "sha256": "dd583b98b540d99b42e80a461629a0ea497d31c3b50ad9b36ce903a842a16be3",
      "size": 1608
    },
    "skills/dataiku-headless/references/plugin-development/macros.md": {
      "sha256": "a1303487a9da283dffc7a49ae898997bfcf374899685932f9398fc0f0b1e6ca2",
      "size": 1343
    },
    "skills/dataiku-headless/references/plugin-development/prepare-processors.md": {
      "sha256": "4950cb33ed9e3448f8775ede08cfb9b36bb9fe4bd9f38a8330214364b802b8b6",
      "size": 1054
    },
    "skills/dataiku-headless/references/plugin-development/recipes.md": {
      "sha256": "b59c5df3bd779a891f698d7ed3bbaa1fb38d12a57c07a5a620a714c1fa251e0c",
      "size": 2062
    },
    "skills/dataiku-headless/references/plugin-development/settings-checks.md": {
      "sha256": "575e8494ebd9b93eaa0a16d0b5acc2916a4e6d0816bc79e7b61e05f918852564",
      "size": 1593
    },
    "skills/dataiku-headless/references/plugin-development/structured-agent-blocks.md": {
      "sha256": "c52498e46a243de7a743a26f817bf8c9d1c838bf5a436da2f1f6d67a23d82fd6",
      "size": 735
    },
    "skills/dataiku-headless/references/plugin-development/webapps.md": {
      "sha256": "9cf94185bbe4df97ffe5a287057ecc0b245dc028b0a88958836f7a03b0ace14a",
      "size": 1511
    },
    "skills/dataiku-headless/references/project-folders.md": {
      "sha256": "cceec670ebc1620230985c7ffaf34d50c596e5adca26dbcee0d3d9730d19c6af",
      "size": 2242
    },
    "skills/dataiku-headless/references/project-libraries.md": {
      "sha256": "12b82f7bbd311b8acbd3a269914b6c74430da11c12258a2a3a5297720e903a0b",
      "size": 3554
    },
    "skills/dataiku-headless/references/projects.md": {
      "sha256": "0a944ee2dd5687d4691b8c4011af697989868a2bf54c843321b1c0042b5598fd",
      "size": 3775
    },
    "skills/dataiku-headless/references/projects/settings.md": {
      "sha256": "bff2018748f3d1acc78a394b2f28e13cc9411c40cd821499210165f209907463",
      "size": 6190
    },
    "skills/dataiku-headless/references/recipes.md": {
      "sha256": "cc0f1503af28968e349fa8de9f0ff6a85c72544d2dc646897ebbb23c65def9c9",
      "size": 5959
    },
    "skills/dataiku-headless/references/recipes/recipe-types/code-recipes.md": {
      "sha256": "1bcb99878d5d8278c9e45015ecf594d3ebcb17d2e12a9f67c446c4a1d15d6590",
      "size": 1158
    },
    "skills/dataiku-headless/references/recipes/recipe-types/data-prep-recipes.md": {
      "sha256": "c5eafab775d2e494784fda06d93fb8a122947dff456a58189e89bbdacc7e0ebb",
      "size": 4459
    },
    "skills/dataiku-headless/references/recipes/recipe-types/genai-recipes.md": {
      "sha256": "3958c31cd3c08c83e926761e5f5e6f58a75cf932e9e5e71f16b6c50eb77c248c",
      "size": 1494
    },
    "skills/dataiku-headless/references/recipes/recipe-types/ml-recipes.md": {
      "sha256": "88c41dba11c87a3e7db1f33751ea4aed34659192d9bad30d6dd6c11a1a3391ed",
      "size": 1420
    },
    "skills/dataiku-headless/references/recipes/shared/dataiku_formula_language.md": {
      "sha256": "ddec417fcbf843e65352e97398a59c25290c1f4cf0ff4ac00d91d2a56fa5ac9e",
      "size": 14583
    },
    "skills/dataiku-headless/references/recipes/shared/prepare_processors_overview.md": {
      "sha256": "0cd7853de9b31be208f4eca4dac07aa8e5492e073abcb77e3c2e74c9d820a215",
      "size": 14131
    },
    "skills/dataiku-headless/references/scenarios.md": {
      "sha256": "b6e23112a2e87fa67acafe648c6238403713c0ce445e3cd5d7283ba50167d893",
      "size": 4427
    },
    "skills/dataiku-headless/references/semantic-models.md": {
      "sha256": "fc33502ea7a1111d2dc572e505589d01c7f78c8e09e40fe043ab53eb6c891448",
      "size": 3662
    },
    "skills/dataiku-headless/references/webapps.md": {
      "sha256": "c5599f542816483f070301a7b067c8d3c246e2d3bd8658989332616e688e5871",
      "size": 3151
    },
    "skills/dataiku-headless/references/wikis.md": {
      "sha256": "a34159b2c1e6b477970d56252e83a215b28ee5b9c02e38101cc9e0246d3d3dcc",
      "size": 2143
    },
    "skills/dataiku-headless/references/wikis/wiki-content.md": {
      "sha256": "43b32bc0b980f3a0eb61afcc397020207871c552bcb3c1f692318c2dae5d7b2e",
      "size": 1073
    },
    "tests/conftest.py": {
      "sha256": "5c4629703c494648293d1cd6819145e24c125a1832c0652a953e07379b7318e8",
      "size": 2277
    },
    "tests/test_auth.py": {
      "sha256": "0b90b7514e5fdfe5ef81895fdf99778e4d5df7d64e78696fe55f4948e41fee99",
      "size": 6199
    },
    "tests/test_capabilities_doc.py": {
      "sha256": "1b7c19168dec8dca519f0f8938bc4ea79b71f0b48df90aaa9a8cb8e2944211c5",
      "size": 3138
    },
    "tests/test_cobuild.py": {
      "sha256": "618d9ece76cf4809fb79dbe91f0c2166f145f347566e3e6cd0b0805fd6756688",
      "size": 21151
    },
    "tests/test_code_environments.py": {
      "sha256": "31f0ddd992a0aa208cfe43642d2145026ed3da1ac2216cfaf10a317a5b036041",
      "size": 15190
    },
    "tests/test_config.py": {
      "sha256": "5c42ee6856270c8f991b0ffef41244be30293d59e69949f9e1785a080139e7bc",
      "size": 38341
    },
    "tests/test_config_files.py": {
      "sha256": "a6d008f5c43f761af91a0f24fab1ca4187f0f21fdce530ae0b6a5de7998703ec",
      "size": 2016
    },
    "tests/test_connections.py": {
      "sha256": "4433e22d6777da1c1764127eb59caf5985d504ad42acfb7fd14fb878828866a0",
      "size": 1776
    },
    "tests/test_container_exec.py": {
      "sha256": "c4e32467ae25793d06f3809bd6ea871eb24c3c5d138ec0cdc1c051190695ba11",
      "size": 15498
    },
    "tests/test_cursor_plugin.py": {
      "sha256": "ad6dab83d5951b2d5a30a109ae79d2d99f642debee598f7fdce6df7b4aba464b",
      "size": 1508
    },
    "tests/test_dataset_metrics.py": {
      "sha256": "23e4f3a936278c8de624dc078c7a42f5950dec1be195de07c05b0eabb95e2c01",
      "size": 6955
    },
    "tests/test_datasets.py": {
      "sha256": "1a3c26fc5ef871ebbd3e038cd271754ee98cfff608d50b43e71b3051404234a5",
      "size": 10217
    },
    "tests/test_execution_tools.py": {
      "sha256": "7655056bc8d1d32611945df29bb18a901e260a3507b6bd70485d6eb68f3f9bfd",
      "size": 41150
    },
    "tests/test_fakes.py": {
      "sha256": "3320fcc8139b14048e53dee6342d10e02f1876d634eade23755a0297c2ac199a",
      "size": 1775
    },
    "tests/test_flow_graph.py": {
      "sha256": "473eac5415bea2c00187d98c432b04c1a5aa5d4bbc91363783dc39fbc39a1099",
      "size": 14746
    },
    "tests/test_general_settings.py": {
      "sha256": "890cd225c0bda0e91a6517a9d65f5dcc6e34a9f21f0b7e1246b619c731c8a629",
      "size": 6920
    },
    "tests/test_groups.py": {
      "sha256": "f680d004aa1dd7bd3f69e86a2df63dc61aa61aecef8a8226912c73cde557c4e7",
      "size": 4245
    },
    "tests/test_http_config.py": {
      "sha256": "1be66dc0e1efb84c15adecfc40e3a2724997d80198057415ccb571bc95f85330",
      "size": 32743
    },
    "tests/test_http_middleware.py": {
      "sha256": "2d75ab0ff3aa2b2a9238e84d7c93670c39a37f8ed93f2a5fd4e669334dfe8db1",
      "size": 9590
    },
    "tests/test_http_plugin_renderer.py": {
      "sha256": "82110e41742086c8f16a0c007257fd21bff12d7d2dfde45cd75c607feca5e2e9",
      "size": 6160
    },
    "tests/test_instance_pinning.py": {
      "sha256": "51c6acd0c77948fb43f15047ad992191cd6b7afed2e998a024e5c11becb400c2",
      "size": 2564
    },
    "tests/test_instance_policy.py": {
      "sha256": "c7c5fa83139803cdb4a020def372758b8b5b26cc5d020d08aff6b8bc684c54b7",
      "size": 13875
    },
    "tests/test_instances.py": {
      "sha256": "23ea6368e1e0addacef1dc160b98cc295daa25902105562903bd6c1cd438a524",
      "size": 12441
    },
    "tests/test_launcher_cli.py": {
      "sha256": "a93f9cb8377c5275d9f292285a99571dcdb0f4f2679c99afcfce9c1355945290",
      "size": 4359
    },
    "tests/test_local_file_http_guards.py": {
      "sha256": "0091957b4ed63a9f9713a04b67c779c0e6b9328ddaf6bd56935ccb19a5c1836f",
      "size": 2172
    },
    "tests/test_onboarding_ui.py": {
      "sha256": "3662fbd3ba45572fb5b532fd1669f9affb692808f50d8e32729063fe2387625b",
      "size": 1042
    },
    "tests/test_pep723_launcher.py": {
      "sha256": "0784ffa1a050cd3ffb3fc2f35e9119fa595bb9a1d8802cb75bcd2552bc5fb710",
      "size": 4243
    },
    "tests/test_plugin_futures.py": {
      "sha256": "75d9ed23b3eb280ddc31bde4819479b5ec190989ac09f35ec7e52b23ef2bf59b",
      "size": 4846
    },
    "tests/test_plugin_packaging.py": {
      "sha256": "01bee934a7d31c3892ad729732ff4bb9d377bed0fa87ca7b847d629ed4d11d2f",
      "size": 6547
    },
    "tests/test_plugins.py": {
      "sha256": "002019bb10e95a766452613ef8c972ba959d947cd80eeeed38528b37bfdd982f",
      "size": 70849
    },
    "tests/test_project_settings.py": {
      "sha256": "58700d233bbac5a263adad7fa214bc3e4878c225a21e55c962853e97f7796404",
      "size": 6312
    },
    "tests/test_project_variables.py": {
      "sha256": "9e06ef65f63819196dff7fc0083403648f0b381740ec97d5d7980bb0c0803d32",
      "size": 2931
    },
    "tests/test_release.py": {
      "sha256": "6c2a241bc9d697f7e30e598d7ff293283e7ea58f21ebef7ced6637be9d2e8d79",
      "size": 11372
    },
    "tests/test_server.py": {
      "sha256": "8d1f277c85be089144b9462b4d95bafadc75bd9efaf494edff24c663b294e5a5",
      "size": 9591
    },
    "tests/test_setup_server.py": {
      "sha256": "9a7608a6074d1f3a2cf251556dfe67d20fdc0f909653da897d33fd18f05349c5",
      "size": 20230
    },
    "tests/test_smoke.py": {
      "sha256": "d115dd73a722c076e1d9596c0d09b38a926700b3d8cacfa308deabd9d5a1d35e",
      "size": 1988
    },
    "tests/test_tls_trust.py": {
      "sha256": "33a58568d442dc2a6357db92fb04a695ee4e4c29a9627b9e6b246c0234a34791",
      "size": 5208
    },
    "tests/test_tool_surface.py": {
      "sha256": "285c9ebf998a189e8d9d30d1913cea7f63187bc7490c59478dc3ef789e047a80",
      "size": 8670
    },
    "tests/test_users.py": {
      "sha256": "1a45e66c5c001308abcb8fc50f083fbd3505cf6427f3d258e1e81994c8ca3f96",
      "size": 6089
    },
    "tests/utils/fakes.py": {
      "sha256": "8ce9812999f93c96ba83f50301a745d009e560cddb1f8abad86b036984123fc9",
      "size": 2341
    },
    "uv.lock": {
      "sha256": "6249f71d815813a22c5930a3480b49e59d16d6366dd3873ed87fdfff7e51ff30",
      "size": 419395
    }
  }
}

SHA-256 of public snapshot: 181cd644401784043e329a2935a65ac4587413f1fc263d113295ba5bb17e116b