@bragduck/mcp 1.6.0 → 1.7.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 (46) hide show
  1. package/dist/index.js +1856 -117
  2. package/dist/index.js.map +1 -1
  3. package/package.json +6 -4
  4. package/dist/api-client.d.ts +0 -29
  5. package/dist/api-client.js +0 -146
  6. package/dist/api-client.js.map +0 -1
  7. package/dist/auth.d.ts +0 -8
  8. package/dist/auth.js +0 -202
  9. package/dist/auth.js.map +0 -1
  10. package/dist/credentials.d.ts +0 -31
  11. package/dist/credentials.js +0 -150
  12. package/dist/credentials.js.map +0 -1
  13. package/dist/index.d.ts +0 -2
  14. package/dist/org-preference.d.ts +0 -7
  15. package/dist/org-preference.js +0 -22
  16. package/dist/org-preference.js.map +0 -1
  17. package/dist/tools/link-brag-to-key-result.d.ts +0 -30
  18. package/dist/tools/link-brag-to-key-result.js +0 -81
  19. package/dist/tools/link-brag-to-key-result.js.map +0 -1
  20. package/dist/tools/list-brags.d.ts +0 -53
  21. package/dist/tools/list-brags.js +0 -110
  22. package/dist/tools/list-brags.js.map +0 -1
  23. package/dist/tools/list-objectives.d.ts +0 -15
  24. package/dist/tools/list-objectives.js +0 -66
  25. package/dist/tools/list-objectives.js.map +0 -1
  26. package/dist/tools/list-organisations.d.ts +0 -15
  27. package/dist/tools/list-organisations.js +0 -73
  28. package/dist/tools/list-organisations.js.map +0 -1
  29. package/dist/tools/log-brag.d.ts +0 -88
  30. package/dist/tools/log-brag.js +0 -175
  31. package/dist/tools/log-brag.js.map +0 -1
  32. package/dist/tools/log-story.d.ts +0 -76
  33. package/dist/tools/log-story.js +0 -116
  34. package/dist/tools/log-story.js.map +0 -1
  35. package/dist/tools/login.d.ts +0 -24
  36. package/dist/tools/login.js +0 -46
  37. package/dist/tools/login.js.map +0 -1
  38. package/dist/tools/preview-brag.d.ts +0 -71
  39. package/dist/tools/preview-brag.js +0 -103
  40. package/dist/tools/preview-brag.js.map +0 -1
  41. package/dist/tools/quick-brag.d.ts +0 -38
  42. package/dist/tools/quick-brag.js +0 -143
  43. package/dist/tools/quick-brag.js.map +0 -1
  44. package/dist/tools/save-org-preference.d.ts +0 -30
  45. package/dist/tools/save-org-preference.js +0 -47
  46. package/dist/tools/save-org-preference.js.map +0 -1
