@juancr11/sibu 0.16.0 → 0.17.1

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/README.md +66 -29
  2. package/bin/entrypoints/cli/create-program.js +1 -1
  3. package/bin/entrypoints/cli/execute-command.js +4 -7
  4. package/bin/modules/agent-tool-configuration/index.js +1 -0
  5. package/bin/modules/agent-tool-configuration/mcp-config.js +134 -0
  6. package/bin/modules/interactive-guidance/prompts.js +1 -1
  7. package/bin/modules/mcp-server-selection-management/list-mcp-servers/handler.js +2 -2
  8. package/bin/modules/mcp-server-selection-management/stop-mcp-server/handler.js +5 -5
  9. package/bin/modules/mcp-server-selection-management/use-mcp-server/handler.js +4 -3
  10. package/bin/modules/skill-selection-management/list-skills/handler.js +2 -2
  11. package/bin/modules/skill-selection-management/stop-managing-file/handler.js +5 -4
  12. package/bin/modules/skill-selection-management/use-skill/handler.js +5 -4
  13. package/bin/modules/{sync-review → sync-review-orchestrator}/action-prompt.js +14 -1
  14. package/bin/modules/{sync-review → sync-review-orchestrator}/apply-action.js +4 -3
  15. package/bin/modules/sync-review-orchestrator/handler.js +124 -0
  16. package/bin/modules/{sync-review → sync-review-orchestrator}/index.js +2 -0
  17. package/bin/modules/{sync-review → sync-review-orchestrator}/log-preview.js +1 -1
  18. package/bin/modules/{sync-review → sync-review-orchestrator}/sync-preview.js +3 -3
  19. package/bin/modules/sync-review-orchestrator/unsupported-agent-cleanup.js +57 -0
  20. package/bin/modules/{workflow-mutation-readiness → sync-review-orchestrator}/workflow-mutation-readiness.js +12 -3
  21. package/bin/modules/{workflow-target-planning → template-catalog}/catalog.js +83 -26
  22. package/bin/modules/{workflow-target-planning → template-catalog}/index.js +2 -1
  23. package/bin/modules/template-catalog/templates.js +154 -0
  24. package/bin/modules/workflow-configuration-manager/index.js +6 -0
  25. package/bin/modules/workflow-configuration-manager/list-mcp-servers/handler.js +46 -0
  26. package/bin/modules/workflow-configuration-manager/list-skills/command.js +1 -0
  27. package/bin/modules/workflow-configuration-manager/list-skills/handler.js +75 -0
  28. package/bin/modules/workflow-configuration-manager/stop-managing-file/command.js +1 -0
  29. package/bin/modules/workflow-configuration-manager/stop-managing-file/handler.js +221 -0
  30. package/bin/modules/workflow-configuration-manager/stop-mcp-server/command.js +1 -0
  31. package/bin/modules/workflow-configuration-manager/stop-mcp-server/handler.js +198 -0
  32. package/bin/modules/workflow-configuration-manager/use-mcp-server/command.js +1 -0
  33. package/bin/modules/workflow-configuration-manager/use-mcp-server/handler.js +193 -0
  34. package/bin/modules/workflow-configuration-manager/use-skill/command.js +1 -0
  35. package/bin/modules/workflow-configuration-manager/use-skill/handler.js +314 -0
  36. package/bin/modules/workflow-health-inspector/command.js +1 -0
  37. package/bin/modules/{workflow-health-diagnosis → workflow-health-inspector}/handler.js +7 -7
  38. package/bin/modules/workflow-installer/command.js +1 -0
  39. package/bin/modules/{project-adoption → workflow-installer}/handler.js +5 -4
  40. package/bin/modules/workflow-state-ledger/index.js +2 -0
  41. package/bin/modules/workflow-state-ledger/state-path.js +1 -0
  42. package/bin/modules/{workflow-state-registry → workflow-state-ledger}/state.js +40 -1
  43. package/bin/{modules/workflow-target-planning/workflow-targets.js → shared/expected-workflow-targets.js} +3 -103
  44. package/bin/shared/paths.js +1 -1
  45. package/bin/support/expected-workflow-targets.js +131 -0
  46. package/bin/support/interactive-guidance/index.js +1 -0
  47. package/bin/support/interactive-guidance/prompts.js +275 -0
  48. package/bin/support/version-advisory/index.js +1 -0
  49. package/bin/support/version-advisory/npm-version.js +205 -0
  50. package/package.json +2 -1
  51. package/templates/.claude/agents/sibu-implementation-executor.md +30 -0
  52. package/templates/.claude/agents/sibu-implementation-planner.md +30 -0
  53. package/templates/.codex/agents/sibu-implementation-executor.toml +30 -0
  54. package/templates/.codex/agents/sibu-implementation-planner.toml +30 -0
  55. package/templates/.gemini/agents/sibu-implementation-executor.md +30 -0
  56. package/templates/.gemini/agents/sibu-implementation-planner.md +30 -0
  57. package/templates/AGENTS.md +4 -2
  58. package/templates/manifest.json +94 -17
  59. package/templates/skills/ai-implementation-executor-toolbox/SKILL.md +78 -0
  60. package/templates/skills/ai-implementation-plan-executor/SKILL.md +64 -108
  61. package/templates/skills/ai-implementation-planner/SKILL.md +55 -138
  62. package/templates/skills/ai-implementation-planner-toolbox/SKILL.md +78 -0
  63. package/templates/skills/business-domain-model-writer/SKILL.md +313 -0
  64. package/templates/skills/capabilities-map-writer/SKILL.md +271 -0
  65. package/templates/skills/deep-module-map-writer/SKILL.md +50 -14
  66. package/templates/skills/feature-brief-writer/SKILL.md +72 -32
  67. package/templates/skills/technical-design-writer/SKILL.md +10 -10
  68. package/templates/skills/ux-expert/SKILL.md +62 -17
  69. package/bin/modules/sync-review/handler.js +0 -77
  70. package/bin/modules/template-catalog-rendering/index.js +0 -1
  71. package/bin/modules/template-catalog-rendering/templates.js +0 -163
  72. package/bin/modules/workflow-mutation-readiness/index.js +0 -1
  73. package/bin/modules/workflow-state-registry/index.js +0 -1
  74. /package/bin/{modules/project-adoption/command.js → entrypoints/cli-command-surface/index.js} +0 -0
  75. /package/bin/modules/{sync-review → sync-review-orchestrator}/command.js +0 -0
  76. /package/bin/modules/{workflow-health-diagnosis → workflow-configuration-manager/list-mcp-servers}/command.js +0 -0
  77. /package/bin/modules/{workflow-health-diagnosis → workflow-health-inspector}/index.js +0 -0
  78. /package/bin/modules/{project-adoption → workflow-installer}/index.js +0 -0
