@h-rig/task-cli-plugin 0.0.6-alpha.156 → 0.0.6-alpha.158
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/dist/src/plugin.js +95 -6
- package/package.json +3 -3
package/dist/src/plugin.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var __require = import.meta.require;
|
|
3
|
-
|
|
4
2
|
// packages/task-cli-plugin/src/plugin.ts
|
|
5
3
|
import { definePlugin } from "@rig/core/config";
|
|
4
|
+
import { defineCapability } from "@rig/core/capability";
|
|
5
|
+
import { requireCapabilityForRoot } from "@rig/core/capability-loaders";
|
|
6
|
+
import { TASK_IO_SERVICE_CAPABILITY } from "@rig/contracts";
|
|
6
7
|
var STANDARD_TASK_CLI_PLUGIN_NAME = "@rig/task-cli-plugin";
|
|
7
8
|
var STANDARD_TASK_CLI_ID = "@rig/task-cli-plugin:task";
|
|
8
9
|
function takeOption(args, flag) {
|
|
@@ -34,16 +35,105 @@ function parseTaskFilters(args) {
|
|
|
34
35
|
if (stateValue !== undefined && stateValue !== "open" && stateValue !== "closed") {
|
|
35
36
|
throw new Error(`Invalid --state value: ${state.value}`);
|
|
36
37
|
}
|
|
38
|
+
const limitValue = parsePositiveLimit(limit.value);
|
|
37
39
|
return {
|
|
38
40
|
filters: {
|
|
39
41
|
...assignee.value ? { assignee: assignee.value } : {},
|
|
40
42
|
...stateValue ? { state: stateValue } : {},
|
|
41
|
-
...
|
|
43
|
+
...limitValue !== undefined ? { limit: limitValue } : {},
|
|
42
44
|
...search.value?.trim() ? { search: search.value.trim() } : {}
|
|
43
45
|
},
|
|
44
46
|
rest: search.rest
|
|
45
47
|
};
|
|
46
48
|
}
|
|
49
|
+
var CLOSED_STATUSES = {
|
|
50
|
+
closed: true,
|
|
51
|
+
completed: true,
|
|
52
|
+
complete: true,
|
|
53
|
+
done: true,
|
|
54
|
+
cancelled: true,
|
|
55
|
+
canceled: true,
|
|
56
|
+
merged: true,
|
|
57
|
+
resolved: true
|
|
58
|
+
};
|
|
59
|
+
function isRecord(value) {
|
|
60
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
61
|
+
}
|
|
62
|
+
function readTaskStatus(task) {
|
|
63
|
+
return typeof task.status === "string" ? task.status.trim().toLowerCase() : "";
|
|
64
|
+
}
|
|
65
|
+
function currentLogin(env = process.env) {
|
|
66
|
+
for (const key of ["RIG_GITHUB_LOGIN", "GITHUB_ACTOR", "GH_USER", "USER", "USERNAME"]) {
|
|
67
|
+
const value = env[key]?.trim();
|
|
68
|
+
if (value)
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
function resolveAssignee(value, env = process.env) {
|
|
74
|
+
const trimmed = value?.trim();
|
|
75
|
+
if (!trimmed)
|
|
76
|
+
return;
|
|
77
|
+
const lowered = trimmed.toLowerCase();
|
|
78
|
+
if (lowered === "me" || lowered === "@me")
|
|
79
|
+
return currentLogin(env) ?? "@me";
|
|
80
|
+
return trimmed.startsWith("@") ? trimmed.slice(1) : trimmed;
|
|
81
|
+
}
|
|
82
|
+
function taskMatchesState(task, state) {
|
|
83
|
+
if (!state)
|
|
84
|
+
return true;
|
|
85
|
+
const closed = CLOSED_STATUSES[readTaskStatus(task)] === true;
|
|
86
|
+
return state === "closed" ? closed : !closed;
|
|
87
|
+
}
|
|
88
|
+
function taskMatchesSearch(task, search) {
|
|
89
|
+
const needle = search?.trim().toLowerCase();
|
|
90
|
+
if (!needle)
|
|
91
|
+
return true;
|
|
92
|
+
const record = task;
|
|
93
|
+
const title = typeof task.title === "string" ? task.title : "";
|
|
94
|
+
const body = typeof record.body === "string" ? record.body : "";
|
|
95
|
+
const description = typeof record.description === "string" ? record.description : "";
|
|
96
|
+
return `${task.id}
|
|
97
|
+
${title}
|
|
98
|
+
${body}
|
|
99
|
+
${description}`.toLowerCase().includes(needle);
|
|
100
|
+
}
|
|
101
|
+
function collectAssigneeLogins(value) {
|
|
102
|
+
if (typeof value === "string")
|
|
103
|
+
return [value];
|
|
104
|
+
if (Array.isArray(value))
|
|
105
|
+
return value.flatMap((entry) => collectAssigneeLogins(entry));
|
|
106
|
+
if (isRecord(value))
|
|
107
|
+
return [value.login, value.username, value.name, value.id].flatMap((entry) => collectAssigneeLogins(entry));
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
function taskAssignees(task) {
|
|
111
|
+
const record = task;
|
|
112
|
+
const raw = isRecord(record.raw) ? record.raw : null;
|
|
113
|
+
return [
|
|
114
|
+
record.assignee,
|
|
115
|
+
record.assignees,
|
|
116
|
+
record.assignedTo,
|
|
117
|
+
record.owner,
|
|
118
|
+
raw?.assignee,
|
|
119
|
+
raw?.assignees,
|
|
120
|
+
raw?.assignedTo,
|
|
121
|
+
raw?.owner
|
|
122
|
+
].flatMap((value) => collectAssigneeLogins(value));
|
|
123
|
+
}
|
|
124
|
+
function taskMatchesAssignee(task, assignee) {
|
|
125
|
+
if (!assignee)
|
|
126
|
+
return true;
|
|
127
|
+
const needle = assignee.startsWith("@") ? assignee.slice(1) : assignee;
|
|
128
|
+
return taskAssignees(task).some((login) => {
|
|
129
|
+
const normalized = login.startsWith("@") ? login.slice(1) : login;
|
|
130
|
+
return normalized.localeCompare(needle, undefined, { sensitivity: "accent" }) === 0;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function applyFilters(tasks, filters = {}) {
|
|
134
|
+
const filtered = tasks.filter((task) => taskMatchesAssignee(task, resolveAssignee(filters.assignee))).filter((task) => taskMatchesState(task, filters.state)).filter((task) => taskMatchesSearch(task, filters.search));
|
|
135
|
+
return filters.limit === undefined ? filtered : filtered.slice(0, filters.limit);
|
|
136
|
+
}
|
|
47
137
|
function taskListTitle(task) {
|
|
48
138
|
const title = typeof task.title === "string" && task.title.trim().length > 0 ? task.title.trim() : "(untitled)";
|
|
49
139
|
const status = typeof task.status === "string" && task.status.trim().length > 0 ? ` [${task.status.trim()}]` : "";
|
|
@@ -71,9 +161,8 @@ function createStandardTaskCliCommand() {
|
|
|
71
161
|
if (parsed.rest.length > 0) {
|
|
72
162
|
throw new Error(`Unsupported arguments for rig task list: ${parsed.rest.join(" ")}`);
|
|
73
163
|
}
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
const tasks = applyFilters(await listTasks(context.projectRoot), parsed.filters);
|
|
164
|
+
const taskIo = await requireCapabilityForRoot(context.projectRoot, defineCapability(TASK_IO_SERVICE_CAPABILITY), "No task-sources plugin provides task IO for this project root.");
|
|
165
|
+
const tasks = applyFilters(await taskIo.listTasks(context.projectRoot), parsed.filters);
|
|
77
166
|
if (context.outputMode === "text") {
|
|
78
167
|
if (tasks.length === 0) {
|
|
79
168
|
console.log("No tasks found.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-rig/task-cli-plugin",
|
|
3
|
-
"version": "0.0.6-alpha.
|
|
3
|
+
"version": "0.0.6-alpha.158",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Standard Rig task CLI plugin boundary backed by the Rig client runtime.",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"bun": ">=1.3.11"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@rig/
|
|
26
|
-
"@rig/
|
|
25
|
+
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.158",
|
|
26
|
+
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.158"
|
|
27
27
|
}
|
|
28
28
|
}
|