Skip to content

feat: add interactive command mode, :help/:usage commands, and token usage tracking#747

Open
seagochen wants to merge 20 commits intosipeed:mainfrom
seagochen:dev_features
Open

feat: add interactive command mode, :help/:usage commands, and token usage tracking#747
seagochen wants to merge 20 commits intosipeed:mainfrom
seagochen:dev_features

Conversation

@seagochen
Copy link

@seagochen seagochen commented Feb 25, 2026

📝 Description

This PR adds several new interactive features to the PicoClaw CLI agent:

  1. Interactive Command Mode (:cmd / :pico): Users can now switch between AI chat mode and a direct shell command execution mode. Command mode supports cd with working directory tracking, cross-platform shell execution (sh on Unix, PowerShell on Windows), and persists the working directory across commands.

  2. AI-Assisted Command Mode (:hipico): From within command mode, users can invoke one-shot AI assistance. The current working directory is injected into the system prompt so the AI resolves paths relative to the cmd working directory.

  3. :help Command: A printInteractiveHelp() function that displays detailed usage for all modes and commands, available in any interactive mode.

  4. :usage Command: Displays current model name, max tokens, temperature, and accumulated session token statistics (prompt tokens, completion tokens, total requests).

  5. Token Usage Tracking: AgentInstance now tracks TotalPromptTokens, TotalCompletionTokens, and TotalRequests via atomic counters, accumulated after each LLM call via AddUsage().

  6. Refactoring: Renamed printHelpprintCliHelp (top-level CLI help) and printInteractiveHelp (interactive mode help) to eliminate function name collisions.

🗣️ Type of Change

  • 🐞 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 📖 Documentation update
  • ⚡ Code refactoring (no functional changes, no api changes)

🤖 AI Code Generation

  • 🤖 Fully AI-generated (100% AI, 0% Human)
  • 🛠️ Mostly AI-generated (AI draft, Human verified/modified)
  • 👨‍💻 Mostly Human-written (Human lead, AI assisted or none)

🔗 Related Issue

📚 Technical Context (Skip for Docs)

🧪 Test Environment

  • Hardware:
  • OS:
  • Model/Provider:
  • Channels:

📸 Evidence (Optional)

Click to view Logs/Screenshots スクリーンショット 2026-02-25 094428 スクリーンショット 2026-02-25 094450 スクリーンショット 2026-02-25 094504 スクリーンショット 2026-02-25 094658 スクリーンショット 2026-02-25 094720

☑️ Checklist

  • My code/docs follow the style of this project.
  • I have performed a self-review of my own changes.
  • I have updated the documentation accordingly.

claude and others added 11 commits February 24, 2026 03:31
Add three interactive modes to the CLI agent:
- /cmd: switch to command mode for direct shell command execution
- /pico: switch back to AI chat mode
- /hipico <msg>: invoke AI assistance from within command mode
- /byepico: end AI assistance and return to command mode

Command mode supports cd with directory tracking, cross-platform
shell execution (sh on Unix, PowerShell on Windows), and contextual
AI assistance that knows the current working directory.

https://claude.ai/code/session_01PoHBfe7eKmhHvVF12W3xZ2
Adds a printHelp() function that outputs detailed usage information
covering all three modes (chat, command, AI-assisted), available
commands, mode switching, and examples. /help is intercepted before
the mode-specific switch block so it works in any mode.

https://claude.ai/code/session_01PoHBfe7eKmhHvVF12W3xZ2
Adds token usage tracking to AgentInstance using atomic counters
(TotalPromptTokens, TotalCompletionTokens, TotalRequests) that
accumulate after each LLM call. The /usage command displays current
model name, max tokens, temperature, and session token statistics.
Available in all interactive modes like /help.

https://claude.ai/code/session_01PoHBfe7eKmhHvVF12W3xZ2
Resolve function name collision between the top-level CLI help and the
interactive mode help by giving each a distinct, descriptive name.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…mode

- Add :edit command for file viewing and editing in cmd mode
  (:edit file, :edit file N text, :edit file +N text, :edit file -N,
   :edit file -m """...""" for multi-line write with auto-create)
- Intercept vim/nano/vi/emacs with helpful :edit redirect message
- Replace Makefile with scripts/ (build.sh, install.sh, deploy.sh,
  setup.sh, check.sh, docker.sh) for build, test, deploy, and
  environment setup
- Simplify :hipico to one-shot mode, remove :byepico and modeHiPico
- Switch command prefixes from / to : (:cmd, :pico, :hipico, :help)
- Add console-like code block formatting and emoji file type indicators
  for ls output in cmd mode
- Update Dockerfile and CI workflow to use scripts/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When using :hipico from cmd mode after cd'ing to a subdirectory, the AI
now sees the current working directory in the system prompt instead of
just a weak user-message prefix. This ensures the AI resolves file paths
relative to the cmd working directory, not the workspace root.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Revert the build system back to Makefile, removing the shell scripts
introduced in d9ae60b.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update CI and Docker build to use `make` instead of removed scripts/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- handleCdCommand: redirect cd, cd ~, cd /, cd /path to workspace
  directory instead of $HOME or system root for safety