@@ -0,0 +1,57 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { getSelectedAgentsFromState, getSelectedArchitectureSkillFromState, getSelectedDatabaseSkillsFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getSelectedMcpServersFromState, getSelectedWorkflowSkillsFromState, getWorkflowTargets, SUPPORTED_AGENTS, } from '../template-catalog/index.js';
4
+ import { cloneState } from '../workflow-state-ledger/index.js';
5
+ export function getUnsupportedAgentCleanupPlan({ rootPath, state }) {
6
+ const supportedAgentIds = new Set(SUPPORTED_AGENTS.map((agent) => agent.id));
7
+ const unsupportedAgentIds = state.selectedAgents.filter((agentId) => !supportedAgentIds.has(agentId));
8
+ if (unsupportedAgentIds.length === 0) {
9
+ return undefined;
10
+ }
11
+ const remainingSupportedAgents = getSelectedAgentsFromState(state);
12
+ const obsoleteManagedFilePaths = getObsoleteManagedFilePaths({ rootPath, state, remainingSupportedAgents });
13
+ const filePathsToDelete = obsoleteManagedFilePaths.filter((relativePath) => state.managedFiles[relativePath]?.status !== 'unmanaged');
14
+ return {
15
+ unsupportedAgentIds,
16
+ remainingSupportedAgents,
17
+ obsoleteManagedFilePaths,
18
+ filePathsToDelete,
19
+ removesSibuState: remainingSupportedAgents.length === 0,
20
+ };
21
+ }
22
+ export function applyUnsupportedAgentCleanup({ rootPath, statePath, state, plan, }) {
23
+ const removedFiles = [];
24
+ for (const relativePath of plan.filePathsToDelete) {
25
+ const targetPath = path.join(rootPath, relativePath);
26
+ if (!fs.existsSync(targetPath)) {
27
+ continue;
28
+ }
29
+ fs.rmSync(targetPath, { recursive: true, force: true });
30
+ removedFiles.push(relativePath);
31
+ }
32
+ if (plan.removesSibuState) {
33
+ fs.rmSync(statePath, { force: true });
34
+ return { removedStateFile: true, removedFiles };
35
+ }
36
+ const unsupportedAgentIds = new Set(plan.unsupportedAgentIds);
37
+ const obsoleteManagedFilePaths = new Set(plan.obsoleteManagedFilePaths);
38
+ const nextState = cloneState(state);
39
+ nextState.selectedAgents = nextState.selectedAgents.filter((agentId) => !unsupportedAgentIds.has(agentId));
40
+ nextState.updatedAt = new Date().toISOString();
41
+ for (const relativePath of obsoleteManagedFilePaths) {
42
+ delete nextState.managedFiles[relativePath];
43
+ }
44
+ return {
45
+ removedStateFile: false,
46
+ removedFiles,
47
+ state: nextState,
48
+ };
49
+ }
50
+ function getObsoleteManagedFilePaths({ rootPath, state, remainingSupportedAgents, }) {
51
+ if (remainingSupportedAgents.length === 0) {
52
+ return Object.keys(state.managedFiles);
53
+ }
54
+ const expectedTargets = getWorkflowTargets(rootPath, remainingSupportedAgents, getSelectedLanguageSkillsFromState(state), getSelectedFrameworkSkillsFromState(state), getSelectedArchitectureSkillFromState(state), getSelectedWorkflowSkillsFromState(state), getSelectedDatabaseSkillsFromState(state), getSelectedMcpServersFromState(state));
55
+ const expectedManagedFilePaths = new Set(expectedTargets.map((target) => path.relative(rootPath, target.targetPath)));
56
+ return Object.keys(state.managedFiles).filter((relativePath) => !expectedManagedFilePaths.has(relativePath));
57
+ }
@@ -1,6 +1,7 @@
1
- import { readStateForDoctor } from '../workflow-state-registry/index.js';
2
- import { getSyncPreviews, isActionableSyncPreview } from '../sync-review/index.js';
3
- import { readTemplateManifest } from '../template-catalog-rendering/index.js';
1
+ import { readTemplateManifest } from '../template-catalog/index.js';
2
+ import { readStateForDoctor } from '../workflow-state-ledger/index.js';
3
+ import { getSyncPreviews, isActionableSyncPreview } from './sync-preview.js';
4
+ import { getUnsupportedAgentCleanupPlan } from './unsupported-agent-cleanup.js';
4
5
  export function getWorkflowMutationReadiness({ rootPath, statePath }) {
5
6
  const stateResult = readStateForDoctor(statePath);
6
7
  if (!stateResult.ok) {
@@ -11,6 +12,14 @@ export function getWorkflowMutationReadiness({ rootPath, statePath }) {
11
12
  };
12
13
  }
13
14
  const manifest = readTemplateManifest();
15
+ const unsupportedAgentCleanupPlan = getUnsupportedAgentCleanupPlan({ rootPath, state: stateResult.state });
16
+ if (unsupportedAgentCleanupPlan) {
17
+ return {
18
+ ok: false,
19
+ message: 'Workflow state is not clean enough to select a skill safely.',
20
+ hint: 'Run `sibu sync` to review workflow state before selecting a skill.',
21
+ };
22
+ }
14
23
  const previews = getSyncPreviews({ rootPath, state: stateResult.state, manifest });
15
24
  const actionablePreviews = previews.filter(isActionableSyncPreview);
16
25
  if (actionablePreviews.length > 0) {
@@ -5,7 +5,6 @@ export const MANDATORY_SKILLS = [
5
5
  codex: '.agents/skills/clean-code/SKILL.md',
6
6
  gemini: '.agents/skills/clean-code/SKILL.md',
7
7
  claude: '.agents/skills/clean-code/SKILL.md',
8
- windsurf: '.agents/skills/clean-code/SKILL.md',
9
8
  },
10
9
  },
11
10
  {
@@ -14,7 +13,22 @@ export const MANDATORY_SKILLS = [
14
13
  codex: '.agents/skills/product-vision-writer/SKILL.md',
15
14
  gemini: '.agents/skills/product-vision-writer/SKILL.md',
16
15
  claude: '.agents/skills/product-vision-writer/SKILL.md',
17
- windsurf: '.agents/skills/product-vision-writer/SKILL.md',
16
+ },
17
+ },
18
+ {
19
+ templateRelativePath: 'skills/business-domain-model-writer/SKILL.md',
20
+ targetRelativePathsByAgent: {
21
+ codex: '.agents/skills/business-domain-model-writer/SKILL.md',
22
+ gemini: '.agents/skills/business-domain-model-writer/SKILL.md',
23
+ claude: '.agents/skills/business-domain-model-writer/SKILL.md',
24
+ },
25
+ },
26
+ {
27
+ templateRelativePath: 'skills/capabilities-map-writer/SKILL.md',
28
+ targetRelativePathsByAgent: {
29
+ codex: '.agents/skills/capabilities-map-writer/SKILL.md',
30
+ gemini: '.agents/skills/capabilities-map-writer/SKILL.md',
31
+ claude: '.agents/skills/capabilities-map-writer/SKILL.md',
18
32
  },
19
33
  },
20
34
  {
@@ -23,7 +37,6 @@ export const MANDATORY_SKILLS = [
23
37
  codex: '.agents/skills/deep-module-map-writer/SKILL.md',
24
38
  gemini: '.agents/skills/deep-module-map-writer/SKILL.md',
25
39
  claude: '.agents/skills/deep-module-map-writer/SKILL.md',
26
- windsurf: '.agents/skills/deep-module-map-writer/SKILL.md',
27
40
  },
28
41
  },
29
42
  {
@@ -32,7 +45,6 @@ export const MANDATORY_SKILLS = [
32
45
  codex: '.agents/skills/feature-brief-writer/SKILL.md',
33
46
  gemini: '.agents/skills/feature-brief-writer/SKILL.md',
34
47
  claude: '.agents/skills/feature-brief-writer/SKILL.md',
35
- windsurf: '.agents/skills/feature-brief-writer/SKILL.md',
36
48
  },
37
49
  },
38
50
  {
@@ -41,7 +53,6 @@ export const MANDATORY_SKILLS = [
41
53
  codex: '.agents/skills/technical-design-writer/SKILL.md',
42
54
  gemini: '.agents/skills/technical-design-writer/SKILL.md',
43
55
  claude: '.agents/skills/technical-design-writer/SKILL.md',
44
- windsurf: '.agents/skills/technical-design-writer/SKILL.md',
45
56
  },
46
57
  },
47
58
  {
@@ -50,7 +61,6 @@ export const MANDATORY_SKILLS = [
50
61
  codex: '.agents/skills/scrum-master-planner/SKILL.md',
51
62
  gemini: '.agents/skills/scrum-master-planner/SKILL.md',
52
63
  claude: '.agents/skills/scrum-master-planner/SKILL.md',
53
- windsurf: '.agents/skills/scrum-master-planner/SKILL.md',
54
64
  },
55
65
  },
56
66
  {
@@ -59,7 +69,38 @@ export const MANDATORY_SKILLS = [
59
69
  codex: '.agents/skills/ai-implementation-planner/SKILL.md',
60
70
  gemini: '.agents/skills/ai-implementation-planner/SKILL.md',
61
71
  claude: '.agents/skills/ai-implementation-planner/SKILL.md',
62
- windsurf: '.agents/skills/ai-implementation-planner/SKILL.md',
72
+ },
73
+ supplementalTargetsByAgent: {
74
+ codex: [
75
+ {
76
+ templateRelativePath: 'skills/ai-implementation-planner-toolbox/SKILL.md',
77
+ targetRelativePath: '.agents/skills/ai-implementation-planner-toolbox/SKILL.md',
78
+ },
79
+ {
80
+ templateRelativePath: '.codex/agents/sibu-implementation-planner.toml',
81
+ targetRelativePath: '.codex/agents/sibu-implementation-planner.toml',
82
+ },
83
+ ],
84
+ gemini: [
85
+ {
86
+ templateRelativePath: 'skills/ai-implementation-planner-toolbox/SKILL.md',
87
+ targetRelativePath: '.agents/skills/ai-implementation-planner-toolbox/SKILL.md',
88
+ },
89
+ {
90
+ templateRelativePath: '.gemini/agents/sibu-implementation-planner.md',
91
+ targetRelativePath: '.gemini/agents/sibu-implementation-planner.md',
92
+ },
93
+ ],
94
+ claude: [
95
+ {
96
+ templateRelativePath: 'skills/ai-implementation-planner-toolbox/SKILL.md',
97
+ targetRelativePath: '.agents/skills/ai-implementation-planner-toolbox/SKILL.md',
98
+ },
99
+ {
100
+ templateRelativePath: '.claude/agents/sibu-implementation-planner.md',
101
+ targetRelativePath: '.claude/agents/sibu-implementation-planner.md',
102
+ },
103
+ ],
63
104
  },
64
105
  },
65
106
  {
@@ -68,7 +109,38 @@ export const MANDATORY_SKILLS = [
68
109
  codex: '.agents/skills/ai-implementation-plan-executor/SKILL.md',
69
110
  gemini: '.agents/skills/ai-implementation-plan-executor/SKILL.md',
70
111
  claude: '.agents/skills/ai-implementation-plan-executor/SKILL.md',
71
- windsurf: '.agents/skills/ai-implementation-plan-executor/SKILL.md',
112
+ },
113
+ supplementalTargetsByAgent: {
114
+ codex: [
115
+ {
116
+ templateRelativePath: 'skills/ai-implementation-executor-toolbox/SKILL.md',
117
+ targetRelativePath: '.agents/skills/ai-implementation-executor-toolbox/SKILL.md',
118
+ },
119
+ {
120
+ templateRelativePath: '.codex/agents/sibu-implementation-executor.toml',
121
+ targetRelativePath: '.codex/agents/sibu-implementation-executor.toml',
122
+ },
123
+ ],
124
+ gemini: [
125
+ {
126
+ templateRelativePath: 'skills/ai-implementation-executor-toolbox/SKILL.md',
127
+ targetRelativePath: '.agents/skills/ai-implementation-executor-toolbox/SKILL.md',
128
+ },
129
+ {
130
+ templateRelativePath: '.gemini/agents/sibu-implementation-executor.md',
131
+ targetRelativePath: '.gemini/agents/sibu-implementation-executor.md',
132
+ },
133
+ ],
134
+ claude: [
135
+ {
136
+ templateRelativePath: 'skills/ai-implementation-executor-toolbox/SKILL.md',
137
+ targetRelativePath: '.agents/skills/ai-implementation-executor-toolbox/SKILL.md',
138
+ },
139
+ {
140
+ templateRelativePath: '.claude/agents/sibu-implementation-executor.md',
141
+ targetRelativePath: '.claude/agents/sibu-implementation-executor.md',
142
+ },
143
+ ],
72
144
  },
73
145
  },
74
146
  {
@@ -77,7 +149,6 @@ export const MANDATORY_SKILLS = [
77
149
  codex: '.agents/skills/feature-idea-capture/SKILL.md',
78
150
  gemini: '.agents/skills/feature-idea-capture/SKILL.md',
79
151
  claude: '.agents/skills/feature-idea-capture/SKILL.md',
80
- windsurf: '.agents/skills/feature-idea-capture/SKILL.md',
81
152
  },
82
153
  },
83
154
  ];
