vibe-coding-master 0.7.43 → 0.7.44

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 (42) hide show
  1. package/README.md +40 -13
  2. package/dist/backend/api/artifact-routes.js +3 -0
  3. package/dist/backend/api/harness-routes.js +16 -0
  4. package/dist/backend/api/task-routes.js +1 -0
  5. package/dist/backend/api/workflow-control-routes.js +12 -0
  6. package/dist/backend/cli/install-vcm-harness.js +21 -0
  7. package/dist/backend/server.js +3 -1
  8. package/dist/backend/services/artifact-service.js +7 -30
  9. package/dist/backend/services/auto-memory-service.js +640 -12
  10. package/dist/backend/services/claude-hook-service.js +80 -2
  11. package/dist/backend/services/gate-review-service.js +173 -74
  12. package/dist/backend/services/harness-feedback-service.js +76 -78
  13. package/dist/backend/services/harness-service.js +27 -3
  14. package/dist/backend/services/runtime-coordinator-service.js +2 -1
  15. package/dist/backend/services/status-service.js +1 -0
  16. package/dist/backend/services/translation-worker-service.js +19 -4
  17. package/dist/backend/services/workflow-control-service.js +96 -12
  18. package/dist/backend/templates/handoff.js +44 -2
  19. package/dist/backend/templates/harness/architect-agent.js +13 -7
  20. package/dist/backend/templates/harness/architect-scaffold-worker-agent.js +1 -1
  21. package/dist/backend/templates/harness/check-scaffold-ledger.js +234 -10
  22. package/dist/backend/templates/harness/claude-root.js +3 -2
  23. package/dist/backend/templates/harness/coder-agent.js +8 -0
  24. package/dist/backend/templates/harness/gate-review.js +144 -49
  25. package/dist/backend/templates/harness/harness-engineer-agent.js +25 -10
  26. package/dist/backend/templates/harness/project-manager-agent.js +16 -10
  27. package/dist/backend/templates/harness/resolve-durable-doc-assignment.js +60 -0
  28. package/dist/backend/templates/harness/tester-agent.js +13 -0
  29. package/dist/backend/templates/harness/vcm-ask-user-skill.js +82 -0
  30. package/dist/backend/templates/harness/vcm-code-navigation-skill.js +7 -5
  31. package/dist/backend/templates/harness/vcm-task-state-skill.js +2 -2
  32. package/dist/backend/templates/harness/vcm-workflow-review-skill.js +1 -1
  33. package/dist/shared/types/workflow.js +1 -0
  34. package/dist/shared/validation/artifact-check.js +3 -3
  35. package/dist/shared/validation/artifact-contract.js +1 -1
  36. package/dist/shared/validation/artifact-registry.js +16 -0
  37. package/dist-frontend/assets/{index-VW9tYPP5.js → index-BvCmrFlN.js} +49 -49
  38. package/dist-frontend/index.html +1 -1
  39. package/package.json +1 -1
  40. package/scripts/claude-plugins/vcm-lsp-bridge/.claude-plugin/plugin.json +21 -6
  41. package/scripts/harness-tools/vcm-artifact +1 -2
  42. package/scripts/harness-tools/vcm-bash-guard +1 -1
package/README.md CHANGED
@@ -190,6 +190,12 @@ restart, but it does not infer transitions or choose the next role. Current
190
190
  artifacts, Gate Review state, Round/Turn state, and the role rules remain
191
191
  authoritative.
192
192
 
193
+ Whenever Project Manager asks the user a question, it first uses
194
+ `vcm-ask-user`. VCM records the wait and cancels any pending role dispatch in
195
+ one state update. Stop Hook then ends the PM turn without route scanning. Only
196
+ a new direct user message clears the wait, and the next role dispatch requires
197
+ a fresh Workflow Review.
198
+
193
199
  Typical flow:
194
200
 
