Skip to content

Conversation

@bokelley
Copy link
Collaborator

@bokelley bokelley commented Nov 8, 2025

Summary

Complete overhaul of the Scope3 Agentic Client CLI with enhanced security, debug capabilities, and comprehensive testing. All 86+ CLI commands now work reliably with proper error handling and multiple output formats.

Changes

Core Features:

  • Environment switching (production/staging) via --environment flag or env var
  • Debug mode with --debug flag showing full request/response logging
  • Three output formats: JSON, table (columnar), and list (detailed)
  • Generic array extraction from API responses (fixes hanging brand-agent list)

Security:

  • Sanitizes sensitive data (apiKey, token, password, etc.) in debug logs
  • Config file permissions set to 0600 (owner read/write only)
  • Config directory permissions set to 0700 (owner only)
  • Environment variable validation with helpful warnings

Testing:

  • 74 new tests covering MCP protocol, logging, and CLI formatting
  • Comprehensive error scenario testing
  • Debug mode functionality validated

Test Results

All 83 tests passing with 0 regressions.

bokelley and others added 9 commits November 8, 2025 05:36
The CLI wasn't working with npx because the dist folder was excluded
from npm packages (gitignored but no npmignore override).

Changes:
- Add .npmignore to include dist folder in npm package
- Add explicit "files" field to package.json for clarity
- Add prepublishOnly script to ensure project is built before publishing

The package now correctly includes both CLI executables:
- scope3 (main CLI for Scope3 Agentic API)
- simple-media-agent (media agent server)

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Users can now easily switch between production and staging environments
in both the SDK and CLI without manually specifying full URLs.

SDK changes:
- Add optional 'environment' parameter to ClientConfig
- Support 'production' and 'staging' environments
- Priority: baseUrl > environment > default to production
- Environment URLs:
  - Production: https://api.agentic.scope3.com
  - Staging: https://api.agentic.staging.scope3.com

CLI changes:
- Add --environment flag (production or staging)
- Add environment to config commands (scope3 config set environment)
- Support SCOPE3_ENVIRONMENT environment variable
- Examples:
  - scope3 --environment staging list-tools
  - scope3 config set environment staging
  - export SCOPE3_ENVIRONMENT=staging

Documentation:
- Update README with environment switching examples
- Add environment configuration section
- Include npx usage example

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Staging URL is: https://api.agentic.staging.scope3.com
(subdomain order is api.agentic.staging, not api.staging.agentic)

Changes:
- Set correct staging URL: https://api.agentic.staging.scope3.com
- Add getBaseUrl() public method to retrieve configured URL
- Add initialization logging showing baseUrl, environment, and whether custom URL is used
- Update README with correct staging URL

Users can now verify their configuration:
```typescript
const client = new Scope3AgenticClient({
  apiKey: 'key',
  environment: 'staging'
});
console.log(client.getBaseUrl()); // https://api.agentic.staging.scope3.com
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The API often returns responses with just a pre-formatted message field.
The CLI was displaying these as a table (showing the key/value pair) and
then repeating the message below, causing duplicate output.

Changes:
- Detect when response has only a "message" field
- Display the message directly without table formatting
- Remove duplicate message display at the end
- Cleaner output for commands like agent list, media-product list, etc.

Before: Message shown in table format + repeated below
After: Message shown once, cleanly formatted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Major improvements to CLI output and debugging:

**Debug Mode:**
- Add --debug flag to enable request/response logging
- Capture and log MCP requests with timing information
- Show full request/response details when debug is enabled
- Inspired by AdCP client's debug implementation

**Structured Data:**
- Fix client to use structuredContent from MCP responses
- API returns both formatted text AND structured data
- Client now prioritizes: structuredContent > JSON > text
- Properly handle responses with items arrays

**Improved Output:**
- Extract items array from list responses automatically
- Display data in proper table format with columns
- Clean table output for agent list, products, etc.

**Before:**
- Pre-formatted text messages wrapped in ugly tables
- No visibility into API requests/responses

**After:**
- Beautiful columnar tables with agent data
- Full debug logging with --debug flag
- Proper structured data handling

Example:
```bash
scope3 --debug agent list --type SALES
# Shows MCP request/response + structured table
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Logger was outputting INFO and WARNING messages by default, polluting
the CLI output. Now logs only show when debug mode is enabled.

Changes:
- Add setDebug() method to logger
- Make info/warn/debug respect debug flag
- Errors always log (for critical issues)
- Client enables logger debug when debug config is true

