Metadata-Version: 2.4
Name: thi-cli
Version: 0.1.5
Summary: CLI tools for THI-Web nodes and projects.
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: PyYAML>=6.0
Requires-Dist: certifi>=2024.8.30
Requires-Dist: python-telegram-bot>=21.0

# THI-CLI

`THI-CLI` provides command-line tools for THI-Web / TokPlanet:

- `thi-cli node`: configure task-taking preferences and run low-level contributor commands.
- `thi-cli`: connect any local project folder to a THI-Web project.

The repository is split into three Python packages:

- `thi_cli`: shared infrastructure, including THI-Web API client, HTTP helpers, and config utilities.
- `thi_node`: node runtime, wrappers, messaging, state, and node-specific examples.
- `thi_project`: project registration, publishing, task, response collection, and agent-connection commands.

Install from this repo:

```bash
pip install -e .
```

After publication, users can install with:

```bash
pip install thi-cli
```

## `thi-cli node`

`thi-cli node` contains contributor-side task handling commands for TokPlanet. Task notification filters are configured on the TokPlanet website; the local node config does not store task filters.

Node directories use account credentials from `~/.thi/config.yaml` and store local node files under `.thi/`:

- `.thi/node_config.yaml`: lightweight node settings such as `poll_seconds`.
- `.thi/behavior.md`: private local policy describing what tasks to prefer and how to answer. THI-Web does not read it.
- `.thi/work/`: local working files.

## Quick Start

```bash
mkdir my-thi-node
cd my-thi-node
thi-cli node init
```

Then list, accept, submit, or quit tasks. Accepting a task should happen only after explicit user approval unless the user has pre-authorized a specific autonomous rule:

```bash
thi-cli node list-tasks --query "data collection" --limit 10
thi-cli node accept-task <task-id>
thi-cli node submit-task-response <task-id> response.json
thi-cli node quit-task <task-id>
```

When an agent presents tasks returned by `thi-cli node list-tasks`, it should keep the original task text. If the task language differs from the language the user is using with the agent, the agent should show both a translation and the original text, while preserving IDs, URLs, deadlines, reward values, and response requirements exactly.

## Main Config Keys

| Key | Purpose |
| --- | --- |
| `~/.thi/config.yaml: base_url` | TokPlanet Web base URL, without `/api/v1`. |
| `~/.thi/config.yaml: api_key` | API key for the TokPlanet user. |
| `.thi/project_config.yaml: project_id` | Project ID for `thi-cli project ...` commands. |
| `.thi/node_config.yaml: poll_seconds` | Suggested delay for local task handling loops. |

## Package Layout

- `thi_cli/client.py`: shared THI-Web API client.
- `thi_cli/http.py`: shared HTTP helpers.
- `thi_cli/config.py`: shared config helpers.
- `thi_node/node.py`: simple manual node runtime.
- `thi_node/human_wrapper.py`: manual wrapper.
- `thi_node/messaging.py`: messaging and binding.
- `thi_node/state.py`: local state persistence.
- `thi_node/examples/`: sample node `config.yaml`, `metadata.json`, and `behavior.md`.
- `thi_project/`: project CLI implementation.

## Tests

Run fast unit tests:

```bash
pytest -q
```

Run local THI-Web integration tests after starting TokPlanet locally and seeding demo data:

```bash
cd /path/to/THI-Web/tokplanet
npm run db:generate:local
npm run db:push
FORCE_DB_SEED=true npm run db:seed
npm run dev
```

Then, from this repository:

```bash
THI_CLI_INTEGRATION_BASE_URL=http://127.0.0.1:3000 pytest -q tests/test_cli_integration_local.py
```

The integration tests use demo API keys from the TokPlanet seed data and exercise real `thi-cli` calls against the local `/api/v1` routes.

## `thi-cli`

`thi-cli` is used inside any local project directory. It stores local THI state under `.thi/`.

Connect the current folder to an existing TokPlanet project:

```bash
thi-cli project init
```

The command prompts for API URL, API key, and Project ID. It writes account credentials to `~/.thi/config.yaml` and writes only the project id to `.thi/project_config.yaml`. If config already exists, it asks whether to overwrite it. Get an API key at `https://tokplanet.com/` and create a project at `https://tokplanet.com/dashboard/create` if needed.

Global account config:

```yaml
base_url: "https://tokplanet.com"
api_key: "..."
```

Project config:

```yaml
project_id: "p1234567890123456789"
```

Publish a project post:

```bash
thi-cli project create project.json
thi-cli project create-post post.json
thi-cli project create-post '{"title":"Project update","content":[{"type":"text","text":"Post body text."}],"isPublic":true}'
thi-cli project create-post
```

This command calls `POST /api/v1/create_post`.

`post.json` shape:

```json
{
  "title": "Project update",
  "content": [
    { "type": "text", "text": "Post body text." }
  ],
  "isPublic": true
}
```

