@shawnowen/comet-mcp 2.3.1 → 2.4.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.
- package/README.md +86 -19
- package/dist/alert-dispatcher.d.ts +23 -0
- package/dist/alert-dispatcher.js +101 -0
- package/dist/bound-session.d.ts +23 -0
- package/dist/bound-session.js +119 -0
- package/dist/bridge-config.d.ts +6 -0
- package/dist/bridge-config.js +78 -0
- package/dist/cdp-client.d.ts +40 -4
- package/dist/cdp-client.js +502 -155
- package/dist/comet-ai.d.ts +15 -0
- package/dist/comet-ai.js +114 -38
- package/dist/delegate-binding.d.ts +19 -0
- package/dist/delegate-binding.js +73 -0
- package/dist/discovery/capability-entry.d.ts +215 -0
- package/dist/discovery/capability-entry.js +13 -0
- package/dist/discovery/description-template.d.ts +40 -0
- package/dist/discovery/description-template.js +61 -0
- package/dist/discovery/golden-queries.fixture.d.ts +22 -0
- package/dist/discovery/golden-queries.fixture.js +137 -0
- package/dist/discovery/mcp-source.d.ts +38 -0
- package/dist/discovery/mcp-source.js +70 -0
- package/dist/discovery/metadata-completeness.d.ts +48 -0
- package/dist/discovery/metadata-completeness.js +83 -0
- package/dist/discovery/registry.d.ts +35 -0
- package/dist/discovery/registry.js +35 -0
- package/dist/discovery/safety.d.ts +44 -0
- package/dist/discovery/safety.js +59 -0
- package/dist/discovery/schema-validator.d.ts +36 -0
- package/dist/discovery/schema-validator.js +257 -0
- package/dist/discovery/source-error.d.ts +47 -0
- package/dist/discovery/source-error.js +95 -0
- package/dist/discovery/tool-meta.d.ts +41 -0
- package/dist/discovery/tool-meta.js +229 -0
- package/dist/discovery/virtual-tools.d.ts +20 -0
- package/dist/discovery/virtual-tools.js +69 -0
- package/dist/http-server.js +2067 -47
- package/dist/index.js +3163 -710
- package/dist/observer.d.ts +47 -0
- package/dist/observer.js +516 -0
- package/dist/session-registry.d.ts +57 -0
- package/dist/session-registry.js +500 -0
- package/dist/sidecar-artifacts.d.ts +49 -0
- package/dist/sidecar-artifacts.js +146 -0
- package/dist/snapshot-capture.d.ts +3 -0
- package/dist/snapshot-capture.js +91 -0
- package/dist/tab-group-archive.js +3 -1
- package/dist/tab-groups.d.ts +7 -0
- package/dist/tab-groups.js +21 -3
- package/dist/task-thread-aggregator.d.ts +34 -0
- package/dist/task-thread-aggregator.js +480 -0
- package/dist/task-thread-canonical.d.ts +142 -0
- package/dist/task-thread-canonical.js +116 -0
- package/dist/types.d.ts +237 -0
- package/dist/window-bindings.d.ts +112 -0
- package/dist/window-bindings.js +476 -0
- package/extension/background.js +1556 -300
- package/extension/icons/icon.svg +9 -0
- package/extension/icons/icon128.png +0 -0
- package/extension/icons/icon16.png +0 -0
- package/extension/icons/icon48.png +0 -0
- package/extension/manifest.json +19 -4
- package/extension/session-logic.js +2383 -0
- package/extension/session-manager.html +299 -0
- package/extension/sidepanel.css +5323 -528
- package/extension/sidepanel.html +282 -2
- package/extension/sidepanel.js +10075 -951
- package/extension/window-policy.js +162 -0
- package/package.json +10 -7
- package/vendor/lifecycle-mcp-adapter.mjs +103 -0
- package/vendor/lifecycle-metadata.mjs +252 -0
- package/vendor/readiness-report.mjs +742 -0
- package/dist/cdp-client.d.ts.map +0 -1
- package/dist/cdp-client.js.map +0 -1
- package/dist/comet-ai.d.ts.map +0 -1
- package/dist/comet-ai.js.map +0 -1
- package/dist/http-server.d.ts.map +0 -1
- package/dist/http-server.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/tab-group-archive.d.ts.map +0 -1
- package/dist/tab-group-archive.js.map +0 -1
- package/dist/tab-groups.d.ts.map +0 -1
- package/dist/tab-groups.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { AgentSession, TaskThreadSnapshot, SnapshotReason, TaskThreadStatus } from "./types.js";
|
|
2
|
+
export declare function captureTaskThreadSnapshot(session: AgentSession, reason: SnapshotReason, taskStatus?: TaskThreadStatus): Promise<TaskThreadSnapshot>;
|
|
3
|
+
//# sourceMappingURL=snapshot-capture.d.ts.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Snapshot Capture — Task Thread state preservation before automated closure (Spec 016, FR-003)
|
|
2
|
+
// Captures all tabs, Sidecar threads, window metadata, and task status.
|
|
3
|
+
// Atomic write: temp file → rename to prevent partial captures.
|
|
4
|
+
// If capture fails, caller MUST NOT proceed with close (fail safe).
|
|
5
|
+
import { writeFileSync, renameSync, mkdirSync } from "fs";
|
|
6
|
+
import { join } from "path";
|
|
7
|
+
import { loadBridgeConfig } from "./bridge-config.js";
|
|
8
|
+
export async function captureTaskThreadSnapshot(session, reason, taskStatus = "abandoned") {
|
|
9
|
+
const config = loadBridgeConfig();
|
|
10
|
+
const tabs = [];
|
|
11
|
+
const sidecarThreads = [];
|
|
12
|
+
let windowMetadata = null;
|
|
13
|
+
// Query tabs in this session's tab group via extension messaging
|
|
14
|
+
try {
|
|
15
|
+
const { tabGroupsClient } = await import("./tab-groups.js");
|
|
16
|
+
const allTabs = await tabGroupsClient.listTabs();
|
|
17
|
+
// Filter to tabs in this session's tab group, or by ownership if no group (extension degradation)
|
|
18
|
+
const sessionTabs = session.tabGroupId !== null
|
|
19
|
+
? allTabs.filter((t) => t.groupId === session.tabGroupId)
|
|
20
|
+
: allTabs.filter((t) => t.id === session.chromeTabId);
|
|
21
|
+
for (const tab of sessionTabs) {
|
|
22
|
+
tabs.push({
|
|
23
|
+
url: tab.url,
|
|
24
|
+
title: tab.title,
|
|
25
|
+
chromeTabId: tab.id,
|
|
26
|
+
targetId: session.targetId,
|
|
27
|
+
active: tab.active,
|
|
28
|
+
});
|
|
29
|
+
// Check if tab has a Sidecar thread (Perplexity assistant panel)
|
|
30
|
+
if (tab.url?.includes("perplexity.ai")) {
|
|
31
|
+
sidecarThreads.push({
|
|
32
|
+
threadUrl: tab.url,
|
|
33
|
+
parentTabUrl: tab.url,
|
|
34
|
+
lastQuery: null,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Capture window metadata
|
|
39
|
+
const groups = await tabGroupsClient.listGroups();
|
|
40
|
+
const sessionGroup = groups.find((g) => g.id === session.tabGroupId);
|
|
41
|
+
if (sessionGroup) {
|
|
42
|
+
windowMetadata = {
|
|
43
|
+
windowId: sessionGroup.windowId,
|
|
44
|
+
x: 0,
|
|
45
|
+
y: -1440,
|
|
46
|
+
width: 2560,
|
|
47
|
+
height: 1440,
|
|
48
|
+
displayIndex: 0,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (extErr) {
|
|
53
|
+
// Extension not available — capture what we can from CDP
|
|
54
|
+
console.warn(`[comet-bridge] Snapshot degraded for ${session.sessionKey}: extension unavailable (${extErr instanceof Error ? extErr.message : extErr})`);
|
|
55
|
+
tabs.push({
|
|
56
|
+
url: "unknown (extension unavailable)",
|
|
57
|
+
title: session.taskThreadId,
|
|
58
|
+
chromeTabId: session.chromeTabId ?? 0,
|
|
59
|
+
targetId: session.targetId,
|
|
60
|
+
active: true,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const snapshot = {
|
|
64
|
+
sessionKey: session.sessionKey,
|
|
65
|
+
agentId: session.agentId,
|
|
66
|
+
taskThreadId: session.taskThreadId,
|
|
67
|
+
capturedAt: new Date().toISOString(),
|
|
68
|
+
reason,
|
|
69
|
+
taskStatus,
|
|
70
|
+
tabs,
|
|
71
|
+
sidecarThreads,
|
|
72
|
+
windowMetadata,
|
|
73
|
+
tabGroupId: session.tabGroupId,
|
|
74
|
+
tabGroupColor: session.tabGroupColor,
|
|
75
|
+
};
|
|
76
|
+
// Atomic write: temp file → rename (T026)
|
|
77
|
+
const snapshotDir = config.cleanup.snapshotDir;
|
|
78
|
+
mkdirSync(snapshotDir, { recursive: true });
|
|
79
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
80
|
+
const safeAgentId = session.agentId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
81
|
+
const safeThreadId = session.taskThreadId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
82
|
+
const filename = `${safeAgentId}_${safeThreadId}_${timestamp}.json`;
|
|
83
|
+
const finalPath = join(snapshotDir, filename);
|
|
84
|
+
const tempPath = finalPath + ".tmp";
|
|
85
|
+
// Write to temp file first — if this fails, no partial snapshot exists
|
|
86
|
+
writeFileSync(tempPath, JSON.stringify(snapshot, null, 2));
|
|
87
|
+
// Atomic rename — if this fails, temp file exists but final doesn't
|
|
88
|
+
renameSync(tempPath, finalPath);
|
|
89
|
+
return snapshot;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=snapshot-capture.js.map
|
|
@@ -11,7 +11,9 @@ let writeQueue = Promise.resolve();
|
|
|
11
11
|
function serialized(fn) {
|
|
12
12
|
const prev = writeQueue;
|
|
13
13
|
let resolve;
|
|
14
|
-
writeQueue = new Promise((r) => {
|
|
14
|
+
writeQueue = new Promise((r) => {
|
|
15
|
+
resolve = r;
|
|
16
|
+
});
|
|
15
17
|
return prev.then(fn).finally(() => resolve());
|
|
16
18
|
}
|
|
17
19
|
function resolveArchivePaths(archiveDir) {
|
package/dist/tab-groups.d.ts
CHANGED
|
@@ -15,6 +15,11 @@ export interface TabInfo {
|
|
|
15
15
|
url: string;
|
|
16
16
|
active: boolean;
|
|
17
17
|
}
|
|
18
|
+
export interface WindowTabInfo {
|
|
19
|
+
tabId: number;
|
|
20
|
+
windowId: number;
|
|
21
|
+
url: string;
|
|
22
|
+
}
|
|
18
23
|
export interface CreateGroupOptions {
|
|
19
24
|
tabIds: number[];
|
|
20
25
|
title?: string;
|
|
@@ -68,6 +73,8 @@ export declare class TabGroupsClient {
|
|
|
68
73
|
groupId: number;
|
|
69
74
|
group: TabGroup;
|
|
70
75
|
}>;
|
|
76
|
+
/** Create a managed browser window locked to the top display fullscreen policy. */
|
|
77
|
+
createTopDisplayFullscreenWindowWithTab(url: string): Promise<WindowTabInfo>;
|
|
71
78
|
/** Update an existing tab group's title, color, or collapsed state. */
|
|
72
79
|
updateGroup(options: UpdateGroupOptions): Promise<TabGroup>;
|
|
73
80
|
/** Move a tab group to a new position. */
|
package/dist/tab-groups.js
CHANGED
|
@@ -116,8 +116,7 @@ export class TabGroupsClient {
|
|
|
116
116
|
returnByValue: true,
|
|
117
117
|
});
|
|
118
118
|
if (result.exceptionDetails) {
|
|
119
|
-
const msg = result.exceptionDetails.exception?.description ||
|
|
120
|
-
result.exceptionDetails.text;
|
|
119
|
+
const msg = result.exceptionDetails.exception?.description || result.exceptionDetails.text;
|
|
121
120
|
throw new Error(`Extension eval error: ${msg}`);
|
|
122
121
|
}
|
|
123
122
|
return result.result.value;
|
|
@@ -163,7 +162,10 @@ export class TabGroupsClient {
|
|
|
163
162
|
if (Object.keys(updateProps).length > 0) {
|
|
164
163
|
await chrome.tabGroups.update(groupId, updateProps);
|
|
165
164
|
}
|
|
166
|
-
const
|
|
165
|
+
const enforced = await self.CometWindowPolicy.ensureOneGroupPerWindow(groupId, {
|
|
166
|
+
markChangedWindowManaged: true
|
|
167
|
+
});
|
|
168
|
+
const g = enforced?.group || (await chrome.tabGroups.get(groupId));
|
|
167
169
|
return {
|
|
168
170
|
groupId: g.id,
|
|
169
171
|
group: {
|
|
@@ -174,6 +176,22 @@ export class TabGroupsClient {
|
|
|
174
176
|
})()
|
|
175
177
|
`);
|
|
176
178
|
}
|
|
179
|
+
/** Create a managed browser window locked to the top display fullscreen policy. */
|
|
180
|
+
async createTopDisplayFullscreenWindowWithTab(url) {
|
|
181
|
+
return await this.evaluate(`
|
|
182
|
+
(async () => {
|
|
183
|
+
const win = await self.CometWindowPolicy.createTopDisplayFullscreenWindow({
|
|
184
|
+
url: ${JSON.stringify(url)}
|
|
185
|
+
});
|
|
186
|
+
const tab = win.tabs?.[0] || (await chrome.tabs.query({ windowId: win.id }))[0];
|
|
187
|
+
return {
|
|
188
|
+
tabId: tab.id,
|
|
189
|
+
windowId: win.id,
|
|
190
|
+
url: tab.url || tab.pendingUrl || ${JSON.stringify(url)}
|
|
191
|
+
};
|
|
192
|
+
})()
|
|
193
|
+
`);
|
|
194
|
+
}
|
|
177
195
|
/** Update an existing tab group's title, color, or collapsed state. */
|
|
178
196
|
async updateGroup(options) {
|
|
179
197
|
const props = [];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task Thread Aggregator — Phase A
|
|
3
|
+
*
|
|
4
|
+
* Reads all 5 local layers (lifecycle JSONL, session manifest, archive store,
|
|
5
|
+
* snapshots, alert log) and synthesises a CanonicalTaskThread for each known
|
|
6
|
+
* taskThreadId. Exposes the TaskThreadProvider interface so Phase B can swap
|
|
7
|
+
* the implementation for an equa-taskthreads core API client without touching
|
|
8
|
+
* any consumers (FR-040).
|
|
9
|
+
*
|
|
10
|
+
* Spec: specs/041-task-thread-sync/spec.md
|
|
11
|
+
* Plan: specs/041-task-thread-sync/plan.md §Layer Aggregator
|
|
12
|
+
*/
|
|
13
|
+
import { CanonicalStatus, CanonicalTaskThread } from "./task-thread-canonical.js";
|
|
14
|
+
/**
|
|
15
|
+
* The single interface all HTTP route handlers and extension-facing code depends
|
|
16
|
+
* on. Phase B replaces the LocalTaskThreadAggregator with a CoreAPITaskThreadProvider
|
|
17
|
+
* without changing any consumer code.
|
|
18
|
+
*/
|
|
19
|
+
export interface TaskThreadProvider {
|
|
20
|
+
listAll(): Promise<CanonicalTaskThread[]>;
|
|
21
|
+
get(id: string): Promise<CanonicalTaskThread | null>;
|
|
22
|
+
executeTransition(id: string, action: string, reason?: string): Promise<{
|
|
23
|
+
newStatus: CanonicalStatus;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
export declare class LocalTaskThreadAggregator implements TaskThreadProvider {
|
|
27
|
+
listAll(): Promise<CanonicalTaskThread[]>;
|
|
28
|
+
get(id: string): Promise<CanonicalTaskThread | null>;
|
|
29
|
+
executeTransition(id: string, action: string, reason?: string): Promise<{
|
|
30
|
+
newStatus: CanonicalStatus;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
export declare const aggregator: TaskThreadProvider;
|
|
34
|
+
//# sourceMappingURL=task-thread-aggregator.d.ts.map
|