195
201
  ```text
@@ -329,7 +335,8 @@ strict `workflow-progress.md` transition through `vcm-workflow-review`. VCM
329
335
  checks the confirmed dispatch history and current task artifacts, then grants
330
336
  one matching route. The target role's `UserPromptSubmit` consumes that approval
331
337
  and appends the confirmed transition. A rejected transition can be bypassed
332
- only by an exact one-time user authorization recorded through the VCM dialog.
338
+ only by the user's exact one-time authorization recorded in the next Workflow
339
+ Progress submission.
333
340
 
334
341
  If the flow stops, VCM always shows a blocking pause alert. `Pause alert sound`
335
342
  only controls the looping sound. Enabling Gateway turns that preference off once;
@@ -479,7 +486,10 @@ including CCR launches. The project environment must still
479
486
  provide the language server for each detected language: `rust-analyzer`,
480
487
  `typescript-language-server`, `pyright-langserver`, `gopls`, `clangd`, or
481
488
  `jdtls`. Architect preloads `vcm-code-navigation` and uses LSP for semantic
482
- relationships; other roles use generated context and ordinary source reads.
489
+ relationships. Accessors, backing fields, trait items, implementations, wrappers,
490
+ and aliases are queried as separate symbols; a bounded source-text fallback may
491
+ only locate candidates after the correct LSP query is demonstrably partial.
492
+ Other roles use generated context and ordinary source reads.
483
493
  Harness Studio reports
484
494
  whether the server executable and plugin can run; the role Session performs the
485
495
  real workspace indexing and semantic query retries. VCM uses Claude Code progress
@@ -498,10 +508,11 @@ files.
498
508
  `Auto memory` is the switch for the entire automated memory workflow. During
499
509
  Review Task Harness after Final Acceptance, Project Manager, Architect, Coder,
500
510
  Tester, and an enabled Reviewer submit proposals in sequence through
501
- `vcm-propose-memory`. Harness Engineer verifies and consolidates them before VCM
502
- records the result as part of the same Task Harness Retrospective. Workflow roles
503
- cannot edit active memory directly; Harness Engineer edits it only during the
504
- assigned Auto Memory Retrospective.
511
+ `vcm-propose-memory`. Harness Engineer verifies and consolidates them, commits
512
+ the reviewed memory, and writes the assigned machine-readable review result as
513
+ part of the same Task Harness Retrospective. Workflow roles cannot edit active
514
+ memory directly; Harness Engineer edits it only during the assigned Auto Memory
515
+ Retrospective.
505
516
 
506
517
  When Auto Memory is enabled, the planning Architect writes a provisional memory
507
518
  candidate before its post-planning Session restart. VCM snapshots that candidate
@@ -528,7 +539,10 @@ Final Acceptance
528
539
  -> Review pending Harness Feedback
529
540
  -> Review Auto Memory proposals, when Auto Memory is enabled
530
541
  -> Harness Engineer updates and commits memory, when Auto Memory is enabled
531
- -> VCM records the committed memory result
542
+ -> Harness Engineer writes review-result.json, when Auto Memory is enabled
543
+ -> VCM validates and records the committed memory result
544
+ -> VCM dispatches durable-document assignments one at a time
545
+ -> Complete Task Harness Retrospective after every assignment completes
532
546
  ```
533
547
 
534
548
  Memory proposal prompts sent to Project Manager, Architect, Coder, Tester, and
@@ -542,16 +556,29 @@ impact, and durable-document disposition, then evaluates every proposal item
542
556
  independently. Each Add or Update decision records why the memory is necessary,
543
557
  what happens if it is absent, whether it belongs in memory or a durable
544
558
  document, and the exact final memory content when retained. VCM validates that
545
- the commit changes only assigned memory host files and only their
546
- `<VCM-memory>` blocks; it does not parse or apply Harness Engineer's semantic
547
- decisions. Harness Engineer review and retrospective work remain tool role
548
- activity and do not participate in Round completion.
559
+ every existing entry and proposal has one structurally valid decision, every
560
+ move decision has one durable-document assignment, moved content has already
561
+ been removed from memory, and the commit changes only assigned memory host
562
+ files and only their `<VCM-memory>` blocks. VCM does not decide whether the
563
+ Harness Engineer's semantic judgment is correct. Harness Engineer review and
564
+ retrospective work remain tool role activity and do not participate in Round
565
+ completion.
566
+
567
+ For `move-to-durable-doc`, memory is removed in the Harness Engineer commit
568
+ before documentation work starts. VCM assigns architecture and known-issues
569
+ documents to Architect and testing documentation to Tester. For another target,
570
+ PM selects Architect, Coder, or Tester and asks the user only when ownership
571
+ cannot be determined. These assignments are backend-dispatched work rather than
572
+ a Docs-Only Flow. Each owner updates and commits the document, submits the exact
573
+ assignment ID in `docs-update-report.md`, and finishes before the next assignment
574
+ starts. Harness Studio shows assignment status and allows failed work to be
575
+ retried.
549
576
 
