fraim 2.0.274 → 2.0.276

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.
@@ -42,7 +42,8 @@ function describeOnboardingInvocationSurfaces(installedIDEs) {
42
42
  /**
43
43
  * Install Claude FRAIM discovery artifacts at the user level.
44
44
  * Writes a skill to ~/.claude/skills/fraim/SKILL.md and a compatibility command
45
- * to ~/.claude/commands/fraim.md. Existing user files are preserved.
45
+ * to ~/.claude/commands/fraim.md. Stale content from prior FRAIM versions is
46
+ * refreshed; already-current content is left untouched.
46
47
  */
47
48
  async function installSlashCommands(homeDir) {
48
49
  const home = homeDir || os_1.default.homedir();
@@ -50,51 +51,59 @@ async function installSlashCommands(homeDir) {
50
51
  if (!fs_1.default.existsSync(claudeDir)) {
51
52
  return;
52
53
  }
53
- installFileIfMissing(path_1.default.join(claudeDir, 'skills', 'fraim', 'SKILL.md'), (0, ide_invocation_surfaces_1.buildClaudeSkillContent)(), 'Claude FRAIM skill (~/.claude/skills/fraim/SKILL.md)');
54
- installFileIfMissing(path_1.default.join(claudeDir, 'commands', 'fraim.md'), (0, ide_invocation_surfaces_1.buildClaudeCommandShimContent)(), 'Claude compatibility command (~/.claude/commands/fraim.md)');
54
+ installOrUpdateManagedFile(path_1.default.join(claudeDir, 'skills', 'fraim', 'SKILL.md'), (0, ide_invocation_surfaces_1.buildClaudeSkillContent)(), 'Claude FRAIM skill (~/.claude/skills/fraim/SKILL.md)');
55
+ installOrUpdateManagedFile(path_1.default.join(claudeDir, 'commands', 'fraim.md'), (0, ide_invocation_surfaces_1.buildClaudeCommandShimContent)(), 'Claude compatibility command (~/.claude/commands/fraim.md)');
55
56
  }
56
57
  /**
57
58
  * Install FRAIM invocation artifacts for non-Claude IDEs.
58
59
  * Supports: Cursor, Codex, Grok, Gemini CLI, Copilot CLI, Windsurf, Kiro
59
- * Does not overwrite existing files.
60
+ * Stale content from prior FRAIM versions is refreshed; already-current
61
+ * content is left untouched.
60
62
  */
61
63
  async function installGlobalRules(homeDir) {
62
64
  const home = homeDir || os_1.default.homedir();
63
65
  const cursorDir = path_1.default.join(home, '.cursor');
64
66
  if (fs_1.default.existsSync(cursorDir)) {
65
- installFileIfMissing(path_1.default.join(cursorDir, 'rules', 'fraim.mdc'), (0, ide_invocation_surfaces_1.buildCursorMentionRuleContent)(), 'Cursor FRAIM rule (~/.cursor/rules/fraim.mdc)');
67
+ installOrUpdateManagedFile(path_1.default.join(cursorDir, 'rules', 'fraim.mdc'), (0, ide_invocation_surfaces_1.buildCursorMentionRuleContent)(), 'Cursor FRAIM rule (~/.cursor/rules/fraim.mdc)');
66
68
  }
67
69
  const codexDir = path_1.default.join(home, '.codex');
68
70
  if (fs_1.default.existsSync(codexDir)) {
69
- installFileIfMissing(path_1.default.join(codexDir, 'skills', 'fraim', 'SKILL.md'), (0, ide_invocation_surfaces_1.buildCodexSkillContent)(), 'Codex FRAIM skill (~/.codex/skills/fraim/SKILL.md)');
71
+ installOrUpdateManagedFile(path_1.default.join(codexDir, 'skills', 'fraim', 'SKILL.md'), (0, ide_invocation_surfaces_1.buildCodexSkillContent)(), 'Codex FRAIM skill (~/.codex/skills/fraim/SKILL.md)');
70
72
  }
71
73
  const grokDir = path_1.default.join(home, '.grok');
72
74
  if (fs_1.default.existsSync(grokDir)) {
73
- installFileIfMissing(path_1.default.join(grokDir, 'skills', 'fraim', 'SKILL.md'), (0, ide_invocation_surfaces_1.buildGrokSkillContent)(), 'Grok FRAIM skill (~/.grok/skills/fraim/SKILL.md)');
75
+ installOrUpdateManagedFile(path_1.default.join(grokDir, 'skills', 'fraim', 'SKILL.md'), (0, ide_invocation_surfaces_1.buildGrokSkillContent)(), 'Grok FRAIM skill (~/.grok/skills/fraim/SKILL.md)');
74
76
  }
75
77
  const geminiDir = path_1.default.join(home, '.gemini');
76
78
  if (fs_1.default.existsSync(geminiDir)) {
77
- installFileIfMissing(path_1.default.join(geminiDir, 'commands', 'fraim.toml'), (0, ide_invocation_surfaces_1.buildGeminiCommandContent)(), 'Gemini CLI FRAIM command (~/.gemini/commands/fraim.toml)');
79
+ installOrUpdateManagedFile(path_1.default.join(geminiDir, 'commands', 'fraim.toml'), (0, ide_invocation_surfaces_1.buildGeminiCommandContent)(), 'Gemini CLI FRAIM command (~/.gemini/commands/fraim.toml)');
78
80
  }
79
81
  const antigravityDir = path_1.default.join(home, '.gemini', 'antigravity');
80
82
  if (fs_1.default.existsSync(antigravityDir)) {
81
- installFileIfMissing(path_1.default.join(antigravityDir, 'commands', 'fraim.md'), (0, ide_invocation_surfaces_1.buildAntigravityCommandContent)(), 'Antigravity FRAIM command (~/.gemini/antigravity/commands/fraim.md)');
83
+ installOrUpdateManagedFile(path_1.default.join(antigravityDir, 'commands', 'fraim.md'), (0, ide_invocation_surfaces_1.buildAntigravityCommandContent)(), 'Antigravity FRAIM command (~/.gemini/antigravity/commands/fraim.md)');
82
84
  }
83
85
  const windsurfDir = path_1.default.join(home, '.codeium', 'windsurf');
84
86
  if (fs_1.default.existsSync(windsurfDir)) {
85
- installFileIfMissing(path_1.default.join(windsurfDir, 'commands', 'fraim.md'), (0, ide_invocation_surfaces_1.buildWindsurfCommandContent)(), 'Windsurf FRAIM command (~/.codeium/windsurf/commands/fraim.md)');
87
+ installOrUpdateManagedFile(path_1.default.join(windsurfDir, 'commands', 'fraim.md'), (0, ide_invocation_surfaces_1.buildWindsurfCommandContent)(), 'Windsurf FRAIM command (~/.codeium/windsurf/commands/fraim.md)');
86
88
  }
87
89
  const kiroDir = path_1.default.join(home, '.kiro');
88
90
  if (fs_1.default.existsSync(kiroDir)) {
89
- installFileIfMissing(path_1.default.join(kiroDir, 'commands', 'fraim.md'), (0, ide_invocation_surfaces_1.buildKiroCommandContent)(), 'Kiro FRAIM command (~/.kiro/commands/fraim.md)');
91
+ installOrUpdateManagedFile(path_1.default.join(kiroDir, 'commands', 'fraim.md'), (0, ide_invocation_surfaces_1.buildKiroCommandContent)(), 'Kiro FRAIM command (~/.kiro/commands/fraim.md)');
90
92
  }
91
93
  }
92
- function installFileIfMissing(filePath, content, displayName) {
93
- if (fs_1.default.existsSync(filePath)) {
94
- console.log(chalk_1.default.gray(` ${displayName.split('(')[0].trim()} already exists skipping`));
94
+ // These paths (~/.claude/skills/fraim/, ~/.codex/skills/fraim/, etc.) are
95
+ // FRAIM-exclusive — nothing else writes to them — so the file is always
96
+ // brought in line with the current generator output, the same contract
97
+ // `ensureAgentAdapterFiles()` already uses for the equivalent project-level
98
+ // files in agent-adapters.ts. Skipping on existence (issue #1242) permanently
99
+ // locked in stale content from older FRAIM releases with no way to self-heal.
100
+ function installOrUpdateManagedFile(filePath, content, displayName) {
101
+ const existing = fs_1.default.existsSync(filePath) ? fs_1.default.readFileSync(filePath, 'utf8') : null;
102
+ if (existing === content) {
103
+ console.log(chalk_1.default.gray(` ${displayName.split('(')[0].trim()} already up to date — skipping`));
95
104
  return;
96
105
  }
97
106
  fs_1.default.mkdirSync(path_1.default.dirname(filePath), { recursive: true });
98
107
  fs_1.default.writeFileSync(filePath, content, 'utf8');
99
- console.log(chalk_1.default.green(` ✅ Installed ${displayName}`));
108
+ console.log(chalk_1.default.green(` ✅ ${existing === null ? 'Installed' : 'Updated'} ${displayName}`));
100
109
  }
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
@@ -119,5 +152,12 @@ async function syncUserLevelArtifacts(userFraimDir) {
119
152
  console.log(chalk_1.default.gray(` Target: ${baseDir}`));
120
153
  ensureUserLevelDirectories(baseDir);
121
154
  ensureUserLevelDependencies(baseDir);
155
+ // Issue #1201 (R4.2): repair global per-IDE FRAIM discovery artifacts
156
+ // (e.g. ~/.codex/skills/fraim/SKILL.md) on every `npx fraim sync --global`
157
+ // run, not only on `fraim add-ide` and first-run onboarding — closes the
158
+ // gap where a stale file written by an older generator was never repaired.
159
+ const { installGlobalRules, installSlashCommands } = await Promise.resolve().then(() => __importStar(require('./ide-global-integration')));
160
+ await installSlashCommands();
161
+ await installGlobalRules();
122
162
  console.log(chalk_1.default.green('✅ User-level FRAIM directory ready'));
123
163
  }
@@ -219,7 +219,9 @@ exports.PERSONA_CAPABILITY_BUNDLES = {
219
219
  personaKey: 'sreya',
220
220
  bundleId: 'persona-sreya-core',
221
221
  catalogMetadata: buildCatalogMetadata('sreya', ['slo-design-and-implementation', 'incident-response', 'reliability-review']),
222
- protectedJobs: ['slo-design-and-implementation', 'incident-response', 'reliability-review', 'production-readiness-review'],
222
+ // run-on-remote-hub and setup-remote-hub are owned by SReya, the infra
223
+ // persona, rather than the display-only FRAIMworker default.
224
+ protectedJobs: ['slo-design-and-implementation', 'incident-response', 'reliability-review', 'production-readiness-review', 'run-on-remote-hub', 'setup-remote-hub'],
223
225
  protectedAliases: ['sre', 'reliability', 'incident-response', 'on-call'],
224
226
  defaultHireMode: 'job',
225
227
  lockCopy: 'Hire SREya to unlock SLO governance, incident response, and production reliability work for this request.'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fraim",
3
- "version": "2.0.274",
3
+ "version": "2.0.276",
4
4
  "description": "FRAIM core CLI and MCP package.",
5
5
  "main": "index.js",
6
6
  "bin": {