@hechura/noreaster-cli 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.
- package/README.md +14 -0
- package/dist/commands/admin.js +89 -0
- package/dist/commands/customers.js +53 -0
- package/dist/commands/docs.js +61 -0
- package/dist/commands/meetings.js +56 -0
- package/dist/commands/messages.js +18 -0
- package/dist/commands/projects.js +67 -0
- package/dist/commands/prospects.js +61 -0
- package/dist/commands/sprints.js +53 -0
- package/dist/commands/tasks.js +58 -0
- package/dist/commands/team.js +29 -0
- package/dist/commands/timeline.js +53 -0
- package/dist/http.js +50 -0
- package/dist/index.js +38 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# @hechura/noreaster-cli
|
|
2
|
+
|
|
3
|
+
Run the Hechura Noreaster agent CLI from anywhere with `npx`.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
HECHURA_API_BASE_URL="https://noreaster.vercel.app" \
|
|
7
|
+
HECHURA_AGENT_TOKEN="hctra_..." \
|
|
8
|
+
npx @hechura/noreaster-cli projects list
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Required environment variables:
|
|
12
|
+
|
|
13
|
+
- `HECHURA_API_BASE_URL` (optional; defaults to `https://noreaster.vercel.app`)
|
|
14
|
+
- `HECHURA_AGENT_TOKEN` (required)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerAdminCommands = registerAdminCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerAdminCommands(parent) {
|
|
6
|
+
const admin = parent.command("admin").description("Manage AI agents and tokens");
|
|
7
|
+
admin.command("agents").action(async () => {
|
|
8
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", "/api/agent/admin/agents");
|
|
9
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10
|
+
});
|
|
11
|
+
admin
|
|
12
|
+
.command("create-agent")
|
|
13
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/admin/agents", (0, http_1.parsePayload)(options.data));
|
|
16
|
+
console.log(JSON.stringify(result, null, 2));
|
|
17
|
+
});
|
|
18
|
+
admin
|
|
19
|
+
.command("update-agent")
|
|
20
|
+
.argument("<id>")
|
|
21
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
22
|
+
.action(async (id, options) => {
|
|
23
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/admin/agents/${id}`, (0, http_1.parsePayload)(options.data));
|
|
24
|
+
console.log(JSON.stringify(result, null, 2));
|
|
25
|
+
});
|
|
26
|
+
admin
|
|
27
|
+
.command("delete-agent")
|
|
28
|
+
.argument("<id>")
|
|
29
|
+
.action(async (id) => {
|
|
30
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/admin/agents/${id}`);
|
|
31
|
+
console.log(JSON.stringify(result, null, 2));
|
|
32
|
+
});
|
|
33
|
+
admin
|
|
34
|
+
.command("tokens")
|
|
35
|
+
.option("--agent-id <agentId>")
|
|
36
|
+
.action(async (options) => {
|
|
37
|
+
const query = options.agentId ? `?ai_agent_id=${encodeURIComponent(options.agentId)}` : "";
|
|
38
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/admin/tokens${query}`);
|
|
39
|
+
console.log(JSON.stringify(result, null, 2));
|
|
40
|
+
});
|
|
41
|
+
admin
|
|
42
|
+
.command("issue-token")
|
|
43
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
44
|
+
.action(async (options) => {
|
|
45
|
+
const payload = (0, http_1.parsePayload)(options.data);
|
|
46
|
+
const aiAgentId = typeof payload.ai_agent_id === "string" ? payload.ai_agent_id : null;
|
|
47
|
+
if (!aiAgentId) {
|
|
48
|
+
throw new Error("issue-token requires ai_agent_id in --data");
|
|
49
|
+
}
|
|
50
|
+
const existing = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/admin/tokens?ai_agent_id=${encodeURIComponent(aiAgentId)}`);
|
|
51
|
+
const activeTokenExists = Array.isArray(existing?.data) && existing.data.some((token) => {
|
|
52
|
+
if (typeof token.revoked_at === "string" && token.revoked_at.length > 0)
|
|
53
|
+
return false;
|
|
54
|
+
if (!token.expires_at)
|
|
55
|
+
return true;
|
|
56
|
+
if (typeof token.expires_at !== "string")
|
|
57
|
+
return false;
|
|
58
|
+
return new Date(token.expires_at).getTime() > Date.now();
|
|
59
|
+
});
|
|
60
|
+
if (activeTokenExists) {
|
|
61
|
+
throw new Error("Agent already has an active API key. Revoke the existing key first.");
|
|
62
|
+
}
|
|
63
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/admin/tokens", payload);
|
|
64
|
+
console.log(JSON.stringify(result, null, 2));
|
|
65
|
+
});
|
|
66
|
+
admin
|
|
67
|
+
.command("revoke-token")
|
|
68
|
+
.argument("<tokenId>")
|
|
69
|
+
.option("--reason <reason>", "Reason for revocation")
|
|
70
|
+
.action(async (tokenId, options) => {
|
|
71
|
+
const payload = options.reason ? { revoked_reason: options.reason } : {};
|
|
72
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/admin/tokens/${tokenId}`, payload);
|
|
73
|
+
console.log(JSON.stringify(result, null, 2));
|
|
74
|
+
});
|
|
75
|
+
admin
|
|
76
|
+
.command("monitoring")
|
|
77
|
+
.option("--window-hours <windowHours>", "Window size in hours")
|
|
78
|
+
.option("--recent-limit <recentLimit>", "Recent records limit")
|
|
79
|
+
.action(async (options) => {
|
|
80
|
+
const params = new URLSearchParams();
|
|
81
|
+
if (options.windowHours)
|
|
82
|
+
params.set("window_hours", options.windowHours);
|
|
83
|
+
if (options.recentLimit)
|
|
84
|
+
params.set("recent_limit", options.recentLimit);
|
|
85
|
+
const query = params.toString();
|
|
86
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/admin/monitoring${query ? `?${query}` : ""}`);
|
|
87
|
+
console.log(JSON.stringify(result, null, 2));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerCustomerCommands = registerCustomerCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerCustomerCommands(parent) {
|
|
6
|
+
const customers = parent.command("customers").description("Manage customers");
|
|
7
|
+
customers
|
|
8
|
+
.command("list")
|
|
9
|
+
.option("--status <status>")
|
|
10
|
+
.option("--search <search>")
|
|
11
|
+
.option("--limit <limit>")
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
const params = new URLSearchParams();
|
|
14
|
+
if (options.status)
|
|
15
|
+
params.set("status", options.status);
|
|
16
|
+
if (options.search)
|
|
17
|
+
params.set("search", options.search);
|
|
18
|
+
if (options.limit)
|
|
19
|
+
params.set("limit", options.limit);
|
|
20
|
+
const query = params.toString();
|
|
21
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/customers${query ? `?${query}` : ""}`);
|
|
22
|
+
console.log(JSON.stringify(result, null, 2));
|
|
23
|
+
});
|
|
24
|
+
customers
|
|
25
|
+
.command("get")
|
|
26
|
+
.argument("<id>")
|
|
27
|
+
.action(async (id) => {
|
|
28
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/customers/${id}`);
|
|
29
|
+
console.log(JSON.stringify(result, null, 2));
|
|
30
|
+
});
|
|
31
|
+
customers
|
|
32
|
+
.command("create")
|
|
33
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
34
|
+
.action(async (options) => {
|
|
35
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/customers", (0, http_1.parsePayload)(options.data));
|
|
36
|
+
console.log(JSON.stringify(result, null, 2));
|
|
37
|
+
});
|
|
38
|
+
customers
|
|
39
|
+
.command("update")
|
|
40
|
+
.argument("<id>")
|
|
41
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
42
|
+
.action(async (id, options) => {
|
|
43
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/customers/${id}`, (0, http_1.parsePayload)(options.data));
|
|
44
|
+
console.log(JSON.stringify(result, null, 2));
|
|
45
|
+
});
|
|
46
|
+
customers
|
|
47
|
+
.command("delete")
|
|
48
|
+
.argument("<id>")
|
|
49
|
+
.action(async (id) => {
|
|
50
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/customers/${id}`);
|
|
51
|
+
console.log(JSON.stringify(result, null, 2));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerDocumentCommands = registerDocumentCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerDocumentCommands(parent) {
|
|
6
|
+
const docs = parent.command("docs").description("Manage documents");
|
|
7
|
+
docs
|
|
8
|
+
.command("list")
|
|
9
|
+
.description("List documents")
|
|
10
|
+
.option("--project-id <projectId>")
|
|
11
|
+
.option("--customer-id <customerId>")
|
|
12
|
+
.option("--prospect-id <prospectId>")
|
|
13
|
+
.option("--limit <limit>")
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
const params = new URLSearchParams();
|
|
16
|
+
if (options.projectId)
|
|
17
|
+
params.set("project_id", options.projectId);
|
|
18
|
+
if (options.customerId)
|
|
19
|
+
params.set("customer_id", options.customerId);
|
|
20
|
+
if (options.prospectId)
|
|
21
|
+
params.set("prospect_id", options.prospectId);
|
|
22
|
+
if (options.limit)
|
|
23
|
+
params.set("limit", options.limit);
|
|
24
|
+
const query = params.toString();
|
|
25
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/documents${query ? `?${query}` : ""}`);
|
|
26
|
+
console.log(JSON.stringify(result, null, 2));
|
|
27
|
+
});
|
|
28
|
+
docs
|
|
29
|
+
.command("get")
|
|
30
|
+
.description("Get document by id")
|
|
31
|
+
.argument("<id>")
|
|
32
|
+
.action(async (id) => {
|
|
33
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/documents/${id}`);
|
|
34
|
+
console.log(JSON.stringify(result, null, 2));
|
|
35
|
+
});
|
|
36
|
+
docs
|
|
37
|
+
.command("create")
|
|
38
|
+
.description("Create document")
|
|
39
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
40
|
+
.action(async (options) => {
|
|
41
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/documents", (0, http_1.parsePayload)(options.data));
|
|
42
|
+
console.log(JSON.stringify(result, null, 2));
|
|
43
|
+
});
|
|
44
|
+
docs
|
|
45
|
+
.command("update")
|
|
46
|
+
.description("Update document")
|
|
47
|
+
.argument("<id>")
|
|
48
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
49
|
+
.action(async (id, options) => {
|
|
50
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/documents/${id}`, (0, http_1.parsePayload)(options.data));
|
|
51
|
+
console.log(JSON.stringify(result, null, 2));
|
|
52
|
+
});
|
|
53
|
+
docs
|
|
54
|
+
.command("delete")
|
|
55
|
+
.description("Delete document")
|
|
56
|
+
.argument("<id>")
|
|
57
|
+
.action(async (id) => {
|
|
58
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/documents/${id}`);
|
|
59
|
+
console.log(JSON.stringify(result, null, 2));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerMeetingCommands = registerMeetingCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerMeetingCommands(parent) {
|
|
6
|
+
const meetings = parent.command("meetings").description("Manage meetings");
|
|
7
|
+
meetings
|
|
8
|
+
.command("list")
|
|
9
|
+
.option("--status <status>")
|
|
10
|
+
.option("--project-id <projectId>")
|
|
11
|
+
.option("--customer-id <customerId>")
|
|
12
|
+
.option("--limit <limit>")
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
const params = new URLSearchParams();
|
|
15
|
+
if (options.status)
|
|
16
|
+
params.set("status", options.status);
|
|
17
|
+
if (options.projectId)
|
|
18
|
+
params.set("project_id", options.projectId);
|
|
19
|
+
if (options.customerId)
|
|
20
|
+
params.set("customer_id", options.customerId);
|
|
21
|
+
if (options.limit)
|
|
22
|
+
params.set("limit", options.limit);
|
|
23
|
+
const query = params.toString();
|
|
24
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/meetings${query ? `?${query}` : ""}`);
|
|
25
|
+
console.log(JSON.stringify(result, null, 2));
|
|
26
|
+
});
|
|
27
|
+
meetings
|
|
28
|
+
.command("get")
|
|
29
|
+
.argument("<id>")
|
|
30
|
+
.action(async (id) => {
|
|
31
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/meetings/${id}`);
|
|
32
|
+
console.log(JSON.stringify(result, null, 2));
|
|
33
|
+
});
|
|
34
|
+
meetings
|
|
35
|
+
.command("create")
|
|
36
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
37
|
+
.action(async (options) => {
|
|
38
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/meetings", (0, http_1.parsePayload)(options.data));
|
|
39
|
+
console.log(JSON.stringify(result, null, 2));
|
|
40
|
+
});
|
|
41
|
+
meetings
|
|
42
|
+
.command("update")
|
|
43
|
+
.argument("<id>")
|
|
44
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
45
|
+
.action(async (id, options) => {
|
|
46
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/meetings/${id}`, (0, http_1.parsePayload)(options.data));
|
|
47
|
+
console.log(JSON.stringify(result, null, 2));
|
|
48
|
+
});
|
|
49
|
+
meetings
|
|
50
|
+
.command("delete")
|
|
51
|
+
.argument("<id>")
|
|
52
|
+
.action(async (id) => {
|
|
53
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/meetings/${id}`);
|
|
54
|
+
console.log(JSON.stringify(result, null, 2));
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerMessageCommands = registerMessageCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerMessageCommands(parent) {
|
|
6
|
+
const messages = parent.command("messages").description("Manage external messages");
|
|
7
|
+
messages.command("list").action(async () => {
|
|
8
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", "/api/agent/messages");
|
|
9
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10
|
+
});
|
|
11
|
+
messages
|
|
12
|
+
.command("create")
|
|
13
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/messages", (0, http_1.parsePayload)(options.data));
|
|
16
|
+
console.log(JSON.stringify(result, null, 2));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerProjectCommands = registerProjectCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerProjectCommands(parent) {
|
|
6
|
+
const projects = parent.command("projects").description("Manage projects");
|
|
7
|
+
projects.command("list").action(async () => {
|
|
8
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", "/api/agent/projects");
|
|
9
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10
|
+
});
|
|
11
|
+
projects
|
|
12
|
+
.command("get")
|
|
13
|
+
.argument("<id>")
|
|
14
|
+
.action(async (id) => {
|
|
15
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/projects/${id}`);
|
|
16
|
+
console.log(JSON.stringify(result, null, 2));
|
|
17
|
+
});
|
|
18
|
+
projects
|
|
19
|
+
.command("create")
|
|
20
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
21
|
+
.action(async (options) => {
|
|
22
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/projects", (0, http_1.parsePayload)(options.data));
|
|
23
|
+
console.log(JSON.stringify(result, null, 2));
|
|
24
|
+
});
|
|
25
|
+
projects
|
|
26
|
+
.command("update")
|
|
27
|
+
.argument("<id>")
|
|
28
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
29
|
+
.action(async (id, options) => {
|
|
30
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/projects/${id}`, (0, http_1.parsePayload)(options.data));
|
|
31
|
+
console.log(JSON.stringify(result, null, 2));
|
|
32
|
+
});
|
|
33
|
+
projects
|
|
34
|
+
.command("delete")
|
|
35
|
+
.argument("<id>")
|
|
36
|
+
.action(async (id) => {
|
|
37
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/projects/${id}`);
|
|
38
|
+
console.log(JSON.stringify(result, null, 2));
|
|
39
|
+
});
|
|
40
|
+
projects
|
|
41
|
+
.command("set-assignees")
|
|
42
|
+
.description("Replace project assignee ids")
|
|
43
|
+
.argument("<id>")
|
|
44
|
+
.requiredOption("--data <json>", "JSON payload with assignee_ids")
|
|
45
|
+
.action(async (id, options) => {
|
|
46
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PUT", `/api/agent/projects/${id}/assignees`, (0, http_1.parsePayload)(options.data));
|
|
47
|
+
console.log(JSON.stringify(result, null, 2));
|
|
48
|
+
});
|
|
49
|
+
projects
|
|
50
|
+
.command("set-agent-assignees")
|
|
51
|
+
.description("Replace project AI agent assignee ids")
|
|
52
|
+
.argument("<id>")
|
|
53
|
+
.requiredOption("--data <json>", "JSON payload with ai_agent_ids")
|
|
54
|
+
.action(async (id, options) => {
|
|
55
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PUT", `/api/agent/projects/${id}/agent-assignees`, (0, http_1.parsePayload)(options.data));
|
|
56
|
+
console.log(JSON.stringify(result, null, 2));
|
|
57
|
+
});
|
|
58
|
+
projects
|
|
59
|
+
.command("set-calendar-color")
|
|
60
|
+
.description("Set or clear project calendar color")
|
|
61
|
+
.argument("<id>")
|
|
62
|
+
.requiredOption("--data <json>", "JSON payload with calendar_color")
|
|
63
|
+
.action(async (id, options) => {
|
|
64
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/projects/${id}/calendar-color`, (0, http_1.parsePayload)(options.data));
|
|
65
|
+
console.log(JSON.stringify(result, null, 2));
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerProspectCommands = registerProspectCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerProspectCommands(parent) {
|
|
6
|
+
const prospects = parent.command("prospects").description("Manage prospects");
|
|
7
|
+
prospects
|
|
8
|
+
.command("list")
|
|
9
|
+
.option("--pipeline-stage <pipelineStage>")
|
|
10
|
+
.option("--is-archived <isArchived>")
|
|
11
|
+
.option("--limit <limit>")
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
const params = new URLSearchParams();
|
|
14
|
+
if (options.pipelineStage)
|
|
15
|
+
params.set("pipeline_stage", options.pipelineStage);
|
|
16
|
+
if (options.isArchived)
|
|
17
|
+
params.set("is_archived", options.isArchived);
|
|
18
|
+
if (options.limit)
|
|
19
|
+
params.set("limit", options.limit);
|
|
20
|
+
const query = params.toString();
|
|
21
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/prospects${query ? `?${query}` : ""}`);
|
|
22
|
+
console.log(JSON.stringify(result, null, 2));
|
|
23
|
+
});
|
|
24
|
+
prospects
|
|
25
|
+
.command("get")
|
|
26
|
+
.argument("<id>")
|
|
27
|
+
.action(async (id) => {
|
|
28
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/prospects/${id}`);
|
|
29
|
+
console.log(JSON.stringify(result, null, 2));
|
|
30
|
+
});
|
|
31
|
+
prospects
|
|
32
|
+
.command("create")
|
|
33
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
34
|
+
.action(async (options) => {
|
|
35
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/prospects", (0, http_1.parsePayload)(options.data));
|
|
36
|
+
console.log(JSON.stringify(result, null, 2));
|
|
37
|
+
});
|
|
38
|
+
prospects
|
|
39
|
+
.command("update")
|
|
40
|
+
.argument("<id>")
|
|
41
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
42
|
+
.action(async (id, options) => {
|
|
43
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/prospects/${id}`, (0, http_1.parsePayload)(options.data));
|
|
44
|
+
console.log(JSON.stringify(result, null, 2));
|
|
45
|
+
});
|
|
46
|
+
prospects
|
|
47
|
+
.command("delete")
|
|
48
|
+
.argument("<id>")
|
|
49
|
+
.action(async (id) => {
|
|
50
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/prospects/${id}`);
|
|
51
|
+
console.log(JSON.stringify(result, null, 2));
|
|
52
|
+
});
|
|
53
|
+
prospects
|
|
54
|
+
.command("convert")
|
|
55
|
+
.description("Convert prospect to customer")
|
|
56
|
+
.argument("<id>")
|
|
57
|
+
.action(async (id) => {
|
|
58
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", `/api/agent/prospects/${id}/convert`);
|
|
59
|
+
console.log(JSON.stringify(result, null, 2));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSprintCommands = registerSprintCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerSprintCommands(parent) {
|
|
6
|
+
const sprints = parent.command("sprints").description("Manage sprints");
|
|
7
|
+
sprints
|
|
8
|
+
.command("list")
|
|
9
|
+
.option("--project-id <projectId>")
|
|
10
|
+
.option("--status <status>")
|
|
11
|
+
.option("--limit <limit>")
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
const params = new URLSearchParams();
|
|
14
|
+
if (options.projectId)
|
|
15
|
+
params.set("project_id", options.projectId);
|
|
16
|
+
if (options.status)
|
|
17
|
+
params.set("status", options.status);
|
|
18
|
+
if (options.limit)
|
|
19
|
+
params.set("limit", options.limit);
|
|
20
|
+
const query = params.toString();
|
|
21
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/sprints${query ? `?${query}` : ""}`);
|
|
22
|
+
console.log(JSON.stringify(result, null, 2));
|
|
23
|
+
});
|
|
24
|
+
sprints
|
|
25
|
+
.command("get")
|
|
26
|
+
.argument("<id>")
|
|
27
|
+
.action(async (id) => {
|
|
28
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/sprints/${id}`);
|
|
29
|
+
console.log(JSON.stringify(result, null, 2));
|
|
30
|
+
});
|
|
31
|
+
sprints
|
|
32
|
+
.command("create")
|
|
33
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
34
|
+
.action(async (options) => {
|
|
35
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/sprints", (0, http_1.parsePayload)(options.data));
|
|
36
|
+
console.log(JSON.stringify(result, null, 2));
|
|
37
|
+
});
|
|
38
|
+
sprints
|
|
39
|
+
.command("update")
|
|
40
|
+
.argument("<id>")
|
|
41
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
42
|
+
.action(async (id, options) => {
|
|
43
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/sprints/${id}`, (0, http_1.parsePayload)(options.data));
|
|
44
|
+
console.log(JSON.stringify(result, null, 2));
|
|
45
|
+
});
|
|
46
|
+
sprints
|
|
47
|
+
.command("delete")
|
|
48
|
+
.argument("<id>")
|
|
49
|
+
.action(async (id) => {
|
|
50
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/sprints/${id}`);
|
|
51
|
+
console.log(JSON.stringify(result, null, 2));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerTaskCommands = registerTaskCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerTaskCommands(parent) {
|
|
6
|
+
const tasks = parent.command("tasks").description("Manage work items");
|
|
7
|
+
tasks
|
|
8
|
+
.command("list")
|
|
9
|
+
.description("List tasks")
|
|
10
|
+
.option("--project-id <projectId>")
|
|
11
|
+
.option("--status <status>")
|
|
12
|
+
.option("--limit <limit>")
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
const params = new URLSearchParams();
|
|
15
|
+
if (options.projectId)
|
|
16
|
+
params.set("project_id", options.projectId);
|
|
17
|
+
if (options.status)
|
|
18
|
+
params.set("status", options.status);
|
|
19
|
+
if (options.limit)
|
|
20
|
+
params.set("limit", options.limit);
|
|
21
|
+
const query = params.toString();
|
|
22
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/tasks${query ? `?${query}` : ""}`);
|
|
23
|
+
console.log(JSON.stringify(result, null, 2));
|
|
24
|
+
});
|
|
25
|
+
tasks
|
|
26
|
+
.command("get")
|
|
27
|
+
.description("Get task by id")
|
|
28
|
+
.argument("<id>")
|
|
29
|
+
.action(async (id) => {
|
|
30
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/tasks/${id}`);
|
|
31
|
+
console.log(JSON.stringify(result, null, 2));
|
|
32
|
+
});
|
|
33
|
+
tasks
|
|
34
|
+
.command("create")
|
|
35
|
+
.description("Create task")
|
|
36
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
37
|
+
.action(async (options) => {
|
|
38
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/tasks", (0, http_1.parsePayload)(options.data));
|
|
39
|
+
console.log(JSON.stringify(result, null, 2));
|
|
40
|
+
});
|
|
41
|
+
tasks
|
|
42
|
+
.command("update")
|
|
43
|
+
.description("Update task")
|
|
44
|
+
.argument("<id>")
|
|
45
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
46
|
+
.action(async (id, options) => {
|
|
47
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/tasks/${id}`, (0, http_1.parsePayload)(options.data));
|
|
48
|
+
console.log(JSON.stringify(result, null, 2));
|
|
49
|
+
});
|
|
50
|
+
tasks
|
|
51
|
+
.command("delete")
|
|
52
|
+
.description("Delete task")
|
|
53
|
+
.argument("<id>")
|
|
54
|
+
.action(async (id) => {
|
|
55
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/tasks/${id}`);
|
|
56
|
+
console.log(JSON.stringify(result, null, 2));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerTeamCommands = registerTeamCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerTeamCommands(parent) {
|
|
6
|
+
const team = parent.command("team").description("Manage team members and invites");
|
|
7
|
+
team
|
|
8
|
+
.command("invite")
|
|
9
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
10
|
+
.action(async (options) => {
|
|
11
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/team/invite", (0, http_1.parsePayload)(options.data));
|
|
12
|
+
console.log(JSON.stringify(result, null, 2));
|
|
13
|
+
});
|
|
14
|
+
team
|
|
15
|
+
.command("update-role")
|
|
16
|
+
.argument("<id>")
|
|
17
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
18
|
+
.action(async (id, options) => {
|
|
19
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/team/${id}`, (0, http_1.parsePayload)(options.data));
|
|
20
|
+
console.log(JSON.stringify(result, null, 2));
|
|
21
|
+
});
|
|
22
|
+
team
|
|
23
|
+
.command("remove")
|
|
24
|
+
.argument("<id>")
|
|
25
|
+
.action(async (id) => {
|
|
26
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/team/${id}`);
|
|
27
|
+
console.log(JSON.stringify(result, null, 2));
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerTimelineCommands = registerTimelineCommands;
|
|
4
|
+
const http_1 = require("../http");
|
|
5
|
+
function registerTimelineCommands(parent) {
|
|
6
|
+
const timeline = parent.command("timeline").description("Manage timeline entries");
|
|
7
|
+
timeline
|
|
8
|
+
.command("list")
|
|
9
|
+
.option("--project-id <projectId>")
|
|
10
|
+
.option("--customer-id <customerId>")
|
|
11
|
+
.option("--limit <limit>")
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
const params = new URLSearchParams();
|
|
14
|
+
if (options.projectId)
|
|
15
|
+
params.set("project_id", options.projectId);
|
|
16
|
+
if (options.customerId)
|
|
17
|
+
params.set("customer_id", options.customerId);
|
|
18
|
+
if (options.limit)
|
|
19
|
+
params.set("limit", options.limit);
|
|
20
|
+
const query = params.toString();
|
|
21
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/timeline-entries${query ? `?${query}` : ""}`);
|
|
22
|
+
console.log(JSON.stringify(result, null, 2));
|
|
23
|
+
});
|
|
24
|
+
timeline
|
|
25
|
+
.command("get")
|
|
26
|
+
.argument("<id>")
|
|
27
|
+
.action(async (id) => {
|
|
28
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "GET", `/api/agent/timeline-entries/${id}`);
|
|
29
|
+
console.log(JSON.stringify(result, null, 2));
|
|
30
|
+
});
|
|
31
|
+
timeline
|
|
32
|
+
.command("create")
|
|
33
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
34
|
+
.action(async (options) => {
|
|
35
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "POST", "/api/agent/timeline-entries", (0, http_1.parsePayload)(options.data));
|
|
36
|
+
console.log(JSON.stringify(result, null, 2));
|
|
37
|
+
});
|
|
38
|
+
timeline
|
|
39
|
+
.command("update")
|
|
40
|
+
.argument("<id>")
|
|
41
|
+
.requiredOption("--data <json>", "JSON payload")
|
|
42
|
+
.action(async (id, options) => {
|
|
43
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "PATCH", `/api/agent/timeline-entries/${id}`, (0, http_1.parsePayload)(options.data));
|
|
44
|
+
console.log(JSON.stringify(result, null, 2));
|
|
45
|
+
});
|
|
46
|
+
timeline
|
|
47
|
+
.command("delete")
|
|
48
|
+
.argument("<id>")
|
|
49
|
+
.action(async (id) => {
|
|
50
|
+
const result = await (0, http_1.apiRequest)((0, http_1.resolveConfig)(), "DELETE", `/api/agent/timeline-entries/${id}`);
|
|
51
|
+
console.log(JSON.stringify(result, null, 2));
|
|
52
|
+
});
|
|
53
|
+
}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveConfig = resolveConfig;
|
|
4
|
+
exports.parsePayload = parsePayload;
|
|
5
|
+
exports.apiRequest = apiRequest;
|
|
6
|
+
function resolveConfig() {
|
|
7
|
+
const baseUrl = process.env.HECHURA_API_BASE_URL?.replace(/\/+$/, "") ?? "https://noreaster.vercel.app";
|
|
8
|
+
const token = process.env.HECHURA_AGENT_TOKEN ?? "";
|
|
9
|
+
if (!token) {
|
|
10
|
+
throw new Error("Missing HECHURA_AGENT_TOKEN environment variable");
|
|
11
|
+
}
|
|
12
|
+
return { baseUrl, token };
|
|
13
|
+
}
|
|
14
|
+
function parseJson(value) {
|
|
15
|
+
try {
|
|
16
|
+
const parsed = JSON.parse(value);
|
|
17
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
18
|
+
throw new Error("JSON payload must be an object");
|
|
19
|
+
}
|
|
20
|
+
return parsed;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
const message = error instanceof Error ? error.message : "Invalid JSON payload";
|
|
24
|
+
throw new Error(`Invalid JSON payload: ${message}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function parsePayload(data) {
|
|
28
|
+
if (!data)
|
|
29
|
+
return {};
|
|
30
|
+
return parseJson(data);
|
|
31
|
+
}
|
|
32
|
+
async function apiRequest(config, method, path, payload) {
|
|
33
|
+
const response = await fetch(`${config.baseUrl}${path}`, {
|
|
34
|
+
method,
|
|
35
|
+
headers: {
|
|
36
|
+
"content-type": "application/json",
|
|
37
|
+
authorization: `Bearer ${config.token}`,
|
|
38
|
+
},
|
|
39
|
+
body: payload ? JSON.stringify(payload) : undefined,
|
|
40
|
+
});
|
|
41
|
+
const text = await response.text();
|
|
42
|
+
const parsed = text ? JSON.parse(text) : {};
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
const code = typeof parsed?.code === "string" ? parsed.code : null;
|
|
45
|
+
const baseMessage = parsed?.error || `Request failed with status ${response.status}`;
|
|
46
|
+
const message = code ? `${baseMessage} (${code})` : baseMessage;
|
|
47
|
+
throw new Error(message);
|
|
48
|
+
}
|
|
49
|
+
return parsed;
|
|
50
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const tasks_1 = require("./commands/tasks");
|
|
6
|
+
const docs_1 = require("./commands/docs");
|
|
7
|
+
const projects_1 = require("./commands/projects");
|
|
8
|
+
const team_1 = require("./commands/team");
|
|
9
|
+
const messages_1 = require("./commands/messages");
|
|
10
|
+
const admin_1 = require("./commands/admin");
|
|
11
|
+
const sprints_1 = require("./commands/sprints");
|
|
12
|
+
const customers_1 = require("./commands/customers");
|
|
13
|
+
const prospects_1 = require("./commands/prospects");
|
|
14
|
+
const meetings_1 = require("./commands/meetings");
|
|
15
|
+
const timeline_1 = require("./commands/timeline");
|
|
16
|
+
async function main() {
|
|
17
|
+
const program = new commander_1.Command()
|
|
18
|
+
.name("noreaster")
|
|
19
|
+
.description("CLI for admin-equivalent AI agent API access")
|
|
20
|
+
.version("0.1.0");
|
|
21
|
+
(0, tasks_1.registerTaskCommands)(program);
|
|
22
|
+
(0, docs_1.registerDocumentCommands)(program);
|
|
23
|
+
(0, projects_1.registerProjectCommands)(program);
|
|
24
|
+
(0, team_1.registerTeamCommands)(program);
|
|
25
|
+
(0, messages_1.registerMessageCommands)(program);
|
|
26
|
+
(0, sprints_1.registerSprintCommands)(program);
|
|
27
|
+
(0, customers_1.registerCustomerCommands)(program);
|
|
28
|
+
(0, prospects_1.registerProspectCommands)(program);
|
|
29
|
+
(0, meetings_1.registerMeetingCommands)(program);
|
|
30
|
+
(0, timeline_1.registerTimelineCommands)(program);
|
|
31
|
+
(0, admin_1.registerAdminCommands)(program);
|
|
32
|
+
await program.parseAsync(process.argv);
|
|
33
|
+
}
|
|
34
|
+
main().catch((error) => {
|
|
35
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
36
|
+
console.error(message);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hechura/noreaster-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI for Hechura Noreaster agent API access",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/reaganmaconi/hechura_manager.git",
|
|
8
|
+
"directory": "packages/noreaster-cli"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"noreaster": "./dist/index.js",
|
|
15
|
+
"hechura-agent": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "npx tsc -p tsconfig.json",
|
|
22
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
23
|
+
"prepack": "npm run clean && npm run build",
|
|
24
|
+
"pack:dry-run": "npm pack --dry-run"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"commander": "^14.0.3"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"typescript": "^5.7.3"
|
|
34
|
+
}
|
|
35
|
+
}
|