@squidcode/novadev 0.1.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.
Files changed (42) hide show
  1. package/README.md +190 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +25 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/auth.d.ts +3 -0
  7. package/dist/commands/auth.d.ts.map +1 -0
  8. package/dist/commands/auth.js +31 -0
  9. package/dist/commands/auth.js.map +1 -0
  10. package/dist/commands/status.d.ts +3 -0
  11. package/dist/commands/status.d.ts.map +1 -0
  12. package/dist/commands/status.js +33 -0
  13. package/dist/commands/status.js.map +1 -0
  14. package/dist/commands/tasks.d.ts +3 -0
  15. package/dist/commands/tasks.d.ts.map +1 -0
  16. package/dist/commands/tasks.js +56 -0
  17. package/dist/commands/tasks.js.map +1 -0
  18. package/dist/commands/whoami.d.ts +3 -0
  19. package/dist/commands/whoami.d.ts.map +1 -0
  20. package/dist/commands/whoami.js +29 -0
  21. package/dist/commands/whoami.js.map +1 -0
  22. package/dist/config.d.ts +5 -0
  23. package/dist/config.d.ts.map +1 -0
  24. package/dist/config.js +16 -0
  25. package/dist/config.js.map +1 -0
  26. package/dist/index.d.ts +7 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +19 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/lib/api.d.ts +45 -0
  31. package/dist/lib/api.d.ts.map +1 -0
  32. package/dist/lib/api.js +57 -0
  33. package/dist/lib/api.js.map +1 -0
  34. package/dist/lib/credentials.d.ts +18 -0
  35. package/dist/lib/credentials.d.ts.map +1 -0
  36. package/dist/lib/credentials.js +45 -0
  37. package/dist/lib/credentials.js.map +1 -0
  38. package/dist/mcp.d.ts +4 -0
  39. package/dist/mcp.d.ts.map +1 -0
  40. package/dist/mcp.js +140 -0
  41. package/dist/mcp.js.map +1 -0
  42. package/package.json +62 -0