@@ -109,7 +180,6 @@ export const SELECTABLE_LANGUAGE_SKILLS = [
109
180
  codex: '.agents/skills/typescript/SKILL.md',
110
181
  gemini: '.agents/skills/typescript/SKILL.md',
111
182
  claude: '.agents/skills/typescript/SKILL.md',
112
- windsurf: '.agents/skills/typescript/SKILL.md',
113
183
  },
114
184
  },
115
185
  {
@@ -122,7 +192,6 @@ export const SELECTABLE_LANGUAGE_SKILLS = [
122
192
  codex: '.agents/skills/golang/SKILL.md',
123
193
  gemini: '.agents/skills/golang/SKILL.md',
124
194
  claude: '.agents/skills/golang/SKILL.md',
125
- windsurf: '.agents/skills/golang/SKILL.md',
126
195
  },
127
196
  },
128
197
  ];
@@ -137,7 +206,6 @@ export const SELECTABLE_DATABASE_SKILLS = [
137
206
  codex: '.agents/skills/postgresql-expert/SKILL.md',
138
207
  gemini: '.agents/skills/postgresql-expert/SKILL.md',
139
208
  claude: '.agents/skills/postgresql-expert/SKILL.md',
140
- windsurf: '.agents/skills/postgresql-expert/SKILL.md',
141
209
  },
