@shawnowen/comet-mcp 2.3.0 → 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.
Files changed (85) hide show
  1. package/README.md +86 -19
  2. package/dist/alert-dispatcher.d.ts +23 -0
  3. package/dist/alert-dispatcher.js +101 -0
  4. package/dist/bound-session.d.ts +23 -0
  5. package/dist/bound-session.js +119 -0
  6. package/dist/bridge-config.d.ts +6 -0
  7. package/dist/bridge-config.js +78 -0
  8. package/dist/cdp-client.d.ts +40 -4
  9. package/dist/cdp-client.js +502 -155
  10. package/dist/comet-ai.d.ts +15 -0
  11. package/dist/comet-ai.js +114 -38
  12. package/dist/delegate-binding.d.ts +19 -0
  13. package/dist/delegate-binding.js +73 -0
  14. package/dist/discovery/capability-entry.d.ts +215 -0
  15. package/dist/discovery/capability-entry.js +13 -0
  16. package/dist/discovery/description-template.d.ts +40 -0
  17. package/dist/discovery/description-template.js +61 -0
  18. package/dist/discovery/golden-queries.fixture.d.ts +22 -0
  19. package/dist/discovery/golden-queries.fixture.js +137 -0
  20. package/dist/discovery/mcp-source.d.ts +38 -0
  21. package/dist/discovery/mcp-source.js +70 -0
  22. package/dist/discovery/metadata-completeness.d.ts +48 -0
  23. package/dist/discovery/metadata-completeness.js +83 -0
  24. package/dist/discovery/registry.d.ts +35 -0
  25. package/dist/discovery/registry.js +35 -0
  26. package/dist/discovery/safety.d.ts +44 -0
  27. package/dist/discovery/safety.js +59 -0
  28. package/dist/discovery/schema-validator.d.ts +36 -0
  29. package/dist/discovery/schema-validator.js +257 -0
  30. package/dist/discovery/source-error.d.ts +47 -0
  31. package/dist/discovery/source-error.js +95 -0
  32. package/dist/discovery/tool-meta.d.ts +41 -0
  33. package/dist/discovery/tool-meta.js +229 -0
  34. package/dist/discovery/virtual-tools.d.ts +20 -0
  35. package/dist/discovery/virtual-tools.js +69 -0
  36. package/dist/http-server.js +2067 -47
  37. package/dist/index.js +3163 -710
  38. package/dist/observer.d.ts +47 -0
  39. package/dist/observer.js +516 -0
  40. package/dist/session-registry.d.ts +57 -0
  41. package/dist/session-registry.js +500 -0
  42. package/dist/sidecar-artifacts.d.ts +49 -0
  43. package/dist/sidecar-artifacts.js +146 -0
  44. package/dist/snapshot-capture.d.ts +3 -0
  45. package/dist/snapshot-capture.js +91 -0
  46. package/dist/tab-group-archive.js +3 -1
  47. package/dist/tab-groups.d.ts +7 -0
  48. package/dist/tab-groups.js +21 -3
  49. package/dist/task-thread-aggregator.d.ts +34 -0
  50. package/dist/task-thread-aggregator.js +480 -0
  51. package/dist/task-thread-canonical.d.ts +142 -0
  52. package/dist/task-thread-canonical.js +116 -0
  53. package/dist/types.d.ts +237 -0
  54. package/dist/window-bindings.d.ts +112 -0
  55. package/dist/window-bindings.js +476 -0
  56. package/extension/background.js +1556 -300
  57. package/extension/icons/icon.svg +9 -0
  58. package/extension/icons/icon128.png +0 -0
  59. package/extension/icons/icon16.png +0 -0
  60. package/extension/icons/icon48.png +0 -0
  61. package/extension/manifest.json +19 -4
  62. package/extension/session-logic.js +2383 -0
  63. package/extension/session-manager.html +299 -0
  64. package/extension/sidepanel.css +5323 -528
  65. package/extension/sidepanel.html +282 -2
  66. package/extension/sidepanel.js +10075 -951
  67. package/extension/window-policy.js +162 -0
  68. package/package.json +10 -7
  69. package/vendor/lifecycle-mcp-adapter.mjs +103 -0
  70. package/vendor/lifecycle-metadata.mjs +252 -0
  71. package/vendor/readiness-report.mjs +742 -0
  72. package/dist/cdp-client.d.ts.map +0 -1
  73. package/dist/cdp-client.js.map +0 -1
  74. package/dist/comet-ai.d.ts.map +0 -1
  75. package/dist/comet-ai.js.map +0 -1
  76. package/dist/http-server.d.ts.map +0 -1
  77. package/dist/http-server.js.map +0 -1
  78. package/dist/index.d.ts.map +0 -1
  79. package/dist/index.js.map +0 -1
  80. package/dist/tab-group-archive.d.ts.map +0 -1
  81. package/dist/tab-group-archive.js.map +0 -1
  82. package/dist/tab-groups.d.ts.map +0 -1
  83. package/dist/tab-groups.js.map +0 -1
  84. package/dist/types.d.ts.map +0 -1
  85. package/dist/types.js.map +0 -1
