@proletariat/cli 0.3.90 → 0.3.92

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.
Files changed (40) hide show
  1. package/dist/commands/work/index.js +4 -0
  2. package/dist/commands/work/index.js.map +1 -1
  3. package/dist/commands/work/ship.d.ts +43 -0
  4. package/dist/commands/work/ship.js +587 -0
  5. package/dist/commands/work/ship.js.map +1 -0
  6. package/dist/commands/work/start.d.ts +1 -0
  7. package/dist/commands/work/start.js +11 -1
  8. package/dist/commands/work/start.js.map +1 -1
  9. package/dist/lib/execution/context.d.ts +20 -0
  10. package/dist/lib/execution/context.js +88 -0
  11. package/dist/lib/execution/context.js.map +1 -1
  12. package/dist/lib/execution/devcontainer.d.ts +6 -0
  13. package/dist/lib/execution/devcontainer.js +48 -1
  14. package/dist/lib/execution/devcontainer.js.map +1 -1
  15. package/dist/lib/execution/runners/devcontainer.js +11 -0
  16. package/dist/lib/execution/runners/devcontainer.js.map +1 -1
  17. package/dist/lib/execution/runners/docker-management.js +1 -1
  18. package/dist/lib/execution/runners/docker-management.js.map +1 -1
  19. package/dist/lib/execution/runners/orchestrator.js +6 -3
  20. package/dist/lib/execution/runners/orchestrator.js.map +1 -1
  21. package/dist/lib/execution/runners/prompt-builder.js +31 -0
  22. package/dist/lib/execution/runners/prompt-builder.js.map +1 -1
  23. package/dist/lib/execution/runners/shared.d.ts +2 -2
  24. package/dist/lib/execution/runners/shared.js +2 -2
  25. package/dist/lib/execution/runners/shared.js.map +1 -1
  26. package/dist/lib/execution/types.d.ts +23 -0
  27. package/dist/lib/execution/types.js.map +1 -1
  28. package/dist/lib/providers/index.d.ts +2 -0
  29. package/dist/lib/providers/index.js +2 -0
  30. package/dist/lib/providers/index.js.map +1 -1
  31. package/dist/lib/providers/state-intents.d.ts +44 -0
  32. package/dist/lib/providers/state-intents.js +101 -0
  33. package/dist/lib/providers/state-intents.js.map +1 -0
  34. package/dist/lib/providers/state-resolution.d.ts +137 -0
  35. package/dist/lib/providers/state-resolution.js +302 -0
  36. package/dist/lib/providers/state-resolution.js.map +1 -0
  37. package/dist/lib/work-lifecycle/post-execution.js +47 -28
  38. package/dist/lib/work-lifecycle/post-execution.js.map +1 -1
  39. package/oclif.manifest.json +2317 -2203
  40. package/package.json +1 -1
