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.
Objective: Create xCloudDev/xcloud-terminal and initial package scaffold.
Files:
package.jsonbin/xterm.jsREADME.mddocs/BRANCH-ANALYSIS.mddocs/ARCHITECTURE.mddocs/IMPLEMENTATION-PLAN.md
Verification:
node --check bin/xterm.js
node ./bin/xterm.js --help
node ./bin/xterm.js --aiObjective: @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-skillsVerification:
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 hostedObjective: 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:
- Copy/adapt direct command modules from
xCloudDev/xCloud-cli. - Preserve env vars:
XCLOUD_BASE_URLXCLOUD_API_TOKENXCLOUD_API_FLAVORXCLOUD_PROFILE
- Preserve output modes:
table|json|yaml. - Preserve destructive confirmation behavior.
- 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-uuidExpected: backup without --yes fails safely.
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/coreor expose it from@xcloud/clias importable modules. - Final:
@xcloud/terminalcan become the superset package and@xcloud/clican remain direct-only.
Recommendation: Create @xcloud/core only after first working agent. For now copy/adapt, because publishing/package boundaries slow iteration.
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.jsObjective: Bring over useful metadata concepts without copying Laravel code.
Files:
- Create:
docs/tool-catalog-format.md - Modify:
lib/tools/schema.js
Must support:
destructivebilling_impactconfidentiallocksrequired_whenlookup_ref/ dynamic options placeholderresponse_format
Verification: schema tests with fixtures inspired by storage/ai/tool-definitions/server-actions.yaml and site-actions.yaml.
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.
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
openaifor OpenRouter/OpenAI-compatible calls. - Use
@anthropic-ai/sdkfor direct Claude. - All model decisions must be JSON and Zod-validated.
Objective: Create a strict model output schema.
Files:
- Create:
lib/agent/decision-schema.js - Test:
test/decision-schema.test.js
Decision types:
answerask_usertool_callplan
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.
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.
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|offCtrl+Ccancels current run or exits if idle.
Objective: Allow automation-friendly AI prompts.
xterm chat "Which server has highest CPU?" --output jsonBehavior: returns structured JSON with answer, steps, tool calls, and safety denials.
Objective: Check /api/ai/health and /api/ai/tools/available when authenticated.
Files:
- Create:
lib/hosted/health.js - Create:
lib/hosted/client.js
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/healthPOST /api/ai/bootstrapGET /api/ai/chatsPOST /api/ai/chatsPOST /api/ai/chats/messagesPOST /api/ai/chats/{chat}/messagesGET /api/ai/tools/availablePOST /api/ai/chats/{chat}/agent/cancelPOST /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.
Verification:
npm pack --dry-run
npm install -g . --prefix /tmp/xcloud-terminal-global
/tmp/xcloud-terminal-global/bin/xterm --helpFiles:
- Create:
Formula/xcloud-terminal.rb
Options:
- npm global install first.
- Later create
.debvianfpmor GitHub release assets. - Document supported Ubuntu versions and Node install requirement.
xterm servers listworks without AI.xterm --aiopens interactive agent.xterm chat "..." --output jsonworks 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.