@@ -0,0 +1,40 @@
1
+ /**
2
+ * description-template.ts
3
+ * R10 description template renderer (Spec 042, T031).
4
+ *
5
+ * Produces consistent, searchable descriptions for virtual MCP tool entries.
6
+ * Format: "<verb> <object> [<modifier>]. Source: <layer>. Safety: <class>. [multi-agent clause for CAUTION]"
7
+ *
8
+ * Constraints (from spec):
9
+ * - Min 24 chars, max 400 chars
10
+ * - CAUTION entries MUST include the cross-session warning phrase
11
+ */
12
+ import type { SafetyClass, SourceLayer } from "./capability-entry.js";
13
+ export declare const CAUTION_MULTI_AGENT_CLAUSE: string;
14
+ export interface DescriptionOptions {
15
+ /** Short verb phrase: e.g. "Capture a screenshot" */
16
+ verbPhrase: string;
17
+ /** Optional modifier appended after verbPhrase: e.g. "in this agent's tab" */
18
+ modifier?: string;
19
+ /** Source layer — appended as "Source: <layer>." */
20
+ sourceLayer: SourceLayer;
21
+ /** Safety class — appended as "Safety: <class>." */
22
+ safety: SafetyClass;
23
+ }
24
+ /**
25
+ * Render the R10 description for a capability entry.
26
+ * Returns a string between MIN_LENGTH and MAX_LENGTH characters.
27
+ * Throws if the rendered string is outside those bounds.
28
+ */
29
+ export declare function renderDescription(opts: DescriptionOptions): string;
30
+ /**
31
+ * Safe version — returns the string if valid, or an error-annotated fallback.
32
+ * Used when the verbPhrase is untrusted (e.g. from plugin YAML frontmatter).
33
+ */
34
+ export declare function renderDescriptionSafe(opts: DescriptionOptions, fallback?: string): string;
35
+ /**
36
+ * Render a CAUTION description with the mandatory multi-agent clause.
37
+ * Convenience wrapper for T033.
38
+ */
39
+ export declare function renderCautionDescription(verbPhrase: string, sourceLayer: SourceLayer, modifier?: string): string;
40
+ //# sourceMappingURL=description-template.d.ts.map
@@ -0,0 +1,61 @@
1
+ /**
2
+ * description-template.ts
3
+ * R10 description template renderer (Spec 042, T031).
4
+ *
5
+ * Produces consistent, searchable descriptions for virtual MCP tool entries.
6
+ * Format: "<verb> <object> [<modifier>]. Source: <layer>. Safety: <class>. [multi-agent clause for CAUTION]"
7
+ *
8
+ * Constraints (from spec):
9
+ * - Min 24 chars, max 400 chars
10
+ * - CAUTION entries MUST include the cross-session warning phrase
11
+ */
12
+ // Canonical cross-session warning for CAUTION tools.
13
+ // Must appear verbatim in every CAUTION entry description (tested in T029).
14
+ export const CAUTION_MULTI_AGENT_CLAUSE = "CAUTION: may have cross-session side effects — only use on your own session and tab group. " +
15
+ "Never close or modify browser resources you did not create.";
16
+ const MIN_LENGTH = 24;
17
+ const MAX_LENGTH = 400;
18
+ /**
19
+ * Render the R10 description for a capability entry.
20
+ * Returns a string between MIN_LENGTH and MAX_LENGTH characters.
21
+ * Throws if the rendered string is outside those bounds.
22
+ */
23
+ export function renderDescription(opts) {
24
+ const { verbPhrase, modifier, sourceLayer, safety } = opts;
25
+ let text = verbPhrase.trimEnd();
26
+ if (modifier)
27
+ text += " " + modifier.trim();
28
+ text += ". ";
29
+ text += `Source: ${sourceLayer}. Safety: ${safety}.`;
30
+ if (safety === "CAUTION") {
31
+ text += " " + CAUTION_MULTI_AGENT_CLAUSE;
32
+ }
33
+ if (text.length < MIN_LENGTH) {
34
+ throw new RangeError(`Description too short (${text.length} < ${MIN_LENGTH}): "${text}"`);
35
+ }
36
+ if (text.length > MAX_LENGTH) {
37
+ throw new RangeError(`Description too long (${text.length} > ${MAX_LENGTH}): "${text.slice(0, 80)}…"`);
38
+ }
39
+ return text;
40
+ }
41
+ /**
42
+ * Safe version — returns the string if valid, or an error-annotated fallback.
43
+ * Used when the verbPhrase is untrusted (e.g. from plugin YAML frontmatter).
44
+ */
45
+ export function renderDescriptionSafe(opts, fallback) {
46
+ try {
47
+ return renderDescription(opts);
48
+ }
49
+ catch {
50
+ const fb = fallback ?? `${opts.verbPhrase}. Source: ${opts.sourceLayer}. Safety: ${opts.safety}.`;
51
+ return fb.slice(0, MAX_LENGTH);
52
+ }
53
+ }
54
+ /**
55
+ * Render a CAUTION description with the mandatory multi-agent clause.
56
+ * Convenience wrapper for T033.
57
+ */
58
+ export function renderCautionDescription(verbPhrase, sourceLayer, modifier) {
59
+ return renderDescription({ verbPhrase, modifier, sourceLayer, safety: "CAUTION" });
60
+ }
61
+ //# sourceMappingURL=description-template.js.map
@@ -0,0 +1,22 @@
1
+ /**
2
+ * golden-queries.fixture.ts
3
+ * Hand-picked golden query set for US1 ToolSearch ranking tests (Spec 042, T025).
4
+ *
5
+ * Each entry describes a natural-language query an agent might issue plus the
6
+ * canonical tool name expected to appear in the top 5 ToolSearch results.
7
+ *
8
+ * Coverage targets: SC-002 (≥ 95% top-5 hit rate = 19/20 queries must hit).
9
+ * At least one query per safety class and per major capability area.
10
+ */
11
+ export interface GoldenQuery {
12
+ /** Natural language query the agent would type into ToolSearch */
13
+ query: string;
14
+ /** canonicalId of the entry that must appear in the top-5 results */
15
+ expectedCanonicalId: string;
16
+ /** Expected tool name for direct assertion */
17
+ expectedToolName: string;
18
+ /** Human note explaining why this query should resolve to this tool */
19
+ note: string;
20
+ }
21
+ export declare const GOLDEN_QUERIES: GoldenQuery[];
22
+ //# sourceMappingURL=golden-queries.fixture.d.ts.map
@@ -0,0 +1,137 @@
1
+ /**
2
+ * golden-queries.fixture.ts
3
+ * Hand-picked golden query set for US1 ToolSearch ranking tests (Spec 042, T025).
4
+ *
5
+ * Each entry describes a natural-language query an agent might issue plus the
6
+ * canonical tool name expected to appear in the top 5 ToolSearch results.
7
+ *
8
+ * Coverage targets: SC-002 (≥ 95% top-5 hit rate = 19/20 queries must hit).
9
+ * At least one query per safety class and per major capability area.
10
+ */
11
+ export const GOLDEN_QUERIES = [
12
+ // ── Observation / SAFE tools ─────────────────────────────────────────────
13
+ {
14
+ query: "observe browser status",
15
+ expectedCanonicalId: "comet-observe",
16
+ expectedToolName: "comet_observe",
17
+ note: "Primary observation tool — should rank #1 for status queries",
18
+ },
19
+ {
20
+ query: "health check browser extension",
21
+ expectedCanonicalId: "comet-observe",
22
+ expectedToolName: "comet_observe",
23
+ note: "Health check is a sub-action of comet_observe",
24
+ },
25
+ {
26
+ query: "peek at another agent tab",
27
+ expectedCanonicalId: "comet-peek",
28
+ expectedToolName: "comet_peek",
29
+ note: "Cross-agent read-only inspection without affecting the tab",
30
+ },
31
+ {
32
+ query: "inspect tab screenshot cross agent",
33
+ expectedCanonicalId: "comet-peek",
34
+ expectedToolName: "comet_peek",
35
+ note: "comet_peek action=screenshot for another agent's tab",
36
+ },
37
+ {
38
+ query: "list all tab groups",
39
+ expectedCanonicalId: "comet-tab-groups",
40
+ expectedToolName: "comet_tab_groups",
41
+ note: "Tab group management including list action",
42
+ },
43
+ {
44
+ query: "equabot task thread running agents",
45
+ expectedCanonicalId: "comet-task-status",
46
+ expectedToolName: "comet_task_status",
47
+ note: "SAFE status overview tool for orchestrator agents",
48
+ },
49
+ // ── Session tools (SESSION class) ────────────────────────────────────────
50
+ {
51
+ query: "connect to Comet browser start session",
52
+ expectedCanonicalId: "comet-connect",
53
+ expectedToolName: "comet_connect",
54
+ note: "Entry-point for all browser work — must rank first for connect queries",
55
+ },
56
+ {
57
+ query: "take a screenshot of current page",
58
+ expectedCanonicalId: "comet-screenshot",
59
+ expectedToolName: "comet_screenshot",
60
+ note: "Explicit screenshot request in the session context",
61
+ },
62
+ {
63
+ query: "full page screenshot dark mode",
64
+ expectedCanonicalId: "comet-screenshot",
65
+ expectedToolName: "comet_screenshot",
66
+ note: "Natural-language screenshot variant — must appear in top 5",
67
+ },
68
+ {
69
+ query: "navigate to url open page",
70
+ expectedCanonicalId: "comet-navigate",
71
+ expectedToolName: "comet_navigate",
72
+ note: "Explicit navigate request",
73
+ },
74
+ {
75
+ query: "read page content extract text markdown",
76
+ expectedCanonicalId: "comet-read-page",
77
+ expectedToolName: "comet_read_page",
78
+ note: "Content extraction from the current tab",
79
+ },
80
+ {
81
+ query: "click button fill form interact",
82
+ expectedCanonicalId: "comet-interact",
83
+ expectedToolName: "comet_interact",
84
+ note: "DOM interaction — click/type/fill queries",
85
+ },
86
+ {
87
+ query: "ask perplexity research question ai",
88
+ expectedCanonicalId: "comet-ask",
89
+ expectedToolName: "comet_ask",
90
+ note: "Primary research/AI-prompt tool",
91
+ },
92
+ {
93
+ query: "generate pdf print page document",
94
+ expectedCanonicalId: "comet-pdf",
95
+ expectedToolName: "comet_pdf",
96
+ note: "PDF export from current tab",
97
+ },
98
+ {
99
+ query: "scrape extract table structured data",
100
+ expectedCanonicalId: "comet-scrape",
101
+ expectedToolName: "comet_scrape",
102
+ note: "Structured data extraction",
103
+ },
104
+ {
105
+ query: "capture network requests api traffic",
106
+ expectedCanonicalId: "comet-network",
107
+ expectedToolName: "comet_network",
108
+ note: "Network request monitoring",
109
+ },
110
+ {
111
+ query: "run automation workflow multi step",
112
+ expectedCanonicalId: "comet-automate",
113
+ expectedToolName: "comet_automate",
114
+ note: "Multi-step automation playbook",
115
+ },
116
+ // ── Lifecycle tools ───────────────────────────────────────────────────────
117
+ {
118
+ query: "start task thread lifecycle register run",
119
+ expectedCanonicalId: "comet-lifecycle-start",
120
+ expectedToolName: "comet_lifecycle_start",
121
+ note: "Lifecycle start — agent registers a new task run",
122
+ },
123
+ {
124
+ query: "mark task complete finish run",
125
+ expectedCanonicalId: "comet-lifecycle-complete",
126
+ expectedToolName: "comet_lifecycle_complete",
127
+ note: "Terminal lifecycle action for success",
128
+ },
129
+ // ── CAUTION tools ─────────────────────────────────────────────────────────
130
+ {
131
+ query: "delegate task spawn sub-agent equabot",
132
+ expectedCanonicalId: "comet-delegate",
133
+ expectedToolName: "comet_delegate",
134
+ note: "CAUTION: spawns a new agent — must appear with the CAUTION warning",
135
+ },
136
+ ];
137
+ //# sourceMappingURL=golden-queries.fixture.js.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * mcp-source.ts
3
+ * MCP source reader for the Comet Discovery Layer (Spec 042, T020).
4
+ *
5
+ * Reads the native tool metadata catalog (tool-meta.ts) and the TOOLS
6
+ * array from the running MCP server (imported via tool-registry.ts to
7
+ * avoid circular imports), then produces CapabilityEntry[] with
8
+ * sourceLayer: "mcp" for every registered native tool.
9
+ *
10
+ * Tools in the TOOLS array that have no matching entry in TOOL_META_MAP
11
+ * are skipped with a SourceError (warn-and-continue, FR-008a).
12
+ */
13
+ import type { CapabilityEntry, SourceError } from "./capability-entry.js";
14
+ /**
15
+ * Minimal shape of a native MCP tool definition.
16
+ * Matches the Tool type in index.ts without importing it (avoids circular dep).
17
+ */
18
+ interface NativeTool {
19
+ name: string;
20
+ description?: string;
21
+ inputSchema: Record<string, unknown>;
22
+ }
23
+ /**
24
+ * Read the native MCP tool source and return CapabilityEntry[].
25
+ *
26
+ * Accepts the TOOLS array as an argument so tests can inject fixtures
27
+ * without touching index.ts (FR-009).
28
+ *
29
+ * @param tools The TOOLS array from index.ts (or a fixture subset for tests).
30
+ * @returns { entries, errors } — entries for every tool in TOOL_META_MAP;
31
+ * errors for tools missing from the catalog.
32
+ */
33
+ export declare function readMcpSource(tools: NativeTool[]): {
34
+ entries: CapabilityEntry[];
35
+ errors: SourceError[];
36
+ };
37
+ export {};
38
+ //# sourceMappingURL=mcp-source.d.ts.map
@@ -0,0 +1,70 @@
1
+ /**
2
+ * mcp-source.ts
3
+ * MCP source reader for the Comet Discovery Layer (Spec 042, T020).
4
+ *
5
+ * Reads the native tool metadata catalog (tool-meta.ts) and the TOOLS
6
+ * array from the running MCP server (imported via tool-registry.ts to
7
+ * avoid circular imports), then produces CapabilityEntry[] with
8
+ * sourceLayer: "mcp" for every registered native tool.
9
+ *
10
+ * Tools in the TOOLS array that have no matching entry in TOOL_META_MAP
11
+ * are skipped with a SourceError (warn-and-continue, FR-008a).
12
+ */
13
+ import { errorFromException } from "./source-error.js";
14
+ import { assertSafety } from "./safety.js";
15
+ import { TOOL_META_MAP } from "./tool-meta.js";
16
+ // ---------------------------------------------------------------------------
17
+ // Source reader
18
+ // ---------------------------------------------------------------------------
19
+ /**
20
+ * Read the native MCP tool source and return CapabilityEntry[].
21
+ *
22
+ * Accepts the TOOLS array as an argument so tests can inject fixtures
23
+ * without touching index.ts (FR-009).
24
+ *
25
+ * @param tools The TOOLS array from index.ts (or a fixture subset for tests).
26
+ * @returns { entries, errors } — entries for every tool in TOOL_META_MAP;
27
+ * errors for tools missing from the catalog.
28
+ */
29
+ export function readMcpSource(tools) {
30
+ const entries = [];
31
+ const errors = [];
32
+ for (const tool of tools) {
33
+ const meta = TOOL_META_MAP.get(tool.name);
34
+ if (!meta) {
35
+ errors.push({
36
+ source: "mcp",
37
+ reason: `Tool "${tool.name}" has no entry in TOOL_META_MAP — add one to tool-meta.ts`,
38
+ });
39
+ continue;
40
+ }
41
+ // Validate safety class (should always pass for hand-authored catalog)
42
+ let safety;
43
+ try {
44
+ safety = assertSafety(meta.safety, tool.name);
45
+ }
46
+ catch (err) {
47
+ errors.push(errorFromException("mcp", err));
48
+ continue;
49
+ }
50
+ const entry = {
51
+ name: tool.name,
52
+ sourceLayer: "mcp",
53
+ sourcePath: `comet-mcp/src/index.ts#tool_${tool.name}`,
54
+ canonicalId: meta.canonicalId,
55
+ description: meta.description,
56
+ intentKeywords: meta.intentKeywords,
57
+ safety,
58
+ preconditions: meta.preconditions,
59
+ argsSchema: tool.inputSchema,
60
+ humanOnly: false,
61
+ invocation: { kind: "native", toolName: tool.name },
62
+ crossRef: null, // singletons until dedup.ts runs (T043)
63
+ recommended: true, // all native entries are recommended until dedup.ts runs
64
+ alternativeLabel: null,
65
+ };
66
+ entries.push(entry);
67
+ }
68
+ return { entries, errors };
69
+ }
70
+ //# sourceMappingURL=mcp-source.js.map
@@ -0,0 +1,48 @@
1
+ /**
2
+ * metadata-completeness.ts
3
+ * Metadata completeness validator for the Comet Discovery Layer (Spec 042, T032).
4
+ *
5
+ * Walks a CapabilityEntry[] and returns a MetadataCompletenessReport with:
6
+ * - completeness ratio (1.0 = SC-003 satisfied)
7
+ * - per-entry gap list for drift-check and test assertion
8
+ *
9
+ * Used by:
10
+ * - metadata-completeness.test.ts (T028)
11
+ * - coverage.ts (US4, T054) for DriftReport.safetyGaps
12
+ */
13
+ import type { CapabilityEntry } from "./capability-entry.js";
14
+ export interface MetadataGap {
15
+ /** Entry name (tool name / plugin slug / extension slug). */
16
+ name: string;
17
+ /** Which field is incomplete. */
18
+ field: "safety" | "sourceLayer" | "preconditions" | "description" | "canonicalId" | "intentKeywords";
19
+ /** Human-readable reason. */
20
+ reason: string;
21
+ }
22
+ export interface MetadataCompletenessReport {
23
+ /**
24
+ * Ratio of entries with zero gaps to total entries.
25
+ * 0.0 (all entries gapped) to 1.0 (all entries complete).
26
+ * 1.0 = SC-003 satisfied.
27
+ */
28
+ completeness: number;
29
+ /** All gaps found across all entries. */
30
+ gaps: MetadataGap[];
31
+ /** How many entries were checked. */
32
+ totalChecked: number;
33
+ /** How many entries had zero gaps. */
34
+ totalComplete: number;
35
+ }
36
+ /**
37
+ * Validate metadata completeness for a list of CapabilityEntry objects.
38
+ * Returns the completeness ratio and all gaps found.
39
+ *
40
+ * @param entries The composed registry entries to validate.
41
+ */
42
+ export declare function checkMetadataCompleteness(entries: CapabilityEntry[]): MetadataCompletenessReport;
43
+ /**
44
+ * Returns the names of entries missing their safety classification.
45
+ * Used by coverage.ts to populate DriftReport.safetyGaps.
46
+ */
47
+ export declare function getSafetyGaps(entries: CapabilityEntry[]): string[];
48
+ //# sourceMappingURL=metadata-completeness.d.ts.map
@@ -0,0 +1,83 @@
1
+ /**
2
+ * metadata-completeness.ts
3
+ * Metadata completeness validator for the Comet Discovery Layer (Spec 042, T032).
4
+ *
5
+ * Walks a CapabilityEntry[] and returns a MetadataCompletenessReport with:
6
+ * - completeness ratio (1.0 = SC-003 satisfied)
7
+ * - per-entry gap list for drift-check and test assertion
8
+ *
9
+ * Used by:
10
+ * - metadata-completeness.test.ts (T028)
11
+ * - coverage.ts (US4, T054) for DriftReport.safetyGaps
12
+ */
13
+ // ---------------------------------------------------------------------------
14
+ // Validator
15
+ // ---------------------------------------------------------------------------
16
+ /**
17
+ * Validate metadata completeness for a list of CapabilityEntry objects.
18
+ * Returns the completeness ratio and all gaps found.
19
+ *
20
+ * @param entries The composed registry entries to validate.
21
+ */
22
+ export function checkMetadataCompleteness(entries) {
23
+ const gaps = [];
24
+ let totalComplete = 0;
25
+ for (const entry of entries) {
26
+ const entryGaps = [];
27
+ // safety — must be a non-empty SAFE|SESSION|CAUTION value
28
+ if (!entry.safety) {
29
+ entryGaps.push({ name: entry.name, field: "safety", reason: "missing or empty" });
30
+ }
31
+ // sourceLayer — must be non-empty
32
+ if (!entry.sourceLayer) {
33
+ entryGaps.push({ name: entry.name, field: "sourceLayer", reason: "missing or empty" });
34
+ }
35
+ // preconditions — must be an array (may be empty)
36
+ if (!Array.isArray(entry.preconditions)) {
37
+ entryGaps.push({
38
+ name: entry.name,
39
+ field: "preconditions",
40
+ reason: `not an array (got ${typeof entry.preconditions})`,
41
+ });
42
+ }
43
+ // description — must be non-empty and at least 24 chars
44
+ if (!entry.description || entry.description.length < 24) {
45
+ entryGaps.push({
46
+ name: entry.name,
47
+ field: "description",
48
+ reason: `too short (${entry.description?.length ?? 0} chars, min 24)`,
49
+ });
50
+ }
51
+ // canonicalId — must be non-empty
52
+ if (!entry.canonicalId) {
53
+ entryGaps.push({ name: entry.name, field: "canonicalId", reason: "missing or empty" });
54
+ }
55
+ // intentKeywords — must be an array with ≥ 3 items
56
+ if (!Array.isArray(entry.intentKeywords) || entry.intentKeywords.length < 3) {
57
+ entryGaps.push({
58
+ name: entry.name,
59
+ field: "intentKeywords",
60
+ reason: `fewer than 3 keywords (got ${entry.intentKeywords?.length ?? 0})`,
61
+ });
62
+ }
63
+ gaps.push(...entryGaps);
64
+ if (entryGaps.length === 0)
65
+ totalComplete++;
66
+ }
67
+ const totalChecked = entries.length;
68
+ const completeness = totalChecked === 0 ? 1.0 : totalComplete / totalChecked;
69
+ return { completeness, gaps, totalChecked, totalComplete };
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // Convenience: extract safetyGaps for DriftReport (T054)
73
+ // ---------------------------------------------------------------------------
74
+ /**
75
+ * Returns the names of entries missing their safety classification.
76
+ * Used by coverage.ts to populate DriftReport.safetyGaps.
77
+ */
78
+ export function getSafetyGaps(entries) {
79
+ return entries
80
+ .filter((e) => !e.safety)
81
+ .map((e) => e.name);
82
+ }
83
+ //# sourceMappingURL=metadata-completeness.js.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * registry.ts
3
+ * Registry composer for the Comet Discovery Layer (Spec 042, T010/T021/T044).
4
+ *
5
+ * T010: Stub — returned empty arrays (proved the integration point compiled).
6
+ * T021: Wire MCP source reader — reads native tools and returns CapabilityEntry[].
7
+ * T044: Will add plugin + extension sources and dedup (US3, future).
8
+ */
9
+ import type { CapabilityEntry, SourceError } from "./capability-entry.js";
10
+ export interface RegistryResult {
11
+ entries: CapabilityEntry[];
12
+ errors: SourceError[];
13
+ }
14
+ /**
15
+ * Minimal shape of a native MCP tool definition.
16
+ * Passed in by index.ts to avoid a circular import (index.ts → registry.ts
17
+ * is the existing direction; registry.ts must NOT import index.ts).
18
+ */
19
+ export interface NativeToolSpec {
20
+ name: string;
21
+ description?: string;
22
+ inputSchema: Record<string, unknown>;
23
+ }
24
+ /**
25
+ * Compose the full capability registry from all available canonical sources.
26
+ *
27
+ * @param nativeTools The TOOLS array from index.ts (injected to avoid circular
28
+ * imports). If omitted, mcp source returns empty (tests only).
29
+ *
30
+ * Sources wired:
31
+ * T021 — MCP native tools via mcp-source.ts (US1)
32
+ * T044 — plugin + extension sources + dedup (US3, not yet wired)
33
+ */
34
+ export declare function composeRegistry(nativeTools?: NativeToolSpec[]): Promise<RegistryResult>;
35
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * registry.ts
3
+ * Registry composer for the Comet Discovery Layer (Spec 042, T010/T021/T044).
4
+ *
5
+ * T010: Stub — returned empty arrays (proved the integration point compiled).
6
+ * T021: Wire MCP source reader — reads native tools and returns CapabilityEntry[].
7
+ * T044: Will add plugin + extension sources and dedup (US3, future).
8
+ */
9
+ import { readMcpSource } from "./mcp-source.js";
10
+ import { emitSourceWarnings } from "./source-error.js";
11
+ /**
12
+ * Compose the full capability registry from all available canonical sources.
13
+ *
14
+ * @param nativeTools The TOOLS array from index.ts (injected to avoid circular
15
+ * imports). If omitted, mcp source returns empty (tests only).
16
+ *
17
+ * Sources wired:
18
+ * T021 — MCP native tools via mcp-source.ts (US1)
19
+ * T044 — plugin + extension sources + dedup (US3, not yet wired)
20
+ */
21
+ export async function composeRegistry(nativeTools = []) {
22
+ const allEntries = [];
23
+ const allErrors = [];
24
+ // ── T021: MCP native source ──────────────────────────────────────────────
25
+ const { entries: mcpEntries, errors: mcpErrors } = readMcpSource(nativeTools);
26
+ allEntries.push(...mcpEntries);
27
+ allErrors.push(...mcpErrors);
28
+ // Emit any source-level warnings to stderr (FR-008a / R7)
29
+ emitSourceWarnings(allErrors);
30
+ // TODO T044: call plugin-source.ts + extension-source.ts + dedup.ts here.
31
+ // Deterministic ordering by canonicalId (consistent across restarts)
32
+ allEntries.sort((a, b) => a.canonicalId.localeCompare(b.canonicalId));
33
+ return { entries: allEntries, errors: allErrors };
34
+ }
35
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1,44 @@
1
+ /**
2
+ * safety.ts
3
+ * Safety taxonomy loader for the Comet Discovery Layer (Spec 042, T007).
4
+ *
5
+ * Reads the three valid safety classes (SAFE | SESSION | CAUTION) from
6
+ * docs/TOOL-SAFETY-REFERENCE.md as the canonical authority. Exports a
7
+ * validator that rejects any value outside the taxonomy at runtime.
8
+ *
9
+ * This module deliberately does NOT import the taxonomy from TOOL-SAFETY-REFERENCE.md
10
+ * at file-read time (the doc is prose, not machine-readable JSON). Instead we
11
+ * hard-code the three classes here and note the canonical source in JSDoc so
12
+ * T061 can add a pointer from the doc back to this file.
13
+ */
14
+ import type { SafetyClass } from "./capability-entry.js";
15
+ /**
16
+ * The three valid safety classes.
17
+ * Canonical authority: docs/TOOL-SAFETY-REFERENCE.md
18
+ *
19
+ * SAFE — Read-only, zero side effects, no active session required.
20
+ * Examples: comet_observe, comet_peek, comet_tab_groups(action=list).
21
+ * SESSION — Requires an active Comet CDP session (comet_connect first).
22
+ * Scoped to the calling agent's own tab group.
23
+ * Examples: comet_screenshot, comet_read_page, comet_navigate.
24
+ * CAUTION — Cross-session side effects possible; can modify shared browser state.
25
+ * Must carry an explicit multi-agent rule reminder in its description.
26
+ * Examples: comet_stop, comet_automate (when interacting across groups).
27
+ */
28
+ export declare const VALID_SAFETY_CLASSES: ReadonlySet<SafetyClass>;
29
+ /**
30
+ * Assert that `value` is a valid SafetyClass.
31
+ * Throws a descriptive TypeError if not.
32
+ * Used by source readers to reject entries missing or misconfigured safety.
33
+ *
34
+ * @param value - The candidate safety string from a source definition.
35
+ * @param context - Optional label (tool name, file path) for error messages.
36
+ * @returns The validated SafetyClass.
37
+ */
38
+ export declare function assertSafety(value: string, context?: string): SafetyClass;
39
+ /**
40
+ * Safe version of assertSafety — returns null instead of throwing.
41
+ * Useful when the caller wants to route errors through SourceError rather than throw.
42
+ */
43
+ export declare function parseSafety(value: unknown): SafetyClass | null;
44
+ //# sourceMappingURL=safety.d.ts.map