vibe-coding-master 0.8.2 → 0.8.3

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/README.md CHANGED
@@ -506,14 +506,9 @@ provide the language server for each detected language: `rust-analyzer`,
506
506
  relationships. Accessors, backing fields, trait items, implementations, wrappers,
507
507
  and aliases are queried as separate symbols; a bounded source-text fallback may
508
508
  only locate candidates after the correct LSP query is demonstrably partial.
509
- Other roles use generated context and ordinary source reads.
510
- Harness Studio reports
511
- whether the server executable and plugin can run; the role Session performs the
512
- real workspace indexing and semantic query retries. VCM uses Claude Code progress
513
- hooks to detect a model response, tool call, subagent, or compaction that may be
514
- stalled. Detection only opens a warning; it does not interrupt the Session or
515
- change the Round. The user can ignore that warning or explicitly stop and resume
516
- the same Claude Session from the warning dialog.
509
+ Other roles use generated context and ordinary source reads. Harness Studio
510
+ reports whether the server executable and plugin can run; the role Session
511
+ performs the real workspace indexing and semantic query retries.
517
512
 
518
513
  Harness Engineer is task-scoped and runs from the active task worktree. The
519
514
  backend automatically starts a fresh Harness Engineer for each active task or
@@ -77,8 +77,7 @@ export function registerTaskRoutes(app, deps) {
77
77
  orchestration,
78
78
  roundState: displayedRoundState,
79
79
  workflowState,
80
- architectRestart: deps.architectRestartService.getState(project.repoRoot, taskSlug),
81
- roleStallWarning: deps.roleStallDetector.getWarning(project.repoRoot, taskSlug)
80
+ architectRestart: deps.architectRestartService.getState(project.repoRoot, taskSlug)
82
81
  };
83
82
  }
84
83
  catch (error) {
@@ -93,30 +92,12 @@ export function registerTaskRoutes(app, deps) {
93
92
  },
94
93
  roundState: degradedRoundState(taskSlug),
95
94
  workflowState: degradedWorkflowState(taskSlug),
96
- architectRestart: deps.architectRestartService.getState(repoRoot, taskSlug),
97
- roleStallWarning: deps.roleStallDetector.getWarning(repoRoot, taskSlug)
95
+ architectRestart: deps.architectRestartService.getState(repoRoot, taskSlug)
98
96
  };
99
97
  }
100
98
  throw error;
101
99
  }
102
100
  });
