Skip to content

Latest commit

 

History

History
357 lines (253 loc) · 9.43 KB

File metadata and controls

357 lines (253 loc) · 9.43 KB

xCloud Terminal Implementation Plan

For Hermes: Use subagent-driven-development skill to implement this plan task-by-task.

Goal: Build xterm, the xCloud Terminal: an Ubuntu-installable CLI with deterministic direct commands and Claude Code-style AI agent mode.

Architecture: Keep direct API execution deterministic and reusable. Add an AI agent layer that plans and invokes the same tool/client layer with strict schema validation, confirmations, resource safety, output reduction, and provider abstraction. Treat the Laravel AI chatbot branch as server-side inspiration and future hosted backend, not as code to merge wholesale into the CLI.

Tech Stack: Node.js 20+ ESM, commander, enquirer, chalk/ora, zod, Vercel AI SDK, OpenAI-compatible/OpenRouter, Anthropic SDK, optional node-pty, GitHub Actions CI.


Phase 0: Repository bootstrap ✅

Task 0.1: Create standalone repo

Objective: Create xCloudDev/xcloud-terminal and initial package scaffold.

Files:

  • package.json
  • bin/xterm.js
  • README.md
  • docs/BRANCH-ANALYSIS.md
  • docs/ARCHITECTURE.md
  • docs/IMPLEMENTATION-PLAN.md

Verification:

node --check bin/xterm.js
node ./bin/xterm.js --help
node ./bin/xterm.js --ai

Phase 1: Direct command foundation

Task 1.1: Bundle @xcloud/cli and expose xcloud --ai

Objective: @xcloud/terminal installs direct xCloud commands by default and exposes both xterm and xcloud binaries.

Files:

  • Modify: package.json
  • Modify: bin/xterm.js
  • Test: test/smoke.test.js

Expected behavior:

xterm servers list          # delegates to bundled @xcloud/cli
xcloud servers list         # same direct behavior when installed from @xcloud/terminal
xterm --ai                  # opens local AI agent mode
xcloud --ai                 # opens local AI agent mode
xterm --ai --agent hosted   # loads xcloud-agent-skills

Verification:

node --test test/smoke.test.js
npm install -g . --prefix /tmp/xcloud-terminal-global
/tmp/xcloud-terminal-global/bin/xcloud --ai
/tmp/xcloud-terminal-global/bin/xterm --ai --agent hosted

Task 1.2: Import/reuse xCloud direct command client

Objective: Make xterm servers list behave like the existing @xcloud/cli direct mode.

Files:

  • Create: lib/direct/config.js
  • Create: lib/direct/http.js
  • Create: lib/direct/routes.js
  • Create: lib/direct/output.js
  • Modify: bin/xterm.js
  • Test: test/direct.test.js

Steps:

  1. Copy/adapt direct command modules from xCloudDev/xCloud-cli.
  2. Preserve env vars:
    • XCLOUD_BASE_URL
    • XCLOUD_API_TOKEN
    • XCLOUD_API_FLAVOR
    • XCLOUD_PROFILE
  3. Preserve output modes: table|json|yaml.
  4. Preserve destructive confirmation behavior.
  5. Add tests for route resolution, API URL building, JSON output, and confirmation-required errors.

Verification:

node --test test/direct.test.js
node ./bin/xterm.js --output json servers list
node ./bin/xterm.js sites backup fake-uuid

Expected: backup without --yes fails safely.

Task 1.2: Decide package relationship with @xcloud/cli

Objective: Avoid maintaining two divergent command maps.

Options:

  • Short term: copy modules into xcloud-terminal, then backport improvements.
  • Better: move shared direct command code into @xcloud/core or expose it from @xcloud/cli as importable modules.
  • Final: @xcloud/terminal can become the superset package and @xcloud/cli can remain direct-only.

Recommendation: Create @xcloud/core only after first working agent. For now copy/adapt, because publishing/package boundaries slow iteration.


Phase 2: Tool catalog

Task 2.1: Define tool schema

Objective: Define typed tool metadata used by both direct and AI modes.

Files:

  • Create: lib/tools/schema.js
  • Create: lib/tools/catalog.js
  • Test: test/tools.test.js

Schema fields:

{
  id: 'servers.list',
  title: 'List servers',
  description: 'List xCloud servers visible to the active profile',
  method: 'GET',
  path: '/servers',
  apiFlavor: 'public',
  parameters: [],
  destructive: false,
  billingImpact: false,
  requiresConfirmation: false,
  outputReducer: 'json-summary'
}

Verification:

node --test test/tools.test.js

Task 2.2: Adapt Laravel branch YAML concepts

Objective: Bring over useful metadata concepts without copying Laravel code.

Files:

  • Create: docs/tool-catalog-format.md
  • Modify: lib/tools/schema.js

Must support:

  • destructive
  • billing_impact
  • confidential
  • locks
  • required_when
  • lookup_ref / dynamic options placeholder
  • response_format

Verification: schema tests with fixtures inspired by storage/ai/tool-definitions/server-actions.yaml and site-actions.yaml.


