@jami-studio/pinpoint 0.1.12
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/.agents/skills/pinpoint/SKILL.md +77 -0
- package/README.md +412 -0
- package/dist/agent-context-HBCZ4MBN.js +13 -0
- package/dist/agent-context-HBCZ4MBN.js.map +1 -0
- package/dist/chunk-B7TY4FPP.js +569 -0
- package/dist/chunk-B7TY4FPP.js.map +1 -0
- package/dist/chunk-CGJZ7BOM.js +88 -0
- package/dist/chunk-CGJZ7BOM.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-HAEYE6KB.js +25 -0
- package/dist/chunk-HAEYE6KB.js.map +1 -0
- package/dist/chunk-J5PXKVTM.js +53 -0
- package/dist/chunk-J5PXKVTM.js.map +1 -0
- package/dist/chunk-XBX2J7WU.js +94 -0
- package/dist/chunk-XBX2J7WU.js.map +1 -0
- package/dist/chunk-ZW7IO3EW.js +4927 -0
- package/dist/chunk-ZW7IO3EW.js.map +1 -0
- package/dist/cli.js +71 -0
- package/dist/cli.js.map +1 -0
- package/dist/formatter-CR4COA5Z.js +8 -0
- package/dist/formatter-CR4COA5Z.js.map +1 -0
- package/dist/index-NvFcZ4SO.d.ts +200 -0
- package/dist/index.browser.d.ts +377 -0
- package/dist/index.browser.js +620 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.js +936 -0
- package/dist/index.js.map +1 -0
- package/dist/open-file-WR2JHI4P.js +8 -0
- package/dist/open-file-WR2JHI4P.js.map +1 -0
- package/dist/primitives/index.js +28 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/react.d.ts +23 -0
- package/dist/react.js +20 -0
- package/dist/react.js.map +1 -0
- package/dist/server/index.js +457 -0
- package/dist/server/index.js.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +88 -0
- package/src/scripts/create-pin.ts +43 -0
- package/src/scripts/delete-pin.ts +16 -0
- package/src/scripts/get-pins.ts +36 -0
- package/src/scripts/list-sessions.ts +33 -0
- package/src/scripts/resolve-pin.ts +27 -0
- package/src/scripts/run.ts +8 -0
- package/src/scripts/update-pin.ts +32 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import { existsSync, mkdirSync, cpSync, readdirSync } from "fs";
|
|
5
|
+
import { resolve, dirname, join } from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
var command = process.argv[2];
|
|
9
|
+
if (command === "init") {
|
|
10
|
+
init();
|
|
11
|
+
} else {
|
|
12
|
+
console.log("Usage: npx @agent-native/pinpoint@latest init");
|
|
13
|
+
console.log("");
|
|
14
|
+
console.log("Commands:");
|
|
15
|
+
console.log(" init Copy agent scripts and skill to your project");
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
function init() {
|
|
19
|
+
const projectRoot = process.cwd();
|
|
20
|
+
const scriptsSource = resolve(__dirname, "../src/scripts");
|
|
21
|
+
const scriptsDest = resolve(projectRoot, "scripts");
|
|
22
|
+
if (!existsSync(scriptsDest)) {
|
|
23
|
+
mkdirSync(scriptsDest, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
const scriptFiles = readdirSync(scriptsSource).filter(
|
|
26
|
+
(f) => f.endsWith(".ts")
|
|
27
|
+
);
|
|
28
|
+
let copiedScripts = 0;
|
|
29
|
+
for (const file of scriptFiles) {
|
|
30
|
+
const dest = join(scriptsDest, file);
|
|
31
|
+
if (existsSync(dest)) {
|
|
32
|
+
console.log(` skip scripts/${file} (already exists)`);
|
|
33
|
+
} else {
|
|
34
|
+
cpSync(join(scriptsSource, file), dest);
|
|
35
|
+
console.log(` added scripts/${file}`);
|
|
36
|
+
copiedScripts++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const skillSource = resolve(__dirname, "../.agents/skills/pinpoint");
|
|
40
|
+
const skillDest = resolve(projectRoot, ".agents/skills/pinpoint");
|
|
41
|
+
if (existsSync(skillSource)) {
|
|
42
|
+
if (!existsSync(skillDest)) {
|
|
43
|
+
mkdirSync(skillDest, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
const skillFile = join(skillSource, "SKILL.md");
|
|
46
|
+
const skillDestFile = join(skillDest, "SKILL.md");
|
|
47
|
+
if (existsSync(skillFile)) {
|
|
48
|
+
if (existsSync(skillDestFile)) {
|
|
49
|
+
console.log(
|
|
50
|
+
" skip .agents/skills/pinpoint/SKILL.md (already exists)"
|
|
51
|
+
);
|
|
52
|
+
} else {
|
|
53
|
+
cpSync(skillFile, skillDestFile);
|
|
54
|
+
console.log(" added .agents/skills/pinpoint/SKILL.md");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
console.log("");
|
|
59
|
+
console.log(
|
|
60
|
+
copiedScripts > 0 ? "Pinpoint initialized. Agent scripts are in scripts/." : "Pinpoint already initialized. No new files copied."
|
|
61
|
+
);
|
|
62
|
+
console.log("");
|
|
63
|
+
console.log("Next steps:");
|
|
64
|
+
console.log(
|
|
65
|
+
" 1. Add <Pinpoint /> to your client: import { Pinpoint } from '@agent-native/pinpoint/react'"
|
|
66
|
+
);
|
|
67
|
+
console.log(
|
|
68
|
+
' 2. Add middleware to your server: app.use("/api/pins", pagePinRoutes())'
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\r\n// @agent-native/pinpoint — CLI for project setup\r\n// MIT License\r\n//\r\n// Usage: npx @agent-native/pinpoint@latest init\r\n\r\nimport { existsSync, mkdirSync, cpSync, readdirSync } from \"node:fs\";\r\nimport { resolve, dirname, join } from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\n\r\nconst __dirname = dirname(fileURLToPath(import.meta.url));\r\nconst command = process.argv[2];\r\n\r\nif (command === \"init\") {\r\n init();\r\n} else {\r\n console.log(\"Usage: npx @agent-native/pinpoint@latest init\");\r\n console.log(\"\");\r\n console.log(\"Commands:\");\r\n console.log(\" init Copy agent scripts and skill to your project\");\r\n process.exit(0);\r\n}\r\n\r\nfunction init() {\r\n const projectRoot = process.cwd();\r\n\r\n // 1. Copy agent scripts to scripts/\r\n const scriptsSource = resolve(__dirname, \"../src/scripts\");\r\n const scriptsDest = resolve(projectRoot, \"scripts\");\r\n\r\n if (!existsSync(scriptsDest)) {\r\n mkdirSync(scriptsDest, { recursive: true });\r\n }\r\n\r\n const scriptFiles = readdirSync(scriptsSource).filter((f) =>\r\n f.endsWith(\".ts\"),\r\n );\r\n let copiedScripts = 0;\r\n\r\n for (const file of scriptFiles) {\r\n const dest = join(scriptsDest, file);\r\n if (existsSync(dest)) {\r\n console.log(` skip scripts/${file} (already exists)`);\r\n } else {\r\n cpSync(join(scriptsSource, file), dest);\r\n console.log(` added scripts/${file}`);\r\n copiedScripts++;\r\n }\r\n }\r\n\r\n // 2. Copy agent skill if .agents/ directory pattern exists\r\n const skillSource = resolve(__dirname, \"../.agents/skills/pinpoint\");\r\n const skillDest = resolve(projectRoot, \".agents/skills/pinpoint\");\r\n\r\n if (existsSync(skillSource)) {\r\n if (!existsSync(skillDest)) {\r\n mkdirSync(skillDest, { recursive: true });\r\n }\r\n const skillFile = join(skillSource, \"SKILL.md\");\r\n const skillDestFile = join(skillDest, \"SKILL.md\");\r\n if (existsSync(skillFile)) {\r\n if (existsSync(skillDestFile)) {\r\n console.log(\r\n \" skip .agents/skills/pinpoint/SKILL.md (already exists)\",\r\n );\r\n } else {\r\n cpSync(skillFile, skillDestFile);\r\n console.log(\" added .agents/skills/pinpoint/SKILL.md\");\r\n }\r\n }\r\n }\r\n\r\n console.log(\"\");\r\n console.log(\r\n copiedScripts > 0\r\n ? \"Pinpoint initialized. Agent scripts are in scripts/.\"\r\n : \"Pinpoint already initialized. No new files copied.\",\r\n );\r\n console.log(\"\");\r\n console.log(\"Next steps:\");\r\n console.log(\r\n \" 1. Add <Pinpoint /> to your client: import { Pinpoint } from '@agent-native/pinpoint/react'\",\r\n );\r\n console.log(\r\n ' 2. Add middleware to your server: app.use(\"/api/pins\", pagePinRoutes())',\r\n );\r\n}\r\n"],"mappings":";;;AAMA,SAAS,YAAY,WAAW,QAAQ,mBAAmB;AAC3D,SAAS,SAAS,SAAS,YAAY;AACvC,SAAS,qBAAqB;AAE9B,IAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,IAAM,UAAU,QAAQ,KAAK,CAAC;AAE9B,IAAI,YAAY,QAAQ;AACtB,OAAK;AACP,OAAO;AACL,UAAQ,IAAI,+CAA+C;AAC3D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,WAAW;AACvB,UAAQ,IAAI,wDAAwD;AACpE,UAAQ,KAAK,CAAC;AAChB;AAEA,SAAS,OAAO;AACd,QAAM,cAAc,QAAQ,IAAI;AAGhC,QAAM,gBAAgB,QAAQ,WAAW,gBAAgB;AACzD,QAAM,cAAc,QAAQ,aAAa,SAAS;AAElD,MAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,cAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EAC5C;AAEA,QAAM,cAAc,YAAY,aAAa,EAAE;AAAA,IAAO,CAAC,MACrD,EAAE,SAAS,KAAK;AAAA,EAClB;AACA,MAAI,gBAAgB;AAEpB,aAAW,QAAQ,aAAa;AAC9B,UAAM,OAAO,KAAK,aAAa,IAAI;AACnC,QAAI,WAAW,IAAI,GAAG;AACpB,cAAQ,IAAI,mBAAmB,IAAI,mBAAmB;AAAA,IACxD,OAAO;AACL,aAAO,KAAK,eAAe,IAAI,GAAG,IAAI;AACtC,cAAQ,IAAI,mBAAmB,IAAI,EAAE;AACrC;AAAA,IACF;AAAA,EACF;AAGA,QAAM,cAAc,QAAQ,WAAW,4BAA4B;AACnE,QAAM,YAAY,QAAQ,aAAa,yBAAyB;AAEhE,MAAI,WAAW,WAAW,GAAG;AAC3B,QAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,gBAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IAC1C;AACA,UAAM,YAAY,KAAK,aAAa,UAAU;AAC9C,UAAM,gBAAgB,KAAK,WAAW,UAAU;AAChD,QAAI,WAAW,SAAS,GAAG;AACzB,UAAI,WAAW,aAAa,GAAG;AAC7B,gBAAQ;AAAA,UACN;AAAA,QACF;AAAA,MACF,OAAO;AACL,eAAO,WAAW,aAAa;AAC/B,gBAAQ,IAAI,0CAA0C;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ;AAAA,IACN,gBAAgB,IACZ,yDACA;AAAA,EACN;AACA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa;AACzB,UAAQ;AAAA,IACN;AAAA,EACF;AACA,UAAQ;AAAA,IACN;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
type PinStatus = "open" | "acknowledged" | "resolved" | "dismissed";
|
|
2
|
+
type DrawToolType = "freehand" | "arrow" | "circle" | "rect" | "text";
|
|
3
|
+
interface DrawStroke {
|
|
4
|
+
points: {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
}[];
|
|
8
|
+
color: string;
|
|
9
|
+
lineWidth: number;
|
|
10
|
+
type: "freehand" | "arrow" | "circle" | "rect";
|
|
11
|
+
}
|
|
12
|
+
interface TextNote {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
text: string;
|
|
16
|
+
color: string;
|
|
17
|
+
}
|
|
18
|
+
interface QueuedAnnotation {
|
|
19
|
+
id: string;
|
|
20
|
+
pin?: Pin;
|
|
21
|
+
drawings?: DrawStroke[];
|
|
22
|
+
textNotes?: TextNote[];
|
|
23
|
+
timestamp: string;
|
|
24
|
+
}
|
|
25
|
+
interface AgentOutput {
|
|
26
|
+
message: string;
|
|
27
|
+
context: string;
|
|
28
|
+
submit?: boolean;
|
|
29
|
+
}
|
|
30
|
+
type ToolbarMode = "select" | "draw" | "queue";
|
|
31
|
+
interface Pin {
|
|
32
|
+
id: string;
|
|
33
|
+
pageUrl: string;
|
|
34
|
+
createdAt: string;
|
|
35
|
+
updatedAt: string;
|
|
36
|
+
author?: string;
|
|
37
|
+
comment: string;
|
|
38
|
+
element: ElementInfo;
|
|
39
|
+
framework?: FrameworkInfo;
|
|
40
|
+
status: {
|
|
41
|
+
state: PinStatus;
|
|
42
|
+
changedAt: string;
|
|
43
|
+
changedBy?: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
interface ElementInfo {
|
|
47
|
+
tagName: string;
|
|
48
|
+
id?: string;
|
|
49
|
+
classNames: string[];
|
|
50
|
+
selector: string;
|
|
51
|
+
textContent?: string;
|
|
52
|
+
boundingRect: {
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
width: number;
|
|
56
|
+
height: number;
|
|
57
|
+
};
|
|
58
|
+
computedStyles?: Record<string, string>;
|
|
59
|
+
ariaAttributes?: Record<string, string>;
|
|
60
|
+
dataAttributes?: Record<string, string>;
|
|
61
|
+
domPath?: string;
|
|
62
|
+
}
|
|
63
|
+
interface FrameworkInfo {
|
|
64
|
+
framework: string;
|
|
65
|
+
componentPath: string;
|
|
66
|
+
sourceFile?: string;
|
|
67
|
+
frameworkVersion?: string;
|
|
68
|
+
}
|
|
69
|
+
interface ElementContext {
|
|
70
|
+
element: ElementInfo;
|
|
71
|
+
framework?: FrameworkInfo;
|
|
72
|
+
htmlSnippet: string;
|
|
73
|
+
cssSelector: string;
|
|
74
|
+
computedStyles: Record<string, string>;
|
|
75
|
+
}
|
|
76
|
+
interface ComponentInfo {
|
|
77
|
+
name: string;
|
|
78
|
+
displayName?: string;
|
|
79
|
+
filePath?: string;
|
|
80
|
+
lineNumber?: number;
|
|
81
|
+
props?: Record<string, unknown>;
|
|
82
|
+
}
|
|
83
|
+
interface SourceLocation {
|
|
84
|
+
file: string;
|
|
85
|
+
line?: number;
|
|
86
|
+
column?: number;
|
|
87
|
+
}
|
|
88
|
+
interface Plugin {
|
|
89
|
+
name: string;
|
|
90
|
+
setup?(api: PinpointAPI, hooks: PluginHookRegistry): void;
|
|
91
|
+
hooks?: PluginHooks;
|
|
92
|
+
actions?: ContextMenuAction[];
|
|
93
|
+
}
|
|
94
|
+
interface PluginHooks {
|
|
95
|
+
onElementSelect?(element: Element, info: ElementContext): void;
|
|
96
|
+
onElementHover?(element: Element): void;
|
|
97
|
+
onBeforeCopy?(context: CopyContext): CopyContext | false;
|
|
98
|
+
transformOutput?(output: string): string;
|
|
99
|
+
onPinCreate?(pin: Pin): void;
|
|
100
|
+
onPinResolve?(pin: Pin): void;
|
|
101
|
+
}
|
|
102
|
+
interface PluginHookRegistry {
|
|
103
|
+
register(hookName: keyof PluginHooks, handler: Function): void;
|
|
104
|
+
unregister(hookName: keyof PluginHooks, handler: Function): void;
|
|
105
|
+
}
|
|
106
|
+
interface CopyContext {
|
|
107
|
+
pins: Pin[];
|
|
108
|
+
format: OutputFormat;
|
|
109
|
+
output: string;
|
|
110
|
+
}
|
|
111
|
+
type OutputFormat = "compact" | "standard" | "detailed";
|
|
112
|
+
interface ContextMenuAction {
|
|
113
|
+
label: string;
|
|
114
|
+
icon?: string;
|
|
115
|
+
handler(element: Element, context: ElementContext): void;
|
|
116
|
+
}
|
|
117
|
+
interface PinpointAPI {
|
|
118
|
+
activate(): void;
|
|
119
|
+
deactivate(): void;
|
|
120
|
+
toggle(): void;
|
|
121
|
+
isActive(): boolean;
|
|
122
|
+
copyElement(element: Element): Promise<boolean>;
|
|
123
|
+
getElementContext(element: Element): Promise<ElementContext>;
|
|
124
|
+
freeze(elements?: Element[]): void;
|
|
125
|
+
unfreeze(): void;
|
|
126
|
+
openFile(filePath: string, lineNumber?: number): Promise<void>;
|
|
127
|
+
registerPlugin(plugin: Plugin): void;
|
|
128
|
+
unregisterPlugin(name: string): void;
|
|
129
|
+
getPins(): Pin[];
|
|
130
|
+
createPin(element: Element, comment: string): Pin;
|
|
131
|
+
resolvePin(id: string, message?: string): void;
|
|
132
|
+
dispose(): void;
|
|
133
|
+
}
|
|
134
|
+
interface PinStorage {
|
|
135
|
+
load(pageUrl: string): Promise<Pin[]>;
|
|
136
|
+
save(pin: Pin): Promise<void>;
|
|
137
|
+
update(id: string, patch: Partial<Pin>): Promise<void>;
|
|
138
|
+
delete(id: string): Promise<void>;
|
|
139
|
+
list(filter?: {
|
|
140
|
+
pageUrl?: string;
|
|
141
|
+
status?: PinStatus;
|
|
142
|
+
}): Promise<Pin[]>;
|
|
143
|
+
clear(pageUrl?: string): Promise<void>;
|
|
144
|
+
}
|
|
145
|
+
interface PinpointConfig {
|
|
146
|
+
/** Target element to mount pinpoint into */
|
|
147
|
+
target?: HTMLElement;
|
|
148
|
+
/** Author name for annotations */
|
|
149
|
+
author?: string;
|
|
150
|
+
/** REST API endpoint for pin storage */
|
|
151
|
+
endpoint?: string;
|
|
152
|
+
/** Color scheme */
|
|
153
|
+
colorScheme?: "auto" | "light" | "dark";
|
|
154
|
+
/** Output detail level */
|
|
155
|
+
outputFormat?: OutputFormat;
|
|
156
|
+
/** Auto-submit to agent chat */
|
|
157
|
+
autoSubmit?: boolean;
|
|
158
|
+
/** Clear pins after sending */
|
|
159
|
+
clearOnSend?: boolean;
|
|
160
|
+
/** Custom bridge for sending annotations to an agent chat */
|
|
161
|
+
sendToAgent?: (output: AgentOutput) => void | Promise<void>;
|
|
162
|
+
/** Block page interactions during annotation */
|
|
163
|
+
blockInteractions?: boolean;
|
|
164
|
+
/** Freeze JS timers (opt-in, disabled by default) */
|
|
165
|
+
freezeJSTimers?: boolean;
|
|
166
|
+
/** Allowed origins for postMessage */
|
|
167
|
+
allowedOrigins?: string[];
|
|
168
|
+
/** Webhook URL for pin events */
|
|
169
|
+
webhookUrl?: string;
|
|
170
|
+
/** Include source file paths in output */
|
|
171
|
+
includeSourcePaths?: boolean;
|
|
172
|
+
/** Plugins */
|
|
173
|
+
plugins?: Plugin[];
|
|
174
|
+
/** Custom storage adapter */
|
|
175
|
+
storage?: PinStorage;
|
|
176
|
+
/** Initial position of the toolbar */
|
|
177
|
+
position?: {
|
|
178
|
+
x: number;
|
|
179
|
+
y: number;
|
|
180
|
+
};
|
|
181
|
+
/** Marker color */
|
|
182
|
+
markerColor?: string;
|
|
183
|
+
/** Compact popup — hide technical details behind a toggle (default: true) */
|
|
184
|
+
compactPopup?: boolean;
|
|
185
|
+
}
|
|
186
|
+
interface FrameworkAdapter {
|
|
187
|
+
name: string;
|
|
188
|
+
detect(): boolean;
|
|
189
|
+
getComponentInfo(element: Element): ComponentInfo | null;
|
|
190
|
+
getSourceLocation(element: Element): SourceLocation | null;
|
|
191
|
+
freeze?(): void;
|
|
192
|
+
unfreeze?(): void;
|
|
193
|
+
}
|
|
194
|
+
interface PinEvent {
|
|
195
|
+
type: "pin:created" | "pin:updated" | "pin:deleted" | "pin:resolved";
|
|
196
|
+
pin: Pin;
|
|
197
|
+
timestamp: string;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export type { AgentOutput as A, ComponentInfo as C, DrawStroke as D, ElementContext as E, FrameworkInfo as F, OutputFormat as O, PinStorage as P, QueuedAnnotation as Q, SourceLocation as S, TextNote as T, Pin as a, PinStatus as b, ElementInfo as c, FrameworkAdapter as d, PluginHooks as e, Plugin as f, PinpointAPI as g, PinpointConfig as h, ContextMenuAction as i, CopyContext as j, DrawToolType as k, PinEvent as l, ToolbarMode as m };
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { P as PinStorage, a as Pin, b as PinStatus, F as FrameworkInfo, E as ElementContext, c as ElementInfo, d as FrameworkAdapter, C as ComponentInfo, S as SourceLocation, O as OutputFormat, A as AgentOutput, Q as QueuedAnnotation, e as PluginHooks, f as Plugin, g as PinpointAPI, h as PinpointConfig } from './index-NvFcZ4SO.js';
|
|
2
|
+
export { i as ContextMenuAction, j as CopyContext, D as DrawStroke, k as DrawToolType, l as PinEvent, T as TextNote, m as ToolbarMode } from './index-NvFcZ4SO.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
declare class MemoryStore implements PinStorage {
|
|
6
|
+
private pins;
|
|
7
|
+
load(pageUrl: string): Promise<Pin[]>;
|
|
8
|
+
save(pin: Pin): Promise<void>;
|
|
9
|
+
update(id: string, patch: Partial<Pin>): Promise<void>;
|
|
10
|
+
delete(id: string): Promise<void>;
|
|
11
|
+
list(filter?: {
|
|
12
|
+
pageUrl?: string;
|
|
13
|
+
status?: PinStatus;
|
|
14
|
+
}): Promise<Pin[]>;
|
|
15
|
+
clear(pageUrl?: string): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare class RestClient implements PinStorage {
|
|
19
|
+
private endpoint;
|
|
20
|
+
constructor(endpoint: string);
|
|
21
|
+
load(pageUrl: string): Promise<Pin[]>;
|
|
22
|
+
save(pin: Pin): Promise<void>;
|
|
23
|
+
update(id: string, patch: Partial<Pin>): Promise<void>;
|
|
24
|
+
delete(id: string): Promise<void>;
|
|
25
|
+
list(filter?: {
|
|
26
|
+
pageUrl?: string;
|
|
27
|
+
status?: PinStatus;
|
|
28
|
+
}): Promise<Pin[]>;
|
|
29
|
+
clear(pageUrl?: string): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare const ElementInfoSchema: z.ZodObject<{
|
|
33
|
+
tagName: z.ZodString;
|
|
34
|
+
id: z.ZodOptional<z.ZodString>;
|
|
35
|
+
classNames: z.ZodArray<z.ZodString>;
|
|
36
|
+
selector: z.ZodString;
|
|
37
|
+
textContent: z.ZodOptional<z.ZodString>;
|
|
38
|
+
boundingRect: z.ZodObject<{
|
|
39
|
+
x: z.ZodNumber;
|
|
40
|
+
y: z.ZodNumber;
|
|
41
|
+
width: z.ZodNumber;
|
|
42
|
+
height: z.ZodNumber;
|
|
43
|
+
}, z.core.$strip>;
|
|
44
|
+
computedStyles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
45
|
+
ariaAttributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
46
|
+
dataAttributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
47
|
+
domPath: z.ZodOptional<z.ZodString>;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
declare const FrameworkInfoSchema: z.ZodObject<{
|
|
50
|
+
framework: z.ZodString;
|
|
51
|
+
componentPath: z.ZodString;
|
|
52
|
+
sourceFile: z.ZodOptional<z.ZodString>;
|
|
53
|
+
frameworkVersion: z.ZodOptional<z.ZodString>;
|
|
54
|
+
}, z.core.$strip>;
|
|
55
|
+
declare const PinSchema: z.ZodObject<{
|
|
56
|
+
id: z.ZodString;
|
|
57
|
+
pageUrl: z.ZodString;
|
|
58
|
+
createdAt: z.ZodString;
|
|
59
|
+
updatedAt: z.ZodString;
|
|
60
|
+
author: z.ZodOptional<z.ZodString>;
|
|
61
|
+
comment: z.ZodString;
|
|
62
|
+
element: z.ZodObject<{
|
|
63
|
+
tagName: z.ZodString;
|
|
64
|
+
id: z.ZodOptional<z.ZodString>;
|
|
65
|
+
classNames: z.ZodArray<z.ZodString>;
|
|
66
|
+
selector: z.ZodString;
|
|
67
|
+
textContent: z.ZodOptional<z.ZodString>;
|
|
68
|
+
boundingRect: z.ZodObject<{
|
|
69
|
+
x: z.ZodNumber;
|
|
70
|
+
y: z.ZodNumber;
|
|
71
|
+
width: z.ZodNumber;
|
|
72
|
+
height: z.ZodNumber;
|
|
73
|
+
}, z.core.$strip>;
|
|
74
|
+
computedStyles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
75
|
+
ariaAttributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
76
|
+
dataAttributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
77
|
+
domPath: z.ZodOptional<z.ZodString>;
|
|
78
|
+
}, z.core.$strip>;
|
|
79
|
+
framework: z.ZodOptional<z.ZodObject<{
|
|
80
|
+
framework: z.ZodString;
|
|
81
|
+
componentPath: z.ZodString;
|
|
82
|
+
sourceFile: z.ZodOptional<z.ZodString>;
|
|
83
|
+
frameworkVersion: z.ZodOptional<z.ZodString>;
|
|
84
|
+
}, z.core.$strip>>;
|
|
85
|
+
status: z.ZodObject<{
|
|
86
|
+
state: z.ZodEnum<{
|
|
87
|
+
open: "open";
|
|
88
|
+
acknowledged: "acknowledged";
|
|
89
|
+
resolved: "resolved";
|
|
90
|
+
dismissed: "dismissed";
|
|
91
|
+
}>;
|
|
92
|
+
changedAt: z.ZodString;
|
|
93
|
+
changedBy: z.ZodOptional<z.ZodString>;
|
|
94
|
+
}, z.core.$strip>;
|
|
95
|
+
}, z.core.$strip>;
|
|
96
|
+
|
|
97
|
+
interface ElementPickerOptions {
|
|
98
|
+
/** Called on hover with the element under the cursor */
|
|
99
|
+
onHover?: (element: Element | null, rect: DOMRect | null) => void;
|
|
100
|
+
/** Called after stable hover (100ms) with full element context */
|
|
101
|
+
onStableHover?: (element: Element) => void;
|
|
102
|
+
/** Called when an element is clicked/selected */
|
|
103
|
+
onSelect?: (element: Element) => void;
|
|
104
|
+
/** Elements to ignore (e.g., pinpoint's own UI) */
|
|
105
|
+
ignoreSelector?: string;
|
|
106
|
+
/** Whether to block page interactions during selection */
|
|
107
|
+
blockInteractions?: boolean;
|
|
108
|
+
}
|
|
109
|
+
declare class ElementPicker {
|
|
110
|
+
private active;
|
|
111
|
+
private paused;
|
|
112
|
+
private hoveredElement;
|
|
113
|
+
private rafId;
|
|
114
|
+
private stableTimeout;
|
|
115
|
+
private lastTarget;
|
|
116
|
+
private options;
|
|
117
|
+
private handleMouseMove;
|
|
118
|
+
private handleClick;
|
|
119
|
+
private handleKeyDown;
|
|
120
|
+
constructor(options?: ElementPickerOptions);
|
|
121
|
+
/**
|
|
122
|
+
* Check if an event originates from Pinpoint's own UI.
|
|
123
|
+
* Uses composedPath() to cross Shadow DOM boundaries.
|
|
124
|
+
*/
|
|
125
|
+
private isOwnUI;
|
|
126
|
+
private shouldIgnore;
|
|
127
|
+
private pierceElementFromPoint;
|
|
128
|
+
private processHover;
|
|
129
|
+
private clearStableTimeout;
|
|
130
|
+
activate(): void;
|
|
131
|
+
deactivate(): void;
|
|
132
|
+
/** Update blockInteractions at runtime (called from settings toggle) */
|
|
133
|
+
setBlockInteractions(value: boolean): void;
|
|
134
|
+
/** Pause picking without removing listeners (e.g., while popup is open) */
|
|
135
|
+
pause(): void;
|
|
136
|
+
/** Resume picking after pause */
|
|
137
|
+
resume(): void;
|
|
138
|
+
isPaused(): boolean;
|
|
139
|
+
isActive(): boolean;
|
|
140
|
+
/** Get the currently hovered element */
|
|
141
|
+
getHoveredElement(): Element | null;
|
|
142
|
+
dispose(): void;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
interface SelectorOptions {
|
|
146
|
+
/** Timeout for selector generation (ms) */
|
|
147
|
+
timeoutMs?: number;
|
|
148
|
+
/** Additional class names to skip */
|
|
149
|
+
skipClassPatterns?: RegExp[];
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Generate a unique, human-readable CSS selector for an element.
|
|
153
|
+
* Uses @medv/finder (MIT) with configuration to skip CSS-in-JS hashes.
|
|
154
|
+
*/
|
|
155
|
+
declare function buildSelector(element: Element, options?: SelectorOptions): string;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Extract comprehensive metadata from a DOM element.
|
|
159
|
+
*/
|
|
160
|
+
declare function extractElementInfo(element: Element): ElementInfo;
|
|
161
|
+
/**
|
|
162
|
+
* Build a full ElementContext including HTML snippet and framework info.
|
|
163
|
+
*/
|
|
164
|
+
declare function buildElementContext(element: Element, frameworkInfo?: FrameworkInfo): ElementContext;
|
|
165
|
+
|
|
166
|
+
interface DragSelectOptions {
|
|
167
|
+
/** Minimum coverage threshold (0-1) for an element to be considered selected */
|
|
168
|
+
coverageThreshold?: number;
|
|
169
|
+
/** Called when drag starts */
|
|
170
|
+
onDragStart?: (rect: DOMRect) => void;
|
|
171
|
+
/** Called during drag with the current selection rectangle */
|
|
172
|
+
onDragMove?: (rect: DOMRect) => void;
|
|
173
|
+
/** Called when drag ends with selected elements */
|
|
174
|
+
onDragEnd?: (elements: Element[]) => void;
|
|
175
|
+
/** Elements to ignore */
|
|
176
|
+
ignoreSelector?: string;
|
|
177
|
+
}
|
|
178
|
+
declare class DragSelect {
|
|
179
|
+
private active;
|
|
180
|
+
private dragging;
|
|
181
|
+
private startX;
|
|
182
|
+
private startY;
|
|
183
|
+
private options;
|
|
184
|
+
private handleMouseDown;
|
|
185
|
+
private handleMouseMove;
|
|
186
|
+
private handleMouseUp;
|
|
187
|
+
constructor(options?: DragSelectOptions);
|
|
188
|
+
private buildRect;
|
|
189
|
+
private getElementsInRect;
|
|
190
|
+
activate(): void;
|
|
191
|
+
deactivate(): void;
|
|
192
|
+
isDragging(): boolean;
|
|
193
|
+
dispose(): void;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
interface TextSelection {
|
|
197
|
+
/** The selected text */
|
|
198
|
+
text: string;
|
|
199
|
+
/** The container element */
|
|
200
|
+
container: Element;
|
|
201
|
+
/** Start offset within the container */
|
|
202
|
+
startOffset: number;
|
|
203
|
+
/** End offset within the container */
|
|
204
|
+
endOffset: number;
|
|
205
|
+
/** Surrounding context (text before + selected + text after) */
|
|
206
|
+
context: string;
|
|
207
|
+
/** Bounding rect of the selection */
|
|
208
|
+
rect: DOMRect;
|
|
209
|
+
}
|
|
210
|
+
interface TextSelectOptions {
|
|
211
|
+
/** Called when text selection changes */
|
|
212
|
+
onSelect?: (selection: TextSelection | null) => void;
|
|
213
|
+
/** Minimum characters to trigger selection callback */
|
|
214
|
+
minLength?: number;
|
|
215
|
+
}
|
|
216
|
+
declare class TextSelect {
|
|
217
|
+
private active;
|
|
218
|
+
private options;
|
|
219
|
+
private handleSelectionChange;
|
|
220
|
+
private debounceTimer;
|
|
221
|
+
constructor(options?: TextSelectOptions);
|
|
222
|
+
private getTextSelection;
|
|
223
|
+
activate(): void;
|
|
224
|
+
deactivate(): void;
|
|
225
|
+
/** Get the current text selection, if any */
|
|
226
|
+
getCurrentSelection(): TextSelection | null;
|
|
227
|
+
dispose(): void;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Register a framework adapter. Adapters are tried in registration order.
|
|
232
|
+
*/
|
|
233
|
+
declare function registerAdapter(adapter: FrameworkAdapter): void;
|
|
234
|
+
/**
|
|
235
|
+
* Auto-detect the current framework by trying each adapter's detect() method.
|
|
236
|
+
* Returns the first matching adapter, or the generic fallback.
|
|
237
|
+
*/
|
|
238
|
+
declare function detectFramework(): FrameworkAdapter;
|
|
239
|
+
/**
|
|
240
|
+
* Get component info for an element using the detected framework adapter.
|
|
241
|
+
*/
|
|
242
|
+
declare function getComponentInfo(element: Element): ComponentInfo | null;
|
|
243
|
+
/**
|
|
244
|
+
* Get source location for an element using the detected framework adapter.
|
|
245
|
+
*/
|
|
246
|
+
declare function getSourceLocation(element: Element): SourceLocation | null;
|
|
247
|
+
|
|
248
|
+
declare const reactAdapter: FrameworkAdapter;
|
|
249
|
+
|
|
250
|
+
declare const vueAdapter: FrameworkAdapter;
|
|
251
|
+
|
|
252
|
+
declare const genericAdapter: FrameworkAdapter;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Format pins into a human/agent-readable markdown string.
|
|
256
|
+
*/
|
|
257
|
+
declare function formatPins(pins: Pin[], format?: OutputFormat): string;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Format a single pin into rich context for the agent.
|
|
261
|
+
*
|
|
262
|
+
* ```
|
|
263
|
+
* [Annotation on <button class="primary"> in <Header> component]
|
|
264
|
+
* Comment: "This button should be blue instead of gray"
|
|
265
|
+
* Element: button.primary at (120, 45)
|
|
266
|
+
* Source: src/components/Header.tsx:42
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
declare function formatRichPinContext(pin: Pin): string;
|
|
270
|
+
/**
|
|
271
|
+
* Format pins for agent chat.
|
|
272
|
+
* The full formatted output goes into message (visible in chat UI) so the user
|
|
273
|
+
* can see exactly what context the agent is working with.
|
|
274
|
+
*/
|
|
275
|
+
declare function formatPinsForAgent(pins: Pin[], format?: OutputFormat): AgentOutput;
|
|
276
|
+
/**
|
|
277
|
+
* Format queued annotations for batch sending.
|
|
278
|
+
*/
|
|
279
|
+
declare function formatQueueForAgent(queue: QueuedAnnotation[], format?: OutputFormat): AgentOutput;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Register a plugin.
|
|
283
|
+
*/
|
|
284
|
+
declare function registerPlugin(plugin: Plugin, api?: PinpointAPI): void;
|
|
285
|
+
/**
|
|
286
|
+
* Unregister a plugin by name.
|
|
287
|
+
*/
|
|
288
|
+
declare function unregisterPlugin(name: string): void;
|
|
289
|
+
/**
|
|
290
|
+
* Get all registered plugin names.
|
|
291
|
+
*/
|
|
292
|
+
declare function getPlugins(): string[];
|
|
293
|
+
/**
|
|
294
|
+
* Dispatch a hook to all registered handlers.
|
|
295
|
+
*/
|
|
296
|
+
declare function dispatchHook(name: keyof PluginHooks, ...args: unknown[]): void;
|
|
297
|
+
|
|
298
|
+
declare const agentNativePlugin: Plugin;
|
|
299
|
+
|
|
300
|
+
interface FreezeOptions {
|
|
301
|
+
/** Freeze JS timers (opt-in, disabled by default) */
|
|
302
|
+
jsTimers?: boolean;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Freeze all animations, transitions, React updates, and media.
|
|
306
|
+
* Call unfreeze() to restore.
|
|
307
|
+
*/
|
|
308
|
+
declare function freeze(_elements?: Element[], options?: FreezeOptions): void;
|
|
309
|
+
/**
|
|
310
|
+
* Unfreeze everything and restore normal behavior.
|
|
311
|
+
*/
|
|
312
|
+
declare function unfreeze(): void;
|
|
313
|
+
/**
|
|
314
|
+
* Check if freeze is currently active.
|
|
315
|
+
*/
|
|
316
|
+
declare function isFreezeActive(): boolean;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Escape HTML entities in a string.
|
|
320
|
+
* Use on all DOM-derived strings before rendering or including in output.
|
|
321
|
+
*/
|
|
322
|
+
declare function escapeHtml(str: string): string;
|
|
323
|
+
/**
|
|
324
|
+
* Sanitize a string by removing control characters and limiting length.
|
|
325
|
+
*/
|
|
326
|
+
declare function sanitizeString(str: string, maxLength?: number): string;
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Validate that a message origin is allowed.
|
|
330
|
+
* Used for postMessage security when communicating with frames.
|
|
331
|
+
*/
|
|
332
|
+
declare function isAllowedOrigin(origin: string, allowedOrigins?: string[]): boolean;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Open a file in the user's editor. Tries vscode:// protocol first,
|
|
336
|
+
* falls back to a fetch to /api/open-file.
|
|
337
|
+
*/
|
|
338
|
+
declare function openFile(filePath: string, lineNumber?: number): Promise<void>;
|
|
339
|
+
|
|
340
|
+
interface MountResult {
|
|
341
|
+
dispose: () => void;
|
|
342
|
+
shadowRoot: ShadowRoot;
|
|
343
|
+
container: HTMLDivElement;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Mount the Pinpoint overlay into the DOM.
|
|
347
|
+
* Uses Shadow DOM for CSS isolation.
|
|
348
|
+
* Singleton guard prevents multiple instances (HMR-safe).
|
|
349
|
+
*/
|
|
350
|
+
declare function mountPinpoint(config?: PinpointConfig, target?: HTMLElement): MountResult;
|
|
351
|
+
/**
|
|
352
|
+
* Unmount Pinpoint from the DOM.
|
|
353
|
+
*/
|
|
354
|
+
declare function unmountPinpoint(): void;
|
|
355
|
+
|
|
356
|
+
declare class PinMarkerManager {
|
|
357
|
+
private markerColor;
|
|
358
|
+
private markers;
|
|
359
|
+
private updateTimer;
|
|
360
|
+
private onClick;
|
|
361
|
+
private onToggleSelect;
|
|
362
|
+
private selectedPinIds;
|
|
363
|
+
private showCheckboxes;
|
|
364
|
+
constructor(markerColor?: string);
|
|
365
|
+
setOnClick(handler: (pin: Pin) => void): void;
|
|
366
|
+
setOnToggleSelect(handler: (pin: Pin) => void): void;
|
|
367
|
+
setSelectedPins(ids: Set<string>): void;
|
|
368
|
+
setShowCheckboxes(show: boolean): void;
|
|
369
|
+
update(pins: Pin[]): void;
|
|
370
|
+
private updateCheckboxVisual;
|
|
371
|
+
private updateMarker;
|
|
372
|
+
startTracking(pins: Pin[]): void;
|
|
373
|
+
stopTracking(): void;
|
|
374
|
+
dispose(): void;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export { AgentOutput, ComponentInfo, DragSelect, ElementContext, ElementInfo, ElementInfoSchema, ElementPicker, FrameworkAdapter, FrameworkInfo, FrameworkInfoSchema, MemoryStore, OutputFormat, Pin, PinMarkerManager, PinSchema, PinStatus, PinStorage, PinpointAPI, PinpointConfig, Plugin, PluginHooks, QueuedAnnotation, RestClient, SourceLocation, TextSelect, agentNativePlugin, buildElementContext, buildSelector, detectFramework, dispatchHook, escapeHtml, extractElementInfo, formatPins, formatPinsForAgent, formatQueueForAgent, formatRichPinContext, freeze, genericAdapter, getComponentInfo, getPlugins, getSourceLocation, isAllowedOrigin, isFreezeActive, mountPinpoint, openFile, reactAdapter, registerAdapter, registerPlugin, sanitizeString, unfreeze, unmountPinpoint, unregisterPlugin, vueAdapter };
|