prjct-cli 1.21.0 → 1.22.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/CHANGELOG.md +97 -0
- package/README.md +41 -0
- package/core/__tests__/storage/state-storage-feedback.test.ts +463 -0
- package/core/__tests__/storage/state-storage-history.test.ts +469 -0
- package/core/commands/workflow.ts +5 -2
- package/core/schemas/state.ts +43 -0
- package/core/services/agent-generator.ts +70 -1
- package/core/services/sync-service.ts +115 -4
- package/core/storage/state-storage.ts +190 -3
- package/dist/bin/prjct.mjs +256 -10
- package/package.json +1 -1
package/dist/bin/prjct.mjs
CHANGED
|
@@ -10968,7 +10968,7 @@ var init_shipped = __esm({
|
|
|
10968
10968
|
|
|
10969
10969
|
// core/schemas/state.ts
|
|
10970
10970
|
import { z as z14 } from "zod";
|
|
10971
|
-
var PrioritySchema, TaskTypeSchema, TaskSectionSchema, TaskStatusSchema, ActivityTypeSchema, SubtaskSummarySchema, SubtaskCompletionDataSchema, SubtaskSchema, SubtaskProgressSchema, CurrentTaskSchema, PreviousTaskSchema, StateJsonSchema, QueueTaskSchema, QueueJsonSchema, StatsSchema, RecentActivitySchema, StateSchemaFull;
|
|
10971
|
+
var PrioritySchema, TaskTypeSchema, TaskSectionSchema, TaskStatusSchema, ActivityTypeSchema, SubtaskSummarySchema, SubtaskCompletionDataSchema, SubtaskSchema, SubtaskProgressSchema, CurrentTaskSchema, PreviousTaskSchema, TaskFeedbackSchema, TaskHistoryEntrySchema, StateJsonSchema, QueueTaskSchema, QueueJsonSchema, StatsSchema, RecentActivitySchema, StateSchemaFull;
|
|
10972
10972
|
var init_state = __esm({
|
|
10973
10973
|
"core/schemas/state.ts"() {
|
|
10974
10974
|
"use strict";
|
|
@@ -11079,12 +11079,63 @@ var init_state = __esm({
|
|
|
11079
11079
|
// ISO8601
|
|
11080
11080
|
pauseReason: z14.string().optional()
|
|
11081
11081
|
});
|
|
11082
|
+
TaskFeedbackSchema = z14.object({
|
|
11083
|
+
// Stack confirmations - tech confirmed/used during the task
|
|
11084
|
+
stackConfirmed: z14.array(z14.string()).optional(),
|
|
11085
|
+
// ["React 18", "TypeScript strict mode"]
|
|
11086
|
+
// Patterns discovered during the task
|
|
11087
|
+
patternsDiscovered: z14.array(z14.string()).optional(),
|
|
11088
|
+
// ["API routes follow /api/v1/{resource}"]
|
|
11089
|
+
// Agent accuracy - how well domain agents performed
|
|
11090
|
+
agentAccuracy: z14.array(
|
|
11091
|
+
z14.object({
|
|
11092
|
+
agent: z14.string(),
|
|
11093
|
+
// "backend.md"
|
|
11094
|
+
rating: z14.enum(["helpful", "neutral", "inaccurate"]),
|
|
11095
|
+
note: z14.string().optional()
|
|
11096
|
+
// "Missing Tailwind context"
|
|
11097
|
+
})
|
|
11098
|
+
).optional(),
|
|
11099
|
+
// Issues encountered during the task
|
|
11100
|
+
issuesEncountered: z14.array(z14.string()).optional()
|
|
11101
|
+
// ["ESLint conflicts with Prettier"]
|
|
11102
|
+
});
|
|
11103
|
+
TaskHistoryEntrySchema = z14.object({
|
|
11104
|
+
taskId: z14.string(),
|
|
11105
|
+
// task UUID
|
|
11106
|
+
title: z14.string(),
|
|
11107
|
+
// parent task description
|
|
11108
|
+
classification: TaskTypeSchema,
|
|
11109
|
+
// feature, bug, improvement, chore
|
|
11110
|
+
startedAt: z14.string(),
|
|
11111
|
+
// ISO8601
|
|
11112
|
+
completedAt: z14.string(),
|
|
11113
|
+
// ISO8601
|
|
11114
|
+
subtaskCount: z14.number(),
|
|
11115
|
+
// total number of subtasks
|
|
11116
|
+
subtaskSummaries: z14.array(SubtaskSummarySchema),
|
|
11117
|
+
// summary of each subtask
|
|
11118
|
+
outcome: z14.string(),
|
|
11119
|
+
// brief description of what was accomplished
|
|
11120
|
+
branchName: z14.string(),
|
|
11121
|
+
// git branch used
|
|
11122
|
+
linearId: z14.string().optional(),
|
|
11123
|
+
// Linear issue ID if linked
|
|
11124
|
+
linearUuid: z14.string().optional(),
|
|
11125
|
+
// Linear internal UUID
|
|
11126
|
+
prUrl: z14.string().optional(),
|
|
11127
|
+
// PR URL if shipped
|
|
11128
|
+
feedback: TaskFeedbackSchema.optional()
|
|
11129
|
+
// Task-to-analysis feedback (PRJ-272)
|
|
11130
|
+
});
|
|
11082
11131
|
StateJsonSchema = z14.object({
|
|
11083
11132
|
currentTask: CurrentTaskSchema.nullable(),
|
|
11084
11133
|
previousTask: PreviousTaskSchema.nullable().optional(),
|
|
11085
11134
|
// deprecated: use pausedTasks
|
|
11086
11135
|
pausedTasks: z14.array(PreviousTaskSchema).optional(),
|
|
11087
11136
|
// replaces previousTask
|
|
11137
|
+
taskHistory: z14.array(TaskHistoryEntrySchema).optional(),
|
|
11138
|
+
// completed tasks history (max 20)
|
|
11088
11139
|
lastUpdated: z14.string()
|
|
11089
11140
|
});
|
|
11090
11141
|
QueueTaskSchema = z14.object({
|
|
@@ -15187,6 +15238,8 @@ var init_state_storage = __esm({
|
|
|
15187
15238
|
return {
|
|
15188
15239
|
currentTask: null,
|
|
15189
15240
|
previousTask: null,
|
|
15241
|
+
pausedTasks: [],
|
|
15242
|
+
taskHistory: [],
|
|
15190
15243
|
lastUpdated: ""
|
|
15191
15244
|
};
|
|
15192
15245
|
}
|
|
@@ -15245,6 +15298,28 @@ var init_state_storage = __esm({
|
|
|
15245
15298
|
if (prev.pauseReason) m.raw(` Reason: ${prev.pauseReason}`);
|
|
15246
15299
|
});
|
|
15247
15300
|
m.blank().italic("Use /p:resume to continue");
|
|
15301
|
+
}).when((data.taskHistory?.length || 0) > 0, (m) => {
|
|
15302
|
+
const history2 = this.getTaskHistoryFromState(data);
|
|
15303
|
+
if (history2.length === 0) return;
|
|
15304
|
+
const currentTaskType = data.currentTask?.type;
|
|
15305
|
+
const relevantHistory = currentTaskType ? history2.filter((h) => h.classification === currentTaskType).slice(0, 3) : history2.slice(0, 5);
|
|
15306
|
+
if (relevantHistory.length === 0) return;
|
|
15307
|
+
m.hr().h2(
|
|
15308
|
+
currentTaskType ? `Recent ${currentTaskType} tasks (${relevantHistory.length})` : `Recent tasks (${relevantHistory.length})`
|
|
15309
|
+
);
|
|
15310
|
+
relevantHistory.forEach((entry, i) => {
|
|
15311
|
+
m.raw(`${i + 1}. **${entry.title}** (${entry.classification})`).raw(
|
|
15312
|
+
` Completed: ${toRelative(entry.completedAt)} | ${entry.subtaskCount} subtask${entry.subtaskCount > 1 ? "s" : ""}`
|
|
15313
|
+
).raw(` Outcome: ${entry.outcome}`);
|
|
15314
|
+
if (entry.linearId) m.raw(` Linear: ${entry.linearId}`);
|
|
15315
|
+
if (entry.feedback?.patternsDiscovered?.length) {
|
|
15316
|
+
m.raw(` Patterns: ${entry.feedback.patternsDiscovered.join(", ")}`);
|
|
15317
|
+
}
|
|
15318
|
+
if (entry.feedback?.issuesEncountered?.length) {
|
|
15319
|
+
m.raw(` Gotchas: ${entry.feedback.issuesEncountered.join(", ")}`);
|
|
15320
|
+
}
|
|
15321
|
+
});
|
|
15322
|
+
m.blank().italic("Task history helps identify patterns and improve decisions");
|
|
15248
15323
|
}).blank().build();
|
|
15249
15324
|
}
|
|
15250
15325
|
// =========== Transition Validation ===========
|
|
@@ -15306,29 +15381,65 @@ var init_state_storage = __esm({
|
|
|
15306
15381
|
}
|
|
15307
15382
|
/**
|
|
15308
15383
|
* Complete current task
|
|
15384
|
+
* Creates a TaskHistoryEntry and adds it to taskHistory with FIFO eviction
|
|
15385
|
+
* Optionally accepts structured feedback for the task-to-analysis feedback loop (PRJ-272)
|
|
15309
15386
|
*/
|
|
15310
|
-
async completeTask(projectId) {
|
|
15387
|
+
async completeTask(projectId, feedback) {
|
|
15311
15388
|
const state = await this.read(projectId);
|
|
15312
15389
|
const completedTask = state.currentTask;
|
|
15313
15390
|
if (!completedTask) {
|
|
15314
15391
|
return null;
|
|
15315
15392
|
}
|
|
15316
15393
|
this.validateTransition(state, "done");
|
|
15394
|
+
const completedAt = getTimestamp();
|
|
15395
|
+
const historyEntry = this.createTaskHistoryEntry(completedTask, completedAt, feedback);
|
|
15396
|
+
const existingHistory = this.getTaskHistoryFromState(state);
|
|
15397
|
+
const taskHistory = [historyEntry, ...existingHistory].slice(0, this.maxTaskHistory);
|
|
15317
15398
|
await this.update(projectId, () => ({
|
|
15318
15399
|
currentTask: null,
|
|
15319
15400
|
previousTask: null,
|
|
15320
|
-
|
|
15401
|
+
taskHistory,
|
|
15402
|
+
lastUpdated: completedAt
|
|
15321
15403
|
}));
|
|
15322
15404
|
await this.publishEvent(projectId, "task.completed", {
|
|
15323
15405
|
taskId: completedTask.id,
|
|
15324
15406
|
description: completedTask.description,
|
|
15325
15407
|
startedAt: completedTask.startedAt,
|
|
15326
|
-
completedAt
|
|
15408
|
+
completedAt
|
|
15327
15409
|
});
|
|
15328
15410
|
return completedTask;
|
|
15329
15411
|
}
|
|
15412
|
+
/**
|
|
15413
|
+
* Create a TaskHistoryEntry from a completed task
|
|
15414
|
+
* Optionally includes structured feedback for the feedback loop (PRJ-272)
|
|
15415
|
+
*/
|
|
15416
|
+
createTaskHistoryEntry(task, completedAt, feedback) {
|
|
15417
|
+
const taskAny = task;
|
|
15418
|
+
const subtaskSummaries = (task.subtasks || []).filter((st) => st.status === "completed" && st.summary).map((st) => st.summary);
|
|
15419
|
+
const outcome = subtaskSummaries.length > 0 ? subtaskSummaries.map((s) => s.title).join(", ") : "Task completed";
|
|
15420
|
+
const entry = {
|
|
15421
|
+
taskId: task.id,
|
|
15422
|
+
title: taskAny.parentDescription || task.description,
|
|
15423
|
+
classification: taskAny.type || "improvement",
|
|
15424
|
+
startedAt: task.startedAt,
|
|
15425
|
+
completedAt,
|
|
15426
|
+
subtaskCount: task.subtasks?.length || 0,
|
|
15427
|
+
subtaskSummaries,
|
|
15428
|
+
outcome,
|
|
15429
|
+
branchName: taskAny.branch || "unknown",
|
|
15430
|
+
linearId: task.linearId,
|
|
15431
|
+
linearUuid: task.linearUuid,
|
|
15432
|
+
prUrl: taskAny.prUrl
|
|
15433
|
+
};
|
|
15434
|
+
if (feedback) {
|
|
15435
|
+
entry.feedback = feedback;
|
|
15436
|
+
}
|
|
15437
|
+
return entry;
|
|
15438
|
+
}
|
|
15330
15439
|
/** Max number of paused tasks (configurable) */
|
|
15331
15440
|
maxPausedTasks = 5;
|
|
15441
|
+
/** Max number of task history entries (configurable) */
|
|
15442
|
+
maxTaskHistory = 20;
|
|
15332
15443
|
/** Staleness threshold in days */
|
|
15333
15444
|
stalenessThresholdDays = 30;
|
|
15334
15445
|
/**
|
|
@@ -15417,6 +15528,13 @@ var init_state_storage = __esm({
|
|
|
15417
15528
|
}
|
|
15418
15529
|
return paused;
|
|
15419
15530
|
}
|
|
15531
|
+
/**
|
|
15532
|
+
* Get task history from state with backward compatibility
|
|
15533
|
+
* Ensures taskHistory is always an array (never undefined)
|
|
15534
|
+
*/
|
|
15535
|
+
getTaskHistoryFromState(state) {
|
|
15536
|
+
return state.taskHistory || [];
|
|
15537
|
+
}
|
|
15420
15538
|
/**
|
|
15421
15539
|
* Get stale paused tasks (older than threshold)
|
|
15422
15540
|
*/
|
|
@@ -15498,6 +15616,63 @@ var init_state_storage = __esm({
|
|
|
15498
15616
|
const state = await this.read(projectId);
|
|
15499
15617
|
return this.getPausedTasksFromState(state);
|
|
15500
15618
|
}
|
|
15619
|
+
/**
|
|
15620
|
+
* Get full task history (completed tasks)
|
|
15621
|
+
*/
|
|
15622
|
+
async getTaskHistory(projectId) {
|
|
15623
|
+
const state = await this.read(projectId);
|
|
15624
|
+
return this.getTaskHistoryFromState(state);
|
|
15625
|
+
}
|
|
15626
|
+
/**
|
|
15627
|
+
* Get most recent task from history
|
|
15628
|
+
*/
|
|
15629
|
+
async getMostRecentTask(projectId) {
|
|
15630
|
+
const state = await this.read(projectId);
|
|
15631
|
+
const history2 = this.getTaskHistoryFromState(state);
|
|
15632
|
+
return history2[0] || null;
|
|
15633
|
+
}
|
|
15634
|
+
/**
|
|
15635
|
+
* Get task history filtered by classification
|
|
15636
|
+
*/
|
|
15637
|
+
async getTaskHistoryByType(projectId, classification) {
|
|
15638
|
+
const state = await this.read(projectId);
|
|
15639
|
+
const history2 = this.getTaskHistoryFromState(state);
|
|
15640
|
+
return history2.filter((t) => t.classification === classification);
|
|
15641
|
+
}
|
|
15642
|
+
/**
|
|
15643
|
+
* Aggregate feedback from all task history entries (PRJ-272)
|
|
15644
|
+
* Used by sync to feed task discoveries back into analysis and agent generation.
|
|
15645
|
+
* Returns consolidated patterns, stack confirmations, issues, and agent accuracy.
|
|
15646
|
+
*/
|
|
15647
|
+
async getAggregatedFeedback(projectId) {
|
|
15648
|
+
const history2 = await this.getTaskHistory(projectId);
|
|
15649
|
+
const entriesWithFeedback = history2.filter((h) => h.feedback);
|
|
15650
|
+
const stackConfirmed = [];
|
|
15651
|
+
const patternsDiscovered = [];
|
|
15652
|
+
const agentAccuracy = [];
|
|
15653
|
+
const allIssues = [];
|
|
15654
|
+
for (const entry of entriesWithFeedback) {
|
|
15655
|
+
const fb = entry.feedback;
|
|
15656
|
+
if (fb.stackConfirmed) stackConfirmed.push(...fb.stackConfirmed);
|
|
15657
|
+
if (fb.patternsDiscovered) patternsDiscovered.push(...fb.patternsDiscovered);
|
|
15658
|
+
if (fb.agentAccuracy) agentAccuracy.push(...fb.agentAccuracy);
|
|
15659
|
+
if (fb.issuesEncountered) allIssues.push(...fb.issuesEncountered);
|
|
15660
|
+
}
|
|
15661
|
+
const uniqueStack = [...new Set(stackConfirmed)];
|
|
15662
|
+
const uniquePatterns = [...new Set(patternsDiscovered)];
|
|
15663
|
+
const issueCounts = /* @__PURE__ */ new Map();
|
|
15664
|
+
for (const issue of allIssues) {
|
|
15665
|
+
issueCounts.set(issue, (issueCounts.get(issue) || 0) + 1);
|
|
15666
|
+
}
|
|
15667
|
+
const knownGotchas = [...issueCounts.entries()].filter(([_, count]) => count >= 2).map(([issue]) => issue);
|
|
15668
|
+
return {
|
|
15669
|
+
stackConfirmed: uniqueStack,
|
|
15670
|
+
patternsDiscovered: uniquePatterns,
|
|
15671
|
+
agentAccuracy,
|
|
15672
|
+
issuesEncountered: [...new Set(allIssues)],
|
|
15673
|
+
knownGotchas
|
|
15674
|
+
};
|
|
15675
|
+
}
|
|
15501
15676
|
// =========== Subtask Methods ===========
|
|
15502
15677
|
/**
|
|
15503
15678
|
* Create subtasks when fragmenting a task
|
|
@@ -27970,6 +28145,8 @@ var init_sync_service = __esm({
|
|
|
27970
28145
|
projectId = null;
|
|
27971
28146
|
globalPath = "";
|
|
27972
28147
|
cliVersion = "0.0.0";
|
|
28148
|
+
/** Task feedback context for agent generation (PRJ-272) */
|
|
28149
|
+
taskFeedbackContext;
|
|
27973
28150
|
constructor() {
|
|
27974
28151
|
this.projectPath = process.cwd();
|
|
27975
28152
|
}
|
|
@@ -28094,7 +28271,17 @@ var init_sync_service = __esm({
|
|
|
28094
28271
|
});
|
|
28095
28272
|
}
|
|
28096
28273
|
}
|
|
28097
|
-
|
|
28274
|
+
let taskFeedbackContext;
|
|
28275
|
+
if (shouldRegenerateAgents) {
|
|
28276
|
+
try {
|
|
28277
|
+
const feedback = await stateStorage.getAggregatedFeedback(this.projectId);
|
|
28278
|
+
if (feedback.patternsDiscovered.length > 0 || feedback.knownGotchas.length > 0 || feedback.agentAccuracy.length > 0) {
|
|
28279
|
+
taskFeedbackContext = feedback;
|
|
28280
|
+
}
|
|
28281
|
+
} catch {
|
|
28282
|
+
}
|
|
28283
|
+
}
|
|
28284
|
+
const agents = shouldRegenerateAgents ? await this.generateAgents(stack, stats, taskFeedbackContext) : await this.loadExistingAgents();
|
|
28098
28285
|
const skills = this.configureSkills(agents);
|
|
28099
28286
|
const skillsInstalled = shouldRegenerateAgents ? await this.autoInstallSkills(agents) : [];
|
|
28100
28287
|
const sources = this.buildSources(stats, commands);
|
|
@@ -28424,7 +28611,8 @@ var init_sync_service = __esm({
|
|
|
28424
28611
|
// ==========================================================================
|
|
28425
28612
|
// AGENT GENERATION
|
|
28426
28613
|
// ==========================================================================
|
|
28427
|
-
async generateAgents(stack, stats) {
|
|
28614
|
+
async generateAgents(stack, stats, feedbackContext) {
|
|
28615
|
+
this.taskFeedbackContext = feedbackContext;
|
|
28428
28616
|
const agents = [];
|
|
28429
28617
|
const agentsPath = path59.join(this.globalPath, "agents");
|
|
28430
28618
|
try {
|
|
@@ -28565,8 +28753,45 @@ var init_sync_service = __esm({
|
|
|
28565
28753
|
});
|
|
28566
28754
|
content = this.generateMinimalDomainAgent(name, stats, stack);
|
|
28567
28755
|
}
|
|
28756
|
+
content = this.injectFeedbackSection(content, name);
|
|
28568
28757
|
await fs56.writeFile(path59.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
28569
28758
|
}
|
|
28759
|
+
/**
|
|
28760
|
+
* Inject a "Recent Learnings" section into agent content from task feedback (PRJ-272)
|
|
28761
|
+
*/
|
|
28762
|
+
injectFeedbackSection(content, agentName) {
|
|
28763
|
+
if (!this.taskFeedbackContext) return content;
|
|
28764
|
+
const { patternsDiscovered, knownGotchas, agentAccuracy } = this.taskFeedbackContext;
|
|
28765
|
+
const agentNotes = agentAccuracy.filter(
|
|
28766
|
+
(a) => a.agent === `${agentName}.md` || a.agent === agentName
|
|
28767
|
+
);
|
|
28768
|
+
const hasContent = patternsDiscovered.length > 0 || knownGotchas.length > 0 || agentNotes.length > 0;
|
|
28769
|
+
if (!hasContent) return content;
|
|
28770
|
+
const lines = ["\n## Recent Learnings (from completed tasks)\n"];
|
|
28771
|
+
if (patternsDiscovered.length > 0) {
|
|
28772
|
+
lines.push("### Discovered Patterns");
|
|
28773
|
+
for (const pattern of patternsDiscovered) {
|
|
28774
|
+
lines.push(`- ${pattern}`);
|
|
28775
|
+
}
|
|
28776
|
+
lines.push("");
|
|
28777
|
+
}
|
|
28778
|
+
if (knownGotchas.length > 0) {
|
|
28779
|
+
lines.push("### Known Gotchas");
|
|
28780
|
+
for (const gotcha of knownGotchas) {
|
|
28781
|
+
lines.push(`- ${gotcha}`);
|
|
28782
|
+
}
|
|
28783
|
+
lines.push("");
|
|
28784
|
+
}
|
|
28785
|
+
if (agentNotes.length > 0) {
|
|
28786
|
+
lines.push("### Agent Accuracy Notes");
|
|
28787
|
+
for (const note of agentNotes) {
|
|
28788
|
+
const desc = note.note ? ` \u2014 ${note.note}` : "";
|
|
28789
|
+
lines.push(`- ${note.rating}${desc}`);
|
|
28790
|
+
}
|
|
28791
|
+
lines.push("");
|
|
28792
|
+
}
|
|
28793
|
+
return content + lines.join("\n");
|
|
28794
|
+
}
|
|
28570
28795
|
generateMinimalWorkflowAgent(name) {
|
|
28571
28796
|
const descriptions = {
|
|
28572
28797
|
"prjct-workflow": "Task lifecycle: now, done, pause, resume",
|
|
@@ -28892,18 +29117,38 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
28892
29117
|
/**
|
|
28893
29118
|
* Save sync results as a draft analysis.
|
|
28894
29119
|
* Preserves existing sealed analysis — only the draft is overwritten.
|
|
29120
|
+
* Incorporates task feedback from completed tasks (PRJ-272).
|
|
28895
29121
|
*/
|
|
28896
29122
|
async saveDraftAnalysis(git, stats, _stack) {
|
|
28897
29123
|
try {
|
|
28898
29124
|
const commitHash = git.recentCommits[0]?.hash || null;
|
|
29125
|
+
let patterns = [];
|
|
29126
|
+
let antiPatterns = [];
|
|
29127
|
+
try {
|
|
29128
|
+
const feedback = await stateStorage.getAggregatedFeedback(this.projectId);
|
|
29129
|
+
if (feedback.patternsDiscovered.length > 0) {
|
|
29130
|
+
patterns = feedback.patternsDiscovered.map((p) => ({
|
|
29131
|
+
name: p,
|
|
29132
|
+
description: `Discovered during task execution: ${p}`
|
|
29133
|
+
}));
|
|
29134
|
+
}
|
|
29135
|
+
if (feedback.knownGotchas.length > 0) {
|
|
29136
|
+
antiPatterns = feedback.knownGotchas.map((g) => ({
|
|
29137
|
+
issue: g,
|
|
29138
|
+
file: "multiple",
|
|
29139
|
+
suggestion: `Recurring issue reported across tasks: ${g}`
|
|
29140
|
+
}));
|
|
29141
|
+
}
|
|
29142
|
+
} catch {
|
|
29143
|
+
}
|
|
28899
29144
|
await analysisStorage.saveDraft(this.projectId, {
|
|
28900
29145
|
projectId: this.projectId,
|
|
28901
29146
|
languages: stats.languages,
|
|
28902
29147
|
frameworks: stats.frameworks,
|
|
28903
29148
|
configFiles: [],
|
|
28904
29149
|
fileCount: stats.fileCount,
|
|
28905
|
-
patterns
|
|
28906
|
-
antiPatterns
|
|
29150
|
+
patterns,
|
|
29151
|
+
antiPatterns,
|
|
28907
29152
|
analyzedAt: getTimestamp(),
|
|
28908
29153
|
status: "draft",
|
|
28909
29154
|
commitHash: commitHash ?? void 0
|
|
@@ -34388,6 +34633,7 @@ var init_workflow = __esm({
|
|
|
34388
34633
|
}
|
|
34389
34634
|
/**
|
|
34390
34635
|
* /p:done - Complete current task
|
|
34636
|
+
* Optionally accepts structured feedback for the task-to-analysis feedback loop (PRJ-272)
|
|
34391
34637
|
*/
|
|
34392
34638
|
async done(projectPath = process.cwd(), options = {}) {
|
|
34393
34639
|
try {
|
|
@@ -34443,7 +34689,7 @@ var init_workflow = __esm({
|
|
|
34443
34689
|
const sign = diff >= 0 ? "+" : "";
|
|
34444
34690
|
varianceDisplay = ` | est: ${estimatedPoints}pt (${formatMinutesToDuration(estimatedMinutes)}) \u2192 ${sign}${pct}%`;
|
|
34445
34691
|
}
|
|
34446
|
-
await stateStorage.completeTask(projectId);
|
|
34692
|
+
await stateStorage.completeTask(projectId, options.feedback);
|
|
34447
34693
|
const linearId = currentTask.linearId;
|
|
34448
34694
|
if (linearId) {
|
|
34449
34695
|
try {
|
|
@@ -34890,7 +35136,7 @@ var require_package = __commonJS({
|
|
|
34890
35136
|
"package.json"(exports, module) {
|
|
34891
35137
|
module.exports = {
|
|
34892
35138
|
name: "prjct-cli",
|
|
34893
|
-
version: "1.
|
|
35139
|
+
version: "1.22.0",
|
|
34894
35140
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
34895
35141
|
main: "core/index.ts",
|
|
34896
35142
|
bin: {
|