Phase 3: AI provider abstraction

Task 3.1: Add AI config loader

Objective: Read provider/model/API key without leaking secrets.

Files:

  • Create: lib/ai/config.js
  • Create: test/ai-config.test.js

Env vars:

XCLOUD_AI_PROVIDER=openrouter|anthropic|openai
XCLOUD_AI_MODEL=anthropic/claude-sonnet-4-5
XCLOUD_AI_BASE_URL=https://openrouter.ai/api/v1
XCLOUD_AI_API_KEY=...

Verification: missing key reports not_configured; key is redacted in doctor output.

Task 3.2: Add provider client

Objective: Implement one generateDecision(messages, schema) interface.

Files:

  • Create: lib/ai/provider.js
  • Test: test/provider.test.js

Implementation:

  • Use Vercel AI SDK if practical.
  • Use official openai for OpenRouter/OpenAI-compatible calls.
  • Use @anthropic-ai/sdk for direct Claude.
  • All model decisions must be JSON and Zod-validated.

Phase 4: Agent loop

Task 4.1: Define decision schema

Objective: Create a strict model output schema.

Files:

  • Create: lib/agent/decision-schema.js
  • Test: test/decision-schema.test.js

Decision types:

  • answer
  • ask_user
  • tool_call
  • plan

Task 4.2: Implement ReAct loop

Objective: Build Think → Act → Observe loop similar to the Laravel branch ReActAgent, but in Node.

Files:

  • Create: lib/agent/react-agent.js
  • Create: lib/agent/prompts.js
  • Test: test/react-agent.test.js

Rules:

  • Max steps default 8.
  • Each tool call emits a step event.
  • Observations are reduced before re-entering model context.
  • Cancellation supported via AbortController.
  • No raw secret/log blob in model context.

Task 4.3: Tool execution bridge

Objective: Let AI invoke same direct command/API layer.

Files:

  • Create: lib/agent/tool-runner.js
  • Test: test/tool-runner.test.js

Safety:

  • Reject unknown tools.
  • Validate params.
  • Confirm writes/destructive/billing-impact actions.
  • Non-interactive writes require --yes.

Phase 5: Interactive terminal UX

Task 5.1: Add xterm --ai shell

Objective: Open an interactive prompt loop.

Files:

  • Modify: bin/xterm.js
  • Create: lib/ui/agent-shell.js
  • Test: test/agent-shell.test.js

UX:

xCloud Terminal AI
Profile: prod | API: public | Model: anthropic/claude-sonnet-4-5
> show my unhealthy servers

Features:

  • /help
  • /exit
  • /profile prod
  • /mode direct|ai
  • /plan on|off
  • Ctrl+C cancels current run or exits if idle.

Task 5.2: Add one-shot chat command

Objective: Allow automation-friendly AI prompts.

xterm chat "Which server has highest CPU?" --output json

Behavior: returns structured JSON with answer, steps, tool calls, and safety denials.


Phase 6: Hosted xCloud AI backend support

Task 6.1: Detect hosted AI endpoints

Objective: Check /api/ai/health and /api/ai/tools/available when authenticated.

Files:

  • Create: lib/hosted/health.js
  • Create: lib/hosted/client.js

Task 6.2: Implement --agent hosted

Objective: Load portable skills from xCloudDev/xcloud-agent-skills and run with the user's Anthropic/OpenAI/OpenRouter token. Later, optionally forward chat to xCloud Laravel AI endpoints when branch is merged/stable.

Endpoints from inspected branch:

  • GET /api/ai/health
  • POST /api/ai/bootstrap
  • GET /api/ai/chats
  • POST /api/ai/chats
  • POST /api/ai/chats/messages
  • POST /api/ai/chats/{chat}/messages
  • GET /api/ai/tools/available
  • POST /api/ai/chats/{chat}/agent/cancel
  • POST /api/ai/chats/{chat}/agent/{run}/retry

Caution: The branch uses ai.execution.token middleware and web/Sanctum context; CLI token flow may require an API-friendly bootstrap endpoint.


Phase 7: Packaging

Task 7.1: npm packaging

Verification:

npm pack --dry-run
npm install -g . --prefix /tmp/xcloud-terminal-global
/tmp/xcloud-terminal-global/bin/xterm --help

Task 7.2: Homebrew formula

Files:

  • Create: Formula/xcloud-terminal.rb

Task 7.3: Ubuntu/deb install path

Options:

  • npm global install first.
  • Later create .deb via nfpm or GitHub release assets.
  • Document supported Ubuntu versions and Node install requirement.

Acceptance criteria

  • xterm servers list works without AI.
  • xterm --ai opens interactive agent.
  • xterm chat "..." --output json works non-interactively.
  • AI mode can call at least read-only tools first: list servers, show server, list sites, site status, logs/monitoring if endpoint exists.
  • AI mode blocks destructive actions without confirmation.
  • AI mode never prints or stores raw secrets.
  • Tests pass in GitHub Actions.
  • README documents npm install, direct mode, AI mode, provider config, and safety model.