142
210
  },
143
211
  ];
@@ -152,7 +220,6 @@ export const SELECTABLE_FRAMEWORK_SKILLS = [
152
220
  codex: '.agents/skills/react/SKILL.md',
153
221
  gemini: '.agents/skills/react/SKILL.md',
154
222
  claude: '.agents/skills/react/SKILL.md',
155
- windsurf: '.agents/skills/react/SKILL.md',
156
223
  },
157
224
  },
158
225
  {
@@ -165,7 +232,6 @@ export const SELECTABLE_FRAMEWORK_SKILLS = [
165
232
  codex: '.agents/skills/nextjs/SKILL.md',
166
233
  gemini: '.agents/skills/nextjs/SKILL.md',
167
234
  claude: '.agents/skills/nextjs/SKILL.md',
168
- windsurf: '.agents/skills/nextjs/SKILL.md',
169
235
  },
170
236
  },
171
237
  ];
@@ -180,7 +246,6 @@ export const SELECTABLE_ARCHITECTURE_SKILLS = [
180
246
  codex: '.agents/skills/ddd-hexagonal/SKILL.md',
181
247
  gemini: '.agents/skills/ddd-hexagonal/SKILL.md',
182
248
  claude: '.agents/skills/ddd-hexagonal/SKILL.md',
183
- windsurf: '.agents/skills/ddd-hexagonal/SKILL.md',
184
249
  },