Before:
```
scope3 agent list
{"message":"Initializing Scope3 client",...}
[table output]
```

After:
```
scope3 agent list
[clean table output only]

scope3 --debug agent list
{"message":"Initializing Scope3 client",...}
{"message":"MCP Request",...}
{"message":"MCP Response",...}
[table output]
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Users can now choose between three output formats for all commands:
- table: Columnar view (may truncate long values) - default
- list: Detailed view with all fields, no truncation
- json: Raw JSON output

All dynamically generated commands use the same formatOutput() function,
so this works consistently across all 86+ tools.

Format examples:
```bash
# Table (default): compact columnar view
scope3 agent list --type SALES

# List: detailed, no truncation
scope3 agent list --type SALES --format list

# JSON: raw data for scripting
scope3 agent list --type SALES --format json | jq '.items[]'
```

List format shows:
- Numbered items
- All fields with full values
- Colored output (cyan numbers, yellow keys)
- Pretty-printed JSON for complex values
- No data truncation

This addresses the concern that table format may truncate URLs
and other long values. Users can choose the format that fits
their needs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The formatOutput function was only looking for 'items' arrays, but
different API responses use different field names (brandAgents, campaigns, etc).

Issue: brand-agent list command hung because it returns 'brandAgents' not 'items'

Solution: Automatically find and extract the first non-empty array field
from the response, regardless of name.

This makes the CLI work with all list commands without hardcoding
specific field names.

Tested with:
- agent list (items) ✓
- brand-agent list (brandAgents) ✓
- media-product list (products implied) ✓

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
These documents were useful during implementation but are no longer needed
now that comprehensive tests are in place. Clean up project root.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@bokelley bokelley requested a review from a team November 8, 2025 11:56
@bokelley bokelley enabled auto-merge (squash) November 8, 2025 12:01
bokelley and others added 5 commits November 8, 2025 07:11
Instead of dumping full JSON for nested arrays/objects in list and table
formats, show concise summaries like "(1 item)" or "(5 fields)". This makes
output much more readable for list commands with complex nested data.

- Table format: "1 item" instead of full JSON dump
- List format: "(1 item)" in gray text
- JSON format: unchanged, still shows full data
- Single object display: uses summaries too

Example:
  Before: creativeFormats: [{"id":"mobile_banner_320x50","agent_url":"https://..."}]
  After:  creativeFormats: (1 item)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Show simple data inline, summarize complex data. This prevents spam while
still showing useful information.

Rules:
- Arrays with ≤3 primitives and ≤50 chars: show inline ["tag1","tag2"]
- Objects with ≤2 primitive fields and ≤50 chars: show inline {"status":"active"}
- Complex/large data: summarize as "(5 items)" or "(3 fields)"

Examples:
  ["tag1","tag2"] → shown inline
  [{id:1}] → (1 item)
  {status:"active"} → shown inline
  {a:1,b:2,c:3} → (3 fields)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Critical fixes:
1. Redact API key in `config get` output - shows first 8 chars only
2. Add try-catch for corrupted cache fallback to prevent crashes
3. Accept empty arrays in generic extraction for "No results" display

These changes improve security (no accidental key exposure) and reliability
(graceful handling of corrupted cache files and empty result sets).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Creates a monorepo structure with npm workspaces to include the `scope3`
thin wrapper package alongside the main @scope3/agentic-client package.

Changes:
- Add workspaces support to root package.json
- Create packages/scope3-cli/ with thin wrapper
- Bump version to 1.0.5 for both packages
- scope3 package depends on @scope3/agentic-client via file: reference

Publishing workflow:
1. npm run build (from root)
2. npm publish (publishes @scope3/agentic-client@1.0.5)
3. cd packages/scope3-cli && npm publish (publishes scope3@1.0.5)

This allows users to simply: npx scope3 brand-agent list

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Updates:
- Add scope3 package to changeset for minor version bump
- Change release script to use `changeset publish` (publishes all workspace packages)
- Add NPM_TOKEN to release workflow for npm registry authentication

Now when PR merges to main:
1. Changesets creates a "Version Packages" PR with version bumps
2. When that PR merges, GitHub Actions publishes BOTH packages to npm:
   - @scope3/agentic-client@1.0.5
   - scope3@1.0.5

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@bokelley bokelley merged commit 4b7b41b into main Nov 8, 2025
6 checks passed
@bokelley bokelley deleted the npx-cli-fix branch November 8, 2025 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants