@pellux/goodvibes-sdk 0.33.25 → 0.33.26

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.
@@ -3,7 +3,7 @@
3
3
  "product": {
4
4
  "id": "goodvibes",
5
5
  "surface": "operator",
6
- "version": "0.33.25"
6
+ "version": "0.33.26"
7
7
  },
8
8
  "auth": {
9
9
  "modes": [
@@ -22,6 +22,8 @@ export declare class AgentWorktree {
22
22
  * Returns true if a merge was performed, false if no changes were found.
23
23
  */
24
24
  merge(agentId: string): Promise<boolean>;
25
+ commitWorkingTree(message: string): Promise<string | null>;
26
+ currentHead(): Promise<string | null>;
25
27
  /**
26
28
  * Remove the worktree without merging (cancel/error path).
27
29
  */
@@ -33,6 +35,7 @@ export declare class AgentWorktree {
33
35
  * the current branch (the main working tree HEAD).
34
36
  */
35
37
  private _hasChanges;
38
+ private _branchExists;
36
39
  /**
37
40
  * Force-remove a worktree directory.
38
41
  */
@@ -1 +1 @@
1
- {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../../src/platform/agents/worktree.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;gBAErB,GAAG,EAAE,MAAM;IAIvB;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAU9C;;;OAGG;IACG,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA4B9C;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7C,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;IAInB;;;OAGG;YACW,WAAW;IAezB;;OAEG;YACW,eAAe;IAgB7B;;OAEG;YACW,aAAa;CAQ5B"}
1
+ {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../../src/platform/agents/worktree.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;gBAErB,GAAG,EAAE,MAAM;IAIvB;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAU9C;;;OAGG;IACG,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqCxC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmC1D,WAAW,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAU3C;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7C,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;IAInB;;;OAGG;YACW,WAAW;YAeX,aAAa;IAU3B;;OAEG;YACW,eAAe;IAgB7B;;OAEG;YACW,aAAa;CAQ5B"}
@@ -39,16 +39,24 @@ export class AgentWorktree {
39
39
  const worktreePath = this._worktreePath(agentId);
40
40
  const branch = this._branchName(agentId);
41
41
  logger.debug('AgentWorktree.merge', { agentId, worktreePath, branch });
42
+ if (!(await this._branchExists(branch))) {
43
+ logger.debug('AgentWorktree.merge: branch missing, skipping merge', { agentId, branch });
44
+ return false;
45
+ }
42
46
  // Check if the agent branch has any commits beyond base
43
47
  const hasChanges = await this._hasChanges(worktreePath, branch);
44
48
  if (!hasChanges) {
45
49
  logger.debug('AgentWorktree.merge: no changes, skipping merge', { agentId });
46
- await this._removeWorktree(worktreePath);
50
+ if (existsSync(worktreePath)) {
51
+ await this._removeWorktree(worktreePath);
52
+ }
47
53
  await this._deleteBranch(branch);
48
54
  return false;
49
55
  }
50
56
  // Remove worktree first (required before merging the branch)
51
- await this._removeWorktree(worktreePath);
57
+ if (existsSync(worktreePath)) {
58
+ await this._removeWorktree(worktreePath);
59
+ }
52
60
  // Merge the branch
53
61
  await this.git.merge(branch);
54
62
  // Clean up the agent branch
@@ -56,6 +64,50 @@ export class AgentWorktree {
56
64
  logger.debug('AgentWorktree.merge: complete', { agentId });
57
65
  return true;
58
66
  }
67
+ async commitWorkingTree(message) {
68
+ const git = simpleGit({ baseDir: this.git.getCwd() });
69
+ const status = await git.raw([
70
+ 'status',
71
+ '--porcelain',
72
+ '--untracked-files=all',
73
+ '--',
74
+ '.',
75
+ ':(exclude).goodvibes',
76
+ ':(exclude).goodvibes/**',
77
+ ]);
78
+ if (status.trim().length === 0) {
79
+ logger.debug('AgentWorktree.commitWorkingTree: no direct working tree changes');
80
+ return null;
81
+ }
82
+ await git.raw(['add', '--all', '--', '.', ':(exclude).goodvibes', ':(exclude).goodvibes/**']);
83
+ try {
84
+ const result = await this.git.commit(message, {
85
+ fallbackIdentity: { name: 'GoodVibes', email: 'goodvibes@local' },
86
+ });
87
+ logger.debug('AgentWorktree.commitWorkingTree: committed direct working tree changes', {
88
+ hash: result.hash,
89
+ });
90
+ return result.hash;
91
+ }
92
+ catch (error) {
93
+ const message = summarizeError(error).toLowerCase();
94
+ if (message.includes('nothing to commit') || message.includes('no changes added to commit')) {
95
+ logger.debug('AgentWorktree.commitWorkingTree: no committable changes after staging');
96
+ return null;
97
+ }
98
+ throw error;
99
+ }
100
+ }
101
+ async currentHead() {
102
+ try {
103
+ const git = simpleGit({ baseDir: this.git.getCwd() });
104
+ return (await git.raw(['rev-parse', 'HEAD'])).trim();
105
+ }
106
+ catch (error) {
107
+ logger.warn('AgentWorktree.currentHead failed', { error: summarizeError(error) });
108
+ return null;
109
+ }
110
+ }
59
111
  /**
60
112
  * Remove the worktree without merging (cancel/error path).
61
113
  */
@@ -98,6 +150,16 @@ export class AgentWorktree {
98
150
  return false;
99
151
  }
100
152
  }
153
+ async _branchExists(branch) {
154
+ try {
155
+ const wgit = simpleGit({ baseDir: this.git.getCwd() });
156
+ await wgit.raw(['rev-parse', '--verify', '--quiet', branch]);
157
+ return true;
158
+ }
159
+ catch {
160
+ return false;
161
+ }
162
+ }
101
163
  /**
102
164
  * Force-remove a worktree directory.
103
165
  */
@@ -9,7 +9,7 @@ import type { RuntimeEventBus } from '../runtime/events/index.js';
9
9
  import type { ProjectWorkPlanTaskCreateInput, ProjectWorkPlanTaskUpdateInput } from '../knowledge/project-planning/index.js';
10
10
  import { type AgentManagerLike } from './wrfc-config.js';
11
11
  export { extractScoreFromText, extractPassedFromText, extractIssuesFromText } from './wrfc-reporting.js';
12
- type WrfcWorktreeOps = Pick<AgentWorktree, 'merge' | 'cleanup'>;
12
+ type WrfcWorktreeOps = Pick<AgentWorktree, 'merge' | 'cleanup'> & Partial<Pick<AgentWorktree, 'commitWorkingTree' | 'currentHead'>>;
13
13
  type WrfcWorkPlanService = {
14
14
  createWorkPlanTask(input: ProjectWorkPlanTaskCreateInput): Promise<unknown>;
15
15
  updateWorkPlanTask(input: ProjectWorkPlanTaskUpdateInput): Promise<unknown>;
@@ -69,6 +69,8 @@ export declare class WrfcController {
69
69
  private scheduleChainCleanup;
70
70
  private checkAndRunGatesForAll;
71
71
  private autoCommit;
72
+ private autoCommitCandidateAgentIds;
73
+ private autoCommitMessage;
72
74
  private failChain;
73
75
  private cancelRunningChildren;
74
76
  private hasRunningChild;
@@ -1 +1 @@
1
- {"version":3,"file":"wrfc-controller.d.ts","sourceRoot":"","sources":["../../../src/platform/agents/wrfc-controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wrfc-controller.d.ts","sourceRoot":"","sources":["../../../src/platform/agents/wrfc-controller.ts"],"names":[],"mappings":"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"}
@@ -733,11 +733,9 @@ export class WrfcController {
733
733
  }
734
734
  async autoCommit(chain) {
735
735
  this.transition(chain, 'committing');
736
- const agentId = chain.allAgentIds.length > 0
737
- ? chain.allAgentIds[chain.allAgentIds.length - 1]
738
- : (chain.fixerAgentId ?? chain.engineerAgentId);
739
- if (!agentId) {
740
- this.failChain(chain, 'autoCommit: no agent ID found on chain');
736
+ const commitCandidateIds = this.autoCommitCandidateAgentIds(chain);
737
+ if (commitCandidateIds.length === 0) {
738
+ this.failChain(chain, 'autoCommit: no write-capable WRFC agent found on chain');
741
739
  return;
742
740
  }
743
741
  if (!existsSync(join(this.projectRoot, '.git'))) {
@@ -746,11 +744,29 @@ export class WrfcController {
746
744
  return;
747
745
  }
748
746
  const worktree = this.createWorktree();
747
+ let completed = false;
749
748
  try {
750
- const merged = await worktree.merge(agentId);
751
- emitWrfcAutoCommitted(this.runtimeBus, this.sessionId, chain.id);
749
+ const commitMessage = this.autoCommitMessage(chain);
750
+ const directCommitHash = worktree.commitWorkingTree
751
+ ? await worktree.commitWorkingTree(commitMessage)
752
+ : null;
753
+ let mergedCount = 0;
754
+ for (const agentId of commitCandidateIds) {
755
+ if (await worktree.merge(agentId)) {
756
+ mergedCount += 1;
757
+ }
758
+ }
759
+ const headHash = mergedCount > 0 && worktree.currentHead ? await worktree.currentHead() : directCommitHash;
760
+ emitWrfcAutoCommitted(this.runtimeBus, this.sessionId, chain.id, headHash ?? undefined);
752
761
  this.completeChainAsPassed(chain);
753
- logger.debug('WrfcController.autoCommit: success', { chainId: chain.id, agentId, merged });
762
+ completed = true;
763
+ logger.debug('WrfcController.autoCommit: success', {
764
+ chainId: chain.id,
765
+ commitCandidateIds,
766
+ directCommitHash,
767
+ mergedCount,
768
+ headHash,
769
+ });
754
770
  }
755
771
  catch (error) {
756
772
  const reason = summarizeError(error);
@@ -758,7 +774,10 @@ export class WrfcController {
758
774
  this.failChain(chain, `autoCommit failed: ${reason}`);
759
775
  }
760
776
  finally {
761
- for (const id of chain.allAgentIds) {
777
+ const cleanupIds = completed
778
+ ? chain.allAgentIds
779
+ : chain.allAgentIds.filter((id) => !commitCandidateIds.includes(id));
780
+ for (const id of cleanupIds) {
762
781
  worktree.cleanup(id).catch((error) => {
763
782
  logger.warn('WrfcController.autoCommit: cleanup failed', {
764
783
  agentId: id,
@@ -768,6 +787,37 @@ export class WrfcController {
768
787
  }
769
788
  }
770
789
  }
790
+ autoCommitCandidateAgentIds(chain) {
791
+ const candidates = [];
792
+ const add = (agentId) => {
793
+ if (agentId && !candidates.includes(agentId))
794
+ candidates.push(agentId);
795
+ };
796
+ if (chain.subtasks && chain.subtasks.length > 0) {
797
+ for (const subtask of chain.subtasks) {
798
+ add(subtask.fixerAgentId ?? subtask.engineerAgentId);
799
+ }
800
+ add(chain.integratorAgentId);
801
+ return candidates;
802
+ }
803
+ add(chain.fixerAgentId ?? chain.engineerAgentId);
804
+ add(chain.integratorAgentId);
805
+ if (candidates.length > 0) {
806
+ return candidates;
807
+ }
808
+ const writeRoles = new Set(['engineer', 'fixer', 'integrator']);
809
+ for (const agentId of chain.allAgentIds) {
810
+ const recordRole = this.agentManager.getStatus(agentId)?.wrfcRole;
811
+ const role = recordRole ?? this.workPlanRoleForAgent(chain, agentId);
812
+ if (role && writeRoles.has(role))
813
+ add(agentId);
814
+ }
815
+ return candidates;
816
+ }
817
+ autoCommitMessage(chain) {
818
+ const firstLine = chain.task.trim().replace(/\s+/g, ' ').slice(0, 72) || chain.id;
819
+ return `WRFC: ${firstLine}`;
820
+ }
771
821
  failChain(chain, reason) {
772
822
  if (chain.state === 'pending') {
773
823
  this.chainQueue = this.chainQueue.filter((queued) => queued.record.id !== chain.ownerAgentId);
@@ -56,6 +56,10 @@ export declare class GitService {
56
56
  commit(message: string, options?: {
57
57
  amend?: boolean;
58
58
  noVerify?: boolean;
59
+ fallbackIdentity?: {
60
+ name: string;
61
+ email: string;
62
+ } | undefined;
59
63
  }): Promise<{
60
64
  hash: string;
61
65
  summary: string;
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/platform/git/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/platform/git/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAc7D;;;;;;GAMG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,KAAK,CAAwB;IACrC,OAAO,CAAC,GAAG,CAAS;gBAER,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,cAAc;IAU/C,OAAO,CAAC,SAAS;YAgBH,OAAO;YAWP,QAAQ;YAQR,QAAQ;IAYhB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAI3D,MAAM,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IASxE,GAAG,CACP,QAAQ,SAAK,GACZ,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAU5E,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOzC;;;OAGG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAOlE;;;OAGG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAQnF;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIxD,KAAK,CACT,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAkC5E,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAY/C,MAAM,CACV,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,gBAAgB,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAC;KAChE,GACA,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IA6CvC,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAC7B,OAAO,CAAC,IAAI,CAAC;IAeV,KAAK,CACT,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IA4BhD,IAAI,CACR,MAAM,SAAW,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAC5B,OAAO,CAAC,IAAI,CAAC;IAaV,IAAI,CACR,MAAM,SAAW,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IAeV,KAAK,CACT,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAe,EACjD,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAmCZ,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3C,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAapF;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IASlE;;;OAGG;IACH,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAKtC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAO9C,8DAA8D;IAC9D,MAAM,IAAI,MAAM;IAIhB,0DAA0D;IAC1D,OAAO,IAAI,IAAI;CAGhB"}
@@ -1,6 +1,12 @@
1
1
  import { simpleGit } from 'simple-git';
2
2
  import { logger } from '../utils/logger.js';
3
3
  import { summarizeError } from '../utils/error-display.js';
4
+ function isMissingGitIdentityError(error) {
5
+ const message = summarizeError(error).toLowerCase();
6
+ return (message.includes('author identity unknown')
7
+ || message.includes('please tell me who you are')
8
+ || message.includes('unable to auto-detect email address'));
9
+ }
4
10
  /**
5
11
  * GitService — Wraps simple-git with hook emission on all mutating operations.
6
12
  *
@@ -168,6 +174,33 @@ export class GitService {
168
174
  return output;
169
175
  }
170
176
  catch (err) {
177
+ if (options?.fallbackIdentity && isMissingGitIdentityError(err)) {
178
+ try {
179
+ const flags = [];
180
+ if (options.amend)
181
+ flags.push('--amend');
182
+ if (options.noVerify)
183
+ flags.push('--no-verify');
184
+ const raw = await this.git.raw([
185
+ '-c',
186
+ `user.name=${options.fallbackIdentity.name}`,
187
+ '-c',
188
+ `user.email=${options.fallbackIdentity.email}`,
189
+ 'commit',
190
+ '-m',
191
+ message,
192
+ ...flags,
193
+ ]);
194
+ const hash = (await this.git.raw(['rev-parse', 'HEAD'])).trim();
195
+ const output = { hash, summary: raw.trim() };
196
+ await this.firePost('commit', { message, ...output });
197
+ return output;
198
+ }
199
+ catch (fallbackErr) {
200
+ await this.fireFail('commit', { message, error: summarizeError(fallbackErr) });
201
+ throw fallbackErr;
202
+ }
203
+ }
171
204
  await this.fireFail('commit', { message, error: summarizeError(err) });
172
205
  throw err;
173
206
  }
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- let version = '0.33.25';
3
+ let version = '0.33.26';
4
4
  try {
5
5
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', '..', 'package.json'), 'utf-8'));
6
6
  version = pkg.version ?? version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-sdk",
3
- "version": "0.33.25",
3
+ "version": "0.33.26",
4
4
  "description": "TypeScript SDK for building GoodVibes operator, peer, web, mobile, and daemon-connected apps with typed contracts, auth, realtime events, and transport layers.",
5
5
  "keywords": [
6
6
  "goodvibes",
@@ -449,14 +449,14 @@
449
449
  "sideEffects": false,
450
450
  "type": "module",
451
451
  "dependencies": {
452
- "@pellux/goodvibes-contracts": "0.33.25",
453
- "@pellux/goodvibes-daemon-sdk": "0.33.25",
454
- "@pellux/goodvibes-errors": "0.33.25",
455
- "@pellux/goodvibes-operator-sdk": "0.33.25",
456
- "@pellux/goodvibes-peer-sdk": "0.33.25",
457
- "@pellux/goodvibes-transport-core": "0.33.25",
458
- "@pellux/goodvibes-transport-http": "0.33.25",
459
- "@pellux/goodvibes-transport-realtime": "0.33.25"
452
+ "@pellux/goodvibes-contracts": "0.33.26",
453
+ "@pellux/goodvibes-daemon-sdk": "0.33.26",
454
+ "@pellux/goodvibes-errors": "0.33.26",
455
+ "@pellux/goodvibes-operator-sdk": "0.33.26",
456
+ "@pellux/goodvibes-peer-sdk": "0.33.26",
457
+ "@pellux/goodvibes-transport-core": "0.33.26",
458
+ "@pellux/goodvibes-transport-http": "0.33.26",
459
+ "@pellux/goodvibes-transport-realtime": "0.33.26"
460
460
  },
461
461
  "optionalDependencies": {
462
462
  "@agentclientprotocol/sdk": "^0.21.0",