{
  "file": "F28-canvas-extensions.md",
  "bullet": "Install from a local directory (`F28.install-local`).",
  "ids": [
    "F28.install-local"
  ],
  "line": 223,
  "script": "control-agent-server api POST /api/canvas-extensions/install --json \"{\\\"source\\\": \\\"$FX\\\", \\\"enabled\\\": true}\" \\\n  --expect 200 --check name eq qa-canvas --check enabled eq false --check resolved_ref eq null \\\n  --check source eq \"$FX\" --check install_path eq \"$INST/qa-canvas\" \\\n  --check manifest.contributes.pages.0.path eq /qa-canvas --check manifest.icon eq assets/icon.svg \\\n  --save F28.install-local/install\nAT0=$(control-agent-server api GET /api/canvas-extensions/installed/qa-canvas --field installed_at)\ncontrol-agent-server api GET /api/canvas-extensions/installed/qa-canvas --expect 200 \\\n  --check enabled eq false --check manifest.display_name eq 'QA qa-canvas' --save F28.install-local/get\ncontrol-agent-server api GET /api/canvas-extensions/installed --expect 200 --check canvas_extensions len-eq 1 \\\n  --check canvas_extensions.0.name eq qa-canvas --check canvas_extensions.0.enabled eq false --save F28.install-local/list\ncontrol-agent-server state cat home/.openhands/canvas-extensions/installed/.installed.json \\\n  --check extensions.qa-canvas.enabled eq false --check extensions.qa-canvas.installed_at eq \"$AT0\"\ncmp \"$INST/qa-canvas/dist/index.js\" \"$FX/dist/index.js\"\n",
  "exit_code": 0,
  "elapsed_ms": 3472,
  "failed_line": null,
  "failed_command": null,
  "stdout": "{\n  \"ok\": true,\n  \"status\": 200,\n  \"request\": {\n    \"method\": \"POST\",\n    \"path\": \"/api/canvas-extensions/install\",\n    \"query\": [],\n    \"auth\": \"header\",\n    \"body\": {\n      \"source\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/fixtures/canvas/qa-canvas\",\n      \"enabled\": true\n    },\n    \"files\": []\n  },\n  \"response\": {\n    \"status\": 200,\n    \"headers\": {\n      \"content-length\": \"718\",\n      \"content-type\": \"application/json\"\n    },\n    \"body\": {\n      \"name\": \"qa-canvas\",\n      \"version\": \"0.1.0\",\n      \"description\": \"QA fixture Canvas app\",\n      \"enabled\": false,\n      \"source\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/fixtures/canvas/qa-canvas\",\n      \"requested_ref\": null,\n      \"resolved_ref\": null,\n      \"repo_path\": null,\n      \"installed_at\": \"2026-10-13T02:42:21.953802+00:00\",\n      \"install_path\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/home/.openhands/canvas-extensions/installed/qa-canvas\",\n      \"manifest\": {\n        \"schema_version\": 1,\n        \"name\": \"qa-canvas\",\n        \"display_name\": \"QA qa-canvas\",\n        \"version\": \"0.1.0\",\n        \"description\": \"QA fixture Canvas app\",\n        \"entrypoint\": \"dist/index.js\",\n        \"contributes\": {\n          \"pages\": [\n            {\n              \"id\": \"main\",\n              \"title\": \"QA qa-canvas\",\n              \"path\": \"/qa-canvas\"\n            }\n          ]\n        },\n        \"icon\": \"assets/icon.svg\"\n      }\n    },\n    \"truncated\": false\n  },\n  \"elapsed_ms\": 276,\n  \"checks\": [\n    {\n      \"check\": \"name eq qa-canvas\",\n      \"ok\": true,\n      \"actual\": \"qa-canvas\"\n    },\n    {\n      \"check\": \"enabled eq false\",\n      \"ok\": true,\n      \"actual\": \"false\"\n    },\n    {\n      \"check\": \"resolved_ref eq null\",\n      \"ok\": true,\n      \"actual\": \"null\"\n    },\n    {\n      \"check\": \"source eq /workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/fixtures/canvas/qa-canvas\",\n      \"ok\": true,\n      \"actual\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/fixtures/canvas/qa-canvas\"\n    },\n    {\n      \"check\": \"install_path eq /workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/home/.openhands/canvas-extensions/installed/qa-canvas\",\n      \"ok\": true,\n      \"actual\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/home/.openhands/canvas-extensions/installed/qa-canvas\"\n    },\n    {\n      \"check\": \"manifest.contributes.pages.0.path eq /qa-canvas\",\n      \"ok\": true,\n      \"actual\": \"/qa-canvas\"\n    },\n    {\n      \"check\": \"manifest.icon eq assets/icon.svg\",\n      \"ok\": true,\n      \"actual\": \"assets/icon.svg\"\n    }\n  ],\n  \"saved\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/evidence/F28.install-local/install.json\"\n}\n{\n  \"ok\": true,\n  \"status\": 200,\n  \"request\": {\n    \"method\": \"GET\",\n    \"path\": \"/api/canvas-extensions/installed/qa-canvas\",\n    \"query\": [],\n    \"auth\": \"header\",\n    \"body\": null,\n    \"files\": []\n  },\n  \"response\": {\n    \"status\": 200,\n    \"headers\": {\n      \"content-length\": \"718\",\n      \"content-type\": \"application/json\"\n    },\n    \"body\": {\n      \"name\": \"qa-canvas\",\n      \"version\": \"0.1.0\",\n      \"description\": \"QA fixture Canvas app\",\n      \"enabled\": false,\n      \"source\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/fixtures/canvas/qa-canvas\",\n      \"requested_ref\": null,\n      \"resolved_ref\": null,\n      \"repo_path\": null,\n      \"installed_at\": \"2026-10-13T02:42:21.953802+00:00\",\n      \"install_path\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/home/.openhands/canvas-extensions/installed/qa-canvas\",\n      \"manifest\": {\n        \"schema_version\": 1,\n        \"name\": \"qa-canvas\",\n        \"display_name\": \"QA qa-canvas\",\n        \"version\": \"0.1.0\",\n        \"description\": \"QA fixture Canvas app\",\n        \"entrypoint\": \"dist/index.js\",\n        \"contributes\": {\n          \"pages\": [\n            {\n              \"id\": \"main\",\n              \"title\": \"QA qa-canvas\",\n              \"path\": \"/qa-canvas\"\n            }\n          ]\n        },\n        \"icon\": \"assets/icon.svg\"\n      }\n    },\n    \"truncated\": false\n  },\n  \"elapsed_ms\": 102,\n  \"checks\": [\n    {\n      \"check\": \"enabled eq false\",\n      \"ok\": true,\n      \"actual\": \"false\"\n    },\n    {\n      \"check\": \"manifest.display_name eq QA qa-canvas\",\n      \"ok\": true,\n      \"actual\": \"QA qa-canvas\"\n    }\n  ],\n  \"saved\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/evidence/F28.install-local/get.json\"\n}\n{\n  \"ok\": true,\n  \"status\": 200,\n  \"request\": {\n    \"method\": \"GET\",\n    \"path\": \"/api/canvas-extensions/installed\",\n    \"query\": [],\n    \"auth\": \"header\",\n    \"body\": null,\n    \"files\": []\n  },\n  \"response\": {\n    \"status\": 200,\n    \"headers\": {\n      \"content-length\": \"742\",\n      \"content-type\": \"application/json\"\n    },\n    \"body\": {\n      \"canvas_extensions\": [\n        {\n          \"name\": \"qa-canvas\",\n          \"version\": \"0.1.0\",\n          \"description\": \"QA fixture Canvas app\",\n          \"enabled\": false,\n          \"source\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/fixtures/canvas/qa-canvas\",\n          \"requested_ref\": null,\n          \"resolved_ref\": null,\n          \"repo_path\": null,\n          \"installed_at\": \"2026-10-13T02:42:21.953802+00:00\",\n          \"install_path\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/home/.openhands/canvas-extensions/installed/qa-canvas\",\n          \"manifest\": {\n            \"schema_version\": 1,\n            \"name\": \"qa-canvas\",\n            \"display_name\": \"QA qa-canvas\",\n            \"version\": \"0.1.0\",\n            \"description\": \"QA fixture Canvas app\",\n            \"entrypoint\": \"dist/index.js\",\n            \"contributes\": {\n              \"pages\": [\n                {\n                  \"id\": \"main\",\n                  \"title\": \"QA qa-canvas\",\n                  \"path\": \"/qa-canvas\"\n                }\n              ]\n            },\n            \"icon\": \"assets/icon.svg\"\n          }\n        }\n      ]\n    },\n    \"truncated\": false\n  },\n  \"elapsed_ms\": 80,\n  \"checks\": [\n    {\n      \"check\": \"canvas_extensions len-eq 1\",\n      \"ok\": true,\n      \"actual\": \"[{\\\"name\\\": \\\"qa-canvas\\\", \\\"version\\\": \\\"0.1.0\\\", \\\"description\\\": \\\"QA fixture Canvas app\\\", \\\"enabled\\\": false, \\\"source\\\": \\\"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/fixtures/canvas/qa-c\\u2026\"\n    },\n    {\n      \"check\": \"canvas_extensions.0.name eq qa-canvas\",\n      \"ok\": true,\n      \"actual\": \"qa-canvas\"\n    },\n    {\n      \"check\": \"canvas_extensions.0.enabled eq false\",\n      \"ok\": true,\n      \"actual\": \"false\"\n    }\n  ],\n  \"saved\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/evidence/F28.install-local/list.json\"\n}\n{\n  \"ok\": true,\n  \"path\": \"home/.openhands/canvas-extensions/installed/.installed.json\",\n  \"bytes\": 572,\n  \"mode\": \"0o600\",\n  \"content\": {\n    \"extensions\": {\n      \"qa-canvas\": {\n        \"name\": \"qa-canvas\",\n        \"version\": \"0.1.0\",\n        \"description\": \"QA fixture Canvas app\",\n        \"enabled\": false,\n        \"source\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/fixtures/canvas/qa-canvas\",\n        \"requested_ref\": null,\n        \"resolved_ref\": null,\n        \"repo_path\": null,\n        \"installed_at\": \"2026-10-13T02:42:21.953802+00:00\",\n        \"install_path\": \"/workspace/verification-artifacts/runs/20261013-024207-5ac2-map-f28/home/.openhands/canvas-extensions/installed/qa-canvas\"\n      }\n    }\n  },\n  \"checks\": [\n    {\n      \"check\": \"extensions.qa-canvas.enabled eq false\",\n      \"ok\": true,\n      \"actual\": \"false\"\n    },\n    {\n      \"check\": \"extensions.qa-canvas.installed_at eq 2026-10-13T02:42:21.953802+00:00\",\n      \"ok\": true,\n      \"actual\": \"2026-10-13T02:42:21.953802+00:00\"\n    }\n  ]\n}\n",
  "stderr": ""
}
