@coralai/sps-cli 0.6.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/dist/commands/cardAdd.d.ts +2 -0
- package/dist/commands/cardAdd.d.ts.map +1 -0
- package/dist/commands/cardAdd.js +65 -0
- package/dist/commands/cardAdd.js.map +1 -0
- package/dist/commands/doctor.d.ts +9 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +264 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/monitorTick.d.ts +2 -0
- package/dist/commands/monitorTick.d.ts.map +1 -0
- package/dist/commands/monitorTick.js +47 -0
- package/dist/commands/monitorTick.js.map +1 -0
- package/dist/commands/pipelineTick.d.ts +2 -0
- package/dist/commands/pipelineTick.d.ts.map +1 -0
- package/dist/commands/pipelineTick.js +44 -0
- package/dist/commands/pipelineTick.js.map +1 -0
- package/dist/commands/pmCommand.d.ts +2 -0
- package/dist/commands/pmCommand.d.ts.map +1 -0
- package/dist/commands/pmCommand.js +159 -0
- package/dist/commands/pmCommand.js.map +1 -0
- package/dist/commands/projectInit.d.ts +2 -0
- package/dist/commands/projectInit.d.ts.map +1 -0
- package/dist/commands/projectInit.js +75 -0
- package/dist/commands/projectInit.js.map +1 -0
- package/dist/commands/qaTick.d.ts +2 -0
- package/dist/commands/qaTick.d.ts.map +1 -0
- package/dist/commands/qaTick.js +43 -0
- package/dist/commands/qaTick.js.map +1 -0
- package/dist/commands/schedulerTick.d.ts +2 -0
- package/dist/commands/schedulerTick.d.ts.map +1 -0
- package/dist/commands/schedulerTick.js +45 -0
- package/dist/commands/schedulerTick.js.map +1 -0
- package/dist/commands/tick.d.ts +14 -0
- package/dist/commands/tick.d.ts.map +1 -0
- package/dist/commands/tick.js +251 -0
- package/dist/commands/tick.js.map +1 -0
- package/dist/commands/workerLaunch.d.ts +2 -0
- package/dist/commands/workerLaunch.d.ts.map +1 -0
- package/dist/commands/workerLaunch.js +56 -0
- package/dist/commands/workerLaunch.js.map +1 -0
- package/dist/core/config.d.ts +38 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +131 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context.d.ts +23 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +28 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/lock.d.ts +14 -0
- package/dist/core/lock.d.ts.map +1 -0
- package/dist/core/lock.js +65 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/logger.d.ts +24 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +62 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/paths.d.ts +27 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +29 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/queue.d.ts +14 -0
- package/dist/core/queue.d.ts.map +1 -0
- package/dist/core/queue.js +38 -0
- package/dist/core/queue.js.map +1 -0
- package/dist/core/state.d.ts +32 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +52 -0
- package/dist/core/state.js.map +1 -0
- package/dist/engines/CloseoutEngine.d.ts +60 -0
- package/dist/engines/CloseoutEngine.d.ts.map +1 -0
- package/dist/engines/CloseoutEngine.js +596 -0
- package/dist/engines/CloseoutEngine.js.map +1 -0
- package/dist/engines/ExecutionEngine.d.ts +65 -0
- package/dist/engines/ExecutionEngine.d.ts.map +1 -0
- package/dist/engines/ExecutionEngine.js +603 -0
- package/dist/engines/ExecutionEngine.js.map +1 -0
- package/dist/engines/MonitorEngine.d.ts +39 -0
- package/dist/engines/MonitorEngine.d.ts.map +1 -0
- package/dist/engines/MonitorEngine.js +473 -0
- package/dist/engines/MonitorEngine.js.map +1 -0
- package/dist/engines/SchedulerEngine.d.ts +24 -0
- package/dist/engines/SchedulerEngine.d.ts.map +1 -0
- package/dist/engines/SchedulerEngine.js +195 -0
- package/dist/engines/SchedulerEngine.js.map +1 -0
- package/dist/interfaces/HookProvider.d.ts +9 -0
- package/dist/interfaces/HookProvider.d.ts.map +1 -0
- package/dist/interfaces/HookProvider.js +2 -0
- package/dist/interfaces/HookProvider.js.map +1 -0
- package/dist/interfaces/Notifier.d.ts +11 -0
- package/dist/interfaces/Notifier.d.ts.map +1 -0
- package/dist/interfaces/Notifier.js +2 -0
- package/dist/interfaces/Notifier.js.map +1 -0
- package/dist/interfaces/RepoBackend.d.ts +23 -0
- package/dist/interfaces/RepoBackend.d.ts.map +1 -0
- package/dist/interfaces/RepoBackend.js +2 -0
- package/dist/interfaces/RepoBackend.js.map +1 -0
- package/dist/interfaces/TaskBackend.d.ts +24 -0
- package/dist/interfaces/TaskBackend.d.ts.map +1 -0
- package/dist/interfaces/TaskBackend.js +2 -0
- package/dist/interfaces/TaskBackend.js.map +1 -0
- package/dist/interfaces/WorkerProvider.d.ts +23 -0
- package/dist/interfaces/WorkerProvider.d.ts.map +1 -0
- package/dist/interfaces/WorkerProvider.js +2 -0
- package/dist/interfaces/WorkerProvider.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +226 -0
- package/dist/main.js.map +1 -0
- package/dist/models/types.d.ts +68 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +2 -0
- package/dist/models/types.js.map +1 -0
- package/dist/providers/ClaudeWorkerProvider.d.ts +84 -0
- package/dist/providers/ClaudeWorkerProvider.d.ts.map +1 -0
- package/dist/providers/ClaudeWorkerProvider.js +293 -0
- package/dist/providers/ClaudeWorkerProvider.js.map +1 -0
- package/dist/providers/CodexWorkerProvider.d.ts +50 -0
- package/dist/providers/CodexWorkerProvider.d.ts.map +1 -0
- package/dist/providers/CodexWorkerProvider.js +275 -0
- package/dist/providers/CodexWorkerProvider.js.map +1 -0
- package/dist/providers/GitLabRepoBackend.d.ts +42 -0
- package/dist/providers/GitLabRepoBackend.d.ts.map +1 -0
- package/dist/providers/GitLabRepoBackend.js +280 -0
- package/dist/providers/GitLabRepoBackend.js.map +1 -0
- package/dist/providers/MarkdownTaskBackend.d.ts +88 -0
- package/dist/providers/MarkdownTaskBackend.d.ts.map +1 -0
- package/dist/providers/MarkdownTaskBackend.js +414 -0
- package/dist/providers/MarkdownTaskBackend.js.map +1 -0
- package/dist/providers/MatrixNotifier.d.ts +30 -0
- package/dist/providers/MatrixNotifier.d.ts.map +1 -0
- package/dist/providers/MatrixNotifier.js +82 -0
- package/dist/providers/MatrixNotifier.js.map +1 -0
- package/dist/providers/PlaneTaskBackend.d.ts +86 -0
- package/dist/providers/PlaneTaskBackend.d.ts.map +1 -0
- package/dist/providers/PlaneTaskBackend.js +409 -0
- package/dist/providers/PlaneTaskBackend.js.map +1 -0
- package/dist/providers/TrelloTaskBackend.d.ts +53 -0
- package/dist/providers/TrelloTaskBackend.d.ts.map +1 -0
- package/dist/providers/TrelloTaskBackend.js +300 -0
- package/dist/providers/TrelloTaskBackend.js.map +1 -0
- package/dist/providers/registry.d.ts +10 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +29 -0
- package/dist/providers/registry.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { ProjectConfig } from '../core/config.js';
|
|
2
|
+
import type { TaskBackend } from '../interfaces/TaskBackend.js';
|
|
3
|
+
import type { Card, CardState } from '../models/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* TaskBackend implementation for Plane (plane.so / self-hosted).
|
|
6
|
+
*
|
|
7
|
+
* Uses Node.js built-in fetch to communicate with the Plane REST API v1.
|
|
8
|
+
* Local pm_meta JSON files provide the metadata / claim layer.
|
|
9
|
+
*/
|
|
10
|
+
export declare class PlaneTaskBackend implements TaskBackend {
|
|
11
|
+
private readonly apiUrl;
|
|
12
|
+
private readonly apiKey;
|
|
13
|
+
private readonly workspaceSlug;
|
|
14
|
+
private readonly projectId;
|
|
15
|
+
private readonly projectName;
|
|
16
|
+
private readonly pmMetaDir;
|
|
17
|
+
/** Map CardState → Plane state UUID */
|
|
18
|
+
private readonly stateMap;
|
|
19
|
+
/** Reverse map: Plane state UUID → CardState */
|
|
20
|
+
private readonly reverseStateMap;
|
|
21
|
+
/** Cache: label name → label UUID (populated lazily) */
|
|
22
|
+
private labelCache;
|
|
23
|
+
constructor(config: ProjectConfig);
|
|
24
|
+
/** Base URL for project-scoped endpoints. */
|
|
25
|
+
private get baseUrl();
|
|
26
|
+
/** Standard headers for every Plane request. */
|
|
27
|
+
private get headers();
|
|
28
|
+
/**
|
|
29
|
+
* Generic Plane API request wrapper.
|
|
30
|
+
* Throws on non-2xx responses with a descriptive message.
|
|
31
|
+
*/
|
|
32
|
+
private request;
|
|
33
|
+
/**
|
|
34
|
+
* Convert a Plane issue to a Card.
|
|
35
|
+
* Labels may come as objects ({id, name}) or bare UUID strings.
|
|
36
|
+
* When they are UUIDs, resolve to names via the label cache.
|
|
37
|
+
*/
|
|
38
|
+
private resolveIssueToCard;
|
|
39
|
+
/**
|
|
40
|
+
* Reverse lookup: label UUID → name.
|
|
41
|
+
*/
|
|
42
|
+
private reverseLabelName;
|
|
43
|
+
bootstrap(): Promise<void>;
|
|
44
|
+
listByState(state: CardState): Promise<Card[]>;
|
|
45
|
+
getBySeq(seq: string): Promise<Card | null>;
|
|
46
|
+
move(seq: string, targetState: CardState): Promise<void>;
|
|
47
|
+
addLabel(seq: string, label: string): Promise<void>;
|
|
48
|
+
removeLabel(seq: string, label: string): Promise<void>;
|
|
49
|
+
claim(seq: string, workerSlot: string): Promise<void>;
|
|
50
|
+
releaseClaim(seq: string): Promise<void>;
|
|
51
|
+
comment(seq: string, text: string): Promise<void>;
|
|
52
|
+
create(name: string, desc: string, state: CardState): Promise<Card>;
|
|
53
|
+
checklistCreate(seq: string, items: string[]): Promise<void>;
|
|
54
|
+
checklistList(seq: string): Promise<{
|
|
55
|
+
id: string;
|
|
56
|
+
text: string;
|
|
57
|
+
checked: boolean;
|
|
58
|
+
}[]>;
|
|
59
|
+
checklistCheck(seq: string, itemId: string): Promise<void>;
|
|
60
|
+
checklistUncheck(seq: string, itemId: string): Promise<void>;
|
|
61
|
+
private updateChecklistItem;
|
|
62
|
+
metaRead(seq: string): Promise<Record<string, unknown>>;
|
|
63
|
+
metaWrite(seq: string, data: Record<string, unknown>): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Resolve a sequence ID to a full Plane issue object.
|
|
66
|
+
* Throws if the issue cannot be found.
|
|
67
|
+
*/
|
|
68
|
+
private resolveIssue;
|
|
69
|
+
/**
|
|
70
|
+
* Get current label UUIDs on an issue.
|
|
71
|
+
*/
|
|
72
|
+
private getIssueLabelIds;
|
|
73
|
+
/**
|
|
74
|
+
* Find or create a project label by name, returning its UUID.
|
|
75
|
+
*/
|
|
76
|
+
private ensureLabel;
|
|
77
|
+
/**
|
|
78
|
+
* Find label UUID by name. Returns null if not found.
|
|
79
|
+
*/
|
|
80
|
+
private findLabelId;
|
|
81
|
+
/**
|
|
82
|
+
* Populate label name→id cache from Plane API.
|
|
83
|
+
*/
|
|
84
|
+
private refreshLabelCache;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=PlaneTaskBackend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaneTaskBackend.d.ts","sourceRoot":"","sources":["../../src/providers/PlaneTaskBackend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
const ALL_STATES = ['Planning', 'Backlog', 'Todo', 'Inprogress', 'QA', 'Done'];
|
|
4
|
+
/**
|
|
5
|
+
* TaskBackend implementation for Plane (plane.so / self-hosted).
|
|
6
|
+
*
|
|
7
|
+
* Uses Node.js built-in fetch to communicate with the Plane REST API v1.
|
|
8
|
+
* Local pm_meta JSON files provide the metadata / claim layer.
|
|
9
|
+
*/
|
|
10
|
+
export class PlaneTaskBackend {
|
|
11
|
+
apiUrl;
|
|
12
|
+
apiKey;
|
|
13
|
+
workspaceSlug;
|
|
14
|
+
projectId;
|
|
15
|
+
projectName;
|
|
16
|
+
pmMetaDir;
|
|
17
|
+
/** Map CardState → Plane state UUID */
|
|
18
|
+
stateMap;
|
|
19
|
+
/** Reverse map: Plane state UUID → CardState */
|
|
20
|
+
reverseStateMap;
|
|
21
|
+
/** Cache: label name → label UUID (populated lazily) */
|
|
22
|
+
labelCache = null;
|
|
23
|
+
constructor(config) {
|
|
24
|
+
const raw = config.raw;
|
|
25
|
+
this.apiUrl = required(raw, 'PLANE_API_URL');
|
|
26
|
+
this.apiKey = required(raw, 'PLANE_API_KEY');
|
|
27
|
+
this.workspaceSlug = required(raw, 'PLANE_WORKSPACE_SLUG');
|
|
28
|
+
this.projectId = required(raw, 'PLANE_PROJECT_ID');
|
|
29
|
+
this.projectName = config.PROJECT_NAME;
|
|
30
|
+
this.pmMetaDir = resolve(process.env.HOME || '/home/coral', '.projects', this.projectName, 'pm_meta');
|
|
31
|
+
this.stateMap = {
|
|
32
|
+
Planning: required(raw, 'PLANE_STATE_PLANNING'),
|
|
33
|
+
Backlog: required(raw, 'PLANE_STATE_BACKLOG'),
|
|
34
|
+
Todo: required(raw, 'PLANE_STATE_TODO'),
|
|
35
|
+
Inprogress: required(raw, 'PLANE_STATE_INPROGRESS'),
|
|
36
|
+
QA: required(raw, 'PLANE_STATE_QA'),
|
|
37
|
+
Done: required(raw, 'PLANE_STATE_DONE'),
|
|
38
|
+
};
|
|
39
|
+
this.reverseStateMap = new Map();
|
|
40
|
+
for (const state of ALL_STATES) {
|
|
41
|
+
this.reverseStateMap.set(this.stateMap[state], state);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Plane API helpers
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
/** Base URL for project-scoped endpoints. */
|
|
48
|
+
get baseUrl() {
|
|
49
|
+
return `${this.apiUrl}/api/v1/workspaces/${this.workspaceSlug}/projects/${this.projectId}`;
|
|
50
|
+
}
|
|
51
|
+
/** Standard headers for every Plane request. */
|
|
52
|
+
get headers() {
|
|
53
|
+
return {
|
|
54
|
+
'X-API-Key': this.apiKey,
|
|
55
|
+
'Content-Type': 'application/json',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Generic Plane API request wrapper.
|
|
60
|
+
* Throws on non-2xx responses with a descriptive message.
|
|
61
|
+
*/
|
|
62
|
+
async request(method, path, body) {
|
|
63
|
+
const url = `${this.baseUrl}${path}`;
|
|
64
|
+
const init = {
|
|
65
|
+
method,
|
|
66
|
+
headers: this.headers,
|
|
67
|
+
};
|
|
68
|
+
if (body !== undefined) {
|
|
69
|
+
init.body = JSON.stringify(body);
|
|
70
|
+
}
|
|
71
|
+
const res = await fetch(url, init);
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
const text = await res.text().catch(() => '');
|
|
74
|
+
throw new Error(`Plane API ${method} ${path} failed (${res.status}): ${text}`);
|
|
75
|
+
}
|
|
76
|
+
// Some endpoints (DELETE, PATCH with 204) may return empty body
|
|
77
|
+
const text = await res.text();
|
|
78
|
+
if (!text)
|
|
79
|
+
return undefined;
|
|
80
|
+
return JSON.parse(text);
|
|
81
|
+
}
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Issue → Card mapping
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
/**
|
|
86
|
+
* Convert a Plane issue to a Card.
|
|
87
|
+
* Labels may come as objects ({id, name}) or bare UUID strings.
|
|
88
|
+
* When they are UUIDs, resolve to names via the label cache.
|
|
89
|
+
*/
|
|
90
|
+
async resolveIssueToCard(issue) {
|
|
91
|
+
const stateId = issue.state;
|
|
92
|
+
const cardState = this.reverseStateMap.get(stateId) ?? 'Backlog';
|
|
93
|
+
// Resolve label UUIDs to names
|
|
94
|
+
const labelNames = [];
|
|
95
|
+
for (const l of (issue.labels ?? [])) {
|
|
96
|
+
if (typeof l === 'object' && l.name) {
|
|
97
|
+
labelNames.push(l.name);
|
|
98
|
+
}
|
|
99
|
+
else if (typeof l === 'string') {
|
|
100
|
+
// UUID — resolve via cache
|
|
101
|
+
if (!this.labelCache)
|
|
102
|
+
await this.refreshLabelCache();
|
|
103
|
+
const name = this.reverseLabelName(l);
|
|
104
|
+
labelNames.push(name || l);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
id: issue.id,
|
|
109
|
+
seq: String(issue.sequence_id),
|
|
110
|
+
name: issue.name,
|
|
111
|
+
desc: issue.description || stripHtmlTags(issue.description_html ?? '').trim() || '',
|
|
112
|
+
state: cardState,
|
|
113
|
+
labels: labelNames,
|
|
114
|
+
meta: {},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Reverse lookup: label UUID → name.
|
|
119
|
+
*/
|
|
120
|
+
reverseLabelName(id) {
|
|
121
|
+
if (!this.labelCache)
|
|
122
|
+
return null;
|
|
123
|
+
for (const [name, uuid] of this.labelCache.entries()) {
|
|
124
|
+
if (uuid === id)
|
|
125
|
+
return name;
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// TaskBackend implementation
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
async bootstrap() {
|
|
133
|
+
// Verify API connectivity by fetching project info
|
|
134
|
+
const url = `${this.baseUrl}/`;
|
|
135
|
+
const res = await fetch(url, { method: 'GET', headers: this.headers });
|
|
136
|
+
if (!res.ok) {
|
|
137
|
+
throw new Error(`Plane bootstrap failed: cannot reach project (${res.status})`);
|
|
138
|
+
}
|
|
139
|
+
// Verify all state UUIDs are configured
|
|
140
|
+
for (const state of ALL_STATES) {
|
|
141
|
+
if (!this.stateMap[state]) {
|
|
142
|
+
throw new Error(`Plane bootstrap: missing state mapping for ${state}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Ensure pm_meta directory exists
|
|
146
|
+
if (!existsSync(this.pmMetaDir)) {
|
|
147
|
+
mkdirSync(this.pmMetaDir, { recursive: true });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async listByState(state) {
|
|
151
|
+
const stateId = this.stateMap[state];
|
|
152
|
+
if (!stateId)
|
|
153
|
+
throw new Error(`No Plane state mapping for ${state}`);
|
|
154
|
+
// Plane CE API v1 may ignore the ?state= query param,
|
|
155
|
+
// so fetch all issues and filter client-side by state UUID.
|
|
156
|
+
const data = await this.request('GET', '/issues/');
|
|
157
|
+
const issues = Array.isArray(data) ? data : (data.results ?? []);
|
|
158
|
+
const filtered = issues.filter((i) => i.state === stateId);
|
|
159
|
+
return Promise.all(filtered.map((i) => this.resolveIssueToCard(i)));
|
|
160
|
+
}
|
|
161
|
+
async getBySeq(seq) {
|
|
162
|
+
// Plane API doesn't have a direct "get by sequence_id" endpoint,
|
|
163
|
+
// so we filter issues by sequence_id.
|
|
164
|
+
const data = await this.request('GET', `/issues/?search=${seq}`);
|
|
165
|
+
const issues = Array.isArray(data) ? data : (data.results ?? []);
|
|
166
|
+
const match = issues.find((i) => String(i.sequence_id) === seq);
|
|
167
|
+
return match ? await this.resolveIssueToCard(match) : null;
|
|
168
|
+
}
|
|
169
|
+
async move(seq, targetState) {
|
|
170
|
+
const stateId = this.stateMap[targetState];
|
|
171
|
+
if (!stateId)
|
|
172
|
+
throw new Error(`No Plane state mapping for ${targetState}`);
|
|
173
|
+
const issue = await this.resolveIssue(seq);
|
|
174
|
+
await this.request('PATCH', `/issues/${issue.id}/`, { state: stateId });
|
|
175
|
+
}
|
|
176
|
+
async addLabel(seq, label) {
|
|
177
|
+
const issue = await this.resolveIssue(seq);
|
|
178
|
+
const labelId = await this.ensureLabel(label);
|
|
179
|
+
const currentLabelIds = await this.getIssueLabelIds(issue.id);
|
|
180
|
+
if (!currentLabelIds.includes(labelId)) {
|
|
181
|
+
currentLabelIds.push(labelId);
|
|
182
|
+
await this.request('PATCH', `/issues/${issue.id}/`, { labels: currentLabelIds });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async removeLabel(seq, label) {
|
|
186
|
+
const issue = await this.resolveIssue(seq);
|
|
187
|
+
const labelId = await this.findLabelId(label);
|
|
188
|
+
if (!labelId)
|
|
189
|
+
return; // Label doesn't exist, nothing to remove
|
|
190
|
+
const currentLabelIds = await this.getIssueLabelIds(issue.id);
|
|
191
|
+
const filtered = currentLabelIds.filter((id) => id !== labelId);
|
|
192
|
+
if (filtered.length !== currentLabelIds.length) {
|
|
193
|
+
await this.request('PATCH', `/issues/${issue.id}/`, { labels: filtered });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async claim(seq, workerSlot) {
|
|
197
|
+
// Dual-write: local pm_meta + CLAIMED label (doc 12 §9.2)
|
|
198
|
+
await this.metaWrite(seq, {
|
|
199
|
+
status: 'CLAIMED',
|
|
200
|
+
worker: workerSlot,
|
|
201
|
+
claimedAt: new Date().toISOString(),
|
|
202
|
+
});
|
|
203
|
+
await this.addLabel(seq, 'CLAIMED');
|
|
204
|
+
}
|
|
205
|
+
async releaseClaim(seq) {
|
|
206
|
+
// Dual-write: update pm_meta + remove CLAIMED label
|
|
207
|
+
const existing = await this.metaRead(seq);
|
|
208
|
+
await this.metaWrite(seq, {
|
|
209
|
+
...existing,
|
|
210
|
+
status: 'RELEASED',
|
|
211
|
+
releasedAt: new Date().toISOString(),
|
|
212
|
+
});
|
|
213
|
+
await this.removeLabel(seq, 'CLAIMED');
|
|
214
|
+
}
|
|
215
|
+
async comment(seq, text) {
|
|
216
|
+
const issue = await this.resolveIssue(seq);
|
|
217
|
+
await this.request('POST', `/issues/${issue.id}/activities/`, {
|
|
218
|
+
comment_html: `<p>${escapeHtml(text)}</p>`,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
async create(name, desc, state) {
|
|
222
|
+
const stateId = this.stateMap[state];
|
|
223
|
+
if (!stateId)
|
|
224
|
+
throw new Error(`No Plane state mapping for ${state}`);
|
|
225
|
+
const issue = await this.request('POST', '/issues/', {
|
|
226
|
+
name,
|
|
227
|
+
description_html: `<p>${escapeHtml(desc)}</p>`,
|
|
228
|
+
description: desc,
|
|
229
|
+
state: stateId,
|
|
230
|
+
});
|
|
231
|
+
return await this.resolveIssueToCard(issue);
|
|
232
|
+
}
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
// Checklist (via description_html task lists)
|
|
235
|
+
// ---------------------------------------------------------------------------
|
|
236
|
+
async checklistCreate(seq, items) {
|
|
237
|
+
const issue = await this.resolveIssue(seq);
|
|
238
|
+
// Build HTML task list and append to existing description
|
|
239
|
+
const taskListHtml = items
|
|
240
|
+
.map((item) => `<li data-checked="false">${escapeHtml(item)}</li>`)
|
|
241
|
+
.join('');
|
|
242
|
+
const html = `<ul class="checklist">${taskListHtml}</ul>`;
|
|
243
|
+
const currentDesc = issue.description_html ?? '';
|
|
244
|
+
const newDesc = currentDesc + '\n' + html;
|
|
245
|
+
await this.request('PATCH', `/issues/${issue.id}/`, {
|
|
246
|
+
description_html: newDesc,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
async checklistList(seq) {
|
|
250
|
+
const issue = await this.resolveIssue(seq);
|
|
251
|
+
const html = issue.description_html ?? '';
|
|
252
|
+
return parseChecklistItems(html);
|
|
253
|
+
}
|
|
254
|
+
async checklistCheck(seq, itemId) {
|
|
255
|
+
await this.updateChecklistItem(seq, itemId, true);
|
|
256
|
+
}
|
|
257
|
+
async checklistUncheck(seq, itemId) {
|
|
258
|
+
await this.updateChecklistItem(seq, itemId, false);
|
|
259
|
+
}
|
|
260
|
+
async updateChecklistItem(seq, itemId, checked) {
|
|
261
|
+
const issue = await this.resolveIssue(seq);
|
|
262
|
+
const html = issue.description_html ?? '';
|
|
263
|
+
const items = parseChecklistItems(html);
|
|
264
|
+
const idx = parseInt(itemId, 10);
|
|
265
|
+
if (isNaN(idx) || idx < 0 || idx >= items.length) {
|
|
266
|
+
throw new Error(`Checklist item ${itemId} not found on issue ${seq}`);
|
|
267
|
+
}
|
|
268
|
+
const updatedHtml = updateChecklistItemHtml(html, idx, checked);
|
|
269
|
+
await this.request('PATCH', `/issues/${issue.id}/`, {
|
|
270
|
+
description_html: updatedHtml,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
// ---------------------------------------------------------------------------
|
|
274
|
+
// pm_meta (local JSON files)
|
|
275
|
+
// ---------------------------------------------------------------------------
|
|
276
|
+
async metaRead(seq) {
|
|
277
|
+
const issue = await this.resolveIssue(seq);
|
|
278
|
+
const filePath = resolve(this.pmMetaDir, `${issue.id}.json`);
|
|
279
|
+
if (!existsSync(filePath))
|
|
280
|
+
return {};
|
|
281
|
+
try {
|
|
282
|
+
return JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return {};
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async metaWrite(seq, data) {
|
|
289
|
+
const issue = await this.resolveIssue(seq);
|
|
290
|
+
if (!existsSync(this.pmMetaDir)) {
|
|
291
|
+
mkdirSync(this.pmMetaDir, { recursive: true });
|
|
292
|
+
}
|
|
293
|
+
const filePath = resolve(this.pmMetaDir, `${issue.id}.json`);
|
|
294
|
+
writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
295
|
+
}
|
|
296
|
+
// ---------------------------------------------------------------------------
|
|
297
|
+
// Internal helpers
|
|
298
|
+
// ---------------------------------------------------------------------------
|
|
299
|
+
/**
|
|
300
|
+
* Resolve a sequence ID to a full Plane issue object.
|
|
301
|
+
* Throws if the issue cannot be found.
|
|
302
|
+
*/
|
|
303
|
+
async resolveIssue(seq) {
|
|
304
|
+
const data = await this.request('GET', `/issues/?search=${seq}`);
|
|
305
|
+
const issues = Array.isArray(data) ? data : (data.results ?? []);
|
|
306
|
+
const match = issues.find((i) => String(i.sequence_id) === seq);
|
|
307
|
+
if (!match) {
|
|
308
|
+
throw new Error(`Plane issue with sequence_id ${seq} not found`);
|
|
309
|
+
}
|
|
310
|
+
return match;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Get current label UUIDs on an issue.
|
|
314
|
+
*/
|
|
315
|
+
async getIssueLabelIds(issueId) {
|
|
316
|
+
const issue = await this.request('GET', `/issues/${issueId}/`);
|
|
317
|
+
if (!issue.label_ids) {
|
|
318
|
+
// labels may be objects or strings depending on API version
|
|
319
|
+
return (issue.labels ?? []).map((l) => typeof l === 'string' ? l : l.id);
|
|
320
|
+
}
|
|
321
|
+
return [...issue.label_ids];
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Find or create a project label by name, returning its UUID.
|
|
325
|
+
*/
|
|
326
|
+
async ensureLabel(name) {
|
|
327
|
+
const existing = await this.findLabelId(name);
|
|
328
|
+
if (existing)
|
|
329
|
+
return existing;
|
|
330
|
+
// Create the label
|
|
331
|
+
const label = await this.request('POST', '/labels/', { name });
|
|
332
|
+
// Invalidate cache so next lookup picks it up
|
|
333
|
+
this.labelCache = null;
|
|
334
|
+
return label.id;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Find label UUID by name. Returns null if not found.
|
|
338
|
+
*/
|
|
339
|
+
async findLabelId(name) {
|
|
340
|
+
if (!this.labelCache) {
|
|
341
|
+
await this.refreshLabelCache();
|
|
342
|
+
}
|
|
343
|
+
return this.labelCache.get(name) ?? null;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Populate label name→id cache from Plane API.
|
|
347
|
+
*/
|
|
348
|
+
async refreshLabelCache() {
|
|
349
|
+
const data = await this.request('GET', '/labels/');
|
|
350
|
+
const labels = Array.isArray(data) ? data : (data.results ?? []);
|
|
351
|
+
this.labelCache = new Map();
|
|
352
|
+
for (const label of labels) {
|
|
353
|
+
this.labelCache.set(label.name, label.id);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// =============================================================================
|
|
358
|
+
// Utility functions
|
|
359
|
+
// =============================================================================
|
|
360
|
+
function required(raw, key) {
|
|
361
|
+
const val = raw[key];
|
|
362
|
+
if (!val)
|
|
363
|
+
throw new Error(`Missing required config field: ${key}`);
|
|
364
|
+
return val;
|
|
365
|
+
}
|
|
366
|
+
function escapeHtml(text) {
|
|
367
|
+
return text
|
|
368
|
+
.replace(/&/g, '&')
|
|
369
|
+
.replace(/</g, '<')
|
|
370
|
+
.replace(/>/g, '>')
|
|
371
|
+
.replace(/"/g, '"');
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Parse checklist items from Plane description_html.
|
|
375
|
+
* Items are <li> elements with data-checked attribute.
|
|
376
|
+
*/
|
|
377
|
+
function parseChecklistItems(html) {
|
|
378
|
+
const items = [];
|
|
379
|
+
// Match <li data-checked="true|false">text</li>
|
|
380
|
+
const re = /<li\s[^>]*data-checked="(true|false)"[^>]*>([\s\S]*?)<\/li>/gi;
|
|
381
|
+
let m;
|
|
382
|
+
let idx = 0;
|
|
383
|
+
while ((m = re.exec(html)) !== null) {
|
|
384
|
+
items.push({
|
|
385
|
+
id: String(idx),
|
|
386
|
+
text: stripHtmlTags(m[2]).trim(),
|
|
387
|
+
checked: m[1] === 'true',
|
|
388
|
+
});
|
|
389
|
+
idx++;
|
|
390
|
+
}
|
|
391
|
+
return items;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Update a checklist item's checked state in description_html by index.
|
|
395
|
+
*/
|
|
396
|
+
function updateChecklistItemHtml(html, index, checked) {
|
|
397
|
+
const re = /<li\s([^>]*data-checked=")(?:true|false)("[^>]*>)/gi;
|
|
398
|
+
let count = 0;
|
|
399
|
+
return html.replace(re, (match, before, after) => {
|
|
400
|
+
if (count++ === index) {
|
|
401
|
+
return `<li ${before}${checked ? 'true' : 'false'}${after}`;
|
|
402
|
+
}
|
|
403
|
+
return match;
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
function stripHtmlTags(html) {
|
|
407
|
+
return html.replace(/<[^>]*>/g, '');
|
|
408
|
+
}
|
|
409
|
+
//# sourceMappingURL=PlaneTaskBackend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaneTaskBackend.js","sourceRoot":"","sources":["../../src/providers/PlaneTaskBackend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ProjectConfig } from '../core/config.js';
|
|
2
|
+
import type { TaskBackend } from '../interfaces/TaskBackend.js';
|
|
3
|
+
import type { Card, CardState } from '../models/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Trello-backed TaskBackend.
|
|
6
|
+
*
|
|
7
|
+
* Uses Trello REST API via Node.js built-in fetch.
|
|
8
|
+
* Cards are identified by shortLink (seq). Lists represent states.
|
|
9
|
+
* Metadata is stored in card comments with [JARVIS-META] prefix.
|
|
10
|
+
*/
|
|
11
|
+
export declare class TrelloTaskBackend implements TaskBackend {
|
|
12
|
+
private readonly apiBase;
|
|
13
|
+
private readonly apiKey;
|
|
14
|
+
private readonly apiToken;
|
|
15
|
+
private readonly boardId;
|
|
16
|
+
/** CardState → Trello list ID */
|
|
17
|
+
private readonly listMap;
|
|
18
|
+
/** Trello list ID → CardState */
|
|
19
|
+
private readonly reverseListMap;
|
|
20
|
+
/** Cache: label name → label ID */
|
|
21
|
+
private labelCache;
|
|
22
|
+
constructor(config: ProjectConfig);
|
|
23
|
+
private get authParams();
|
|
24
|
+
private get;
|
|
25
|
+
private post;
|
|
26
|
+
private put;
|
|
27
|
+
private del;
|
|
28
|
+
private cardToCard;
|
|
29
|
+
bootstrap(): Promise<void>;
|
|
30
|
+
listByState(state: CardState): Promise<Card[]>;
|
|
31
|
+
getBySeq(seq: string): Promise<Card | null>;
|
|
32
|
+
move(seq: string, targetState: CardState): Promise<void>;
|
|
33
|
+
addLabel(seq: string, label: string): Promise<void>;
|
|
34
|
+
removeLabel(seq: string, label: string): Promise<void>;
|
|
35
|
+
claim(seq: string, workerSlot: string): Promise<void>;
|
|
36
|
+
releaseClaim(seq: string): Promise<void>;
|
|
37
|
+
comment(seq: string, text: string): Promise<void>;
|
|
38
|
+
create(name: string, desc: string, state: CardState): Promise<Card>;
|
|
39
|
+
checklistCreate(seq: string, items: string[]): Promise<void>;
|
|
40
|
+
checklistList(seq: string): Promise<{
|
|
41
|
+
id: string;
|
|
42
|
+
text: string;
|
|
43
|
+
checked: boolean;
|
|
44
|
+
}[]>;
|
|
45
|
+
checklistCheck(seq: string, itemId: string): Promise<void>;
|
|
46
|
+
checklistUncheck(seq: string, itemId: string): Promise<void>;
|
|
47
|
+
metaRead(seq: string): Promise<Record<string, unknown>>;
|
|
48
|
+
metaWrite(seq: string, data: Record<string, unknown>): Promise<void>;
|
|
49
|
+
private requireCard;
|
|
50
|
+
private ensureLabel;
|
|
51
|
+
private findLabelId;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=TrelloTaskBackend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrelloTaskBackend.d.ts","sourceRoot":"","sources":["../../src/providers/TrelloTaskBackend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAI1D;;;;;;GAMG;AACH,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,iCAAiC;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,iCAAiC;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;IAExD,mCAAmC;IACnC,OAAO,CAAC,UAAU,CAAoC;gBAE1C,MAAM,EAAE,aAAa;IAqBjC,OAAO,KAAK,UAAU,GAErB;YAIa,GAAG;YAWH,IAAI;YAcJ,GAAG;YAcH,GAAG;IAWjB,OAAO,CAAC,UAAU;IAeZ,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAS1B,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAU9C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAW3C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASnD,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWtD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnE,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5D,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IAgBrF,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc1D,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe5D,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAoBvD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAwB5D,WAAW;YAMX,WAAW;YAWX,WAAW;CAY1B"}
|