185
250
  },
186
251
  {
@@ -193,7 +258,6 @@ export const SELECTABLE_ARCHITECTURE_SKILLS = [
193
258
  codex: '.agents/skills/command-pattern/SKILL.md',
194
259
  gemini: '.agents/skills/command-pattern/SKILL.md',
195
260
  claude: '.agents/skills/command-pattern/SKILL.md',
196
- windsurf: '.agents/skills/command-pattern/SKILL.md',
197
261
  },
198
262
  },
199
263
  {
@@ -206,7 +270,6 @@ export const SELECTABLE_ARCHITECTURE_SKILLS = [
206
270
  codex: '.agents/skills/layered-architecture/SKILL.md',
207
271
  gemini: '.agents/skills/layered-architecture/SKILL.md',
208
272
  claude: '.agents/skills/layered-architecture/SKILL.md',
209
- windsurf: '.agents/skills/layered-architecture/SKILL.md',
210
273
  },
211
274
  },
212
275
  ];
@@ -221,7 +284,6 @@ export const SELECTABLE_WORKFLOW_SKILLS = [
221
284
  codex: '.agents/skills/ai-prompt-engineer-master/SKILL.md',
222
285
  gemini: '.agents/skills/ai-prompt-engineer-master/SKILL.md',
223
286
  claude: '.agents/skills/ai-prompt-engineer-master/SKILL.md',
224
- windsurf: '.agents/skills/ai-prompt-engineer-master/SKILL.md',
225
287
  },
226
288
  },
227
289
  {
@@ -234,7 +296,6 @@ export const SELECTABLE_WORKFLOW_SKILLS = [
234
296
  codex: '.agents/skills/ux-expert/SKILL.md',
235
297
  gemini: '.agents/skills/ux-expert/SKILL.md',
236
298
  claude: '.agents/skills/ux-expert/SKILL.md',
237
- windsurf: '.agents/skills/ux-expert/SKILL.md',
238
299
  },
239
300
  },
