@mod-computer/cli 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -148
- package/dist/cli.bundle.js +12 -8
- package/dist/cli.bundle.js.map +2 -2
- package/dist/config/features.js +10 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,108 +1,142 @@
|
|
|
1
1
|
# mod-cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Spec-driven development with traceability. Connect your specs, code, and tests so reviews show the full picture.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Quick Start
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## Conceptual Overview
|
|
12
|
-
|
|
13
|
-
**Workspaces**: A workspace is a container for files, branches, and metadata. Create workspaces with `mod workspace create`, list them with `mod workspace list`, switch with `mod workspace switch`. Each workspace has its own history, collaborators, and sync state. A directory connects to one workspace at a time.
|
|
14
|
-
|
|
15
|
-
**Local-First Sync**: `mod sync start` launches a daemon that watches the local directory and syncs to the connected workspace. File edits, new files, deletions propagate automatically. Remote changes from collaborators sync back to local files. The daemon runs in the background; coding agents work locally as normal. Multiple collaborators can sync to the same workspace from different machines.
|
|
16
|
-
|
|
17
|
-
**Branching**: Mod branches are lightweight isolation scopes for work-in-progress. Unlike git branches, they don't require commits or staging. Create a branch, start working, and all changes are tracked automatically. When integrated with git, Mod branches map to git branches. Without git, Mod branches provide standalone isolation.
|
|
18
|
-
|
|
19
|
-
**Changelog**: Every file change on a branch is recorded automatically with timestamp, diff, and context. No manual commits required. The changelog captures what changed, when, and alongside what other activity (agent conversations, spec edits, collaborator comments). View at branch level or filter to a specific file.
|
|
20
|
-
|
|
21
|
-
**Reversion**: Restore to any point in the changelog. Revert an entire branch to a previous state, or revert a single file while keeping other files at their current state. Fine-grained reversion without needing explicit commits as restore points.
|
|
22
|
-
|
|
23
|
-
**Merge**: Combine branches by merging their changes. Mod detects conflicts at the file level and surfaces them for resolution. Metadata (comments, traces) merges automatically. After merge, the target branch contains changes from both branches with full history preserved.
|
|
7
|
+
```bash
|
|
8
|
+
# Install
|
|
9
|
+
npm install -g @mod-computer/cli
|
|
24
10
|
|
|
25
|
-
|
|
11
|
+
# Initialize workspace (installs /mod skill for Claude Code)
|
|
12
|
+
mod init
|
|
13
|
+
mod auth login
|
|
26
14
|
|
|
27
|
-
|
|
15
|
+
# Start working
|
|
16
|
+
git checkout -b feat/user-auth
|
|
17
|
+
```
|
|
28
18
|
|
|
29
|
-
|
|
19
|
+
## The Idea
|
|
30
20
|
|
|
31
|
-
|
|
21
|
+
You write specs. Agents implement them. But at review time, how do you know what requirement each function addresses? What's tested? What changed but isn't connected to anything?
|
|
32
22
|
|
|
33
|
-
|
|
23
|
+
mod-cli builds a trace graph as you work:
|
|
34
24
|
|
|
35
|
-
|
|
25
|
+
```
|
|
26
|
+
Spec requirement → Implementation → Tests
|
|
27
|
+
```
|
|
36
28
|
|
|
37
|
-
|
|
29
|
+
At review, `mod trace report` shows what's connected. `mod trace diff` catches what isn't.
|
|
38
30
|
|
|
39
|
-
|
|
31
|
+
## Usage
|
|
40
32
|
|
|
41
|
-
|
|
33
|
+
### With Claude Code (Recommended)
|
|
42
34
|
|
|
43
|
-
|
|
35
|
+
`mod init` installs the `/mod` skill automatically. Use it to implement specs:
|
|
44
36
|
|
|
45
|
-
|
|
37
|
+
```bash
|
|
38
|
+
# Write a spec
|
|
39
|
+
claude "Write a spec for user authentication in specs/auth.md"
|
|
46
40
|
|
|
47
|
-
|
|
41
|
+
# Implement from spec - agent handles traces
|
|
42
|
+
claude "/mod implement specs/auth.md"
|
|
48
43
|
|
|
49
|
-
|
|
44
|
+
# Add tests - agent traces them to implementations
|
|
45
|
+
claude "/mod test specs/auth.md"
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
# Review coverage
|
|
48
|
+
mod trace report specs/auth.md
|
|
49
|
+
```
|
|
52
50
|
|
|
53
|
-
|
|
51
|
+
### Manual Workflow
|
|
54
52
|
|
|
55
|
-
|
|
53
|
+
```bash
|
|
54
|
+
# Add traces as you work
|
|
55
|
+
mod trace add specs/auth.md:15 --type=requirement
|
|
56
|
+
mod trace add src/auth/login.ts:42 --type=implementation --link=req-login--a1b2
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
# Link existing traces
|
|
59
|
+
mod trace link impl-login--a1b2 spec-login--c3d4
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
# View connections
|
|
62
|
+
mod trace report specs/auth.md
|
|
63
|
+
mod trace coverage
|
|
60
64
|
|
|
61
|
-
|
|
65
|
+
# Find gaps before merge
|
|
66
|
+
mod trace diff # Untraced files on branch
|
|
67
|
+
mod trace unmet # Requirements without implementations
|
|
68
|
+
```
|
|
62
69
|
|
|
63
|
-
## Commands
|
|
70
|
+
## Commands
|
|
64
71
|
|
|
65
|
-
###
|
|
72
|
+
### Setup
|
|
66
73
|
|
|
67
74
|
```bash
|
|
68
|
-
mod init
|
|
69
|
-
mod
|
|
70
|
-
mod
|
|
71
|
-
mod
|
|
72
|
-
mod sync import # Import existing files to workspace
|
|
75
|
+
mod init # Initialize workspace, install /mod skill
|
|
76
|
+
mod auth login # Authenticate
|
|
77
|
+
mod auth logout # Sign out
|
|
78
|
+
mod auth status # Show auth state
|
|
73
79
|
```
|
|
74
80
|
|
|
75
|
-
###
|
|
81
|
+
### Traces
|
|
76
82
|
|
|
77
83
|
```bash
|
|
78
|
-
|
|
79
|
-
mod
|
|
80
|
-
mod
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
mod
|
|
84
|
+
# Add traces
|
|
85
|
+
mod trace add <file>:<line> --type=<type> ["description"]
|
|
86
|
+
mod trace add <file>:<line> --type=<type> --link=<trace-id>
|
|
87
|
+
|
|
88
|
+
# Link traces
|
|
89
|
+
mod trace link <source-id> <target-id>
|
|
90
|
+
|
|
91
|
+
# View traces
|
|
92
|
+
mod trace list # All traces
|
|
93
|
+
mod trace list --type=requirement # Filter by type
|
|
94
|
+
mod trace list --file=<path> # Filter by file
|
|
95
|
+
mod trace get <trace-id> # Get trace details
|
|
96
|
+
|
|
97
|
+
# Reports
|
|
98
|
+
mod trace report <file> # Per-document coverage
|
|
99
|
+
mod trace coverage # Workspace-wide stats
|
|
100
|
+
|
|
101
|
+
# Find gaps
|
|
102
|
+
mod trace diff # Untraced files on branch
|
|
103
|
+
mod trace diff main..HEAD # Explicit git range
|
|
104
|
+
mod trace unmet # Requirements without implementations
|
|
84
105
|
```
|
|
85
106
|
|
|
86
|
-
###
|
|
107
|
+
### Comments
|
|
87
108
|
|
|
88
109
|
```bash
|
|
89
|
-
mod
|
|
90
|
-
mod
|
|
91
|
-
mod workspace switch <name> # Switch active workspace
|
|
92
|
-
mod workspace info # Show workspace details
|
|
110
|
+
mod comment add <file>:<line> "text"
|
|
111
|
+
mod comment list [file]
|
|
93
112
|
```
|
|
94
113
|
|
|
95
|
-
|
|
114
|
+
## Trace Types
|
|
115
|
+
|
|
116
|
+
| Type | Use For |
|
|
117
|
+
|------|---------|
|
|
118
|
+
| `requirement` | Specs, user stories, acceptance criteria |
|
|
119
|
+
| `specification` | Detailed technical specs |
|
|
120
|
+
| `implementation` | Code that builds something |
|
|
121
|
+
| `test` | Code that verifies something |
|
|
122
|
+
| `design` | Design docs, architecture notes |
|
|
123
|
+
| `decision` | ADRs, decision records |
|
|
124
|
+
| `utility` | Helpers that don't need tracing |
|
|
125
|
+
|
|
126
|
+
## CI Integration
|
|
127
|
+
|
|
128
|
+
Commands exit non-zero when issues exist:
|
|
96
129
|
|
|
97
130
|
```bash
|
|
98
|
-
|
|
99
|
-
mod
|
|
100
|
-
mod note set <file> <text> # Set note on file
|
|
101
|
-
mod note get <file> # Get note for file
|
|
102
|
-
mod trace add <file> <req-id> # Add trace linking file to requirement
|
|
103
|
-
mod trace list [file] # List traces (all or per file)
|
|
131
|
+
# Pre-merge validation
|
|
132
|
+
mod trace diff && mod trace unmet && git push
|
|
104
133
|
```
|
|
105
134
|
|
|
135
|
+
| Command | Exit 0 | Exit 1 |
|
|
136
|
+
|---------|--------|--------|
|
|
137
|
+
| `mod trace diff` | All changed files traced | Untraced files exist |
|
|
138
|
+
| `mod trace unmet` | All requirements implemented | Unmet requirements |
|
|
139
|
+
|
|
106
140
|
## Development
|
|
107
141
|
|
|
108
142
|
```bash
|
|
@@ -111,87 +145,3 @@ pnpm build # Build CLI
|
|
|
111
145
|
pnpm dev # Watch mode
|
|
112
146
|
pnpm test # Run tests
|
|
113
147
|
```
|
|
114
|
-
|
|
115
|
-
## Local Testing with Dev Mode
|
|
116
|
-
|
|
117
|
-
For testing cross-client workspace syncing on localhost without OAuth, use dev mode authentication:
|
|
118
|
-
|
|
119
|
-
### Prerequisites
|
|
120
|
-
|
|
121
|
-
1. **Start the sync server**:
|
|
122
|
-
```bash
|
|
123
|
-
cd packages/mod-sync-server
|
|
124
|
-
node src/server.js
|
|
125
|
-
# Server runs on ws://localhost:3030
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
2. **Start the web app** (in another terminal):
|
|
129
|
-
```bash
|
|
130
|
-
cd packages/mod-app-new
|
|
131
|
-
pnpm dev
|
|
132
|
-
# App runs on http://localhost:3000
|
|
133
|
-
# Dev mode automatically enabled (no VITE_MOD_AUTH_URL needed)
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### Testing Workflow
|
|
137
|
-
|
|
138
|
-
1. **Login with dev mode**:
|
|
139
|
-
```bash
|
|
140
|
-
AUTOMERGE_WS_URL=ws://localhost:3030 mod auth login --dev
|
|
141
|
-
```
|
|
142
|
-
This creates a local `dev@localhost` user shared between CLI and web app.
|
|
143
|
-
|
|
144
|
-
2. **Connect a workspace**:
|
|
145
|
-
```bash
|
|
146
|
-
cd /path/to/your/project
|
|
147
|
-
AUTOMERGE_WS_URL=ws://localhost:3030 mod init
|
|
148
|
-
```
|
|
149
|
-
Select or create a workspace. The workspace connects to your local directory.
|
|
150
|
-
|
|
151
|
-
3. **Register workspaces to your user**:
|
|
152
|
-
```bash
|
|
153
|
-
AUTOMERGE_WS_URL=ws://localhost:3030 mod workspace register
|
|
154
|
-
```
|
|
155
|
-
This adds all connected workspaces to your user's workspace list, making them visible in the web app.
|
|
156
|
-
|
|
157
|
-
4. **View in web app**:
|
|
158
|
-
- Open `http://localhost:3000` in your browser
|
|
159
|
-
- Refresh the page to see your workspaces
|
|
160
|
-
- Both CLI and web app share the same `dev@localhost` user document
|
|
161
|
-
- Changes sync via `ws://localhost:3030`
|
|
162
|
-
|
|
163
|
-
### Verification
|
|
164
|
-
|
|
165
|
-
Check authentication status:
|
|
166
|
-
```bash
|
|
167
|
-
AUTOMERGE_WS_URL=ws://localhost:3030 mod auth status
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
List connected workspaces:
|
|
171
|
-
```bash
|
|
172
|
-
AUTOMERGE_WS_URL=ws://localhost:3030 mod workspace list
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
View sync diagnostics at `http://localhost:3000/debug/sync` to see tracked documents and sync state.
|
|
176
|
-
|
|
177
|
-
### Notes
|
|
178
|
-
|
|
179
|
-
- Dev mode uses a shared `dev@localhost` user across CLI and web app
|
|
180
|
-
- No OAuth required - authentication happens locally
|
|
181
|
-
- User document ID is stored in `~/.mod/config`
|
|
182
|
-
- Both clients must connect to the same sync server (`ws://localhost:3030`)
|
|
183
|
-
- Run `mod workspace register` after creating new workspaces to sync them to the web app
|
|
184
|
-
|
|
185
|
-
## Thoughts
|
|
186
|
-
|
|
187
|
-
**Daemon architecture**: The sync daemon runs as a background process rather than requiring an active terminal. This lets developers work normally while sync happens invisibly. The daemon writes logs to `~/.mod/logs/sync.log` for debugging.
|
|
188
|
-
|
|
189
|
-
**CRDT trade-offs**: Automerge handles conflicts automatically, but the resulting merges aren't always what users expect for text files. Currently optimizing for metadata sync; file content sync may need smarter merge strategies.
|
|
190
|
-
|
|
191
|
-
**Git integration**: In git repos, sync is branch-aware: git branch switches trigger Mod branch switches. Mod adds real-time collaboration and agent context on top of git. In non-git directories, Mod provides standalone change tracking and sync.
|
|
192
|
-
|
|
193
|
-
**Device-level storage**: All state lives in `~/.mod/` at the device root rather than per-repo. Sign in once, use across all repos. Single daemon can sync multiple connected directories. No per-repo config to gitignore.
|
|
194
|
-
|
|
195
|
-
**Metadata commands**: Specific commands for comments, notes, and traces rather than a generic `mod meta` interface. Agents benefit from semantic clarity. Each metadata type has different workflows: comments are threaded, notes are single per file, traces link to requirement IDs. Keeping them separate makes intent clear for both agents and humans.
|
|
196
|
-
|
|
197
|
-
**Offline handling**: The daemon queues changes when offline and syncs when reconnected. Local edits always work; sync catches up when possible. Conflict resolution happens through Automerge's CRDT properties.
|
package/dist/cli.bundle.js
CHANGED
|
@@ -20977,10 +20977,7 @@ var repo = async (options) => {
|
|
|
20977
20977
|
if (repoInstance)
|
|
20978
20978
|
return repoInstance;
|
|
20979
20979
|
const wsUrl = (options == null ? void 0 : options.syncServerUrl) ?? resolveAutomergeWsUrl();
|
|
20980
|
-
isAutomergeSyncAvailable(wsUrl, { timeoutMs: 2e3 }).then((
|
|
20981
|
-
if (!syncAvailable) {
|
|
20982
|
-
console.log(`[mod-core] Sync server not reachable (will retry in background)`);
|
|
20983
|
-
}
|
|
20980
|
+
isAutomergeSyncAvailable(wsUrl, { timeoutMs: 2e3 }).then((_syncAvailable) => {
|
|
20984
20981
|
});
|
|
20985
20982
|
const networkAdapters = [
|
|
20986
20983
|
new WebSocketClientAdapter(wsUrl)
|
|
@@ -36495,10 +36492,17 @@ function loadReleaseProfile() {
|
|
|
36495
36492
|
try {
|
|
36496
36493
|
const __filename4 = fileURLToPath4(import.meta.url);
|
|
36497
36494
|
const __dirname4 = path27.dirname(__filename4);
|
|
36498
|
-
const
|
|
36499
|
-
|
|
36500
|
-
|
|
36501
|
-
|
|
36495
|
+
const candidates = [
|
|
36496
|
+
path27.join(__dirname4, "release-profiles", `${profileName}.json`),
|
|
36497
|
+
// unbundled: dist/config/
|
|
36498
|
+
path27.join(__dirname4, "config", "release-profiles", `${profileName}.json`)
|
|
36499
|
+
// bundled: dist/
|
|
36500
|
+
];
|
|
36501
|
+
for (const profilePath of candidates) {
|
|
36502
|
+
if (fs22.existsSync(profilePath)) {
|
|
36503
|
+
const profileData = fs22.readFileSync(profilePath, "utf8");
|
|
36504
|
+
return JSON.parse(profileData);
|
|
36505
|
+
}
|
|
36502
36506
|
}
|
|
36503
36507
|
throw new Error(`Profile ${profileName} not found`);
|
|
36504
36508
|
} catch (error) {
|