@programinglive/dev-workflow-mcp-server 1.13.14 → 1.13.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@programinglive/dev-workflow-mcp-server",
3
- "version": "1.13.14",
3
+ "version": "1.13.15",
4
4
  "description": "MCP server to enforce development workflow discipline",
5
5
  "homepage": "https://devworkflow.programinglive.com/",
6
6
  "mcpName": "io.github.programinglive/dev-workflow-mcp-server",
@@ -186,9 +186,13 @@ export async function handleCommitAndPush(args, context) {
186
186
  const lastCommitMessage = await git.getLastCommitMessage();
187
187
  const effectiveCommitMessage = lastCommitMessage || providedCommitMessage;
188
188
 
189
- // "Tidak ada perubahan" bukan berarti "sudah ter-push". HEAD bisa saja
190
- // berupa commit yang belum pernah dikirim. Memeriksanya mencegah tool
191
- // menandai selesai padahal remote masih tertinggal.
189
+ // "Tidak ada perubahan" bukan berarti "sudah ter-push", dan juga bukan
190
+ // berarti "panggilan ini sudah commit". HEAD bisa saja berupa commit yang
191
+ // belum pernah dikirim, dan bisa juga sudah terkirim oleh panggilan
192
+ // SEBELUMNYA. Memeriksanya mencegah tool menandai selesai padahal remote
193
+ // masih tertinggal - dan kalimat "Assuming commit and push already
194
+ // completed" (dipakai sampai 31 Oktober 2026) membuat agen percaya
195
+ // pekerjaannya sudah masuk padahal tidak ada yang dikerjakan sama sekali.
192
196
  const pushed = await verifyPushed(git, branchForPush);
193
197
  if (!pushed.ok) {
194
198
  return textResponse(
@@ -205,9 +209,20 @@ export async function handleCommitAndPush(args, context) {
205
209
  workflowState.state.currentPhase = isReleaseSatisfied(workflowState.state) ? "ready_to_complete" : "release";
206
210
  await workflowState.save();
207
211
 
212
+ const noActiveTask = workflowState.state.currentPhase === "idle" || !workflowState.state.taskDescription;
213
+
208
214
  return textResponse(
209
- `ℹ️ No changes detected. Assuming commit and push already completed.\nRepo: ${repoName}\nBranch: ${branchForPush} (verified on remote)\nLast commit: ${effectiveCommitMessage || "(unavailable)"
210
- }\n\nNext: Run 'perform_release' to handle the release and push tags.`
215
+ `ℹ️ No changes detected. No commit was made by this call.\n` +
216
+ `Repo: ${repoName}\nBranch: ${branchForPush} (verified on remote, HEAD ${pushed.head.slice(0, 8)})\n` +
217
+ `Commit terakhir: ${effectiveCommitMessage || "(tidak terbaca)"}\n\n` +
218
+ (noActiveTask
219
+ ? `Tidak ada task aktif di state workflow (currentPhase "idle"), jadi memang tidak ada ` +
220
+ `yang diharapkan dari panggilan ini.\n\n`
221
+ : "") +
222
+ `Yang terbukti: commit terakhir sudah ada di remote. Yang TIDAK terbukti: commit itu berisi ` +
223
+ `pekerjaan task ini. Kalau perubahan seharusnya ada, berarti belum ditulis, sudah di-commit ` +
224
+ `oleh panggilan sebelumnya, atau berada di repo/branch lain.\n\n` +
225
+ `Next: Run 'perform_release' to handle the release and push tags.`
211
226
  );
212
227
  }
213
228
 
@@ -134,8 +134,19 @@ export async function handleClaimFactoryTask(args = {}, { workflowState } = {})
134
134
  // dikerjakan, dan papan terlihat penuh task mati.
135
135
  startKeeping(config, session, step);
136
136
 
137
+ // Arsipkan task lokal yang sedang berjalan, jangan hapus diam-diam.
138
+ //
139
+ // 31 Oktober 2026 claim_factory_task dipanggil di tengah task lain yang baru
140
+ // sampai tahap rilis. `reset()` tanpa archive membuat task itu lenyap: tidak
141
+ // ada entri history, tidak ada peringatan, tidak disebut di jawaban.
142
+ // `start_task` sudah mengarsipkan sejak awal; claim tidak.
143
+ let archivedTask = null;
137
144
  if (workflowState) {
138
- workflowState.reset();
145
+ const archived = workflowState.reset({
146
+ archive: true,
147
+ reason: "Diganti claim_factory_task sebelum task selesai",
148
+ });
149
+ archivedTask = archived?.archivedTask || null;
139
150
  workflowState.state.currentPhase = "coding";
140
151
  workflowState.state.taskDescription = `[${task.taskKey || task.id}] ${task.title}`;
141
152
  workflowState.state.taskType = "other";
@@ -145,6 +156,10 @@ export async function handleClaimFactoryTask(args = {}, { workflowState } = {})
145
156
  return textResponse(
146
157
  [
147
158
  `Claimed [${task.taskKey || task.id}] ${task.title}`,
159
+ archivedTask
160
+ ? `⚠️ Task lokal yang belum selesai diarsipkan ke history: "${archivedTask}". ` +
161
+ `Pekerjaannya tidak dihapus, tetapi tidak lagi aktif di sesi ini.`
162
+ : "",
148
163
  session.tookOver && session.previousHolder
149
164
  ? `Took over from ${session.previousHolder.deviceName} (${session.previousHolder.agent}). The reason is recorded on the board.`
150
165
  : "",