@pellux/goodvibes-sdk 0.18.17 → 0.18.18

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 (78) hide show
  1. package/dist/_internal/platform/agents/orchestrator-runner.d.ts +5 -4
  2. package/dist/_internal/platform/agents/orchestrator-runner.d.ts.map +1 -1
  3. package/dist/_internal/platform/agents/orchestrator-runner.js +9 -8
  4. package/dist/_internal/platform/agents/orchestrator.d.ts.map +1 -1
  5. package/dist/_internal/platform/agents/orchestrator.js +1 -0
  6. package/dist/_internal/platform/agents/wrfc-controller.d.ts +2 -1
  7. package/dist/_internal/platform/agents/wrfc-controller.d.ts.map +1 -1
  8. package/dist/_internal/platform/agents/wrfc-controller.js +6 -6
  9. package/dist/_internal/platform/agents/wrfc-workmap.d.ts +4 -1
  10. package/dist/_internal/platform/agents/wrfc-workmap.d.ts.map +1 -1
  11. package/dist/_internal/platform/agents/wrfc-workmap.js +4 -2
  12. package/dist/_internal/platform/automation/schedules.js +1 -1
  13. package/dist/_internal/platform/bookmarks/manager.d.ts +1 -1
  14. package/dist/_internal/platform/bookmarks/manager.js +1 -1
  15. package/dist/_internal/platform/config/schema-domain-core.js +1 -1
  16. package/dist/_internal/platform/config/schema-domain-runtime.js +1 -1
  17. package/dist/_internal/platform/config/service-registry.d.ts +1 -1
  18. package/dist/_internal/platform/config/service-registry.js +1 -1
  19. package/dist/_internal/platform/config/subscription-providers.js +1 -1
  20. package/dist/_internal/platform/daemon/facade-composition.d.ts.map +1 -1
  21. package/dist/_internal/platform/daemon/facade-composition.js +4 -0
  22. package/dist/_internal/platform/daemon/service-manager.d.ts +8 -0
  23. package/dist/_internal/platform/daemon/service-manager.d.ts.map +1 -1
  24. package/dist/_internal/platform/daemon/service-manager.js +41 -27
  25. package/dist/_internal/platform/input/keybindings.d.ts +2 -1
  26. package/dist/_internal/platform/input/keybindings.d.ts.map +1 -1
  27. package/dist/_internal/platform/input/keybindings.js +2 -1
  28. package/dist/_internal/platform/intelligence/config.d.ts +1 -1
  29. package/dist/_internal/platform/intelligence/config.d.ts.map +1 -1
  30. package/dist/_internal/platform/intelligence/config.js +8 -4
  31. package/dist/_internal/platform/intelligence/facade.d.ts +1 -1
  32. package/dist/_internal/platform/intelligence/facade.js +2 -2
  33. package/dist/_internal/platform/profiles/manager.d.ts +1 -1
  34. package/dist/_internal/platform/profiles/manager.js +1 -1
  35. package/dist/_internal/platform/providers/anthropic-compat.d.ts +1 -1
  36. package/dist/_internal/platform/providers/anthropic-compat.js +1 -1
  37. package/dist/_internal/platform/providers/custom-loader.d.ts +1 -1
  38. package/dist/_internal/platform/providers/registry.d.ts +2 -2
  39. package/dist/_internal/platform/providers/registry.js +2 -2
  40. package/dist/_internal/platform/runtime/ecosystem/catalog.js +6 -6
  41. package/dist/_internal/platform/runtime/services.d.ts.map +1 -1
  42. package/dist/_internal/platform/runtime/services.js +3 -2
  43. package/dist/_internal/platform/runtime/session-persistence.d.ts +1 -0
  44. package/dist/_internal/platform/runtime/session-persistence.d.ts.map +1 -1
  45. package/dist/_internal/platform/runtime/session-persistence.js +4 -4
  46. package/dist/_internal/platform/runtime/surface-root.d.ts +2 -0
  47. package/dist/_internal/platform/runtime/surface-root.d.ts.map +1 -1
  48. package/dist/_internal/platform/runtime/surface-root.js +8 -0
  49. package/dist/_internal/platform/runtime/worktree/registry.d.ts +5 -1
  50. package/dist/_internal/platform/runtime/worktree/registry.d.ts.map +1 -1
  51. package/dist/_internal/platform/runtime/worktree/registry.js +20 -17
  52. package/dist/_internal/platform/scheduler/scheduler.d.ts +1 -1
  53. package/dist/_internal/platform/scheduler/scheduler.js +1 -1
  54. package/dist/_internal/platform/sessions/manager.d.ts +5 -2
  55. package/dist/_internal/platform/sessions/manager.d.ts.map +1 -1
  56. package/dist/_internal/platform/sessions/manager.js +4 -3
  57. package/dist/_internal/platform/tools/fetch/schema.d.ts +1 -1
  58. package/dist/_internal/platform/tools/fetch/schema.js +1 -1
  59. package/dist/_internal/platform/tools/index.js +6 -6
  60. package/dist/_internal/platform/tools/packet/index.d.ts +4 -1
  61. package/dist/_internal/platform/tools/packet/index.d.ts.map +1 -1
  62. package/dist/_internal/platform/tools/packet/index.js +5 -2
  63. package/dist/_internal/platform/tools/query/index.d.ts +4 -1
  64. package/dist/_internal/platform/tools/query/index.d.ts.map +1 -1
  65. package/dist/_internal/platform/tools/query/index.js +5 -2
  66. package/dist/_internal/platform/tools/registry-tool/index.d.ts.map +1 -1
  67. package/dist/_internal/platform/tools/registry-tool/index.js +2 -4
  68. package/dist/_internal/platform/tools/registry-tool/skill-loader.d.ts.map +1 -1
  69. package/dist/_internal/platform/tools/registry-tool/skill-loader.js +1 -2
  70. package/dist/_internal/platform/tools/team/index.d.ts +3 -0
  71. package/dist/_internal/platform/tools/team/index.d.ts.map +1 -1
  72. package/dist/_internal/platform/tools/team/index.js +124 -119
  73. package/dist/_internal/platform/tools/worklist/index.d.ts +3 -0
  74. package/dist/_internal/platform/tools/worklist/index.d.ts.map +1 -1
  75. package/dist/_internal/platform/tools/worklist/index.js +108 -103
  76. package/dist/_internal/platform/watchers/store.d.ts.map +1 -1
  77. package/dist/_internal/platform/watchers/store.js +3 -2
  78. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { join, resolve } from 'node:path';