550
577
  When Auto Memory is disabled, Review Task Harness does not collect proposals or
551
578
  ask Harness Engineer to update memory. When enabled, both automatic and manual
552
579
  review requests collect proposals before starting the retrospective. A failed
553
- proposal collection or combined retrospective memory review must be retried
554
- from Harness Studio.
580
+ proposal collection, combined retrospective memory review, or durable-document
581
+ assignment must be retried from Harness Studio.
555
582
 
556
583
  ## Closing a Task
557
584
 
@@ -144,6 +144,9 @@ function artifactNameToPath(paths, artifactName) {
144
144
  if (artifactName === "test-report.md") {
145
145
  return paths.testReportPath;
146
146
  }
147
+ if (artifactName === "docs-update-report.md") {
148
+ return paths.docsUpdateReportPath;
149
+ }
147
150
  if (artifactName === "docs-sync-report.md") {
148
151
  return paths.docsSyncReportPath;
149
152
  }
@@ -208,6 +208,22 @@ export function registerHarnessRoutes(app, deps) {
208
208
  const { project, task } = await requireHarnessTaskContext(deps, request.body?.taskSlug);
209
209
  return deps.autoMemoryService.retryFailedReview(project.repoRoot, task.worktreePath);
210
210
  });
211
+ app.post("/api/projects/harness/memory/assignments/retry", async (request) => {
212
+ const { project, task } = await requireHarnessTaskContext(deps, request.body?.taskSlug);
213
+ return deps.autoMemoryService.retryDurableDocAssignment(project.repoRoot, task.worktreePath, request.body?.assignmentId ?? "");
214
+ });
215
+ app.post("/api/projects/harness/memory/assignments/owner", async (request) => {
216
+ const { project, task } = await requireHarnessTaskContext(deps, request.body?.taskSlug);
217
+ const owner = request.body?.owner;
218
+ if (owner !== "architect" && owner !== "coder" && owner !== "tester") {
219
+ throw new VcmError({
220
+ code: "DURABLE_DOC_OWNER_INVALID",
221
+ message: "Durable-document owner must be architect, coder, or tester.",
222
+ statusCode: 400
223
+ });
224
+ }
225
+ return deps.autoMemoryService.resolveDurableDocAssignmentOwner(project.repoRoot, task.worktreePath, request.body?.assignmentId ?? "", owner);
226
+ });
211
227
  }
212
228
  async function persistHarnessEngineerDefaults(appSettings, session) {
213
229
  const defaults = createDefaultToolSessionDefaults()["harness-engineer"];
@@ -235,6 +235,7 @@ function degradedArtifactSummary(handoffDir) {
235
235
  architectDebugPath: `${handoffDir}/architect-debug.md`,
236
236
  architectureDiagnosisPath: `${handoffDir}/architecture-diagnosis.md`,
237
237
  testReportPath: `${handoffDir}/test-report.md`,
238
+ docsUpdateReportPath: `${handoffDir}/docs-update-report.md`,
238
239
  docsSyncReportPath: `${handoffDir}/docs-sync-report.md`,
239
240
  workflowProgressPath: `${handoffDir}/workflow-progress.md`,
240
241
  finalAcceptancePath: `${handoffDir}/final-acceptance.md`
@@ -5,6 +5,18 @@ export function registerWorkflowControlRoutes(app, deps) {
5
5
  const context = await getContext(deps, request.params.taskSlug);
6
6
  return deps.workflowControlService.getState(context);
7
7
  });
8
+ app.post("/api/tasks/:taskSlug/ask-user", async (request) => {
9
+ const context = await getContext(deps, request.params.taskSlug);
10
+ const question = typeof request.body?.question === "string" ? request.body.question.trim() : "";
11
+ if (!question) {
12
+ throw new VcmError({
13
+ code: "WORKFLOW_USER_QUESTION_REQUIRED",
14
+ message: "A non-empty user question is required.",
15
+ statusCode: 400
16
+ });
17
+ }
18
+ return deps.workflowControlService.requestUserInput(context, question);
19
+ });
8
20
  }