103
- app.post("/api/tasks/:taskSlug/role-stall/ignore", async (request) => {
104
- const project = await requireCurrentProject(deps.projectService);
105
- return deps.roleStallDetector.ignoreWarning(project.repoRoot, request.params.taskSlug, requireWarningId(request.body?.warningId));
106
- });
107
- app.post("/api/tasks/:taskSlug/role-stall/recover", async (request) => {
108
- const project = await requireCurrentProject(deps.projectService);
109
- const config = await deps.projectService.loadConfig(project.repoRoot);
110
- const task = await deps.taskService.loadTask(project.repoRoot, request.params.taskSlug);
111
- const taskRepoRoot = getTaskRuntimeRepoRoot(task);
112
- return deps.roleStallDetector.recoverWarning({
113
- repoRoot: project.repoRoot,
114
- taskRepoRoot,
115
- stateRoot: config.stateRoot,
116
- taskSlug: task.taskSlug,
117
- warningId: requireWarningId(request.body?.warningId)
118
- });
119
- });
120
101
  app.post("/api/tasks/:taskSlug/workflow-state", async (request) => {
121
102
  const project = await requireCurrentProject(deps.projectService);
122
103
  const config = await deps.projectService.loadConfig(project.repoRoot);
@@ -155,16 +136,6 @@ async function delayFlowPauseForTranslation(deps, input) {
155
136
  return input.roundState;
156
137
  }
157
138
  }
158
- function requireWarningId(value) {
159
- if (typeof value === "string" && value.trim()) {
160
- return value.trim();
161
- }
162
- throw new VcmError({
163
- code: "ROLE_STALL_WARNING_ID_REQUIRED",
164
- message: "A role stall warning id is required.",
165
- statusCode: 400
166
- });
167
- }
168
139
  async function requireCurrentProject(projectService) {
169
140
  const project = await projectService.getCurrentProject();
170
141
  if (!project) {
@@ -63,15 +63,8 @@ const VCM_HOOK_DEFINITIONS = [
63
63
  { eventName: "PreToolUse", matcher: "Write|Edit", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
64
64
  { eventName: "PreToolUse", matcher: "Agent", command: VCM_SUBAGENT_GUARD_HOOK_COMMAND, timeout: 10 },
65
65
  { eventName: "UserPromptSubmit", command: VCM_HOOK_COMMAND, timeout: 5 },
66
- { eventName: "PreToolUse", command: VCM_HOOK_COMMAND, timeout: 5 },
67
- { eventName: "PostToolUse", command: VCM_HOOK_COMMAND, timeout: 5 },
68
- { eventName: "PostToolUseFailure", command: VCM_HOOK_COMMAND, timeout: 5 },
69
- { eventName: "PostToolBatch", command: VCM_HOOK_COMMAND, timeout: 5 },
70
- { eventName: "SubagentStart", command: VCM_HOOK_COMMAND, timeout: 5 },
71
- { eventName: "SubagentStop", command: VCM_HOOK_COMMAND, timeout: 5 },
72
66
  { eventName: "Stop", command: VCM_STOP_HOOK_COMMAND, timeout: 10 },
73
67
  { eventName: "StopFailure", command: VCM_HOOK_COMMAND, timeout: 5 },
74
- { eventName: "PreCompact", command: VCM_HOOK_COMMAND, timeout: 5 },
75
68
  { eventName: "PostCompact", command: VCM_HOOK_COMMAND, timeout: 5 },
76
69
  { eventName: "PermissionRequest", command: VCM_PERMISSION_REQUEST_HOOK_COMMAND, timeout: 5 }
77
70
  ];
@@ -14,7 +14,6 @@ import { createCodexBridgeIntegrationService } from "./services/codex-bridge-int
14
14
  import { createAutoMemoryService } from "./services/auto-memory-service.js";
15
15
  import { createArchitectRestartService } from "./services/architect-restart-service.js";
16
16
  import { createRoleContextRestartService } from "./services/role-context-restart-service.js";
17
- import { createRoleStallDetectorService } from "./services/role-stall-detector-service.js";
18
17
  import { createClaudeTranscriptService } from "./services/claude-transcript-service.js";
19
18
  import { createGateReviewService } from "./services/gate-review-service.js";
20
19
  import { createHarnessFeedbackService } from "./services/harness-feedback-service.js";
@@ -137,7 +136,6 @@ export async function createServer(deps, options = {}) {
137
136
  roundService: deps.roundService,
138
137
  taskWorkflowService: deps.taskWorkflowService,
139
138
  architectRestartService: deps.architectRestartService,
140
- roleStallDetector: deps.roleStallDetector,
141
139
  translationService: deps.translationService
142
140
  });
143
141
  registerSessionRoutes(app, {
@@ -351,10 +349,6 @@ export function createDefaultServerDeps(options = {}) {
351
349
  sessionService
352
350
  });
353
351
  const transcripts = createClaudeTranscriptService();
354
- const roleStallDetector = createRoleStallDetectorService({
355
- sessionService,
356
- roundService
357
- });
358
352
  const translationService = createTranslationService({
359
353
  runtime,
360
354
  sessionRegistry: registry,
@@ -432,7 +426,6 @@ export function createDefaultServerDeps(options = {}) {
432
426
  translationWorkerService,
433
427
  architectRestartService,
434
428
  roleContextRestartService,
435
- roleStallDetector,
436
429
  workflowControlService
437
430
  });
438
431
  const runtimeCoordinator = createRuntimeCoordinatorService({
@@ -445,7 +438,6 @@ export function createDefaultServerDeps(options = {}) {
445
438
  harnessFeedbackService,
446
439
  autoMemoryService,
447
440
  roundService,
448
- roleStallDetector,
449
441
  gatewayService,
450
442
  async getStateRoot(repoRoot) {
451
443
  return (await projectService.loadConfig(repoRoot)).stateRoot;
@@ -487,7 +479,6 @@ export function createDefaultServerDeps(options = {}) {
487
479
  autoMemoryService,
488
480
  commandDispatcher,
489
481
  claudeHookService,
490
- roleStallDetector,
491
482
  messageService,
492
483
  taskLaunchService,
493
484
  gateReviewService,
@@ -257,12 +257,6 @@ export function createClaudeHookService(deps) {
257
257
  role: input.role,
258
258
  eventName
259
259
  });
260
- await deps.roleStallDetector?.recordHook({
261
- ...createStallContext(context),
262
- role: input.role,
263
- eventName,
264
- event: input.event
265
- });
266
260
  }
267
261
  if (session) {
268
262
  await deps.translationService.recordConversationBoundary({
@@ -360,12 +354,6 @@ export function createClaudeHookService(deps) {
360
354
  }
361
355
  }
362
356
  }
363
- await deps.roleStallDetector?.recordHook({
364
- ...createStallContext(context),
365
- role: input.role,
366
- eventName,
367
- event: input.event
368
- });
369
357
  if (pmAwaitingUser) {
370
358
  return recordTurnEnd(input, context, eventName, {
371
359
  dispatchRouteFiles: false,
@@ -417,12 +405,6 @@ export function createClaudeHookService(deps) {
417
405
  if (memoryResult) {
418
406
  return memoryResult;
419
407
  }
420
- await deps.roleStallDetector?.recordHook({
421
- ...createStallContext(context),
422
- role: input.role,
423
- eventName,
424
- event: input.event
425
- });
426
408
  const routeDispatchInput = createRouteDispatchInput(input, context);
427
409
  const pending = await deps.messageService.listPendingRouteFiles(routeDispatchInput);
428
410
  const hasCompletionEvidence = pending.some((routeFile) => routeFile.fromRole === input.role);
@@ -496,14 +478,6 @@ export function createClaudeHookService(deps) {
496
478
  runtimeSessionId: stringOrUndefined(input.event.vcm_runtime_session_id),
497
479
  runtimeSessionToken: input.runtimeSessionToken
498
480
  });
499
- if (session) {
500
- await deps.roleStallDetector?.recordHook({
501
- ...createStallContext(context),
502
- role: input.role,
503
- eventName,
504
- event: input.event
505
- });
506
- }
507
481
  return {
508
482
  ok: true,
509
483
  eventName,
@@ -637,14 +611,6 @@ export function createClaudeHookService(deps) {
637
611
  eventName
638
612
  });
639
613
  }
640
- if (boundToTask) {
641
- await deps.roleStallDetector?.recordHook({
642
- ...createStallContext(context),
643
- role: input.role,
644
- eventName,
645
- event: input.event
646
- });
647
- }
648
614
  await deps.autoMemoryService.handleRoleHook({
649
615
  baseRepoRoot: context.project.repoRoot,
650
616
  taskRepoRoot: context.taskRepoRoot,
@@ -869,31 +835,6 @@ export function createClaudeHookService(deps) {
869
835
  taskSlug: context.taskSlug
870
836
  };
871
837
  }
872
- function createStallContext(context) {
873
- return {
874
- repoRoot: context.project.repoRoot,
875
- taskRepoRoot: context.taskRepoRoot,
876
- stateRoot: context.config.stateRoot,
877
- taskSlug: context.taskSlug
878
- };
879
- }
880
- async function processProgressHook(input, eventName) {
881
- const role = input.role;
882
- if (!isVcmRoleName(role)) {
883
- return completedHookResult(input, eventName);
884
- }
885
- const context = await getHookContext(input);
886
- if (!(await isCurrentRoleHook(context, input, eventName))) {
887
- return completedHookResult(input, eventName);
888
- }
889
- await deps.roleStallDetector?.recordHook({
890
- ...createStallContext(context),
891
- role,
892
- eventName,
893
- event: input.event
894
- });
895
- return completedHookResult(input, eventName);
896
- }
897
838
  function renderStopFailureRecoveryPrompt() {
898
839
  return [
899
840
  "[VCM Recovery]",
@@ -936,17 +877,6 @@ export function createClaudeHookService(deps) {
936
877
  });
937
878
  }
938
879
  const preferences = await deps.appSettings.getPreferences();
939
- if (deps.roleStallDetector) {
940
- const context = await getHookContext(input);
941
- if (await isCurrentRoleHook(context, input, "PermissionRequest")) {
942
- await deps.roleStallDetector.recordHook({
943
- ...createStallContext(context),
944
- role: input.role,
945
- eventName: "PermissionRequest",
946
- event: input.event
947
- });
948
- }
949
- }
950
880
  if (preferences.permissionRequestMode !== "allowAll") {
951
881
  return undefined;
952
882
  }
@@ -963,9 +893,6 @@ export function createClaudeHookService(deps) {
963
893
  async handleHook(input) {
964
894
  return withRoleHookLock(input, async () => {
965
895
  const eventName = parseHookEvent(input.event.hook_event_name);
966
- if (isProgressHook(eventName)) {
967
- return processProgressHook(input, eventName);
968
- }
969
896
  if (isTranslatorToolRoleName(input.role)) {
970
897
  return processTranslatorHook(input);
971
898
  }
@@ -1004,13 +931,6 @@ function parseHookEvent(value) {
1004
931
  if (value === "UserPromptSubmit"
1005
932
  || value === "Stop"
1006
933
  || value === "StopFailure"
1007
- || value === "PreToolUse"
1008
- || value === "PostToolUse"
1009
- || value === "PostToolUseFailure"
1010
- || value === "PostToolBatch"
1011
- || value === "SubagentStart"
1012
- || value === "SubagentStop"
1013
- || value === "PreCompact"
1014
934
  || value === "PostCompact") {
1015
935
  return value;
1016
936
  }
@@ -1021,15 +941,6 @@ function parseHookEvent(value) {
1021
941
  hint: "Use a Claude Code event installed by the VCM Harness."
1022
942
  });
1023
943
  }
1024
- function isProgressHook(eventName) {
1025
- return eventName === "PreToolUse"
1026
- || eventName === "PostToolUse"
1027
- || eventName === "PostToolUseFailure"
1028
- || eventName === "PostToolBatch"
1029
- || eventName === "SubagentStart"
1030
- || eventName === "SubagentStop"
1031
- || eventName === "PreCompact";
1032
- }
1033
944
  function parseBusinessHookEvent(value) {
1034
945
  const eventName = parseHookEvent(value);
1035
946
  if (eventName === "UserPromptSubmit"
@@ -63,15 +63,8 @@ const VCM_HOOK_DEFINITIONS = [
63
63
  { eventName: "PreToolUse", matcher: "Write|Edit", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
64
64
  { eventName: "PreToolUse", matcher: "Agent", command: VCM_SUBAGENT_GUARD_HOOK_COMMAND, timeout: 10 },
65
65
  { eventName: "UserPromptSubmit", command: VCM_HOOK_COMMAND, timeout: 5 },
66
- { eventName: "PreToolUse", command: VCM_HOOK_COMMAND, timeout: 5 },
67
- { eventName: "PostToolUse", command: VCM_HOOK_COMMAND, timeout: 5 },
68
- { eventName: "PostToolUseFailure", command: VCM_HOOK_COMMAND, timeout: 5 },
69
- { eventName: "PostToolBatch", command: VCM_HOOK_COMMAND, timeout: 5 },
70
- { eventName: "SubagentStart", command: VCM_HOOK_COMMAND, timeout: 5 },
71
- { eventName: "SubagentStop", command: VCM_HOOK_COMMAND, timeout: 5 },
72
66
  { eventName: "Stop", command: VCM_STOP_HOOK_COMMAND, timeout: 10 },
73
67
  { eventName: "StopFailure", command: VCM_HOOK_COMMAND, timeout: 5 },
74
- { eventName: "PreCompact", command: VCM_HOOK_COMMAND, timeout: 5 },
75
68
  { eventName: "PostCompact", command: VCM_HOOK_COMMAND, timeout: 5 },
76
69
  { eventName: "PermissionRequest", command: VCM_PERMISSION_REQUEST_HOOK_COMMAND, timeout: 5 }
77
70
  ];
@@ -42,17 +42,9 @@ export function createRuntimeCoordinatorService(deps) {
42
42
  ]);
43
43
  const preferences = await deps.appSettings.getPreferences();
44
44
  if (!activeTask) {
45
- deps.roleStallDetector.clearProject(repoRoot);
46
45
  return { activeTask: null, gatewayStatus };
47
46
  }
48
47
  const taskRepoRoot = getTaskRuntimeRepoRoot(activeTask);
49
- const stateRoot = await deps.getStateRoot(repoRoot);
50
- await deps.roleStallDetector.reconcileTask({
51
- repoRoot,
52
- taskRepoRoot,
53
- stateRoot,
54
- taskSlug: activeTask.taskSlug
55
- });
56
48
  const harnessInitialized = await deps.harnessService.getHarnessStatus(taskRepoRoot)
57
49
  .then((status) => status.initialized)
58
50
  .catch(() => false);
@@ -86,7 +78,6 @@ export function createRuntimeCoordinatorService(deps) {
86
78
  void reconcileCurrentProject().catch(() => undefined);
87
79
  },
88
80
  stop() {
89
- deps.roleStallDetector.stop();
90
81
  if (reconcileTimer === undefined) {
91
82
  return;
92
83
  }
@@ -98,7 +89,6 @@ export function createRuntimeCoordinatorService(deps) {
98
89
  async function reconcileCurrentProject() {
99
90
  const project = await deps.projectService.getCurrentProject();
100
91
  if (!project) {
101
- deps.roleStallDetector.stop();
102
92
  return;
103
93
  }
104
94
  await reconcileProject(project.repoRoot);
@@ -721,8 +721,7 @@ export function createSessionService(deps) {
721
721
  return undefined;
722
722
  }
723
723
  const timestamp = now();
724
- const turnWasRunning = current.activityStatus === "running"
725
- && current.expectedRuntimeExitReason !== "role-stall-recovery";
724
+ const turnWasRunning = current.activityStatus === "running";
726
725
  const updated = {
727
726
  ...current,
728
727
  status: input.status,
@@ -738,71 +737,6 @@ export function createSessionService(deps) {
738
737
  await persistRoleSessionRecord(deps.fs, repoRoot, getTaskRuntimeRepoRoot(task), config.stateRoot, updated);
739
738
  return { record: updated, turnWasRunning };
740
739
  }
741
- async function persistTaskRoleRecord(repoRoot, taskSlug, record) {
742
- deps.registry.upsert(record);
743
- const config = await deps.projectService.loadConfig(repoRoot);
744
- const task = await deps.taskService.loadTask(repoRoot, taskSlug);
745
- await persistRoleSessionRecord(deps.fs, repoRoot, getTaskRuntimeRepoRoot(task), config.stateRoot, record);
746
- return record;
747
- }
748
- async function recoverRoleSession(repoRoot, taskSlug, input) {
749
- const current = await getTaskRoleSessionView(repoRoot, taskSlug, input.role);
750
- if (!current
751
- || current.id !== input.expectedSessionId
752
- || current.runtimeSessionToken !== input.expectedRuntimeSessionToken
753
- || current.status !== "running"
754
- || current.activityStatus !== "running") {
755
- throw new VcmError({
756
- code: "ROLE_STALL_SESSION_CHANGED",
757
- message: `${input.role} session changed before recovery could begin.`,
758
- statusCode: 409
759
- });
760
- }
761
- if (!current.claudeSessionId) {
762
- throw new VcmError({
763
- code: "CLAUDE_SESSION_MISSING",
764
- message: `${input.role} does not have a confirmed Claude session id to resume.`,
765
- statusCode: 409
766
- });
767
- }
768
- const prepared = await persistTaskRoleRecord(repoRoot, taskSlug, {
769
- ...current,
770
- expectedRuntimeExitReason: "role-stall-recovery",
771
- updatedAt: now()
772
- });
773
- if (deps.runtime.getSession(prepared.id)) {
774
- await deps.runtime.stop(prepared.id);
775
- }
776
- await persistTaskRoleRecord(repoRoot, taskSlug, {
777
- ...prepared,
778
- status: "exited",
779
- activityStatus: "idle",
780
- pid: undefined,
781
- expectedRuntimeExitReason: undefined,
782
- updatedAt: now()
783
- });
784
- const resumed = await launchRoleSession(repoRoot, taskSlug, input.role, {
785
- permissionMode: prepared.permissionMode,
786
- model: prepared.model,
787
- effort: prepared.effort
788
- }, "resume");
789
- if ((await waitForSessionInputReady(resumed.id)) === "exited") {
790
- throw new VcmError({
791
- code: "ROLE_STALL_RESUME_FAILED",
792
- message: `${input.role} session exited before recovery input could be submitted.`,
793
- statusCode: 409
794
- });
795
- }
796
- await submitTerminalInput(deps.runtime, resumed.id, input.recoveryPrompt);
797
- return persistTaskRoleRecord(repoRoot, taskSlug, {
798
- ...resumed,
799
- activityStatus: "running",
800
- lastTurnStartedAt: now(),
801
- lastHookEventAt: now(),
802
- expectedRuntimeExitReason: undefined,
803
- updatedAt: now()
804
- });
805
- }
806
740
  return {
807
741
  async assertModelLaunchReady(model = "default") {
808
742
  await getModelLaunchEnvironment(normalizeClaudeModel(model));
@@ -1307,8 +1241,7 @@ export function createSessionService(deps) {
1307
1241
  : undefined;
1308
1242
  }
1309
1243
  return markTaskRoleActivityIdle(repoRoot, taskSlug, role);
1310
- },
1311
- recoverRoleSession
1244
+ }
1312
1245
  };
1313
1246
  }
1314
1247
  function toRoleSessionRecordView(record, runtime) {
@@ -1398,7 +1331,7 @@ function isSessionMissingError(error) {
1398
1331
  error.code === "SESSION_MISSING";
1399
1332
  }
1400
1333
  function withoutRuntimeOnlySessionFields(session) {
1401
- const { pid: _pid, runtimeSessionToken: _runtimeSessionToken, expectedRuntimeExitReason: _expectedRuntimeExitReason, ...persisted } = session;
1334
+ const { pid: _pid, runtimeSessionToken: _runtimeSessionToken, ...persisted } = session;
1402
1335
  return persisted;
1403
1336
  }
1404
1337
  function defaultIsProcessAlive(pid) {