@critical-path/svelte 0.17.11 → 0.18.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 (54) hide show
  1. package/README.md +13 -0
  2. package/dist/activity-state.svelte.d.ts +3 -0
  3. package/dist/activity-state.svelte.d.ts.map +1 -1
  4. package/dist/attachment-state.svelte.d.ts +3 -0
  5. package/dist/attachment-state.svelte.d.ts.map +1 -1
  6. package/dist/comment-state.svelte.d.ts +3 -0
  7. package/dist/comment-state.svelte.d.ts.map +1 -1
  8. package/dist/critical-path-state.svelte.d.ts +3 -0
  9. package/dist/critical-path-state.svelte.d.ts.map +1 -1
  10. package/dist/deliverable-state.svelte.d.ts +3 -0
  11. package/dist/deliverable-state.svelte.d.ts.map +1 -1
  12. package/dist/deliverable-summary-state.svelte.d.ts +3 -0
  13. package/dist/deliverable-summary-state.svelte.d.ts.map +1 -1
  14. package/dist/index.js +645 -551
  15. package/dist/latest-request.d.ts +15 -0
  16. package/dist/latest-request.d.ts.map +1 -0
  17. package/dist/project-state.svelte.d.ts +3 -0
  18. package/dist/project-state.svelte.d.ts.map +1 -1
  19. package/dist/task-metrics-state.svelte.d.ts +3 -0
  20. package/dist/task-metrics-state.svelte.d.ts.map +1 -1
  21. package/dist/task-state.svelte.d.ts +3 -0
  22. package/dist/task-state.svelte.d.ts.map +1 -1
  23. package/dist/task-transitions-state.svelte.d.ts +3 -0
  24. package/dist/task-transitions-state.svelte.d.ts.map +1 -1
  25. package/dist/timeline-ladder-state.svelte.d.ts +3 -0
  26. package/dist/timeline-ladder-state.svelte.d.ts.map +1 -1
  27. package/dist/workflow-state.svelte.d.ts +3 -0
  28. package/dist/workflow-state.svelte.d.ts.map +1 -1
  29. package/dist/workload-state.svelte.d.ts +3 -0
  30. package/dist/workload-state.svelte.d.ts.map +1 -1
  31. package/package.json +10 -6
  32. package/CHANGELOG.md +0 -714
  33. package/dist/index.test.d.ts +0 -2
  34. package/dist/index.test.d.ts.map +0 -1
  35. package/src/activity-state.svelte.ts +0 -193
  36. package/src/attachment-state.svelte.ts +0 -61
  37. package/src/comment-state.svelte.ts +0 -130
  38. package/src/critical-path-state.svelte.ts +0 -33
  39. package/src/deliverable-state.svelte.ts +0 -77
  40. package/src/deliverable-summary-state.svelte.ts +0 -41
  41. package/src/index.test.ts +0 -885
  42. package/src/index.ts +0 -23
  43. package/src/kanban-state.svelte.ts +0 -113
  44. package/src/project-state.svelte.ts +0 -54
  45. package/src/task-metrics-state.svelte.ts +0 -83
  46. package/src/task-state.svelte.ts +0 -195
  47. package/src/task-transitions-state.svelte.ts +0 -36
  48. package/src/timeline-ladder-state.svelte.ts +0 -58
  49. package/src/webmcp-state.svelte.ts +0 -78
  50. package/src/workflow-state.svelte.ts +0 -62
  51. package/src/workload-state.svelte.ts +0 -83
  52. package/tsconfig.json +0 -8
  53. package/vite.config.ts +0 -22
  54. package/vitest.config.ts +0 -6
package/src/index.ts DELETED
@@ -1,23 +0,0 @@
1
- import { CriticalPathClient, type ClientOptions } from '@critical-path/client';
2
-
3
- export function createCriticalPathClient(options: ClientOptions): CriticalPathClient {
4
- return new CriticalPathClient(options);
5
- }
6
-
7
- export * from './project-state.svelte.js';
8
- export * from './task-state.svelte.js';
9
- export * from './workflow-state.svelte.js';
10
- export * from './comment-state.svelte.js';
11
- export * from './attachment-state.svelte.js';
12
- export * from './activity-state.svelte.js';
13
- export * from './deliverable-state.svelte.js';
14
- export * from './deliverable-summary-state.svelte.js';
15
- export * from './kanban-state.svelte.js';
16
- export * from './task-transitions-state.svelte.js';
17
- export * from './webmcp-state.svelte.js';
18
- export * from './critical-path-state.svelte.js';
19
- export * from './timeline-ladder-state.svelte.js';
20
- export * from './task-metrics-state.svelte.js';
21
- export * from './workload-state.svelte.js';
22
-
23
-
@@ -1,113 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { CreateTaskBody } from '@critical-path/core/schemas';
3
- import type { CriticalPathClient } from '@critical-path/client';
4
- import type { Task, TaskStatus, StatusDefinition, SemanticStatus } from '@critical-path/core';
5
- import { resolveStatusDefinition } from '@critical-path/core';
6
- import { TaskState } from './task-state.svelte.js';
7
-
8
- export interface KanbanStateOptions {
9
- groupBy?: 'workflow' | 'semantic';
10
- customDefinitions?: StatusDefinition[];
11
- }
12
-
13
- export class KanbanState {
14
- private taskState: TaskState;
15
-
16
- get data(): Task[] {
17
- return this.taskState.data;
18
- }
19
-
20
- get tasks(): Task[] {
21
- return this.taskState.data;
22
- }
23
-
24
- get loading(): boolean {
25
- return this.taskState.loading;
26
- }
27
-
28
- get error(): Error | null {
29
- return this.taskState.error;
30
- }
31
-
32
- columns = $derived.by<Record<string, Task[]>>(() => {
33
- const tasks = this.taskState.data;
34
- if (this.options?.groupBy === 'semantic') {
35
- const semanticCols: Record<SemanticStatus, Task[]> = {
36
- not_started: [],
37
- in_progress: [],
38
- completed: [],
39
- canceled: []
40
- };
41
- for (const task of tasks) {
42
- const category =
43
- task.semanticStatus ||
44
- resolveStatusDefinition(task.status, this.options?.customDefinitions).category;
45
- if (semanticCols[category]) {
46
- semanticCols[category].push(task);
47
- } else {
48
- semanticCols.not_started.push(task);
49
- }
50
- }
51
- return semanticCols;
52
- }
53
-
54
- const workflowCols: Record<string, Task[]> = {};
55
- if (this.options?.customDefinitions && this.options.customDefinitions.length > 0) {
56
- for (const def of this.options.customDefinitions) {
57
- workflowCols[def.key] = [];
58
- }
59
- } else {
60
- workflowCols.backlog = [];
61
- workflowCols.todo = [];
62
- workflowCols.in_progress = [];
63
- workflowCols.in_review = [];
64
- workflowCols.done = [];
65
- workflowCols.canceled = [];
66
- }
67
-
68
- for (const task of tasks) {
69
- if (!workflowCols[task.status]) {
70
- workflowCols[task.status] = [];
71
- }
72
- workflowCols[task.status].push(task);
73
- }
74
-
75
- return workflowCols;
76
- });
77
-
78
- constructor(
79
- client: CriticalPathClient,
80
- public projectId?: string,
81
- public options: KanbanStateOptions = {}
82
- ) {
83
- this.taskState = new TaskState(client, projectId);
84
- }
85
-
86
- async fetch() {
87
- return this.taskState.fetch();
88
- }
89
-
90
- async createTask(input: CreateTaskBody) {
91
- return this.taskState.createTask(input);
92
- }
93
-
94
- async moveTask(taskId: string, targetStatus: TaskStatus) {
95
- return this.taskState.updateTaskStatus(taskId, targetStatus);
96
- }
97
-
98
- async updateTaskStatus(taskId: string, status: TaskStatus) {
99
- return this.taskState.updateTaskStatus(taskId, status);
100
- }
101
-
102
- async deleteTask(taskId: string) {
103
- return this.taskState.deleteTask(taskId);
104
- }
105
- }
106
-
107
- export function createKanbanState(
108
- client: CriticalPathClient,
109
- projectId?: string,
110
- options?: KanbanStateOptions
111
- ): KanbanState {
112
- return new KanbanState(client, projectId, options);
113
- }
@@ -1,54 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { CriticalPathClient } from '@critical-path/client';
3
- import type { Project } from '@critical-path/core';
4
-
5
- export class ProjectState {
6
- data = $state<Project[]>([]);
7
- loading = $state<boolean>(false);
8
- error = $state<Error | null>(null);
9
-
10
- constructor(private client: CriticalPathClient) {}
11
-
12
- async fetch() {
13
- this.loading = true;
14
- this.error = null;
15
- try {
16
- this.data = await this.client.getProjects();
17
- } catch (err) {
18
- this.error = err instanceof Error ? err : new Error(String(err));
19
- } finally {
20
- this.loading = false;
21
- }
22
- }
23
-
24
- async createProject(input: Omit<Project, 'id' | 'createdAt' | 'updatedAt'>) {
25
- const tempId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`;
26
- const now = new Date().toISOString();
27
- const tempProject: Project = {
28
- ...input,
29
- id: tempId,
30
- createdAt: now,
31
- updatedAt: now
32
- };
33
-
34
- // Optimistically add temp project
35
- this.data = [...this.data, tempProject];
36
-
37
- try {
38
- const created = await this.client.createProject(input);
39
- // Replace temp project with server created project
40
- this.data = this.data.map((p) => (p.id === tempId ? created : p));
41
- return created;
42
- } catch (err) {
43
- // Rollback on error
44
- this.data = this.data.filter((p) => p.id !== tempId);
45
- const errorObj = err instanceof Error ? err : new Error(String(err));
46
- this.error = errorObj;
47
- throw errorObj;
48
- }
49
- }
50
- }
51
-
52
- export function createProjectState(client: CriticalPathClient): ProjectState {
53
- return new ProjectState(client);
54
- }
@@ -1,83 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { CriticalPathClient } from '@critical-path/client';
3
- import type {
4
- TaskMetrics,
5
- TaskProgressHistory,
6
- TaskInferredActuals,
7
- RealityDelta,
8
- TaskProgressInference,
9
- TaskEVM,
10
- ProgressCurveProfile
11
- } from '@critical-path/core';
12
-
13
- export class TaskMetricsState {
14
- metrics = $state<TaskMetrics | null>(null);
15
- history = $state<TaskProgressHistory | null>(null);
16
- loading = $state<boolean>(false);
17
- error = $state<Error | null>(null);
18
-
19
- inferredActuals = $derived<TaskInferredActuals | null>(this.metrics?.inferredActuals ?? null);
20
- realityDelta = $derived<RealityDelta | null>(this.metrics?.realityDelta ?? null);
21
- progress = $derived<TaskProgressInference | null>(this.metrics?.progress ?? null);
22
- evm = $derived<TaskEVM | null>(this.metrics?.evm ?? null);
23
- curveProfile = $derived<ProgressCurveProfile | null>(this.history?.curveProfile ?? null);
24
-
25
- constructor(
26
- private client: CriticalPathClient,
27
- public taskId: string
28
- ) {}
29
-
30
- async fetchMetrics(): Promise<TaskMetrics | null> {
31
- this.loading = true;
32
- this.error = null;
33
- try {
34
- this.metrics = await this.client.getTaskMetrics(this.taskId);
35
- return this.metrics;
36
- } catch (err) {
37
- this.error = err instanceof Error ? err : new Error(String(err));
38
- return null;
39
- } finally {
40
- this.loading = false;
41
- }
42
- }
43
-
44
- async fetchHistory(): Promise<TaskProgressHistory | null> {
45
- this.loading = true;
46
- this.error = null;
47
- try {
48
- this.history = await this.client.getTaskProgressHistory(this.taskId);
49
- return this.history;
50
- } catch (err) {
51
- this.error = err instanceof Error ? err : new Error(String(err));
52
- return null;
53
- } finally {
54
- this.loading = false;
55
- }
56
- }
57
-
58
- async fetchAll(): Promise<{ metrics: TaskMetrics | null; history: TaskProgressHistory | null }> {
59
- this.loading = true;
60
- this.error = null;
61
- try {
62
- const [m, h] = await Promise.all([
63
- this.client.getTaskMetrics(this.taskId),
64
- this.client.getTaskProgressHistory(this.taskId)
65
- ]);
66
- this.metrics = m;
67
- this.history = h;
68
- return { metrics: m, history: h };
69
- } catch (err) {
70
- this.error = err instanceof Error ? err : new Error(String(err));
71
- return { metrics: null, history: null };
72
- } finally {
73
- this.loading = false;
74
- }
75
- }
76
- }
77
-
78
- export function createTaskMetricsState(
79
- client: CriticalPathClient,
80
- taskId: string
81
- ): TaskMetricsState {
82
- return new TaskMetricsState(client, taskId);
83
- }
@@ -1,195 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { CreateTaskBody, UpdateTaskBody } from '@critical-path/core/schemas';
3
- import type { CriticalPathClient } from '@critical-path/client';
4
- import { type Task, type TaskStatus, isTempTaskId } from '@critical-path/core';
5
-
6
- export class TaskState {
7
- data = $state<Task[]>([]);
8
- loading = $state<boolean>(false);
9
- error = $state<Error | null>(null);
10
-
11
- private pendingCreations = new Map<string, Promise<Task>>();
12
- private tempToRealIdMap = new Map<string, string>();
13
-
14
- constructor(
15
- private client: CriticalPathClient,
16
- public projectId?: string
17
- ) {}
18
-
19
- async fetch() {
20
- this.loading = true;
21
- this.error = null;
22
- try {
23
- this.data = await this.client.getTasks(this.projectId);
24
- } catch (err) {
25
- this.error = err instanceof Error ? err : new Error(String(err));
26
- } finally {
27
- this.loading = false;
28
- }
29
- }
30
-
31
- async createTask(input: CreateTaskBody) {
32
- const tempId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`;
33
- const now = new Date().toISOString();
34
- const tempTask: Task = {
35
- ...input,
36
- // Placeholders until the server responds with the workflow's real defaults
37
- status: input.status ?? 'todo',
38
- priority: input.priority ?? 'medium',
39
- id: tempId,
40
- createdAt: now,
41
- updatedAt: now
42
- };
43
-
44
- // Optimistically add temp task
45
- this.data = [...this.data, tempTask];
46
-
47
- const promise = this.client.createTask(input);
48
- this.pendingCreations.set(tempId, promise);
49
-
50
- try {
51
- const created = await promise;
52
- this.tempToRealIdMap.set(tempId, created.id);
53
- // Replace temp task with created task from server
54
- this.data = this.data.map((t) => (t.id === tempId ? created : t));
55
- return created;
56
- } catch (err) {
57
- // Rollback on error
58
- this.data = this.data.filter((t) => t.id !== tempId);
59
- const errorObj = err instanceof Error ? err : new Error(String(err));
60
- this.error = errorObj;
61
- throw errorObj;
62
- } finally {
63
- this.pendingCreations.delete(tempId);
64
- }
65
- }
66
-
67
- async updateTask(taskId: string, updates: UpdateTaskBody) {
68
- let targetId = taskId;
69
- if (this.tempToRealIdMap.has(taskId)) {
70
- targetId = this.tempToRealIdMap.get(taskId)!;
71
- }
72
-
73
- // 1. Immediately apply optimistic updates to the local task (temp or confirmed)
74
- const idx = this.data.findIndex((t) => t.id === targetId || t.id === taskId);
75
- let previousTask: Task | undefined;
76
- if (idx !== -1) {
77
- previousTask = this.data[idx];
78
- const optimisticTask: Task = {
79
- ...previousTask,
80
- ...updates,
81
- updatedAt: new Date().toISOString()
82
- };
83
- const newData = [...this.data];
84
- newData[idx] = optimisticTask;
85
- this.data = newData;
86
- }
87
-
88
- // 2. If it's a temporary task, await pending creation if in flight
89
- if (isTempTaskId(targetId)) {
90
- const pendingPromise =
91
- this.pendingCreations.get(targetId) ||
92
- (this.pendingCreations.size === 1
93
- ? Array.from(this.pendingCreations.values())[0]
94
- : undefined);
95
-
96
- if (pendingPromise) {
97
- try {
98
- const created = await pendingPromise;
99
- if (created && created.id) {
100
- targetId = created.id;
101
- this.tempToRealIdMap.set(taskId, targetId);
102
- }
103
- } catch {
104
- throw new Error(`Failed to update task: task creation failed for "${taskId}"`);
105
- }
106
- }
107
- }
108
-
109
- // If still a temp ID, task exists purely in local client state; avoid sending unresolvable temp ID
110
- if (isTempTaskId(targetId)) {
111
- const currentTask = this.data.find((t) => t.id === targetId || t.id === taskId);
112
- return (currentTask || { id: targetId, ...updates }) as Task;
113
- }
114
-
115
- try {
116
- const updated = await this.client.updateTask(targetId, updates);
117
- const currentIdx = this.data.findIndex((t) => t.id === targetId || t.id === taskId);
118
- if (currentIdx !== -1) {
119
- const confirmedData = [...this.data];
120
- confirmedData[currentIdx] = updated;
121
- this.data = confirmedData;
122
- }
123
- return updated;
124
- } catch (err) {
125
- // Rollback to previous task on error
126
- if (previousTask) {
127
- const rollbackIdx = this.data.findIndex((t) => t.id === targetId || t.id === taskId);
128
- if (rollbackIdx !== -1) {
129
- const rollbackData = [...this.data];
130
- rollbackData[rollbackIdx] = previousTask;
131
- this.data = rollbackData;
132
- }
133
- }
134
- const errorObj = err instanceof Error ? err : new Error(String(err));
135
- this.error = errorObj;
136
- throw errorObj;
137
- }
138
- }
139
-
140
- async updateTaskStatus(taskId: string, status: TaskStatus) {
141
- return this.updateTask(taskId, { status });
142
- }
143
-
144
- async deleteTask(taskId: string) {
145
- let targetId = taskId;
146
- if (this.tempToRealIdMap.has(taskId)) {
147
- targetId = this.tempToRealIdMap.get(taskId)!;
148
- }
149
-
150
- const idx = this.data.findIndex((t) => t.id === targetId || t.id === taskId);
151
- const previousTask = idx !== -1 ? this.data[idx] : undefined;
152
-
153
- // Optimistically remove task from local state
154
- if (idx !== -1) {
155
- this.data = this.data.filter((t) => t.id !== targetId && t.id !== taskId);
156
- }
157
-
158
- // If temporary task:
159
- if (isTempTaskId(targetId)) {
160
- const pendingPromise = this.pendingCreations.get(targetId);
161
- if (pendingPromise) {
162
- try {
163
- const created = await pendingPromise;
164
- if (created && created.id) {
165
- await this.client.deleteTask(created.id);
166
- }
167
- } catch {
168
- // If creation failed anyway, task is already gone
169
- }
170
- }
171
- return;
172
- }
173
-
174
- try {
175
- await this.client.deleteTask(targetId);
176
- } catch (err) {
177
- // Rollback on error by re-inserting at previous index
178
- if (previousTask && idx !== -1) {
179
- const restoredData = [...this.data];
180
- restoredData.splice(idx, 0, previousTask);
181
- this.data = restoredData;
182
- }
183
- const errorObj = err instanceof Error ? err : new Error(String(err));
184
- this.error = errorObj;
185
- throw errorObj;
186
- }
187
- }
188
- }
189
-
190
- export function createTaskState(
191
- client: CriticalPathClient,
192
- projectId?: string
193
- ): TaskState {
194
- return new TaskState(client, projectId);
195
- }
@@ -1,36 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { CriticalPathClient } from '@critical-path/client';
3
-
4
- export class TaskTransitionsState {
5
- allowedTransitions = $state<string[]>([]);
6
- loading = $state<boolean>(false);
7
- error = $state<Error | null>(null);
8
-
9
- constructor(private client: CriticalPathClient, public taskId?: string) {}
10
-
11
- async fetch(taskId?: string) {
12
- const targetTaskId = taskId || this.taskId;
13
- if (!targetTaskId) {
14
- this.allowedTransitions = [];
15
- this.loading = false;
16
- return;
17
- }
18
- this.taskId = targetTaskId;
19
- this.loading = true;
20
- this.error = null;
21
- try {
22
- this.allowedTransitions = await this.client.getAllowedTaskTransitions(targetTaskId);
23
- } catch (err) {
24
- this.error = err instanceof Error ? err : new Error(String(err));
25
- } finally {
26
- this.loading = false;
27
- }
28
- }
29
- }
30
-
31
- export function createTaskTransitionsState(
32
- client: CriticalPathClient,
33
- taskId?: string
34
- ): TaskTransitionsState {
35
- return new TaskTransitionsState(client, taskId);
36
- }
@@ -1,58 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { CriticalPathClient } from '@critical-path/client';
3
- import type {
4
- TimelineLadder,
5
- TimelineLadderOptions,
6
- AbstractionLevel,
7
- MacroTimelineSummary,
8
- ConcreteTaskEvidence
9
- } from '@critical-path/core';
10
-
11
- export class TimelineLadderState {
12
- data = $state<TimelineLadder | null>(null);
13
- level = $state<AbstractionLevel>('all');
14
- loading = $state<boolean>(false);
15
- error = $state<Error | null>(null);
16
-
17
- macro = $derived<MacroTimelineSummary | null>(this.data?.macro ?? null);
18
- standard = $derived<TimelineLadder['standard'] | null>(this.data?.standard ?? null);
19
- concrete = $derived<Record<string, ConcreteTaskEvidence> | null>(this.data?.concrete ?? null);
20
-
21
- constructor(
22
- private client: CriticalPathClient,
23
- public projectId: string,
24
- initialOptions?: TimelineLadderOptions
25
- ) {
26
- if (initialOptions?.level) {
27
- this.level = initialOptions.level;
28
- }
29
- }
30
-
31
- async setLevel(newLevel: AbstractionLevel) {
32
- this.level = newLevel;
33
- await this.fetch();
34
- }
35
-
36
- async fetch(options?: TimelineLadderOptions) {
37
- this.loading = true;
38
- this.error = null;
39
- try {
40
- this.data = await this.client.getTimelineLadder(this.projectId, {
41
- level: this.level,
42
- ...options
43
- });
44
- } catch (err) {
45
- this.error = err instanceof Error ? err : new Error(String(err));
46
- } finally {
47
- this.loading = false;
48
- }
49
- }
50
- }
51
-
52
- export function createTimelineLadderState(
53
- client: CriticalPathClient,
54
- projectId: string,
55
- initialOptions?: TimelineLadderOptions
56
- ): TimelineLadderState {
57
- return new TimelineLadderState(client, projectId, initialOptions);
58
- }
@@ -1,78 +0,0 @@
1
- import type { CriticalPathClient } from '@critical-path/client';
2
- import { registerWebMcpTools, type WebMcpRegistryHandle } from '@critical-path/mcp/web';
3
-
4
- export interface WebMcpStateOptions {
5
- projectId?: string;
6
- tools?: string[];
7
- autoRegister?: boolean;
8
- document?: any;
9
- navigator?: any;
10
- window?: any;
11
- onToolExecuted?: (toolName: string, input: any, result: any) => void;
12
- }
13
-
14
- export class WebMcpState {
15
- registered = $state<boolean>(false);
16
- activeProjectId = $state<string | undefined>(undefined);
17
- tools = $state<string[]>([]);
18
- error = $state<Error | null>(null);
19
-
20
- private handle: WebMcpRegistryHandle | null = null;
21
- private abortController: AbortController | null = null;
22
-
23
- constructor(private client: CriticalPathClient, private options: WebMcpStateOptions = {}) {
24
- this.activeProjectId = options.projectId;
25
- if (options.autoRegister ?? true) {
26
- this.register();
27
- }
28
- }
29
-
30
- register(): void {
31
- if (this.registered) return;
32
- this.error = null;
33
-
34
- try {
35
- this.abortController = new AbortController();
36
- this.handle = registerWebMcpTools({
37
- client: this.client,
38
- projectId: this.activeProjectId,
39
- tools: this.options.tools,
40
- signal: this.abortController.signal,
41
- document: this.options.document,
42
- navigator: this.options.navigator,
43
- window: this.options.window,
44
- onToolExecuted: (name, input, result) => {
45
- this.options.onToolExecuted?.(name, input, result);
46
- }
47
- });
48
- this.tools = this.handle.getRegisteredTools().map((t) => t.name);
49
- this.registered = true;
50
- } catch (err) {
51
- this.error = err instanceof Error ? err : new Error(String(err));
52
- this.registered = false;
53
- }
54
- }
55
-
56
- unregister(): void {
57
- if (!this.registered) return;
58
- this.abortController?.abort();
59
- this.handle?.unregister();
60
- this.handle = null;
61
- this.abortController = null;
62
- this.registered = false;
63
- this.tools = [];
64
- }
65
-
66
- setProjectId(projectId?: string): void {
67
- if (this.activeProjectId === projectId) return;
68
- this.activeProjectId = projectId;
69
- if (this.registered) {
70
- this.unregister();
71
- this.register();
72
- }
73
- }
74
- }
75
-
76
- export function createWebMcpState(client: CriticalPathClient, options?: WebMcpStateOptions): WebMcpState {
77
- return new WebMcpState(client, options);
78
- }