@proletariat/cli 0.3.94 → 0.3.95
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/agent/cleanup.d.ts +3 -4
- package/dist/commands/agent/cleanup.js +5 -4
- package/dist/commands/agent/cleanup.js.map +1 -1
- package/dist/commands/agent/gc.d.ts +3 -4
- package/dist/commands/agent/gc.js +5 -4
- package/dist/commands/agent/gc.js.map +1 -1
- package/dist/commands/agent/index.d.ts +3 -4
- package/dist/commands/agent/index.js +5 -4
- package/dist/commands/agent/index.js.map +1 -1
- package/dist/commands/agent/list.d.ts +3 -4
- package/dist/commands/agent/list.js +5 -4
- package/dist/commands/agent/list.js.map +1 -1
- package/dist/commands/agent/remove.d.ts +3 -4
- package/dist/commands/agent/remove.js +5 -4
- package/dist/commands/agent/remove.js.map +1 -1
- package/dist/commands/agent/staff/index.d.ts +3 -4
- package/dist/commands/agent/staff/index.js +5 -4
- package/dist/commands/agent/staff/index.js.map +1 -1
- package/dist/commands/agent/staff/remove.d.ts +3 -4
- package/dist/commands/agent/staff/remove.js +5 -4
- package/dist/commands/agent/staff/remove.js.map +1 -1
- package/dist/commands/agent/status.d.ts +3 -4
- package/dist/commands/agent/status.js +5 -4
- package/dist/commands/agent/status.js.map +1 -1
- package/dist/commands/agent/visit.d.ts +3 -4
- package/dist/commands/agent/visit.js +5 -4
- package/dist/commands/agent/visit.js.map +1 -1
- package/dist/commands/branch/create.js +1 -12
- package/dist/commands/branch/create.js.map +1 -1
- package/dist/commands/branch/list.d.ts +3 -4
- package/dist/commands/branch/list.js +5 -4
- package/dist/commands/branch/list.js.map +1 -1
- package/dist/commands/branch/validate.d.ts +3 -4
- package/dist/commands/branch/validate.js +6 -5
- package/dist/commands/branch/validate.js.map +1 -1
- package/dist/commands/branch/where.d.ts +3 -4
- package/dist/commands/branch/where.js +5 -4
- package/dist/commands/branch/where.js.map +1 -1
- package/dist/commands/commit.js +1 -1
- package/dist/commands/commit.js.map +1 -1
- package/dist/commands/db/backup.d.ts +16 -0
- package/dist/commands/db/backup.js +125 -0
- package/dist/commands/db/backup.js.map +1 -0
- package/dist/commands/db/repair.js +8 -11
- package/dist/commands/db/repair.js.map +1 -1
- package/dist/commands/execution/config.d.ts +3 -4
- package/dist/commands/execution/config.js +5 -4
- package/dist/commands/execution/config.js.map +1 -1
- package/dist/commands/execution/index.d.ts +3 -4
- package/dist/commands/execution/index.js +5 -4
- package/dist/commands/execution/index.js.map +1 -1
- package/dist/commands/execution/list.d.ts +3 -4
- package/dist/commands/execution/list.js +5 -4
- package/dist/commands/execution/list.js.map +1 -1
- package/dist/commands/execution/logs.d.ts +3 -4
- package/dist/commands/execution/logs.js +5 -4
- package/dist/commands/execution/logs.js.map +1 -1
- package/dist/commands/execution/stop.d.ts +3 -4
- package/dist/commands/execution/stop.js +5 -4
- package/dist/commands/execution/stop.js.map +1 -1
- package/dist/commands/execution/view.d.ts +3 -4
- package/dist/commands/execution/view.js +5 -4
- package/dist/commands/execution/view.js.map +1 -1
- package/dist/commands/hook/export.d.ts +3 -4
- package/dist/commands/hook/export.js +5 -4
- package/dist/commands/hook/export.js.map +1 -1
- package/dist/commands/hook/fire.d.ts +3 -4
- package/dist/commands/hook/fire.js +5 -4
- package/dist/commands/hook/fire.js.map +1 -1
- package/dist/commands/hook/list.d.ts +3 -4
- package/dist/commands/hook/list.js +5 -4
- package/dist/commands/hook/list.js.map +1 -1
- package/dist/commands/hook/preset.d.ts +3 -4
- package/dist/commands/hook/preset.js +5 -4
- package/dist/commands/hook/preset.js.map +1 -1
- package/dist/commands/orchestrate/index.d.ts +3 -4
- package/dist/commands/orchestrate/index.js +5 -4
- package/dist/commands/orchestrate/index.js.map +1 -1
- package/dist/commands/orchestrator/index.d.ts +3 -4
- package/dist/commands/orchestrator/index.js +5 -4
- package/dist/commands/orchestrator/index.js.map +1 -1
- package/dist/commands/pr/checks.d.ts +3 -4
- package/dist/commands/pr/checks.js +5 -4
- package/dist/commands/pr/checks.js.map +1 -1
- package/dist/commands/repo/add.d.ts +3 -4
- package/dist/commands/repo/add.js +5 -4
- package/dist/commands/repo/add.js.map +1 -1
- package/dist/commands/repo/create.d.ts +3 -4
- package/dist/commands/repo/create.js +5 -4
- package/dist/commands/repo/create.js.map +1 -1
- package/dist/commands/repo/fix-remotes.d.ts +3 -4
- package/dist/commands/repo/fix-remotes.js +5 -4
- package/dist/commands/repo/fix-remotes.js.map +1 -1
- package/dist/commands/repo/index.d.ts +3 -4
- package/dist/commands/repo/index.js +5 -4
- package/dist/commands/repo/index.js.map +1 -1
- package/dist/commands/repo/list.d.ts +3 -4
- package/dist/commands/repo/list.js +5 -4
- package/dist/commands/repo/list.js.map +1 -1
- package/dist/commands/session/cleanup.d.ts +3 -4
- package/dist/commands/session/cleanup.js +5 -4
- package/dist/commands/session/cleanup.js.map +1 -1
- package/dist/commands/session/create.d.ts +3 -4
- package/dist/commands/session/create.js +5 -4
- package/dist/commands/session/create.js.map +1 -1
- package/dist/commands/session/exec.d.ts +3 -4
- package/dist/commands/session/exec.js +5 -4
- package/dist/commands/session/exec.js.map +1 -1
- package/dist/commands/session/health.js +18 -0
- package/dist/commands/session/health.js.map +1 -1
- package/dist/commands/session/index.d.ts +3 -4
- package/dist/commands/session/index.js +9 -4
- package/dist/commands/session/index.js.map +1 -1
- package/dist/commands/session/inspect.d.ts +3 -4
- package/dist/commands/session/inspect.js +5 -4
- package/dist/commands/session/inspect.js.map +1 -1
- package/dist/commands/session/list.d.ts +3 -4
- package/dist/commands/session/list.js +19 -5
- package/dist/commands/session/list.js.map +1 -1
- package/dist/commands/session/prune.d.ts +3 -4
- package/dist/commands/session/prune.js +5 -4
- package/dist/commands/session/prune.js.map +1 -1
- package/dist/commands/session/report.d.ts +25 -5
- package/dist/commands/session/report.js +201 -5
- package/dist/commands/session/report.js.map +1 -1
- package/dist/commands/session/restart.d.ts +3 -4
- package/dist/commands/session/restart.js +5 -4
- package/dist/commands/session/restart.js.map +1 -1
- package/dist/commands/session/watch.d.ts +17 -0
- package/dist/commands/session/watch.js +139 -0
- package/dist/commands/session/watch.js.map +1 -0
- package/dist/commands/ticket/index.d.ts +3 -4
- package/dist/commands/ticket/index.js +5 -4
- package/dist/commands/ticket/index.js.map +1 -1
- package/dist/commands/web.d.ts +20 -0
- package/dist/commands/web.js +82 -0
- package/dist/commands/web.js.map +1 -0
- package/dist/commands/work/hooks/add.d.ts +3 -4
- package/dist/commands/work/hooks/add.js +5 -4
- package/dist/commands/work/hooks/add.js.map +1 -1
- package/dist/commands/work/hooks/list.d.ts +3 -4
- package/dist/commands/work/hooks/list.js +5 -4
- package/dist/commands/work/hooks/list.js.map +1 -1
- package/dist/commands/work/hooks/toggle.d.ts +3 -4
- package/dist/commands/work/hooks/toggle.js +5 -4
- package/dist/commands/work/hooks/toggle.js.map +1 -1
- package/dist/commands/work/peek.d.ts +3 -4
- package/dist/commands/work/peek.js +5 -4
- package/dist/commands/work/peek.js.map +1 -1
- package/dist/commands/work/propose.d.ts +23 -0
- package/dist/commands/work/propose.js +57 -0
- package/dist/commands/work/propose.js.map +1 -0
- package/dist/commands/work/ready.js +2 -2
- package/dist/commands/work/ready.js.map +1 -1
- package/dist/commands/work/rebase.d.ts +1 -1
- package/dist/commands/work/rebase.js +52 -49
- package/dist/commands/work/rebase.js.map +1 -1
- package/dist/commands/work/ship.d.ts +6 -0
- package/dist/commands/work/ship.js +217 -48
- package/dist/commands/work/ship.js.map +1 -1
- package/dist/commands/work/start.js +3 -6
- package/dist/commands/work/start.js.map +1 -1
- package/dist/commands/work/stop.d.ts +3 -4
- package/dist/commands/work/stop.js +5 -4
- package/dist/commands/work/stop.js.map +1 -1
- package/dist/hooks/init.js +11 -1
- package/dist/hooks/init.js.map +1 -1
- package/dist/lib/branch/index.d.ts +6 -5
- package/dist/lib/branch/index.js +8 -13
- package/dist/lib/branch/index.js.map +1 -1
- package/dist/lib/dashboard/html.d.ts +2 -1
- package/dist/lib/dashboard/html.js +150 -522
- package/dist/lib/dashboard/html.js.map +1 -1
- package/dist/lib/database/db-safety.d.ts +48 -9
- package/dist/lib/database/db-safety.js +308 -43
- package/dist/lib/database/db-safety.js.map +1 -1
- package/dist/lib/database/index.d.ts +1 -1
- package/dist/lib/database/index.js +1 -1
- package/dist/lib/database/index.js.map +1 -1
- package/dist/lib/database/workspace.js +3 -1
- package/dist/lib/database/workspace.js.map +1 -1
- package/dist/lib/execution/runners/docker.js +8 -0
- package/dist/lib/execution/runners/docker.js.map +1 -1
- package/dist/lib/execution/runners/prompt-builder.js +9 -6
- package/dist/lib/execution/runners/prompt-builder.js.map +1 -1
- package/dist/lib/execution/spawner.js +2 -4
- package/dist/lib/execution/spawner.js.map +1 -1
- package/dist/lib/execution/storage.d.ts +29 -1
- package/dist/lib/execution/storage.js +77 -0
- package/dist/lib/execution/storage.js.map +1 -1
- package/dist/lib/execution/types.d.ts +17 -6
- package/dist/lib/execution/types.js +10 -7
- package/dist/lib/execution/types.js.map +1 -1
- package/dist/lib/machine-config.d.ts +8 -0
- package/dist/lib/machine-config.js +37 -0
- package/dist/lib/machine-config.js.map +1 -1
- package/dist/lib/orchestrate/poller.d.ts +1 -1
- package/dist/lib/orchestrate/poller.js +1 -1
- package/dist/lib/pmo/storage/base.js +5 -3
- package/dist/lib/pmo/storage/base.js.map +1 -1
- package/dist/lib/providers/index.d.ts +1 -0
- package/dist/lib/providers/index.js +1 -0
- package/dist/lib/providers/index.js.map +1 -1
- package/dist/lib/providers/resolver.js +16 -0
- package/dist/lib/providers/resolver.js.map +1 -1
- package/dist/lib/providers/trello-provider.d.ts +28 -0
- package/dist/lib/providers/trello-provider.js +381 -0
- package/dist/lib/providers/trello-provider.js.map +1 -0
- package/dist/lib/session/heartbeat.d.ts +45 -0
- package/dist/lib/session/heartbeat.js +150 -0
- package/dist/lib/session/heartbeat.js.map +1 -0
- package/dist/lib/session/index.d.ts +7 -0
- package/dist/lib/session/index.js +8 -0
- package/dist/lib/session/index.js.map +1 -0
- package/dist/lib/session/watcher.d.ts +79 -0
- package/dist/lib/session/watcher.js +142 -0
- package/dist/lib/session/watcher.js.map +1 -0
- package/dist/lib/shipping/auto-merge.d.ts +57 -0
- package/dist/lib/shipping/auto-merge.js +311 -0
- package/dist/lib/shipping/auto-merge.js.map +1 -0
- package/dist/lib/shipping/github.d.ts +68 -0
- package/dist/lib/shipping/github.js +217 -0
- package/dist/lib/shipping/github.js.map +1 -0
- package/dist/lib/shipping/index.d.ts +13 -0
- package/dist/lib/shipping/index.js +11 -0
- package/dist/lib/shipping/index.js.map +1 -0
- package/dist/lib/shipping/rebase.d.ts +35 -0
- package/dist/lib/shipping/rebase.js +107 -0
- package/dist/lib/shipping/rebase.js.map +1 -0
- package/dist/lib/shipping/types.d.ts +181 -0
- package/dist/lib/shipping/types.js +9 -0
- package/dist/lib/shipping/types.js.map +1 -0
- package/dist/lib/trello/client.d.ts +1 -0
- package/dist/lib/trello/client.js +6 -0
- package/dist/lib/trello/client.js.map +1 -1
- package/oclif.manifest.json +908 -1009
- package/package.json +8 -8
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trello Ticket Provider
|
|
3
|
+
*
|
|
4
|
+
* Writes ticket operations directly to Trello via API,
|
|
5
|
+
* then updates local PMO to keep it in sync.
|
|
6
|
+
*
|
|
7
|
+
* Follows the same pattern as LinearTicketProvider:
|
|
8
|
+
* Trello is the source of truth, PMO is best-effort mirror.
|
|
9
|
+
*/
|
|
10
|
+
import { TrelloClient } from '../trello/client.js';
|
|
11
|
+
import { TrelloMapper } from '../trello/mapper.js';
|
|
12
|
+
import { getTrelloApiKey, getTrelloApiToken, loadTrelloConfig } from '../trello/config.js';
|
|
13
|
+
import { listTrelloCards } from '../external-issues/trello.js';
|
|
14
|
+
export class TrelloTicketProvider {
|
|
15
|
+
db;
|
|
16
|
+
storage;
|
|
17
|
+
projectId;
|
|
18
|
+
ticketStatusCategory;
|
|
19
|
+
name = 'trello';
|
|
20
|
+
constructor(db, storage, projectId, ticketStatusCategory) {
|
|
21
|
+
this.db = db;
|
|
22
|
+
this.storage = storage;
|
|
23
|
+
this.projectId = projectId;
|
|
24
|
+
this.ticketStatusCategory = ticketStatusCategory;
|
|
25
|
+
}
|
|
26
|
+
getCredentialsOrFail() {
|
|
27
|
+
const apiKey = getTrelloApiKey(this.db);
|
|
28
|
+
if (!apiKey)
|
|
29
|
+
throw new Error('Trello API key not configured');
|
|
30
|
+
const apiToken = getTrelloApiToken(this.db);
|
|
31
|
+
if (!apiToken)
|
|
32
|
+
throw new Error('Trello API token not configured');
|
|
33
|
+
return { apiKey, apiToken };
|
|
34
|
+
}
|
|
35
|
+
async moveTicket(ticketId, newState) {
|
|
36
|
+
// 1. Get Trello credentials
|
|
37
|
+
let creds;
|
|
38
|
+
try {
|
|
39
|
+
creds = this.getCredentialsOrFail();
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return { success: false, provider: 'trello', error: 'Trello credentials not configured' };
|
|
43
|
+
}
|
|
44
|
+
// 2. Look up Trello mapping for this PMO ticket
|
|
45
|
+
const mapper = new TrelloMapper(this.db);
|
|
46
|
+
const mapping = mapper.getByTicketId(ticketId);
|
|
47
|
+
if (!mapping) {
|
|
48
|
+
return { success: false, provider: 'trello', error: `No Trello mapping for ticket ${ticketId}` };
|
|
49
|
+
}
|
|
50
|
+
const client = new TrelloClient(creds.apiKey, creds.apiToken);
|
|
51
|
+
// 3. Get the card to find its board
|
|
52
|
+
const card = await client.getCard(mapping.trelloCardId);
|
|
53
|
+
if (!card) {
|
|
54
|
+
return { success: false, provider: 'trello', error: `Trello card ${mapping.trelloCardId} not found` };
|
|
55
|
+
}
|
|
56
|
+
// 4. Get board lists and find matching list for the target state
|
|
57
|
+
let lists;
|
|
58
|
+
try {
|
|
59
|
+
lists = await client.getBoardLists(card.idBoard);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
return {
|
|
63
|
+
success: false,
|
|
64
|
+
provider: 'trello',
|
|
65
|
+
error: `Failed to get board lists: ${error instanceof Error ? error.message : String(error)}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const targetList = findMatchingTrelloList(lists, newState);
|
|
69
|
+
if (!targetList) {
|
|
70
|
+
return {
|
|
71
|
+
success: false,
|
|
72
|
+
provider: 'trello',
|
|
73
|
+
error: `No matching Trello list for state "${newState}". Available lists: ${lists.map(l => l.name).join(', ')}`,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// 5. Move the card to the target list
|
|
77
|
+
try {
|
|
78
|
+
await client.updateCard(mapping.trelloCardId, { name: card.name, idList: targetList.id });
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
provider: 'trello',
|
|
84
|
+
error: `Failed to move Trello card: ${error instanceof Error ? error.message : String(error)}`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// 6. Update local PMO mirror (best-effort)
|
|
88
|
+
try {
|
|
89
|
+
await this.storage.moveTicket(this.projectId, ticketId, newState);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// Non-fatal: Trello is the source of truth
|
|
93
|
+
}
|
|
94
|
+
// 7. Post a comment about the status change (best-effort)
|
|
95
|
+
try {
|
|
96
|
+
await client.addComment(mapping.trelloCardId, `Status updated to **${newState}** (via prlt)`);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Non-fatal: comment is informational
|
|
100
|
+
}
|
|
101
|
+
// 8. Update sync timestamp (best-effort)
|
|
102
|
+
try {
|
|
103
|
+
mapper.updateSyncTimestamp(ticketId);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Non-fatal
|
|
107
|
+
}
|
|
108
|
+
return { success: true, provider: 'trello' };
|
|
109
|
+
}
|
|
110
|
+
async deleteTicket(ticketId) {
|
|
111
|
+
let creds;
|
|
112
|
+
try {
|
|
113
|
+
creds = this.getCredentialsOrFail();
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return { success: false, provider: 'trello', error: 'Trello credentials not configured' };
|
|
117
|
+
}
|
|
118
|
+
// Look up Trello mapping
|
|
119
|
+
const mapper = new TrelloMapper(this.db);
|
|
120
|
+
const mapping = mapper.getByTicketId(ticketId);
|
|
121
|
+
if (mapping) {
|
|
122
|
+
// Archive the card in Trello (closed = true)
|
|
123
|
+
const client = new TrelloClient(creds.apiKey, creds.apiToken);
|
|
124
|
+
try {
|
|
125
|
+
const card = await client.getCard(mapping.trelloCardId);
|
|
126
|
+
if (card) {
|
|
127
|
+
await client.updateCard(mapping.trelloCardId, { name: card.name, closed: true });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
return {
|
|
132
|
+
success: false,
|
|
133
|
+
provider: 'trello',
|
|
134
|
+
error: `Failed to archive Trello card: ${error instanceof Error ? error.message : String(error)}`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Delete the local PMO mirror
|
|
139
|
+
try {
|
|
140
|
+
await this.storage.deleteTicket(ticketId);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// Non-fatal if Trello archive succeeded
|
|
144
|
+
}
|
|
145
|
+
return { success: true, provider: 'trello' };
|
|
146
|
+
}
|
|
147
|
+
async listTickets(projectId, filter) {
|
|
148
|
+
let creds;
|
|
149
|
+
try {
|
|
150
|
+
creds = this.getCredentialsOrFail();
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return { success: false, provider: 'trello', tickets: [], error: 'Trello credentials not configured' };
|
|
154
|
+
}
|
|
155
|
+
const trelloConfig = loadTrelloConfig(this.db);
|
|
156
|
+
const boardId = trelloConfig?.boardId || process.env.PRLT_TRELLO_BOARD_ID;
|
|
157
|
+
try {
|
|
158
|
+
const envelopes = await listTrelloCards({ apiKey: creds.apiKey, apiToken: creds.apiToken, boardId }, { limit: 50, query: filter?.search });
|
|
159
|
+
let tickets = envelopes.map(envelope => ({
|
|
160
|
+
id: envelope.source.externalKey,
|
|
161
|
+
title: envelope.title,
|
|
162
|
+
description: envelope.description || undefined,
|
|
163
|
+
priority: envelope.priority || undefined,
|
|
164
|
+
category: envelope.category || undefined,
|
|
165
|
+
projectId: envelope.projectKey,
|
|
166
|
+
projectName: envelope.projectKey,
|
|
167
|
+
statusId: envelope.status,
|
|
168
|
+
statusName: envelope.status,
|
|
169
|
+
owner: envelope.assignee || undefined,
|
|
170
|
+
assignee: envelope.assignee || undefined,
|
|
171
|
+
subtasks: [],
|
|
172
|
+
labels: envelope.labels,
|
|
173
|
+
metadata: {
|
|
174
|
+
external_source: envelope.source.name,
|
|
175
|
+
external_key: envelope.source.externalKey,
|
|
176
|
+
external_id: envelope.source.externalId,
|
|
177
|
+
external_url: envelope.source.url,
|
|
178
|
+
},
|
|
179
|
+
createdAt: new Date(),
|
|
180
|
+
updatedAt: new Date(),
|
|
181
|
+
}));
|
|
182
|
+
// Apply client-side filters
|
|
183
|
+
if (filter?.priority) {
|
|
184
|
+
tickets = tickets.filter(t => t.priority === filter.priority);
|
|
185
|
+
}
|
|
186
|
+
if (filter?.column) {
|
|
187
|
+
tickets = tickets.filter(t => t.statusName === filter.column);
|
|
188
|
+
}
|
|
189
|
+
if (filter?.category) {
|
|
190
|
+
tickets = tickets.filter(t => t.category === filter.category);
|
|
191
|
+
}
|
|
192
|
+
if (filter?.search) {
|
|
193
|
+
const term = filter.search.toLowerCase();
|
|
194
|
+
tickets = tickets.filter(t => t.title.toLowerCase().includes(term) ||
|
|
195
|
+
(t.description || '').toLowerCase().includes(term));
|
|
196
|
+
}
|
|
197
|
+
if (filter?.label) {
|
|
198
|
+
const label = filter.label.toLowerCase();
|
|
199
|
+
tickets = tickets.filter(t => t.labels.some(l => l.toLowerCase() === label));
|
|
200
|
+
}
|
|
201
|
+
return { success: true, provider: 'trello', tickets };
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
return {
|
|
205
|
+
success: false,
|
|
206
|
+
provider: 'trello',
|
|
207
|
+
tickets: [],
|
|
208
|
+
error: error instanceof Error ? error.message : String(error),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async createTicket(projectId, input) {
|
|
213
|
+
let creds;
|
|
214
|
+
try {
|
|
215
|
+
creds = this.getCredentialsOrFail();
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return { success: false, provider: 'trello', error: 'Trello credentials not configured' };
|
|
219
|
+
}
|
|
220
|
+
const client = new TrelloClient(creds.apiKey, creds.apiToken);
|
|
221
|
+
const trelloConfig = loadTrelloConfig(this.db);
|
|
222
|
+
const boardId = trelloConfig?.boardId || process.env.PRLT_TRELLO_BOARD_ID;
|
|
223
|
+
if (!boardId) {
|
|
224
|
+
return { success: false, provider: 'trello', error: 'Trello board ID is required. Run "prlt trello configure" or set PRLT_TRELLO_BOARD_ID.' };
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
// Get the first list on the board as the default target
|
|
228
|
+
const lists = await client.getBoardLists(boardId);
|
|
229
|
+
if (lists.length === 0) {
|
|
230
|
+
return { success: false, provider: 'trello', error: 'No lists found on the Trello board.' };
|
|
231
|
+
}
|
|
232
|
+
const targetList = lists[0];
|
|
233
|
+
// Create the card in Trello
|
|
234
|
+
const card = await client.createCard({
|
|
235
|
+
name: input.title,
|
|
236
|
+
desc: input.description || undefined,
|
|
237
|
+
idList: targetList.id,
|
|
238
|
+
idBoard: boardId,
|
|
239
|
+
});
|
|
240
|
+
// Create local PMO mirror ticket
|
|
241
|
+
const mirrorDescription = [
|
|
242
|
+
input.description || '',
|
|
243
|
+
'',
|
|
244
|
+
'---',
|
|
245
|
+
`_Created in Trello: [${card.name}](${card.url})_`,
|
|
246
|
+
].join('\n').trim();
|
|
247
|
+
const pmoTicket = await this.storage.createTicket(projectId, {
|
|
248
|
+
...input,
|
|
249
|
+
title: card.name,
|
|
250
|
+
description: mirrorDescription,
|
|
251
|
+
metadata: {
|
|
252
|
+
...input.metadata,
|
|
253
|
+
'external_source': 'trello',
|
|
254
|
+
'external_id': card.id,
|
|
255
|
+
'external_key': card.id,
|
|
256
|
+
'external_url': card.url,
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
// Create mapping record for sync operations
|
|
260
|
+
const mapper = new TrelloMapper(this.db);
|
|
261
|
+
mapper.createOrUpdateMapping(pmoTicket.id, card.id, card.idBoard);
|
|
262
|
+
return { success: true, provider: 'trello', ticket: pmoTicket };
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
return {
|
|
266
|
+
success: false,
|
|
267
|
+
provider: 'trello',
|
|
268
|
+
error: error instanceof Error ? error.message : String(error),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async getTicket(ticketId) {
|
|
273
|
+
// Use local PMO mirror to avoid unnecessary API calls (same pattern as Linear)
|
|
274
|
+
try {
|
|
275
|
+
const ticket = await this.storage.getTicket(ticketId);
|
|
276
|
+
return { success: true, provider: 'trello', ticket };
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
return {
|
|
280
|
+
success: false,
|
|
281
|
+
provider: 'trello',
|
|
282
|
+
error: error instanceof Error ? error.message : String(error),
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async updateTicket(ticketId, input) {
|
|
287
|
+
let creds;
|
|
288
|
+
try {
|
|
289
|
+
creds = this.getCredentialsOrFail();
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
return { success: false, provider: 'trello', error: 'Trello credentials not configured' };
|
|
293
|
+
}
|
|
294
|
+
// Look up Trello mapping for this PMO ticket
|
|
295
|
+
const mapper = new TrelloMapper(this.db);
|
|
296
|
+
const mapping = mapper.getByTicketId(ticketId);
|
|
297
|
+
if (mapping) {
|
|
298
|
+
// Build Trello update payload from input fields
|
|
299
|
+
const trelloInput = {};
|
|
300
|
+
if (input.title !== undefined)
|
|
301
|
+
trelloInput.name = input.title;
|
|
302
|
+
if (input.description !== undefined)
|
|
303
|
+
trelloInput.desc = input.description ?? undefined;
|
|
304
|
+
// Only call Trello API if there are Trello-relevant fields
|
|
305
|
+
if (Object.keys(trelloInput).length > 0) {
|
|
306
|
+
const client = new TrelloClient(creds.apiKey, creds.apiToken);
|
|
307
|
+
try {
|
|
308
|
+
// Trello updateCard requires name, so fetch current card if we don't have it
|
|
309
|
+
if (!trelloInput.name) {
|
|
310
|
+
const card = await client.getCard(mapping.trelloCardId);
|
|
311
|
+
if (card)
|
|
312
|
+
trelloInput.name = card.name;
|
|
313
|
+
}
|
|
314
|
+
await client.updateCard(mapping.trelloCardId, trelloInput);
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
return {
|
|
318
|
+
success: false,
|
|
319
|
+
provider: 'trello',
|
|
320
|
+
error: `Failed to update Trello card: ${error instanceof Error ? error.message : String(error)}`,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
// Update sync timestamp (best-effort)
|
|
325
|
+
try {
|
|
326
|
+
mapper.updateSyncTimestamp(ticketId);
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
// Non-fatal
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// Also update local PMO mirror
|
|
333
|
+
try {
|
|
334
|
+
const ticket = await this.storage.updateTicket(ticketId, input);
|
|
335
|
+
return { success: true, provider: 'trello', ticket };
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
return {
|
|
339
|
+
success: false,
|
|
340
|
+
provider: 'trello',
|
|
341
|
+
error: error instanceof Error ? error.message : String(error),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
async assignTicket(ticketId, assignee) {
|
|
346
|
+
// Trello assignee is via member IDs — best-effort on Trello side,
|
|
347
|
+
// always update local PMO mirror
|
|
348
|
+
try {
|
|
349
|
+
await this.storage.updateTicket(ticketId, { assignee });
|
|
350
|
+
return { success: true, provider: 'trello' };
|
|
351
|
+
}
|
|
352
|
+
catch (error) {
|
|
353
|
+
return {
|
|
354
|
+
success: false,
|
|
355
|
+
provider: 'trello',
|
|
356
|
+
error: error instanceof Error ? error.message : String(error),
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Find the best matching Trello list for a target state name.
|
|
363
|
+
* Uses case-insensitive exact match first, then substring match.
|
|
364
|
+
*/
|
|
365
|
+
function findMatchingTrelloList(lists, targetState) {
|
|
366
|
+
const lower = targetState.toLowerCase();
|
|
367
|
+
// 1. Exact match (case-insensitive)
|
|
368
|
+
const exact = lists.find(l => l.name.toLowerCase() === lower);
|
|
369
|
+
if (exact)
|
|
370
|
+
return exact;
|
|
371
|
+
// 2. List name contains the target state
|
|
372
|
+
const contains = lists.find(l => l.name.toLowerCase().includes(lower));
|
|
373
|
+
if (contains)
|
|
374
|
+
return contains;
|
|
375
|
+
// 3. Target state contains the list name
|
|
376
|
+
const reverseContains = lists.find(l => lower.includes(l.name.toLowerCase()));
|
|
377
|
+
if (reverseContains)
|
|
378
|
+
return reverseContains;
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=trello-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trello-provider.js","sourceRoot":"","sources":["../../../src/lib/providers/trello-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Heartbeat
|
|
3
|
+
*
|
|
4
|
+
* Heartbeat recording and checking for agent executions.
|
|
5
|
+
* The heartbeat system has two sides:
|
|
6
|
+
*
|
|
7
|
+
* 1. Agent-side (push): Agents update their heartbeat when alive/active.
|
|
8
|
+
* This is done by checking tmux pane liveness and JSONL file activity.
|
|
9
|
+
*
|
|
10
|
+
* 2. Host-side (pull): The watcher checks heartbeat timestamps and marks
|
|
11
|
+
* stale executions as failed. This catches the case where the agent is
|
|
12
|
+
* so dead it can't self-report (OOM, zombie processes).
|
|
13
|
+
*/
|
|
14
|
+
import { ExecutionStorage } from '../execution/storage.js';
|
|
15
|
+
import type { AgentWork } from '../execution/types.js';
|
|
16
|
+
/**
|
|
17
|
+
* Record a heartbeat for an execution by checking if its tmux session is alive.
|
|
18
|
+
* Uses tmux pane inspection to determine if the agent is still active.
|
|
19
|
+
*
|
|
20
|
+
* Returns the detected health state, or null if the session couldn't be found.
|
|
21
|
+
*/
|
|
22
|
+
export declare function recordHeartbeatFromSession(storage: ExecutionStorage, execution: AgentWork): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Record heartbeats for all running executions.
|
|
25
|
+
* Returns a map of execution ID to detected state.
|
|
26
|
+
*/
|
|
27
|
+
export declare function recordAllHeartbeats(storage: ExecutionStorage): Map<string, string>;
|
|
28
|
+
/**
|
|
29
|
+
* Information about a stale execution detected by heartbeat timeout.
|
|
30
|
+
*/
|
|
31
|
+
export interface StaleExecution {
|
|
32
|
+
execution: AgentWork;
|
|
33
|
+
lastHeartbeat: Date | null;
|
|
34
|
+
staleDurationMinutes: number;
|
|
35
|
+
reason: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check for stale executions that have exceeded the heartbeat timeout.
|
|
39
|
+
*/
|
|
40
|
+
export declare function detectStaleExecutions(storage: ExecutionStorage, timeoutMinutes: number): StaleExecution[];
|
|
41
|
+
/**
|
|
42
|
+
* Kill a Docker container by ID.
|
|
43
|
+
* Returns true if the container was killed or already stopped.
|
|
44
|
+
*/
|
|
45
|
+
export declare function killContainer(containerId: string): boolean;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Heartbeat
|
|
3
|
+
*
|
|
4
|
+
* Heartbeat recording and checking for agent executions.
|
|
5
|
+
* The heartbeat system has two sides:
|
|
6
|
+
*
|
|
7
|
+
* 1. Agent-side (push): Agents update their heartbeat when alive/active.
|
|
8
|
+
* This is done by checking tmux pane liveness and JSONL file activity.
|
|
9
|
+
*
|
|
10
|
+
* 2. Host-side (pull): The watcher checks heartbeat timestamps and marks
|
|
11
|
+
* stale executions as failed. This catches the case where the agent is
|
|
12
|
+
* so dead it can't self-report (OOM, zombie processes).
|
|
13
|
+
*/
|
|
14
|
+
import { execSync } from 'node:child_process';
|
|
15
|
+
import { captureTmuxPane, getHostTmuxSessionNames, getContainerTmuxSessionMap, findContainerSessionsByPrefix, findSessionForExecution, } from '../execution/session-utils.js';
|
|
16
|
+
import { detectState } from '../../commands/session/health.js';
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// Heartbeat Recording (Agent-side push)
|
|
19
|
+
// =============================================================================
|
|
20
|
+
/**
|
|
21
|
+
* Record a heartbeat for an execution by checking if its tmux session is alive.
|
|
22
|
+
* Uses tmux pane inspection to determine if the agent is still active.
|
|
23
|
+
*
|
|
24
|
+
* Returns the detected health state, or null if the session couldn't be found.
|
|
25
|
+
*/
|
|
26
|
+
export function recordHeartbeatFromSession(storage, execution) {
|
|
27
|
+
const isContainer = execution.environment === 'devcontainer';
|
|
28
|
+
let sessionId = execution.sessionId;
|
|
29
|
+
// Try to find the tmux session
|
|
30
|
+
if (isContainer && execution.containerId) {
|
|
31
|
+
const containerSessions = getContainerTmuxSessionMap();
|
|
32
|
+
const sessions = findContainerSessionsByPrefix(containerSessions, execution.containerId);
|
|
33
|
+
if (!sessions || sessions.length === 0)
|
|
34
|
+
return null;
|
|
35
|
+
if (sessionId && sessions.includes(sessionId)) {
|
|
36
|
+
// Session found by exact match
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Try fuzzy match
|
|
40
|
+
const match = findSessionForExecution(execution.ticketId, execution.agentName, sessions);
|
|
41
|
+
if (match) {
|
|
42
|
+
sessionId = match;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const hostSessions = getHostTmuxSessionNames();
|
|
51
|
+
if (sessionId && hostSessions.includes(sessionId)) {
|
|
52
|
+
// Session found
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const match = findSessionForExecution(execution.ticketId, execution.agentName, hostSessions);
|
|
56
|
+
if (match) {
|
|
57
|
+
sessionId = match;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!sessionId)
|
|
65
|
+
return null;
|
|
66
|
+
// Capture pane content and detect state
|
|
67
|
+
const paneContent = captureTmuxPane(sessionId, 10, isContainer ? execution.containerId : undefined);
|
|
68
|
+
const state = detectState(paneContent);
|
|
69
|
+
// If the session is alive (any state other than UNKNOWN with no content), record heartbeat
|
|
70
|
+
if (paneContent !== null) {
|
|
71
|
+
storage.updateHeartbeat(execution.id);
|
|
72
|
+
// Update lifecycle state based on detected health
|
|
73
|
+
if (state === 'WORKING') {
|
|
74
|
+
storage.updateLifecycleState(execution.id, 'healthy');
|
|
75
|
+
}
|
|
76
|
+
else if (state === 'IDLE') {
|
|
77
|
+
storage.updateLifecycleState(execution.id, 'idle');
|
|
78
|
+
}
|
|
79
|
+
else if (state === 'DONE') {
|
|
80
|
+
storage.updateLifecycleState(execution.id, 'completed');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return state;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Record heartbeats for all running executions.
|
|
87
|
+
* Returns a map of execution ID to detected state.
|
|
88
|
+
*/
|
|
89
|
+
export function recordAllHeartbeats(storage) {
|
|
90
|
+
const results = new Map();
|
|
91
|
+
const runningExecutions = storage.listExecutions({ status: 'running' });
|
|
92
|
+
const startingExecutions = storage.listExecutions({ status: 'starting' });
|
|
93
|
+
const activeExecutions = [...runningExecutions, ...startingExecutions];
|
|
94
|
+
for (const exec of activeExecutions) {
|
|
95
|
+
const state = recordHeartbeatFromSession(storage, exec);
|
|
96
|
+
if (state) {
|
|
97
|
+
results.set(exec.id, state);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return results;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Check for stale executions that have exceeded the heartbeat timeout.
|
|
104
|
+
*/
|
|
105
|
+
export function detectStaleExecutions(storage, timeoutMinutes) {
|
|
106
|
+
const staleExecutions = storage.getStaleExecutions(timeoutMinutes);
|
|
107
|
+
return staleExecutions.map(exec => {
|
|
108
|
+
const lastHeartbeat = exec.lastHeartbeat || null;
|
|
109
|
+
const referenceTime = lastHeartbeat || exec.startedAt;
|
|
110
|
+
const staleDurationMs = Date.now() - referenceTime.getTime();
|
|
111
|
+
const staleDurationMinutes = Math.floor(staleDurationMs / 60000);
|
|
112
|
+
const reason = lastHeartbeat
|
|
113
|
+
? `No heartbeat for ${staleDurationMinutes} minutes (last: ${lastHeartbeat.toISOString()})`
|
|
114
|
+
: `No heartbeat since start ${staleDurationMinutes} minutes ago`;
|
|
115
|
+
return {
|
|
116
|
+
execution: exec,
|
|
117
|
+
lastHeartbeat,
|
|
118
|
+
staleDurationMinutes,
|
|
119
|
+
reason,
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// =============================================================================
|
|
124
|
+
// Container Kill
|
|
125
|
+
// =============================================================================
|
|
126
|
+
/**
|
|
127
|
+
* Kill a Docker container by ID.
|
|
128
|
+
* Returns true if the container was killed or already stopped.
|
|
129
|
+
*/
|
|
130
|
+
export function killContainer(containerId) {
|
|
131
|
+
try {
|
|
132
|
+
execSync(`docker kill ${containerId}`, {
|
|
133
|
+
encoding: 'utf-8',
|
|
134
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
135
|
+
timeout: 30000,
|
|
136
|
+
});
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// Container may already be stopped
|
|
141
|
+
try {
|
|
142
|
+
const status = execSync(`docker inspect --format '{{.State.Status}}' ${containerId}`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 10000 }).trim();
|
|
143
|
+
return status === 'exited' || status === 'dead';
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../../src/lib/session/heartbeat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/session/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA"}
|