@krl-grn/wande 0.1.0 → 0.1.1
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 +2 -0
- package/dist/index.js +38 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,6 +27,8 @@ wande whoami --json
|
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
29
|
wande tasks:list --limit 20 --json
|
|
30
|
+
wande tasks:list --project-id <PROJECT_ID> --json
|
|
31
|
+
wande tasks:list --project "Project Name" --json
|
|
30
32
|
wande tasks:create --title "Task from CLI" --status new --json
|
|
31
33
|
wande tasks:status --id <TASK_ID> --status done --json
|
|
32
34
|
```
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,31 @@ async function getRuntime() {
|
|
|
17
17
|
client: new BotApiClient(baseUrl),
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
+
async function resolveProjectIdByTitle(client, token, projectTitle) {
|
|
21
|
+
const normalized = projectTitle.trim().toLowerCase();
|
|
22
|
+
if (!normalized) {
|
|
23
|
+
throw new Error("Project title cannot be empty");
|
|
24
|
+
}
|
|
25
|
+
const response = await client.request("/bot/projects?limit=200", {
|
|
26
|
+
token,
|
|
27
|
+
});
|
|
28
|
+
const projects = response.data ?? [];
|
|
29
|
+
const exact = projects.filter((project) => project.title.trim().toLowerCase() === normalized);
|
|
30
|
+
if (exact.length === 1) {
|
|
31
|
+
return exact[0]._id;
|
|
32
|
+
}
|
|
33
|
+
if (exact.length > 1) {
|
|
34
|
+
throw new Error(`Multiple projects found with title \"${projectTitle}\". Use --project-id instead.`);
|
|
35
|
+
}
|
|
36
|
+
const partial = projects.filter((project) => project.title.trim().toLowerCase().includes(normalized));
|
|
37
|
+
if (partial.length === 1) {
|
|
38
|
+
return partial[0]._id;
|
|
39
|
+
}
|
|
40
|
+
if (partial.length > 1) {
|
|
41
|
+
throw new Error(`Multiple projects match \"${projectTitle}\". Use --project-id instead.`);
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`Project not found: ${projectTitle}`);
|
|
44
|
+
}
|
|
20
45
|
async function performLogin(token, explicitUrl) {
|
|
21
46
|
const current = await loadConfig();
|
|
22
47
|
const baseUrl = await resolveBotBaseUrl(explicitUrl, current.baseUrl);
|
|
@@ -80,6 +105,8 @@ program.command("auth:whoami").description("Legacy alias for whoami").option("--
|
|
|
80
105
|
program
|
|
81
106
|
.command("tasks:list")
|
|
82
107
|
.option("--status <status>")
|
|
108
|
+
.option("--project-id <projectId>")
|
|
109
|
+
.option("--project <projectTitle>")
|
|
83
110
|
.option("--limit <limit>")
|
|
84
111
|
.option("--json", "JSON output", false)
|
|
85
112
|
.action(async (opts) => {
|
|
@@ -87,6 +114,17 @@ program
|
|
|
87
114
|
const params = new URLSearchParams();
|
|
88
115
|
if (opts.status)
|
|
89
116
|
params.set("status", String(opts.status));
|
|
117
|
+
const providedProjectFilters = Number(Boolean(opts.projectId)) + Number(Boolean(opts.project));
|
|
118
|
+
if (providedProjectFilters > 1) {
|
|
119
|
+
throw new Error("Use only one of --project-id or --project");
|
|
120
|
+
}
|
|
121
|
+
if (opts.projectId) {
|
|
122
|
+
params.set("project_id", String(opts.projectId));
|
|
123
|
+
}
|
|
124
|
+
else if (opts.project) {
|
|
125
|
+
const resolvedProjectId = await resolveProjectIdByTitle(client, token, opts.project);
|
|
126
|
+
params.set("project_id", resolvedProjectId);
|
|
127
|
+
}
|
|
90
128
|
if (opts.limit)
|
|
91
129
|
params.set("limit", String(opts.limit));
|
|
92
130
|
const suffix = params.toString() ? `?${params.toString()}` : "";
|