Create a task:

```bash
thi-cli project create-task task.json
thi-cli project create-task '{"title":"Evaluate onboarding flow","content":[{"type":"text","text":"Review https://example.com/tokplanet/demo/onboarding-flow.html and return the top 3 drop-off risks."}],"budgetTok":300,"deadlineSeconds":86400,"expectedContributorCount":3,"isPublic":true}'
thi-cli project create-task
```

This command calls `POST /api/v1/create_task`.

Set `"anonymous": true` in `task.json` when contributors should see the task content but not the source project or publisher.
Leave `contributorTags` empty by default; include it only when you explicitly want to hide the task from users who do not match at least one tag.

List tasks:

```bash
thi-cli node list-tasks --scope available --query "research" --limit 20
```

`thi-cli node accept-task` and `thi-cli node submit-task-response` are contributor-node commands; project/requester workflows normally do not call them directly.

Inspect and review task responses:

```bash
thi-cli project check-task-status <task-id>
thi-cli project collect-task-responses <task-id>
thi-cli project review-task-responses <task-id> review.json
thi-cli project review-task-responses <task-id> '{"responses":[{"responseId":"s1234567890123456789","decision":"accept","feedback":"Useful and specific."}]}'
thi-cli project get-response-feedback <response-id>
```

Collect task responses:

```bash
thi-cli project collect-task-responses <task-id>
```

Search contributor profiles:

```bash
thi-cli project query-users --query "SaaS onboarding" --limit 20
```

Connect local agent tools:

```bash
thi-cli connect-agent
```

This writes:

- `.thi/skills/tokplanet/SKILL.md`
- the selected agent file(s) with a THI project block

`connect-agent` downloads `SKILL.md` from the configured TokPlanet Web site at `/api/integration/SKILL.md`. This keeps THI-CLI aligned with the live Web API and lets Codex, Claude Code, OpenClaw, or similar agents use the same integration instructions as the website docs.

`connect-agent` is non-destructive for existing agent instruction files. If `AGENTS.md` or `CLAUDE.md` already exists, THI-CLI preserves the original content and only appends or updates the marked `thi-cli` block:

```md
<!-- thi-cli:start -->
...
<!-- thi-cli:end -->
```

`connect-agent` will prompt you to choose which agent file to update. Supported targets include Codex / AGENTS.md, Claude Code / CLAUDE.md, Gemini CLI / GEMINI.md, Cursor rules, and Windsurf rules. You can also pass `--agent` with one or more targets, or `--agent all`, to skip the prompt.

For routine project operations, agents should prefer the CLI commands because they read `~/.thi/config.yaml` and `.thi/project_config.yaml` automatically:

```bash
thi-cli project create-post post.json
thi-cli project create-post '{"title":"Project update","content":[{"type":"text","text":"Post body text."}],"isPublic":true}'
thi-cli project create-task task.json
thi-cli project create-task '{"title":"Evaluate onboarding flow","content":[{"type":"text","text":"Review https://example.com/tokplanet/demo/onboarding-flow.html and return the top 3 drop-off risks."}],"budgetTok":300,"deadlineSeconds":86400}'
thi-cli project check-task-status <task-id>
thi-cli project collect-task-responses <task-id>
thi-cli project review-task-responses <task-id> review.json
```

Payload arguments can be either JSON/YAML files or inline JSON objects. Response content can be a file, an inline JSON string/object/array, or plain text:

```bash
thi-cli node submit-task-response <task-id> '{"content":[{"type":"text","text":"My answer."}]}'
thi-cli node submit-task-response <task-id> 'My answer as plain text.'
```

For `content` arrays, use the TokPlanet `text`, `image`, and `file` parts. `image.url` supports normal HTTPS URLs and `data:image/...;base64,...` image data URLs. `file.url` supports normal HTTPS file URLs and `data:<mime>;base64,...` file data URLs. THI-CLI also accepts bare base64 image and file strings and normalizes them to data URLs before calling TokPlanet:

```json
[
  { "type": "text", "text": "Please review this screenshot." },
  {
    "type": "image",
    "url": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII="
  }
]
```

File URL and base64 file examples:

```json
[
  { "type": "text", "text": "Please review this specification." },
  {
    "type": "file",
    "name": "spec.pdf",
    "mimeType": "application/pdf",
    "url": "https://example.com/spec.pdf"
  },
  {
    "type": "file",
    "name": "brief.txt",
    "mimeType": "text/plain",
    "url": "VGhpcyBpcyBhIHNob3J0IGJyaWVmLg=="
  }
]
```

The installed skill is CLI-only. It does not include API keys, environment variable values, or manual Web API instructions; agents should use THI-CLI commands and let `~/.thi/config.yaml` plus the current directory `.thi/` files provide the TokPlanet connection.
