@indemn/cli 1.7.9 → 1.7.10

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.
@@ -51,6 +51,10 @@ export declare function refreshAccess(client: IndemnClient): Promise<Access | nu
51
51
  export declare function usableSomewhere(tool: string, access: Access | null, onlyOrgId?: string): boolean;
52
52
  /** The person's role in an org, for messages ("agent in Acme"). */
53
53
  export declare function roleIn(access: Access | null, orgId: string | undefined): string | null;
54
+ /** The org's project where the person can invite people: copilot's invite route needs owner or admin there. */
55
+ export declare function inviteProject(access: Access | null, orgId: string): AccessProject | undefined;
56
+ /** Why the person can't invite people to this org, or null (also when access is unknown: the server decides). */
57
+ export declare function inviteDenial(access: Access | null, orgId: string | undefined): string | null;
54
58
  /**
55
59
  * For org-scoped requirements: why this org can't be used, or null. Project-scoped
56
60
  * requirements are decided by the server (the project comes from the agent).
@@ -1 +1 @@
1
- {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/sdk/access.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACzD,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAExC,6GAA6G;AAC7G,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAcvF,CAAC;AAIH,yGAAyG;AACzG,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAKlE;AAiBD,kDAAkD;AAClD,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWhF;AAMD,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAOhG;AAED,mEAAmE;AACnE,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKtF;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAgBvG"}
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/sdk/access.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACzD,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAExC,6GAA6G;AAC7G,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAcvF,CAAC;AAIH,yGAAyG;AACzG,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAKlE;AAiBD,kDAAkD;AAClD,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWhF;AAMD,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAOhG;AAED,mEAAmE;AACnE,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKtF;AAED,+GAA+G;AAC/G,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAE7F;AAED,iHAAiH;AACjH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAI5F;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAgBvG"}
@@ -86,6 +86,17 @@ export function roleIn(access, orgId) {
86
86
  return null;
87
87
  return `${org.role ?? 'member'} in ${org.org_name}`;
88
88
  }
89
+ /** The org's project where the person can invite people: copilot's invite route needs owner or admin there. */
90
+ export function inviteProject(access, orgId) {
91
+ return access?.orgs.find((o) => o.org_id === orgId)?.projects.find((p) => p.role === 'owner' || p.role === 'admin');
92
+ }
93
+ /** Why the person can't invite people to this org, or null (also when access is unknown: the server decides). */
94
+ export function inviteDenial(access, orgId) {
95
+ const org = orgId ? access?.orgs.find((o) => o.org_id === orgId) : undefined;
96
+ if (!org || inviteProject(access, org.org_id))
97
+ return null;
98
+ return `Only owners and admins can invite people, and your role in ${org.org_name} is ${org.role ?? 'member'}.`;
99
+ }
89
100
  /**
90
101
  * For org-scoped requirements: why this org can't be used, or null. Project-scoped
91
102
  * requirements are decided by the server (the project comes from the agent).
@@ -1 +1 @@
1
- {"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/sdk/access.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/sdk/access.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,15 @@
1
1
  import { IndemnClient } from './client.js';
2
2
  import type { Channel, OrgMember, OrgSummary } from './types.js';
3
+ /** The roles the dashboard's Invite user page offers. copilot saves any role it is sent, so never owner here. */
4
+ export declare const INVITE_ROLES: readonly ["admin", "agent", "member"];
5
+ export type InviteRole = (typeof INVITE_ROLES)[number];
6
+ export interface InviteResult {
7
+ email: string;
8
+ role: InviteRole;
9
+ /** invited: no Indemn account yet, a sign-up email went out; added: an existing account joined now. The others changed nothing. */
10
+ outcome: 'invited' | 'added' | 'already_invited' | 'already_member';
11
+ message: string;
12
+ }
3
13
  export interface SandboxOrg {
4
14
  organization_id: string;
5
15
  name: string;
@@ -14,6 +24,12 @@ export declare class OrgsSDK {
14
24
  listOrganizations(): Promise<OrgSummary[]>;
15
25
  /** People with owner, admin or agent roles in the org, one row per person. */
16
26
  listMembers(): Promise<OrgMember[]>;
27
+ /**
28
+ * Invite someone to the org's project, as the dashboard's Invite user page does (copilot allows owners and
29
+ * admins only). A new email gets a sign-up invitation; an existing Indemn account is added at once and told
30
+ * by email. Already invited or already a member: nothing is sent, and the result says so.
31
+ */
32
+ inviteMember(projectId: string, email: string, role: InviteRole): Promise<InviteResult>;
17
33
  /**
18
34
  * A sandbox organization for a prospect. Only the Indemn support account may create one (copilot
19
35
  * refuses anyone else), and copilot always puts it on the sandbox plan set for the platform.
@@ -1 +1 @@
1
- {"version":3,"file":"orgs.d.ts","sourceRoot":"","sources":["../../src/sdk/orgs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AASjE,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,OAAO;IACN,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,YAAY;IAExC,+FAA+F;IACzF,iBAAiB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAIhD,8EAA8E;IACxE,WAAW,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAkCzC;;;OAGG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAetD,+DAA+D;IACzD,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;CAIzC"}
1
+ {"version":3,"file":"orgs.d.ts","sourceRoot":"","sources":["../../src/sdk/orgs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AASjE,iHAAiH;AACjH,eAAO,MAAM,YAAY,uCAAwC,CAAC;AAClE,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,mIAAmI;IACnI,OAAO,EAAE,SAAS,GAAG,OAAO,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IACpE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,OAAO;IACN,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,YAAY;IAExC,+FAA+F;IACzF,iBAAiB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAIhD,8EAA8E;IACxE,WAAW,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAkCzC;;;;OAIG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC;IAoB7F;;;OAGG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAetD,+DAA+D;IACzD,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;CAIzC"}
package/dist/sdk/orgs.js CHANGED
@@ -1,3 +1,5 @@
1
+ /** The roles the dashboard's Invite user page offers. copilot saves any role it is sent, so never owner here. */
2
+ export const INVITE_ROLES = ['admin', 'agent', 'member'];
1
3
  export class OrgsSDK {
2
4
  client;
3
5
  constructor(client) {
@@ -45,6 +47,34 @@ export class OrgsSDK {
45
47
  }
46
48
  return [...byUser.values()];
47
49
  }
50
+ /**
51
+ * Invite someone to the org's project, as the dashboard's Invite user page does (copilot allows owners and
52
+ * admins only). A new email gets a sign-up invitation; an existing Indemn account is added at once and told
53
+ * by email. Already invited or already a member: nothing is sent, and the result says so.
54
+ */
55
+ async inviteMember(projectId, email, role) {
56
+ const address = email.trim().toLowerCase();
57
+ const result = (outcome, message) => ({ email: address, role, outcome, message });
58
+ try {
59
+ const res = await this.client.copilotPost(`/${projectId}/project_users/invite`, {
60
+ email: address, role, user_available: false, id_organization: await this.client.currentOrgId(),
61
+ });
62
+ return res?.pendingInvitation
63
+ ? result('invited', `Invitation sent to ${address}. They join as ${role} once they sign up from the email.`)
64
+ : result('added', `${address} already had an Indemn account and is now in the organization as ${role}. They were told by email.`);
65
+ }
66
+ catch (err) {
67
+ // copilot answers these with 200 {success:false} and 500/403 with a code; the dashboard shows them as messages.
68
+ const message = err instanceof Error ? err.message : String(err);
69
+ if (/Pending Invitation already exist/i.test(message))
70
+ return result('already_invited', `${address} already has a pending invitation. Nothing was sent again.`);
71
+ if (/already a member/i.test(message))
72
+ return result('already_member', `${address} is already a member of the organization. Nothing was changed.`);
73
+ if (/invite oneself/i.test(message))
74
+ throw new Error('You can\'t invite yourself. Nothing was sent.');
75
+ throw err;
76
+ }
77
+ }
48
78
  /**
49
79
  * A sandbox organization for a prospect. Only the Indemn support account may create one (copilot
50
80
  * refuses anyone else), and copilot always puts it on the sandbox plan set for the platform.
@@ -1 +1 @@
1
- {"version":3,"file":"orgs.js","sourceRoot":"","sources":["../../src/sdk/orgs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"orgs.js","sourceRoot":"","sources":["../../src/sdk/orgs.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indemn/cli",
3
- "version": "1.7.9",
3
+ "version": "1.7.10",
4
4
  "description": "CLI, MCP server, and plugin for managing Indemn AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/sdk/index.js",
@@ -57,6 +57,11 @@ export const TOOL_META: Record<string, ToolMeta> = {
57
57
  describe: (a) => `This will create a new organization "${a.name}" on the sandbox plan (its trial, then the plan's monthly price, invoiced to the support account).`,
58
58
  },
59
59
  list_org_members: { ...read('List organization members'), paginate: true },
60
+ invite_org_member: {
61
+ ...write('Invite organization member'),
62
+ guard: true,
63
+ describe: (a) => `This will invite ${a.email} to the organization as ${({ admin: 'Administrator', agent: 'Agent', member: 'Member' } as Record<string, string>)[String(a.role)] ?? a.role}. Without an Indemn account they get an email to sign up; with one they join at once.`,
64
+ },
60
65
  list_channels: read('List channels'),
61
66
 
62
67
  // Agents
package/src/mcp/tools.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod/v3';
2
- import { currentAccess, orgDenial, refreshAccess, roleIn, usableSomewhere } from '../sdk/access.js';
2
+ import { currentAccess, inviteDenial, inviteProject, orgDenial, refreshAccess, roleIn, usableSomewhere } from '../sdk/access.js';
3
3
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
4
  import type { IndemnClient } from '../sdk/client.js';
5
5
  import { AgentInsightsSDK, AgentsSDK } from '../sdk/agents.js';
@@ -28,7 +28,7 @@ import { exchange, openTestChat } from '../sdk/test-chat.js';
28
28
  import { ConversationsSDK, conversationToTestSet, conversationUrl, isCliConversation, isTestConversation, projectOfAgent } from '../sdk/conversations.js';
29
29
  import { exportEvalMarkdown, exportEvalReport, exportAgentCard } from '../report/export.js';
30
30
  import { createRegistry, type Registry } from './registry.js';
31
- import { OrgsSDK } from '../sdk/orgs.js';
31
+ import { INVITE_ROLES, OrgsSDK } from '../sdk/orgs.js';
32
32
  import { whoami } from '../sdk/auth.js';
33
33
  import { NeedsInputError, SessionExpiredError } from '../core/runtime.js';
34
34
 
@@ -182,6 +182,7 @@ export function registerTools(server: McpServer, client: IndemnClient): Registry
182
182
  visible: (name) => usableSomewhere(name, currentAccess(client), orgInView()),
183
183
  // Refuse early only when the saved access still says no after asking again (it may be stale).
184
184
  deny: async (name, orgId) => {
185
+ if (name === 'invite_org_member') return inviteDenial((await refreshAccess(client)) ?? currentAccess(client), orgId);
185
186
  if (CAMPAIGN_TOOLS.has(name) && orgId) {
186
187
  const on = await client.copilotGet<{ enableSolutions?: boolean }>(`/organization/${orgId}/configurations`).then((c) => c?.enableSolutions === true, () => false);
187
188
  if (!on) return SOLUTIONS_OFF;
@@ -292,6 +293,22 @@ export function registerTools(server: McpServer, client: IndemnClient): Registry
292
293
  },
293
294
  );
294
295
 
296
+ reg.tool(
297
+ 'invite_org_member',
298
+ 'Invite someone to the organization by email, as the dashboard\'s Invite user page does. Only owners and admins can invite. Roles: admin (manages agents, knowledge bases, conversations, teammates and organization settings; not billing), agent (handles live conversations, with full AI Studio access; cannot manage teammates or settings) or member (tests and reviews agents and sees conversations). Ask for the role if the person did not say one; there is no owner role here. Someone without an Indemn account gets an email to sign up; an existing account joins at once. The host asks the person to approve.',
299
+ {
300
+ email: z.string().trim().email().describe('Email address of the person to invite'),
301
+ role: z.enum(INVITE_ROLES).describe('admin, agent or member'),
302
+ },
303
+ async (args) => {
304
+ try {
305
+ const project = inviteProject(currentAccess(client) ?? await refreshAccess(client), await client.currentOrgId());
306
+ if (!project) throw new Error('Could not find a project in this organization where you are an owner or admin. Nothing was sent.');
307
+ return success(await orgs.inviteMember(project.project_id, args.email, args.role));
308
+ } catch (err) { return error(err); }
309
+ },
310
+ );
311
+
295
312
  reg.tool(
296
313
  'list_channels',
297
314
  'List the channels an agent can be published on, such as WEB or VOICE.',
package/src/sdk/access.ts CHANGED
@@ -120,6 +120,18 @@ export function roleIn(access: Access | null, orgId: string | undefined): string
120
120
  return `${org.role ?? 'member'} in ${org.org_name}`;
121
121
  }
122
122
 
123
+ /** The org's project where the person can invite people: copilot's invite route needs owner or admin there. */
124
+ export function inviteProject(access: Access | null, orgId: string): AccessProject | undefined {
125
+ return access?.orgs.find((o) => o.org_id === orgId)?.projects.find((p) => p.role === 'owner' || p.role === 'admin');
126
+ }
127
+
128
+ /** Why the person can't invite people to this org, or null (also when access is unknown: the server decides). */
129
+ export function inviteDenial(access: Access | null, orgId: string | undefined): string | null {
130
+ const org = orgId ? access?.orgs.find((o) => o.org_id === orgId) : undefined;
131
+ if (!org || inviteProject(access, org.org_id)) return null;
132
+ return `Only owners and admins can invite people, and your role in ${org.org_name} is ${org.role ?? 'member'}.`;
133
+ }
134
+
123
135
  /**
124
136
  * For org-scoped requirements: why this org can't be used, or null. Project-scoped
125
137
  * requirements are decided by the server (the project comes from the agent).
package/src/sdk/orgs.ts CHANGED
@@ -8,6 +8,18 @@ interface RawProjectUser {
8
8
  id_project?: { name?: string } | string | null;
9
9
  }
10
10
 
11
+ /** The roles the dashboard's Invite user page offers. copilot saves any role it is sent, so never owner here. */
12
+ export const INVITE_ROLES = ['admin', 'agent', 'member'] as const;
13
+ export type InviteRole = (typeof INVITE_ROLES)[number];
14
+
15
+ export interface InviteResult {
16
+ email: string;
17
+ role: InviteRole;
18
+ /** invited: no Indemn account yet, a sign-up email went out; added: an existing account joined now. The others changed nothing. */
19
+ outcome: 'invited' | 'added' | 'already_invited' | 'already_member';
20
+ message: string;
21
+ }
22
+
11
23
  export interface SandboxOrg {
12
24
  organization_id: string;
13
25
  name: string;
@@ -59,6 +71,31 @@ export class OrgsSDK {
59
71
  return [...byUser.values()];
60
72
  }
61
73
 
74
+ /**
75
+ * Invite someone to the org's project, as the dashboard's Invite user page does (copilot allows owners and
76
+ * admins only). A new email gets a sign-up invitation; an existing Indemn account is added at once and told
77
+ * by email. Already invited or already a member: nothing is sent, and the result says so.
78
+ */
79
+ async inviteMember(projectId: string, email: string, role: InviteRole): Promise<InviteResult> {
80
+ const address = email.trim().toLowerCase();
81
+ const result = (outcome: InviteResult['outcome'], message: string): InviteResult => ({ email: address, role, outcome, message });
82
+ try {
83
+ const res = await this.client.copilotPost<{ pendingInvitation?: unknown }>(`/${projectId}/project_users/invite`, {
84
+ email: address, role, user_available: false, id_organization: await this.client.currentOrgId(),
85
+ });
86
+ return res?.pendingInvitation
87
+ ? result('invited', `Invitation sent to ${address}. They join as ${role} once they sign up from the email.`)
88
+ : result('added', `${address} already had an Indemn account and is now in the organization as ${role}. They were told by email.`);
89
+ } catch (err) {
90
+ // copilot answers these with 200 {success:false} and 500/403 with a code; the dashboard shows them as messages.
91
+ const message = err instanceof Error ? err.message : String(err);
92
+ if (/Pending Invitation already exist/i.test(message)) return result('already_invited', `${address} already has a pending invitation. Nothing was sent again.`);
93
+ if (/already a member/i.test(message)) return result('already_member', `${address} is already a member of the organization. Nothing was changed.`);
94
+ if (/invite oneself/i.test(message)) throw new Error('You can\'t invite yourself. Nothing was sent.');
95
+ throw err;
96
+ }
97
+ }
98
+
62
99
  /**
63
100
  * A sandbox organization for a prospect. Only the Indemn support account may create one (copilot
64
101
  * refuses anyone else), and copilot always puts it on the sandbox plan set for the platform.
@@ -68,6 +68,7 @@ exports[`MCP tool list > gives every tool a title and annotations 1`] = `
68
68
  "import_agent",
69
69
  "import_functions",
70
70
  "import_kb",
71
+ "invite_org_member",
71
72
  "jarvis_chat",
72
73
  "jarvis_create_job",
73
74
  "jarvis_jobs",
@@ -127,6 +127,24 @@ describe('role-aware MCP tools', () => {
127
127
  await pair.close();
128
128
  });
129
129
 
130
+ it('invites only where the person is an owner or admin, into that project, after approval', async () => {
131
+ const { calls } = recordFetch([
132
+ on('GET', '/auth/me/access', { json: accessWith() }),
133
+ on('POST', '/project_users/invite', { json: { pendingInvitation: { _id: 'i1' } } }),
134
+ ]);
135
+ const pair = await connectPair(setup, { elicit: () => ({ action: 'accept', content: { confirm: true } }) });
136
+ const refused = await pair.call('invite_org_member', { org_id: B, email: 'jane@acme.test', role: 'agent' });
137
+ expect(refused.isError).toBe(true);
138
+ expect(refused.body).toContain('Only owners and admins can invite people, and your role in QA B is guest.');
139
+ expect(pair.questions).toHaveLength(0);
140
+ const sent = await pair.call('invite_org_member', { org_id: A, email: 'jane@acme.test', role: 'agent' });
141
+ expect(sent.body.data).toMatchObject({ outcome: 'invited', email: 'jane@acme.test' });
142
+ expect(pair.questions[0].message).toContain('This will invite jane@acme.test to the organization as Agent.');
143
+ const invites = calls.filter((c) => c.url.includes('/project_users/invite'));
144
+ expect(invites.map((c) => new URL(c.url).pathname)).toEqual(['/api/p1/project_users/invite']);
145
+ await pair.close();
146
+ });
147
+
130
148
  it('tells the host when the visible tools change', async () => {
131
149
  vi.stubEnv('INDEMN_ORG_ID', B);
132
150
  recordFetch([on('GET', '/auth/me/access', { json: accessWith(true) })]);
@@ -17,7 +17,7 @@ describe('MCP tool list', () => {
17
17
  expect(typeof tool.annotations?.readOnlyHint, tool.name).toBe('boolean');
18
18
  }
19
19
  expect(tools.map((t) => t.name).sort()).toMatchSnapshot();
20
- expect(tools).toHaveLength(148); // +7 campaign tools // +numbers // +set_agent_transcriber // +set_org_admin_settings // +remove_holiday // +create_sandbox_org
20
+ expect(tools).toHaveLength(149); // +invite_org_member // +7 campaign tools // +numbers // +set_agent_transcriber // +set_org_admin_settings // +remove_holiday // +create_sandbox_org
21
21
  const props = (name: string) => Object.keys((tools.find((t) => t.name === name)!.inputSchema as { properties?: object }).properties ?? {});
22
22
  for (const name of ['list_agents', 'delete_agent', 'set_prompt', 'list_org_members', 'list_channels', 'chat_with_agent']) {
23
23
  expect(props(name), name).toContain('org_id');
@@ -58,6 +58,37 @@ describe('OrgsSDK', () => {
58
58
  await expect(new OrgsSDK(new IndemnClient({ orgId: A })).listMembers()).resolves.toEqual([]);
59
59
  });
60
60
 
61
+ it('invites by email into the project, as the dashboard does', async () => {
62
+ const { calls } = recordFetch([on('POST', '/project_users/invite', { json: { msg: 'User not found, save invite in pending ', pendingInvitation: { _id: 'i1' } } })]);
63
+ await expect(new OrgsSDK(new IndemnClient({ orgId: A })).inviteMember('p1', ' Jane@Acme.test ', 'agent')).resolves.toEqual({
64
+ email: 'jane@acme.test', role: 'agent', outcome: 'invited',
65
+ message: 'Invitation sent to jane@acme.test. They join as agent once they sign up from the email.',
66
+ });
67
+ expect(new URL(calls[0].url).pathname).toBe('/api/p1/project_users/invite');
68
+ expect(calls[0].body).toEqual({ email: 'jane@acme.test', role: 'agent', user_available: false, id_organization: A });
69
+ });
70
+
71
+ it('says when an existing account joined at once', async () => {
72
+ recordFetch([on('POST', '/project_users/invite', { json: { _id: 'pu1', role: 'admin', id_project: 'p1' } })]);
73
+ await expect(new OrgsSDK(new IndemnClient({ orgId: A })).inviteMember('p1', 'jo@acme.test', 'admin')).resolves.toMatchObject({ outcome: 'added', role: 'admin' });
74
+ });
75
+
76
+ it('already invited or already a member: nothing sent, said plainly', async () => {
77
+ recordFetch([on('POST', '/project_users/invite', { json: { success: false, msg: 'Pending Invitation already exist.', invite: {} } })]);
78
+ await expect(new OrgsSDK(new IndemnClient({ orgId: A })).inviteMember('p1', 'jane@acme.test', 'agent')).resolves.toMatchObject({
79
+ outcome: 'already_invited', message: 'jane@acme.test already has a pending invitation. Nothing was sent again.',
80
+ });
81
+ recordFetch([on('POST', '/project_users/invite', { status: 500, json: { success: false, msg: 'Forbidden. User is already a member', code: 4001, alreadyCurrentProjectMember: true } })]);
82
+ await expect(new OrgsSDK(new IndemnClient({ orgId: A })).inviteMember('p1', 'jo@acme.test', 'member')).resolves.toMatchObject({ outcome: 'already_member' });
83
+ });
84
+
85
+ it('refuses inviting yourself and keeps copilot\'s other refusals', async () => {
86
+ recordFetch([on('POST', '/project_users/invite', { status: 403, json: { success: false, msg: 'Forbidden. It is not allowed to invite oneself', code: 4000 } })]);
87
+ await expect(new OrgsSDK(new IndemnClient({ orgId: A })).inviteMember('p1', 'pat@acme.test', 'agent')).rejects.toThrow('You can\'t invite yourself. Nothing was sent.');
88
+ recordFetch([on('POST', '/project_users/invite', { status: 403, json: { success: false, msg: 'You don\'t have the required role.' } })]);
89
+ await expect(new OrgsSDK(new IndemnClient({ orgId: A })).inviteMember('p1', 'jane@acme.test', 'agent')).rejects.toThrow('Not allowed: You don\'t have the required role.');
90
+ });
91
+
61
92
  it('creates a sandbox org with only its name and links to it', async () => {
62
93
  const { calls } = recordFetch([on('POST', '/organization/sandbox', { json: { success: true, id_organization: A, id_project: 'p1', id_plan: 'plan1' } })]);
63
94
  await expect(new OrgsSDK(new IndemnClient()).createSandbox('Acme Insurance')).resolves.toEqual({