@@ -0,0 +1,302 @@
1
+ /**
2
+ * State Resolution Engine
3
+ *
4
+ * Resolves semantic intents (e.g., 'review', 'active', 'done') to actual
5
+ * PM tool states at runtime. Never caches state IDs across calls.
6
+ *
7
+ * Resolution flow:
8
+ * 1. Always fetch fresh states from the PM provider
9
+ * 2. Check user config — `state-map.{intent}` overrides exact-match against fetched states
10
+ * 3. Match against built-in semantic intent aliases
11
+ * 4. No config + no alias match → LLM resolves (pass available states to LLM)
12
+ * 5. No match → skip (don't move, log warning)
13
+ *
14
+ * The same move() function works across Linear, Trello, ClickUp, Jira, etc. —
15
+ * each provider implements fetchStates() differently but returns the same shape.
16
+ * Resolution logic is provider-agnostic.
17
+ */
18
+ import { SettingsStore } from '../database/settings-store.js';
19
+ import { matchIntentByAliases, getDefaultIntent } from './state-intents.js';
20
+ /**
21
+ * Config key prefix for state-map overrides.
22
+ * e.g., `state-map.review` → "Awaiting Client Feedback"
23
+ */
24
+ const STATE_MAP_PREFIX = 'state-map.';
25
+ // ---------------------------------------------------------------------------
26
+ // LLM Resolution
27
+ // ---------------------------------------------------------------------------
28
+ /**
29
+ * Use the LLM to resolve which available state best matches a semantic intent.
30
+ *
31
+ * Sends the list of available states and the intent to the Anthropic API.
32
+ * Returns the matching state ID, or null if no match.
33
+ *
34
+ * Requires ANTHROPIC_API_KEY to be set.
35
+ */
36
+ export async function llmResolveState(states, intent) {
37
+ const apiKey = process.env.ANTHROPIC_API_KEY;
38
+ if (!apiKey) {
39
+ return null;
40
+ }
41
+ const stateList = states.map(s => `- "${s.name}" (id: ${s.id})`).join('\n');
42
+ const prompt = `You are a state resolution assistant. Given a list of available workflow states from a project management tool and a semantic intent, pick the state that best matches the intent.
43
+
44
+ Available states:
45
+ ${stateList}
46
+
47
+ Semantic intent: "${intent}"
48
+ ${getDefaultIntent(intent) ? `Intent description: ${getDefaultIntent(intent).description}` : ''}
49
+
50
+ Respond with ONLY the exact state ID that best matches this intent. If no state matches, respond with "NONE".`;
51
+ try {
52
+ const response = await fetch('https://api.anthropic.com/v1/messages', {
53
+ method: 'POST',
54
+ headers: {
55
+ 'Content-Type': 'application/json',
56
+ 'x-api-key': apiKey,
57
+ 'anthropic-version': '2023-06-01',
58
+ },
59
+ body: JSON.stringify({
60
+ model: 'claude-haiku-4-5-20251001',
61
+ max_tokens: 100,
62
+ messages: [
63
+ {
64
+ role: 'user',
65
+ content: prompt,
66
+ },
67
+ ],
68
+ }),
69
+ });
70
+ if (!response.ok) {
71
+ return null;
72
+ }
73
+ const data = (await response.json());
74
+ const text = data.content?.[0]?.text?.trim();
75
+ if (!text || text === 'NONE') {
76
+ return null;
77
+ }
78
+ // The LLM should return a state ID — find the matching state
79
+ const match = states.find(s => s.id === text);
80
+ if (match)
81
+ return match;
82
+ // Fallback: LLM might have returned a state name instead of ID
83
+ const nameMatch = states.find(s => s.name.toLowerCase() === text.toLowerCase());
84
+ if (nameMatch)
85
+ return nameMatch;
86
+ return null;
87
+ }
88
+ catch {
89
+ // LLM call failed — non-fatal, fall through to skip
90
+ return null;
91
+ }
92
+ }
93
+ // ---------------------------------------------------------------------------
94
+ // Config Resolution
95
+ // ---------------------------------------------------------------------------
96
+ /**
97
+ * Check user config for a state-map override for the given intent.
98
+ * Config stores state NAMES, not IDs.
99
+ *
100
+ * @param db - Database instance for settings lookup
101
+ * @param intent - Semantic intent name (e.g., 'review')
102
+ * @returns The configured state name, or null if not set
103
+ */
104
+ export function getStateMapConfig(db, intent) {
105
+ try {
106
+ const settings = new SettingsStore(db);
107
+ return settings.get(`${STATE_MAP_PREFIX}${intent}`);
108
+ }
109
+ catch {
110
+ return null;
111
+ }
112
+ }
113
+ /**
114
+ * Set a state-map config override for an intent.
115
+ *
116
+ * @param db - Database instance
117
+ * @param intent - Semantic intent name
118
+ * @param stateName - The state name to map to
119
+ */
120
+ export function setStateMapConfig(db, intent, stateName) {
121
+ const settings = new SettingsStore(db);
122
+ settings.set(`${STATE_MAP_PREFIX}${intent}`, stateName);
123
+ }
124
+ /**
125
+ * Remove a state-map config override for an intent.
126
+ */
127
+ export function deleteStateMapConfig(db, intent) {
128
+ const settings = new SettingsStore(db);
129
+ settings.delete(`${STATE_MAP_PREFIX}${intent}`);
130
+ }
131
+ /**
132
+ * List all state-map config overrides.
133
+ */
134
+ export function listStateMapConfigs(db) {
135
+ try {
136
+ const settings = new SettingsStore(db);
137
+ const entries = settings.getByPrefix(STATE_MAP_PREFIX);
138
+ return entries.map(e => ({
139
+ intent: e.key.slice(STATE_MAP_PREFIX.length),
140
+ stateName: e.value,
141
+ }));
142
+ }
143
+ catch {
144
+ return [];
145
+ }
146
+ }
147
+ // ---------------------------------------------------------------------------
148
+ // State Fetching — Provider Adapters
149
+ // ---------------------------------------------------------------------------
150
+ /**
151
+ * Create a PMProvider adapter from the existing TicketProvider + ProviderStorage.
152
+ *
153
+ * Fetches fresh states from the project's board via storage, and delegates
154
+ * moveTicket to the TicketProvider (which routes to Linear/Jira/PMO).
155
+ */
156
+ export function createPMProviderAdapter(provider, storage, projectId) {
157
+ return {
158
+ async fetchStates(_ticketId) {
159
+ const board = await storage.getProjectBoard(projectId);
160
+ if (!board)
161
+ return [];
162
+ return board.columns.map((col, idx) => ({
163
+ id: col.name, // For PMO, the state ID is the column name
164
+ name: col.name,
165
+ }));
166
+ },
167
+ async moveTicket(ticketId, stateId) {
168
+ const result = await provider.moveTicket(ticketId, stateId);
169
+ return { success: result.success, error: result.error };
170
+ },
171
+ };
172
+ }
173
+ /**
174
+ * Move a ticket to a state matching a semantic intent.
175
+ *
176
+ * Resolution order:
177
+ * 1. Fetch fresh states from the provider (never cache)
178
+ * 2. Check user config for `state-map.{intent}` override → exact match
179
+ * 3. Match against built-in semantic intent aliases
180
+ * 4. LLM fallback — ask Claude which state matches the intent
181
+ * 5. No match → skip, return warning
182
+ *
183
+ * @param pmProvider - The PM provider to fetch states from and move tickets in
184
+ * @param ticketId - The ticket to move
185
+ * @param intent - The semantic intent (e.g., 'review', 'active', 'done', 'blocked')
186
+ * @param dbOrOptions - Database instance or options object
187
+ * @returns Resolution result with success/failure and metadata
188
+ */
189
+ export async function move(pmProvider, ticketId, intent, dbOrOptions) {
190
+ // Normalize arguments: support both `move(p, id, intent, db)` and `move(p, id, intent, { db, currentState })`
191
+ let db;
192
+ let currentState;
193
+ if (dbOrOptions && typeof dbOrOptions === 'object' && 'prepare' in dbOrOptions) {
194
+ // It's a Database instance (has .prepare method)
195
+ db = dbOrOptions;
196
+ }
197
+ else if (dbOrOptions && typeof dbOrOptions === 'object') {
198
+ const opts = dbOrOptions;
199
+ db = opts.db;
200
+ currentState = opts.currentState;
201
+ }
202
+ // 1. Always fetch fresh states
203
+ let states;
204
+ try {
205
+ states = await pmProvider.fetchStates(ticketId);
206
+ }
207
+ catch (error) {
208
+ return {
209
+ success: false,
210
+ error: `Failed to fetch states: ${error instanceof Error ? error.message : String(error)}`,
211
+ };
212
+ }
213
+ if (states.length === 0) {
214
+ return {
215
+ success: false,
216
+ error: 'No states available from provider',
217
+ };
218
+ }
219
+ // Helper: check if ticket is already in the resolved state (case-insensitive)
220
+ const isAlreadyInState = (stateName) => {
221
+ if (!currentState)
222
+ return false;
223
+ return currentState.toLowerCase() === stateName.toLowerCase();
224
+ };
225
+ // 2. Check user config override
226
+ if (db) {
227
+ const configOverride = getStateMapConfig(db, intent);
228
+ if (configOverride) {
229
+ const match = states.find(s => s.name.toLowerCase() === configOverride.toLowerCase());
230
+ if (match) {
231
+ if (isAlreadyInState(match.name)) {
232
+ return { success: false, resolvedVia: 'config', stateName: match.name, stateId: match.id };
233
+ }
234
+ const result = await pmProvider.moveTicket(ticketId, match.id);
235
+ return {
236
+ success: result.success,
237
+ resolvedVia: 'config',
238
+ stateName: match.name,
239
+ stateId: match.id,
240
+ error: result.error,
241
+ };
242
+ }
243
+ // Config is set but no matching state — fall through to alias/LLM
244
+ }
245
+ }
246
+ // 3. Match against built-in semantic intent aliases
247
+ const intentDef = getDefaultIntent(intent);
248
+ if (intentDef) {
249
+ const aliasMatch = matchIntentByAliases(states, intentDef);
250
+ if (aliasMatch) {
251
+ if (isAlreadyInState(aliasMatch.name)) {
252
+ return { success: false, resolvedVia: 'alias', stateName: aliasMatch.name, stateId: aliasMatch.id };
253
+ }
254
+ const result = await pmProvider.moveTicket(ticketId, aliasMatch.id);
255
+ return {
256
+ success: result.success,
257
+ resolvedVia: 'alias',
258
+ stateName: aliasMatch.name,
259
+ stateId: aliasMatch.id,
260
+ error: result.error,
261
+ };
262
+ }
263
+ }
264
+ // 4. LLM fallback
265
+ const llmMatch = await llmResolveState(states, intent);
266
+ if (llmMatch) {
267
+ if (isAlreadyInState(llmMatch.name)) {
268
+ return { success: false, resolvedVia: 'llm', stateName: llmMatch.name, stateId: llmMatch.id };
269
+ }
270
+ const result = await pmProvider.moveTicket(ticketId, llmMatch.id);
271
+ return {
272
+ success: result.success,
273
+ resolvedVia: 'llm',
274
+ stateName: llmMatch.name,
275
+ stateId: llmMatch.id,
276
+ error: result.error,
277
+ };
278
+ }
279
+ // 5. No match — skip
280
+ const warning = `No state match for intent '${intent}', skipping move`;
281
+ console.warn(warning);
282
+ return {
283
+ success: false,
284
+ resolvedVia: 'skipped',
285
+ warning,
286
+ };
287
+ }
288
+ // ---------------------------------------------------------------------------
289
+ // Convenience: moveWithProvider()
290
+ // ---------------------------------------------------------------------------
291
+ /**
292
+ * High-level convenience function that wraps move() with the existing
293
+ * TicketProvider + ProviderStorage infrastructure.
294
+ *
295
+ * Use this from commands and lifecycle hooks that already have a resolved
296
+ * TicketProvider and ProviderStorage.
297
+ */
298
+ export async function moveWithProvider(provider, storage, projectId, ticketId, intent, db, currentState) {
299
+ const pmProvider = createPMProviderAdapter(provider, storage, projectId);
300
+ return move(pmProvider, ticketId, intent, { db, currentState });
301
+ }
302
+ //# sourceMappingURL=state-resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-resolution.js","sourceRoot":"","sources":["../../../src/lib/providers/state-resolution.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@
16
16
  import { getWorkColumnSetting, findColumnByName, getReviewGateSetting } from '../pmo/utils.js';
