agents-scrum-master 1.0.0
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/CONTRIBUTING.md +51 -0
- package/DEPLOYMENT.md +121 -0
- package/LICENSE +21 -0
- package/README.md +217 -0
- package/bin/cli.js +65 -0
- package/package.json +38 -0
- package/src/setup.js +186 -0
- package/tests/setup.test.js +98 -0
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Contributing to agent-scrum-master
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing! This is an open-source project and we welcome all contributions.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/ashishdogra/agent-scrum-master.git
|
|
9
|
+
cd agent-scrum-master
|
|
10
|
+
npm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Development
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Test locally in watch mode
|
|
17
|
+
node bin/cli.js --verbose
|
|
18
|
+
|
|
19
|
+
# Test in a real project
|
|
20
|
+
cd /path/to/test-project
|
|
21
|
+
node /path/to/agent-scrum-master/bin/cli.js --verbose
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Publishing to npm
|
|
25
|
+
|
|
26
|
+
1. Update version in `package.json`
|
|
27
|
+
2. Create a git tag: `git tag v1.0.0`
|
|
28
|
+
3. Push: `git push origin main && git push origin --tags`
|
|
29
|
+
4. Publish: `npm publish`
|
|
30
|
+
|
|
31
|
+
## Areas for Contribution
|
|
32
|
+
|
|
33
|
+
- Additional ticket system integrations (Linear, GitHub Projects, etc.)
|
|
34
|
+
- Enhanced error messages
|
|
35
|
+
- Test coverage
|
|
36
|
+
- Documentation improvements
|
|
37
|
+
- Feature suggestions (via issues)
|
|
38
|
+
|
|
39
|
+
## Code Style
|
|
40
|
+
|
|
41
|
+
- ESM modules only
|
|
42
|
+
- No external dependencies (keep it lightweight)
|
|
43
|
+
- Node.js 18+ compatibility
|
|
44
|
+
|
|
45
|
+
## Reporting Issues
|
|
46
|
+
|
|
47
|
+
Please open an issue with:
|
|
48
|
+
- Node version
|
|
49
|
+
- OS
|
|
50
|
+
- Steps to reproduce
|
|
51
|
+
- Expected vs actual behavior
|
package/DEPLOYMENT.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Deployment Guide: agent-scrum-master
|
|
2
|
+
|
|
3
|
+
## Step 1: Create GitHub Repository
|
|
4
|
+
|
|
5
|
+
1. Go to https://github.com/new
|
|
6
|
+
2. Create public repo: `agent-scrum-master`
|
|
7
|
+
3. Initialize with no README (we have one)
|
|
8
|
+
|
|
9
|
+
## Step 2: Push to GitHub
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cd /path/to/agent-scrum-master
|
|
13
|
+
git init
|
|
14
|
+
git add .
|
|
15
|
+
git commit -m "chore: initial commit"
|
|
16
|
+
git remote add origin https://github.com/YOUR_USERNAME/agent-scrum-master.git
|
|
17
|
+
git branch -M main
|
|
18
|
+
git push -u origin main
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Step 3: Setup npm (one-time only)
|
|
22
|
+
|
|
23
|
+
1. Create npm account: https://www.npmjs.com/signup
|
|
24
|
+
2. Verify email
|
|
25
|
+
3. Login locally:
|
|
26
|
+
```bash
|
|
27
|
+
npm login
|
|
28
|
+
```
|
|
29
|
+
- Username: your npm username
|
|
30
|
+
- Password: your npm password
|
|
31
|
+
- Email: your email
|
|
32
|
+
|
|
33
|
+
## Step 4: Publish to npm
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Ensure package.json has correct name (agent-scrum-master)
|
|
37
|
+
# Ensure version bumped: 1.0.0
|
|
38
|
+
npm publish
|
|
39
|
+
|
|
40
|
+
# Verify it's published
|
|
41
|
+
npm view agent-scrum-master
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Step 5: Test Installation
|
|
45
|
+
|
|
46
|
+
In a fresh project:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cd /tmp/test-project
|
|
50
|
+
mkdir -p /tmp/test-project
|
|
51
|
+
cd /tmp/test-project
|
|
52
|
+
git init
|
|
53
|
+
npx agent-scrum-master
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Should see:
|
|
57
|
+
```
|
|
58
|
+
ā
agent-scrum-master initialized!
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Step 6: Add GitHub Release
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git tag v1.0.0
|
|
65
|
+
git push origin v1.0.0
|
|
66
|
+
|
|
67
|
+
# Then create release on GitHub:
|
|
68
|
+
# https://github.com/YOUR_USERNAME/agent-scrum-master/releases/new
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Future Updates
|
|
72
|
+
|
|
73
|
+
1. Update version in `package.json`:
|
|
74
|
+
```json
|
|
75
|
+
"version": "1.0.1"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
2. Commit and tag:
|
|
79
|
+
```bash
|
|
80
|
+
git add package.json
|
|
81
|
+
git commit -m "chore: bump to 1.0.1"
|
|
82
|
+
git tag v1.0.1
|
|
83
|
+
git push origin main && git push origin v1.0.1
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
3. Publish:
|
|
87
|
+
```bash
|
|
88
|
+
npm publish
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Troubleshooting
|
|
92
|
+
|
|
93
|
+
### Package name taken
|
|
94
|
+
- Choose alternative: `agent-tasks-setup`, `agent-workspace-init`, etc.
|
|
95
|
+
- Update in `package.json` and `.npmrc`
|
|
96
|
+
|
|
97
|
+
### npm login issues
|
|
98
|
+
- Clear cache: `npm cache clean --force`
|
|
99
|
+
- Re-login: `npm logout && npm login`
|
|
100
|
+
|
|
101
|
+
### Publish failed
|
|
102
|
+
- Check version is higher than previous: `npm view agent-scrum-master versions`
|
|
103
|
+
- Ensure `.npmrc` is configured or logged in
|
|
104
|
+
|
|
105
|
+
## Verification Commands
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Check if published
|
|
109
|
+
npm search agent-scrum-master
|
|
110
|
+
|
|
111
|
+
# Install globally
|
|
112
|
+
npm install -g agent-scrum-master
|
|
113
|
+
agent-scrum-master --help
|
|
114
|
+
|
|
115
|
+
# Install from npx
|
|
116
|
+
npx agent-scrum-master --help
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
That's it! Your npm package is live and ready for anyone to use.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Ashish Dogra
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# agent-scrum-master
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[](https://www.npmjs.com/package/agent-scrum-master)
|
|
5
|
+
|
|
6
|
+
**One command to auto-configure agent-tasks pipeline for any project.**
|
|
7
|
+
|
|
8
|
+
Bootstraps [agent-tasks](https://github.com/keshrath/agent-tasks) ā a pipeline task manager for AI agents ā with a single `npx` call. Sets up MCP integration, project structure, and gitignore automatically. Works with Claude Code, Cursor, Windsurf, and any MCP client.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- ⨠**One-command setup** ā `npx agent-scrum-master`
|
|
15
|
+
- š **Project-scoped** ā isolated task database per project (not global)
|
|
16
|
+
- š¤ **Agent-agnostic** ā works with Claude Code, Cursor, Windsurf, any MCP client
|
|
17
|
+
- š **Ticket system ready** ā optional Jira integration flags
|
|
18
|
+
- š§¹ **Automatic cleanup** ā handles .gitignore and directory structure
|
|
19
|
+
- š **Dashboard included** ā real-time kanban at `localhost:3422`
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### Option 1: npx (one-liner, no install)
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd /path/to/your/project
|
|
29
|
+
npx agent-scrum-master
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Option 2: npm install (global)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install -g agent-scrum-master
|
|
36
|
+
cd /path/to/your/project
|
|
37
|
+
agent-scrum-master
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## What It Does
|
|
43
|
+
|
|
44
|
+
Runs in your project root and:
|
|
45
|
+
|
|
46
|
+
1. ā Creates `.claude/settings.json` with MCP server config
|
|
47
|
+
2. ā Creates `.agent-tasks/` directory for local task database
|
|
48
|
+
3. ā Adds `.agent-tasks/` to `.gitignore`
|
|
49
|
+
4. ā Ready for Claude Code, Cursor, or any MCP client
|
|
50
|
+
|
|
51
|
+
**Result:** Open the project in your agent and the task pipeline is live.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Commands
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Initialize (default)
|
|
59
|
+
npx agent-scrum-master
|
|
60
|
+
|
|
61
|
+
# Open dashboard in browser
|
|
62
|
+
npx agent-scrum-master dashboard
|
|
63
|
+
|
|
64
|
+
# With Jira integration
|
|
65
|
+
npx agent-scrum-master --jira-url=https://jira.company.com --jira-project=GROWTH
|
|
66
|
+
|
|
67
|
+
# Check status
|
|
68
|
+
npx agent-scrum-master status
|
|
69
|
+
|
|
70
|
+
# Remove setup
|
|
71
|
+
npx agent-scrum-master reset
|
|
72
|
+
|
|
73
|
+
# Verbose output
|
|
74
|
+
npx agent-scrum-master --verbose
|
|
75
|
+
|
|
76
|
+
# Overwrite existing config
|
|
77
|
+
npx agent-scrum-master --force
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Usage in Your Agent
|
|
83
|
+
|
|
84
|
+
Once initialized, open the project in Claude Code or Cursor:
|
|
85
|
+
|
|
86
|
+
### View dashboard
|
|
87
|
+
Open in browser with one command:
|
|
88
|
+
```bash
|
|
89
|
+
npx agent-scrum-master dashboard
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Or navigate manually to `http://localhost:3422`
|
|
93
|
+
|
|
94
|
+
### Create a task
|
|
95
|
+
```
|
|
96
|
+
Use the MCP tool: task_create(title: "Build login flow", description: "...", project: "MyProject")
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Advance stages
|
|
100
|
+
```
|
|
101
|
+
Use task_stage(id: "task-123", stage: "implement")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
See [agent-tasks API docs](https://github.com/keshrath/agent-tasks/blob/main/docs/API.md) for full tool reference.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Project Structure
|
|
109
|
+
|
|
110
|
+
After running `agent-scrum-master`:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
your-project/
|
|
114
|
+
āāā .claude/
|
|
115
|
+
ā āāā settings.json # MCP config (auto-created)
|
|
116
|
+
āāā .agent-tasks/ # Task database (git-ignored)
|
|
117
|
+
ā āāā tasks.db
|
|
118
|
+
āāā .gitignore # Updated with .agent-tasks/
|
|
119
|
+
āāā ... (your code)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`.claude/settings.json` is **committed to git** ā other team members inherit the setup automatically.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Jira Integration (Optional)
|
|
127
|
+
|
|
128
|
+
Add Jira sync to your project:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx agent-scrum-master \
|
|
132
|
+
--jira-url=https://jira.company.com \
|
|
133
|
+
--jira-project=GROWTH
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
This sets environment variables in `.claude/settings.json`. Agent-tasks can then sync task completions to Jira.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Multi-Project Setup
|
|
141
|
+
|
|
142
|
+
Each project gets its own isolated database:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
project-a/
|
|
146
|
+
āāā .agent-tasks/tasks.db # Isolated to project-a
|
|
147
|
+
|
|
148
|
+
project-b/
|
|
149
|
+
āāā .agent-tasks/tasks.db # Isolated to project-b
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
No cross-project bleed ā dashboards run on the same port but serve different DBs by project.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Requirements
|
|
157
|
+
|
|
158
|
+
- Node.js >= 18
|
|
159
|
+
- Agent supporting MCP (Claude Code, Cursor, Windsurf, etc.)
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Troubleshooting
|
|
164
|
+
|
|
165
|
+
### Dashboard doesn't start
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Check if agent-tasks is installed
|
|
169
|
+
npx agent-tasks --help
|
|
170
|
+
|
|
171
|
+
# Manually start dashboard
|
|
172
|
+
cd your-project
|
|
173
|
+
npx agent-tasks
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Reset and reinitialize
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
npx agent-scrum-master reset
|
|
180
|
+
npx agent-scrum-master --force
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Check status
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
npx agent-scrum-master status
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Development
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Clone
|
|
195
|
+
git clone https://github.com/ashishdogra/agent-scrum-master.git
|
|
196
|
+
cd agent-scrum-master
|
|
197
|
+
|
|
198
|
+
# Test locally
|
|
199
|
+
node bin/cli.js --verbose
|
|
200
|
+
|
|
201
|
+
# Publish to npm
|
|
202
|
+
npm publish
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
MIT ā see [LICENSE](LICENSE)
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## See Also
|
|
214
|
+
|
|
215
|
+
- [agent-tasks](https://github.com/keshrath/agent-tasks) ā The pipeline engine this bootstraps
|
|
216
|
+
- [agent-comm](https://github.com/keshrath/agent-comm) ā Agent heartbeat & messaging
|
|
217
|
+
- [agent-knowledge](https://github.com/keshrath/agent-knowledge) ā Knowledge persistence
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { setup, openDashboard } from '../src/setup.js';
|
|
4
|
+
|
|
5
|
+
const args = process.argv.slice(2);
|
|
6
|
+
const command = args[0] || 'init';
|
|
7
|
+
const options = {
|
|
8
|
+
projectRoot: process.cwd(),
|
|
9
|
+
verbose: args.includes('--verbose') || args.includes('-v'),
|
|
10
|
+
force: args.includes('--force') || args.includes('-f'),
|
|
11
|
+
jiraUrl: args.find(a => a.startsWith('--jira-url='))?.split('=')[1],
|
|
12
|
+
jiraProject: args.find(a => a.startsWith('--jira-project='))?.split('=')[1],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
16
|
+
console.log(`
|
|
17
|
+
agent-scrum-master - Setup agent-tasks pipeline for your project
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
npx agent-scrum-master [command] [options]
|
|
21
|
+
|
|
22
|
+
Commands:
|
|
23
|
+
init Initialize agent-tasks (default)
|
|
24
|
+
reset Remove agent-tasks setup from project
|
|
25
|
+
status Check if agent-tasks is initialized
|
|
26
|
+
dashboard Open the task dashboard in browser
|
|
27
|
+
|
|
28
|
+
Options:
|
|
29
|
+
--verbose, -v Show detailed output
|
|
30
|
+
--force, -f Overwrite existing configuration
|
|
31
|
+
--jira-url=<url> Jira instance URL (optional)
|
|
32
|
+
--jira-project=<key> Jira project key (optional)
|
|
33
|
+
--help, -h Show this help
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
npx agent-scrum-master
|
|
37
|
+
npx agent-scrum-master --verbose
|
|
38
|
+
npx agent-scrum-master init --jira-url=https://jira.company.com --jira-project=GROWTH
|
|
39
|
+
npx agent-scrum-master reset
|
|
40
|
+
npx agent-scrum-master status
|
|
41
|
+
npx agent-scrum-master dashboard
|
|
42
|
+
`);
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
if (command === 'init') {
|
|
48
|
+
await setup(options);
|
|
49
|
+
} else if (command === 'reset') {
|
|
50
|
+
await setup({ ...options, reset: true });
|
|
51
|
+
} else if (command === 'status') {
|
|
52
|
+
await setup({ ...options, statusOnly: true });
|
|
53
|
+
} else if (command === 'dashboard') {
|
|
54
|
+
await openDashboard(options);
|
|
55
|
+
} else {
|
|
56
|
+
console.error(`Unknown command: ${command}`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error('\nā Error:', error.message);
|
|
61
|
+
if (options.verbose) {
|
|
62
|
+
console.error(error);
|
|
63
|
+
}
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agents-scrum-master",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Auto-setup agent-tasks pipeline for any project. One command to initialize agent-driven workflow management.",
|
|
5
|
+
"main": "src/setup.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"agents-scrum-master": "./bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "node --test tests/*.test.js",
|
|
12
|
+
"lint": "eslint .",
|
|
13
|
+
"format": "prettier --write ."
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"agent-tasks",
|
|
17
|
+
"ai-agents",
|
|
18
|
+
"task-pipeline",
|
|
19
|
+
"workflow",
|
|
20
|
+
"claude-code",
|
|
21
|
+
"cursor",
|
|
22
|
+
"mcp",
|
|
23
|
+
"initialization"
|
|
24
|
+
],
|
|
25
|
+
"author": "Ashish Dogra",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/ashishdogra/agent-scrum-master.git"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/ashishdogra/agent-scrum-master/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/ashishdogra/agent-scrum-master#readme",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18.0.0"
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src/setup.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { spawn } from 'child_process';
|
|
5
|
+
import os from 'os';
|
|
6
|
+
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
|
|
9
|
+
export async function setup(options = {}) {
|
|
10
|
+
const {
|
|
11
|
+
projectRoot = process.cwd(),
|
|
12
|
+
verbose = false,
|
|
13
|
+
force = false,
|
|
14
|
+
reset = false,
|
|
15
|
+
statusOnly = false,
|
|
16
|
+
jiraUrl = null,
|
|
17
|
+
jiraProject = null,
|
|
18
|
+
} = options;
|
|
19
|
+
|
|
20
|
+
const log = (msg) => verbose && console.log(msg);
|
|
21
|
+
const claudeDir = path.join(projectRoot, '.claude');
|
|
22
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
23
|
+
const agentTasksDir = path.join(projectRoot, '.agent-tasks');
|
|
24
|
+
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
25
|
+
|
|
26
|
+
// Status check
|
|
27
|
+
if (statusOnly) {
|
|
28
|
+
const hasSettings = fs.existsSync(settingsPath);
|
|
29
|
+
const hasDir = fs.existsSync(agentTasksDir);
|
|
30
|
+
console.log(`\nš agent-scrum-master status in ${projectRoot}\n`);
|
|
31
|
+
console.log(` .claude/settings.json: ${hasSettings ? 'ā' : 'ā'}`);
|
|
32
|
+
console.log(` .agent-tasks/: ${hasDir ? 'ā' : 'ā'}`);
|
|
33
|
+
console.log(
|
|
34
|
+
`\n Status: ${hasSettings && hasDir ? 'ā
Initialized' : 'ā ļø Not initialized'}\n`
|
|
35
|
+
);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Reset
|
|
40
|
+
if (reset) {
|
|
41
|
+
log('Removing agent-scrum-master setup...');
|
|
42
|
+
if (fs.existsSync(settingsPath)) {
|
|
43
|
+
fs.unlinkSync(settingsPath);
|
|
44
|
+
console.log('ā Removed .claude/settings.json');
|
|
45
|
+
}
|
|
46
|
+
if (fs.existsSync(agentTasksDir)) {
|
|
47
|
+
fs.rmSync(agentTasksDir, { recursive: true, force: true });
|
|
48
|
+
console.log('ā Removed .agent-tasks/');
|
|
49
|
+
}
|
|
50
|
+
console.log('ā
agent-scrum-master reset complete');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Init
|
|
55
|
+
console.log('\nš Initializing agent-scrum-master...\n');
|
|
56
|
+
|
|
57
|
+
// Ensure .claude directory exists
|
|
58
|
+
if (!fs.existsSync(claudeDir)) {
|
|
59
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
60
|
+
log('Created .claude/');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Create settings.json
|
|
64
|
+
if (!fs.existsSync(settingsPath) || force) {
|
|
65
|
+
const settings = buildSettings(jiraUrl, jiraProject);
|
|
66
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
67
|
+
console.log('ā Created .claude/settings.json');
|
|
68
|
+
log(` ā MCP server: agent-tasks`);
|
|
69
|
+
log(` ā Database: .agent-tasks/tasks.db`);
|
|
70
|
+
if (jiraUrl) log(` ā Jira integration: ${jiraUrl}`);
|
|
71
|
+
} else {
|
|
72
|
+
console.log('ā .claude/settings.json already exists');
|
|
73
|
+
if (!force) {
|
|
74
|
+
log(' (use --force to overwrite)');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Ensure .agent-tasks directory exists
|
|
79
|
+
if (!fs.existsSync(agentTasksDir)) {
|
|
80
|
+
fs.mkdirSync(agentTasksDir, { recursive: true });
|
|
81
|
+
console.log('ā Created .agent-tasks/');
|
|
82
|
+
} else {
|
|
83
|
+
log('ā .agent-tasks/ already exists');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Add to .gitignore
|
|
87
|
+
if (fs.existsSync(gitignorePath)) {
|
|
88
|
+
const gitignore = fs.readFileSync(gitignorePath, 'utf-8');
|
|
89
|
+
if (!gitignore.includes('.agent-tasks/')) {
|
|
90
|
+
fs.appendFileSync(gitignorePath, '\n.agent-tasks/\n');
|
|
91
|
+
console.log('ā Added .agent-tasks/ to .gitignore');
|
|
92
|
+
} else {
|
|
93
|
+
log('ā .agent-tasks/ already in .gitignore');
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
fs.writeFileSync(gitignorePath, '.agent-tasks/\n');
|
|
97
|
+
console.log('ā Created .gitignore and added .agent-tasks/');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Create .claude/.gitignore
|
|
101
|
+
const claudeGitignore = path.join(claudeDir, '.gitignore');
|
|
102
|
+
if (!fs.existsSync(claudeGitignore)) {
|
|
103
|
+
fs.writeFileSync(claudeGitignore, '');
|
|
104
|
+
log('Created .claude/.gitignore');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.log(`
|
|
108
|
+
ā
agent-scrum-master initialized!
|
|
109
|
+
|
|
110
|
+
Next steps:
|
|
111
|
+
1. Commit: git add .claude/settings.json && git commit -m "chore: enable agent-scrum-master"
|
|
112
|
+
2. Start: Open this project in Claude Code or Cursor
|
|
113
|
+
3. Dashboard: http://localhost:3422 (auto-starts on first connection)
|
|
114
|
+
4. Create tasks: Use 'task_create' MCP tool in your agent
|
|
115
|
+
|
|
116
|
+
Learn more: https://github.com/keshrath/agent-tasks
|
|
117
|
+
`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export async function openDashboard(options = {}) {
|
|
121
|
+
const { projectRoot = process.cwd(), verbose = false } = options;
|
|
122
|
+
|
|
123
|
+
const log = (msg) => verbose && console.log(msg);
|
|
124
|
+
const claudeDir = path.join(projectRoot, '.claude');
|
|
125
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
126
|
+
|
|
127
|
+
// Check if project is initialized
|
|
128
|
+
if (!fs.existsSync(settingsPath)) {
|
|
129
|
+
console.error('\nā Project not initialized');
|
|
130
|
+
console.error(' Run: npx agent-scrum-master init\n');
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Read settings to get port
|
|
135
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
136
|
+
const port = settings.environmentVariables?.AGENT_TASKS_PORT || 3422;
|
|
137
|
+
const url = `http://localhost:${port}`;
|
|
138
|
+
|
|
139
|
+
console.log(`\nš Opening dashboard at ${url}...\n`);
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
// Open URL in default browser (cross-platform)
|
|
143
|
+
const platform = os.platform();
|
|
144
|
+
const openCommand =
|
|
145
|
+
platform === 'darwin'
|
|
146
|
+
? 'open'
|
|
147
|
+
: platform === 'win32'
|
|
148
|
+
? 'start'
|
|
149
|
+
: 'xdg-open';
|
|
150
|
+
|
|
151
|
+
spawn(openCommand, [url], {
|
|
152
|
+
stdio: 'ignore',
|
|
153
|
+
detached: true,
|
|
154
|
+
}).unref();
|
|
155
|
+
|
|
156
|
+
log(`ā Dashboard should open shortly`);
|
|
157
|
+
console.log(`š” Make sure agent-tasks is running. Open your project in Claude Code or Cursor.`);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
console.error(`\nā ļø Could not open browser automatically`);
|
|
160
|
+
console.error(` Please visit: ${url}\n`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function buildSettings(jiraUrl, jiraProject) {
|
|
165
|
+
const env = {
|
|
166
|
+
AGENT_TASKS_DB: '.agent-tasks/tasks.db',
|
|
167
|
+
AGENT_TASKS_PORT: '3422',
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
if (jiraUrl) {
|
|
171
|
+
env.AGENT_TASKS_JIRA_URL = jiraUrl;
|
|
172
|
+
}
|
|
173
|
+
if (jiraProject) {
|
|
174
|
+
env.AGENT_TASKS_JIRA_PROJECT = jiraProject;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
mcpServers: {
|
|
179
|
+
'agent-tasks': {
|
|
180
|
+
command: 'npx',
|
|
181
|
+
args: ['agent-tasks'],
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
environmentVariables: env,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { setup } from '../src/setup.js';
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const testDir = path.join(__dirname, '../tmp-test-project');
|
|
10
|
+
|
|
11
|
+
// Cleanup helper
|
|
12
|
+
function cleanupTest() {
|
|
13
|
+
if (fs.existsSync(testDir)) {
|
|
14
|
+
fs.rmSync(testDir, { recursive: true, force: true });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Ensure test directory exists
|
|
19
|
+
function setupTest() {
|
|
20
|
+
cleanupTest();
|
|
21
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
test('creates .claude directory', async () => {
|
|
25
|
+
setupTest();
|
|
26
|
+
await setup({ projectRoot: testDir });
|
|
27
|
+
const claudeDir = path.join(testDir, '.claude');
|
|
28
|
+
assert.ok(fs.existsSync(claudeDir), '.claude directory should exist');
|
|
29
|
+
cleanupTest();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('creates .claude/settings.json with MCP config', async () => {
|
|
33
|
+
setupTest();
|
|
34
|
+
await setup({ projectRoot: testDir });
|
|
35
|
+
const settingsPath = path.join(testDir, '.claude', 'settings.json');
|
|
36
|
+
assert.ok(fs.existsSync(settingsPath), 'settings.json should exist');
|
|
37
|
+
|
|
38
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
39
|
+
assert.ok(settings.mcpServers, 'mcpServers should exist');
|
|
40
|
+
assert.ok(settings.mcpServers['agent-tasks'], 'agent-tasks MCP server should be configured');
|
|
41
|
+
assert.equal(settings.environmentVariables.AGENT_TASKS_DB, '.agent-tasks/tasks.db');
|
|
42
|
+
cleanupTest();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('creates .agent-tasks directory', async () => {
|
|
46
|
+
setupTest();
|
|
47
|
+
await setup({ projectRoot: testDir });
|
|
48
|
+
const agentTasksDir = path.join(testDir, '.agent-tasks');
|
|
49
|
+
assert.ok(fs.existsSync(agentTasksDir), '.agent-tasks directory should exist');
|
|
50
|
+
cleanupTest();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('adds .agent-tasks to .gitignore', async () => {
|
|
54
|
+
setupTest();
|
|
55
|
+
await setup({ projectRoot: testDir });
|
|
56
|
+
const gitignorePath = path.join(testDir, '.gitignore');
|
|
57
|
+
assert.ok(fs.existsSync(gitignorePath), '.gitignore should exist');
|
|
58
|
+
const gitignore = fs.readFileSync(gitignorePath, 'utf-8');
|
|
59
|
+
assert.ok(gitignore.includes('.agent-tasks/'), '.agent-tasks should be in .gitignore');
|
|
60
|
+
cleanupTest();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('respects --force flag to overwrite settings', async () => {
|
|
64
|
+
setupTest();
|
|
65
|
+
const settingsPath = path.join(testDir, '.claude', 'settings.json');
|
|
66
|
+
|
|
67
|
+
// First setup
|
|
68
|
+
await setup({ projectRoot: testDir });
|
|
69
|
+
const firstSettings = fs.readFileSync(settingsPath, 'utf-8');
|
|
70
|
+
|
|
71
|
+
// Second setup without force (should not overwrite)
|
|
72
|
+
await setup({ projectRoot: testDir, force: false });
|
|
73
|
+
const secondSettings = fs.readFileSync(settingsPath, 'utf-8');
|
|
74
|
+
assert.equal(firstSettings, secondSettings, 'settings should not change without --force');
|
|
75
|
+
|
|
76
|
+
// Third setup with force (should update)
|
|
77
|
+
await setup({ projectRoot: testDir, force: true, jiraUrl: 'https://jira.example.com' });
|
|
78
|
+
const thirdSettings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
79
|
+
assert.ok(
|
|
80
|
+
thirdSettings.environmentVariables.AGENT_TASKS_JIRA_URL,
|
|
81
|
+
'Jira URL should be added with --force'
|
|
82
|
+
);
|
|
83
|
+
cleanupTest();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('includes Jira config when flags provided', async () => {
|
|
87
|
+
setupTest();
|
|
88
|
+
await setup({
|
|
89
|
+
projectRoot: testDir,
|
|
90
|
+
jiraUrl: 'https://jira.company.com',
|
|
91
|
+
jiraProject: 'GROWTH',
|
|
92
|
+
});
|
|
93
|
+
const settingsPath = path.join(testDir, '.claude', 'settings.json');
|
|
94
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
95
|
+
assert.equal(settings.environmentVariables.AGENT_TASKS_JIRA_URL, 'https://jira.company.com');
|
|
96
|
+
assert.equal(settings.environmentVariables.AGENT_TASKS_JIRA_PROJECT, 'GROWTH');
|
|
97
|
+
cleanupTest();
|
|
98
|
+
});
|