@juancr11/sibu 0.5.3 → 0.7.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 (67) hide show
  1. package/bin/admin/changelog.js +155 -0
  2. package/bin/admin/release.js +217 -0
  3. package/bin/entrypoints/cli/create-program.js +1 -1
  4. package/bin/entrypoints/cli/execute-command.js +6 -6
  5. package/bin/modules/interactive-guidance/index.js +1 -0
  6. package/bin/{shared → modules/interactive-guidance}/prompts.js +1 -1
  7. package/bin/modules/maintainer-release-support/generate-changelog/changelog-format.js +213 -0
  8. package/bin/modules/maintainer-release-support/generate-changelog/changelog-writer.js +91 -0
  9. package/bin/modules/maintainer-release-support/generate-changelog/git-history.js +93 -0
  10. package/bin/modules/maintainer-release-support/generate-changelog/handler.js +167 -0
  11. package/bin/modules/maintainer-release-support/generate-changelog/semver.js +40 -0
  12. package/bin/modules/maintainer-release-support/index.js +2 -0
  13. package/bin/modules/maintainer-release-support/release-workflow/git-release.js +114 -0
  14. package/bin/modules/maintainer-release-support/release-workflow/handler.js +369 -0
  15. package/bin/modules/maintainer-release-support/release-workflow/package-json.js +181 -0
  16. package/bin/modules/maintainer-release-support/release-workflow/release-plan.js +87 -0
  17. package/bin/{features/init-project → modules/project-adoption}/handler.js +3 -3
  18. package/bin/modules/project-adoption/index.js +1 -0
  19. package/bin/modules/skill-selection-management/index.js +3 -0
  20. package/bin/{features → modules/skill-selection-management}/list-skills/handler.js +4 -4
  21. package/bin/{features → modules/skill-selection-management}/stop-managing-file/handler.js +9 -8
  22. package/bin/modules/skill-selection-management/use-skill/command.js +1 -0
  23. package/bin/{features → modules/skill-selection-management}/use-skill/handler.js +7 -6
  24. package/bin/{features/sync-project → modules/sync-review}/apply-action.js +3 -3
  25. package/bin/modules/sync-review/command.js +1 -0
  26. package/bin/{features/sync-project → modules/sync-review}/handler.js +4 -4
  27. package/bin/modules/sync-review/index.js +5 -0
  28. package/bin/{shared → modules/sync-review}/sync-preview.js +4 -4
  29. package/bin/modules/template-catalog-rendering/index.js +1 -0
  30. package/bin/modules/template-catalog-rendering/templates.js +60 -0
  31. package/bin/modules/version-advisory/index.js +1 -0
  32. package/bin/{shared → modules/version-advisory}/npm-version.js +29 -2
  33. package/bin/modules/workflow-health-diagnosis/command.js +1 -0
  34. package/bin/{features/doctor-project → modules/workflow-health-diagnosis}/handler.js +8 -7
  35. package/bin/modules/workflow-health-diagnosis/index.js +1 -0
  36. package/bin/modules/workflow-mutation-readiness/index.js +1 -0
  37. package/bin/{shared → modules/workflow-mutation-readiness}/workflow-mutation-readiness.js +3 -3
  38. package/bin/modules/workflow-state-registry/index.js +1 -0
  39. package/bin/{shared → modules/workflow-state-registry}/state.js +1 -1
  40. package/bin/modules/workflow-target-planning/catalog.js +233 -0
  41. package/bin/modules/workflow-target-planning/index.js +2 -0
  42. package/bin/modules/workflow-target-planning/workflow-targets.js +125 -0
  43. package/bin/shared/catalog.js +0 -244
  44. package/bin/shared/paths.js +1 -12
  45. package/bin/shared/workflow-targets.js +3 -2
  46. package/package.json +5 -3
  47. package/templates/AGENTS.md +4 -1
  48. package/templates/manifest.json +33 -22
  49. package/templates/skills/ai-implementation-plan-executor/SKILL.md +93 -51
  50. package/templates/skills/ai-implementation-planner/SKILL.md +52 -8
  51. package/templates/skills/architecture/command-pattern/SKILL.md +38 -16
  52. package/templates/skills/architecture/ddd-hexagonal/SKILL.md +19 -4
  53. package/templates/skills/deep-module-map-writer/SKILL.md +241 -0
  54. package/templates/skills/feature-brief-writer/SKILL.md +86 -13
  55. package/templates/skills/product-vision-writer/SKILL.md +25 -0
  56. package/templates/skills/scrum-master-planner/SKILL.md +29 -0
  57. package/templates/skills/technical-design-writer/SKILL.md +48 -5
  58. package/templates/skills/ux-expert/SKILL.md +28 -0
  59. package/bin/features/sync-project/preview.js +0 -1
  60. /package/bin/{features/doctor-project/command.js → modules/cli-command-surface/index.js} +0 -0
  61. /package/bin/{features/init-project → modules/maintainer-release-support/generate-changelog}/command.js +0 -0
  62. /package/bin/{features/list-skills → modules/maintainer-release-support/release-workflow}/command.js +0 -0
  63. /package/bin/{features/stop-managing-file → modules/project-adoption}/command.js +0 -0
  64. /package/bin/{features/sync-project → modules/skill-selection-management/list-skills}/command.js +0 -0
  65. /package/bin/{features/use-skill → modules/skill-selection-management/stop-managing-file}/command.js +0 -0
  66. /package/bin/{features/sync-project → modules/sync-review}/action-prompt.js +0 -0
  67. /package/bin/{features/sync-project → modules/sync-review}/log-preview.js +0 -0