17
17
  import { resolveTicketProvider } from '../providers/resolver.js';
18
18
  import { tryValidateCommits } from '../execution/commit-validation.js';
19
+ import { moveWithProvider } from '../providers/state-resolution.js';
19
20
  /**
20
21
  * Check if a completed execution should trigger an automatic state transition.
21
22
  *
@@ -82,40 +83,58 @@ export async function handlePostExecutionTransition(context, storage, db) {
82
83
  // If we can't validate, allow the transition to proceed.
83
84
  }
84
85
  }
85
- // Determine target column based on review gate mode:
86
- // - auto: move to Done (no human review needed)
87
- // - post: move to Review (human reviews post-merge)
88
- // - required: move to Review (human must approve)
89
- const targetColumnType = reviewGate === 'auto' ? 'done' : 'review';
90
- const targetColumnName = getWorkColumnSetting(db, targetColumnType);
91
- // Get board columns to find the target column
92
- const board = await storage.getProjectBoard(ticket.projectId);
93
- if (!board) {
94
- return { transitioned: false, reviewGate };
95
- }
96
- const columnNames = board.columns.map(col => col.name);
97
- const targetColumn = findColumnByName(columnNames, targetColumnName);
98
- if (!targetColumn) {
99
- return { transitioned: false, reviewGate };
100
- }
101
- // Already in target state — skip
102
- if (ticket.statusName === targetColumn) {
103
- return { transitioned: false, reviewGate };
104
- }
86
+ // Determine semantic intent based on review gate mode:
87
+ // - auto: intent is 'done' (no human review needed)
88
+ // - post/required: intent is 'review' (human reviews)
89
+ const intent = reviewGate === 'auto' ? 'done' : 'review';
105
90
  // Resolve the appropriate provider for this ticket
106
91
  // Cast to ProviderStorage — at runtime the actual object is SQLiteStorage
107
92
  // which implements the full interface. For post-execution, only moveTicket is used.
108
93
  const provider = resolveTicketProvider(context.ticketId, ticket.projectId, db, storage, ticket.metadata);
109
- // Move ticket via the provider
94
+ // Use state resolution engine to resolve intent → actual state and move
110
95
  const previousState = ticket.statusName;
111
- const moveResult = await provider.moveTicket(context.ticketId, targetColumn);
112
- if (!moveResult.success) {
96
+ const resolution = await moveWithProvider(provider, storage, ticket.projectId, context.ticketId, intent, db, ticket.statusName);
97
+ if (!resolution.success) {
98
+ // If skipped (no match), fall back to legacy column matching
99
+ if (resolution.resolvedVia === 'skipped') {
100
+ const targetColumnType = reviewGate === 'auto' ? 'done' : 'review';
101
+ const targetColumnName = getWorkColumnSetting(db, targetColumnType);
102
+ const board = await storage.getProjectBoard(ticket.projectId);
103
+ if (!board) {
104
+ return { transitioned: false, reviewGate };
105
+ }
106
+ const columnNames = board.columns.map(col => col.name);
107
+ const targetColumn = findColumnByName(columnNames, targetColumnName);
108
+ if (!targetColumn || ticket.statusName === targetColumn) {
109
+ return { transitioned: false, reviewGate };
110
+ }
111
+ const moveResult = await provider.moveTicket(context.ticketId, targetColumn);
112
+ if (!moveResult.success) {
113
+ return {
114
+ transitioned: false,
115
+ fromState: previousState,
116
+ toState: targetColumn,
117
+ provider: moveResult.provider,
118
+ providerError: moveResult.error,
119
+ validation,
120
+ reviewGate,
121
+ };
122
+ }
123
+ return {
124
+ transitioned: true,
125
+ fromState: previousState,
126
+ toState: targetColumn,
127
+ provider: moveResult.provider,
128
+ validation,
129
+ reviewGate,
130
+ };
131
+ }
113
132
  return {
114
133
  transitioned: false,
115
134
  fromState: previousState,
116
- toState: targetColumn,
117
- provider: moveResult.provider,
118
- providerError: moveResult.error,
135
+ toState: resolution.stateName,
136
+ provider: provider.name,
137
+ providerError: resolution.error || resolution.warning,
119
138
  validation,
120
139
  reviewGate,
121
140
  };
@@ -123,8 +142,8 @@ export async function handlePostExecutionTransition(context, storage, db) {
123
142
  return {
124
143
  transitioned: true,
125
144
  fromState: previousState,
126
- toState: targetColumn,
127
- provider: moveResult.provider,
145
+ toState: resolution.stateName,
146
+ provider: provider.name,
128
147
  validation,
129
148
  reviewGate,
130
149
  };
@@ -1 +1 @@
1
- {"version":3,"file":"post-execution.js","sourceRoot":"","sources":["../../../src/lib/work-lifecycle/post-execution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"post-execution.js","sourceRoot":"","sources":["../../../src/lib/work-lifecycle/post-execution.ts"],"names":[],"mappings":"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"}