fraim 2.0.287 → 2.0.289

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.
@@ -97,6 +97,27 @@ async function runAgentCliHealthCheck(cli) {
97
97
  : managedPath === ambientPath
98
98
  ? ambientVersion
99
99
  : probeVersion(managedPath);
100
+ // Issue #1412: a resolved file that fails to execute at all (e.g. an
101
+ // interrupted update left a non-executable fallback launcher) is a harder
102
+ // failure than drift — `getSystemCommandPath()` only proves the file
103
+ // exists, not that it can run. Without this check, a single broken install
104
+ // with nothing else on PATH to disagree with (ambientPath === managedPath,
105
+ // both versions null) falls straight through the mismatch check below and
106
+ // reads as "consistent". Check this before computing npm-global/drift
107
+ // details that don't matter once the CLI can't run at all.
108
+ const brokenPath = ambientPath && !ambientVersion
109
+ ? ambientPath
110
+ : managedPath && !managedVersion
111
+ ? managedPath
112
+ : null;
113
+ if (brokenPath) {
114
+ return {
115
+ status: 'error',
116
+ message: `${cli.label} is installed at ${brokenPath} but failed to run (\`${cli.command} --version\` produced no output). An interrupted or partial update may have left a non-functional launcher.`,
117
+ suggestion: `Reinstall ${cli.label}, then run "${cli.command} --version" again to confirm it's fixed.`,
118
+ details: { ambientPath, ambientVersion, managedPath, managedVersion },
119
+ };
120
+ }
100
121
  const npmGlobalBinDirs = (0, managed_agent_paths_1.resolveNpmGlobalBinDirs)();
101
122
  const npmGlobalPath = npmGlobalBinDirs.length > 0
102
123
  ? (0, command_resolution_1.getSystemCommandPath)(cli.command, npmGlobalBinDirs.join(path_1.default.delimiter))
@@ -64,13 +64,17 @@ function buildSearchQuery(roleKey) {
64
64
  const profile = getHumanManagerProfile(roleKey);
65
65
  return `${profile.keywords.join(' OR ')} AND ${AI_MANAGER_QUERY_TERMS}`;
66
66
  }
67
+ function indefiniteArticle(phrase) {
68
+ return /^[aeiou]/i.test(phrase.trim()) ? 'an' : 'a';
69
+ }
67
70
  function buildJobDescription(roleKey) {
68
71
  const profile = getHumanManagerProfile(roleKey);
69
72
  const role = persona_hiring_1.PERSONA_HIRE_CATALOG[roleKey]?.role ?? 'AI Employee';
73
+ const article = indefiniteArticle(role);
70
74
  return [
71
- `${profile.humanTitle} — manager for an ${role}`,
75
+ `${profile.humanTitle} — manager for ${article} ${role}`,
72
76
  '',
73
- `You will manage an ${role} (an autonomous AI agent) and the humans around it, owning the outcomes it ships.`,
77
+ `You will manage ${article} ${role} (an autonomous AI agent) and the humans around it, owning the outcomes it ships.`,
74
78
  '',
75
79
  "What you'll do:",
76
80
  `- Write crisp specifications and acceptance criteria the ${role} can execute against.`,
@@ -278,7 +278,7 @@ exports.PERSONA_CAPABILITY_BUNDLES = {
278
278
  ],
279
279
  protectedAliases: ['ai-engineering', 'agent-engineering', 'ai-agents'],
280
280
  defaultHireMode: 'job',
281
- lockCopy: 'Hire AIda to unlock AI agent design, MCP enablement, eval authoring, and agent evaluation work for this request.'
281
+ lockCopy: 'Hire AIDa to unlock AI agent design, MCP enablement, eval authoring, and agent evaluation work for this request.'
282
282
  }
283
283
  };
284
284
  const PROTECTED_JOB_TO_PERSONA = new Map();
@@ -20,8 +20,8 @@ exports.getPersonaHireAmountCents = getPersonaHireAmountCents;
20
20
  */
21
21
  exports.PERSONA_HIRE_CATALOG = {
22
22
  aida: {
23
- displayName: 'AIda',
24
- role: 'AI Engineer',
23
+ displayName: 'AIDa',
24
+ role: 'AI Developer',
25
25
  emoji: '\u{1F9E0}',
26
26
  gradient: 'linear-gradient(135deg, #4f46e5 0%, #06b6d4 50%, #10b981 100%)',
27
27
  blurb: 'Designs production AI agents, connects them to tools and data, and proves their behavior with evals before deployment.',
@@ -30,7 +30,7 @@ exports.PERSONA_HIRE_CATALOG = {
30
30
  },
31
31
  swen: {
32
32
  displayName: 'SWEn',
33
- role: 'AI Software Engineer',
33
+ role: 'Software Engineer',
34
34
  emoji: '💻',
35
35
  gradient: 'linear-gradient(135deg, #2563eb 0%, #06b6d4 100%)',
36
36
  blurb: 'Implements features, refactors code, and drives PR iteration to merge, reviewing design and code as a senior would.',
@@ -39,7 +39,7 @@ exports.PERSONA_HIRE_CATALOG = {
39
39
  },
40
40
  qasm: {
41
41
  displayName: 'QAsm',
42
- role: 'AI QA Engineer',
42
+ role: 'QA Engineer',
43
43
  emoji: '🛡️',
44
44
  gradient: 'linear-gradient(135deg, #10b981 0%, #14b8a6 100%)',
45
45
  blurb: 'Runs tests, assesses code and test quality, polishes UI, and drives bug bashes with evidence.',
@@ -48,7 +48,7 @@ exports.PERSONA_HIRE_CATALOG = {
48
48
  },
49
49
  sekhar: {
50
50
  displayName: 'SEChar',
51
- role: 'AI Security Engineer',
51
+ role: 'Security Engineer',
52
52
  emoji: '🔒',
53
53
  gradient: 'linear-gradient(135deg, #ef4444 0%, #f43f5e 100%)',
54
54
  blurb: 'Sets up AI-native security baselines, runs the findings command center, reviews changes for risk, and drives remediation to closure.',
@@ -57,7 +57,7 @@ exports.PERSONA_HIRE_CATALOG = {
57
57
  },
58
58
  sreya: {
59
59
  displayName: 'SREya',
60
- role: 'AI Site Reliability Engineer',
60
+ role: 'Site Reliability Engineer',
61
61
  emoji: '☁️',
62
62
  gradient: 'linear-gradient(135deg, #2563eb 0%, #10b981 100%)',
63
63
  blurb: 'Manages deployments, monitors uptime, optimizes cloud cost, and keeps infrastructure resilient and observable.',
@@ -66,7 +66,7 @@ exports.PERSONA_HIRE_CATALOG = {
66
66
  },
67
67
  sade: {
68
68
  displayName: 'SADE',
69
- role: 'AI Salesforce Developer',
69
+ role: 'Salesforce Developer',
70
70
  emoji: '☁️',
71
71
  gradient: 'linear-gradient(135deg, #0284c7 0%, #0369a1 100%)',
72
72
  blurb: 'Deploys Salesforce configuration from ServiceNow tickets, builds reports and dashboards, creates Flows from business requirements, audits org health, and manages users and data at scale.',
@@ -75,7 +75,7 @@ exports.PERSONA_HIRE_CATALOG = {
75
75
  },
76
76
  pam: {
77
77
  displayName: 'PaM',
78
- role: 'AI Product Manager',
78
+ role: 'Product Manager',
79
79
  emoji: '📋',
80
80
  gradient: 'linear-gradient(135deg, #8b5cf6 0%, #d946ef 100%)',
81
81
  blurb: 'Owns specs, PRDs, technical design, issue prep, and the path from idea to shippable artifact.',
@@ -84,7 +84,7 @@ exports.PERSONA_HIRE_CATALOG = {
84
84
  },
85
85
  huxley: {
86
86
  displayName: 'hUXley',
87
- role: 'AI UX / Brand Designer',
87
+ role: 'UX / Brand Designer',
88
88
  emoji: '🎨',
89
89
  gradient: 'linear-gradient(135deg, #ec4899 0%, #f472b6 100%)',
90
90
  blurb: 'Builds design systems, prototypes polished user-facing surfaces, and carries brand decisions into shipped product experiences.',
@@ -93,7 +93,7 @@ exports.PERSONA_HIRE_CATALOG = {
93
93
  },
94
94
  gautam: {
95
95
  displayName: 'GauTaM',
96
- role: 'AI GTM & Marketing Manager',
96
+ role: 'GTM & Marketing Manager',
97
97
  emoji: '📣',
98
98
  gradient: 'linear-gradient(135deg, #f97316 0%, #f59e0b 100%)',
99
99
  blurb: 'Defines marketing strategy, ships content, runs launches, and owns the brand voice in market.',
@@ -102,7 +102,7 @@ exports.PERSONA_HIRE_CATALOG = {
102
102
  },
103
103
  sam: {
104
104
  displayName: 'SAM',
105
- role: 'AI Sales Account Manager',
105
+ role: 'Sales Account Manager',
106
106
  emoji: '📈',
107
107
  gradient: 'linear-gradient(135deg, #059669 0%, #0d9488 100%)',
108
108
  blurb: 'Surfaces stalled deals, computes pipeline health, and drafts account-specific re-engagement proposals for your top at-risk opportunities.',
@@ -111,7 +111,7 @@ exports.PERSONA_HIRE_CATALOG = {
111
111
  },
112
112
  casey: {
113
113
  displayName: 'CaSey',
114
- role: 'AI Customer Success + Support',
114
+ role: 'Customer Success + Support',
115
115
  emoji: '💬',
116
116
  gradient: 'linear-gradient(135deg, #db2777 0%, #9333ea 100%)',
117
117
  blurb: 'Scores account churn risk and expansion potential, generates prioritized action plans for CSMs, triages support cases, and routes L1 cases through automated resolution.',
@@ -120,7 +120,7 @@ exports.PERSONA_HIRE_CATALOG = {
120
120
  },
121
121
  mona: {
122
122
  displayName: 'MONa',
123
- role: 'AI Finance Manager',
123
+ role: 'Finance Manager',
124
124
  emoji: '💰',
125
125
  gradient: 'linear-gradient(135deg, #10b981 0%, #f59e0b 100%)',
126
126
  blurb: 'Models revenue, tracks unit economics, builds financial forecasts, and owns the metrics that drive growth decisions.',
@@ -129,7 +129,7 @@ exports.PERSONA_HIRE_CATALOG = {
129
129
  },
130
130
  hari: {
131
131
  displayName: 'HaRi',
132
- role: 'AI HR Manager',
132
+ role: 'HR Manager',
133
133
  emoji: '👥',
134
134
  gradient: 'linear-gradient(135deg, #0d9488 0%, #059669 100%)',
135
135
  blurb: 'Manages onboarding, performance reviews, benefits analysis, payroll coordination, and HR business-partner advisory.',
@@ -138,7 +138,7 @@ exports.PERSONA_HIRE_CATALOG = {
138
138
  },
139
139
  ricardo: {
140
140
  displayName: 'RECardo',
141
- role: 'AI Recruiter',
141
+ role: 'Recruiter',
142
142
  emoji: '🤝',
143
143
  gradient: 'linear-gradient(135deg, #6366f1 0%, #ec4899 100%)',
144
144
  blurb: 'Sources candidates, writes job descriptions, screens pipelines, and manages the hiring loop end-to-end.',
@@ -147,7 +147,7 @@ exports.PERSONA_HIRE_CATALOG = {
147
147
  },
148
148
  cela: {
149
149
  displayName: 'CELiA',
150
- role: 'AI Legal Counsel',
150
+ role: 'Legal Counsel',
151
151
  emoji: '⚖️',
152
152
  gradient: 'linear-gradient(135deg, #475569 0%, #6366f1 100%)',
153
153
  blurb: 'Drafts and reviews contracts, NDAs, patents, trademarks, and the SaaS legal stack.',
@@ -156,7 +156,7 @@ exports.PERSONA_HIRE_CATALOG = {
156
156
  },
157
157
  procella: {
158
158
  displayName: 'PROCella',
159
- role: 'AI Procurement Manager',
159
+ role: 'Procurement Manager',
160
160
  emoji: '📦',
161
161
  gradient: 'linear-gradient(135deg, #0f766e 0%, #7c3aed 100%)',
162
162
  blurb: 'Frames procurement strategy, sources suppliers, runs RFx packages, evaluates responses, and keeps purchases acceptance-gated.',
@@ -165,7 +165,7 @@ exports.PERSONA_HIRE_CATALOG = {
165
165
  },
166
166
  banke: {
167
167
  displayName: 'BANKe',
168
- role: 'AI Banking KYC Employee',
168
+ role: 'Banking KYC Employee',
169
169
  emoji: '\u{1F3E6}',
170
170
  gradient: 'linear-gradient(135deg, #0f766e 0%, #2563eb 100%)',
171
171
  blurb: 'Runs banking KYC cases with consent-aware evidence capture, decision receipts, and stable audit handoff artifacts.',
@@ -174,7 +174,7 @@ exports.PERSONA_HIRE_CATALOG = {
174
174
  },
175
175
  auditya: {
176
176
  displayName: 'AUDITya',
177
- role: 'AI Banking Auditor',
177
+ role: 'Banking Auditor',
178
178
  emoji: '\u{1F50E}',
179
179
  gradient: 'linear-gradient(135deg, #7c3aed 0%, #0f172a 100%)',
180
180
  blurb: 'Audits AI banking work by tracing decisions back to evidence, receipts, exceptions, and reusable audit reports.',
@@ -183,7 +183,7 @@ exports.PERSONA_HIRE_CATALOG = {
183
183
  },
184
184
  deidre: {
185
185
  displayName: 'DEIdre',
186
- role: 'AI Inclusion Leader',
186
+ role: 'Inclusion Leader',
187
187
  emoji: '🌍',
188
188
  gradient: 'linear-gradient(135deg, #9333ea 0%, #d946ef 100%)',
189
189
  blurb: 'Audits equity gaps, designs bias-aware AI governance, builds ERG toolkits, and creates inclusion-fluency programs.',
@@ -192,7 +192,7 @@ exports.PERSONA_HIRE_CATALOG = {
192
192
  },
193
193
  careena: {
194
194
  displayName: 'CAREEna',
195
- role: 'AI Career Coach',
195
+ role: 'Career Coach',
196
196
  emoji: '🎓',
197
197
  gradient: 'linear-gradient(135deg, #0ea5e9 0%, #6366f1 100%)',
198
198
  blurb: 'Runs the candidate-side search loop: role sourcing, application execution, networking, interview prep, and close-stage offer strategy.',
@@ -201,7 +201,7 @@ exports.PERSONA_HIRE_CATALOG = {
201
201
  },
202
202
  ashley: {
203
203
  displayName: 'AshLey',
204
- role: 'AI Executive Assistant',
204
+ role: 'Executive Assistant',
205
205
  emoji: '📅',
206
206
  gradient: 'linear-gradient(135deg, #f59e0b 0%, #fbbf24 100%)',
207
207
  blurb: 'Owns executive coordination, weekly operating reviews, and portfolio reporting across the workforce.',
@@ -210,7 +210,7 @@ exports.PERSONA_HIRE_CATALOG = {
210
210
  },
211
211
  mandy: {
212
212
  displayName: 'MANdy',
213
- role: 'AI Manager',
213
+ role: 'Manager',
214
214
  emoji: '🎯',
215
215
  gradient: 'linear-gradient(135deg, #7c3aed 0%, #4338ca 100%)',
216
216
  blurb: 'Plans the job sequence, runs sub-agents in parallel, coaches them through verification loops, and hands back a synthesized DRAFT for your approval.',
@@ -219,7 +219,7 @@ exports.PERSONA_HIRE_CATALOG = {
219
219
  },
220
220
  beza: {
221
221
  displayName: 'BeZa',
222
- role: 'AI Business Strategist',
222
+ role: 'Business Strategist',
223
223
  emoji: '🧭',
224
224
  gradient: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
225
225
  blurb: 'Turns ideas into structured business plans, validates founder-market fit, and pressure-tests strategy.',
@@ -228,7 +228,7 @@ exports.PERSONA_HIRE_CATALOG = {
228
228
  },
229
229
  maestro: {
230
230
  displayName: 'MAESTRO',
231
- role: 'Full-Brained AI Employee',
231
+ role: 'Full-Brained Employee',
232
232
  emoji: '★',
233
233
  gradient: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #d946ef 100%)',
234
234
  blurb: 'One AI employee who can take a job from any function and ship it back with evidence. You set the direction. You sign off on what ships. Maestro does the work.',
@@ -260,7 +260,7 @@ exports.PERSONA_AVATAR_CATALOG = {
260
260
  procella: { seed: 'PROCELLA-procurement', bg: 'ccfbf1', style: 'notionists' },
261
261
  banke: { seed: 'BANKe-banking-kyc', bg: 'ccfbf1', style: 'notionists' },
262
262
  auditya: { seed: 'AUDITya-banking-audit', bg: 'e9d5ff', style: 'notionists' },
263
- aida: { seed: 'AIda-ai-engineer', bg: 'c7d2fe', style: 'notionists' },
263
+ aida: { seed: 'AIDa-ai-developer', bg: 'c7d2fe', style: 'notionists' },
264
264
  };
265
265
  function buildPersonaAvatarUrl(personaKey) {
266
266
  const avatar = exports.PERSONA_AVATAR_CATALOG[personaKey];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fraim",
3
- "version": "2.0.287",
3
+ "version": "2.0.289",
4
4
  "description": "FRAIM core CLI and MCP package.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -717,7 +717,16 @@
717
717
  }
718
718
  };
719
719
  submit.addEventListener('click', onSubmit);
720
- input.addEventListener('keydown', (e) => { if (e.key === 'Enter') onSubmit(); });
720
+ input.addEventListener('keydown', (e) => {
721
+ if (e.key === 'Enter') {
722
+ onSubmit();
723
+ return;
724
+ }
725
+ if (e.key === 'Tab' && !e.shiftKey) {
726
+ e.preventDefault();
727
+ submit.focus();
728
+ }
729
+ });
721
730
  card.appendChild(submit);
722
731
 
723
732
  CHECKLIST_EL.appendChild(card);