@@ -1,116 +0,0 @@
1
- import { apiRequest, requirePaidPlan } from '../api-client.js';
2
- import { getUserInfo } from '../credentials.js';
3
- export const logStoryTool = {
4
- name: 'log_story',
5
- description: 'Save a STAR-formatted interview story to BragDuck. ' +
6
- 'Use this when the user discusses interview prep, behavioral questions, or asks to save a story. ' +
7
- 'Each story has Situation, Task, Action, Result fields plus competency tags. ' +
8
- 'Call this in the same response as a preview — the tool permission prompt (Allow/Deny) ' +
9
- 'that appears to the user IS the confirmation.',
10
- inputSchema: {
11
- type: 'object',
12
- properties: {
13
- title: {
14
- type: 'string',
15
- minLength: 5,
16
- maxLength: 200,
17
- description: 'Short title for the story (e.g., "Led migration to microservices")',
18
- },
19
- situation: {
20
- type: 'string',
21
- minLength: 10,
22
- description: 'The context and background — what was happening, what was the environment',
23
- },
24
- task: {
25
- type: 'string',
26
- minLength: 10,
27
- description: 'What was your specific responsibility or challenge',
28
- },
29
- action: {
30
- type: 'string',
31
- minLength: 10,
32
- description: 'What you specifically did — the steps you took',
33
- },
34
- result: {
35
- type: 'string',
36
- minLength: 10,
37
- description: 'The outcome — measurable impact, what changed, what you learned',
38
- },
39
- competencies: {
40
- type: 'array',
41
- items: { type: 'string', minLength: 2, maxLength: 50 },
42
- maxItems: 20,
43
- description: 'Skills or competencies this story demonstrates (e.g., "leadership", "system design", "conflict resolution")',
44
- },
45
- bragIds: {
46
- type: 'array',
47
- items: { type: 'string' },
48
- maxItems: 20,
49
- description: 'IDs of BragDuck brags that back this story',
50
- },
51
- orgId: {
52
- type: 'string',
53
- description: 'Organisation ID to associate the story with',
54
- },
55
- },
56
- required: ['title', 'situation', 'task', 'action', 'result'],
57
- },
58
- };
59
- export async function handleLogStory(input) {
60
- const planError = await requirePaidPlan();
61
- if (planError)
62
- return planError;
63
- try {
64
- const userInfo = getUserInfo();
65
- if (!userInfo) {
66
- return {
67
- content: [{
68
- type: 'text',
69
- text: 'Not authenticated with BragDuck. Please call the "login" tool first.',
70
- }],
71
- isError: true,
72
- };
73
- }
74
- const body = {
75
- title: input.title,
76
- situation: input.situation,
77
- task: input.task,
78
- action: input.action,
79
- result: input.result,
80
- competencies: input.competencies || [],
81
- bragIds: input.bragIds || [],
82
- source: 'mcp',
83
- };
84
- if (input.orgId)
85
- body.orgId = input.orgId;
86
- const story = await apiRequest(`/v1/users/${userInfo.id}/stories`, { method: 'POST', body });
87
- const competencyLine = story.competencies.length > 0
88
- ? `\nCompetencies: ${story.competencies.join(', ')}`
89
- : '';
90
- return {
91
- content: [{
92
- type: 'text',
93
- text: `Story saved: "${story.title}"${competencyLine}`,
94
- }],
95
- };
96
- }
97
- catch (error) {
98
- if (error instanceof Error && (error.message === 'NOT_AUTHENTICATED' || error.message === 'TOKEN_EXPIRED')) {
99
- return {
100
- content: [{
101
- type: 'text',
102
- text: 'Not authenticated with BragDuck. Please call the "login" tool first.',
103
- }],
104
- isError: true,
105
- };
106
- }
107
- return {
108
- content: [{
109
- type: 'text',
110
- text: `Failed to save story: ${error instanceof Error ? error.message : String(error)}`,
111
- }],
112
- isError: true,
113
- };
114
- }
115
- }
116
- //# sourceMappingURL=log-story.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"log-story.js","sourceRoot":"","sources":["../../src/tools/log-story.ts"],"names":[],"mappings":"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"}
@@ -1,24 +0,0 @@
1
- export declare const loginTool: {
2
- name: string;
3
- description: string;
4
- inputSchema: {
5
- type: "object";
6
- properties: {
7
- force: {
8
- type: string;
9
- description: string;
10
- };
11
- };
12
- };
13
- };
14
- interface LoginInput {
15
- force?: boolean;
16
- }
17
- export declare function handleLogin(input?: LoginInput): Promise<{
18
- content: Array<{
19
- type: string;
20
- text: string;
21
- }>;
22
- isError?: boolean;
23
- }>;
24
- export {};
@@ -1,46 +0,0 @@
1
- import { login } from '../auth.js';
2
- import { getAccessToken } from '../credentials.js';
3
- export const loginTool = {
4
- name: 'login',
5
- description: 'Authenticate with BragDuck. Opens the browser for sign-in/sign-up. ' +
6
- 'Call this when other tools return an authentication error.',
7
- inputSchema: {
8
- type: 'object',
9
- properties: {
10
- force: {
11
- type: 'boolean',
12
- description: 'Force re-authentication even if already logged in',
13
- },
14
- },
15
- },
16
- };
17
- export async function handleLogin(input) {
18
- // Check if already authenticated (skip if force=true)
19
- if (!input?.force) {
20
- const existingToken = getAccessToken();
21
- if (existingToken) {
22
- return {
23
- content: [{ type: 'text', text: 'Already authenticated with BragDuck.' }],
24
- };
25
- }
26
- }
27
- try {
28
- const user = await login();
29
- return {
30
- content: [{
31
- type: 'text',
32
- text: `Authenticated as ${user.name} (${user.email}). You can now log brags and manage objectives.`,
33
- }],
34
- };
35
- }
36
- catch (error) {
37
- return {
38
- content: [{
39
- type: 'text',
40
- text: `Authentication failed: ${error instanceof Error ? error.message : String(error)}`,
41
- }],
42
- isError: true,
43
- };
44
- }
45
- }
46
- //# sourceMappingURL=login.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/tools/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,OAAO;IACb,WAAW,EACT,qEAAqE;QACrE,4DAA4D;IAC9D,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,mDAAmD;aACjE;SACF;KACF;CACF,CAAC;AAMF,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAkB;IAElB,sDAAsD;IACtD,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC;QAClB,MAAM,aAAa,GAAG,cAAc,EAAE,CAAC;QACvC,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,sCAAsC,EAAE,CAAC;aAC1E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,KAAK,EAAE,CAAC;QAC3B,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,oBAAoB,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,iDAAiD;iBACpG,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;iBACzF,CAAC;YACF,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1,71 +0,0 @@
1
- export declare const previewBragTool: {
2
- name: string;
3
- description: string;
4
- inputSchema: {
5
- type: "object";
6
- properties: {
7
- title: {
8
- type: string;
9
- minLength: number;
10
- maxLength: number;
11
- description: string;
12
- };
13
- description: {
14
- type: string;
15
- minLength: number;
16
- maxLength: number;
17
- description: string;
18
- };
19
- type: {
20
- type: string;
21
- enum: string[];
22
- description: string;
23
- };
24
- impact_level: {
25
- type: string;
26
- enum: number[];
27
- description: string;
28
- };
29
- impact_description: {
30
- type: string;
31
- description: string;
32
- };
33
- tags: {
34
- type: string;
35
- items: {
36
- type: string;
37
- minLength: number;
38
- maxLength: number;
39
- };
40
- maxItems: number;
41
- description: string;
42
- };
43
- references: {
44
- type: string;
45
- items: {
46
- type: string;
47
- format: string;
48
- };
49
- maxItems: number;
50
- description: string;
51
- };
52
- };
53
- required: string[];
54
- };
55
- };
56
- interface PreviewBragInput {
57
- title: string;
58
- description: string;
59
- type: string;
60
- impact_level: number;
61
- impact_description: string;
62
- tags?: string[];
63
- references?: string[];
64
- }
65
- export declare function handlePreviewBrag(input: PreviewBragInput): {
66
- content: Array<{
67
- type: string;
68
- text: string;
69
- }>;
70
- };
71
- export {};
@@ -1,103 +0,0 @@
1
- const IMPACT_LABELS = {
2
- 0: 'None (personal learning / routine)',
3
- 1: 'Low (individual contributor impact)',
4
- 2: 'Medium (team-level impact)',
5
- 3: 'High (organisation-level impact)',
6
- };
7
- const TYPE_EMOJIS = {
8
- progress: '📈',
9
- achievement: '🏆',
10
- recognition: '🌟',
11
- support: '🤝',
12
- code: '💻',
13
- leadership: '🧭',
14
- learning: '📚',
15
- collaboration: '👥',
16
- challenge: '⚔️',
17
- innovation: '💡',
18
- meeting: '🗣️',
19
- bug: '🐛',
20
- others: '📌',
21
- };
22
- export const previewBragTool = {
23
- name: 'preview_brag',
24
- description: 'Show the user a formatted preview of a proposed brag BEFORE logging it. ' +
25
- 'Only call this when: (1) the user has confirmed they want to log a brag, ' +
26
- '(2) you have assessed the achievement as bragable, and ' +
27
- '(3) you have enough concrete detail to fill every required field without fabricating. ' +
28
- 'If any of those conditions are not met, do not call this — ask clarifying questions instead.',
29
- inputSchema: {
30
- type: 'object',
31
- properties: {
32
- title: {
33
- type: 'string',
34
- minLength: 10,
35
- maxLength: 200,
36
- description: 'Short title of the achievement (10-200 characters)',
37
- },
38
- description: {
39
- type: 'string',
40
- minLength: 50,
41
- maxLength: 2000,
42
- description: 'Detailed description of what was accomplished and its impact (50-2000 characters)',
43
- },
44
- type: {
45
- type: 'string',
46
- enum: [
47
- 'progress', 'achievement', 'recognition', 'support', 'code',
48
- 'leadership', 'learning', 'collaboration', 'challenge', 'innovation',
49
- 'meeting', 'bug', 'others',
50
- ],
51
- description: 'Category that best fits this achievement',
52
- },
53
- impact_level: {
54
- type: 'number',
55
- enum: [0, 1, 2, 3],
56
- description: '0=none, 1=low (individual), 2=medium (team), 3=high (org)',
57
- },
58
- impact_description: {
59
- type: 'string',
60
- description: 'Narrative of the impact. Start with scope (Individual/Team/Organization), ' +
61
- 'then 1-3 measurable outcomes.',
62
- },
63
- tags: {
64
- type: 'array',
65
- items: { type: 'string', minLength: 2, maxLength: 30 },
66
- maxItems: 10,
67
- description: 'Tags to categorise the brag',
68
- },
69
- references: {
70
- type: 'array',
71
- items: { type: 'string', format: 'uri' },
72
- maxItems: 10,
73
- description: 'URLs: PRs, tickets, commits, design docs, etc.',
74
- },
75
- },
76
- required: ['title', 'description', 'type', 'impact_level', 'impact_description'],
77
- },
78
- };
79
- export function handlePreviewBrag(input) {
80
- const emoji = TYPE_EMOJIS[input.type] ?? '📌';
81
- const impactLabel = IMPACT_LABELS[input.impact_level] ?? String(input.impact_level);
82
- // Return structured data so the AI renders the table natively in its own
83
- // response (AI-generated markdown renders correctly; tool-result text does not).
84
- return {
85
- content: [
86
- {
87
- type: 'text',
88
- text: JSON.stringify({
89
- title: input.title,
90
- type: `${emoji} ${input.type}`,
91
- impact_level: impactLabel,
92
- impact_details: input.impact_description,
93
- description: input.description,
94
- tags: input.tags && input.tags.length > 0 ? input.tags.join(', ') : '—',
95
- references: input.references && input.references.length > 0
96
- ? input.references.join(', ')
97
- : '—',
98
- }),
99
- },
100
- ],
101
- };
102
- }
103
- //# sourceMappingURL=preview-brag.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"preview-brag.js","sourceRoot":"","sources":["../../src/tools/preview-brag.ts"],"names":[],"mappings":"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"}
@@ -1,38 +0,0 @@
1
- export declare const quickBragTool: {
2
- name: string;
3
- description: string;
4
- inputSchema: {
5
- type: "object";
6
- properties: {
7
- text: {
8
- type: string;
9
- minLength: number;
10
- maxLength: number;
11
- description: string;
12
- };
13
- orgId: {
14
- type: string;
15
- description: string;
16
- };
17
- agent: {
18
- type: string;
19
- maxLength: number;
20
- description: string;
21
- };
22
- };
23
- required: string[];
24
- };
25
- };
26
- interface QuickBragInput {
27
- text: string;
28
- orgId?: string;
29
- agent?: string;
30
- }
31
- export declare function handleQuickBrag(input: QuickBragInput): Promise<{
32
- content: Array<{
33
- type: string;
34
- text: string;
35
- }>;
36
- isError?: boolean;
37
- }>;
38
- export {};
@@ -1,143 +0,0 @@
1
- import { apiRequest, requirePaidPlan } from '../api-client.js';
2
- export const quickBragTool = {
3
- name: 'quick_brag',
4
- description: 'Log a brag from raw text. Accepts free-form text (a sentence, paragraph, or paste from a message/PR/doc) ' +
5
- 'and uses AI to extract and structure it into a proper brag. The AI will parse the text into a title, ' +
6
- 'description, type, impact, and tags, then log it. Use this when the user says "/brag" followed by text, ' +
7
- 'or pastes something and asks to log it as a brag.',
8
- inputSchema: {
9
- type: 'object',
10
- properties: {
11
- text: {
12
- type: 'string',
13
- minLength: 10,
14
- maxLength: 5000,
15
- description: 'Raw text describing the achievement. Can be a sentence, paragraph, paste from a PR description, ' +
16
- 'Slack message, commit message, or any free-form text. The AI will extract brag fields from it.',
17
- },
18
- orgId: {
19
- type: 'string',
20
- description: 'Organisation ID to associate the brag with (optional)',
21
- },
22
- agent: {
23
- type: 'string',
24
- maxLength: 50,
25
- description: 'Optional AI agent/client name, e.g. "claude", "cursor", "copilot".',
26
- },
27
- },
28
- required: ['text'],
29
- },
30
- };
31
- function toAgentExternalType(agent) {
32
- if (!agent)
33
- return undefined;
34
- const normalized = agent
35
- .trim()
36
- .toLowerCase()
37
- .replace(/\s+/g, '-')
38
- .replace(/[^a-z0-9_-]/g, '');
39
- if (normalized.length === 0)
40
- return undefined;
41
- return `agent:${normalized.slice(0, 50)}`;
42
- }
43
- export async function handleQuickBrag(input) {
44
- const planError = await requirePaidPlan();
45
- if (planError)
46
- return planError;
47
- try {
48
- // Step 1: Refine raw text into structured brag via AI
49
- const refined = await apiRequest('/v1/brags/refine', {
50
- method: 'POST',
51
- body: { brags: [{ text: input.text }] },
52
- });
53
- if (!refined.refined_brags || refined.refined_brags.length === 0) {
54
- return {
55
- content: [{
56
- type: 'text',
57
- text: 'Could not extract a brag from the provided text. Try adding more detail about what was accomplished and its impact.',
58
- }],
59
- isError: true,
60
- };
61
- }
62
- // Step 2: Log the refined brag
63
- const extracted = refined.refined_brags[0];
64
- const brag = {
65
- title: extracted.refined_title,
66
- description: extracted.refined_description,
67
- tags: extracted.suggested_tags || [],
68
- date: new Date().toISOString(),
69
- visibility: 'private',
70
- impactLevel: extracted.suggested_impactLevel,
71
- impact_description: extracted.impact_description || '',
72
- typeKey: extracted.suggested_type_key,
73
- };
74
- const allLinks = [
75
- ...(extracted.extracted_links || []),
76
- ...(extracted.attachments || []),
77
- ].filter(Boolean);
78
- if (allLinks.length > 0)
79
- brag.attachments = allLinks;
80
- if (input.orgId)
81
- brag.orgId = input.orgId;
82
- const agentExternalType = toAgentExternalType(input.agent);
83
- if (agentExternalType)
84
- brag.externalType = agentExternalType;
85
- const response = await apiRequest('/v1/brags', {
86
- method: 'POST',
87
- body: { brags: [brag], source: 'mcp' },
88
- });
89
- // Check for validation errors first
90
- if (response.errors && response.errors.length > 0) {
91
- const errorMessages = response.errors.map((e) => e.message).join('; ');
92
- return {
93
- content: [{
94
- type: 'text',
95
- text: `Failed to create brag: ${errorMessages}`,
96
- }],
97
- isError: true,
98
- };
99
- }
100
- if (response.brags && response.brags.length > 0) {
101
- const created = response.brags[0];
102
- const lines = [
103
- `Brag logged: "${created.title}"`,
104
- `${created.url}`,
105
- ];
106
- if (created.keyResultIds && created.keyResultIds.length > 0) {
107
- lines.push(`Automatically linked to key result: ${created.keyResultIds[0]}`);
108
- }
109
- return {
110
- content: [{
111
- type: 'text',
112
- text: lines.join('\n'),
113
- }],
114
- };
115
- }
116
- return {
117
- content: [{
118
- type: 'text',
119
- text: 'Server returned no brag and no error detail',
120
- }],
121
- isError: true,
122
- };
123
- }
124
- catch (error) {
125
- if (error instanceof Error && (error.message === 'NOT_AUTHENTICATED' || error.message === 'TOKEN_EXPIRED')) {
126
- return {
127
- content: [{
128
- type: 'text',
129
- text: 'Not authenticated with BragDuck. Please call the "login" tool first.',
130
- }],
131
- isError: true,
132
- };
133
- }
134
- return {
135
- content: [{
136
- type: 'text',
137
- text: `Error: ${error instanceof Error ? error.message : String(error)}`,
138
- }],
139
- isError: true,
140
- };
141
- }
142
- }
143
- //# sourceMappingURL=quick-brag.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"quick-brag.js","sourceRoot":"","sources":["../../src/tools/quick-brag.ts"],"names":[],"mappings":"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"}
@@ -1,30 +0,0 @@
1
- export declare const saveOrgPreferenceTool: {
2
- name: string;
3
- description: string;
4
- inputSchema: {
5
- type: "object";
6
- properties: {
7
- orgId: {
8
- type: string;
9
- description: string;
10
- };
11
- orgName: {
12
- type: string;
13
- description: string;
14
- };
15
- };
16
- required: string[];
17
- };
18
- };
19
- interface SaveOrgPreferenceInput {
20
- orgId: string;
21
- orgName: string;
22
- }
23
- export declare function handleSaveOrgPreference(input: SaveOrgPreferenceInput): Promise<{
24
- content: Array<{
25
- type: string;
26
- text: string;
27
- }>;
28
- isError?: boolean;
29
- }>;
30
- export {};
@@ -1,47 +0,0 @@
1
- import { requirePaidPlan } from '../api-client.js';
2
- import { saveOrgPreference } from '../org-preference.js';
3
- export const saveOrgPreferenceTool = {
4
- name: 'save_org_preference',
5
- description: 'Save the organisation preference for the current working directory. ' +
6
- 'Call this after the user selects which company a brag belongs to, ' +
7
- 'so the same choice is remembered for future brags in this directory.',
8
- inputSchema: {
9
- type: 'object',
10
- properties: {
11
- orgId: {
12
- type: 'string',
13
- description: 'The organisation ID to save as the preference for this directory',
14
- },
15
- orgName: {
16
- type: 'string',
17
- description: 'The organisation name (for display purposes)',
18
- },
19
- },
20
- required: ['orgId', 'orgName'],
21
- },
22
- };
23
- export async function handleSaveOrgPreference(input) {
24
- const planError = await requirePaidPlan();
25
- if (planError)
26
- return planError;
27
- try {
28
- const cwd = process.cwd();
29
- saveOrgPreference(cwd, input.orgId, input.orgName);
30
- return {
31
- content: [{
32
- type: 'text',
33
- text: `Saved: brags in this directory will be associated with **${input.orgName}**.`,
34
- }],
35
- };
36
- }
37
- catch (error) {
38
- return {
39
- content: [{
40
- type: 'text',
41
- text: `Failed to save preference: ${error instanceof Error ? error.message : String(error)}`,
42
- }],
43
- isError: true,
44
- };
45
- }
46
- }
47
- //# sourceMappingURL=save-org-preference.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"save-org-preference.js","sourceRoot":"","sources":["../../src/tools/save-org-preference.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EACT,sEAAsE;QACtE,oEAAoE;QACpE,sEAAsE;IACxE,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,kEAAkE;aAChF;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,8CAA8C;aAC5D;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC;KAC/B;CACF,CAAC;AAOF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,KAA6B;IAE7B,MAAM,SAAS,GAAG,MAAM,eAAe,EAAE,CAAC;IAC1C,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1B,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,4DAA4D,KAAK,CAAC,OAAO,KAAK;iBACrF,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,8BAA8B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;iBAC7F,CAAC;YACF,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC"}