package/README.md ADDED
@@ -0,0 +1,190 @@
1
+ # NovaDev
2
+
3
+ **Connect AI agents to your teams in the Nova system.**
4
+
5
+ NovaDev is a CLI and MCP tool that lets AI agents authenticate with Nova organizations, report their work status, and pull tasks from their assigned teams — acting as first-class team members alongside humans.
6
+
7
+ ## Concepts
8
+
9
+ ### Organizations & Teams
10
+
11
+ - An **organization** contains humans and agents
12
+ - Organizations have one or more **teams**
13
+ - Every member (human or agent) belongs to a **default team** and can be added to additional teams
14
+ - **Admins** can invite both humans and agents
15
+
16
+ ### Agent Identity & Auth
17
+
18
+ 1. Admin invites an agent via Nova dashboard → server generates an **invite token** (hash) and stores the secret server-side
19
+ 2. Admin copies the invite token and enters it into `novadev auth <token>`
20
+ 3. NovaDev exchanges the invite token for a long-lived **auth credential**, stored locally in `~/.novadev/credentials.json`
21
+ 4. The agent authenticates **once per org** — identity is shared across all teams within that org
22
+ 5. Admin can name the agent and assign it to multiple teams
23
+
24
+ ### Agent Reporting
25
+
26
+ Agents report status to Nova (the engineering manager) automatically:
27
+
28
+ | Event | When |
29
+ | -------------- | ------------------------------ |
30
+ | `work:start` | Agent begins working on a task |
31
+ | `work:done` | Agent finishes a task |
32
+ | `work:blocked` | Agent hits an issue or blocker |
33
+
34
+ ### Task Discovery
35
+
36
+ Agents can query available tasks for any team they belong to, pick up work, and report progress.
37
+
38
+ ## Usage
39
+
40
+ ```bash
41
+ # Authenticate with an org (one-time setup)
42
+ novadev auth <invite-token>
43
+
44
+ # Check your teams and identity
45
+ novadev whoami
46
+
47
+ # List available tasks for your teams
48
+ novadev tasks
49
+
50
+ # Report status
51
+ novadev status start "Implementing auth flow for #42"
52
+ novadev status done "Completed auth flow for #42"
53
+ novadev status blocked "Waiting on API spec for payments"
54
+ ```
55
+
56
+ ### MCP Mode
57
+
58
+ NovaDev also runs as an MCP server (stdio transport), exposing the same capabilities as tools for AI agents:
59
+
60
+ ```bash
61
+ # Start as MCP server
62
+ novadev mcp
63
+ ```
64
+
65
+ | Tool | Description |
66
+ | ------------------ | ---------------------------------------------- |
67
+ | `nova_auth` | Authenticate with an org using an invite token |
68
+ | `nova_whoami` | Check agent identity and team memberships |
69
+ | `nova_status` | Report work status (start/done/blocked) |
70
+ | `nova_tasks` | List available tasks for your teams |
71
+ | `nova_tasks_claim` | Claim an available task |
72
+
73
+ Add to your Claude Code MCP config (`~/.claude/claude_desktop_config.json`):
74
+
75
+ ```json
76
+ {
77
+ "mcpServers": {
78
+ "novadev": {
79
+ "command": "npx",
80
+ "args": ["@squidcode/novadev", "mcp"]
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ ## Architecture
87
+
88
+ ```
89
+ ┌──────────────────────────────────────────────────────┐
90
+ │ Nova Platform │
91
+ │ │
92
+ │ ┌─────────┐ ┌──────────┐ ┌──────────────────────┐ │
93
+ │ │ Auth │ │ Teams │ │ Task Management │ │
94
+ │ │ Service │ │ Service │ │ Service │ │
95
+ │ └────┬────┘ └────┬─────┘ └──────────┬───────────┘ │
96
+ │ └─────────┬──┴──────────────────┬┘ │
97
+ │ │ Nova API │ │
98
+ └─────────────────┼────────────────────┼───────────────┘
99
+ │ │
100
+ ┌───────┴────────────────────┴───────┐
101
+ │ NovaDev CLI / MCP │
102
+ │ │
103
+ │ • Auth & credential management │
104
+ │ • Status reporting │
105
+ │ • Task queries │
106
+ │ • Local credential storage │
107
+ │ (~/.novadev/credentials.json) │
108
+ └─────────────────────────────────────┘
109
+ ```
110
+
111
+ ## API Endpoints (to build)
112
+
113
+ ### Auth
114
+
115
+ - `POST /api/agents/invite` — Admin creates agent invite → returns invite token
116
+ - `POST /api/agents/auth` — Agent exchanges invite token for auth credential
117
+ - `GET /api/agents/me` — Get agent identity, org, and teams
118
+
119
+ ### Status Reporting
120
+
121
+ - `POST /api/agents/status` — Report work status (start/done/blocked)
122
+ - `GET /api/agents/status/:agentId` — Get agent's current status
123
+
124
+ ### Tasks
125
+
126
+ - `GET /api/teams/:teamId/tasks` — List available tasks for a team
127
+ - `GET /api/agents/me/tasks` — List tasks across all agent's teams
128
+ - `POST /api/tasks/:taskId/claim` — Agent claims a task
129
+
130
+ ### Team Management (Admin)
131
+
132
+ - `POST /api/teams/:teamId/agents` — Add agent to team
133
+ - `DELETE /api/teams/:teamId/agents/:agentId` — Remove agent from team
134
+ - `PUT /api/agents/:agentId` — Update agent name/config
135
+
136
+ ## Credential Storage
137
+
138
+ ```
139
+ ~/.novadev/
140
+ credentials.json # { orgId, agentId, token, name }
141
+ ```
142
+
143
+ - One credential per org
144
+ - Agent authenticates once, credential persists
145
+ - Token used for all subsequent API calls
146
+
147
+ ## Tech Stack
148
+
149
+ | Component | Technology |
150
+ | ---------- | --------------------------------------------- |
151
+ | CLI | Node.js, TypeScript, Commander.js |
152
+ | MCP Server | `@modelcontextprotocol/sdk` (stdio transport) |
153
+ | Auth | Invite token → JWT exchange |
154
+ | Storage | Local JSON file |
155
+
156
+ ## Roadmap
157
+
158
+ ### Phase 1: Auth & Identity
159
+
160
+ - [ ] Agent invite flow (admin dashboard + API)
161
+ - [ ] Token exchange endpoint
162
+ - [ ] `novadev auth` command
163
+ - [ ] Local credential storage
164
+ - [ ] `novadev whoami` command
165
+
166
+ ### Phase 2: Status Reporting
167
+
168
+ - [ ] Status reporting endpoints
169
+ - [ ] `novadev status` command
170
+ - [ ] Nova receives and displays agent activity
171
+
172
+ ### Phase 3: Task Management
173
+
174
+ - [ ] Task listing endpoints
175
+ - [ ] `novadev tasks` command
176
+ - [ ] Task claiming flow
177
+
178
+ ### Phase 4: MCP Integration
179
+
180
+ - [x] MCP server mode (`novadev mcp`)
181
+ - [x] All CLI commands as MCP tools
182
+ - [ ] Agent auto-reporting via MCP hooks
183
+
184
+ ## License
185
+
186
+ MIT
187
+
188
+ ---
189
+
190
+ _Part of the [Nova](https://github.com/squidcode/nova) ecosystem by [Squidcode](https://squidcode.com)_
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const auth_js_1 = require("./commands/auth.js");
6
+ const whoami_js_1 = require("./commands/whoami.js");
7
+ const status_js_1 = require("./commands/status.js");
8
+ const tasks_js_1 = require("./commands/tasks.js");
9
+ const mcp_js_1 = require("./mcp.js");
10
+ const program = new commander_1.Command()
11
+ .name('novadev')
12
+ .description('Connect AI agents to your teams in the Nova system')
13
+ .version('0.1.0');
14
+ program.addCommand(auth_js_1.authCommand);
15
+ program.addCommand(whoami_js_1.whoamiCommand);
16
+ program.addCommand(status_js_1.statusCommand);
17
+ program.addCommand(tasks_js_1.tasksCommand);
18
+ program
19
+ .command('mcp')
20
+ .description('Start as an MCP server (stdio transport)')
21
+ .action(async () => {
22
+ await (0, mcp_js_1.startMcpServer)();
23
+ });
24
+ program.parse();
25
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,gDAAiD;AACjD,oDAAqD;AACrD,oDAAqD;AACrD,kDAAmD;AACnD,qCAA0C;AAE1C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE;KAC1B,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,oDAAoD,CAAC;KACjE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,uBAAY,CAAC,CAAC;AAEjC,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,IAAA,uBAAc,GAAE,CAAC;AACzB,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const authCommand: Command;
3
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,WAAW,SAwBpB,CAAC"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authCommand = void 0;
4
+ const commander_1 = require("commander");
5
+ const api_js_1 = require("../lib/api.js");
6
+ const credentials_js_1 = require("../lib/credentials.js");
7
+ exports.authCommand = new commander_1.Command('auth')
8
+ .description('Authenticate with a Nova organization using an invite token')
9
+ .argument('<token>', 'Invite token from your org admin')
10
+ .action(async (token) => {
11
+ try {
12
+ console.log('Authenticating with Nova...');
13
+ const res = await api_js_1.api.auth(token);
14
+ (0, credentials_js_1.setCredential)(res.orgId, {
15
+ agentId: res.agentId,
16
+ token: res.token,
17
+ name: res.name,
18
+ orgName: res.orgName,
19
+ authenticatedAt: new Date().toISOString(),
20
+ });
21
+ console.log(`Authenticated as "${res.name}" in ${res.orgName}`);
22
+ console.log(`Teams: ${res.teams.map((t) => t.name).join(', ')}`);
23
+ }
24
+ catch (err) {
25
+ if (err instanceof Error) {
26
+ console.error(`Authentication failed: ${err.message}`);
27
+ }
28
+ process.exit(1);
29
+ }
30
+ });
31
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AACpC,0CAAoC;AACpC,0DAAsD;AAEzC,QAAA,WAAW,GAAG,IAAI,mBAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,6DAA6D,CAAC;KAC1E,QAAQ,CAAC,SAAS,EAAE,kCAAkC,CAAC;KACvD,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;IAC9B,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,YAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAElC,IAAA,8BAAa,EAAC,GAAG,CAAC,KAAK,EAAE;YACvB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,eAAe,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC1C,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const statusCommand: Command;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,aAAa,SAyBtB,CAAC"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.statusCommand = void 0;
4
+ const commander_1 = require("commander");
5
+ const api_js_1 = require("../lib/api.js");
6
+ const credentials_js_1 = require("../lib/credentials.js");
7
+ const VALID_TYPES = ['start', 'done', 'blocked'];
8
+ exports.statusCommand = new commander_1.Command('status')
9
+ .description('Report work status to Nova')
10
+ .argument('<type>', 'Status type: start, done, or blocked')
11
+ .argument('<message>', 'Status message')
12
+ .option('-t, --task <taskId>', 'Associated task ID')
13
+ .action(async (type, message, opts) => {
14
+ if (!(0, credentials_js_1.getActiveCredential)()) {
15
+ console.error('Not authenticated. Run: novadev auth <token>');
16
+ process.exit(1);
17
+ }
18
+ if (!VALID_TYPES.includes(type)) {
19
+ console.error(`Invalid status type "${type}". Use: ${VALID_TYPES.join(', ')}`);
20
+ process.exit(1);
21
+ }
22
+ try {
23
+ await api_js_1.api.reportStatus(type, message, opts.task);
24
+ console.log(`Reported: [${type}] ${message}`);
25
+ }
26
+ catch (err) {
27
+ if (err instanceof Error) {
28
+ console.error(`Failed to report status: ${err.message}`);
29
+ }
30
+ process.exit(1);
31
+ }
32
+ });
33
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AACpC,0CAAoC;AACpC,0DAA4D;AAE5D,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAU,CAAC;AAG7C,QAAA,aAAa,GAAG,IAAI,mBAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,4BAA4B,CAAC;KACzC,QAAQ,CAAC,QAAQ,EAAE,sCAAsC,CAAC;KAC1D,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;KACvC,MAAM,CAAC,qBAAqB,EAAE,oBAAoB,CAAC;KACnD,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAAe,EAAE,IAAuB,EAAE,EAAE;IACvE,IAAI,CAAC,IAAA,oCAAmB,GAAE,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAkB,CAAC,EAAE,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,wBAAwB,IAAI,WAAW,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAG,CAAC,YAAY,CAAC,IAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,4BAA4B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const tasksCommand: Command;
3
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/commands/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBpC,eAAO,MAAM,YAAY,SAerB,CAAC"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tasksCommand = void 0;
4
+ const commander_1 = require("commander");
5
+ const api_js_1 = require("../lib/api.js");
6
+ const credentials_js_1 = require("../lib/credentials.js");
7
+ function requireAuth() {
8
+ if (!(0, credentials_js_1.getActiveCredential)()) {
9
+ console.error('Not authenticated. Run: novadev auth <token>');
10
+ process.exit(1);
11
+ }
12
+ }
13
+ function printTasks(tasks) {
14
+ if (tasks.length === 0) {
15
+ console.log('No tasks available.');
16
+ return;
17
+ }
18
+ for (const task of tasks) {
19
+ const assignee = task.assigneeId ? `[assigned]` : '[open]';
20
+ console.log(` ${task.id} ${assignee} ${task.title} (${task.teamName})`);
21
+ }
22
+ }
23
+ exports.tasksCommand = new commander_1.Command('tasks')
24
+ .description('List available tasks for your teams')
25
+ .option('--team <teamId>', 'Filter by team ID')
26
+ .action(async (opts) => {
27
+ requireAuth();
28
+ try {
29
+ const tasks = await api_js_1.api.tasks(opts.team);
30
+ printTasks(tasks);
31
+ }
32
+ catch (err) {
33
+ if (err instanceof Error) {
34
+ console.error(`Failed to fetch tasks: ${err.message}`);
35
+ }
36
+ process.exit(1);
37
+ }
38
+ });
39
+ exports.tasksCommand
40
+ .command('claim')
41
+ .description('Claim a task')
42
+ .argument('<taskId>', 'Task ID to claim')
43
+ .action(async (taskId) => {
44
+ requireAuth();
45
+ try {
46
+ await api_js_1.api.claimTask(taskId);
47
+ console.log(`Claimed task ${taskId}`);
48
+ }
49
+ catch (err) {
50
+ if (err instanceof Error) {
51
+ console.error(`Failed to claim task: ${err.message}`);
52
+ }
53
+ process.exit(1);
54
+ }
55
+ });
56
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/commands/tasks.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AACpC,0CAA0C;AAC1C,0DAA4D;AAE5D,SAAS,WAAW;IAClB,IAAI,CAAC,IAAA,oCAAmB,GAAE,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO;IACT,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,EAAE,KAAK,QAAQ,KAAK,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAEY,QAAA,YAAY,GAAG,IAAI,mBAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,CAAC;KAC9C,MAAM,CAAC,KAAK,EAAE,IAAuB,EAAE,EAAE;IACxC,WAAW,EAAE,CAAC;IAEd,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,YAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,UAAU,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,oBAAY;KACT,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,cAAc,CAAC;KAC3B,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;KACxC,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,EAAE;IAC/B,WAAW,EAAE,CAAC;IAEd,IAAI,CAAC;QACH,MAAM,YAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,yBAAyB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const whoamiCommand: Command;
3
+ //# sourceMappingURL=whoami.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,SAqBtB,CAAC"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.whoamiCommand = void 0;
4
+ const commander_1 = require("commander");
5
+ const api_js_1 = require("../lib/api.js");
6
+ const credentials_js_1 = require("../lib/credentials.js");
7
+ exports.whoamiCommand = new commander_1.Command('whoami')
8
+ .description('Show your agent identity and teams')
9
+ .action(async () => {
10
+ const cred = (0, credentials_js_1.getActiveCredential)();
11
+ if (!cred) {
12
+ console.error('Not authenticated. Run: novadev auth <token>');
13
+ process.exit(1);
14
+ }
15
+ try {
16
+ const info = await api_js_1.api.me();
17
+ console.log(`Agent: ${info.name}`);
18
+ console.log(`Org: ${info.orgName}`);
19
+ console.log(`Status: ${info.status}`);
20
+ console.log(`Teams: ${info.teams.map((t) => t.name).join(', ')}`);
21
+ }
22
+ catch (err) {
23
+ if (err instanceof Error) {
24
+ console.error(`Failed to fetch identity: ${err.message}`);
25
+ }
26
+ process.exit(1);
27
+ }
28
+ });
29
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AACpC,0CAAoC;AACpC,0DAA4D;AAE/C,QAAA,aAAa,GAAG,IAAI,mBAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,IAAI,GAAG,IAAA,oCAAmB,GAAE,CAAC;IACnC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,YAAG,CAAC,EAAE,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,6BAA6B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const NOVADEV_DIR: string;
2
+ export declare const CREDENTIALS_FILE: string;
3
+ export declare const DEFAULT_API_URL = "https://api.nova.squidcode.com";
4
+ export declare function getApiUrl(): string;
5
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,QAAsC,CAAC;AAC/D,eAAO,MAAM,gBAAgB,QAA6C,CAAC;AAE3E,eAAO,MAAM,eAAe,mCAAmC,CAAC;AAEhE,wBAAgB,SAAS,IAAI,MAAM,CAElC"}
package/dist/config.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_API_URL = exports.CREDENTIALS_FILE = exports.NOVADEV_DIR = void 0;
7
+ exports.getApiUrl = getApiUrl;
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const node_os_1 = __importDefault(require("node:os"));
10
+ exports.NOVADEV_DIR = node_path_1.default.join(node_os_1.default.homedir(), '.novadev');
11
+ exports.CREDENTIALS_FILE = node_path_1.default.join(exports.NOVADEV_DIR, 'credentials.json');
12
+ exports.DEFAULT_API_URL = 'https://api.nova.squidcode.com';
13
+ function getApiUrl() {
14
+ return process.env.NOVA_API_URL || exports.DEFAULT_API_URL;
15
+ }
16
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;AAQA,8BAEC;AAVD,0DAA6B;AAC7B,sDAAyB;AAEZ,QAAA,WAAW,GAAG,mBAAI,CAAC,IAAI,CAAC,iBAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAClD,QAAA,gBAAgB,GAAG,mBAAI,CAAC,IAAI,CAAC,mBAAW,EAAE,kBAAkB,CAAC,CAAC;AAE9D,QAAA,eAAe,GAAG,gCAAgC,CAAC;AAEhE,SAAgB,SAAS;IACvB,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uBAAe,CAAC;AACrD,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { api, NovaApiError } from './lib/api.js';
2
+ export type { AuthResponse, AgentInfo, Task } from './lib/api.js';
3
+ export { loadCredentials, saveCredentials, getActiveCredential, setCredential, } from './lib/credentials.js';
4
+ export type { OrgCredential, CredentialStore } from './lib/credentials.js';
5
+ export { getApiUrl, NOVADEV_DIR, CREDENTIALS_FILE } from './config.js';
6
+ export { createMcpServer, startMcpServer } from './mcp.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EACL,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,aAAa,GACd,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startMcpServer = exports.createMcpServer = exports.CREDENTIALS_FILE = exports.NOVADEV_DIR = exports.getApiUrl = exports.setCredential = exports.getActiveCredential = exports.saveCredentials = exports.loadCredentials = exports.NovaApiError = exports.api = void 0;
4
+ var api_js_1 = require("./lib/api.js");
5
+ Object.defineProperty(exports, "api", { enumerable: true, get: function () { return api_js_1.api; } });
6
+ Object.defineProperty(exports, "NovaApiError", { enumerable: true, get: function () { return api_js_1.NovaApiError; } });
7
+ var credentials_js_1 = require("./lib/credentials.js");
8
+ Object.defineProperty(exports, "loadCredentials", { enumerable: true, get: function () { return credentials_js_1.loadCredentials; } });
9
+ Object.defineProperty(exports, "saveCredentials", { enumerable: true, get: function () { return credentials_js_1.saveCredentials; } });
10
+ Object.defineProperty(exports, "getActiveCredential", { enumerable: true, get: function () { return credentials_js_1.getActiveCredential; } });
11
+ Object.defineProperty(exports, "setCredential", { enumerable: true, get: function () { return credentials_js_1.setCredential; } });
12
+ var config_js_1 = require("./config.js");
13
+ Object.defineProperty(exports, "getApiUrl", { enumerable: true, get: function () { return config_js_1.getApiUrl; } });
14
+ Object.defineProperty(exports, "NOVADEV_DIR", { enumerable: true, get: function () { return config_js_1.NOVADEV_DIR; } });
15
+ Object.defineProperty(exports, "CREDENTIALS_FILE", { enumerable: true, get: function () { return config_js_1.CREDENTIALS_FILE; } });
16
+ var mcp_js_1 = require("./mcp.js");
17
+ Object.defineProperty(exports, "createMcpServer", { enumerable: true, get: function () { return mcp_js_1.createMcpServer; } });
18
+ Object.defineProperty(exports, "startMcpServer", { enumerable: true, get: function () { return mcp_js_1.startMcpServer; } });
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uCAAiD;AAAxC,6FAAA,GAAG,OAAA;AAAE,sGAAA,YAAY,OAAA;AAE1B,uDAK8B;AAJ5B,iHAAA,eAAe,OAAA;AACf,iHAAA,eAAe,OAAA;AACf,qHAAA,mBAAmB,OAAA;AACnB,+GAAA,aAAa,OAAA;AAGf,yCAAuE;AAA9D,sGAAA,SAAS,OAAA;AAAE,wGAAA,WAAW,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AACjD,mCAA2D;AAAlD,yGAAA,eAAe,OAAA;AAAE,wGAAA,cAAc,OAAA"}
@@ -0,0 +1,45 @@
1
+ export declare class NovaApiError extends Error {
2
+ status: number;
3
+ constructor(status: number, message: string);
4
+ }
5
+ export interface AuthResponse {
6
+ agentId: string;
7
+ orgId: string;
8
+ orgName: string;
9
+ token: string;
10
+ name: string;
11
+ teams: Array<{
12
+ id: string;
13
+ name: string;
14
+ }>;
15
+ }
16
+ export interface AgentInfo {
17
+ agentId: string;
18
+ name: string;
19
+ orgId: string;
20
+ orgName: string;
21
+ teams: Array<{
22
+ id: string;
23
+ name: string;
24
+ }>;
25
+ status: string;
26
+ }
27
+ export interface Task {
28
+ id: string;
29
+ title: string;
30
+ description: string;
31
+ status: string;
32
+ teamId: string;
33
+ teamName: string;
34
+ assigneeId: string | null;
35
+ priority: string;
36
+ createdAt: string;
37
+ }
38
+ export declare const api: {
39
+ auth(inviteToken: string): Promise<AuthResponse>;
40
+ me(): Promise<AgentInfo>;
41
+ reportStatus(type: "start" | "done" | "blocked", message: string, taskId?: string): Promise<unknown>;
42
+ tasks(teamId?: string): Promise<Task[]>;
43
+ claimTask(taskId: string): Promise<unknown>;
44
+ };
45
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAGA,qBAAa,YAAa,SAAQ,KAAK;IAE5B,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM;CAKlB;AA+BD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,GAAG;sBACI,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;UAM1C,OAAO,CAAC,SAAS,CAAC;uBAIL,OAAO,GAAG,MAAM,GAAG,SAAS,WAAW,MAAM,WAAW,MAAM;mBAMlE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;sBAKrB,MAAM;CAGzB,CAAC"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.api = exports.NovaApiError = void 0;
4
+ const config_js_1 = require("../config.js");
5
+ const credentials_js_1 = require("./credentials.js");
6
+ class NovaApiError extends Error {
7
+ status;
8
+ constructor(status, message) {
9
+ super(message);
10
+ this.status = status;
11
+ this.name = 'NovaApiError';
12
+ }
13
+ }
14
+ exports.NovaApiError = NovaApiError;
15
+ async function request(method, path, options) {
16
+ const url = `${(0, config_js_1.getApiUrl)()}${path}`;
17
+ const headers = {
18
+ 'Content-Type': 'application/json',
19
+ };
20
+ const token = options?.token || (0, credentials_js_1.getActiveCredential)()?.token;
21
+ if (token) {
22
+ headers['Authorization'] = `Bearer ${token}`;
23
+ }
24
+ const res = await fetch(url, {
25
+ method,
26
+ headers,
27
+ body: options?.body ? JSON.stringify(options.body) : undefined,
28
+ });
29
+ if (!res.ok) {
30
+ const text = await res.text().catch(() => res.statusText);
31
+ throw new NovaApiError(res.status, text);
32
+ }
33
+ return res.json();
34
+ }
35
+ exports.api = {
36
+ auth(inviteToken) {
37
+ return request('POST', '/api/agents/auth', {
38
+ body: { inviteToken },
39
+ });
40
+ },
41
+ me() {
42
+ return request('GET', '/api/agents/me');
43
+ },
44
+ reportStatus(type, message, taskId) {
45
+ return request('POST', '/api/agents/status', {
46
+ body: { type, message, taskId },
47
+ });
48
+ },
49
+ tasks(teamId) {
50
+ const path = teamId ? `/api/teams/${teamId}/tasks` : '/api/agents/me/tasks';
51
+ return request('GET', path);
52
+ },
53
+ claimTask(taskId) {
54
+ return request('POST', `/api/tasks/${taskId}/claim`);
55
+ },
56
+ };
57
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":";;;AAAA,4CAAyC;AACzC,qDAAuD;AAEvD,MAAa,YAAa,SAAQ,KAAK;IAE5B;IADT,YACS,MAAc,EACrB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,WAAM,GAAN,MAAM,CAAQ;QAIrB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AARD,oCAQC;AAED,KAAK,UAAU,OAAO,CACpB,MAAc,EACd,IAAY,EACZ,OAA4C;IAE5C,MAAM,GAAG,GAAG,GAAG,IAAA,qBAAS,GAAE,GAAG,IAAI,EAAE,CAAC;IACpC,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;KACnC,CAAC;IAEF,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,IAAA,oCAAmB,GAAE,EAAE,KAAK,CAAC;IAC7D,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC3B,MAAM;QACN,OAAO;QACP,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KAC/D,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC1D,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;AAClC,CAAC;AAgCY,QAAA,GAAG,GAAG;IACjB,IAAI,CAAC,WAAmB;QACtB,OAAO,OAAO,CAAe,MAAM,EAAE,kBAAkB,EAAE;YACvD,IAAI,EAAE,EAAE,WAAW,EAAE;SACtB,CAAC,CAAC;IACL,CAAC;IAED,EAAE;QACA,OAAO,OAAO,CAAY,KAAK,EAAE,gBAAgB,CAAC,CAAC;IACrD,CAAC;IAED,YAAY,CAAC,IAAkC,EAAE,OAAe,EAAE,MAAe;QAC/E,OAAO,OAAO,CAAC,MAAM,EAAE,oBAAoB,EAAE;YAC3C,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE;SAChC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAe;QACnB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,cAAc,MAAM,QAAQ,CAAC,CAAC,CAAC,sBAAsB,CAAC;QAC5E,OAAO,OAAO,CAAS,KAAK,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,SAAS,CAAC,MAAc;QACtB,OAAO,OAAO,CAAC,MAAM,EAAE,cAAc,MAAM,QAAQ,CAAC,CAAC;IACvD,CAAC;CACF,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface OrgCredential {
2
+ agentId: string;
3
+ token: string;
4
+ name: string;
5
+ orgName: string;
6
+ authenticatedAt: string;
7
+ }
8
+ export interface CredentialStore {
9
+ orgs: Record<string, OrgCredential>;
10
+ defaultOrg: string | null;
11
+ }
12
+ export declare function loadCredentials(): CredentialStore;
13
+ export declare function saveCredentials(store: CredentialStore): void;
14
+ export declare function getActiveCredential(): (OrgCredential & {
15
+ orgId: string;
16
+ }) | null;
17
+ export declare function setCredential(orgId: string, credential: OrgCredential): void;
18
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACpC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAQD,wBAAgB,eAAe,IAAI,eAAe,CAMjD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAK5D;AAED,wBAAgB,mBAAmB,IAAI,CAAC,aAAa,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAKhF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,GAAG,IAAI,CAO5E"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.loadCredentials = loadCredentials;
7
+ exports.saveCredentials = saveCredentials;
8
+ exports.getActiveCredential = getActiveCredential;
9
+ exports.setCredential = setCredential;
10
+ const node_fs_1 = __importDefault(require("node:fs"));
11
+ const config_js_1 = require("../config.js");
12
+ function ensureDir() {
13
+ if (!node_fs_1.default.existsSync(config_js_1.NOVADEV_DIR)) {
14
+ node_fs_1.default.mkdirSync(config_js_1.NOVADEV_DIR, { recursive: true, mode: 0o700 });
15
+ }
16
+ }
17
+ function loadCredentials() {
18
+ if (!node_fs_1.default.existsSync(config_js_1.CREDENTIALS_FILE)) {
19
+ return { orgs: {}, defaultOrg: null };
20
+ }
21
+ const raw = node_fs_1.default.readFileSync(config_js_1.CREDENTIALS_FILE, 'utf-8');
22
+ return JSON.parse(raw);
23
+ }
24
+ function saveCredentials(store) {
25
+ ensureDir();
26
+ node_fs_1.default.writeFileSync(config_js_1.CREDENTIALS_FILE, JSON.stringify(store, null, 2), {
27
+ mode: 0o600,
28
+ });
29
+ }
30
+ function getActiveCredential() {
31
+ const store = loadCredentials();
32
+ const orgId = store.defaultOrg;
33
+ if (!orgId || !store.orgs[orgId])
34
+ return null;
35
+ return { ...store.orgs[orgId], orgId };
36
+ }
37
+ function setCredential(orgId, credential) {
38
+ const store = loadCredentials();
39
+ store.orgs[orgId] = credential;
40
+ if (!store.defaultOrg) {
41
+ store.defaultOrg = orgId;
42
+ }
43
+ saveCredentials(store);
44
+ }
45
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":";;;;;AAsBA,0CAMC;AAED,0CAKC;AAED,kDAKC;AAED,sCAOC;AAnDD,sDAAyB;AACzB,4CAA6D;AAe7D,SAAS,SAAS;IAChB,IAAI,CAAC,iBAAE,CAAC,UAAU,CAAC,uBAAW,CAAC,EAAE,CAAC;QAChC,iBAAE,CAAC,SAAS,CAAC,uBAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAED,SAAgB,eAAe;IAC7B,IAAI,CAAC,iBAAE,CAAC,UAAU,CAAC,4BAAgB,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACxC,CAAC;IACD,MAAM,GAAG,GAAG,iBAAE,CAAC,YAAY,CAAC,4BAAgB,EAAE,OAAO,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;AAC5C,CAAC;AAED,SAAgB,eAAe,CAAC,KAAsB;IACpD,SAAS,EAAE,CAAC;IACZ,iBAAE,CAAC,aAAa,CAAC,4BAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QACjE,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,mBAAmB;IACjC,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC;IAC/B,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;AACzC,CAAC;AAED,SAAgB,aAAa,CAAC,KAAa,EAAE,UAAyB;IACpE,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC;IAC/B,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACtB,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;IAC3B,CAAC;IACD,eAAe,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function createMcpServer(): McpServer;
3
+ export declare function startMcpServer(): Promise<void>;
4
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,wBAAgB,eAAe,IAAI,SAAS,CA+J3C;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAIpD"}
package/dist/mcp.js ADDED
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMcpServer = createMcpServer;
4
+ exports.startMcpServer = startMcpServer;
5
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
6
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
7
+ const zod_1 = require("zod");
8
+ const api_js_1 = require("./lib/api.js");
9
+ const credentials_js_1 = require("./lib/credentials.js");
10
+ function createMcpServer() {
11
+ const server = new mcp_js_1.McpServer({
12
+ name: 'novadev',
13
+ version: '0.1.0',
14
+ });
15
+ server.registerTool('nova_auth', {
16
+ title: 'Authenticate with Nova',
17
+ description: 'Authenticate with a Nova organization using an invite token (one-time setup)',
18
+ inputSchema: {
19
+ token: zod_1.z.string().describe('Invite token from your org admin'),
20
+ },
21
+ }, async ({ token }) => {
22
+ const res = await api_js_1.api.auth(token);
23
+ (0, credentials_js_1.setCredential)(res.orgId, {
24
+ agentId: res.agentId,
25
+ token: res.token,
26
+ name: res.name,
27
+ orgName: res.orgName,
28
+ authenticatedAt: new Date().toISOString(),
29
+ });
30
+ return {
31
+ content: [
32
+ {
33
+ type: 'text',
34
+ text: `Authenticated as "${res.name}" in ${res.orgName}. Teams: ${res.teams.map((t) => t.name).join(', ')}`,
35
+ },
36
+ ],
37
+ };
38
+ });
39
+ server.registerTool('nova_whoami', {
40
+ title: 'Check Nova identity',
41
+ description: 'Show your agent identity, organization, and team memberships',
42
+ }, async () => {
43
+ const cred = (0, credentials_js_1.getActiveCredential)();
44
+ if (!cred) {
45
+ return {
46
+ content: [{ type: 'text', text: 'Not authenticated. Use nova_auth first.' }],
47
+ isError: true,
48
+ };
49
+ }
50
+ const info = await api_js_1.api.me();
51
+ return {
52
+ content: [
53
+ {
54
+ type: 'text',
55
+ text: [
56
+ `Agent: ${info.name}`,
57
+ `Org: ${info.orgName}`,
58
+ `Status: ${info.status}`,
59
+ `Teams: ${info.teams.map((t) => t.name).join(', ')}`,
60
+ ].join('\n'),
61
+ },
62
+ ],
63
+ };
64
+ });
65
+ server.registerTool('nova_status', {
66
+ title: 'Report work status',
67
+ description: 'Report work status to Nova (the engineering manager). Use "start" when beginning work, "done" when finished, "blocked" when hitting an issue.',
68
+ inputSchema: {
69
+ type: zod_1.z.enum(['start', 'done', 'blocked']).describe('Status type'),
70
+ message: zod_1.z.string().describe('Status message describing what you are working on'),
71
+ taskId: zod_1.z.string().optional().describe('Associated task ID (optional)'),
72
+ },
73
+ }, async ({ type, message, taskId }) => {
74
+ const cred = (0, credentials_js_1.getActiveCredential)();
75
+ if (!cred) {
76
+ return {
77
+ content: [{ type: 'text', text: 'Not authenticated. Use nova_auth first.' }],
78
+ isError: true,
79
+ };
80
+ }
81
+ await api_js_1.api.reportStatus(type, message, taskId);
82
+ return {
83
+ content: [{ type: 'text', text: `Reported: [${type}] ${message}` }],
84
+ };
85
+ });
86
+ server.registerTool('nova_tasks', {
87
+ title: 'List available tasks',
88
+ description: 'List available tasks for your teams. Optionally filter by team ID.',
89
+ inputSchema: {
90
+ teamId: zod_1.z.string().optional().describe('Filter by team ID (optional)'),
91
+ },
92
+ }, async ({ teamId }) => {
93
+ const cred = (0, credentials_js_1.getActiveCredential)();
94
+ if (!cred) {
95
+ return {
96
+ content: [{ type: 'text', text: 'Not authenticated. Use nova_auth first.' }],
97
+ isError: true,
98
+ };
99
+ }
100
+ const tasks = await api_js_1.api.tasks(teamId);
101
+ if (tasks.length === 0) {
102
+ return {
103
+ content: [{ type: 'text', text: 'No tasks available.' }],
104
+ };
105
+ }
106
+ const lines = tasks.map((t) => {
107
+ const assignee = t.assigneeId ? '[assigned]' : '[open]';
108
+ return `${t.id} ${assignee} ${t.title} (${t.teamName})`;
109
+ });
110
+ return {
111
+ content: [{ type: 'text', text: lines.join('\n') }],
112
+ };
113
+ });
114
+ server.registerTool('nova_tasks_claim', {
115
+ title: 'Claim a task',
116
+ description: 'Claim an available task to work on. This assigns the task to you.',
117
+ inputSchema: {
118
+ taskId: zod_1.z.string().describe('The task ID to claim'),
119
+ },
120
+ }, async ({ taskId }) => {
121
+ const cred = (0, credentials_js_1.getActiveCredential)();
122
+ if (!cred) {
123
+ return {
124
+ content: [{ type: 'text', text: 'Not authenticated. Use nova_auth first.' }],
125
+ isError: true,
126
+ };
127
+ }
128
+ await api_js_1.api.claimTask(taskId);
129
+ return {
130
+ content: [{ type: 'text', text: `Claimed task ${taskId}` }],
131
+ };
132
+ });
133
+ return server;
134
+ }
135
+ async function startMcpServer() {
136
+ const server = createMcpServer();
137
+ const transport = new stdio_js_1.StdioServerTransport();
138
+ await server.connect(transport);
139
+ }
140
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@squidcode/novadev",
3
+ "version": "0.1.0",
4
+ "description": "Connect AI agents to your teams in the Nova system",
5
+ "type": "commonjs",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "novadev": "dist/cli.js"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "dev": "tsc --watch",
17
+ "lint": "eslint src/",
18
+ "lint:fix": "eslint src/ --fix",
19
+ "format": "prettier --write .",
20
+ "format:check": "prettier --check .",
21
+ "typecheck": "tsc --noEmit",
22
+ "check": "npm run typecheck && npm run lint && npm run format:check",
23
+ "prepublishOnly": "npm run check && npm run build",
24
+ "prepare": "husky"
25
+ },
26
+ "keywords": [
27
+ "nova",
28
+ "ai-agents",
29
+ "cli",
30
+ "mcp",
31
+ "team-management"
32
+ ],
33
+ "author": "Squidcode <hello@squidcode.com>",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/squidcode/novadev.git"
38
+ },
39
+ "homepage": "https://github.com/squidcode/novadev#readme",
40
+ "bugs": {
41
+ "url": "https://github.com/squidcode/novadev/issues"
42
+ },
43
+ "engines": {
44
+ "node": ">=18"
45
+ },
46
+ "dependencies": {
47
+ "@modelcontextprotocol/sdk": "^1.27.1",
48
+ "commander": "^13.1.0",
49
+ "zod": "^4.3.6"
50
+ },
51
+ "devDependencies": {
52
+ "@eslint/js": "^9.21.0",
53
+ "@types/node": "^22.13.0",
54
+ "eslint": "^9.21.0",
55
+ "eslint-config-prettier": "^10.0.1",
56
+ "husky": "^9.1.0",
57
+ "lint-staged": "^15.4.0",
58
+ "prettier": "^3.5.0",
59
+ "typescript": "^5.7.0",
60
+ "typescript-eslint": "^8.25.0"
61
+ }
62
+ }