Skip to content

Comments

H-6214: move cli tools to apps and update (WIP)#116

Draft
lunelson wants to merge 68 commits intomainfrom
ln/h-6214-move-existing-clis-to-apps-and-update
Draft

H-6214: move cli tools to apps and update (WIP)#116
lunelson wants to merge 68 commits intomainfrom
ln/h-6214-move-existing-clis-to-apps-and-update

Conversation

@lunelson
Copy link
Contributor

No description provided.

@vercel
Copy link

vercel bot commented Feb 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
petrinaut-hazel Ready Ready Preview, Comment Feb 22, 2026 5:04pm

lunelson and others added 21 commits February 17, 2026 14:55
- Create src/lib/symlink.ts with low-level helpers:
  - readSymlinkTarget: read symlink target
  - isSymlink: check if path is a symlink
  - atomicSymlink: create symlink atomically (temp + rename pattern)
  - moveDirectory: move directory (rename with cross-device fallback)

- Add symlink-based methods to ConfigManager:
  - getGlobalConfigPath: resolve agent's global config dir
  - getSymlinkStatus: check state (active/unmanaged/missing/broken/external)
  - getActiveProfile: get current profile slug
  - adoptExisting: move real dir to _base, create symlink back
  - switchProfile: atomically swap symlink to different profile
  - unlinkProfile: move profile back to global location

- Add shared directory methods:
  - getSharedDirStatus: check shared dir state
  - adoptSharedDir: adopt shared directory
  - unlinkSharedDir: unlink shared directory

- Add SHARED_DIRECTORIES constant to types/index.ts
- Add SymlinkStatus type to config.ts

All methods handle edge cases (permissions, broken symlinks, cross-device moves).
Atomic symlink swap uses temp symlink + rename pattern for safety.
…allback

- Fix getSymlinkStatus() to use fs.lstat() first instead of fs.access() to properly detect broken symlinks
- Fix getSharedDirStatus() with the same pattern for consistent behavior
- Remove EACCES from moveDirectory() fallback condition (only EXDEV should trigger copy+delete)
- Run npm run format to fix formatting issues

All verification checks pass:
- npm run typecheck ✓
- npm run lint ✓
- npm run format:check ✓
- npm test ✓ (15 tests passed)
- Update add.ts: copy from _base if exists, offer switch, reject _base name
- Rewrite remove.ts: remove all direnv code, protect _base and active profile
- Update list.ts: show active profile marker, label _base as 'Base profile'
- Update prompts.ts: show active marker and _base label in profile selection
- Update remove.test.ts: replace old envrc tests with new symlink-based tests
- All tests passing, build successful
- Rewrite src/lib/onboarding.ts to use ConfigManager and symlink adoption flow
- Remove all direnv references from onboarding
- Scan agents and shared directories, offer adoption as _base profile
- Use @clack/prompts for interactive prompts
- Update src/commands/setup.ts to handle success/failure
- Update ensureInitialized() to reference 'setup' instead of 'init'
- All tests pass, typecheck passes, formatting correct

Agent-Id: agent-cd0d6e01-e38c-484d-9b22-a9946514d68b
Agent-Id: agent-3de0fdd4-15bd-400b-b463-9c65ce1e2621
- Delete scripts/smoke-envrc.sh (dead file from direnv era)
- Remove "direnv" from package.json keywords
- Update src/lib/banner.ts comment to remove direnv reference
- Add alias command files (create.ts, init.ts, rm.ts) to AGENTS.md code tree

All checks pass: format, typecheck, lint. No direnv references in src/, AGENTS.md, or package.json.

Agent-Id: agent-2a35e35c-7dc3-4890-b921-dc2055b0e3c4
- Add saveConfig() method to ConfigManager to persist cliConfig to config.json
- Add setContentDir() method to update and persist contentDir
- Call setContentDir() in onboarding.ts after user confirms custom contentDir
- Add test to verify config.json persistence
- Also add meta.json creation in adoptExisting() for better profile tracking
Agent-Id: agent-d3f23ff1-d424-4733-a1b0-56aec6657c9b
- Remove all .agentprofiles.json references (no longer used)
- Remove 'Project tracking' section entirely
- Update 'How It Works' to focus on symlinks only
- Remove 'What to Commit' section (no files to track)
- Update 'Removing agentprofiles' section with unset and manual removal
- Rename 'Getting Started' to 'Quick Start' with clearer workflow
- Update 'Troubleshooting' for symlink-based issues
- Add new troubleshooting item for status command
- Remove direnv references (only in FAQ explaining why we don't use it)

Verified:
- No .agentprofiles.json or .envrc references
- All commands match actual CLI behavior
- Quick Start demonstrates core workflow
- Troubleshooting covers common symlink issues
- Formatting passes npm run format:check
- Add batchSwitchAll() function to switch all managed agents to a profile
- Support --all flag: agentprofiles set --all work
- Support shorthand: agentprofiles set <profile> (no agent arg)
- Skip agents that don't have the profile (with warning)
- Skip unmanaged/missing/broken agents (with note)
- Show summary of switched and skipped agents
- Add test for batch profile switching
- Create src/commands/release.ts with interactive confirmation
- Register command in src/index.ts
- Add 'Release agent' option to src/lib/main-menu.ts
- Update CLI help test to include release command
- Add test for release command flow

The release command allows users to stop managing an agent by:
1. Confirming the action with the user
2. Showing which profile will be restored to the global path
3. Calling config.unlinkProfile() to move the active profile back
4. Handling errors appropriately

All verification commands pass:
- npm run typecheck ✓
- npm run lint ✓
- npm run format:check ✓
- npm test ✓ (30 tests passing)
Agent-Id: agent-6d9fe57e-8909-41ad-99ad-cb439fea7bca
- Add optional  argument to  command
- If  is provided, copy from that profile instead of
- Validate that source profile exists before copying
- Still overwrite  after copy with new profile metadata
- Add three tests for --from behavior:
  - Test cloning from arbitrary profile with symlink preservation
  - Test error when source profile doesn't exist
  - Existing test for default _base behavior still passes

Verification:
- npm run typecheck ✓
- npm run lint ✓
- npm run format:check ✓
- npm test (40 tests) ✓

Agent-Id: agent-7460564f-f34c-49e1-90b1-5135f0eae801
- Create src/commands/doctor.ts with interactive repair functionality
- Detect and fix broken symlinks (switch to _base or remove)
- Create missing _base profiles and meta.json files
- Check shared directories for issues
- Register command in src/index.ts and src/lib/main-menu.ts
- Add tests for broken symlink detection and repair
- All tests pass, typecheck clean, lint clean, format clean
- adoptExisting now accepts { replaceExisting } option to handle
  the case where _base profile already exists in contentDir
- Setup prompts user to replace or skip when _base conflict detected
- Removed process.env.AGENTPROFILES_CONTENT_DIR write from onboarding;
  contentDir is now persisted via config.json only

Amp-Thread-ID: https://ampcode.com/threads/T-019c4709-ea5a-77ab-a924-eb394343f5fd
Co-authored-by: Amp <amp@ampcode.com>
- Install better-sqlite3 and @types/better-sqlite3 dependencies
- Add getDbPath() to src/lib/config.ts for database path management
- Create src/lib/db.ts with openDb(), closeDb(), and CRUD operations
- Add DbRepoRow type to src/types/index.ts
- Create comprehensive tests in tests/lib/db.test.ts
- All verification gates pass: format, lint, typecheck, test, build

Agent-Id: agent-569cf7d5-3bec-4987-b279-e039bf030f0e
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.

1 participant