9
21
  async function getContext(deps, taskSlug) {
10
22
  const project = await deps.projectService.getCurrentProject();
@@ -28,10 +28,12 @@ import { renderVcmLongRunningValidationSkillRules } from "../templates/harness/v
28
28
  import { renderVcmProposeMemorySkillRules } from "../templates/harness/vcm-propose-memory-skill.js";
29
29
  import { renderVcmReportHarnessIssueSkillRules } from "../templates/harness/vcm-report-harness-issue-skill.js";
30
30
  import { renderVcmRouteMessageSkillRules } from "../templates/harness/vcm-route-message-skill.js";
31
+ import { renderAskUserTool, renderVcmAskUserSkillRules } from "../templates/harness/vcm-ask-user-skill.js";
31
32
  import { renderUpdateTaskStateTool, renderVcmTaskStateSkillRules } from "../templates/harness/vcm-task-state-skill.js";
32
33
  import { renderVcmWorkflowReviewSkillRules } from "../templates/harness/vcm-workflow-review-skill.js";
33
34
  import { renderCheckScaffoldLedgerTool } from "../templates/harness/check-scaffold-ledger.js";
34
35
  import { renderRequestArchitectRestartTool, renderRestartArchitectSkillRules } from "../templates/harness/restart-architect-skill.js";
36
+ import { renderResolveDurableDocAssignmentTool } from "../templates/harness/resolve-durable-doc-assignment.js";
35
37
  import { readVcmPackageVersion } from "../app-version.js";
36
38
  const CLI_DIR = path.dirname(fileURLToPath(import.meta.url));
37
39
  const APP_ROOT = path.resolve(CLI_DIR, "../../..");
@@ -318,6 +320,12 @@ const WHOLE_FILES = [
318
320
  mode: 0o644,
319
321
  content: renderSkillFile("VCM Route Message Skill", "vcm-route-message", "Use when project-manager dispatches a VCM role or when a VCM role reports a question, result, blocker, or finding back to project-manager.", renderVcmRouteMessageSkillRules())
320
322
  },
323
+ {
324
+ path: ".claude/skills/vcm-ask-user/SKILL.md",
325
+ category: "skill",
326
+ mode: 0o644,
327
+ content: renderSkillFile("VCM Ask User Skill", "vcm-ask-user", "Use whenever project-manager asks the user a question and must pause the workflow.", renderVcmAskUserSkillRules())
328
+ },
321
329
  {
322
330
  path: ".claude/skills/vcm-task-state/SKILL.md",
323
331
  category: "skill",
@@ -360,6 +368,12 @@ const WHOLE_FILES = [
360
368
  mode: 0o755,
361
369
  content: renderRequestGateReviewTool()
362
370
  },
371
+ {
372
+ path: ".ai/tools/vcm-ask-user",
373
+ category: "runtime-tool",
374
+ mode: 0o755,
375
+ content: renderAskUserTool()
376
+ },
363
377
  {
364
378
  path: ".ai/tools/update-task-state",
365
379
  category: "runtime-tool",
@@ -378,6 +392,12 @@ const WHOLE_FILES = [
378
392
  mode: 0o755,
379
393
  content: renderRequestArchitectRestartTool()
380
394
  },
395
+ {
396
+ path: ".ai/tools/resolve-durable-doc-assignment",
397
+ category: "runtime-tool",
398
+ mode: 0o755,
399
+ content: renderResolveDurableDocAssignmentTool()
400
+ },
381
401
  {
382
402
  path: ".ai/tools/run-long-check",
383
403
  category: "runtime-tool",
@@ -642,6 +662,7 @@ function fixedDirectories() {
642
662
  ".claude/skills/vcm-harness-bootstrap/",
643
663
  ".claude/skills/vcm-long-running-validation/",
644
664
  ".claude/skills/vcm-route-message/",
665
+ ".claude/skills/vcm-ask-user/",
645
666
  ".claude/skills/vcm-task-state/",
646
667
  ".claude/skills/vcm-workflow-review/",
647
668
  ".claude/skills/vcm-gate-review/",
@@ -332,6 +332,7 @@ export function createDefaultServerDeps(options = {}) {
332
332
  appSettings,
333
333
  sessionService,
334
334
  roundService,
335
+ workflowControlService,
335
336
  onArchitecturePlanDisposition: ({ repoRoot, taskSlug, accepted }) => architectRestartService.recordArchitectureGateDisposition(repoRoot, taskSlug, accepted)
336
337
  });
337
338
  const translationWorkerService = createTranslationWorkerService({
@@ -416,7 +417,8 @@ export function createDefaultServerDeps(options = {}) {
416
417
  jobGuard: createJobGuardService(),
417
418
  translationWorkerService,
418
419
  architectRestartService,
419
- roleStallDetector
420
+ roleStallDetector,
421
+ workflowControlService
420
422
  });
421
423
  const runtimeCoordinator = createRuntimeCoordinatorService({
422
424
  appSettings,
@@ -4,7 +4,7 @@ import { checkMarkdownArtifact } from "../../shared/validation/artifact-check.js
4
4
  import { getArtifactDefinition, isArtifactKind } from "../../shared/validation/artifact-registry.js";
5
5
  import { VcmError } from "../errors.js";
6
6
  import { resolveRepoPath } from "../adapters/filesystem.js";
7
- import { renderArchitectureBriefTemplate, renderArchitectureDiagnosisTemplate, renderArchitectureEvidenceTemplate, renderArchitecturePlanTemplate, renderArchitectDebugTemplate, renderCoderCompletionTemplate, renderDocsSyncReportTemplate, renderFinalAcceptanceTemplate, renderKnownIssuesTemplate, renderPlanningProgressTemplate, renderMessageRouteTemplate, renderTestReportTemplate, renderWorkflowProgressTemplate } from "../templates/handoff.js";
7
+ import { renderArchitectureBriefTemplate, renderArchitectureDiagnosisTemplate, renderArchitectureEvidenceTemplate, renderArchitecturePlanTemplate, renderArchitectDebugTemplate, renderCoderCompletionTemplate, renderDocsUpdateReportTemplate, renderDocsSyncReportTemplate, renderFinalAcceptanceTemplate, renderKnownIssuesTemplate, renderPlanningProgressTemplate, renderMessageRouteTemplate, renderTestReportTemplate, renderWorkflowProgressTemplate } from "../templates/handoff.js";
8
8
  import { renderRoleCommandTemplate } from "../templates/role-command.js";
9
9
  import { validateMemoryProposal } from "./memory-proposal-validation.js";
10
10
  import { isMemoryProposalSubmissionPath } from "./memory-review-paths.js";
@@ -18,6 +18,7 @@ const ARTIFACT_PATH_KEYS = [
18
18
  ["architect-debug", "architectDebugPath"],
19
19
  ["architecture-diagnosis", "architectureDiagnosisPath"],
20
20
  ["test-report", "testReportPath"],
21
+ ["docs-update-report", "docsUpdateReportPath"],
21
22
  ["docs-sync-report", "docsSyncReportPath"],
22
23
  ["workflow-progress", "workflowProgressPath"],
23
24
  ["final-acceptance", "finalAcceptancePath"]
@@ -55,6 +56,7 @@ export function createArtifactService(fs, deps = {}) {
55
56
  architectDebugPath: path.posix.join(handoffDir, "architect-debug.md"),
56
57
  architectureDiagnosisPath: path.posix.join(handoffDir, "architecture-diagnosis.md"),
57
58
  testReportPath: path.posix.join(handoffDir, "test-report.md"),
59
+ docsUpdateReportPath: path.posix.join(handoffDir, "docs-update-report.md"),
58
60
  docsSyncReportPath: path.posix.join(handoffDir, "docs-sync-report.md"),
59
61
  workflowProgressPath: path.posix.join(handoffDir, "workflow-progress.md"),
60
62
  finalAcceptancePath: path.posix.join(handoffDir, "final-acceptance.md")
@@ -85,6 +87,7 @@ export function createArtifactService(fs, deps = {}) {
85
87
  [paths.architectDebugPath, renderArchitectDebugTemplate(input.taskSlug)],
86
88
  [paths.architectureDiagnosisPath, renderArchitectureDiagnosisTemplate(input.taskSlug)],
87
89
  [paths.testReportPath, renderTestReportTemplate(input.taskSlug)],
90
+ [paths.docsUpdateReportPath, renderDocsUpdateReportTemplate(input.taskSlug)],
88
91
  [paths.docsSyncReportPath, renderDocsSyncReportTemplate(input.taskSlug)],
89
92
  [paths.workflowProgressPath, renderWorkflowProgressTemplate(input.taskSlug)],
90
93
  [paths.finalAcceptancePath, renderFinalAcceptanceTemplate(input.taskSlug)],
@@ -190,10 +193,11 @@ export function createArtifactService(fs, deps = {}) {
190
193
  }
191
194
  if (isArtifactKind(input.kind)) {
192
195
  const definition = getArtifactDefinition(input.kind);
193
- if (definition.owner !== input.role) {
196
+ const owners = Array.isArray(definition.owner) ? definition.owner : [definition.owner];
197
+ if (!owners.includes(input.role)) {
194
198
  throw new VcmError({
195
199
  code: "ARTIFACT_OWNER_MISMATCH",
196
- message: `${input.kind} is owned by ${definition.owner}, not ${input.role}.`,
200
+ message: `${input.kind} is owned by ${owners.join("|")}, not ${input.role}.`,
197
201
  statusCode: 403
198
202
  });
199
203
  }
@@ -334,39 +338,12 @@ async function validateDynamicArtifact(fs, input, content, workflowControlServic
334
338
  validateHarnessFeedback(content);
335
339
  return { kind: input.kind, root: input.baseRepoRoot, path: artifactPath };
336
340
  }
337
- if (input.kind === "retrospective-report") {
338
- if (input.role !== "harness-engineer") {
339
- throw artifactRejected(input.kind, ["Only Harness Engineer may submit a retrospective report."]);
340
- }
341
- if (!/^\.ai\/vcm\/harness-feedback\/task-retrospectives\/[A-Za-z0-9._-]+\.md$/.test(artifactPath)) {
342
- throw artifactRejected(input.kind, ["Retrospective report path must be under .ai/vcm/harness-feedback/task-retrospectives/."]);
343
- }
344
- validateRetrospectiveReport(content);
345
- return { kind: input.kind, root: input.baseRepoRoot, path: artifactPath };
346
- }
347
341
  throw new VcmError({
348
342
  code: "ARTIFACT_KIND_INVALID",
349
343
  message: `Unknown managed artifact kind: ${input.kind}`,
350
344
  statusCode: 400
351
345
  });
352
346
  }
353
- function validateRetrospectiveReport(content) {
354
- const errors = getRetrospectiveReportErrors(content);
355
- if (errors.length > 0)
356
- throw artifactRejected("retrospective-report", errors);
357
- }
358
- export function getRetrospectiveReportErrors(content) {
359
- const errors = [];
360
- if (!/^# Task Harness Retrospective(?::\s*.+)?\s*$/m.test(content)) {
361
- errors.push("Retrospective report requires '# Task Harness Retrospective: <task>'.");
362
- }
363
- for (const heading of ["Findings", "Feedback Dispositions", "Recommended Harness Changes", "VCM Issue Drafts"]) {
364
- if (!new RegExp(`^## ${escapeRegExp(heading)}\\s*$`, "m").test(content)) {
365
- errors.push(`Missing required section: ${heading}.`);
366
- }
367
- }
368
- return errors;
369
- }
370
347
  function validateCoderWorkerReport(content) {
371
348
  const errors = [];
372
349
  if (!/^# Coder Worker Report:\s*\S.+$/m.test(content)) {