@clicksmith/core 0.1.0
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/LICENSE +21 -0
- package/README.md +66 -0
- package/dist/index.d.ts +2320 -0
- package/dist/index.js +364 -0
- package/dist/index.js.map +1 -0
- package/package.json +31 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// src/schemas.ts
|
|
4
|
+
var CURRENT_BUNDLE_VERSION = 5;
|
|
5
|
+
var isoDateTime = z.string().datetime({ offset: true }).describe("ISO-8601 timestamp");
|
|
6
|
+
var SourceLocatorSchema = z.object({
|
|
7
|
+
kind: z.literal("source"),
|
|
8
|
+
file: z.string().min(1),
|
|
9
|
+
line: z.number().int().positive(),
|
|
10
|
+
column: z.number().int().nonnegative().optional(),
|
|
11
|
+
export: z.string().optional()
|
|
12
|
+
});
|
|
13
|
+
var AttrLocatorSchema = z.object({
|
|
14
|
+
kind: z.literal("attr"),
|
|
15
|
+
attr: z.string().min(1),
|
|
16
|
+
value: z.string(),
|
|
17
|
+
selector: z.string().min(1)
|
|
18
|
+
});
|
|
19
|
+
var BehavioralLocatorSchema = z.object({
|
|
20
|
+
kind: z.literal("behavioral"),
|
|
21
|
+
role: z.string().min(1),
|
|
22
|
+
name: z.string(),
|
|
23
|
+
nth: z.number().int().nonnegative().optional()
|
|
24
|
+
});
|
|
25
|
+
var DomLocatorSchema = z.object({
|
|
26
|
+
kind: z.literal("dom"),
|
|
27
|
+
selector: z.string().min(1),
|
|
28
|
+
fingerprint: z.string().min(1)
|
|
29
|
+
});
|
|
30
|
+
var LocatorSchema = z.discriminatedUnion("kind", [
|
|
31
|
+
SourceLocatorSchema,
|
|
32
|
+
AttrLocatorSchema,
|
|
33
|
+
BehavioralLocatorSchema,
|
|
34
|
+
DomLocatorSchema
|
|
35
|
+
]);
|
|
36
|
+
var ElementDescriptorSchema = z.object({
|
|
37
|
+
tag: z.string().min(1),
|
|
38
|
+
text: z.string().optional(),
|
|
39
|
+
role: z.string().optional(),
|
|
40
|
+
label: z.string().optional(),
|
|
41
|
+
attrs: z.record(z.string()).default({}),
|
|
42
|
+
iconHints: z.array(z.string()).optional()
|
|
43
|
+
});
|
|
44
|
+
var NearContextSchema = z.object({
|
|
45
|
+
labels: z.array(z.string()).optional(),
|
|
46
|
+
headings: z.array(z.string()).optional(),
|
|
47
|
+
landmarks: z.array(z.string()).optional(),
|
|
48
|
+
parentText: z.string().optional()
|
|
49
|
+
});
|
|
50
|
+
var ConditionsSchema = z.object({
|
|
51
|
+
viewport: z.object({
|
|
52
|
+
w: z.number().int().positive(),
|
|
53
|
+
h: z.number().int().positive()
|
|
54
|
+
}),
|
|
55
|
+
theme: z.enum(["light", "dark"]).optional(),
|
|
56
|
+
mediaQueries: z.record(z.boolean()).optional()
|
|
57
|
+
});
|
|
58
|
+
var CapturedElementSchema = z.object({
|
|
59
|
+
/** 1-based identifier surfaced to users as `#N`. Stable within a session. */
|
|
60
|
+
id: z.number().int().positive(),
|
|
61
|
+
ts: isoDateTime,
|
|
62
|
+
locator: LocatorSchema,
|
|
63
|
+
el: ElementDescriptorSchema,
|
|
64
|
+
near: NearContextSchema.default({}),
|
|
65
|
+
conditions: ConditionsSchema,
|
|
66
|
+
screenshot: z.string().optional(),
|
|
67
|
+
frameworkHints: z.record(z.unknown()).optional()
|
|
68
|
+
});
|
|
69
|
+
var ExecutionModeSchema = z.enum(["plan", "edit"]);
|
|
70
|
+
var IsolationSchema = z.enum(["worktree", "branch", "inplace"]);
|
|
71
|
+
var ExecutionOptionsSchema = z.object({
|
|
72
|
+
mode: ExecutionModeSchema.default("plan"),
|
|
73
|
+
isolation: IsolationSchema.default("worktree"),
|
|
74
|
+
autoApply: z.boolean().default(false),
|
|
75
|
+
agentId: z.string().optional(),
|
|
76
|
+
/** Git ref the sandbox should branch from. Defaults to the current HEAD. */
|
|
77
|
+
baseRef: z.string().optional()
|
|
78
|
+
});
|
|
79
|
+
var ElementEnrichmentSchema = z.object({
|
|
80
|
+
elementId: z.number().int().positive(),
|
|
81
|
+
reviewContext: z.string().optional(),
|
|
82
|
+
impactRadius: z.unknown().optional(),
|
|
83
|
+
affectedFlows: z.unknown().optional()
|
|
84
|
+
});
|
|
85
|
+
var EnrichmentSchema = z.object({
|
|
86
|
+
source: z.literal("code-review-graph"),
|
|
87
|
+
perElement: z.array(ElementEnrichmentSchema).default([]),
|
|
88
|
+
warnings: z.array(z.string()).default([])
|
|
89
|
+
});
|
|
90
|
+
var AppContextSchema = z.object({
|
|
91
|
+
url: z.string().url(),
|
|
92
|
+
route: z.string().min(1),
|
|
93
|
+
page: z.string().optional()
|
|
94
|
+
});
|
|
95
|
+
var CaptureBundleSchema = z.object({
|
|
96
|
+
v: z.literal(CURRENT_BUNDLE_VERSION),
|
|
97
|
+
sessionId: z.string().min(1),
|
|
98
|
+
submittedAt: isoDateTime,
|
|
99
|
+
prompt: z.string().min(1),
|
|
100
|
+
app: AppContextSchema,
|
|
101
|
+
elements: z.array(CapturedElementSchema).min(1),
|
|
102
|
+
execution: ExecutionOptionsSchema,
|
|
103
|
+
enrichment: EnrichmentSchema.optional()
|
|
104
|
+
});
|
|
105
|
+
var SessionStatusSchema = z.enum(["active", "submitted", "expired"]);
|
|
106
|
+
var SessionSchema = z.object({
|
|
107
|
+
id: z.string().min(1),
|
|
108
|
+
createdAt: isoDateTime,
|
|
109
|
+
updatedAt: isoDateTime,
|
|
110
|
+
expiresAt: isoDateTime,
|
|
111
|
+
status: SessionStatusSchema.default("active"),
|
|
112
|
+
app: AppContextSchema,
|
|
113
|
+
elements: z.array(CapturedElementSchema).default([]),
|
|
114
|
+
prompt: z.string().optional(),
|
|
115
|
+
/**
|
|
116
|
+
* High-water mark of element ids ever assigned. Ensures `#N` ids are never
|
|
117
|
+
* reused, even after the highest-numbered element is removed.
|
|
118
|
+
*/
|
|
119
|
+
lastElementId: z.number().int().nonnegative().default(0)
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// src/ids.ts
|
|
123
|
+
function randomToken(bytes = 8) {
|
|
124
|
+
const cryptoObj = globalThis.crypto;
|
|
125
|
+
if (cryptoObj?.getRandomValues) {
|
|
126
|
+
const arr = new Uint8Array(bytes);
|
|
127
|
+
cryptoObj.getRandomValues(arr);
|
|
128
|
+
return Array.from(arr, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
129
|
+
}
|
|
130
|
+
let out = "";
|
|
131
|
+
for (let i = 0; i < bytes; i++) {
|
|
132
|
+
out += Math.floor(Math.random() * 256).toString(16).padStart(2, "0");
|
|
133
|
+
}
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
function newSessionId(now = /* @__PURE__ */ new Date()) {
|
|
137
|
+
return `cs_${now.getTime().toString(36)}_${randomToken(4)}`;
|
|
138
|
+
}
|
|
139
|
+
function newRunId(now = /* @__PURE__ */ new Date()) {
|
|
140
|
+
return `run_${now.getTime().toString(36)}_${randomToken(4)}`;
|
|
141
|
+
}
|
|
142
|
+
function nextElementId(existingIds, lastSeen = 0) {
|
|
143
|
+
return Math.max(lastSeen, ...existingIds, 0) + 1;
|
|
144
|
+
}
|
|
145
|
+
function parseElementRef(ref) {
|
|
146
|
+
const match = ref.trim().match(/^#?\s*(\d+)$/);
|
|
147
|
+
if (!match) return void 0;
|
|
148
|
+
const n = Number.parseInt(match[1], 10);
|
|
149
|
+
return Number.isSafeInteger(n) && n > 0 ? n : void 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/locator.ts
|
|
153
|
+
var LOCATOR_PRIORITY = ["source", "attr", "behavioral", "dom"];
|
|
154
|
+
var RANK = {
|
|
155
|
+
source: 0,
|
|
156
|
+
attr: 1,
|
|
157
|
+
behavioral: 2,
|
|
158
|
+
dom: 3
|
|
159
|
+
};
|
|
160
|
+
function locatorRank(kind) {
|
|
161
|
+
return RANK[kind];
|
|
162
|
+
}
|
|
163
|
+
function compareLocators(a, b) {
|
|
164
|
+
return locatorRank(a.kind) - locatorRank(b.kind);
|
|
165
|
+
}
|
|
166
|
+
function rankLocators(locators) {
|
|
167
|
+
return [...locators].sort(compareLocators);
|
|
168
|
+
}
|
|
169
|
+
function pickBestLocator(locators) {
|
|
170
|
+
if (locators.length === 0) return void 0;
|
|
171
|
+
return rankLocators(locators)[0];
|
|
172
|
+
}
|
|
173
|
+
function describeLocator(locator) {
|
|
174
|
+
switch (locator.kind) {
|
|
175
|
+
case "source":
|
|
176
|
+
return `source:${locator.file}:${locator.line}${locator.column != null ? `:${locator.column}` : ""}`;
|
|
177
|
+
case "attr":
|
|
178
|
+
return `attr:[${locator.attr}="${locator.value}"]`;
|
|
179
|
+
case "behavioral":
|
|
180
|
+
return `role:${locator.role}${locator.name ? ` name="${locator.name}"` : ""}${locator.nth != null ? ` (nth=${locator.nth})` : ""}`;
|
|
181
|
+
case "dom":
|
|
182
|
+
return `dom:${locator.selector}`;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function isSourceResolved(locator) {
|
|
186
|
+
return locator.kind === "source";
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// src/defaults.ts
|
|
190
|
+
var DEFAULT_DAEMON_PORT = 8722;
|
|
191
|
+
var DEFAULT_DAEMON_HOST = "127.0.0.1";
|
|
192
|
+
var DEFAULT_SESSION_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
193
|
+
var DEFAULT_EXECUTION_OPTIONS = {
|
|
194
|
+
mode: "plan",
|
|
195
|
+
isolation: "worktree",
|
|
196
|
+
autoApply: false
|
|
197
|
+
};
|
|
198
|
+
function requiresConfirmation(execution) {
|
|
199
|
+
return execution.mode !== "plan" || execution.isolation === "inplace" || execution.autoApply;
|
|
200
|
+
}
|
|
201
|
+
function confirmationReasons(execution) {
|
|
202
|
+
const reasons = [];
|
|
203
|
+
if (execution.mode !== "plan") {
|
|
204
|
+
reasons.push("Edit mode lets the agent modify files directly instead of only proposing a plan.");
|
|
205
|
+
}
|
|
206
|
+
if (execution.isolation === "inplace") {
|
|
207
|
+
reasons.push("In-place isolation runs against your working tree instead of a throwaway worktree.");
|
|
208
|
+
}
|
|
209
|
+
if (execution.autoApply) {
|
|
210
|
+
reasons.push("Auto-apply merges the agent\u2019s changes back without a manual review step.");
|
|
211
|
+
}
|
|
212
|
+
return reasons;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/session.ts
|
|
216
|
+
function createSession(input) {
|
|
217
|
+
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
218
|
+
const ttlMs = input.ttlMs ?? DEFAULT_SESSION_TTL_MS;
|
|
219
|
+
const iso = now.toISOString();
|
|
220
|
+
return {
|
|
221
|
+
id: input.id ?? newSessionId(now),
|
|
222
|
+
createdAt: iso,
|
|
223
|
+
updatedAt: iso,
|
|
224
|
+
expiresAt: new Date(now.getTime() + ttlMs).toISOString(),
|
|
225
|
+
status: "active",
|
|
226
|
+
app: input.app,
|
|
227
|
+
elements: [],
|
|
228
|
+
lastElementId: 0
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function appendElement(session, input, now = /* @__PURE__ */ new Date()) {
|
|
232
|
+
const id = nextElementId(
|
|
233
|
+
session.elements.map((e) => e.id),
|
|
234
|
+
session.lastElementId
|
|
235
|
+
);
|
|
236
|
+
const element = { ...input, id };
|
|
237
|
+
const next = {
|
|
238
|
+
...session,
|
|
239
|
+
elements: [...session.elements, element],
|
|
240
|
+
lastElementId: id,
|
|
241
|
+
updatedAt: now.toISOString()
|
|
242
|
+
};
|
|
243
|
+
return { session: next, element };
|
|
244
|
+
}
|
|
245
|
+
function removeElement(session, elementId, now = /* @__PURE__ */ new Date()) {
|
|
246
|
+
const elements = session.elements.filter((e) => e.id !== elementId);
|
|
247
|
+
const removed = elements.length !== session.elements.length;
|
|
248
|
+
if (!removed) return { session, removed: false };
|
|
249
|
+
return {
|
|
250
|
+
session: { ...session, elements, updatedAt: now.toISOString() },
|
|
251
|
+
removed: true
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function findElement(session, elementId) {
|
|
255
|
+
return session.elements.find((e) => e.id === elementId);
|
|
256
|
+
}
|
|
257
|
+
function isExpired(session, now = /* @__PURE__ */ new Date()) {
|
|
258
|
+
if (session.status === "submitted") return false;
|
|
259
|
+
return new Date(session.expiresAt).getTime() <= now.getTime();
|
|
260
|
+
}
|
|
261
|
+
function touchSession(session, now = /* @__PURE__ */ new Date(), ttlMs = DEFAULT_SESSION_TTL_MS) {
|
|
262
|
+
return {
|
|
263
|
+
...session,
|
|
264
|
+
updatedAt: now.toISOString(),
|
|
265
|
+
expiresAt: new Date(now.getTime() + ttlMs).toISOString()
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
function finalizeSession(session, input) {
|
|
269
|
+
if (session.elements.length === 0) {
|
|
270
|
+
throw new Error(`Cannot finalize session ${session.id}: no captured elements.`);
|
|
271
|
+
}
|
|
272
|
+
if (!input.prompt.trim()) {
|
|
273
|
+
throw new Error(`Cannot finalize session ${session.id}: prompt is empty.`);
|
|
274
|
+
}
|
|
275
|
+
const bundle = {
|
|
276
|
+
v: CURRENT_BUNDLE_VERSION,
|
|
277
|
+
sessionId: session.id,
|
|
278
|
+
submittedAt: (input.submittedAt ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
279
|
+
prompt: input.prompt.trim(),
|
|
280
|
+
app: session.app,
|
|
281
|
+
elements: session.elements,
|
|
282
|
+
execution: input.execution ?? { ...DEFAULT_EXECUTION_OPTIONS },
|
|
283
|
+
...input.enrichment ? { enrichment: input.enrichment } : {}
|
|
284
|
+
};
|
|
285
|
+
return CaptureBundleSchema.parse(bundle);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// src/bundle.ts
|
|
289
|
+
function validateBundle(value) {
|
|
290
|
+
const result = CaptureBundleSchema.safeParse(value);
|
|
291
|
+
if (result.success) return { ok: true, bundle: result.data };
|
|
292
|
+
return { ok: false, error: result.error };
|
|
293
|
+
}
|
|
294
|
+
function parseBundle(value) {
|
|
295
|
+
const result = validateBundle(value);
|
|
296
|
+
if (result.ok) return result.bundle;
|
|
297
|
+
throw new Error(`Invalid CaptureBundle: ${result.error.message}`);
|
|
298
|
+
}
|
|
299
|
+
function serializeBundle(bundle) {
|
|
300
|
+
return JSON.stringify(parseBundle(bundle), stableReplacer(), 2);
|
|
301
|
+
}
|
|
302
|
+
function deserializeBundle(json) {
|
|
303
|
+
let parsed;
|
|
304
|
+
try {
|
|
305
|
+
parsed = JSON.parse(json);
|
|
306
|
+
} catch (err) {
|
|
307
|
+
throw new Error(`CaptureBundle is not valid JSON: ${err.message}`);
|
|
308
|
+
}
|
|
309
|
+
return parseBundle(parsed);
|
|
310
|
+
}
|
|
311
|
+
function isCurrentVersion(value) {
|
|
312
|
+
return typeof value === "object" && value !== null && value.v === CURRENT_BUNDLE_VERSION;
|
|
313
|
+
}
|
|
314
|
+
function stableReplacer() {
|
|
315
|
+
return function(_key, value) {
|
|
316
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
317
|
+
const sorted = {};
|
|
318
|
+
for (const k of Object.keys(value).sort()) {
|
|
319
|
+
sorted[k] = value[k];
|
|
320
|
+
}
|
|
321
|
+
return sorted;
|
|
322
|
+
}
|
|
323
|
+
return value;
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
var CapturedElementInputSchema = CapturedElementSchema.omit({ id: true });
|
|
327
|
+
var CaptureRequestSchema = z.object({
|
|
328
|
+
/** Append to this session if present; otherwise the daemon opens one. */
|
|
329
|
+
sessionId: z.string().optional(),
|
|
330
|
+
app: AppContextSchema,
|
|
331
|
+
element: CapturedElementInputSchema
|
|
332
|
+
});
|
|
333
|
+
var SubmitRequestSchema = z.object({
|
|
334
|
+
sessionId: z.string().min(1),
|
|
335
|
+
prompt: z.string().min(1),
|
|
336
|
+
execution: ExecutionOptionsSchema.partial().optional(),
|
|
337
|
+
enrichment: EnrichmentSchema.optional()
|
|
338
|
+
});
|
|
339
|
+
var RunStatusSchema = z.enum([
|
|
340
|
+
"pending",
|
|
341
|
+
"running",
|
|
342
|
+
"plan-ready",
|
|
343
|
+
"done",
|
|
344
|
+
"applying",
|
|
345
|
+
"applied",
|
|
346
|
+
"error",
|
|
347
|
+
"apply-error"
|
|
348
|
+
]);
|
|
349
|
+
var SERVER_EVENT_TYPES = [
|
|
350
|
+
"capture-ack",
|
|
351
|
+
"element-removed",
|
|
352
|
+
"agent-started",
|
|
353
|
+
"agent-log",
|
|
354
|
+
"plan-ready",
|
|
355
|
+
"agent-done",
|
|
356
|
+
"agent-error",
|
|
357
|
+
"apply-started",
|
|
358
|
+
"apply-done",
|
|
359
|
+
"apply-error"
|
|
360
|
+
];
|
|
361
|
+
|
|
362
|
+
export { AppContextSchema, AttrLocatorSchema, BehavioralLocatorSchema, CURRENT_BUNDLE_VERSION, CaptureBundleSchema, CaptureRequestSchema, CapturedElementInputSchema, CapturedElementSchema, ConditionsSchema, DEFAULT_DAEMON_HOST, DEFAULT_DAEMON_PORT, DEFAULT_EXECUTION_OPTIONS, DEFAULT_SESSION_TTL_MS, DomLocatorSchema, ElementDescriptorSchema, ElementEnrichmentSchema, EnrichmentSchema, ExecutionModeSchema, ExecutionOptionsSchema, IsolationSchema, LOCATOR_PRIORITY, LocatorSchema, NearContextSchema, RunStatusSchema, SERVER_EVENT_TYPES, SessionSchema, SessionStatusSchema, SourceLocatorSchema, SubmitRequestSchema, appendElement, compareLocators, confirmationReasons, createSession, describeLocator, deserializeBundle, finalizeSession, findElement, isCurrentVersion, isExpired, isSourceResolved, locatorRank, newRunId, newSessionId, nextElementId, parseBundle, parseElementRef, pickBestLocator, rankLocators, removeElement, requiresConfirmation, serializeBundle, touchSession, validateBundle };
|
|
363
|
+
//# sourceMappingURL=index.js.map
|
|
364
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas.ts","../src/ids.ts","../src/locator.ts","../src/defaults.ts","../src/session.ts","../src/bundle.ts","../src/protocol.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\n/**\n * The current {@link CaptureBundle} schema version. Bumped whenever the wire\n * format changes in a backward-incompatible way.\n */\nexport const CURRENT_BUNDLE_VERSION = 5 as const;\n\nconst isoDateTime = z\n .string()\n .datetime({ offset: true })\n .describe('ISO-8601 timestamp');\n\n/* -------------------------------------------------------------------------- */\n/* Locator */\n/* -------------------------------------------------------------------------- */\n\n/**\n * A `source` locator is the most precise: it points at the exact file/line that\n * rendered the element, recovered from a dev-only `data-loc` attribute injected\n * by `@clicksmith/unplugin`.\n */\nexport const SourceLocatorSchema = z.object({\n kind: z.literal('source'),\n file: z.string().min(1),\n line: z.number().int().positive(),\n column: z.number().int().nonnegative().optional(),\n export: z.string().optional(),\n});\n\n/** A stable, author-provided attribute such as `data-testid` or `id`. */\nexport const AttrLocatorSchema = z.object({\n kind: z.literal('attr'),\n attr: z.string().min(1),\n value: z.string(),\n selector: z.string().min(1),\n});\n\n/** An accessibility-based locator: ARIA role + accessible name. */\nexport const BehavioralLocatorSchema = z.object({\n kind: z.literal('behavioral'),\n role: z.string().min(1),\n name: z.string(),\n nth: z.number().int().nonnegative().optional(),\n});\n\n/** Last-resort structural locator: a CSS selector plus a DOM fingerprint. */\nexport const DomLocatorSchema = z.object({\n kind: z.literal('dom'),\n selector: z.string().min(1),\n fingerprint: z.string().min(1),\n});\n\n/**\n * Discriminated union of all locator kinds, ranked exactly\n * `source -> attr -> behavioral -> dom` (see `locator.ts`).\n */\nexport const LocatorSchema = z.discriminatedUnion('kind', [\n SourceLocatorSchema,\n AttrLocatorSchema,\n BehavioralLocatorSchema,\n DomLocatorSchema,\n]);\n\n/* -------------------------------------------------------------------------- */\n/* Captured element */\n/* -------------------------------------------------------------------------- */\n\nexport const ElementDescriptorSchema = z.object({\n tag: z.string().min(1),\n text: z.string().optional(),\n role: z.string().optional(),\n label: z.string().optional(),\n attrs: z.record(z.string()).default({}),\n iconHints: z.array(z.string()).optional(),\n});\n\nexport const NearContextSchema = z.object({\n labels: z.array(z.string()).optional(),\n headings: z.array(z.string()).optional(),\n landmarks: z.array(z.string()).optional(),\n parentText: z.string().optional(),\n});\n\nexport const ConditionsSchema = z.object({\n viewport: z.object({\n w: z.number().int().positive(),\n h: z.number().int().positive(),\n }),\n theme: z.enum(['light', 'dark']).optional(),\n mediaQueries: z.record(z.boolean()).optional(),\n});\n\nexport const CapturedElementSchema = z.object({\n /** 1-based identifier surfaced to users as `#N`. Stable within a session. */\n id: z.number().int().positive(),\n ts: isoDateTime,\n locator: LocatorSchema,\n el: ElementDescriptorSchema,\n near: NearContextSchema.default({}),\n conditions: ConditionsSchema,\n screenshot: z.string().optional(),\n frameworkHints: z.record(z.unknown()).optional(),\n});\n\n/* -------------------------------------------------------------------------- */\n/* Execution options */\n/* -------------------------------------------------------------------------- */\n\nexport const ExecutionModeSchema = z.enum(['plan', 'edit']);\nexport const IsolationSchema = z.enum(['worktree', 'branch', 'inplace']);\n\n/**\n * How a run should be executed. The defaults — `plan` + `worktree` + no\n * auto-apply — are the immutable safe path. Any deviation (edit mode, inplace\n * isolation, or auto-apply) is a risky option requiring explicit confirmation.\n */\nexport const ExecutionOptionsSchema = z.object({\n mode: ExecutionModeSchema.default('plan'),\n isolation: IsolationSchema.default('worktree'),\n autoApply: z.boolean().default(false),\n agentId: z.string().optional(),\n /** Git ref the sandbox should branch from. Defaults to the current HEAD. */\n baseRef: z.string().optional(),\n});\n\n/* -------------------------------------------------------------------------- */\n/* Enrichment */\n/* -------------------------------------------------------------------------- */\n\nexport const ElementEnrichmentSchema = z.object({\n elementId: z.number().int().positive(),\n reviewContext: z.string().optional(),\n impactRadius: z.unknown().optional(),\n affectedFlows: z.unknown().optional(),\n});\n\nexport const EnrichmentSchema = z.object({\n source: z.literal('code-review-graph'),\n perElement: z.array(ElementEnrichmentSchema).default([]),\n warnings: z.array(z.string()).default([]),\n});\n\n/* -------------------------------------------------------------------------- */\n/* App context */\n/* -------------------------------------------------------------------------- */\n\nexport const AppContextSchema = z.object({\n url: z.string().url(),\n route: z.string().min(1),\n page: z.string().optional(),\n});\n\n/* -------------------------------------------------------------------------- */\n/* Capture bundle */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The finalized, agent-ready payload produced when a user submits a session.\n * Version 5.\n */\nexport const CaptureBundleSchema = z.object({\n v: z.literal(CURRENT_BUNDLE_VERSION),\n sessionId: z.string().min(1),\n submittedAt: isoDateTime,\n prompt: z.string().min(1),\n app: AppContextSchema,\n elements: z.array(CapturedElementSchema).min(1),\n execution: ExecutionOptionsSchema,\n enrichment: EnrichmentSchema.optional(),\n});\n\n/* -------------------------------------------------------------------------- */\n/* Session */\n/* -------------------------------------------------------------------------- */\n\nexport const SessionStatusSchema = z.enum(['active', 'submitted', 'expired']);\n\n/**\n * An in-progress capture session held by the daemon before the user submits.\n * Finalizing a session produces a {@link CaptureBundleSchema}.\n */\nexport const SessionSchema = z.object({\n id: z.string().min(1),\n createdAt: isoDateTime,\n updatedAt: isoDateTime,\n expiresAt: isoDateTime,\n status: SessionStatusSchema.default('active'),\n app: AppContextSchema,\n elements: z.array(CapturedElementSchema).default([]),\n prompt: z.string().optional(),\n /**\n * High-water mark of element ids ever assigned. Ensures `#N` ids are never\n * reused, even after the highest-numbered element is removed.\n */\n lastElementId: z.number().int().nonnegative().default(0),\n});\n","/**\n * Platform-neutral identifier helpers. These rely only on the Web Crypto API\n * (`globalThis.crypto`), which is available in modern browsers and Node >= 20,\n * with a deterministic-enough fallback so `core` never imports `node:crypto`.\n */\n\nfunction randomToken(bytes = 8): string {\n const cryptoObj = globalThis.crypto;\n if (cryptoObj?.getRandomValues) {\n const arr = new Uint8Array(bytes);\n cryptoObj.getRandomValues(arr);\n return Array.from(arr, (b) => b.toString(16).padStart(2, '0')).join('');\n }\n // Fallback for exotic runtimes without Web Crypto.\n let out = '';\n for (let i = 0; i < bytes; i++) {\n out += Math.floor(Math.random() * 256)\n .toString(16)\n .padStart(2, '0');\n }\n return out;\n}\n\n/** A new opaque session id, e.g. `cs_lt4f9q_a1b2c3d4`. */\nexport function newSessionId(now: Date = new Date()): string {\n return `cs_${now.getTime().toString(36)}_${randomToken(4)}`;\n}\n\n/** A new opaque run id, e.g. `run_lt4f9q_a1b2c3d4`. */\nexport function newRunId(now: Date = new Date()): string {\n return `run_${now.getTime().toString(36)}_${randomToken(4)}`;\n}\n\n/**\n * Assign the next element id for a session. Ids are 1-based, strictly\n * increasing, and never reused — even after the highest-numbered mark is\n * removed — so user-typed references like `#2` remain stable for the life of\n * the session. Pass the session's high-water mark (`lastElementId`) so removal\n * of the top id still advances the counter.\n */\nexport function nextElementId(existingIds: readonly number[], lastSeen = 0): number {\n return Math.max(lastSeen, ...existingIds, 0) + 1;\n}\n\n/** Parse a `#N` reference (e.g. `\"#3\"`, `\"3\"`, `\"# 3\"`) into a number. */\nexport function parseElementRef(ref: string): number | undefined {\n const match = ref.trim().match(/^#?\\s*(\\d+)$/);\n if (!match) return undefined;\n const n = Number.parseInt(match[1]!, 10);\n return Number.isSafeInteger(n) && n > 0 ? n : undefined;\n}\n","import type { Locator, LocatorKind } from './types.js';\n\n/**\n * The canonical locator priority, best first. This ordering is a hard contract\n * shared by the extension (which picks the best locator it can build) and the\n * agent instructions (which teach the agent to trust higher-ranked locators).\n */\nexport const LOCATOR_PRIORITY = ['source', 'attr', 'behavioral', 'dom'] as const;\n\nconst RANK: Record<LocatorKind, number> = {\n source: 0,\n attr: 1,\n behavioral: 2,\n dom: 3,\n};\n\n/** Numeric rank of a locator kind; lower is more precise. */\nexport function locatorRank(kind: LocatorKind): number {\n return RANK[kind];\n}\n\n/**\n * Comparator for `Array.prototype.sort`, ordering locators best-first per\n * {@link LOCATOR_PRIORITY}.\n */\nexport function compareLocators(a: Locator, b: Locator): number {\n return locatorRank(a.kind) - locatorRank(b.kind);\n}\n\n/** Return a new array of locators sorted best-first. Does not mutate input. */\nexport function rankLocators(locators: readonly Locator[]): Locator[] {\n return [...locators].sort(compareLocators);\n}\n\n/** The single most precise locator from a list, or `undefined` if empty. */\nexport function pickBestLocator(locators: readonly Locator[]): Locator | undefined {\n if (locators.length === 0) return undefined;\n return rankLocators(locators)[0];\n}\n\n/**\n * A compact, human- and agent-readable description of a locator, suitable for\n * embedding in instructions or logs.\n */\nexport function describeLocator(locator: Locator): string {\n switch (locator.kind) {\n case 'source':\n return `source:${locator.file}:${locator.line}${\n locator.column != null ? `:${locator.column}` : ''\n }`;\n case 'attr':\n return `attr:[${locator.attr}=\"${locator.value}\"]`;\n case 'behavioral':\n return `role:${locator.role}${locator.name ? ` name=\"${locator.name}\"` : ''}${\n locator.nth != null ? ` (nth=${locator.nth})` : ''\n }`;\n case 'dom':\n return `dom:${locator.selector}`;\n }\n}\n\n/** Whether a locator points directly at source (the strongest signal). */\nexport function isSourceResolved(locator: Locator): boolean {\n return locator.kind === 'source';\n}\n","import type { ExecutionOptions } from './types.js';\n\n/** Default localhost port the daemon listens on. */\nexport const DEFAULT_DAEMON_PORT = 8722;\n\n/** Default localhost host. ClickSmith only ever binds loopback. */\nexport const DEFAULT_DAEMON_HOST = '127.0.0.1';\n\n/** Default time-to-live for an unfinished capture session: 24 hours. */\nexport const DEFAULT_SESSION_TTL_MS = 24 * 60 * 60 * 1000;\n\n/**\n * The immutable safe defaults: plan mode, worktree isolation, no auto-apply.\n * Any change away from these is considered a \"risky option\".\n */\nexport const DEFAULT_EXECUTION_OPTIONS: ExecutionOptions = {\n mode: 'plan',\n isolation: 'worktree',\n autoApply: false,\n};\n\n/**\n * Whether a set of execution options deviates from the safe defaults and\n * therefore requires explicit user confirmation in the extension/CLI:\n * non-plan mode, in-place isolation, or auto-apply.\n */\nexport function requiresConfirmation(execution: ExecutionOptions): boolean {\n return execution.mode !== 'plan' || execution.isolation === 'inplace' || execution.autoApply;\n}\n\n/** Human-readable reasons a given execution config is considered risky. */\nexport function confirmationReasons(execution: ExecutionOptions): string[] {\n const reasons: string[] = [];\n if (execution.mode !== 'plan') {\n reasons.push('Edit mode lets the agent modify files directly instead of only proposing a plan.');\n }\n if (execution.isolation === 'inplace') {\n reasons.push('In-place isolation runs against your working tree instead of a throwaway worktree.');\n }\n if (execution.autoApply) {\n reasons.push('Auto-apply merges the agent’s changes back without a manual review step.');\n }\n return reasons;\n}\n","import { CaptureBundleSchema, CURRENT_BUNDLE_VERSION } from './schemas.js';\nimport { newSessionId, nextElementId } from './ids.js';\nimport { DEFAULT_EXECUTION_OPTIONS, DEFAULT_SESSION_TTL_MS } from './defaults.js';\nimport type {\n AppContext,\n CaptureBundle,\n CapturedElement,\n CapturedElementInput,\n ExecutionOptions,\n Session,\n} from './types.js';\n\nexport interface CreateSessionInput {\n app: AppContext;\n now?: Date;\n ttlMs?: number;\n id?: string;\n}\n\n/** Create a fresh, empty, active capture session. Pure. */\nexport function createSession(input: CreateSessionInput): Session {\n const now = input.now ?? new Date();\n const ttlMs = input.ttlMs ?? DEFAULT_SESSION_TTL_MS;\n const iso = now.toISOString();\n return {\n id: input.id ?? newSessionId(now),\n createdAt: iso,\n updatedAt: iso,\n expiresAt: new Date(now.getTime() + ttlMs).toISOString(),\n status: 'active',\n app: input.app,\n elements: [],\n lastElementId: 0,\n };\n}\n\n/**\n * Append a captured element to a session, assigning the next stable id. Returns\n * a new session plus the fully-formed element (so callers know the assigned id).\n * Pure — the input session is not mutated.\n */\nexport function appendElement(\n session: Session,\n input: CapturedElementInput,\n now: Date = new Date(),\n): { session: Session; element: CapturedElement } {\n const id = nextElementId(\n session.elements.map((e) => e.id),\n session.lastElementId,\n );\n const element: CapturedElement = { ...input, id };\n const next: Session = {\n ...session,\n elements: [...session.elements, element],\n lastElementId: id,\n updatedAt: now.toISOString(),\n };\n return { session: next, element };\n}\n\n/**\n * Remove a captured element by id. Ids are never renumbered, keeping existing\n * `#N` references valid. Returns the new session and whether anything changed.\n * Pure.\n */\nexport function removeElement(\n session: Session,\n elementId: number,\n now: Date = new Date(),\n): { session: Session; removed: boolean } {\n const elements = session.elements.filter((e) => e.id !== elementId);\n const removed = elements.length !== session.elements.length;\n if (!removed) return { session, removed: false };\n return {\n session: { ...session, elements, updatedAt: now.toISOString() },\n removed: true,\n };\n}\n\n/** Find a captured element by its `#N` id. */\nexport function findElement(session: Session, elementId: number): CapturedElement | undefined {\n return session.elements.find((e) => e.id === elementId);\n}\n\n/** Whether a session has passed its expiry (and was never submitted). */\nexport function isExpired(session: Session, now: Date = new Date()): boolean {\n if (session.status === 'submitted') return false;\n return new Date(session.expiresAt).getTime() <= now.getTime();\n}\n\n/** Slide a session's expiry forward by `ttlMs` from `now`. Pure. */\nexport function touchSession(\n session: Session,\n now: Date = new Date(),\n ttlMs: number = DEFAULT_SESSION_TTL_MS,\n): Session {\n return {\n ...session,\n updatedAt: now.toISOString(),\n expiresAt: new Date(now.getTime() + ttlMs).toISOString(),\n };\n}\n\nexport interface FinalizeInput {\n prompt: string;\n execution?: ExecutionOptions;\n submittedAt?: Date;\n enrichment?: CaptureBundle['enrichment'];\n}\n\n/**\n * Finalize a session into a validated v5 {@link CaptureBundle}. Throws if the\n * session has no elements or the prompt is empty. Does not mutate the session.\n */\nexport function finalizeSession(session: Session, input: FinalizeInput): CaptureBundle {\n if (session.elements.length === 0) {\n throw new Error(`Cannot finalize session ${session.id}: no captured elements.`);\n }\n if (!input.prompt.trim()) {\n throw new Error(`Cannot finalize session ${session.id}: prompt is empty.`);\n }\n const bundle: CaptureBundle = {\n v: CURRENT_BUNDLE_VERSION,\n sessionId: session.id,\n submittedAt: (input.submittedAt ?? new Date()).toISOString(),\n prompt: input.prompt.trim(),\n app: session.app,\n elements: session.elements,\n execution: input.execution ?? { ...DEFAULT_EXECUTION_OPTIONS },\n ...(input.enrichment ? { enrichment: input.enrichment } : {}),\n };\n // Validate before handing off; surfaces schema regressions early.\n return CaptureBundleSchema.parse(bundle);\n}\n","import type { z } from 'zod';\nimport { CaptureBundleSchema, CURRENT_BUNDLE_VERSION } from './schemas.js';\nimport type { CaptureBundle } from './types.js';\n\nexport type ValidationResult =\n | { ok: true; bundle: CaptureBundle }\n | { ok: false; error: z.ZodError };\n\n/** Validate an unknown value as a {@link CaptureBundle} without throwing. */\nexport function validateBundle(value: unknown): ValidationResult {\n const result = CaptureBundleSchema.safeParse(value);\n if (result.success) return { ok: true, bundle: result.data };\n return { ok: false, error: result.error };\n}\n\n/** Validate and throw on failure (with a readable message). */\nexport function parseBundle(value: unknown): CaptureBundle {\n const result = validateBundle(value);\n if (result.ok) return result.bundle;\n throw new Error(`Invalid CaptureBundle: ${result.error.message}`);\n}\n\n/** Deterministically serialize a bundle to JSON (stable key order, 2-space). */\nexport function serializeBundle(bundle: CaptureBundle): string {\n return JSON.stringify(parseBundle(bundle), stableReplacer(), 2);\n}\n\n/** Parse a JSON string into a validated bundle. */\nexport function deserializeBundle(json: string): CaptureBundle {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (err) {\n throw new Error(`CaptureBundle is not valid JSON: ${(err as Error).message}`);\n }\n return parseBundle(parsed);\n}\n\n/** Whether a value claims to be the current bundle version. */\nexport function isCurrentVersion(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { v?: unknown }).v === CURRENT_BUNDLE_VERSION\n );\n}\n\n/**\n * A JSON.stringify replacer that emits object keys in sorted order, producing\n * byte-stable output for hashing / golden-file comparisons.\n */\nfunction stableReplacer(): (this: unknown, key: string, value: unknown) => unknown {\n return function (_key, value) {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {};\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k];\n }\n return sorted;\n }\n return value;\n };\n}\n","import { z } from 'zod';\nimport {\n AppContextSchema,\n CapturedElementSchema,\n EnrichmentSchema,\n ExecutionOptionsSchema,\n} from './schemas.js';\nimport type { CaptureBundle, CapturedElement, Session } from './types.js';\n\n/* -------------------------------------------------------------------------- */\n/* HTTP request / response DTOs */\n/* -------------------------------------------------------------------------- */\n\n/** The element payload the extension sends (everything but the daemon id). */\nexport const CapturedElementInputSchema = CapturedElementSchema.omit({ id: true });\n\nexport const CaptureRequestSchema = z.object({\n /** Append to this session if present; otherwise the daemon opens one. */\n sessionId: z.string().optional(),\n app: AppContextSchema,\n element: CapturedElementInputSchema,\n});\nexport type CaptureRequest = z.infer<typeof CaptureRequestSchema>;\n\nexport interface CaptureResponse {\n sessionId: string;\n element: CapturedElement;\n}\n\nexport const SubmitRequestSchema = z.object({\n sessionId: z.string().min(1),\n prompt: z.string().min(1),\n execution: ExecutionOptionsSchema.partial().optional(),\n enrichment: EnrichmentSchema.optional(),\n});\nexport type SubmitRequest = z.infer<typeof SubmitRequestSchema>;\n\nexport interface SubmitResponse {\n runId: string;\n bundle: CaptureBundle;\n}\n\nexport interface ApplyResponse {\n applied: boolean;\n commit?: string;\n conflicts?: string[];\n}\n\nexport interface HealthResponse {\n ok: true;\n name: 'clicksmith-daemon';\n version: string;\n host: string;\n port: number;\n repoRoot: string | null;\n activeSessions: number;\n}\n\nexport type SessionResponse = Session;\n\nexport interface RemoveElementResponse {\n removed: boolean;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Run state */\n/* -------------------------------------------------------------------------- */\n\nexport const RunStatusSchema = z.enum([\n 'pending',\n 'running',\n 'plan-ready',\n 'done',\n 'applying',\n 'applied',\n 'error',\n 'apply-error',\n]);\nexport type RunStatus = z.infer<typeof RunStatusSchema>;\n\nexport interface RunSummary {\n runId: string;\n sessionId: string;\n agentId: string;\n status: RunStatus;\n createdAt: string;\n sandbox: SandboxInfo | null;\n}\n\nexport interface SandboxInfo {\n isolation: 'worktree' | 'branch' | 'inplace';\n path: string;\n branch: string | null;\n baseCommit: string;\n}\n\n/* -------------------------------------------------------------------------- */\n/* WebSocket event protocol */\n/* -------------------------------------------------------------------------- */\n\n/** Events streamed from daemon to the extension over the WebSocket. */\nexport type ServerEvent =\n | { type: 'capture-ack'; sessionId: string; element: CapturedElement }\n | { type: 'element-removed'; sessionId: string; elementId: number }\n | { type: 'agent-started'; runId: string; sessionId: string; agentId: string; sandbox: SandboxInfo | null }\n | { type: 'agent-log'; runId: string; stream: 'stdout' | 'stderr'; chunk: string }\n | { type: 'plan-ready'; runId: string; plan?: string; diff?: string }\n | { type: 'agent-done'; runId: string; exitCode: number }\n | { type: 'agent-error'; runId: string; message: string }\n | { type: 'apply-started'; runId: string }\n | { type: 'apply-done'; runId: string; commit?: string }\n | { type: 'apply-error'; runId: string; message: string; conflicts?: string[] };\n\nexport type ServerEventType = ServerEvent['type'];\n\n/** Messages the extension may send to the daemon over the WebSocket. */\nexport type ClientMessage =\n | { type: 'subscribe'; sessionId?: string }\n | { type: 'ping' };\n\n/** Ordered list of every WS event type, useful for tests and docs. */\nexport const SERVER_EVENT_TYPES = [\n 'capture-ack',\n 'element-removed',\n 'agent-started',\n 'agent-log',\n 'plan-ready',\n 'agent-done',\n 'agent-error',\n 'apply-started',\n 'apply-done',\n 'apply-error',\n] as const satisfies readonly ServerEventType[];\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@clicksmith/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Shared schemas, types, locator ranking, and session/bundle logic for ClickSmith. Platform-neutral (zod only).",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"zod": "^3.23.8"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsup",
|
|
24
|
+
"dev": "tsup --watch",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"lint": "eslint src",
|
|
29
|
+
"clean": "rimraf dist .turbo"
|
|
30
|
+
}
|
|
31
|
+
}
|