diff --git a/.github/workflows/shell.yml b/.github/workflows/shell.yml index b49c0e7..f9ee11b 100644 --- a/.github/workflows/shell.yml +++ b/.github/workflows/shell.yml @@ -213,6 +213,7 @@ jobs: - codex-runtime - datamachine-worker - detect-site-domain + - dm-workspace-discovery - homeboy-codebox-canary - homeboy-components - homeboy-dmc-provider diff --git a/setup.sh b/setup.sh index 8f62d8b..b6497d6 100755 --- a/setup.sh +++ b/setup.sh @@ -521,6 +521,7 @@ setup_ai_gateway runtime_install runtime_discover_dm_paths +discover_dm_workspace_dir runtime_generate_config ai_gateway_configure_opencode runtime_install_hooks diff --git a/tests/dm-workspace-discovery.sh b/tests/dm-workspace-discovery.sh new file mode 100755 index 0000000..6ba1010 --- /dev/null +++ b/tests/dm-workspace-discovery.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# tests/dm-workspace-discovery.sh — canonical DMC workspace root discovery. +set -eu + +SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +TMP="$(mktemp -d)" +trap 'rm -rf "$TMP"' EXIT + +SITE_PATH="$TMP/site" +mkdir -p "$SITE_PATH" +touch "$SITE_PATH/wp-config.php" + +export SITE_PATH +export DRY_RUN=false + +wp_cmd() { + if [ "$*" != "datamachine-code workspace path" ]; then + echo "unexpected wp_cmd call: $*" >&2 + return 1 + fi + printf '%s\n' "$TMP/Developer" +} + +# shellcheck disable=SC1091 +source "$SCRIPT_DIR/lib/data-machine.sh" + +DM_WORKSPACE_DIR="$TMP/.datamachine/workspace" +DATAMACHINE_WORKSPACE_PATH="" +discover_dm_workspace_dir +if [ "$DM_WORKSPACE_DIR" != "$TMP/Developer" ]; then + echo "FAIL: canonical DMC workspace was not discovered: $DM_WORKSPACE_DIR" + exit 1 +fi + +DATAMACHINE_WORKSPACE_PATH="$TMP/explicit-workspace" +DM_WORKSPACE_DIR="$TMP/Developer" +discover_dm_workspace_dir +if [ "$DM_WORKSPACE_DIR" != "$TMP/explicit-workspace" ]; then + echo "FAIL: explicit workspace path was not authoritative: $DM_WORKSPACE_DIR" + exit 1 +fi + +echo "PASS: tests/dm-workspace-discovery.sh" diff --git a/tests/opencode-local-plugin-path.sh b/tests/opencode-local-plugin-path.sh index 6d60783..8717f6d 100755 --- a/tests/opencode-local-plugin-path.sh +++ b/tests/opencode-local-plugin-path.sh @@ -39,6 +39,7 @@ runtime_generate_config python3 - "$SITE_PATH/opencode.json" "$KIMAKI_DATA_DIR" <<'PY' import json +import os import sys opencode_json, kimaki_data_dir = sys.argv[1], sys.argv[2] @@ -55,6 +56,12 @@ actual = data.get("plugin") if actual != expected: raise SystemExit(f"unexpected local plugin paths: {actual}") +external = data.get("permission", {}).get("external_directory", {}) +expected_workspace = f"{opencode_json.rsplit('/', 1)[0]}/../workspace" +expected_workspace = os.path.normpath(expected_workspace) + "/**" +if external != {expected_workspace: "allow"}: + raise SystemExit(f"unexpected workspace grant: {external}") + edit = data.get("permission", {}).get("edit", {}) for required in ("wp-admin/**", "wp-includes/**", "wp-content/plugins/**", "wp-content/themes/**", "wp-content/mu-plugins/**", "wp-config.php"): diff --git a/tests/repair-opencode-json.sh b/tests/repair-opencode-json.sh index 33a3182..9a701d5 100755 --- a/tests/repair-opencode-json.sh +++ b/tests/repair-opencode-json.sh @@ -231,6 +231,38 @@ if permission.get("bash") != "allow": PY grep -q '"edit_permission": "synced"' "$TMP/edit-permissions.out" +cat > "$TMP/workspace-permission.json" <<'JSON' +{ + "permission": { + "external_directory": { + "/Users/example/.datamachine/workspace/**": "allow" + } + } +} +JSON + +python3 "$REPAIR" \ + --file "$TMP/workspace-permission.json" \ + --runtime opencode \ + --chat-bridge none \ + --kimaki-plugins-dir /opt/kimaki-config/plugins \ + --workspace-dir /Users/example/Developer \ + --additive > "$TMP/workspace-permission.out" + +python3 - "$TMP/workspace-permission.json" <<'PY' +import json +import sys + +with open(sys.argv[1], encoding="utf-8") as handle: + data = json.load(handle) + +external = data.get("permission", {}).get("external_directory", {}) +expected = {"/Users/example/Developer/**": "allow"} +if external != expected: + raise SystemExit(f"stale workspace grant was not replaced: {external}") +PY +grep -q '"external_directory": "synced"' "$TMP/workspace-permission.out" + cat > "$TMP/claude-code-auth-plugin.json" <<'JSON' { "plugin": [] diff --git a/upgrade.sh b/upgrade.sh index 6566024..484a06e 100755 --- a/upgrade.sh +++ b/upgrade.sh @@ -1405,6 +1405,7 @@ configure_homeboy_dmc_worktree_provider_phase sync_cli_transport_runtime update_ai_gateway sync_chat_bridge_config +discover_dm_workspace_dir check_opencode_json_drift ai_gateway_configure_opencode sync_skills