@agent-native/pinpoint 0.1.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/.agents/skills/pinpoint/SKILL.md +77 -0
- package/README.md +408 -0
- package/dist/agent-context-76ZW6ODH.js +13 -0
- package/dist/agent-context-76ZW6ODH.js.map +1 -0
- package/dist/chunk-5OW42OKO.js +4897 -0
- package/dist/chunk-5OW42OKO.js.map +1 -0
- package/dist/chunk-BB7X7W3H.js +94 -0
- package/dist/chunk-BB7X7W3H.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-EPXBFDY6.js +88 -0
- package/dist/chunk-EPXBFDY6.js.map +1 -0
- package/dist/chunk-JCYY4S7A.js +53 -0
- package/dist/chunk-JCYY4S7A.js.map +1 -0
- package/dist/chunk-W7IKAJ3P.js +569 -0
- package/dist/chunk-W7IKAJ3P.js.map +1 -0
- package/dist/chunk-Y7IWDHIU.js +25 -0
- package/dist/chunk-Y7IWDHIU.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +71 -0
- package/dist/cli.js.map +1 -0
- package/dist/formatter-25JPHXYA.js +8 -0
- package/dist/formatter-25JPHXYA.js.map +1 -0
- package/dist/index-5or67wLi.d.ts +193 -0
- package/dist/index-CJGmgMCD.d.ts +79 -0
- package/dist/index.browser.d.ts +381 -0
- package/dist/index.browser.js +657 -0
- package/dist/index.browser.js.map +1 -0
- package/dist/index.d.ts +269 -0
- package/dist/index.js +973 -0
- package/dist/index.js.map +1 -0
- package/dist/open-file-RQVHOCXI.js +8 -0
- package/dist/open-file-RQVHOCXI.js.map +1 -0
- package/dist/primitives/index.d.ts +2 -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.d.ts +161 -0
- package/dist/server/index.js +457 -0
- package/dist/server/index.js.map +1 -0
- package/dist/types/index.d.ts +193 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +83 -0
- package/src/scripts/create-pin.ts +41 -0
- package/src/scripts/delete-pin.ts +15 -0
- package/src/scripts/get-pins.ts +35 -0
- package/src/scripts/list-sessions.ts +33 -0
- package/src/scripts/resolve-pin.ts +26 -0
- package/src/scripts/run.ts +8 -0
- package/src/scripts/update-pin.ts +31 -0
|
@@ -0,0 +1,193 @@
|
|
|
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
|
+
type ToolbarMode = "select" | "draw" | "queue";
|
|
26
|
+
interface Pin {
|
|
27
|
+
id: string;
|
|
28
|
+
pageUrl: string;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
updatedAt: string;
|
|
31
|
+
author?: string;
|
|
32
|
+
comment: string;
|
|
33
|
+
element: ElementInfo;
|
|
34
|
+
framework?: FrameworkInfo;
|
|
35
|
+
status: {
|
|
36
|
+
state: PinStatus;
|
|
37
|
+
changedAt: string;
|
|
38
|
+
changedBy?: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
interface ElementInfo {
|
|
42
|
+
tagName: string;
|
|
43
|
+
id?: string;
|
|
44
|
+
classNames: string[];
|
|
45
|
+
selector: string;
|
|
46
|
+
textContent?: string;
|
|
47
|
+
boundingRect: {
|
|
48
|
+
x: number;
|
|
49
|
+
y: number;
|
|
50
|
+
width: number;
|
|
51
|
+
height: number;
|
|
52
|
+
};
|
|
53
|
+
computedStyles?: Record<string, string>;
|
|
54
|
+
ariaAttributes?: Record<string, string>;
|
|
55
|
+
dataAttributes?: Record<string, string>;
|
|
56
|
+
domPath?: string;
|
|
57
|
+
}
|
|
58
|
+
interface FrameworkInfo {
|
|
59
|
+
framework: string;
|
|
60
|
+
componentPath: string;
|
|
61
|
+
sourceFile?: string;
|
|
62
|
+
frameworkVersion?: string;
|
|
63
|
+
}
|
|
64
|
+
interface ElementContext {
|
|
65
|
+
element: ElementInfo;
|
|
66
|
+
framework?: FrameworkInfo;
|
|
67
|
+
htmlSnippet: string;
|
|
68
|
+
cssSelector: string;
|
|
69
|
+
computedStyles: Record<string, string>;
|
|
70
|
+
}
|
|
71
|
+
interface ComponentInfo {
|
|
72
|
+
name: string;
|
|
73
|
+
displayName?: string;
|
|
74
|
+
filePath?: string;
|
|
75
|
+
lineNumber?: number;
|
|
76
|
+
props?: Record<string, unknown>;
|
|
77
|
+
}
|
|
78
|
+
interface SourceLocation {
|
|
79
|
+
file: string;
|
|
80
|
+
line?: number;
|
|
81
|
+
column?: number;
|
|
82
|
+
}
|
|
83
|
+
interface Plugin {
|
|
84
|
+
name: string;
|
|
85
|
+
setup?(api: PinpointAPI, hooks: PluginHookRegistry): void;
|
|
86
|
+
hooks?: PluginHooks;
|
|
87
|
+
actions?: ContextMenuAction[];
|
|
88
|
+
}
|
|
89
|
+
interface PluginHooks {
|
|
90
|
+
onElementSelect?(element: Element, info: ElementContext): void;
|
|
91
|
+
onElementHover?(element: Element): void;
|
|
92
|
+
onBeforeCopy?(context: CopyContext): CopyContext | false;
|
|
93
|
+
transformOutput?(output: string): string;
|
|
94
|
+
onPinCreate?(pin: Pin): void;
|
|
95
|
+
onPinResolve?(pin: Pin): void;
|
|
96
|
+
}
|
|
97
|
+
interface PluginHookRegistry {
|
|
98
|
+
register(hookName: keyof PluginHooks, handler: Function): void;
|
|
99
|
+
unregister(hookName: keyof PluginHooks, handler: Function): void;
|
|
100
|
+
}
|
|
101
|
+
interface CopyContext {
|
|
102
|
+
pins: Pin[];
|
|
103
|
+
format: OutputFormat;
|
|
104
|
+
output: string;
|
|
105
|
+
}
|
|
106
|
+
type OutputFormat = "compact" | "standard" | "detailed";
|
|
107
|
+
interface ContextMenuAction {
|
|
108
|
+
label: string;
|
|
109
|
+
icon?: string;
|
|
110
|
+
handler(element: Element, context: ElementContext): void;
|
|
111
|
+
}
|
|
112
|
+
interface PinpointAPI {
|
|
113
|
+
activate(): void;
|
|
114
|
+
deactivate(): void;
|
|
115
|
+
toggle(): void;
|
|
116
|
+
isActive(): boolean;
|
|
117
|
+
copyElement(element: Element): Promise<boolean>;
|
|
118
|
+
getElementContext(element: Element): Promise<ElementContext>;
|
|
119
|
+
freeze(elements?: Element[]): void;
|
|
120
|
+
unfreeze(): void;
|
|
121
|
+
openFile(filePath: string, lineNumber?: number): Promise<void>;
|
|
122
|
+
registerPlugin(plugin: Plugin): void;
|
|
123
|
+
unregisterPlugin(name: string): void;
|
|
124
|
+
getPins(): Pin[];
|
|
125
|
+
createPin(element: Element, comment: string): Pin;
|
|
126
|
+
resolvePin(id: string, message?: string): void;
|
|
127
|
+
dispose(): void;
|
|
128
|
+
}
|
|
129
|
+
interface PinStorage {
|
|
130
|
+
load(pageUrl: string): Promise<Pin[]>;
|
|
131
|
+
save(pin: Pin): Promise<void>;
|
|
132
|
+
update(id: string, patch: Partial<Pin>): Promise<void>;
|
|
133
|
+
delete(id: string): Promise<void>;
|
|
134
|
+
list(filter?: {
|
|
135
|
+
pageUrl?: string;
|
|
136
|
+
status?: PinStatus;
|
|
137
|
+
}): Promise<Pin[]>;
|
|
138
|
+
clear(pageUrl?: string): Promise<void>;
|
|
139
|
+
}
|
|
140
|
+
interface PinpointConfig {
|
|
141
|
+
/** Target element to mount pinpoint into */
|
|
142
|
+
target?: HTMLElement;
|
|
143
|
+
/** Author name for annotations */
|
|
144
|
+
author?: string;
|
|
145
|
+
/** REST API endpoint for pin storage */
|
|
146
|
+
endpoint?: string;
|
|
147
|
+
/** Color scheme */
|
|
148
|
+
colorScheme?: "auto" | "light" | "dark";
|
|
149
|
+
/** Output detail level */
|
|
150
|
+
outputFormat?: OutputFormat;
|
|
151
|
+
/** Auto-submit to agent chat */
|
|
152
|
+
autoSubmit?: boolean;
|
|
153
|
+
/** Clear pins after sending */
|
|
154
|
+
clearOnSend?: boolean;
|
|
155
|
+
/** Block page interactions during annotation */
|
|
156
|
+
blockInteractions?: boolean;
|
|
157
|
+
/** Freeze JS timers (opt-in, disabled by default) */
|
|
158
|
+
freezeJSTimers?: boolean;
|
|
159
|
+
/** Allowed origins for postMessage */
|
|
160
|
+
allowedOrigins?: string[];
|
|
161
|
+
/** Webhook URL for pin events */
|
|
162
|
+
webhookUrl?: string;
|
|
163
|
+
/** Include source file paths in output */
|
|
164
|
+
includeSourcePaths?: boolean;
|
|
165
|
+
/** Plugins */
|
|
166
|
+
plugins?: Plugin[];
|
|
167
|
+
/** Custom storage adapter */
|
|
168
|
+
storage?: PinStorage;
|
|
169
|
+
/** Initial position of the toolbar */
|
|
170
|
+
position?: {
|
|
171
|
+
x: number;
|
|
172
|
+
y: number;
|
|
173
|
+
};
|
|
174
|
+
/** Marker color */
|
|
175
|
+
markerColor?: string;
|
|
176
|
+
/** Compact popup — hide technical details behind a toggle (default: true) */
|
|
177
|
+
compactPopup?: boolean;
|
|
178
|
+
}
|
|
179
|
+
interface FrameworkAdapter {
|
|
180
|
+
name: string;
|
|
181
|
+
detect(): boolean;
|
|
182
|
+
getComponentInfo(element: Element): ComponentInfo | null;
|
|
183
|
+
getSourceLocation(element: Element): SourceLocation | null;
|
|
184
|
+
freeze?(): void;
|
|
185
|
+
unfreeze?(): void;
|
|
186
|
+
}
|
|
187
|
+
interface PinEvent {
|
|
188
|
+
type: "pin:created" | "pin:updated" | "pin:deleted" | "pin:resolved";
|
|
189
|
+
pin: Pin;
|
|
190
|
+
timestamp: string;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export type { ComponentInfo, ContextMenuAction, CopyContext, DrawStroke, DrawToolType, ElementContext, ElementInfo, FrameworkAdapter, FrameworkInfo, OutputFormat, Pin, PinEvent, PinStatus, PinStorage, PinpointAPI, PinpointConfig, Plugin, PluginHookRegistry, PluginHooks, QueuedAnnotation, SourceLocation, TextNote, ToolbarMode };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agent-native/pinpoint",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Visual feedback and annotation tool for agent-native web applications",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/BuilderIO/agent-native",
|
|
10
|
+
"directory": "packages/pinpoint"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/BuilderIO/agent-native/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"browser": "./dist/index.browser.js",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./react": {
|
|
23
|
+
"types": "./dist/react.d.ts",
|
|
24
|
+
"import": "./dist/react.js"
|
|
25
|
+
},
|
|
26
|
+
"./primitives": {
|
|
27
|
+
"types": "./dist/primitives/index.d.ts",
|
|
28
|
+
"import": "./dist/primitives/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./server": {
|
|
31
|
+
"types": "./dist/server/index.d.ts",
|
|
32
|
+
"import": "./dist/server/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./types": {
|
|
35
|
+
"types": "./dist/types/index.d.ts",
|
|
36
|
+
"import": "./dist/types/index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"bin": {
|
|
40
|
+
"pinpoint": "./dist/cli.js"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"src/scripts",
|
|
45
|
+
".agents"
|
|
46
|
+
],
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@medv/finder": "^4.0.2",
|
|
49
|
+
"bippy": "^0.5.32",
|
|
50
|
+
"element-source": "^0.0.3",
|
|
51
|
+
"solid-js": "^1.9.10",
|
|
52
|
+
"zod": "^4.3.6"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"@agent-native/core": ">=0.7",
|
|
56
|
+
"react": ">=18.0.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependenciesMeta": {
|
|
59
|
+
"react": {
|
|
60
|
+
"optional": true
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
65
|
+
"@types/express": "^5.0.3",
|
|
66
|
+
"@types/node": "^24.2.1",
|
|
67
|
+
"@types/react": "^19.2.14",
|
|
68
|
+
"babel-preset-solid": "^1.9.10",
|
|
69
|
+
"esbuild-plugin-solid": "^0.6.0",
|
|
70
|
+
"express": "^5.1.0",
|
|
71
|
+
"tsup": "^8.4.0",
|
|
72
|
+
"typescript": "^6.0.3",
|
|
73
|
+
"vite-plugin-solid": "^2.11.0",
|
|
74
|
+
"vitest": "^4.1.5",
|
|
75
|
+
"@agent-native/core": "0.7.15"
|
|
76
|
+
},
|
|
77
|
+
"scripts": {
|
|
78
|
+
"build": "tsup",
|
|
79
|
+
"dev": "tsup --watch",
|
|
80
|
+
"typecheck": "tsc --noEmit",
|
|
81
|
+
"test": "vitest --run"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// @agent-native/pinpoint — Create annotation script
|
|
2
|
+
// MIT License
|
|
3
|
+
|
|
4
|
+
import { parseArgs, fail } from "@agent-native/core/scripts";
|
|
5
|
+
import { FileStore } from "../storage/file-store.js";
|
|
6
|
+
import { randomUUID } from "crypto";
|
|
7
|
+
import type { Pin } from "../types/index.js";
|
|
8
|
+
|
|
9
|
+
export default async function (args: string[]) {
|
|
10
|
+
const { pageUrl, selector, comment, author } = parseArgs(args) as {
|
|
11
|
+
pageUrl?: string;
|
|
12
|
+
selector?: string;
|
|
13
|
+
comment?: string;
|
|
14
|
+
author?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
if (!pageUrl) fail("--pageUrl is required");
|
|
18
|
+
if (!selector) fail("--selector is required");
|
|
19
|
+
if (!comment) fail("--comment is required");
|
|
20
|
+
|
|
21
|
+
const now = new Date().toISOString();
|
|
22
|
+
const pin: Pin = {
|
|
23
|
+
id: randomUUID(),
|
|
24
|
+
pageUrl: pageUrl!,
|
|
25
|
+
createdAt: now,
|
|
26
|
+
updatedAt: now,
|
|
27
|
+
author,
|
|
28
|
+
comment: comment!,
|
|
29
|
+
element: {
|
|
30
|
+
tagName: "unknown",
|
|
31
|
+
classNames: [],
|
|
32
|
+
selector: selector!,
|
|
33
|
+
boundingRect: { x: 0, y: 0, width: 0, height: 0 },
|
|
34
|
+
},
|
|
35
|
+
status: { state: "open", changedAt: now, changedBy: "agent" },
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const store = new FileStore();
|
|
39
|
+
await store.save(pin);
|
|
40
|
+
console.log(`Created annotation ${pin.id} on ${pageUrl} → ${selector}`);
|
|
41
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @agent-native/pinpoint — Delete annotation script
|
|
2
|
+
// MIT License
|
|
3
|
+
|
|
4
|
+
import { parseArgs, fail } from "@agent-native/core/scripts";
|
|
5
|
+
import { FileStore } from "../storage/file-store.js";
|
|
6
|
+
|
|
7
|
+
export default async function (args: string[]) {
|
|
8
|
+
const { id } = parseArgs(args) as { id?: string };
|
|
9
|
+
|
|
10
|
+
if (!id) fail("--id is required");
|
|
11
|
+
|
|
12
|
+
const store = new FileStore();
|
|
13
|
+
await store.delete(id!);
|
|
14
|
+
console.log(`Deleted annotation ${id}`);
|
|
15
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// @agent-native/pinpoint — List/filter annotations script
|
|
2
|
+
// MIT License
|
|
3
|
+
|
|
4
|
+
import { parseArgs } from "@agent-native/core/scripts";
|
|
5
|
+
import { FileStore } from "../storage/file-store.js";
|
|
6
|
+
import type { PinStatus } from "../types/index.js";
|
|
7
|
+
|
|
8
|
+
export default async function (args: string[]) {
|
|
9
|
+
const { pageUrl, status } = parseArgs(args) as {
|
|
10
|
+
pageUrl?: string;
|
|
11
|
+
status?: PinStatus;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const store = new FileStore();
|
|
15
|
+
const pins = await store.list({ pageUrl, status });
|
|
16
|
+
|
|
17
|
+
if (pins.length === 0) {
|
|
18
|
+
console.log("No annotations found.");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
console.log(`Found ${pins.length} annotation(s):\n`);
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < pins.length; i++) {
|
|
25
|
+
const pin = pins[i];
|
|
26
|
+
console.log(`${i + 1}. [${pin.status.state}] ${pin.element.selector}`);
|
|
27
|
+
console.log(` Comment: ${pin.comment}`);
|
|
28
|
+
if (pin.author) console.log(` Author: ${pin.author}`);
|
|
29
|
+
if (pin.framework?.sourceFile)
|
|
30
|
+
console.log(` Source: ${pin.framework.sourceFile}`);
|
|
31
|
+
console.log(` Page: ${pin.pageUrl}`);
|
|
32
|
+
console.log(` ID: ${pin.id}`);
|
|
33
|
+
console.log();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// @agent-native/pinpoint — List annotation sessions by page URL
|
|
2
|
+
// MIT License
|
|
3
|
+
|
|
4
|
+
import { FileStore } from "../storage/file-store.js";
|
|
5
|
+
|
|
6
|
+
export default async function (_args: string[]) {
|
|
7
|
+
const store = new FileStore();
|
|
8
|
+
const pins = await store.list();
|
|
9
|
+
|
|
10
|
+
// Group by page URL
|
|
11
|
+
const sessions = new Map<string, { count: number; latest: string }>();
|
|
12
|
+
for (const pin of pins) {
|
|
13
|
+
const existing = sessions.get(pin.pageUrl);
|
|
14
|
+
if (!existing || pin.updatedAt > existing.latest) {
|
|
15
|
+
sessions.set(pin.pageUrl, {
|
|
16
|
+
count: (existing?.count ?? 0) + 1,
|
|
17
|
+
latest: pin.updatedAt,
|
|
18
|
+
});
|
|
19
|
+
} else {
|
|
20
|
+
existing.count++;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (sessions.size === 0) {
|
|
25
|
+
console.log("No annotation sessions found.");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
console.log(`${sessions.size} page(s) with annotations:\n`);
|
|
30
|
+
for (const [url, info] of sessions) {
|
|
31
|
+
console.log(` ${url} — ${info.count} pin(s), last updated ${info.latest}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @agent-native/pinpoint — Resolve annotation script
|
|
2
|
+
// MIT License
|
|
3
|
+
|
|
4
|
+
import { parseArgs, fail } from "@agent-native/core/scripts";
|
|
5
|
+
import { FileStore } from "../storage/file-store.js";
|
|
6
|
+
|
|
7
|
+
export default async function (args: string[]) {
|
|
8
|
+
const { id, message } = parseArgs(args) as {
|
|
9
|
+
id?: string;
|
|
10
|
+
message?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
if (!id) fail("--id is required");
|
|
14
|
+
|
|
15
|
+
const store = new FileStore();
|
|
16
|
+
await store.update(id!, {
|
|
17
|
+
status: {
|
|
18
|
+
state: "resolved",
|
|
19
|
+
changedAt: new Date().toISOString(),
|
|
20
|
+
changedBy: "agent",
|
|
21
|
+
},
|
|
22
|
+
...(message ? { comment: message } : {}),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log(`Resolved annotation ${id}`);
|
|
26
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// @agent-native/pinpoint — Update annotation script
|
|
2
|
+
// MIT License
|
|
3
|
+
|
|
4
|
+
import { parseArgs, fail } from "@agent-native/core/scripts";
|
|
5
|
+
import { FileStore } from "../storage/file-store.js";
|
|
6
|
+
|
|
7
|
+
export default async function (args: string[]) {
|
|
8
|
+
const { id, comment, status } = parseArgs(args) as {
|
|
9
|
+
id?: string;
|
|
10
|
+
comment?: string;
|
|
11
|
+
status?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
if (!id) fail("--id is required");
|
|
15
|
+
if (!comment && !status) fail("--comment or --status is required");
|
|
16
|
+
|
|
17
|
+
const store = new FileStore();
|
|
18
|
+
const patch: Record<string, any> = {};
|
|
19
|
+
|
|
20
|
+
if (comment) patch.comment = comment;
|
|
21
|
+
if (status) {
|
|
22
|
+
patch.status = {
|
|
23
|
+
state: status,
|
|
24
|
+
changedAt: new Date().toISOString(),
|
|
25
|
+
changedBy: "agent",
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
await store.update(id!, patch);
|
|
30
|
+
console.log(`Updated annotation ${id}`);
|
|
31
|
+
}
|