- guardCommand: fix path regex false positive that extracted "/exe"
  from "./exe.sh" and blocked it as absolute path outside workspace

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@xiaket xiaket added type: enhancement New feature or request domain: agent labels Feb 25, 2026
Copy link

@nikolasdehor nikolasdehor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a 1068-line PR that adds interactive command mode, file editing, token tracking, and several UX features. It is doing too many things at once and would benefit from being split into separate PRs (token tracking, command mode, edit command, ls formatting). Several significant issues:

Security Issues:

  1. :edit bypasses workspace restriction: The resolveEditPath function allows absolute paths (/etc/passwd) and ~/ expansion to the real home directory (not the workspace). This means from any channel (WhatsApp, Telegram, Discord), a user can read and write arbitrary files on the host. The cd command correctly restricts absolute paths to the workspace, but :edit does not.

  2. :edit -m creates files with MkdirAll: Combined with the above, a user can create arbitrary directories and files anywhere on the filesystem.

  3. Shell command execution via command mode: executeCmdMode calls agent.Tools.ExecuteWithContext which should go through the ExecTool safety guard, but the command mode concept itself needs careful thought about access control — especially when exposed over multi-user channels like Telegram groups.

Correctness Issues:

  1. Global mutable state cmdWorkingDir: The package-level var cmdWorkingDir with an init() function is only used by the CLI executeShellCommand but is global state. If the agent loop is used from the gateway (non-CLI), this is unused. More importantly, the per-session working directory in loop.go (via getSessionWorkDir/setSessionWorkDir) and the global cmdWorkingDir are two separate tracking mechanisms for the same concept.

  2. Duplicated logic: The mode switching logic (interactiveMode and simpleInteractiveMode) is nearly identical — 100+ lines of duplicated switch/case blocks. Extract a shared handler function.

  3. : commands intercepted globally: handleCommand now intercepts ALL messages starting with : across ALL channels. If a Telegram user sends :) or :thinking:, it will return "Unknown command: :)". This breaks normal chat usage. The : prefix should only be recognized in specific contexts (CLI interactive mode), not in the agent loop's global command handler.

  4. ensureLsLong silently modifies user commands: Injecting -l into ls commands changes the output format. This is surprising behavior — if someone types ls *.go they expect filename-only output, not a long listing. The emoji formatting is a nice touch but should be opt-in.

Missing:

  1. No tests: 1068 lines of new code with zero test coverage. At minimum, editLineOp, ensureLsLong, isPermString, resolveEditPath, handleCdCommand, and shortenHomePath should have unit tests.

  2. No documentation: The PR adds significant user-facing features but does not update the README or docs.

Orlando Chen and others added 5 commits February 26, 2026 16:09
Resolve conflicts by accepting main's cobra CLI restructuring.
CLI mode switching code (cmdWorkingDir, executeShellCommand, duplicated
interactiveMode/simpleInteractiveMode switch/case) is removed — the
agent loop's processMessage already handles all mode switching for
all channels including CLI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Export validatePath → ValidatePath for cross-package use
- Rewrite resolveEditPath to validate paths via tools.ValidatePath,
  blocking absolute paths, symlink escape, and path traversal
- Map ~ to workspace root (not $HOME) for consistency with cd
- Return access denied error for paths outside workspace

Security: previously :edit /etc/passwd or :edit ~/.ssh/id_rsa could
read/write arbitrary files. Now all :edit paths are sandboxed to the
agent workspace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change handleExtensionCommand default case to pass through unrecognized
: prefixed messages as normal chat. Previously :) :D 🤔 etc.
would return "Unknown command" across all channels (Telegram, Discord).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove ensureLsLong which silently injected -l into all ls commands,
changing output format unexpectedly. Now ls runs as-is; emoji type
indicators only apply when user explicitly uses ls -l.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- resolveEditPath: absolute blocked, ~ maps to workspace, traversal
  blocked, symlink escape blocked, valid relative works
- shortenHomePath: home/subpath/other cases
- isLsCommand, hasLongFlag, isPermString: table-driven tests
- guardCommand: verify ./executable is not blocked
- handleExtensionCommand: verify :) :D 🤔 pass through

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@alexhoshina
Copy link
Collaborator

Please run golangci-lint run --fix to pass the checks

Orlando Chen and others added 3 commits February 26, 2026 16:30
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merge handleCommand() and handleExtensionCommand() into a single
function. Convert /show, /list, /switch to :show, :list, :switch.
Remove duplicate Telegram-side /show and /list handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The colon-prefix unification was not practical for these commands.
Restore original /show, /list, /switch behavior and Telegram handlers.
Remove them from :help output to keep the help text focused on
colon commands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
raw := cmd[loc[0]:loc[1]]
// Skip relative paths like ./executable — the regex extracts
// "/executable" from "./executable" but it's not an absolute path.
if loc[0] > 0 && cmd[loc[0]-1] == '.' {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the ../ path, escape may occur.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for reviewing, I have added some limitations to such case.

After filepath.Clean resolves ../  sequences, verify the resulting
path is still within the workspace directory.  If not, silently
redirect to workspace root — same behaviour as cd / and cd ~.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants