# Install Office Floor Tour

Install the official `office-floor-tour` Beatra Skill package. It uses the same
Beatra account, full-scope Device Token, credits, MCP endpoint, and task history
as every other Beatra package.

<!-- beatra-release-metadata:start -->
- ZIP: https://cdn.beatra.ai/agent-packages/office-floor-tour/v0.2.6/office-floor-tour-skill-0.2.6.zip
- Mirror: https://cdn.beatra.cn/agent-packages/office-floor-tour/v0.2.6/office-floor-tour-skill-0.2.6.zip
- SHA-256: `b8fa117c79550e75cff094e0488d771634d8acd7ecada3b504df7e266083122f`
<!-- beatra-release-metadata:end -->

Download the ZIP with your own HTTP or file tools into a fresh directory. Never
pipe a remote script into a shell, and never extract before verifying.

If the ZIP link does not download, use the Mirror link instead: it serves the
same file, and the check below verifies it the same way.

One Python program checks the SHA-256, rejects unsafe archive entries
(absolute paths, `..`, backslashes, symbolic links, any top-level directory
other than `office-floor-tour/`), extracts the verified
`office-floor-tour/` directory next to the archive, and adds a one-line
`install-source.json` to it so Beatra knows this copy came from its website.
It deletes nothing.

Run it from the directory containing the download. On macOS or Linux:

```bash
# beatra-posix-release:start
ARCHIVE=office-floor-tour-skill-0.2.6.zip
EXPECTED=b8fa117c79550e75cff094e0488d771634d8acd7ecada3b504df7e266083122f
# beatra-posix-release:end
python3 - "$ARCHIVE" "$EXPECTED" <<'PY'
import hashlib
import stat
import sys
import zipfile
from pathlib import Path, PurePosixPath

if sys.version_info < (3, 10):
    raise SystemExit("Beatra Skills require Python 3.10 or newer")

archive = Path(sys.argv[1])
expected = sys.argv[2]
digest = hashlib.sha256(archive.read_bytes()).hexdigest()
if digest != expected:
    raise SystemExit(f"checksum mismatch: expected {expected}, got {digest}")
with zipfile.ZipFile(archive) as bundle:
    for info in bundle.infolist():
        path = PurePosixPath(info.filename)
        if (
            path.is_absolute()
            or ".." in path.parts
            or "\\" in info.filename
            or not path.parts
            or path.parts[0] != "office-floor-tour"
            or stat.S_ISLNK(info.external_attr >> 16)
        ):
            raise SystemExit(f"unsafe archive entry: {info.filename}")
    bundle.extractall(archive.parent)
(archive.parent / "office-floor-tour" / "install-source.json").write_bytes(
    b'{"schema_version":1,"source":"website"}\n'
)
print(f"Verified Beatra Skill directory: {archive.parent / 'office-floor-tour'}")
PY
```

On Windows PowerShell (use `py -3` if `python` is not on PATH):

```powershell
# beatra-powershell-release:start
$Archive = "office-floor-tour-skill-0.2.6.zip"
$Expected = "b8fa117c79550e75cff094e0488d771634d8acd7ecada3b504df7e266083122f"
# beatra-powershell-release:end
@'
import hashlib
import stat
import sys
import zipfile
from pathlib import Path, PurePosixPath

if sys.version_info < (3, 10):
    raise SystemExit("Beatra Skills require Python 3.10 or newer")

archive = Path(sys.argv[1])
expected = sys.argv[2]
digest = hashlib.sha256(archive.read_bytes()).hexdigest()
if digest != expected:
    raise SystemExit(f"checksum mismatch: expected {expected}, got {digest}")
with zipfile.ZipFile(archive) as bundle:
    for info in bundle.infolist():
        path = PurePosixPath(info.filename)
        if (
            path.is_absolute()
            or ".." in path.parts
            or "\\" in info.filename
            or not path.parts
            or path.parts[0] != "office-floor-tour"
            or stat.S_ISLNK(info.external_attr >> 16)
        ):
            raise SystemExit(f"unsafe archive entry: {info.filename}")
    bundle.extractall(archive.parent)
(archive.parent / "office-floor-tour" / "install-source.json").write_bytes(
    b'{"schema_version":1,"source":"website"}\n'
)
print(f"Verified Beatra Skill directory: {archive.parent / 'office-floor-tour'}")
'@ | python - $Archive $Expected
```

If the check fails, delete the download with your file tools and start over
from a fresh download.

Install the verified `office-floor-tour/` directory through the current agent's
native Skill mechanism, using your own file tools, and preserve every unrelated
Skill. The downloaded archive and the extracted working copy are no longer
needed once the Skill is installed — remove them with your file tools, or
leave them.

Python 3.10 or newer is required; the Skill helpers use only its standard
library. Always run `python3 scripts/authorize.py` from the
installed Skill directory, using `python` instead when that is the available
Python 3.10+ command. The helper is idempotent: it verifies an existing shared credential
with a non-billable MCP request, starts Device Authorization only after a
definitive authentication failure, and reports Ready only after verification.
It prints the approval link at once and waits for the user to select Allow;
leave it running. When it prints `BEATRA_AUTH_PENDING`, show the user the
approval link, then run the same command again until it prints
`Beatra is ready`; every run continues the same approval, so the user
approves only once.

Do not add, enable, trust, or configure a Beatra Connector in the host UI. The
Skill always runs Beatra tools through its bundled `scripts/mcp_client.py`,
which connects to the remote Beatra MCP endpoint. Do not generate media merely
to test installation.