3
+ import { resolveScopedDirectory } from '../../runtime/surface-root.js';
3
4
  import { PACKET_TOOL_SCHEMA } from './schema.js';
4
5
  function summarizePacket(record) {
5
6
  return {
@@ -16,9 +17,11 @@ function summarizePacket(record) {
16
17
  publishedAt: record.publishedAt,
17
18
  };
18
19
  }
19
- export function createPacketTool(workingDirectory) {
20
+ export function createPacketTool(options) {
21
+ const workingDirectory = typeof options === 'string' ? options : options.workingDirectory;
22
+ const surfaceRoot = typeof options === 'string' ? undefined : options.surfaceRoot;
20
23
  const workspaceRoot = resolve(workingDirectory);
21
- const packetsDir = join(workspaceRoot, '.goodvibes', 'goodvibes');
24
+ const packetsDir = resolveScopedDirectory(workspaceRoot, surfaceRoot);
22
25
  const packetsPath = join(packetsDir, 'packets.json');
23
26
  function loadPackets() {
24
27
  try {
@@ -1,3 +1,6 @@
1
1
  import type { Tool } from '../../types/tools.js';
2
- export declare function createQueryTool(workingDirectory: string): Tool;
2
+ export declare function createQueryTool(options: string | {
3
+ readonly workingDirectory: string;
4
+ readonly surfaceRoot?: string;
5
+ }): Tool;
3
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/query/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AA6BjD,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAiG9D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/query/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AA8BjD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACrF,IAAI,CAmGN"}
@@ -1,5 +1,6 @@
1
1
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { join, resolve } from 'node:path';
3
+ import { resolveScopedDirectory } from '../../runtime/surface-root.js';
3
4
  import { QUERY_TOOL_SCHEMA } from './schema.js';
4
5
  function summarizeQuery(record) {
5
6
  return {
@@ -14,9 +15,11 @@ function summarizeQuery(record) {
14
15
  updatedAt: record.updatedAt,
15
16
  };
16
17
  }
17
- export function createQueryTool(workingDirectory) {
18
+ export function createQueryTool(options) {
19
+ const workingDirectory = typeof options === 'string' ? options : options.workingDirectory;
20
+ const surfaceRoot = typeof options === 'string' ? undefined : options.surfaceRoot;
18
21
  const workspaceRoot = resolve(workingDirectory);
19
- const queriesDir = join(workspaceRoot, '.goodvibes', 'goodvibes');
22
+ const queriesDir = resolveScopedDirectory(workspaceRoot, surfaceRoot);
20
23
  const queriesPath = join(queriesDir, 'queries.json');
21
24
  function loadQueries() {
22
25
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/registry-tool/index.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,IAAI,EAAkB,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAmCnD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAiID;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAwC7F"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/registry-tool/index.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,IAAI,EAAkB,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAmCnD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AA6HD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAwC7F"}
@@ -114,20 +114,18 @@ function fuzzyFilter(items, query) {
114
114
  function getSkillDirs(roots) {
115
115
  const dirs = [
116
116
  join(roots.workingDirectory, '.goodvibes', 'skills'),
117
- join(roots.workingDirectory, '.goodvibes', 'goodvibes', 'skills'),
118
117
  ];
119
118
  if (roots.homeDirectory) {
120
- dirs.push(join(roots.homeDirectory, '.goodvibes', 'skills'), join(roots.homeDirectory, '.goodvibes', 'goodvibes', 'skills'));
119
+ dirs.push(join(roots.homeDirectory, '.goodvibes', 'skills'));
121
120
  }
122
121
  return dirs;
123
122
  }
124
123
  function getAgentDirs(roots) {
125
124
  const dirs = [
126
125
  join(roots.workingDirectory, '.goodvibes', 'agents'),
127
- join(roots.workingDirectory, '.goodvibes', 'goodvibes', 'agents'),
128
126
  ];
129
127
  if (roots.homeDirectory) {
130
- dirs.push(join(roots.homeDirectory, '.goodvibes', 'agents'), join(roots.homeDirectory, '.goodvibes', 'goodvibes', 'agents'));
128
+ dirs.push(join(roots.homeDirectory, '.goodvibes', 'agents'));
131
129
  }
132
130
  return dirs;
133
131
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skill-loader.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/registry-tool/skill-loader.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAgBD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAuDxF"}
1
+ {"version":3,"file":"skill-loader.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/registry-tool/skill-loader.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAcD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAuDxF"}
@@ -10,10 +10,9 @@ import { materializeMarkdownBody, parseMarkdownFrontmatter, normalizeFrontmatter
10
10
  function getSkillDirs(roots) {
11
11
  const dirs = [
12
12
  join(roots.workingDirectory, '.goodvibes', 'skills'),
13
- join(roots.workingDirectory, '.goodvibes', 'goodvibes', 'skills'),
14
13
  ];
15
14
  if (roots.homeDirectory) {
16
- dirs.push(join(roots.homeDirectory, '.goodvibes', 'skills'), join(roots.homeDirectory, '.goodvibes', 'goodvibes', 'skills'));
15
+ dirs.push(join(roots.homeDirectory, '.goodvibes', 'skills'));
17
16
  }
18
17
  return dirs;
19
18
  }
@@ -1,3 +1,6 @@
1
1
  import type { Tool } from '../../types/tools.js';
2
+ export declare function createTeamTool(options?: {
3
+ readonly surfaceRoot?: string;
4
+ }): Tool;
2
5
  export declare const teamTool: Tool;
3
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/team/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AA4DjD,eAAO,MAAM,QAAQ,EAAE,IA4HtB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/team/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AA6DjD,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA+HhF;AAED,eAAO,MAAM,QAAQ,MAAmB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
2
- import { dirname, join } from 'node:path';
2
+ import { dirname } from 'node:path';
3
+ import { resolveScopedDirectory } from '../../runtime/surface-root.js';
3
4
  import { TEAM_TOOL_SCHEMA } from './schema.js';
4
5
  function summarizeTeam(team) {
5
6
  return {
@@ -12,11 +13,11 @@ function summarizeTeam(team) {
12
13
  updatedAt: team.updatedAt,
13
14
  };
14
15
  }
15
- function teamsPath(storageRoot) {
16
- return join(storageRoot, '.goodvibes', 'goodvibes', 'teams.json');
16
+ function teamsPath(storageRoot, surfaceRoot) {
17
+ return resolveScopedDirectory(storageRoot, surfaceRoot, 'teams.json');
17
18
  }
18
- function loadTeams(storageRoot) {
19
- const path = teamsPath(storageRoot);
19
+ function loadTeams(storageRoot, surfaceRoot) {
20
+ const path = teamsPath(storageRoot, surfaceRoot);
20
21
  if (!existsSync(path))
21
22
  return [];
22
23
  try {
@@ -27,123 +28,127 @@ function loadTeams(storageRoot) {
27
28
  return [];
28
29
  }
29
30
  }
30
- function saveTeams(storageRoot, teams) {
31
- const path = teamsPath(storageRoot);
31
+ function saveTeams(storageRoot, teams, surfaceRoot) {
32
+ const path = teamsPath(storageRoot, surfaceRoot);
32
33
  mkdirSync(dirname(path), { recursive: true });
33
34
  writeFileSync(path, JSON.stringify({ version: 1, teams }, null, 2) + '\n', 'utf-8');
34
35
  }
35
- export const teamTool = {
36
- definition: {
37
- name: 'team',
38
- description: 'Manage durable team definitions, roles, and communication lanes.',
39
- parameters: TEAM_TOOL_SCHEMA,
40
- sideEffects: ['workflow', 'state'],
41
- concurrency: 'serial',
42
- },
43
- async execute(args) {
44
- if (!args || typeof args !== 'object' || typeof args.mode !== 'string') {
45
- return { success: false, error: 'Invalid args: mode is required.' };
46
- }
47
- const input = args;
48
- if (!input.storageRoot || input.storageRoot.trim().length === 0) {
49
- return { success: false, error: 'team requires storageRoot.' };
50
- }
51
- const teams = loadTeams(input.storageRoot);
52
- const view = input.view ?? 'summary';
53
- if (input.mode === 'create') {
54
- if (!input.teamId || !input.name || !input.summary) {
55
- return { success: false, error: 'create requires teamId, name, and summary.' };
36
+ export function createTeamTool(options) {
37
+ const surfaceRoot = options?.surfaceRoot;
38
+ return {
39
+ definition: {
40
+ name: 'team',
41
+ description: 'Manage durable team definitions, roles, and communication lanes.',
42
+ parameters: TEAM_TOOL_SCHEMA,
43
+ sideEffects: ['workflow', 'state'],
44
+ concurrency: 'serial',
45
+ },
46
+ async execute(args) {
47
+ if (!args || typeof args !== 'object' || typeof args.mode !== 'string') {
48
+ return { success: false, error: 'Invalid args: mode is required.' };
49
+ }
50
+ const input = args;
51
+ if (!input.storageRoot || input.storageRoot.trim().length === 0) {
52
+ return { success: false, error: 'team requires storageRoot.' };
53
+ }
54
+ const teams = loadTeams(input.storageRoot, surfaceRoot);
55
+ const view = input.view ?? 'summary';
56
+ if (input.mode === 'create') {
57
+ if (!input.teamId || !input.name || !input.summary) {
58
+ return { success: false, error: 'create requires teamId, name, and summary.' };
59
+ }
60
+ if (teams.some((team) => team.id === input.teamId)) {
61
+ return { success: false, error: `Team already exists: ${input.teamId}` };
62
+ }
63
+ const now = Date.now();
64
+ const team = {
65
+ id: input.teamId,
66
+ name: input.name,
67
+ summary: input.summary,
68
+ members: [],
69
+ createdAt: now,
70
+ updatedAt: now,
71
+ };
72
+ saveTeams(input.storageRoot, [...teams, team], surfaceRoot);
73
+ return { success: true, output: JSON.stringify(team) };
74
+ }
75
+ if (input.mode === 'list') {
76
+ return {
77
+ success: true,
78
+ output: JSON.stringify({
79
+ view,
80
+ count: teams.length,
81
+ teams: view === 'full' ? teams : teams.map(summarizeTeam),
82
+ }),
83
+ };
84
+ }
85
+ const index = teams.findIndex((team) => team.id === input.teamId);
86
+ if (index < 0) {
87
+ return { success: false, error: `Unknown team: ${input.teamId ?? '(missing)'}` };
56
88
  }
57
- if (teams.some((team) => team.id === input.teamId)) {
58
- return { success: false, error: `Team already exists: ${input.teamId}` };
89
+ const current = teams[index];
90
+ if (input.mode === 'show') {
91
+ return {
92
+ success: true,
93
+ output: JSON.stringify(view === 'full' ? current : {
94
+ ...summarizeTeam(current),
95
+ members: current.members.map((member) => ({
96
+ id: member.id,
97
+ role: member.role,
98
+ lanes: member.lanes,
99
+ })),
100
+ }),
101
+ };
59
102
  }
60
- const now = Date.now();
61
- const team = {
62
- id: input.teamId,
63
- name: input.name,
64
- summary: input.summary,
65
- members: [],
66
- createdAt: now,
67
- updatedAt: now,
68
- };
69
- saveTeams(input.storageRoot, [...teams, team]);
70
- return { success: true, output: JSON.stringify(team) };
71
- }
72
- if (input.mode === 'list') {
73
- return {
74
- success: true,
75
- output: JSON.stringify({
76
- view,
77
- count: teams.length,
78
- teams: view === 'full' ? teams : teams.map(summarizeTeam),
79
- }),
80
- };
81
- }
82
- const index = teams.findIndex((team) => team.id === input.teamId);
83
- if (index < 0) {
84
- return { success: false, error: `Unknown team: ${input.teamId ?? '(missing)'}` };
85
- }
86
- const current = teams[index];
87
- if (input.mode === 'show') {
88
- return {
89
- success: true,
90
- output: JSON.stringify(view === 'full' ? current : {
91
- ...summarizeTeam(current),
92
- members: current.members.map((member) => ({
93
- id: member.id,
94
- role: member.role,
95
- lanes: member.lanes,
96
- })),
97
- }),
98
- };
99
- }
100
- if (input.mode === 'delete') {
101
- saveTeams(input.storageRoot, teams.filter((team) => team.id !== input.teamId));
102
- return { success: true, output: JSON.stringify({ removed: input.teamId }) };
103
- }
104
- if (input.mode === 'add-member') {
105
- if (!input.memberId || !input.role) {
106
- return { success: false, error: 'add-member requires memberId and role.' };
103
+ if (input.mode === 'delete') {
104
+ saveTeams(input.storageRoot, teams.filter((team) => team.id !== input.teamId), surfaceRoot);
105
+ return { success: true, output: JSON.stringify({ removed: input.teamId }) };
107
106
  }
108
- const next = {
109
- ...current,
110
- members: [
111
- ...current.members.filter((member) => member.id !== input.memberId),
112
- { id: input.memberId, role: input.role, lanes: input.lanes ?? [] },
113
- ],
114
- updatedAt: Date.now(),
115
- };
116
- teams[index] = next;
117
- saveTeams(input.storageRoot, teams);
118
- return { success: true, output: JSON.stringify(next) };
119
- }
120
- if (input.mode === 'remove-member') {
121
- if (!input.memberId)
122
- return { success: false, error: 'remove-member requires memberId.' };
123
- const next = {
124
- ...current,
125
- members: current.members.filter((member) => member.id !== input.memberId),
126
- updatedAt: Date.now(),
127
- };
128
- teams[index] = next;
129
- saveTeams(input.storageRoot, teams);
130
- return { success: true, output: JSON.stringify(next) };
131
- }
132
- if (input.mode === 'set-lanes') {
133
- if (!input.memberId)
134
- return { success: false, error: 'set-lanes requires memberId.' };
135
- const members = current.members.map((member) => (member.id === input.memberId
136
- ? { ...member, lanes: input.lanes ?? [] }
137
- : member));
138
- const next = {
139
- ...current,
140
- members,
141
- updatedAt: Date.now(),
142
- };
143
- teams[index] = next;
144
- saveTeams(input.storageRoot, teams);
145
- return { success: true, output: JSON.stringify(next) };
146
- }
147
- return { success: false, error: `Unknown mode: ${input.mode}` };
148
- },
149
- };
107
+ if (input.mode === 'add-member') {
108
+ if (!input.memberId || !input.role) {
109
+ return { success: false, error: 'add-member requires memberId and role.' };
110
+ }
111
+ const next = {
112
+ ...current,
113
+ members: [
114
+ ...current.members.filter((member) => member.id !== input.memberId),
115
+ { id: input.memberId, role: input.role, lanes: input.lanes ?? [] },
116
+ ],
117
+ updatedAt: Date.now(),
118
+ };
119
+ teams[index] = next;
120
+ saveTeams(input.storageRoot, teams, surfaceRoot);
121
+ return { success: true, output: JSON.stringify(next) };
122
+ }
123
+ if (input.mode === 'remove-member') {
124
+ if (!input.memberId)
125
+ return { success: false, error: 'remove-member requires memberId.' };
126
+ const next = {
127
+ ...current,
128
+ members: current.members.filter((member) => member.id !== input.memberId),
129
+ updatedAt: Date.now(),
130
+ };
131
+ teams[index] = next;
132
+ saveTeams(input.storageRoot, teams, surfaceRoot);
133
+ return { success: true, output: JSON.stringify(next) };
134
+ }
135
+ if (input.mode === 'set-lanes') {
136
+ if (!input.memberId)
137
+ return { success: false, error: 'set-lanes requires memberId.' };
138
+ const members = current.members.map((member) => (member.id === input.memberId
139
+ ? { ...member, lanes: input.lanes ?? [] }
140
+ : member));
141
+ const next = {
142
+ ...current,
143
+ members,
144
+ updatedAt: Date.now(),
145
+ };
146
+ teams[index] = next;
147
+ saveTeams(input.storageRoot, teams, surfaceRoot);
148
+ return { success: true, output: JSON.stringify(next) };
149
+ }
150
+ return { success: false, error: `Unknown mode: ${input.mode}` };
151
+ },
152
+ };
153
+ }
154
+ export const teamTool = createTeamTool();
@@ -1,3 +1,6 @@
1
1
  import type { Tool } from '../../types/tools.js';
2
+ export declare function createWorklistTool(options?: {
3
+ readonly surfaceRoot?: string;
4
+ }): Tool;
2
5
  export declare const worklistTool: Tool;
3
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/worklist/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AA+DjD,eAAO,MAAM,YAAY,EAAE,IAyG1B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/worklist/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAgEjD,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4GpF;AAED,eAAO,MAAM,YAAY,MAAuB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { dirname, join } from 'node:path';
2
+ import { dirname } from 'node:path';
3
+ import { resolveScopedDirectory } from '../../runtime/surface-root.js';
3
4
  import { WORKLIST_TOOL_SCHEMA } from './schema.js';
4
5
  function summarizeWorklist(record) {
5
6
  const openCount = record.items.filter((item) => item.status === 'open').length;
@@ -14,11 +15,11 @@ function summarizeWorklist(record) {
14
15
  updatedAt: record.updatedAt,
15
16
  };
16
17
  }
17
- function worklistsPath(storageRoot) {
18
- return join(storageRoot, '.goodvibes', 'goodvibes', 'worklists.json');
18
+ function worklistsPath(storageRoot, surfaceRoot) {
19
+ return resolveScopedDirectory(storageRoot, surfaceRoot, 'worklists.json');
19
20
  }
20
- function loadWorklists(storageRoot) {
21
- const path = worklistsPath(storageRoot);
21
+ function loadWorklists(storageRoot, surfaceRoot) {
22
+ const path = worklistsPath(storageRoot, surfaceRoot);
22
23
  if (!existsSync(path))
23
24
  return [];
24
25
  try {
@@ -29,112 +30,116 @@ function loadWorklists(storageRoot) {
29
30
  return [];
30
31
  }
31
32
  }
32
- function saveWorklists(storageRoot, worklists) {
33
- const path = worklistsPath(storageRoot);
33
+ function saveWorklists(storageRoot, worklists, surfaceRoot) {
34
+ const path = worklistsPath(storageRoot, surfaceRoot);
34
35
  mkdirSync(dirname(path), { recursive: true });
35
36
  writeFileSync(path, JSON.stringify({ version: 1, worklists }, null, 2) + '\n', 'utf-8');
36
37
  }
37
- export const worklistTool = {
38
- definition: {
39
- name: 'worklist',
40
- description: 'Manage durable worklists and checklist items for execution planning and follow-up.',
41
- parameters: WORKLIST_TOOL_SCHEMA,
42
- sideEffects: ['workflow', 'state'],
43
- concurrency: 'serial',
44
- },
45
- async execute(args) {
46
- if (!args || typeof args !== 'object' || typeof args.mode !== 'string') {
47
- return { success: false, error: 'Invalid args: mode is required.' };
48
- }
49
- const input = args;
50
- if (!input.storageRoot || input.storageRoot.trim().length === 0) {
51
- return { success: false, error: 'worklist requires storageRoot.' };
52
- }
53
- const worklists = loadWorklists(input.storageRoot);
54
- const view = input.view ?? 'summary';
55
- if (input.mode === 'create') {
56
- if (!input.worklistId || !input.title) {
57
- return { success: false, error: 'create requires worklistId and title.' };
38
+ export function createWorklistTool(options) {
39
+ const surfaceRoot = options?.surfaceRoot;
40
+ return {
41
+ definition: {
42
+ name: 'worklist',
43
+ description: 'Manage durable worklists and checklist items for execution planning and follow-up.',
44
+ parameters: WORKLIST_TOOL_SCHEMA,
45
+ sideEffects: ['workflow', 'state'],
46
+ concurrency: 'serial',
47
+ },
48
+ async execute(args) {
49
+ if (!args || typeof args !== 'object' || typeof args.mode !== 'string') {
50
+ return { success: false, error: 'Invalid args: mode is required.' };
58
51
  }
59
- if (worklists.some((entry) => entry.id === input.worklistId)) {
60
- return { success: false, error: `Worklist already exists: ${input.worklistId}` };
52
+ const input = args;
53
+ if (!input.storageRoot || input.storageRoot.trim().length === 0) {
54
+ return { success: false, error: 'worklist requires storageRoot.' };
61
55
  }
62
- const now = Date.now();
63
- const record = {
64
- id: input.worklistId,
65
- title: input.title,
66
- items: [],
67
- createdAt: now,
68
- updatedAt: now,
69
- };
70
- saveWorklists(input.storageRoot, [...worklists, record]);
71
- return { success: true, output: JSON.stringify(record) };
72
- }
73
- if (input.mode === 'list') {
74
- return {
75
- success: true,
76
- output: JSON.stringify({
77
- view,
78
- count: worklists.length,
79
- worklists: view === 'full' ? worklists : worklists.map(summarizeWorklist),
80
- }),
81
- };
82
- }
83
- const index = worklists.findIndex((entry) => entry.id === input.worklistId);
84
- if (index < 0) {
85
- return { success: false, error: `Unknown worklist: ${input.worklistId ?? '(missing)'}` };
86
- }
87
- const current = worklists[index];
88
- if (input.mode === 'show') {
89
- return {
90
- success: true,
91
- output: JSON.stringify(view === 'full' ? current : {
92
- ...summarizeWorklist(current),
93
- items: current.items.map((item) => ({
94
- id: item.id,
95
- text: item.text,
96
- status: item.status,
97
- owner: item.owner,
98
- priority: item.priority,
99
- })),
100
- }),
101
- };
102
- }
103
- if (input.mode === 'add-item') {
104
- if (!input.itemId || !input.text)
105
- return { success: false, error: 'add-item requires itemId and text.' };
56
+ const worklists = loadWorklists(input.storageRoot, surfaceRoot);
57
+ const view = input.view ?? 'summary';
58
+ if (input.mode === 'create') {
59
+ if (!input.worklistId || !input.title) {
60
+ return { success: false, error: 'create requires worklistId and title.' };
61
+ }
62
+ if (worklists.some((entry) => entry.id === input.worklistId)) {
63
+ return { success: false, error: `Worklist already exists: ${input.worklistId}` };
64
+ }
65
+ const now = Date.now();
66
+ const record = {
67
+ id: input.worklistId,
68
+ title: input.title,
69
+ items: [],
70
+ createdAt: now,
71
+ updatedAt: now,
72
+ };
73
+ saveWorklists(input.storageRoot, [...worklists, record], surfaceRoot);
74
+ return { success: true, output: JSON.stringify(record) };
75
+ }
76
+ if (input.mode === 'list') {
77
+ return {
78
+ success: true,
79
+ output: JSON.stringify({
80
+ view,
81
+ count: worklists.length,
82
+ worklists: view === 'full' ? worklists : worklists.map(summarizeWorklist),
83
+ }),
84
+ };
85
+ }
86
+ const index = worklists.findIndex((entry) => entry.id === input.worklistId);
87
+ if (index < 0) {
88
+ return { success: false, error: `Unknown worklist: ${input.worklistId ?? '(missing)'}` };
89
+ }
90
+ const current = worklists[index];
91
+ if (input.mode === 'show') {
92
+ return {
93
+ success: true,
94
+ output: JSON.stringify(view === 'full' ? current : {
95
+ ...summarizeWorklist(current),
96
+ items: current.items.map((item) => ({
97
+ id: item.id,
98
+ text: item.text,
99
+ status: item.status,
100
+ owner: item.owner,
101
+ priority: item.priority,
102
+ })),
103
+ }),
104
+ };
105
+ }
106
+ if (input.mode === 'add-item') {
107
+ if (!input.itemId || !input.text)
108
+ return { success: false, error: 'add-item requires itemId and text.' };
109
+ const next = {
110
+ ...current,
111
+ items: [
112
+ ...current.items.filter((item) => item.id !== input.itemId),
113
+ { id: input.itemId, text: input.text, status: 'open', priority: input.priority ?? 'medium', ...(input.owner ? { owner: input.owner } : {}) },
114
+ ],
115
+ updatedAt: Date.now(),
116
+ };
117
+ worklists[index] = next;
118
+ saveWorklists(input.storageRoot, worklists, surfaceRoot);
119
+ return { success: true, output: JSON.stringify(next) };
120
+ }
121
+ if (!input.itemId)
122
+ return { success: false, error: `${input.mode} requires itemId.` };
123
+ const nextItems = current.items
124
+ .filter((item) => input.mode !== 'remove-item' || item.id !== input.itemId)
125
+ .map((item) => {
126
+ if (item.id !== input.itemId)
127
+ return item;
128
+ if (input.mode === 'complete-item')
129
+ return { ...item, status: 'done' };
130
+ if (input.mode === 'reopen-item')
131
+ return { ...item, status: 'open' };
132
+ return item;
133
+ });
106
134
  const next = {
107
135
  ...current,
108
- items: [
109
- ...current.items.filter((item) => item.id !== input.itemId),
110
- { id: input.itemId, text: input.text, status: 'open', priority: input.priority ?? 'medium', ...(input.owner ? { owner: input.owner } : {}) },
111
- ],
136
+ items: nextItems,
112
137
  updatedAt: Date.now(),
113
138
  };
114
139
  worklists[index] = next;
115
- saveWorklists(input.storageRoot, worklists);
140
+ saveWorklists(input.storageRoot, worklists, surfaceRoot);
116
141
  return { success: true, output: JSON.stringify(next) };
117
- }
118
- if (!input.itemId)
119
- return { success: false, error: `${input.mode} requires itemId.` };
120
- const nextItems = current.items
121
- .filter((item) => input.mode !== 'remove-item' || item.id !== input.itemId)
122
- .map((item) => {
123
- if (item.id !== input.itemId)
124
- return item;
125
- if (input.mode === 'complete-item')
126
- return { ...item, status: 'done' };
127
- if (input.mode === 'reopen-item')
128
- return { ...item, status: 'open' };
129
- return item;
130
- });
131
- const next = {
132
- ...current,
133
- items: nextItems,
134
- updatedAt: Date.now(),
135
- };
136
- worklists[index] = next;
137
- saveWorklists(input.storageRoot, worklists);
138
- return { success: true, output: JSON.stringify(next) };
139
- },
140
- };
142
+ },
143
+ };
144
+ }
145
+ export const worklistTool = createWorklistTool();