@juancr11/sibu 0.7.0 → 0.9.0

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 (31) hide show
  1. package/README.md +89 -0
  2. package/bin/entrypoints/cli/create-program.js +13 -0
  3. package/bin/entrypoints/cli/execute-command.js +10 -0
  4. package/bin/modules/interactive-guidance/index.js +1 -1
  5. package/bin/modules/interactive-guidance/prompts.js +34 -1
  6. package/bin/modules/mcp-server-selection-management/index.js +3 -0
  7. package/bin/modules/mcp-server-selection-management/list-mcp-servers/command.js +1 -0
  8. package/bin/modules/mcp-server-selection-management/list-mcp-servers/handler.js +46 -0
  9. package/bin/modules/mcp-server-selection-management/stop-mcp-server/command.js +1 -0
  10. package/bin/modules/mcp-server-selection-management/stop-mcp-server/handler.js +194 -0
  11. package/bin/modules/mcp-server-selection-management/use-mcp-server/command.js +1 -0
  12. package/bin/modules/mcp-server-selection-management/use-mcp-server/handler.js +127 -0
  13. package/bin/modules/project-adoption/handler.js +37 -11
  14. package/bin/modules/skill-selection-management/list-skills/handler.js +11 -1
  15. package/bin/modules/skill-selection-management/stop-managing-file/handler.js +7 -1
  16. package/bin/modules/skill-selection-management/use-skill/handler.js +35 -2
  17. package/bin/modules/sync-review/apply-action.js +5 -1
  18. package/bin/modules/sync-review/sync-preview.js +20 -6
  19. package/bin/modules/template-catalog-rendering/index.js +1 -1
  20. package/bin/modules/template-catalog-rendering/templates.js +59 -4
  21. package/bin/modules/workflow-health-diagnosis/handler.js +13 -3
  22. package/bin/modules/workflow-state-registry/state.js +4 -0
  23. package/bin/modules/workflow-target-planning/catalog.js +34 -0
  24. package/bin/modules/workflow-target-planning/index.js +2 -2
  25. package/bin/modules/workflow-target-planning/workflow-targets.js +82 -9
  26. package/package.json +1 -1
  27. package/templates/manifest.json +27 -6
  28. package/templates/mcp/claude/.mcp.json +3 -0
  29. package/templates/mcp/gemini/settings.json +3 -0
  30. package/templates/skills/postgresql-expert/SKILL.md +72 -0
  31. package/templates/skills/scrum-master-planner/SKILL.md +22 -0
@@ -1,11 +1,11 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { SIBU_VERSION } from '../version-advisory/index.js';
4
- import { MANDATORY_SKILLS, SELECTABLE_ARCHITECTURE_SKILLS, SELECTABLE_FRAMEWORK_SKILLS, SELECTABLE_LANGUAGE_SKILLS, SELECTABLE_WORKFLOW_SKILLS, SUPPORTED_AGENTS, } from './index.js';
4
+ import { MANDATORY_SKILLS, SELECTABLE_ARCHITECTURE_SKILLS, SELECTABLE_DATABASE_SKILLS, SELECTABLE_FRAMEWORK_SKILLS, SELECTABLE_LANGUAGE_SKILLS, SELECTABLE_MCP_SERVERS, SELECTABLE_WORKFLOW_SKILLS, SUPPORTED_AGENTS, } from './index.js';
5
5
  import { sha256 } from '../../shared/hash.js';
6
6
  import { removeUndefinedFields } from '../../shared/object.js';
7
7
  import { readExistingState } from '../workflow-state-registry/index.js';
8
- import { getTemplateVersion, readTemplate, readTemplateManifest, renderSkillRouting } from '../template-catalog-rendering/index.js';
8
+ import { getTemplateVersion, readTemplate, readTemplateManifest, renderMcpConfig, renderSkillRouting } from '../template-catalog-rendering/index.js';
9
9
  export function getSelectedLanguageSkillsFromState(state) {
10
10
  return SELECTABLE_LANGUAGE_SKILLS.filter((skill) => state.selectedLanguageSkills?.includes(skill.id));
11
11
  }
