Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This repo is the community ecosystem around OpenShell -- a hub for contributed s
| `sandboxes/ollama/` | Ollama for local and cloud LLMs with Claude Code, Codex, OpenCode pre-installed |
| `sandboxes/pi/` | [Pi](https://pi.dev) pre-installed |
| `sandboxes/sdg/` | Synthetic data generation workflows |
| `sandboxes/xquik/` | Xquik Twitter scraper Skill with read-only API access |

## Getting Started

Expand Down
36 changes: 36 additions & 0 deletions sandboxes/xquik/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# syntax=docker/dockerfile:1.4

# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Xquik Skill sandbox image for OpenShell.
#
# Build: docker build -t openshell-xquik --build-arg BASE_IMAGE=openshell-base .
# Run: openshell sandbox create --from xquik --provider xquik -- claude

ARG BASE_IMAGE=ghcr.io/nvidia/openshell-community/sandboxes/base:latest
FROM ${BASE_IMAGE}

USER root

# Pin the public Skill source for a reproducible and reviewable image.
ARG XQUIK_SKILL_COMMIT=5f2a6d1251dbf9bc5a1211a085d6cac2f2f689af
RUN set -eux; \
git init /tmp/x-twitter-scraper; \
git -C /tmp/x-twitter-scraper remote add origin https://github.com/Xquik-dev/x-twitter-scraper.git; \
git -C /tmp/x-twitter-scraper fetch --depth=1 origin "${XQUIK_SKILL_COMMIT}"; \
git -C /tmp/x-twitter-scraper checkout --detach FETCH_HEAD; \
test "$(git -C /tmp/x-twitter-scraper rev-parse HEAD)" = "${XQUIK_SKILL_COMMIT}"; \
cp -a /tmp/x-twitter-scraper/skills/x-twitter-scraper /sandbox/.agents/skills/; \
install -Dm644 /tmp/x-twitter-scraper/LICENSE /usr/share/licenses/x-twitter-scraper/LICENSE; \
ln -sfn /sandbox/.agents/skills/x-twitter-scraper /sandbox/.claude/skills/x-twitter-scraper; \
chown -R sandbox:sandbox /sandbox/.agents/skills/x-twitter-scraper; \
test -f /sandbox/.agents/skills/x-twitter-scraper/SKILL.md; \
test -f /sandbox/.agents/skills/x-twitter-scraper/references/security.md; \
rm -rf /tmp/x-twitter-scraper

COPY provider-profile.yaml /usr/share/openshell/provider-profiles/xquik-read-only.yaml

USER sandbox

ENTRYPOINT ["/bin/bash"]
95 changes: 95 additions & 0 deletions sandboxes/xquik/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Xquik Twitter scraper sandbox

This image adds the public [Xquik Twitter scraper Skill](https://github.com/Xquik-dev/x-twitter-scraper) to the OpenShell base sandbox. The Skill covers bounded Twitter search, user lookup, timelines, follower data, and API setup.

Xquik is an independent third-party service. Not affiliated with X Corp. "Twitter" and "X" are trademarks of X Corp.

## What is included

- Xquik X Twitter Scraper Skill version 2.6.7
- The complete public Skill reference library
- A read-only OpenShell provider profile
- Every tool from the [base sandbox](../base/README.md)

The image fetches commit [`5f2a6d1`](https://github.com/Xquik-dev/x-twitter-scraper/commit/5f2a6d1251dbf9bc5a1211a085d6cac2f2f689af). The Dockerfile verifies the full commit before copying the Skill and its MIT license.

## Configure the provider

Export a valid Xquik API key on the host. Do not store it in this repository.

```bash
export XQUIK_API_KEY="xq_replace_me"
```

Download the reviewed provider profile:

```bash
curl -fsSLo xquik-read-only.yaml \
https://raw.githubusercontent.com/NVIDIA/OpenShell-Community/main/sandboxes/xquik/provider-profile.yaml
```

Enable provider policy composition. Then lint and import the profile:

```bash
openshell settings set --global --key providers_v2_enabled --value true --yes
openshell provider profile lint -f xquik-read-only.yaml
openshell provider profile import -f xquik-read-only.yaml
```

Create the provider from the host environment. The bare key form keeps the value out of the command line.

```bash
openshell provider create \
--name xquik \
--type xquik-read-only \
--credential XQUIK_API_KEY
```

## Start the sandbox

Launch Claude Code with the provider attached:

```bash
openshell sandbox create --from xquik --provider xquik -- claude
```

The same Skill is available to Codex, OpenCode, and GitHub Copilot in the base image.

## Read-only boundary

The provider permits `GET`, `HEAD`, and `OPTIONS` requests to these locations:

- `https://xquik.com/api/v1/**`
- `https://xquik.com/openapi.json`
- `https://docs.xquik.com/**`

OpenShell injects `XQUIK_API_KEY` as a placeholder. The proxy resolves it only for the profile endpoints.

The profile blocks API writes and remote MCP calls. It does not enable extraction jobs, monitors, webhooks, or account actions. Those operations use write methods or MCP calls and need a separate reviewed policy.

The network policy cannot distinguish public and private `GET` requests. Follow the Skill's approval rule before any private read.

## Verify access

Inside the sandbox, check the authenticated read path without starting a job:

```bash
curl --fail --silent --show-error \
--header "x-api-key: ${XQUIK_API_KEY}" \
https://xquik.com/api/v1/credits
```

The sandbox receives a placeholder, not the stored API key. OpenShell replaces it at the approved endpoint.

## Build locally

Build against the published base image:

```bash
docker build \
--build-arg BASE_IMAGE=ghcr.io/nvidia/openshell-community/sandboxes/base:latest \
-t openshell-xquik \
sandboxes/xquik
```

To update the Skill, change `XQUIK_SKILL_COMMIT` only after reviewing the public diff and license.
43 changes: 43 additions & 0 deletions sandboxes/xquik/provider-profile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

id: xquik-read-only
display_name: Xquik read-only API
description: Read-only Xquik API access for sandbox agents
category: data
inference_capable: false
credentials:
- name: api_key
description: Xquik API key
env_vars: [XQUIK_API_KEY]
required: true
auth_style: header
header_name: x-api-key
discovery:
credentials: [api_key]
endpoints:
- host: xquik.com
port: 443
path: /api/v1/**
protocol: rest
access: read-only
enforcement: enforce
- host: xquik.com
port: 443
path: /openapi.json
protocol: rest
access: read-only
enforcement: enforce
- host: docs.xquik.com
port: 443
protocol: rest
access: read-only
enforcement: enforce
binaries:
- /usr/local/bin/claude
- /usr/bin/node
- /usr/bin/codex
- /usr/local/bin/opencode
- /usr/lib/node_modules/opencode-ai/bin/.opencode
- /usr/bin/copilot
- /usr/bin/curl