240
301
  {
@@ -247,7 +308,6 @@ export const SELECTABLE_WORKFLOW_SKILLS = [
247
308
  codex: '.agents/skills/export-to-github/SKILL.md',
248
309
  gemini: '.agents/skills/export-to-github/SKILL.md',
249
310
  claude: '.agents/skills/export-to-github/SKILL.md',
250
- windsurf: '.agents/skills/export-to-github/SKILL.md',
251
311
  },
252
312
  supplementalTargetsByAgent: {
253
313
  codex: [
@@ -280,7 +340,6 @@ export const SELECTABLE_WORKFLOW_SKILLS = [
280
340
  codex: '.agents/skills/export-to-notion/SKILL.md',
281
341
  gemini: '.agents/skills/export-to-notion/SKILL.md',
282
342
  claude: '.agents/skills/export-to-notion/SKILL.md',
283
- windsurf: '.agents/skills/export-to-notion/SKILL.md',
284
343
  },
285
344
  supplementalTargetsByAgent: {
286
345
  codex: [
@@ -352,6 +411,7 @@ export const SUPPORTED_AGENTS = [
352
411
  description: 'Create .codex/config.toml pointing Codex to AGENTS.md',
353
412
  targetRelativePath: '.codex/config.toml',
354
413
  templateRelativePath: '.codex/config.toml',
414
+ supportsForegroundWorkers: true,
355
415
  },
356
416
  {
357
417
  id: 'gemini',
@@ -359,6 +419,7 @@ export const SUPPORTED_AGENTS = [
359
419
  description: 'Create GEMINI.md that delegates to AGENTS.md',
360
420
  targetRelativePath: 'GEMINI.md',
361
421
  templateRelativePath: 'GEMINI.md',
422
+ supportsForegroundWorkers: true,
362
423
  },
363
424
  {
364
425
  id: 'claude',
@@ -366,11 +427,7 @@ export const SUPPORTED_AGENTS = [
366
427
  description: 'Create CLAUDE.md that delegates to AGENTS.md',
367
428
  targetRelativePath: 'CLAUDE.md',
368
429
  templateRelativePath: 'CLAUDE.md',
369
- },
370
- {
371
- id: 'windsurf',
372
- name: 'Windsurf',
373
- description: 'Use root AGENTS.md and shared .agents/skills/ discovery',
430
+ supportsForegroundWorkers: true,
374
431
  },
375
432
  ];
376
433
  export function resolveSelectableMcpServerById(serverId) {
@@ -1,2 +1,3 @@
1
+ export { extractProjectOverview, getTemplateVersion, readTemplate, readTemplateManifest, renderMissingWorkflowFiles, renderSkillRouting, renderTemplateForSync, renderWorkerToolboxRouting, renderWorkerToolboxRoutingPlaceholders, } from './templates.js';
1
2
  export { MANDATORY_SKILLS, SELECTABLE_ARCHITECTURE_SKILLS, SELECTABLE_DATABASE_SKILLS, SELECTABLE_FRAMEWORK_SKILLS, SELECTABLE_LANGUAGE_SKILLS, SELECTABLE_MCP_SERVERS, SELECTABLE_WORKFLOW_SKILLS, SESSION_START_HOOKS, SUPPORTED_AGENTS, getMcpServersRequiredByWorkflowSkills, getWorkflowSkillsImpliedByMcpServers, resolveSelectableMcpServerById, resolveSelectableSkillById, } from './catalog.js';
2
- export { getSelectedAgentsFromState, getSelectedArchitectureSkillFromState, getSelectedDatabaseSkillsFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getSelectedMcpServersFromState, getSelectedMcpTargetsForAgents, getSelectedSkillTargetsForAgents, getSelectedWorkflowSkillsFromState, getSkillTargetsForAgents, getWorkflowTargets, renderMissingWorkflowFiles, writeSibuState, } from './workflow-targets.js';
3
+ export { getSelectedAgentsFromState, getSelectedArchitectureSkillFromState, getSelectedDatabaseSkillsFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getSelectedMcpServersFromState, getSelectedSkillTargetsForAgents, getSelectedWorkflowSkillsFromState, getSkillTargetsForAgents, getWorkflowTargets, } from '../../support/expected-workflow-targets.js';
@@ -0,0 +1,154 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { getTemplatesPath } from '../../shared/paths.js';
4
+ import { renderMcpConfig, resolveMcpConfigAgentId } from '../agent-tool-configuration/index.js';
5
+ export function readTemplate(relativePath) {
6
+ return fs.readFileSync(path.join(getTemplatesPath(), relativePath), 'utf8');
7
+ }
8
+ export function readTemplateManifest() {
9
+ const manifest = JSON.parse(fs.readFileSync(path.join(getTemplatesPath(), 'manifest.json'), 'utf8'));
10
+ if (!isTemplateManifest(manifest)) {
11
+ throw new Error('templates/manifest.json is not a valid template manifest.');
12
+ }
13
+ return manifest;
14
+ }
15
+ export function getTemplateVersion(manifest, templateRelativePath) {
16
+ const template = manifest.templates[templateRelativePath];
17
+ if (!template) {
18
+ throw new Error(`Template ${templateRelativePath} is missing from templates/manifest.json.`);
19
+ }
20
+ return template.version;
21
+ }
22
+ function isTemplateManifest(value) {
23
+ if (!value || typeof value !== 'object') {
24
+ return false;
25
+ }
26
+ const manifest = value;
27
+ return (typeof manifest.templateVersion === 'string' &&
28
+ !!manifest.templates &&
29
+ typeof manifest.templates === 'object' &&
30
+ Object.values(manifest.templates).every((template) => !!template &&
31
+ typeof template === 'object' &&
32
+ typeof template.version === 'string' &&
33
+ typeof template.description === 'string' &&
34
+ Array.isArray(template.changes) &&
35
+ template.changes.every((change) => typeof change === 'string')));
36
+ }
37
+ export function renderTemplateForSync({ templateRelativePath, currentPath, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], selectedDatabaseSkills = [], selectedMcpServers = [], }) {
38
+ let contents = readTemplate(templateRelativePath);
39
+ const mcpConfigAgentId = resolveMcpConfigAgentId(templateRelativePath);
40
+ if (mcpConfigAgentId) {
41
+ return renderMcpConfig({ agentId: mcpConfigAgentId, baseContents: contents, selectedMcpServers });
42
+ }
43
+ if (contents.includes('{{PROJECT_OVERVIEW}}')) {
44
+ contents = contents.replace('{{PROJECT_OVERVIEW}}', extractProjectOverview(currentPath) ?? 'Describe this project.');
45
+ }
46
+ contents = renderSkillRouting(contents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills, selectedDatabaseSkills);
47
+ contents = renderWorkerToolboxRoutingPlaceholders(contents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills, selectedDatabaseSkills);
48
+ return contents;
49
+ }
50
+ export function renderMissingWorkflowFiles({ missingTargets, overview, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], selectedDatabaseSkills = [], selectedMcpServers = [], }) {
51
+ return missingTargets.map((target) => {
52
+ let contents = readTemplate(target.templateRelativePath);
53
+ if (target.mcpConfigAgentId && (target.selectedMcpServers?.length || selectedMcpServers.length)) {
54
+ contents = renderMcpConfig({
55
+ agentId: target.mcpConfigAgentId,
56
+ baseContents: contents,
57
+ selectedMcpServers: target.selectedMcpServers ?? selectedMcpServers,
58
+ });
59
+ }
60
+ if (target.requiresProjectOverview) {
61
+ if (!overview?.trim()) {
62
+ throw new Error('Project overview is required to create AGENTS.md.');
63
+ }
64
+ contents = contents.replace('{{PROJECT_OVERVIEW}}', overview.trim());
65
+ }
66
+ contents = renderSkillRouting(contents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills, selectedDatabaseSkills);
67
+ contents = renderWorkerToolboxRoutingPlaceholders(contents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills, selectedDatabaseSkills);
68
+ return {
69
+ label: target.label,
70
+ targetPath: target.targetPath,
71
+ contents,
72
+ };
73
+ });
74
+ }
75
+ export function renderSkillRouting(contents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], selectedDatabaseSkills = []) {
76
+ if (!contents.includes('{{OPTIONAL_SKILL_ROUTING}}')) {
77
+ return contents;
78
+ }
79
+ const optionalRouting = [...selectedLanguageSkills, ...selectedFrameworkSkills, ...selectedDatabaseSkills, ...(selectedArchitectureSkill ? [selectedArchitectureSkill] : []), ...selectedWorkflowSkills]
80
+ .map((skill) => `- ${skill.routingInstruction}`)
81
+ .join('\n');
82
+ return contents.replace('{{OPTIONAL_SKILL_ROUTING}}', optionalRouting);
83
+ }
84
+ export function renderWorkerToolboxRouting({ profile, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], selectedDatabaseSkills = [], }) {
85
+ const selectedSkills = collectWorkerRelevantSkills({
86
+ selectedLanguageSkills,
87
+ selectedFrameworkSkills,
88
+ selectedArchitectureSkill,
89
+ selectedWorkflowSkills,
90
+ selectedDatabaseSkills,
91
+ });
92
+ const selectedSkillLines = selectedSkills.map((skill) => `- ${skill.name}: read \`${getSharedSkillTargetPath(skill)}\` when relevant. ${skill.routingInstruction}`);
93
+ const selectedSkillsSection = selectedSkillLines.length > 0
94
+ ? selectedSkillLines.join('\n')
95
+ : '- No optional implementation-relevant Sibu skills are selected for this project. Use source artifacts and flag unmapped patterns as risks instead of guessing silently.';
96
+ return `## Focused ${profile} worker routing
97
+
98
+ - Always read and apply \`.agents/skills/clean-code/SKILL.md\` before ${profile === 'planner' ? 'writing implementation plan steps' : 'editing code or running story execution'}.
99
+ - Read the worker toolbox skill path provided in the main-agent packet before doing work.
100
+ - Read every required skill path listed in the packet. If a required skill path is missing, stop and report the blocker to the main agent.
101
+ - Read optional installed skill paths only when they are relevant to the story, touched files, source artifacts, or validation work.
102
+ - Treat distilled skill constraints from the packet as binding task constraints.
103
+ - If an optional relevant skill is not installed and you encounter an unmapped language, framework, database, or architecture pattern, do not guess silently; continue only when safe and flag the gap as a ${profile === 'planner' ? 'plan risk' : 'Review Gate risk'}.
104
+
105
+ ### Optional installed skills relevant to ${profile} work
106
+ ${selectedSkillsSection}`;
107
+ }
108
+ export function renderWorkerToolboxRoutingPlaceholders(contents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], selectedDatabaseSkills = []) {
109
+ const placeholderProfiles = [
110
+ { placeholder: '{{PLANNER_WORKER_ROUTING}}', profile: 'planner' },
111
+ { placeholder: '{{EXECUTOR_WORKER_ROUTING}}', profile: 'executor' },
112
+ ];
113
+ let renderedContents = contents;
114
+ for (const { placeholder, profile } of placeholderProfiles) {
115
+ if (!renderedContents.includes(placeholder)) {
116
+ continue;
117
+ }
118
+ renderedContents = renderedContents.replace(placeholder, renderWorkerToolboxRouting({
119
+ profile,
120
+ selectedLanguageSkills,
121
+ selectedFrameworkSkills,
122
+ selectedArchitectureSkill,
123
+ selectedWorkflowSkills,
124
+ selectedDatabaseSkills,
125
+ }));
126
+ }
127
+ return renderedContents;
128
+ }
129
+ function collectWorkerRelevantSkills({ selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills, selectedDatabaseSkills, }) {
130
+ const implementationRelevantWorkflowSkills = selectedWorkflowSkills.filter((skill) => skill.id === 'ai-prompt-engineer-master' || skill.id === 'ux-expert');
131
+ return [
132
+ ...selectedLanguageSkills,
133
+ ...selectedFrameworkSkills,
134
+ ...selectedDatabaseSkills,
135
+ ...(selectedArchitectureSkill ? [selectedArchitectureSkill] : []),
136
+ ...implementationRelevantWorkflowSkills,
137
+ ];
138
+ }
139
+ function getSharedSkillTargetPath(skill) {
140
+ const sharedTargetPath = Object.values(skill.targetRelativePathsByAgent).find((targetPath) => targetPath !== undefined);
141
+ if (!sharedTargetPath) {
142
+ throw new Error(`Selectable skill ${skill.id} has no target path.`);
143
+ }
144
+ return sharedTargetPath;
145
+ }
146
+ export function extractProjectOverview(filePath) {
147
+ if (!fs.existsSync(filePath)) {
148
+ return undefined;
149
+ }
150
+ const contents = fs.readFileSync(filePath, 'utf8');
151
+ const match = contents.match(/## Project overview\s+([\s\S]*?)(?=\n## |$)/);
152
+ const overview = match?.[1]?.trim();
153
+ return overview || undefined;
154
+ }
@@ -0,0 +1,6 @@
1
+ export { handleListSkills } from './list-skills/handler.js';
2
+ export { getNextSkillSelection, handleUseSkill } from './use-skill/handler.js';
3
+ export { handleStopManagingFile, stopSelectedSkill } from './stop-managing-file/handler.js';
4
+ export { getMcpServerListItems, handleListMcpServers } from './list-mcp-servers/handler.js';
5
+ export { getNextMcpSelection, handleUseMcpServer } from './use-mcp-server/handler.js';
6
+ export { applyStoppedMcpFileDeleteDecision, getNextStoppedMcpSelection, handleStopMcpServer, stopSelectedMcpServer } from './stop-mcp-server/handler.js';
@@ -0,0 +1,46 @@
1
+ import { intro, log, outro } from '@clack/prompts';
2
+ import chalk from 'chalk';
3
+ import { SELECTABLE_MCP_SERVERS } from '../../template-catalog/index.js';
4
+ import { getProjectContext } from '../../../shared/paths.js';
5
+ import { renderIntro } from '../../../support/interactive-guidance/index.js';
6
+ import { readStateForDoctor } from '../../workflow-state-ledger/index.js';
7
+ const defaultDependencies = {
8
+ renderIntro,
9
+ intro,
10
+ logMessage: log.message,
11
+ logWarn: log.warn,
12
+ logInfo: log.info,
13
+ outro,
14
+ getStatePath: () => getProjectContext().statePath,
15
+ readState: readStateForDoctor,
16
+ };
17
+ export async function handleListMcpServers(_command, dependencies = defaultDependencies) {
18
+ await dependencies.renderIntro();
19
+ dependencies.intro(chalk.cyan('Available MCP servers'));
20
+ const statePath = dependencies.getStatePath();
21
+ const stateResult = dependencies.readState(statePath);
22
+ const state = stateResult.ok ? stateResult.state : undefined;
23
+ if (!stateResult.ok) {
24
+ dependencies.logWarn(`${stateResult.message} Showing available MCP servers without project state.`);
25
+ dependencies.logInfo('Run `sibu init` before selecting project MCP servers.');
26
+ }
27
+ dependencies.logInfo('Sibu configures MCP files only; prerequisites, credentials, and provider authentication remain user-owned.');
28
+ dependencies.logMessage(chalk.bold('MCP servers'));
29
+ for (const server of getMcpServerListItems(state)) {
30
+ const marker = server.selected ? chalk.green('● selected') : chalk.dim('○ available');
31
+ console.log(` ${marker} ${chalk.bold(server.name)} ${chalk.dim(`(${server.id})`)}`);
32
+ console.log(` ${chalk.dim(server.description)}`);
33
+ console.log(` ${chalk.dim(`Source: ${server.source}`)}`);
34
+ }
35
+ dependencies.outro(chalk.green('MCP server list ready.'));
36
+ }
37
+ export function getMcpServerListItems(state) {
38
+ const selectedServerIds = new Set(state?.selectedMcpServers ?? []);
39
+ return SELECTABLE_MCP_SERVERS.map((server) => ({
40
+ name: server.name,
41
+ id: server.id,
42
+ description: server.description,
43
+ source: server.source,
44
+ selected: selectedServerIds.has(server.id),
45
+ }));
46
+ }
@@ -0,0 +1,75 @@
1
+ import { intro, log, outro } from '@clack/prompts';
2
+ import chalk from 'chalk';
3
+ import { SELECTABLE_ARCHITECTURE_SKILLS, SELECTABLE_DATABASE_SKILLS, SELECTABLE_FRAMEWORK_SKILLS, SELECTABLE_LANGUAGE_SKILLS, SELECTABLE_WORKFLOW_SKILLS } from '../../template-catalog/index.js';
4
+ import { getProjectContext } from '../../../shared/paths.js';
5
+ import { renderIntro } from '../../../support/interactive-guidance/index.js';
6
+ import { readStateForDoctor } from '../../workflow-state-ledger/index.js';
7
+ export async function handleListSkills(_command) {
8
+ await renderIntro();
9
+ intro(chalk.cyan('Available workflow skills'));
10
+ const { statePath } = getProjectContext();
11
+ const stateResult = readStateForDoctor(statePath);
12
+ const state = stateResult.ok ? stateResult.state : undefined;
13
+ if (!stateResult.ok) {
14
+ log.warn(`${stateResult.message} Showing available skills without project state.`);
15
+ log.info('Run `sibu init` before selecting project skills.');
16
+ }
17
+ logSkillGroup('Languages', getLanguageSkillItems(state));
18
+ logSkillGroup('Frameworks', getFrameworkSkillItems(state));
19
+ logSkillGroup('Databases', getDatabaseSkillItems(state));
20
+ logSkillGroup('Architecture', getArchitectureSkillItems(state));
21
+ logSkillGroup('Workflow', getWorkflowSkillItems(state));
22
+ outro(chalk.green('Skill list ready.'));
23
+ }
24
+ function getLanguageSkillItems(state) {
25
+ const selectedSkillIds = new Set(state?.selectedLanguageSkills ?? []);
26
+ return SELECTABLE_LANGUAGE_SKILLS.map((skill) => ({
27
+ name: skill.name,
28
+ id: skill.id,
29
+ description: skill.description,
30
+ selected: selectedSkillIds.has(skill.id),
31
+ }));
32
+ }
33
+ function getFrameworkSkillItems(state) {
34
+ const selectedSkillIds = new Set(state?.selectedFrameworkSkills ?? []);
35
+ return SELECTABLE_FRAMEWORK_SKILLS.map((skill) => ({
36
+ name: skill.name,
37
+ id: skill.id,
38
+ description: skill.description,
39
+ selected: selectedSkillIds.has(skill.id),
40
+ }));
41
+ }
42
+ function getDatabaseSkillItems(state) {
43
+ const selectedSkillIds = new Set(state?.selectedDatabaseSkills ?? []);
44
+ return SELECTABLE_DATABASE_SKILLS.map((skill) => ({
45
+ name: skill.name,
46
+ id: skill.id,
47
+ description: skill.description,
48
+ selected: selectedSkillIds.has(skill.id),
49
+ }));
50
+ }
51
+ function getArchitectureSkillItems(state) {
52
+ return SELECTABLE_ARCHITECTURE_SKILLS.map((skill) => ({
53
+ name: skill.name,
54
+ id: skill.id,
55
+ description: skill.description,
56
+ selected: state?.selectedArchitectureSkill === skill.id,
57
+ }));
58
+ }
59
+ function getWorkflowSkillItems(state) {
60
+ const selectedSkillIds = new Set(state?.selectedWorkflowSkills ?? []);
61
+ return SELECTABLE_WORKFLOW_SKILLS.map((skill) => ({
62
+ name: skill.name,
63
+ id: skill.id,
64
+ description: skill.description,
65
+ selected: selectedSkillIds.has(skill.id),
66
+ }));
67
+ }
68
+ function logSkillGroup(label, skills) {
69
+ log.message(chalk.bold(label));
70
+ for (const skill of skills) {
71
+ const marker = skill.selected ? chalk.green('● selected') : chalk.dim('○ available');
72
+ console.log(` ${marker} ${chalk.bold(skill.name)} ${chalk.dim(`(${skill.id})`)}`);
73
+ console.log(` ${chalk.dim(skill.description)}`);
74
+ }
75
+ }