@@ -2,14 +2,15 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { cancel, intro, isCancel, log, outro, select } from '@clack/prompts';
4
4
  import chalk from 'chalk';
5
- import { STATE_RELATIVE_PATH, resolveSelectableSkillById } from '../../shared/catalog.js';
6
- import { readFileHashIfPresent, sha256 } from '../../shared/hash.js';
7
- import { getProjectContext } from '../../shared/paths.js';
8
- import { renderIntro } from '../../shared/prompts.js';
9
- import { cloneState, readStateForDoctor, writeStateFile } from '../../shared/state.js';
10
- import { getTemplateVersion, readTemplateManifest, renderTemplateForSync } from '../../shared/templates.js';
11
- import { removeUndefinedFields } from '../../shared/object.js';
12
- import { getSelectedAgentsFromState, getSelectedArchitectureSkillFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getSelectedWorkflowSkillsFromState, } from '../../shared/workflow-targets.js';
5
+ import { STATE_RELATIVE_PATH } from '../../../shared/catalog.js';
6
+ import { resolveSelectableSkillById } from '../../workflow-target-planning/index.js';
7
+ import { readFileHashIfPresent, sha256 } from '../../../shared/hash.js';
8
+ import { getProjectContext } from '../../../shared/paths.js';
9
+ import { renderIntro } from '../../interactive-guidance/index.js';
10
+ import { cloneState, readStateForDoctor, writeStateFile } from '../../workflow-state-registry/index.js';
11
+ import { getTemplateVersion, readTemplateManifest, renderTemplateForSync } from '../../template-catalog-rendering/index.js';
12
+ import { removeUndefinedFields } from '../../../shared/object.js';
13
+ import { getSelectedAgentsFromState, getSelectedArchitectureSkillFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getSelectedWorkflowSkillsFromState, } from '../../workflow-target-planning/index.js';
13
14
  export async function handleStopManagingFile({ skillName }) {
14
15
  await renderIntro();
15
16
  intro(chalk.cyan('Updating skill management'));
@@ -1,12 +1,13 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { log } from '@clack/prompts';
4
- import { STATE_RELATIVE_PATH, resolveSelectableSkillById } from '../../shared/catalog.js';
5
- import { sha256 } from '../../shared/hash.js';
6
- import { getProjectContext } from '../../shared/paths.js';
7
- import { renderTemplateForSync } from '../../shared/templates.js';
8
- import { getWorkflowMutationReadiness } from '../../shared/workflow-mutation-readiness.js';
9
- import { getSelectedAgentsFromState, getWorkflowTargets, renderMissingWorkflowFiles, writeSibuState } from '../../shared/workflow-targets.js';
4
+ import { STATE_RELATIVE_PATH } from '../../../shared/catalog.js';
5
+ import { resolveSelectableSkillById } from '../../workflow-target-planning/index.js';
6
+ import { sha256 } from '../../../shared/hash.js';
7
+ import { getProjectContext } from '../../../shared/paths.js';
8
+ import { renderTemplateForSync } from '../../template-catalog-rendering/index.js';
9
+ import { getWorkflowMutationReadiness } from '../../workflow-mutation-readiness/index.js';
10
+ import { getSelectedAgentsFromState, getWorkflowTargets, renderMissingWorkflowFiles, writeSibuState } from '../../workflow-target-planning/index.js';
10
11
  export async function handleUseSkill(command) {
11
12
  const { rootPath, statePath } = getProjectContext();
12
13
  const readiness = getWorkflowMutationReadiness({ rootPath, statePath });
@@ -3,9 +3,9 @@ import path from 'node:path';
3
3
  import { log } from '@clack/prompts';
4
4
  import { sha256 } from '../../shared/hash.js';
5
5
  import { getSideTemplatePath } from '../../shared/paths.js';
6
- import { cloneState } from '../../shared/state.js';
7
- import { getTemplateVersion, renderTemplateForSync } from '../../shared/templates.js';
8
- import { getSelectedArchitectureSkillFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getSelectedWorkflowSkillsFromState, } from '../../shared/workflow-targets.js';
6
+ import { cloneState } from '../workflow-state-registry/index.js';
7
+ import { getTemplateVersion, renderTemplateForSync } from '../template-catalog-rendering/index.js';
8
+ import { getSelectedArchitectureSkillFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getSelectedWorkflowSkillsFromState, } from '../workflow-target-planning/index.js';
9
9
  export function applySyncAction({ rootPath, state, manifest, preview, action, }) {
10
10
  const nextState = cloneState(state);
11
11
  const managedFile = nextState.managedFiles[preview.relativePath] ?? preview.managedFile;
@@ -0,0 +1 @@
1
+ export {};
@@ -2,13 +2,13 @@ import { intro, log, outro } from '@clack/prompts';
2
2
  import chalk from 'chalk';
3
3
  import { STATE_RELATIVE_PATH } from '../../shared/catalog.js';
4
4
  import { getProjectContext } from '../../shared/paths.js';
5
- import { askForMissingFrameworkSkills, askForNewArchitectureSkill, askForNewLanguageSkills, renderIntro } from '../../shared/prompts.js';
6
- import { readStateForDoctor, writeStateFile } from '../../shared/state.js';
7
- import { readTemplateManifest } from '../../shared/templates.js';
5
+ import { askForMissingFrameworkSkills, askForNewArchitectureSkill, askForNewLanguageSkills, renderIntro } from '../interactive-guidance/index.js';
6
+ import { readStateForDoctor, writeStateFile } from '../workflow-state-registry/index.js';
7
+ import { readTemplateManifest } from '../template-catalog-rendering/index.js';
8
8
  import { askForSyncAction } from './action-prompt.js';
9
9
  import { applySyncAction } from './apply-action.js';
10
10
  import { logSyncPreview } from './log-preview.js';
11
- import { getSyncPreviews, isActionableSyncPreview, shouldAskForSyncAction } from './preview.js';
11
+ import { getSyncPreviews, isActionableSyncPreview, shouldAskForSyncAction } from './sync-preview.js';
12
12
  export async function handleSyncProject(_command) {
13
13
  await renderIntro();
14
14
  intro(chalk.cyan('Reviewing workflow updates'));
@@ -0,0 +1,5 @@
1
+ export { askForSyncAction } from './action-prompt.js';
2
+ export { applySyncAction } from './apply-action.js';
3
+ export { handleSyncProject } from './handler.js';
4
+ export { logSyncPreview } from './log-preview.js';
5
+ export { getSyncPreviews, isActionableSyncPreview, shouldAskForSyncAction } from './sync-preview.js';
@@ -1,9 +1,9 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { sha256 } from './hash.js';
4
- import { hasReviewedTemplateVersion } from './state.js';
5
- import { renderTemplateForSync } from './templates.js';
6
- import { getSelectedAgentsFromState, getSelectedArchitectureSkillFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getSelectedWorkflowSkillsFromState, getWorkflowTargets, } from './workflow-targets.js';
3
+ import { sha256 } from '../../shared/hash.js';
4
+ import { hasReviewedTemplateVersion } from '../workflow-state-registry/index.js';
5
+ import { renderTemplateForSync } from '../template-catalog-rendering/index.js';
6
+ import { getSelectedAgentsFromState, getSelectedArchitectureSkillFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getSelectedWorkflowSkillsFromState, getWorkflowTargets, } from '../workflow-target-planning/index.js';
7
7
  const ACTIONABLE_SYNC_PREVIEW_STATUSES = new Set([
8
8
  'new-template',
9
9
  'missing',
@@ -0,0 +1 @@
1
+ export { extractProjectOverview, getTemplateVersion, readTemplate, readTemplateManifest, renderSkillRouting, renderTemplateForSync, } from './templates.js';
@@ -0,0 +1,60 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { getTemplatesPath } from '../../shared/paths.js';
4
+ export function readTemplate(relativePath) {
5
+ return fs.readFileSync(path.join(getTemplatesPath(), relativePath), 'utf8');
6
+ }
7
+ export function readTemplateManifest() {
8
+ const manifest = JSON.parse(fs.readFileSync(path.join(getTemplatesPath(), 'manifest.json'), 'utf8'));
9
+ if (!isTemplateManifest(manifest)) {
10
+ throw new Error('templates/manifest.json is not a valid template manifest.');
11
+ }
12
+ return manifest;
13
+ }
14
+ export function getTemplateVersion(manifest, templateRelativePath) {
15
+ const template = manifest.templates[templateRelativePath];
16
+ if (!template) {
17
+ throw new Error(`Template ${templateRelativePath} is missing from templates/manifest.json.`);
18
+ }
19
+ return template.version;
20
+ }
21
+ export function renderTemplateForSync({ templateRelativePath, currentPath, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = [], }) {
22
+ let contents = readTemplate(templateRelativePath);
23
+ if (contents.includes('{{PROJECT_OVERVIEW}}')) {
24
+ contents = contents.replace('{{PROJECT_OVERVIEW}}', extractProjectOverview(currentPath) ?? 'Describe this project.');
25
+ }
26
+ return renderSkillRouting(contents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills);
27
+ }
28
+ export function renderSkillRouting(contents, selectedLanguageSkills, selectedFrameworkSkills, selectedArchitectureSkill, selectedWorkflowSkills = []) {
29
+ if (!contents.includes('{{OPTIONAL_SKILL_ROUTING}}')) {
30
+ return contents;
31
+ }
32
+ const optionalRouting = [...selectedLanguageSkills, ...selectedFrameworkSkills, ...(selectedArchitectureSkill ? [selectedArchitectureSkill] : []), ...selectedWorkflowSkills]
33
+ .map((skill) => `- ${skill.routingInstruction}`)
34
+ .join('\n');
35
+ return contents.replace('{{OPTIONAL_SKILL_ROUTING}}', optionalRouting);
36
+ }
37
+ export function extractProjectOverview(filePath) {
38
+ if (!fs.existsSync(filePath)) {
39
+ return undefined;
40
+ }
41
+ const contents = fs.readFileSync(filePath, 'utf8');
42
+ const match = contents.match(/## Project overview\s+([\s\S]*?)(?=\n## |$)/);
43
+ const overview = match?.[1]?.trim();
44
+ return overview || undefined;
45
+ }
46
+ function isTemplateManifest(value) {
47
+ if (!value || typeof value !== 'object') {
48
+ return false;
49
+ }
50
+ const manifest = value;
51
+ return (typeof manifest.templateVersion === 'string' &&
52
+ !!manifest.templates &&
53
+ typeof manifest.templates === 'object' &&
54
+ Object.values(manifest.templates).every((template) => !!template &&
55
+ typeof template === 'object' &&
56
+ typeof template.version === 'string' &&
57
+ typeof template.description === 'string' &&
58
+ Array.isArray(template.changes) &&
59
+ template.changes.every((change) => typeof change === 'string')));
60
+ }
@@ -0,0 +1 @@
1
+ export { checkForLatestSibuVersion, SIBU_CACHE_HOME_ENV, SIBU_PACKAGE_NAME, SIBU_VERSION } from './npm-version.js';
@@ -1,7 +1,13 @@
1
1
  import fs from 'node:fs';
2
+ import os from 'node:os';
2
3
  import path from 'node:path';
3
- import { NPM_VERSION_LOOKUP_MODE_ENV, NPM_VERSION_OVERRIDE_ENV, SIBU_PACKAGE_NAME, SIBU_VERSION, SUPPORTED_NPM_LOOKUP_MODES } from './catalog.js';
4
- import { getNpmVersionCachePath } from './paths.js';
4
+ import { fileURLToPath } from 'node:url';
5
+ export const SIBU_PACKAGE_NAME = '@juancr11/sibu';
6
+ export const SIBU_VERSION = readPackageVersion();
7
+ export const NPM_VERSION_LOOKUP_MODE_ENV = 'SIBU_NPM_LOOKUP_MODE';
8
+ export const NPM_VERSION_OVERRIDE_ENV = 'SIBU_NPM_LATEST_VERSION';
9
+ export const SIBU_CACHE_HOME_ENV = 'SIBU_CACHE_HOME';
10
+ export const SUPPORTED_NPM_LOOKUP_MODES = ['live', 'offline'];
5
11
  const NPM_VERSION_CACHE_TTL_MS = 6 * 60 * 60 * 1000;
6
12
  const NPM_REGISTRY_URL = 'https://registry.npmjs.org';
7
13
  export async function checkForLatestSibuVersion(options = {}) {
@@ -176,3 +182,24 @@ function isNpmVersionCacheRecord(value) {
176
182
  typeof record.packageName === 'string' &&
177
183
  typeof record.source === 'string');
178
184
  }
185
+ function getNpmVersionCachePath() {
186
+ return path.join(getSibuCacheRoot(), 'cache', 'npm-version.json');
187
+ }
188
+ function getSibuCacheRoot() {
189
+ const override = process.env[SIBU_CACHE_HOME_ENV]?.trim();
190
+ if (override) {
191
+ return path.resolve(override);
192
+ }
193
+ return path.join(os.homedir(), '.sibu');
194
+ }
195
+ function readPackageVersion() {
196
+ const packageJsonPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..', 'package.json');
197
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
198
+ if (!isPackageJsonWithVersion(packageJson)) {
199
+ throw new Error(`Could not read Sibu version from ${packageJsonPath}.`);
200
+ }
201
+ return packageJson.version;
202
+ }
203
+ function isPackageJsonWithVersion(value) {
204
+ return Boolean(value && typeof value === 'object' && typeof value.version === 'string');
205
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -2,14 +2,15 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { intro, log, outro } from '@clack/prompts';
4
4
  import chalk from 'chalk';
5
- import { SELECTABLE_ARCHITECTURE_SKILLS, SELECTABLE_FRAMEWORK_SKILLS, SELECTABLE_LANGUAGE_SKILLS, STATE_RELATIVE_PATH, SUPPORTED_AGENTS } from '../../shared/catalog.js';
5
+ import { STATE_RELATIVE_PATH } from '../../shared/catalog.js';
6
+ import { SELECTABLE_ARCHITECTURE_SKILLS, SELECTABLE_FRAMEWORK_SKILLS, SELECTABLE_LANGUAGE_SKILLS, SUPPORTED_AGENTS } from '../workflow-target-planning/index.js';
6
7
  import { sha256 } from '../../shared/hash.js';
7
- import { checkForLatestSibuVersion } from '../../shared/npm-version.js';
8
+ import { checkForLatestSibuVersion } from '../version-advisory/index.js';
8
9
  import { getProjectContext } from '../../shared/paths.js';
9
- import { renderIntro } from '../../shared/prompts.js';
10
- import { hasReviewedTemplateVersion, readStateForDoctor } from '../../shared/state.js';
11
- import { getTemplateVersion, readTemplateManifest } from '../../shared/templates.js';
12
- import { getSelectedAgentsFromState, getSelectedArchitectureSkillFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getWorkflowTargets, } from '../../shared/workflow-targets.js';
10
+ import { renderIntro } from '../interactive-guidance/index.js';
11
+ import { hasReviewedTemplateVersion, readStateForDoctor } from '../workflow-state-registry/index.js';
12
+ import { getTemplateVersion, readTemplateManifest } from '../template-catalog-rendering/index.js';
13
+ import { getSelectedAgentsFromState, getSelectedArchitectureSkillFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getWorkflowTargets, } from '../workflow-target-planning/index.js';
13
14
  export async function handleDoctorProject(_command) {
14
15
  await renderIntro();
15
16
  intro(chalk.cyan('Checking workflow state'));
@@ -77,7 +78,7 @@ function logSyncNextStep() {
77
78
  log.info(line);
78
79
  }
79
80
  }
80
- function diagnoseState({ rootPath, state }) {
81
+ export function diagnoseState({ rootPath, state }) {
81
82
  const issues = [];
82
83
  const manifest = readTemplateManifest();
83
84
  if (state.templateVersion !== manifest.templateVersion) {
@@ -0,0 +1 @@
1
+ export { diagnoseState, getDoctorSyncNextStepLines, getNpmVersionAdvisoryLines, handleDoctorProject } from './handler.js';
@@ -0,0 +1 @@
1
+ export { getWorkflowMutationReadiness } from './workflow-mutation-readiness.js';
@@ -1,6 +1,6 @@
1
- import { readStateForDoctor } from './state.js';
2
- import { getSyncPreviews, isActionableSyncPreview } from './sync-preview.js';
3
- import { readTemplateManifest } from './templates.js';
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';
4
4
  export function getWorkflowMutationReadiness({ rootPath, statePath }) {
5
5
  const stateResult = readStateForDoctor(statePath);
6
6
  if (!stateResult.ok) {
@@ -0,0 +1 @@
1
+ export { cloneState, hasReviewedTemplateVersion, readExistingState, readStateForDoctor, writeStateFile } from './state.js';
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { STATE_RELATIVE_PATH } from './catalog.js';
3
+ import { STATE_RELATIVE_PATH } from '../../shared/catalog.js';
4
4
  export function readStateForDoctor(statePath) {
5
5
  if (!fs.existsSync(statePath)) {
6
6
  return { ok: false, message: `${STATE_RELATIVE_PATH} is missing.` };
@@ -0,0 +1,233 @@
1
+ export const MANDATORY_SKILLS = [
2
+ {
3
+ templateRelativePath: 'skills/clean-code/SKILL.md',
4
+ targetRelativePathsByAgent: {
5
+ codex: '.agents/skills/clean-code/SKILL.md',
6
+ gemini: '.agents/skills/clean-code/SKILL.md',
7
+ claude: '.agents/skills/clean-code/SKILL.md',
8
+ windsurf: '.agents/skills/clean-code/SKILL.md',
9
+ },
10
+ },
11
+ {
12
+ templateRelativePath: 'skills/product-vision-writer/SKILL.md',
13
+ targetRelativePathsByAgent: {
14
+ codex: '.agents/skills/product-vision-writer/SKILL.md',
15
+ gemini: '.agents/skills/product-vision-writer/SKILL.md',
16
+ claude: '.agents/skills/product-vision-writer/SKILL.md',
17
+ windsurf: '.agents/skills/product-vision-writer/SKILL.md',
18
+ },
19
+ },
20
+ {
21
+ templateRelativePath: 'skills/deep-module-map-writer/SKILL.md',
22
+ targetRelativePathsByAgent: {
23
+ codex: '.agents/skills/deep-module-map-writer/SKILL.md',
24
+ gemini: '.agents/skills/deep-module-map-writer/SKILL.md',
25
+ claude: '.agents/skills/deep-module-map-writer/SKILL.md',
26
+ windsurf: '.agents/skills/deep-module-map-writer/SKILL.md',
27
+ },
28
+ },
29
+ {
30
+ templateRelativePath: 'skills/feature-brief-writer/SKILL.md',
31
+ targetRelativePathsByAgent: {
32
+ codex: '.agents/skills/feature-brief-writer/SKILL.md',
33
+ gemini: '.agents/skills/feature-brief-writer/SKILL.md',
34
+ claude: '.agents/skills/feature-brief-writer/SKILL.md',
35
+ windsurf: '.agents/skills/feature-brief-writer/SKILL.md',
36
+ },
37
+ },
38
+ {
39
+ templateRelativePath: 'skills/technical-design-writer/SKILL.md',
40
+ targetRelativePathsByAgent: {
41
+ codex: '.agents/skills/technical-design-writer/SKILL.md',
42
+ gemini: '.agents/skills/technical-design-writer/SKILL.md',
43
+ claude: '.agents/skills/technical-design-writer/SKILL.md',
44
+ windsurf: '.agents/skills/technical-design-writer/SKILL.md',
45
+ },
46
+ },
47
+ {
48
+ templateRelativePath: 'skills/scrum-master-planner/SKILL.md',
49
+ targetRelativePathsByAgent: {
50
+ codex: '.agents/skills/scrum-master-planner/SKILL.md',
51
+ gemini: '.agents/skills/scrum-master-planner/SKILL.md',
52
+ claude: '.agents/skills/scrum-master-planner/SKILL.md',
53
+ windsurf: '.agents/skills/scrum-master-planner/SKILL.md',
54
+ },
55
+ },
56
+ {
57
+ templateRelativePath: 'skills/ai-implementation-planner/SKILL.md',
58
+ targetRelativePathsByAgent: {
59
+ codex: '.agents/skills/ai-implementation-planner/SKILL.md',
60
+ gemini: '.agents/skills/ai-implementation-planner/SKILL.md',
61
+ claude: '.agents/skills/ai-implementation-planner/SKILL.md',
62
+ windsurf: '.agents/skills/ai-implementation-planner/SKILL.md',
63
+ },
64
+ },
65
+ {
66
+ templateRelativePath: 'skills/ai-implementation-plan-executor/SKILL.md',
67
+ targetRelativePathsByAgent: {
68
+ codex: '.agents/skills/ai-implementation-plan-executor/SKILL.md',
69
+ gemini: '.agents/skills/ai-implementation-plan-executor/SKILL.md',
70
+ claude: '.agents/skills/ai-implementation-plan-executor/SKILL.md',
71
+ windsurf: '.agents/skills/ai-implementation-plan-executor/SKILL.md',
72
+ },
73
+ },
74
+ ];
75
+ export const SELECTABLE_LANGUAGE_SKILLS = [
76
+ {
77
+ id: 'typescript',
78
+ name: 'TypeScript',
79
+ description: 'Install practical guidance for writing and modifying .ts and .tsx files',
80
+ routingInstruction: 'For any task that changes `.ts` or `.tsx` files, also use `typescript`.',
81
+ templateRelativePath: 'skills/typescript/SKILL.md',
82
+ targetRelativePathsByAgent: {
83
+ codex: '.agents/skills/typescript/SKILL.md',
84
+ gemini: '.agents/skills/typescript/SKILL.md',
85
+ claude: '.agents/skills/typescript/SKILL.md',
86
+ windsurf: '.agents/skills/typescript/SKILL.md',
87
+ },
88
+ },
89
+ {
90
+ id: 'golang',
91
+ name: 'Go',
92
+ description: 'Install practical guidance for writing and modifying .go files',
93
+ routingInstruction: 'For any task that changes `.go` files, also use `golang`.',
94
+ templateRelativePath: 'skills/golang/SKILL.md',
95
+ targetRelativePathsByAgent: {
96
+ codex: '.agents/skills/golang/SKILL.md',
97
+ gemini: '.agents/skills/golang/SKILL.md',
98
+ claude: '.agents/skills/golang/SKILL.md',
99
+ windsurf: '.agents/skills/golang/SKILL.md',
100
+ },
101
+ },
102
+ ];
103
+ export const SELECTABLE_FRAMEWORK_SKILLS = [
104
+ {
105
+ id: 'react',
106
+ name: 'React',
107
+ description: 'Install guidance for React components, props, state ownership, and component boundaries',
108
+ routingInstruction: 'For React component changes involving responsibility, props, state ownership, or presentational/data-owning boundaries, use `react`.',
109
+ templateRelativePath: 'skills/react/SKILL.md',
110
+ targetRelativePathsByAgent: {
111
+ codex: '.agents/skills/react/SKILL.md',
112
+ gemini: '.agents/skills/react/SKILL.md',
113
+ claude: '.agents/skills/react/SKILL.md',
114
+ windsurf: '.agents/skills/react/SKILL.md',
115
+ },
116
+ },
117
+ {
118
+ id: 'nextjs',
119
+ name: 'Next.js',
120
+ description: 'Install guidance for Next.js App Router and framework-specific files',
121
+ routingInstruction: 'For Next.js App Router or framework-specific changes—`src/app/**`, pages, layouts, route handlers, loading/error/not-found files, metadata, or Server/Client boundaries—use `nextjs`.',
122
+ templateRelativePath: 'skills/nextjs/SKILL.md',
123
+ targetRelativePathsByAgent: {
124
+ codex: '.agents/skills/nextjs/SKILL.md',
125
+ gemini: '.agents/skills/nextjs/SKILL.md',
126
+ claude: '.agents/skills/nextjs/SKILL.md',
127
+ windsurf: '.agents/skills/nextjs/SKILL.md',
128
+ },
129
+ },
130
+ ];
131
+ export const SELECTABLE_ARCHITECTURE_SKILLS = [
132
+ {
133
+ id: 'ddd-hexagonal',
134
+ name: 'DDD + Hexagonal Architecture',
135
+ description: 'Install back-end architecture guidance for DDD, ports/adapters, and inward dependencies',
136
+ routingInstruction: 'For backend features, refactors, bug fixes, persistence, external integrations, application/service boundaries, domain modeling, or architectural tradeoffs, use `ddd-hexagonal`.',
137
+ templateRelativePath: 'skills/architecture/ddd-hexagonal/SKILL.md',
138
+ targetRelativePathsByAgent: {
139
+ codex: '.agents/skills/ddd-hexagonal/SKILL.md',
140
+ gemini: '.agents/skills/ddd-hexagonal/SKILL.md',
141
+ claude: '.agents/skills/ddd-hexagonal/SKILL.md',
142
+ windsurf: '.agents/skills/ddd-hexagonal/SKILL.md',
143
+ },
144
+ },
145
+ {
146
+ id: 'command-pattern',
147
+ name: 'Command Pattern',
148
+ description: 'Install architecture guidance for structuring executable operations as commands and handlers',
149
+ routingInstruction: 'For work that structures actions, workflows, command handlers, operation dispatch, request processing, or executable tasks, use `command-pattern`.',
150
+ templateRelativePath: 'skills/architecture/command-pattern/SKILL.md',
151
+ targetRelativePathsByAgent: {
152
+ codex: '.agents/skills/command-pattern/SKILL.md',
153
+ gemini: '.agents/skills/command-pattern/SKILL.md',
154
+ claude: '.agents/skills/command-pattern/SKILL.md',
155
+ windsurf: '.agents/skills/command-pattern/SKILL.md',
156
+ },
157
+ },
158
+ ];
159
+ export const SELECTABLE_WORKFLOW_SKILLS = [
160
+ {
161
+ id: 'ai-prompt-engineer-master',
162
+ name: 'AI Prompt Engineer Master',
163
+ description: 'Install guidance for creating, rewriting, optimizing, compressing, and evaluating AI prompts',
164
+ routingInstruction: 'For prompt creation, rewriting, optimization, compression, evaluation, or reusable templates for AI models, agents, tools, coding assistants, or product workflows, use `ai-prompt-engineer-master`.',
165
+ templateRelativePath: 'skills/ai-prompt-engineer-master/SKILL.md',
166
+ targetRelativePathsByAgent: {
167
+ codex: '.agents/skills/ai-prompt-engineer-master/SKILL.md',
168
+ gemini: '.agents/skills/ai-prompt-engineer-master/SKILL.md',
169
+ claude: '.agents/skills/ai-prompt-engineer-master/SKILL.md',
170
+ windsurf: '.agents/skills/ai-prompt-engineer-master/SKILL.md',
171
+ },
172
+ },
173
+ {
174
+ id: 'ux-expert',
175
+ name: 'UX Expert',
176
+ description: 'Install senior UX/UI guidance for UI-changing features, responsive layouts, flows, states, accessibility, and binding mockups',
177
+ routingInstruction: 'For UX/UI design after product definition for UI-changing features, use `ux-expert`; downstream design, planning, and implementation must treat `docs/features/<feature-slug>/ux.md` mockups as binding UI goals, not redesign targets.',
178
+ templateRelativePath: 'skills/ux-expert/SKILL.md',
179
+ targetRelativePathsByAgent: {
180
+ codex: '.agents/skills/ux-expert/SKILL.md',
181
+ gemini: '.agents/skills/ux-expert/SKILL.md',
182
+ claude: '.agents/skills/ux-expert/SKILL.md',
183
+ windsurf: '.agents/skills/ux-expert/SKILL.md',
184
+ },
185
+ },
186
+ ];
187
+ export const SUPPORTED_AGENTS = [
188
+ {
189
+ id: 'codex',
190
+ name: 'Codex',
191
+ description: 'Create .codex/config.toml pointing Codex to AGENTS.md',
192
+ targetRelativePath: '.codex/config.toml',
193
+ templateRelativePath: '.codex/config.toml',
194
+ },
195
+ {
196
+ id: 'gemini',
197
+ name: 'Gemini',
198
+ description: 'Create GEMINI.md that delegates to AGENTS.md',
199
+ targetRelativePath: 'GEMINI.md',
200
+ templateRelativePath: 'GEMINI.md',
201
+ },
202
+ {
203
+ id: 'claude',
204
+ name: 'Claude',
205
+ description: 'Create CLAUDE.md that delegates to AGENTS.md',
206
+ targetRelativePath: 'CLAUDE.md',
207
+ templateRelativePath: 'CLAUDE.md',
208
+ },
209
+ {
210
+ id: 'windsurf',
211
+ name: 'Windsurf',
212
+ description: 'Use root AGENTS.md and shared .agents/skills/ discovery',
213
+ },
214
+ ];
215
+ export function resolveSelectableSkillById(skillId) {
216
+ const languageSkill = SELECTABLE_LANGUAGE_SKILLS.find((skill) => skill.id === skillId);
217
+ if (languageSkill) {
218
+ return { ok: true, resolved: { kind: 'language', skill: languageSkill } };
219
+ }
220
+ const frameworkSkill = SELECTABLE_FRAMEWORK_SKILLS.find((skill) => skill.id === skillId);
221
+ if (frameworkSkill) {
222
+ return { ok: true, resolved: { kind: 'framework', skill: frameworkSkill } };
223
+ }
224
+ const architectureSkill = SELECTABLE_ARCHITECTURE_SKILLS.find((skill) => skill.id === skillId);
225
+ if (architectureSkill) {
226
+ return { ok: true, resolved: { kind: 'architecture', skill: architectureSkill } };
227
+ }
228
+ const workflowSkill = SELECTABLE_WORKFLOW_SKILLS.find((skill) => skill.id === skillId);
229
+ if (workflowSkill) {
230
+ return { ok: true, resolved: { kind: 'workflow', skill: workflowSkill } };
231
+ }
232
+ return { ok: false, message: `Unknown skill \`${skillId}\`. Run \`sibu skills list\` to see available skills.` };
233
+ }
@@ -0,0 +1,2 @@
1
+ export { MANDATORY_SKILLS, SELECTABLE_ARCHITECTURE_SKILLS, SELECTABLE_FRAMEWORK_SKILLS, SELECTABLE_LANGUAGE_SKILLS, SELECTABLE_WORKFLOW_SKILLS, SUPPORTED_AGENTS, resolveSelectableSkillById, } from './catalog.js';
2
+ export { getSelectedAgentsFromState, getSelectedArchitectureSkillFromState, getSelectedFrameworkSkillsFromState, getSelectedLanguageSkillsFromState, getSelectedSkillTargetsForAgents, getSelectedWorkflowSkillsFromState, getWorkflowTargets, renderMissingWorkflowFiles, writeSibuState, } from './workflow-targets.js';