@@ -18,12 +18,19 @@ export function getSelectedArchitectureSkillFromState(state) {
18
18
  export function getSelectedWorkflowSkillsFromState(state) {
19
19
  return SELECTABLE_WORKFLOW_SKILLS.filter((skill) => state.selectedWorkflowSkills?.includes(skill.id));
20
20
  }
21
- export function getSelectedSkillTargetsForAgents(selectedAgents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = []) {
21
+ export function getSelectedDatabaseSkillsFromState(state) {
22
+ return SELECTABLE_DATABASE_SKILLS.filter((skill) => state.selectedDatabaseSkills?.includes(skill.id));
23
+ }
24
+ export function getSelectedMcpServersFromState(state) {
25
+ return SELECTABLE_MCP_SERVERS.filter((server) => state.selectedMcpServers?.includes(server.id));
26
+ }
27
+ export function getSelectedSkillTargetsForAgents(selectedAgents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], selectedDatabaseSkills = []) {
22
28
  const skillTargets = new Map();
23
29
  const selectedSkills = [
24
30
  ...MANDATORY_SKILLS,
25
31
  ...selectedLanguageSkills,
26
32
  ...selectedFrameworkSkills,
33
+ ...selectedDatabaseSkills,
27
34
  ...(selectedArchitectureSkill ? [selectedArchitectureSkill] : []),
28
35
  ...selectedWorkflowSkills,
29
36
  ];
@@ -41,13 +48,49 @@ export function getSelectedSkillTargetsForAgents(selectedAgents, selectedLanguag
41
48
  }
42
49
  return [...skillTargets.values()];
43
50
  }
44
- export function getWorkflowTargets(rootPath, selectedAgents, selectedLanguageSkills = [], selectedFrameworkSkills = [], selectedArchitectureSkill, selectedWorkflowSkills = []) {
45
- return [
51
+ export function getSelectedMcpTargetsForAgents(selectedAgents, selectedMcpServers) {
52
+ if (!selectedMcpServers.some((server) => server.id === 'github')) {
53
+ return [];
54
+ }
55
+ return selectedAgents.flatMap((agent) => {
56
+ if (agent.id === 'codex') {
57
+ return [
58
+ {
59
+ targetRelativePath: '.codex/config.toml',
60
+ templateRelativePath: '.codex/config.toml',
61
+ agentId: 'codex',
62
+ },
63
+ ];
64
+ }
65
+ if (agent.id === 'claude') {
66
+ return [
67
+ {
68
+ targetRelativePath: '.mcp.json',
69
+ templateRelativePath: 'mcp/claude/.mcp.json',
70
+ agentId: 'claude',
71
+ },
72
+ ];
73
+ }
74
+ if (agent.id === 'gemini') {
75
+ return [
76
+ {
77
+ targetRelativePath: '.gemini/settings.json',
78
+ templateRelativePath: 'mcp/gemini/settings.json',
79
+ agentId: 'gemini',
80
+ },
81
+ ];
82
+ }
83
+ return [];
84
+ });
85
+ }
86
+ export function getWorkflowTargets(rootPath, selectedAgents, selectedLanguageSkills = [], selectedFrameworkSkills = [], selectedArchitectureSkill, selectedWorkflowSkills = [], selectedDatabaseSkills = [], selectedMcpServers = []) {
87
+ const targets = [
46
88
  {
47
89
  label: 'AGENTS.md',
48
90
  targetPath: path.join(rootPath, 'AGENTS.md'),
49
91
  templateRelativePath: 'AGENTS.md',
50
92
  requiresProjectOverview: true,
93
+ targetKind: 'agent-support',
51
94
  },
52
95
  ...selectedAgents.flatMap((agent) => {
53
96
  if (!agent.targetRelativePath || !agent.templateRelativePath) {
@@ -59,27 +102,55 @@ export function getWorkflowTargets(rootPath, selectedAgents, selectedLanguageSki
59
102
  targetPath: path.join(rootPath, agent.targetRelativePath),
60
103
  templateRelativePath: agent.templateRelativePath,
61
104
  requiresProjectOverview: false,
105
+ targetKind: 'agent-support',
62
106
  },
63
107
  ];
64
108
  }),
65
- ...getSelectedSkillTargetsForAgents(selectedAgents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills).map((skillTarget) => ({
109
+ ...getSelectedSkillTargetsForAgents(selectedAgents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills, selectedDatabaseSkills).map((skillTarget) => ({
66
110
  label: skillTarget.targetRelativePath,
67
111
  targetPath: path.join(rootPath, skillTarget.targetRelativePath),
68
112
  templateRelativePath: skillTarget.templateRelativePath,
69
113
  requiresProjectOverview: false,
114
+ targetKind: 'skill',
70
115
  })),
71
116
  ];
117
+ for (const mcpTarget of getSelectedMcpTargetsForAgents(selectedAgents, selectedMcpServers)) {
118
+ const targetPath = path.join(rootPath, mcpTarget.targetRelativePath);
119
+ const existingTarget = targets.find((target) => target.targetPath === targetPath);
120
+ if (existingTarget) {
121
+ existingTarget.selectedMcpServers = selectedMcpServers;
122
+ existingTarget.mcpConfigAgentId = mcpTarget.agentId;
123
+ continue;
124
+ }
125
+ targets.push({
126
+ label: mcpTarget.targetRelativePath,
127
+ targetPath,
128
+ templateRelativePath: mcpTarget.templateRelativePath,
129
+ requiresProjectOverview: false,
130
+ targetKind: 'mcp-config',
131
+ mcpConfigAgentId: mcpTarget.agentId,
132
+ selectedMcpServers,
133
+ });
134
+ }
135
+ return targets;
72
136
  }
73
- export function renderMissingWorkflowFiles({ missingTargets, overview, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], }) {
137
+ export function renderMissingWorkflowFiles({ missingTargets, overview, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], selectedDatabaseSkills = [], selectedMcpServers = [], }) {
74
138
  return missingTargets.map((target) => {
75
139
  let contents = readTemplate(target.templateRelativePath);
140
+ if (target.mcpConfigAgentId && (target.selectedMcpServers?.length || selectedMcpServers.length)) {
141
+ contents = renderMcpConfig({
142
+ agentId: target.mcpConfigAgentId,
143
+ baseContents: contents,
144
+ selectedMcpServers: target.selectedMcpServers ?? selectedMcpServers,
145
+ });
146
+ }
76
147
  if (target.requiresProjectOverview) {
77
148
  if (!overview?.trim()) {
78
149
  throw new Error('Project overview is required to create AGENTS.md.');
79
150
  }
80
151
  contents = contents.replace('{{PROJECT_OVERVIEW}}', overview.trim());
81
152
  }
82
- contents = renderSkillRouting(contents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills);
153
+ contents = renderSkillRouting(contents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills, selectedDatabaseSkills);
83
154
  return {
84
155
  label: target.label,
85
156
  targetPath: target.targetPath,
@@ -87,7 +158,7 @@ export function renderMissingWorkflowFiles({ missingTargets, overview, selectedL
87
158
  };
88
159
  });
89
160
  }
90
- export function writeSibuState({ rootPath, statePath, selectedAgents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], targets, }) {
161
+ export function writeSibuState({ rootPath, statePath, selectedAgents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], selectedDatabaseSkills = [], selectedMcpServers, targets, }) {
91
162
  const previousState = readExistingState(statePath);
92
163
  const now = new Date().toISOString();
93
164
  const manifest = readTemplateManifest();
@@ -101,6 +172,8 @@ export function writeSibuState({ rootPath, statePath, selectedAgents, selectedLa
101
172
  selectedFrameworkSkills: selectedFrameworkSkills.map((skill) => skill.id),
102
173
  selectedArchitectureSkill: selectedArchitectureSkill?.id,
103
174
  selectedWorkflowSkills: selectedWorkflowSkills.map((skill) => skill.id),
175
+ selectedDatabaseSkills: selectedDatabaseSkills.map((skill) => skill.id),
176
+ ...(selectedMcpServers !== undefined ? { selectedMcpServers: selectedMcpServers.map((server) => server.id) } : {}),
104
177
  managedFiles: Object.fromEntries(targets
105
178
  .filter((target) => fs.existsSync(target.targetPath))
106
179
  .map((target) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juancr11/sibu",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "CLI for setting up a local AI-augmented development workflow.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,5 +1,5 @@
1
1
  {
2
- "templateVersion": "69",
2
+ "templateVersion": "74",
3
3
  "templates": {
4
4
  "AGENTS.md": {
5
5
  "version": "25",
@@ -9,10 +9,10 @@
9
9
  ]
10
10
  },
11
11
  ".codex/config.toml": {
12
- "version": "1",
13
- "description": "Codex configuration pointing to AGENTS.md.",
12
+ "version": "2",
13
+ "description": "Codex configuration pointing to AGENTS.md and rendering selected MCP servers with Codex-compatible settings.",
14
14
  "changes": [
15
- "Configures Codex to use the root AGENTS.md instructions file."
15
+ "Updates Codex GitHub MCP rendering to use the hosted HTTPS endpoint with bearer_token_env_var instead of Docker command arguments."
16
16
  ]
17
17
  },
18
18
  "GEMINI.md": {
@@ -29,6 +29,20 @@
29
29
  "Delegates Claude project instructions to AGENTS.md as the source of truth."
30
30
  ]
31
31
  },
32
+ "mcp/claude/.mcp.json": {
33
+ "version": "2",
34
+ "description": "Claude MCP configuration template managed when selectable MCP servers are selected.",
35
+ "changes": [
36
+ "Updates Claude GitHub MCP rendering to use the hosted HTTPS endpoint with an Authorization header instead of Docker."
37
+ ]
38
+ },
39
+ "mcp/gemini/settings.json": {
40
+ "version": "2",
41
+ "description": "Gemini MCP configuration template managed when selectable MCP servers are selected.",
42
+ "changes": [
43
+ "Updates Gemini GitHub MCP rendering to use the hosted streamable HTTP endpoint with an Authorization header instead of Docker."
44
+ ]
45
+ },
32
46
  "skills/clean-code/SKILL.md": {
33
47
  "version": "4",
34
48
  "description": "Mandatory clean-code skill installed once at the shared .agents/skills workspace path.",
@@ -80,6 +94,13 @@
80
94
  "Adds an optional Go skill with concise, Effective Go\u2013style guidance for .go files, package APIs, interfaces, errors, receivers, concurrency, and tests."
81
95
  ]
82
96
  },
97
+ "skills/postgresql-expert/SKILL.md": {
98
+ "version": "1",
99
+ "description": "Selectable PostgreSQL Expert skill for practical database schema design and PostgreSQL-specific tradeoff guidance.",
100
+ "changes": [
101
+ "Adds an optional PostgreSQL Expert database skill focused on simple schema design, data integrity, migrations, access patterns, and purposeful indexing."
102
+ ]
103
+ },
83
104
  "skills/architecture/ddd-hexagonal/SKILL.md": {
84
105
  "version": "4",
85
106
  "description": "Selectable back-end architecture skill for DDD and Hexagonal Architecture.",
@@ -109,10 +130,10 @@
109
130
  ]
110
131
  },
111
132
  "skills/scrum-master-planner/SKILL.md": {
112
- "version": "7",
133
+ "version": "8",
113
134
  "description": "Mandatory Scrum planner skill for creating pragmatic Epics and User Stories from approved feature and technical design docs.",
114
135
  "changes": [
115
- "Updates Scrum planning guidance to preserve Deep Module implementation boundaries from technical designs."
136
+ "Adds optional GitHub issue export guidance after Scrum planning when GitHub MCP tools are available."
116
137
  ]
117
138
  },
118
139
  "skills/ai-implementation-planner/SKILL.md": {
@@ -0,0 +1,3 @@
1
+ {
2
+ "mcpServers": {}
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "mcpServers": {}
3
+ }
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: postgresql-expert
3
+ description: Use this skill for PostgreSQL schema design, migrations, constraints, queries, indexing, and database tradeoffs when practical database judgment is needed.
4
+ ---
5
+
6
+ # PostgreSQL Expert
7
+
8
+ Use this skill when working with PostgreSQL database design or database-facing application changes.
9
+
10
+ Apply this skill together with `clean-code`. Keep the guidance practical: prefer the simplest database design that protects data integrity and supports the application's real access patterns.
11
+
12
+ ## Use this skill for
13
+
14
+ - designing or reviewing PostgreSQL schemas
15
+ - planning migrations and safe schema evolution
16
+ - choosing keys, constraints, relationships, and transactions
17
+ - reasoning about queries, access patterns, and indexes
18
+ - deciding whether PostgreSQL-specific features are worth using
19
+ - reviewing database-related tradeoffs in application code
20
+
21
+ ## Core principles
22
+
23
+ ### 1. Start with the product model
24
+ - Model the real domain concepts, not speculative future reporting or scaling needs.
25
+ - Prefer clear table and column names that match product language.
26
+ - Keep schemas boring until the product needs something more specialized.
27
+ - Do not add tables, abstractions, or generic metadata columns just in case.
28
+
29
+ ### 2. Protect data integrity in the database
30
+ - Use primary keys, foreign keys, `NOT NULL`, `UNIQUE`, and `CHECK` constraints when they express real invariants.
31
+ - Prefer database-enforced integrity over relying only on application checks for durable rules.
32
+ - Make deletion behavior explicit with appropriate foreign-key actions.
33
+ - Use transactions when a change must succeed or fail as one unit.
34
+
35
+ ### 3. Evolve schemas safely
36
+ - Treat migrations as production changes that need clear rollback or recovery thinking.
37
+ - Prefer small, reversible migration steps for risky changes.
38
+ - Avoid destructive changes until data has been backfilled, verified, and callers have moved over.
39
+ - Consider lock behavior and table size before changing large production tables.
40
+
41
+ ### 4. Design from access patterns, not guesses
42
+ - Understand the queries the application actually needs before optimizing.
43
+ - Keep common reads and writes straightforward before introducing denormalization.
44
+ - Use normalization for clarity and integrity; denormalize only for a measured or well-understood reason.
45
+ - Explain tradeoffs when choosing between simpler schema shape and query convenience.
46
+
47
+ ### 5. Add indexes only when justified
48
+ - Do not add indexes just because a column is used, foreign-keyed, or might be queried someday.
49
+ - Add an index when there is a clear query, filtering, joining, sorting, uniqueness, or constraint need.
50
+ - Remember that indexes speed some reads but add write cost, storage cost, and maintenance overhead.
51
+ - Prefer a small number of purposeful indexes over broad defensive indexing.
52
+
53
+ ### 6. Use PostgreSQL features with restraint
54
+ - Consider PostgreSQL capabilities such as JSONB, arrays, partial indexes, generated columns, enums, extensions, and full-text search when they simplify a real requirement.
55
+ - Do not use PostgreSQL-specific features to appear sophisticated when standard relational modeling is clearer.
56
+ - Be explicit about portability tradeoffs when choosing PostgreSQL-specific behavior.
57
+ - Prefer built-in PostgreSQL capabilities before adding extra infrastructure.
58
+
59
+ ### 7. Keep database advice actionable
60
+ - Tie recommendations to the schema, query, migration, or invariant at hand.
61
+ - Say what evidence would change the recommendation, such as query plans, row counts, write volume, or latency targets.
62
+ - When context is missing, ask for the relevant schema, migration, query, or access pattern instead of guessing.
63
+ - Avoid broad DBA checklists unless the task is explicitly about operations or performance investigation.
64
+
65
+ ## Decision rule
66
+
67
+ When unsure, prefer:
68
+ 1. simple schema design that matches current product needs
69
+ 2. explicit database constraints for real invariants
70
+ 3. safe, incremental migrations
71
+ 4. query-aware design over speculative optimization
72
+ 5. purposeful indexes over blanket indexing
@@ -210,6 +210,28 @@ Before finishing, verify:
210
210
  - no Story adds scope that is absent from the feature brief or technical design
211
211
  - acceptance criteria are testable enough for a reviewer
212
212
 
213
+ ### 6. Optionally export planning artifacts to GitHub Issues
214
+
215
+ After all local Epic and User Story files are written, check whether GitHub MCP tools are available for issue creation, label creation, and native sub-issue mutation.
216
+
217
+ If any required GitHub MCP capability is unavailable, do not offer GitHub export. Finish with the normal local planning response.
218
+
219
+ If the required GitHub MCP capabilities are available:
220
+
221
+ 1. Resolve the target repository from the current local repo's GitHub `origin` remote only. Do not ask for or use another repository.
222
+ 2. Ask one explicit opt-in question before any GitHub mutation: "GitHub MCP is available. Create GitHub Issues for these Epics and User Stories in the current repo?"
223
+ 3. If the user declines, perform no GitHub mutation.
224
+ 4. If the user accepts, create a fresh issue set every time. Do not search for duplicates or update existing issues.
225
+ 5. Create missing labels before creating issues: `epic`, `user-story`, and `sibu-generated`.
226
+ 6. Create one issue per Epic with labels `epic` and `sibu-generated`.
227
+ 7. Create one issue per User Story with labels `user-story` and `sibu-generated`.
228
+ 8. Attach each User Story issue as a native GitHub sub-issue of its parent Epic issue.
229
+ 9. Report created issue numbers or URLs.
230
+
231
+ Keep issue bodies concise and source-grounded. Include the source local doc path and relevant summary, scope, acceptance criteria, or validation notes. Do not modify local Markdown files with GitHub URLs.
232
+
233
+ Native sub-issues are required for this export. Preserve each created User Story issue's GitHub issue `id` because native sub-issue APIs need the child issue ID, not only its issue number. If label creation, issue creation, issue ID access, or native sub-issue attachment fails or is unavailable, fail clearly and do not fall back to Markdown checklists, loose links, GitHub Projects, milestones, assignees, or status tracking.
234
+
213
235
  ## Final response behavior
214
236
 
215
237
  After writing files, final-answer with only: