@nestr/mcp 0.1.24 → 0.1.27

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.
package/README.md CHANGED
@@ -71,34 +71,93 @@ Ask your AI assistant things like:
71
71
 
72
72
  ## Available Tools
73
73
 
74
+ ### Workspace & Search
75
+
74
76
  | Tool | Description |
75
77
  |------|-------------|
76
78
  | `nestr_list_workspaces` | List accessible workspaces |
77
79
  | `nestr_get_workspace` | Get workspace details |
80
+ | `nestr_create_workspace` | Create a new workspace (OAuth only) |
78
81
  | `nestr_search` | Search for nests (tasks, projects, roles) |
82
+
83
+ ### Nests (Tasks, Projects, Roles)
84
+
85
+ | Tool | Description |
86
+ |------|-------------|
79
87
  | `nestr_get_nest` | Get details of a specific nest |
80
88
  | `nestr_get_nest_children` | Get child nests |
81
89
  | `nestr_create_nest` | Create a new nest |
82
90
  | `nestr_update_nest` | Update nest properties |
83
91
  | `nestr_delete_nest` | Delete a nest |
92
+ | `nestr_reorder_nest` | Reorder a nest relative to another |
93
+ | `nestr_bulk_reorder` | Bulk reorder multiple nests |
94
+
95
+ ### Comments & Discussion
96
+
97
+ | Tool | Description |
98
+ |------|-------------|
84
99
  | `nestr_add_comment` | Add a comment to a nest |
85
100
  | `nestr_get_comments` | Get comments/discussion on a nest |
101
+
102
+ ### Organization Structure
103
+
104
+ | Tool | Description |
105
+ |------|-------------|
86
106
  | `nestr_list_circles` | List organizational circles |
87
107
  | `nestr_get_circle` | Get circle details |
88
108
  | `nestr_get_circle_roles` | Get roles in a circle |
89
109
  | `nestr_list_roles` | List all roles |
90
110
  | `nestr_list_users` | List workspace members |
91
111
  | `nestr_get_user` | Get user details |
92
- | `nestr_list_labels` | List available labels |
112
+
113
+ ### Labels & Projects
114
+
115
+ | Tool | Description |
116
+ |------|-------------|
117
+ | `nestr_list_labels` | List workspace labels |
93
118
  | `nestr_get_label` | Get label details |
94
119
  | `nestr_get_projects` | List projects with status |
120
+
121
+ ### Insights & Apps
122
+
123
+ | Tool | Description |
124
+ |------|-------------|
95
125
  | `nestr_get_insights` | Get workspace metrics |
96
126
  | `nestr_get_insight_history` | Get historical trend data for a metric |
97
127
  | `nestr_get_workspace_apps` | List enabled apps/features |
98
- | `nestr_list_inbox` | List items in user's inbox (OAuth only) |
99
- | `nestr_create_inbox_item` | Quick capture to inbox (OAuth only) |
100
- | `nestr_get_inbox_item` | Get inbox item details (OAuth only) |
101
- | `nestr_update_inbox_item` | Update inbox item (OAuth only) |
128
+
129
+ ### Personal (OAuth only)
130
+
131
+ | Tool | Description |
132
+ |------|-------------|
133
+ | `nestr_list_inbox` | List items in user's inbox |
134
+ | `nestr_create_inbox_item` | Quick capture to inbox |
135
+ | `nestr_get_inbox_item` | Get inbox item details |
136
+ | `nestr_update_inbox_item` | Update inbox item |
137
+ | `nestr_reorder_inbox` | Reorder inbox items |
138
+ | `nestr_list_personal_labels` | List user's personal labels |
139
+ | `nestr_create_personal_label` | Create a personal label |
140
+ | `nestr_get_daily_plan` | Get items marked for today |
141
+
142
+ ## MCP Apps (Interactive UI)
143
+
144
+ MCP Apps are interactive UI components that can be embedded in MCP clients that support them (like Claude.ai). They provide rich, visual interfaces for working with Nestr data.
145
+
146
+ ### Completable List
147
+
148
+ **Resource URI:** `ui://nestr/completable-list`
149
+
150
+ An interactive list for viewing and completing tasks and projects.
151
+
152
+ **Features:**
153
+ - Projects show a box icon, todos show a checkbox
154
+ - Check items to mark them complete (strikethrough)
155
+ - Inline editing of titles (auto-saves)
156
+ - Drag-and-drop reordering
157
+ - Shows parent path for context
158
+ - Quick link to open item in Nestr
159
+
160
+ **Usage:** When an AI assistant returns task or project results, supporting clients can render this interactive UI instead of plain text, allowing you to complete items, edit titles, and reorder directly in the chat.
102
161
 
103
162
  ## Authentication
104
163
 
@@ -116,14 +175,54 @@ API keys provide full workspace access and work with the local npm package. See
116
175
 
117
176
  ## Environment Variables
118
177
 
119
- | Variable | Description | Required |
120
- |----------|-------------|----------|
121
- | `NESTR_API_KEY` | Nestr API key (full workspace access) | Yes* |
122
- | `NESTR_OAUTH_TOKEN` | OAuth token (respects user permissions) | Yes* |
123
- | `NESTR_API_BASE` | API base URL (default: `https://app.nestr.io/api`) | No |
178
+ ### Authentication (Required)
179
+
180
+ | Variable | Description |
181
+ |----------|-------------|
182
+ | `NESTR_API_KEY` | Nestr API key (full workspace access) |
183
+ | `NESTR_OAUTH_TOKEN` | OAuth token (respects user permissions) |
124
184
 
125
185
  \* Either `NESTR_API_KEY` or `NESTR_OAUTH_TOKEN` is required for local usage.
126
186
 
187
+ ### Configuration (Optional)
188
+
189
+ | Variable | Description | Default |
190
+ |----------|-------------|---------|
191
+ | `NESTR_API_BASE` | API base URL | `https://app.nestr.io/api` |
192
+
193
+ ### Hosting/Server (HTTP transport only)
194
+
195
+ These are used when running the HTTP server for hosted deployments:
196
+
197
+ | Variable | Description | Default |
198
+ |----------|-------------|---------|
199
+ | `PORT` | HTTP server port | `3000` |
200
+ | `NESTR_OAUTH_CLIENT_ID` | OAuth client ID for hosted OAuth flow | - |
201
+ | `NESTR_OAUTH_CLIENT_SECRET` | OAuth client secret | - |
202
+ | `OAUTH_ENCRYPTION_KEY` | 32-byte base64 key for encrypting OAuth sessions at rest | - |
203
+ | `GTM_ID` | Google Tag Manager container ID for landing page | - |
204
+
205
+ ### Analytics (Optional)
206
+
207
+ Server-side analytics options:
208
+
209
+ **GA4 Measurement Protocol:**
210
+
211
+ | Variable | Description |
212
+ |----------|-------------|
213
+ | `GA4_MEASUREMENT_ID` | GA4 Measurement ID (e.g., `G-XXXXXXXXXX`) |
214
+ | `GA4_API_SECRET` | Measurement Protocol API secret |
215
+ | `GA4_DEBUG` | Set to `true` to validate events without recording |
216
+
217
+ **Note:** Both `GA4_MEASUREMENT_ID` and `GA4_API_SECRET` are required for GA4 tracking. If only the measurement ID is set, a warning is logged and tracking is disabled.
218
+
219
+ **MCPcat (MCP-specific analytics):**
220
+
221
+ | Variable | Description |
222
+ |----------|-------------|
223
+ | `MCPCAT_PROJECT_ID` | MCPcat project ID (from [mcpcat.io](https://mcpcat.io)) |
224
+ | `MCPCAT_ENABLE_REPLAY` | Enable session replay (default: `false`) |
225
+
127
226
  ## Development
128
227
 
129
228
  ```bash
@@ -0,0 +1,13 @@
1
+ /**
2
+ * GA4 Analytics via Measurement Protocol
3
+ *
4
+ * Implements the EventTracker interface for Google Analytics 4.
5
+ * Uses the Measurement Protocol for server-side event tracking.
6
+ *
7
+ * Environment variables:
8
+ * - GA4_MEASUREMENT_ID: GA4 measurement ID (e.g., G-XXXXXXXXXX)
9
+ * - GA4_API_SECRET: Measurement Protocol API secret
10
+ * - GA4_DEBUG: Set to "true" to use debug endpoint (validates but doesn't record)
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=ga4.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ga4.d.ts","sourceRoot":"","sources":["../../src/analytics/ga4.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * GA4 Analytics via Measurement Protocol
3
+ *
4
+ * Implements the EventTracker interface for Google Analytics 4.
5
+ * Uses the Measurement Protocol for server-side event tracking.
6
+ *
7
+ * Environment variables:
8
+ * - GA4_MEASUREMENT_ID: GA4 measurement ID (e.g., G-XXXXXXXXXX)
9
+ * - GA4_API_SECRET: Measurement Protocol API secret
10
+ * - GA4_DEBUG: Set to "true" to use debug endpoint (validates but doesn't record)
11
+ */
12
+ import { analytics, } from "./index.js";
13
+ // GA4 configuration from environment
14
+ const GA4_MEASUREMENT_ID = process.env.GA4_MEASUREMENT_ID;
15
+ const GA4_API_SECRET = process.env.GA4_API_SECRET;
16
+ const GA4_ENDPOINT = "https://www.google-analytics.com/mp/collect";
17
+ // Debug endpoint for testing (validates but doesn't record)
18
+ const GA4_DEBUG_ENDPOINT = "https://www.google-analytics.com/debug/mp/collect";
19
+ const DEBUG_MODE = process.env.GA4_DEBUG === "true";
20
+ /**
21
+ * Send event(s) to GA4 Measurement Protocol
22
+ * Non-blocking - failures are logged but don't throw
23
+ */
24
+ async function sendToGA4(payload) {
25
+ const endpoint = DEBUG_MODE ? GA4_DEBUG_ENDPOINT : GA4_ENDPOINT;
26
+ const url = `${endpoint}?measurement_id=${GA4_MEASUREMENT_ID}&api_secret=${GA4_API_SECRET}`;
27
+ try {
28
+ const response = await fetch(url, {
29
+ method: "POST",
30
+ headers: {
31
+ "Content-Type": "application/json",
32
+ },
33
+ body: JSON.stringify(payload),
34
+ });
35
+ if (DEBUG_MODE) {
36
+ const debugResponse = await response.json();
37
+ console.log("[GA4] Debug response:", JSON.stringify(debugResponse, null, 2));
38
+ }
39
+ else if (!response.ok) {
40
+ console.error(`[GA4] Failed to send event: ${response.status}`);
41
+ }
42
+ }
43
+ catch (error) {
44
+ console.error("[GA4] Error sending event:", error);
45
+ }
46
+ }
47
+ /**
48
+ * Build and send an event
49
+ */
50
+ function trackEvent(context, eventName, params) {
51
+ const payload = {
52
+ client_id: context.clientId,
53
+ events: [
54
+ {
55
+ name: eventName,
56
+ params: {
57
+ ...params,
58
+ app: "nestr_mcp",
59
+ mcp_client: context.mcpClient,
60
+ transport: context.transport,
61
+ engagement_time_msec: 100,
62
+ },
63
+ },
64
+ ],
65
+ };
66
+ if (context.userId) {
67
+ payload.user_id = context.userId;
68
+ }
69
+ // Fire and forget
70
+ sendToGA4(payload).catch(() => { });
71
+ }
72
+ /**
73
+ * GA4 EventTracker implementation
74
+ */
75
+ class GA4Tracker {
76
+ name = "GA4";
77
+ initialize() {
78
+ // Validate configuration
79
+ if (GA4_MEASUREMENT_ID && !GA4_API_SECRET) {
80
+ console.warn("[GA4] Warning: GA4_MEASUREMENT_ID is set but GA4_API_SECRET is missing. " +
81
+ "GA4 analytics is disabled. Get your API secret from: " +
82
+ "GA4 Admin → Data Streams → Measurement Protocol API secrets");
83
+ throw new Error("GA4 configuration incomplete");
84
+ }
85
+ if (!GA4_MEASUREMENT_ID || !GA4_API_SECRET) {
86
+ throw new Error("GA4 not configured");
87
+ }
88
+ console.log(`[GA4] Initialized with measurement ID: ${GA4_MEASUREMENT_ID}${DEBUG_MODE ? " (debug mode)" : ""}`);
89
+ }
90
+ trackSessionStart(context, params) {
91
+ trackEvent(context, "mcp_session_start", {
92
+ has_token: params?.hasToken,
93
+ auth_method: params?.authMethod,
94
+ });
95
+ }
96
+ trackToolCall(context, params) {
97
+ trackEvent(context, "mcp_tool_call", {
98
+ tool_name: params.toolName,
99
+ workspace_id: params.workspaceId,
100
+ success: params.success,
101
+ error_code: params.errorCode,
102
+ });
103
+ }
104
+ trackOAuthStart(context, params) {
105
+ trackEvent(context, "mcp_oauth_start", {
106
+ client_consumer: params?.clientConsumer,
107
+ });
108
+ }
109
+ trackOAuthComplete(context, params) {
110
+ trackEvent(context, "mcp_oauth_complete", {
111
+ is_new_user: params?.isNewUser,
112
+ });
113
+ }
114
+ trackSessionEnd(context, params) {
115
+ trackEvent(context, "mcp_session_end", {
116
+ duration_seconds: params?.duration,
117
+ tool_call_count: params?.toolCallCount,
118
+ });
119
+ }
120
+ trackError(context, params) {
121
+ trackEvent(context, "mcp_error", {
122
+ error_type: params.errorType,
123
+ error_message: params.errorMessage?.slice(0, 100),
124
+ tool_name: params.toolName,
125
+ });
126
+ }
127
+ }
128
+ // Auto-register GA4 tracker if configured
129
+ try {
130
+ analytics.register(new GA4Tracker());
131
+ }
132
+ catch {
133
+ // Not configured or incomplete - that's fine, warning already logged if needed
134
+ }
135
+ //# sourceMappingURL=ga4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ga4.js","sourceRoot":"","sources":["../../src/analytics/ga4.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Analytics Event Tracking
3
+ *
4
+ * Generic event tracking interface with pluggable implementations.
5
+ * Trackers register themselves and all receive events.
6
+ *
7
+ * Usage:
8
+ * import { analytics, AnalyticsContext } from "./analytics/index.js";
9
+ * analytics.trackSessionStart(context, { hasToken: true });
10
+ */
11
+ /**
12
+ * Analytics context for an MCP session
13
+ */
14
+ export interface AnalyticsContext {
15
+ /** Client ID for session tracking */
16
+ clientId: string;
17
+ /** User ID for cross-session tracking (e.g., Nestr user._id) */
18
+ userId?: string;
19
+ /** MCP client name (e.g., "claude-desktop", "cursor") */
20
+ mcpClient?: string;
21
+ /** Transport type */
22
+ transport: "http" | "stdio";
23
+ }
24
+ /**
25
+ * Session start event parameters
26
+ */
27
+ export interface SessionStartParams {
28
+ hasToken?: boolean;
29
+ authMethod?: "oauth" | "api_key";
30
+ }
31
+ /**
32
+ * Tool call event parameters
33
+ */
34
+ export interface ToolCallParams {
35
+ toolName: string;
36
+ workspaceId?: string;
37
+ success?: boolean;
38
+ errorCode?: string;
39
+ }
40
+ /**
41
+ * OAuth start event parameters
42
+ */
43
+ export interface OAuthStartParams {
44
+ clientConsumer?: string;
45
+ }
46
+ /**
47
+ * OAuth complete event parameters
48
+ */
49
+ export interface OAuthCompleteParams {
50
+ isNewUser?: boolean;
51
+ }
52
+ /**
53
+ * Session end event parameters
54
+ */
55
+ export interface SessionEndParams {
56
+ duration?: number;
57
+ toolCallCount?: number;
58
+ }
59
+ /**
60
+ * Error event parameters
61
+ */
62
+ export interface ErrorParams {
63
+ errorType: string;
64
+ errorMessage?: string;
65
+ toolName?: string;
66
+ }
67
+ /**
68
+ * Event tracker interface - implement this to add a new analytics provider
69
+ */
70
+ export interface EventTracker {
71
+ /** Unique name for this tracker (for logging) */
72
+ readonly name: string;
73
+ /** Called when tracker is registered - use for startup validation */
74
+ initialize?(): void;
75
+ /** Track MCP session start */
76
+ trackSessionStart(context: AnalyticsContext, params?: SessionStartParams): void;
77
+ /** Track MCP tool call */
78
+ trackToolCall(context: AnalyticsContext, params: ToolCallParams): void;
79
+ /** Track OAuth flow start */
80
+ trackOAuthStart(context: AnalyticsContext, params?: OAuthStartParams): void;
81
+ /** Track OAuth flow completion */
82
+ trackOAuthComplete(context: AnalyticsContext, params?: OAuthCompleteParams): void;
83
+ /** Track MCP session end */
84
+ trackSessionEnd(context: AnalyticsContext, params?: SessionEndParams): void;
85
+ /** Track errors */
86
+ trackError(context: AnalyticsContext, params: ErrorParams): void;
87
+ }
88
+ /**
89
+ * Analytics registry - manages multiple event trackers
90
+ */
91
+ declare class Analytics {
92
+ private trackers;
93
+ /**
94
+ * Register an event tracker
95
+ */
96
+ register(tracker: EventTracker): void;
97
+ /**
98
+ * Check if any trackers are registered
99
+ */
100
+ isEnabled(): boolean;
101
+ /**
102
+ * Generate a new client ID for session tracking
103
+ */
104
+ generateClientId(): string;
105
+ /**
106
+ * Track session start across all registered trackers
107
+ */
108
+ trackSessionStart(context: AnalyticsContext, params?: SessionStartParams): void;
109
+ /**
110
+ * Track tool call across all registered trackers
111
+ */
112
+ trackToolCall(context: AnalyticsContext, params: ToolCallParams): void;
113
+ /**
114
+ * Track OAuth start across all registered trackers
115
+ */
116
+ trackOAuthStart(context: AnalyticsContext, params?: OAuthStartParams): void;
117
+ /**
118
+ * Track OAuth complete across all registered trackers
119
+ */
120
+ trackOAuthComplete(context: AnalyticsContext, params?: OAuthCompleteParams): void;
121
+ /**
122
+ * Track session end across all registered trackers
123
+ */
124
+ trackSessionEnd(context: AnalyticsContext, params?: SessionEndParams): void;
125
+ /**
126
+ * Track error across all registered trackers
127
+ */
128
+ trackError(context: AnalyticsContext, params: ErrorParams): void;
129
+ }
130
+ /**
131
+ * Singleton analytics instance
132
+ */
133
+ export declare const analytics: Analytics;
134
+ export {};
135
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,qEAAqE;IACrE,UAAU,CAAC,IAAI,IAAI,CAAC;IAEpB,8BAA8B;IAC9B,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAEhF,0BAA0B;IAC1B,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAEvE,6BAA6B;IAC7B,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE5E,kCAAkC;IAClC,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAElF,4BAA4B;IAC5B,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE5E,mBAAmB;IACnB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;CAClE;AAED;;GAEG;AACH,cAAM,SAAS;IACb,OAAO,CAAC,QAAQ,CAAsB;IAEtC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAUrC;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI;IAU/E;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI;IAUtE;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,IAAI;IAU3E;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,IAAI;IAUjF;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,IAAI;IAU3E;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;CASjE;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,WAAkB,CAAC"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Analytics Event Tracking
3
+ *
4
+ * Generic event tracking interface with pluggable implementations.
5
+ * Trackers register themselves and all receive events.
6
+ *
7
+ * Usage:
8
+ * import { analytics, AnalyticsContext } from "./analytics/index.js";
9
+ * analytics.trackSessionStart(context, { hasToken: true });
10
+ */
11
+ import { randomUUID } from "node:crypto";
12
+ /**
13
+ * Analytics registry - manages multiple event trackers
14
+ */
15
+ class Analytics {
16
+ trackers = [];
17
+ /**
18
+ * Register an event tracker
19
+ */
20
+ register(tracker) {
21
+ try {
22
+ tracker.initialize?.();
23
+ this.trackers.push(tracker);
24
+ console.log(`[Analytics] Registered tracker: ${tracker.name}`);
25
+ }
26
+ catch (error) {
27
+ console.error(`[Analytics] Failed to register tracker ${tracker.name}:`, error);
28
+ }
29
+ }
30
+ /**
31
+ * Check if any trackers are registered
32
+ */
33
+ isEnabled() {
34
+ return this.trackers.length > 0;
35
+ }
36
+ /**
37
+ * Generate a new client ID for session tracking
38
+ */
39
+ generateClientId() {
40
+ return randomUUID();
41
+ }
42
+ /**
43
+ * Track session start across all registered trackers
44
+ */
45
+ trackSessionStart(context, params) {
46
+ for (const tracker of this.trackers) {
47
+ try {
48
+ tracker.trackSessionStart(context, params);
49
+ }
50
+ catch (error) {
51
+ console.error(`[Analytics] ${tracker.name} trackSessionStart error:`, error);
52
+ }
53
+ }
54
+ }
55
+ /**
56
+ * Track tool call across all registered trackers
57
+ */
58
+ trackToolCall(context, params) {
59
+ for (const tracker of this.trackers) {
60
+ try {
61
+ tracker.trackToolCall(context, params);
62
+ }
63
+ catch (error) {
64
+ console.error(`[Analytics] ${tracker.name} trackToolCall error:`, error);
65
+ }
66
+ }
67
+ }
68
+ /**
69
+ * Track OAuth start across all registered trackers
70
+ */
71
+ trackOAuthStart(context, params) {
72
+ for (const tracker of this.trackers) {
73
+ try {
74
+ tracker.trackOAuthStart(context, params);
75
+ }
76
+ catch (error) {
77
+ console.error(`[Analytics] ${tracker.name} trackOAuthStart error:`, error);
78
+ }
79
+ }
80
+ }
81
+ /**
82
+ * Track OAuth complete across all registered trackers
83
+ */
84
+ trackOAuthComplete(context, params) {
85
+ for (const tracker of this.trackers) {
86
+ try {
87
+ tracker.trackOAuthComplete(context, params);
88
+ }
89
+ catch (error) {
90
+ console.error(`[Analytics] ${tracker.name} trackOAuthComplete error:`, error);
91
+ }
92
+ }
93
+ }
94
+ /**
95
+ * Track session end across all registered trackers
96
+ */
97
+ trackSessionEnd(context, params) {
98
+ for (const tracker of this.trackers) {
99
+ try {
100
+ tracker.trackSessionEnd(context, params);
101
+ }
102
+ catch (error) {
103
+ console.error(`[Analytics] ${tracker.name} trackSessionEnd error:`, error);
104
+ }
105
+ }
106
+ }
107
+ /**
108
+ * Track error across all registered trackers
109
+ */
110
+ trackError(context, params) {
111
+ for (const tracker of this.trackers) {
112
+ try {
113
+ tracker.trackError(context, params);
114
+ }
115
+ catch (error) {
116
+ console.error(`[Analytics] ${tracker.name} trackError error:`, error);
117
+ }
118
+ }
119
+ }
120
+ }
121
+ /**
122
+ * Singleton analytics instance
123
+ */
124
+ export const analytics = new Analytics();
125
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"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"}
@@ -116,6 +116,22 @@ export declare class NestrClient {
116
116
  cleanText?: boolean;
117
117
  }): Promise<Nest[]>;
118
118
  getWorkspace(workspaceId: string, cleanText?: boolean): Promise<Nest>;
119
+ createWorkspace(options: {
120
+ title: string;
121
+ purpose?: string;
122
+ configuration?: {
123
+ /** 'collaborate' for team workspace, 'personal' for individual workspace */
124
+ collaborators?: 'collaborate' | 'personal';
125
+ /** Self-organization model */
126
+ governance?: 'holacracy' | 'sociocracy' | 'roles_circles';
127
+ /** Subscription plan for collaborative workspaces */
128
+ plan?: 'plan_starter' | 'plan_pro';
129
+ /** Optional apps to enable */
130
+ variableApps?: Array<'okr' | 'feedback' | 'insights'>;
131
+ /** Layout style (personal workspaces only) */
132
+ layout?: 'board' | 'list';
133
+ };
134
+ }): Promise<Nest>;
119
135
  searchWorkspace(workspaceId: string, search: string, options?: {
120
136
  limit?: number;
121
137
  page?: number;
@@ -126,7 +142,12 @@ export declare class NestrClient {
126
142
  page?: number;
127
143
  cleanText?: boolean;
128
144
  }): Promise<Nest[]>;
129
- getNest(nestId: string, cleanText?: boolean): Promise<Nest>;
145
+ getNest(nestId: string, options?: {
146
+ cleanText?: boolean;
147
+ fieldsMetaData?: boolean;
148
+ }): Promise<Nest & {
149
+ fieldsMetaData?: Record<string, unknown>;
150
+ }>;
130
151
  getNestChildren(nestId: string, options?: {
131
152
  limit?: number;
132
153
  page?: number;
@@ -235,6 +256,57 @@ export declare class NestrClient {
235
256
  completed: boolean;
236
257
  data: Record<string, unknown>;
237
258
  }>): Promise<Nest>;
259
+ /**
260
+ * List the current user's personal labels.
261
+ * Requires OAuth token (user-scoped) - does not work with workspace API keys.
262
+ */
263
+ listPersonalLabels(): Promise<Label[]>;
264
+ /**
265
+ * Create a new personal label for the current user.
266
+ * Requires OAuth token (user-scoped) - does not work with workspace API keys.
267
+ */
268
+ createPersonalLabel(data: {
269
+ title: string;
270
+ description?: string;
271
+ color?: string;
272
+ icon?: string;
273
+ }): Promise<Label>;
274
+ /**
275
+ * Get the user's daily plan - items marked with the 'now' label.
276
+ * Requires OAuth token (user-scoped) - does not work with workspace API keys.
277
+ * Note: Only returns items from inbox and in-scope workspaces.
278
+ */
279
+ getDailyPlan(): Promise<Nest[]>;
280
+ /**
281
+ * Reorder a nest by positioning it before or after another nest.
282
+ * Updates searchOrder (and order if both nests share the same parent).
283
+ */
284
+ reorderNest(nestId: string, position: "before" | "after", relatedNestId: string): Promise<Nest & {
285
+ searchOrder?: number;
286
+ order?: number;
287
+ }>;
288
+ /**
289
+ * Bulk reorder nests by providing an array of nest IDs in the desired order.
290
+ * Updates searchOrder for all nests and order for nests sharing the same parent.
291
+ */
292
+ bulkReorder(workspaceId: string, nestIds: string[]): Promise<Array<Nest & {
293
+ searchOrder?: number;
294
+ order?: number;
295
+ }>>;
296
+ /**
297
+ * Reorder inbox items by providing an array of item IDs in the desired order.
298
+ * Requires OAuth token.
299
+ */
300
+ reorderInbox(nestIds: string[]): Promise<Array<Nest & {
301
+ searchOrder?: number;
302
+ order?: number;
303
+ }>>;
304
+ /**
305
+ * Get the current authenticated user's info.
306
+ * Requires OAuth token - does not work with workspace API keys.
307
+ * Used for analytics to get user_id for session stitching.
308
+ */
309
+ getCurrentUser(): Promise<User>;
238
310
  }
239
311
  /**
240
312
  * Factory function to create client from environment variables