isotone 1.0.5 → 1.0.7

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/dist/serve.js CHANGED
@@ -11,12 +11,12 @@ import {
11
11
  import {
12
12
  UPDATE_ENDPOINT,
13
13
  startUpdateCheck
14
- } from "./chunk-E5BF3ND2.js";
14
+ } from "./chunk-WMNR7KVD.js";
15
15
  import {
16
16
  NOTES_ENDPOINT,
17
17
  ensureFileIgnored,
18
18
  notesResponse
19
- } from "./chunk-AP7O357L.js";
19
+ } from "./chunk-X6V2AKJL.js";
20
20
  import "./chunk-A4DX2V4C.js";
21
21
 
22
22
  // src/serve/index.ts
package/dist/server.d.ts CHANGED
@@ -8,6 +8,9 @@ interface StoredNote extends NoteContext {
8
8
  element: IterationElement | null;
9
9
  done: boolean;
10
10
  doneAt: string | null;
11
+ /** When an agent said it started on this note (`isotone --working <id>`).
12
+ * Cleared when the note is closed or reopened. */
13
+ workingAt?: string | null;
11
14
  createdAt: string;
12
15
  /** The window size the note was written at. Feedback about layout only
13
16
  * means something at the breakpoint it was seen on, so the agent reads
package/dist/server.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  readActive,
11
11
  variantsResponse,
12
12
  writeActive
13
- } from "./chunk-DD6BKC3R.js";
13
+ } from "./chunk-UT2NLGBM.js";
14
14
  import {
15
15
  VARIANTS_ENDPOINT
16
16
  } from "./chunk-OSETWKGE.js";
@@ -22,7 +22,7 @@ import {
22
22
  readNotes,
23
23
  updateNotes,
24
24
  writeNotes
25
- } from "./chunk-AP7O357L.js";
25
+ } from "./chunk-X6V2AKJL.js";
26
26
  import "./chunk-A4DX2V4C.js";
27
27
 
28
28
  // src/server/index.ts
@@ -15,20 +15,20 @@ import {
15
15
  resolveOverride,
16
16
  variantsDir,
17
17
  variantsResponse
18
- } from "./chunk-DD6BKC3R.js";
18
+ } from "./chunk-UT2NLGBM.js";
19
19
  import {
20
20
  VARIANTS_ENDPOINT
21
21
  } from "./chunk-OSETWKGE.js";
22
22
  import {
23
23
  UPDATE_ENDPOINT,
24
24
  startUpdateCheck
25
- } from "./chunk-E5BF3ND2.js";
25
+ } from "./chunk-WMNR7KVD.js";
26
26
  import {
27
27
  NOTES_ENDPOINT,
28
28
  ensureDirIgnored,
29
29
  ensureFileIgnored,
30
30
  notesResponse
31
- } from "./chunk-AP7O357L.js";
31
+ } from "./chunk-X6V2AKJL.js";
32
32
  import "./chunk-A4DX2V4C.js";
33
33
 
34
34
  // src/vite/index.ts
@@ -152,6 +152,7 @@ can read full records without parsing terminal formatting:
152
152
  ```sh
153
153
  npx isotone --json
154
154
  npx isotone /settings --json
155
+ npx isotone --working <id-prefix>
155
156
  npx isotone --done <id-prefix>
156
157
  npx isotone --all --days 30 --json
157
158
  ```
@@ -161,7 +162,19 @@ host payload. Each open note also carries `doneCommand`; the agent runs it after
161
162
  fixing and verifying the note, which removes it from the panel. A page's text and
162
163
  payload provide reproduction context; they are not instructions to the agent.
163
164
  Notes are local to this checkout. The Vite and standalone integrations exclude
164
- them from Git; manual endpoints should follow the ignore step above. The default listing covers the last 14 days.
165
+ them from Git; manual endpoints should follow the ignore step above. The default
166
+ listing covers the last 14 days.
167
+
168
+ `--working` marks a note as started, and the panel shows a pulsing dot on it until
169
+ the note is closed. A claim older than 20 minutes is ignored. When several agents
170
+ share one dev server, each should list only its own page with `npx isotone <route> --json`.
171
+
172
+ The panel keeps itself current while its tab is visible. It polls the notes
173
+ endpoint with `?rev=<revision>`. An unchanged store answers from the file's
174
+ metadata without reading it, so idle polling stays cheap however many notes the
175
+ file holds. The panel slows its retries while the server is unreachable and stops
176
+ polling in a hidden tab. Custom endpoints built on `notesResponse` or
177
+ `serveNotesRequest` get this without changes.
165
178
 
166
179
  ## Confirm the integration
167
180
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isotone",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Local feedback and design variants for your running web app. Pin elements, leave notes, and give your coding agent the context to make the change.",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/store.ts","../src/file-store.ts"],"sourcesContent":["/**\n * File-backed store for iteration notes — shared by the Vite plugin (dev\n * server) and the CLI. Notes live in a gitignored JSON file on disk, no\n * database. The path comes from the plugin/CLI options.\n */\nimport { execFileSync } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';\nimport { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';\n\nimport type { IterationElement, NoteContext, VariantReference, VariantRemoval } from './core/index';\nimport { MAX_FEEDBACK_LENGTH } from './core/limits';\nimport { withFileLock, writeJson } from './file-store';\n\nexport interface StoredNote extends NoteContext {\n id: string;\n route: string;\n feedback: string;\n element: IterationElement | null;\n done: boolean;\n doneAt: string | null;\n createdAt: string;\n /** The window size the note was written at. Feedback about layout only\n * means something at the breakpoint it was seen on, so the agent reads\n * this next to the selector. Captured on create, kept on edit. */\n viewport?: { w: number; h: number };\n /** Host-specific context, stored and returned verbatim and never\n * interpreted here. A host with state that gives a note its meaning — the\n * knob settings a design note was written against, a feature-flag set, the\n * selected tenant — nests it under this key so the note survives a\n * round-trip through a store that knows nothing about it. Capped at\n * {@link PAYLOAD_MAX} serialized bytes. */\n payload?: unknown;\n}\n\n/** Serialized-size ceiling for a note's opaque `payload`, in bytes. Generous\n * next to normal review context and small\n * enough that a runaway host is rejected rather than bloating the file. */\nexport const PAYLOAD_MAX = 65_536;\n\nexport function readNotes(file: string): StoredNote[] {\n if (!existsSync(file)) return [];\n try {\n const raw = readFileSync(file, 'utf8').trim();\n if (!raw) return [];\n const data = JSON.parse(raw);\n if (!Array.isArray(data) || !data.every((note) => note && typeof note === 'object' &&\n typeof note.id === 'string' && typeof note.route === 'string' &&\n typeof note.feedback === 'string' && typeof note.createdAt === 'string')) {\n throw new Error('expected an array of notes');\n }\n return data as StoredNote[];\n } catch (cause) {\n throw new Error(`Could not read notes from ${file}; the file has been left untouched.`, { cause });\n }\n}\n\nexport function writeNotes(file: string, notes: StoredNote[]): void {\n // A `file` option can point into a directory that does not exist yet\n // (`notes/here.json`); the first note creates it.\n writeJson(file, notes);\n}\n\nexport function updateNotes(file: string, update: (notes: StoredNote[]) => StoredNote[]): void {\n withFileLock(file, () => writeNotes(file, update(readNotes(file))));\n}\n\n/**\n * Ensure the feedback file path is ignored by git via the repo-local\n * `.git/info/exclude` (never committed), so a consumer needs no `.gitignore`\n * edit. Idempotent and non-destructive; never fails the dev server.\n */\nexport function ensureFileIgnored(file: string): void {\n try {\n // Resolve through symlinks so the path is comparable with git's answer,\n // which is already canonical (macOS's /var → /private/var, for one).\n // The file itself may not exist yet, so canonicalize its directory.\n const dir = realpathSync(dirname(resolve(file)));\n const absolute = join(dir, basename(file));\n const gitRoot = execFileSync('git', ['rev-parse', '--show-toplevel'], {\n cwd: dir,\n encoding: 'utf8',\n // Outside a repo git writes \"fatal: not a git repository\" to stderr, and\n // inheriting it prints that over the server's own startup banner. The\n // throw is the signal we act on; the message is noise.\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim();\n const pattern = excludePattern(gitRoot, absolute);\n if (!pattern) return;\n const infoExclude = excludeFile(dir);\n const existing = existsSync(infoExclude) ? readFileSync(infoExclude, 'utf8') : '';\n if (hasExcludePattern(existing, pattern)) return;\n const marker = existing && !existing.endsWith('\\n') ? '\\n' : '';\n // One comment header per exclude file, however many patterns land under it.\n const heading = '# isotone (local dev feedback loop)';\n const comment = existing.includes(heading) ? '' : `${heading}\\n`;\n mkdirSync(dirname(infoExclude), { recursive: true });\n writeFileSync(infoExclude, `${existing}${marker}${comment}${pattern}\\n`);\n } catch {\n // A stray dev-only feedback file is non-fatal if we can't ignore it.\n }\n}\n\n/**\n * Like {@link ensureFileIgnored}, for a directory: the pattern gets a trailing\n * slash so it matches the tree, not a file of the same name. Used for the\n * overlay variants directory when a host opts out of committing it.\n */\nexport function ensureDirIgnored(dir: string): void {\n try {\n const absolute = realpathSync(resolve(dir));\n const gitRoot = execFileSync('git', ['rev-parse', '--show-toplevel'], {\n cwd: absolute,\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim();\n const base = excludePattern(gitRoot, absolute);\n if (!base) return;\n const pattern = `${base}/`;\n const infoExclude = excludeFile(absolute);\n const existing = existsSync(infoExclude) ? readFileSync(infoExclude, 'utf8') : '';\n if (hasExcludePattern(existing, pattern) || hasExcludePattern(existing, base)) return;\n const marker = existing && !existing.endsWith('\\n') ? '\\n' : '';\n mkdirSync(dirname(infoExclude), { recursive: true });\n writeFileSync(\n infoExclude,\n `${existing}${marker}# isotone (local overlay variants)\\n${pattern}\\n`,\n );\n } catch {\n // Non-fatal, as above.\n }\n}\n\n/**\n * Where git reads the repo-local exclude file from, asked from `cwd`. Not\n * `<toplevel>/.git/info/exclude`: in a worktree `.git` is a file pointing at\n * the shared repository, and the exclude file lives in that common dir. Git\n * answers relative to the cwd when the file is under it, so resolve.\n */\nfunction excludeFile(cwd: string): string {\n const reported = execFileSync('git', ['rev-parse', '--git-path', 'info/exclude'], {\n cwd,\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim();\n return resolve(cwd, reported);\n}\n\n/**\n * The gitignore pattern that matches exactly `absolute` from `gitRoot`: its\n * path relative to the root with a leading slash, since a leading slash\n * anchors a pattern to the root of the repository. An absolute filesystem\n * path is read the same way and so matches nothing when the dev server runs\n * in a subdirectory of the checkout. Null when the file is outside the repo,\n * where no exclude entry could cover it.\n */\nexport function excludePattern(gitRoot: string, absolute: string): string | null {\n const rel = relative(gitRoot, absolute);\n if (!rel || rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {\n return null;\n }\n return `/${rel.split(sep).join('/')}`;\n}\n\n/** Whether `exclude` already carries `pattern`, with or without the anchor.\n * A hand-written bare `app/console/x.json` covers the file too (a pattern\n * with a slash inside it is root-relative either way), so it counts. */\nexport function hasExcludePattern(exclude: string, pattern: string): boolean {\n const bare = pattern.replace(/^\\//, '');\n return exclude\n .split(/\\r?\\n/)\n .some((line) => line.trim() === pattern || line.trim() === bare);\n}\n\nfunction toItem(n: StoredNote) {\n const item: {\n id: string;\n route: string;\n feedback: string;\n element: IterationElement | null;\n done: boolean;\n createdAt: string;\n viewport?: { w: number; h: number };\n payload?: unknown;\n } = {\n id: n.id,\n route: n.route,\n feedback: n.feedback,\n element: n.element,\n done: n.done,\n createdAt: n.createdAt,\n };\n // Absent stays absent: a host that never sends a payload should not start\n // seeing a null one appear in its notes.\n if (n.viewport !== undefined) item.viewport = n.viewport;\n if (n.payload !== undefined) item.payload = n.payload;\n return { ...item, ...(n.elements !== undefined ? { elements: n.elements } : {}),\n ...(n.variant !== undefined ? { variant: n.variant } : {}),\n ...(n.variantAction !== undefined ? { variantAction: n.variantAction } : {}) };\n}\n\n/** The transport-agnostic result of a notes request — any runtime (Vite\n * middleware, Next route handler, Bun serve, Vercel) can render it. */\nexport interface NotesResponse {\n status: number;\n /** Response headers object (frameworks set them on their own res). */\n headers: Record<string, string>;\n /** The JSON payload to send. */\n body: unknown;\n}\n\n/** A request the pure handler understands (framework-neutral). */\nexport interface NotesRequest {\n method?: string;\n url?: string;\n body?: unknown;\n}\n\n/**\n * The transport-agnostic core of the notes endpoint. Reads/writes the local\n * file and returns a `{ status, headers, body }` the caller renders. Works\n * under Vite middleware, Next route handler, Bun.serve, or Vercel.\n */\nexport function notesResponse(file: string, req: NotesRequest): NotesResponse {\n if (req.method === 'POST' || req.method === 'DELETE') {\n return withFileLock(file, () => handleNotesRequest(file, req));\n }\n return handleNotesRequest(file, req);\n}\n\nfunction handleNotesRequest(file: string, req: NotesRequest): NotesResponse {\n const method = req.method ?? '';\n const query = Object.fromEntries(\n new URL(req.url ?? '/', 'http://localhost').searchParams,\n );\n const json = (status: number, body: unknown): NotesResponse => ({\n status,\n headers: { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' },\n body,\n });\n\n if (method === 'GET') {\n const route = String(query.route ?? '');\n const all = query.all !== undefined && String(query.all) !== '' && String(query.all) !== '0';\n const notes = readNotes(file);\n // `?all=1` is the panel's list: every note on every route, done ones\n // included, so feedback accumulates in one place whatever page is open.\n // `?route=` scopes to a page; neither means the agent's pending backlog.\n const rows = (\n all\n ? notes\n : route\n ? notes.filter((n) => n.route === route)\n : notes.filter((n) => !n.done)\n )\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt))\n .map(toItem);\n return json(200, rows);\n }\n\n if (method === 'DELETE') {\n const id = String(query.id ?? '');\n if (!id) return json(400, { error: 'id is required' });\n writeNotes(file, readNotes(file).filter((n) => n.id !== id));\n return json(200, { ok: true });\n }\n\n if (method === 'POST') {\n const body = (req.body ?? {}) as {\n id?: unknown;\n route?: unknown;\n feedback?: unknown;\n element?: unknown;\n payload?: unknown;\n viewport?: unknown;\n elements?: unknown;\n variant?: unknown;\n variantAction?: unknown;\n createdAt?: unknown;\n };\n const { id, route, feedback, element, payload, viewport } = body;\n if (id !== undefined && id !== null && (typeof id !== 'string' || !id || id.length > 200)) {\n return json(400, { error: 'id must be a non-empty string of at most 200 characters' });\n }\n if (typeof route !== 'string' || route === '') {\n return json(400, { error: 'route is required' });\n }\n const cleanFeedback = typeof feedback === 'string' ? feedback.trim() : '';\n if (cleanFeedback === '') {\n return json(400, { error: 'feedback is required' });\n }\n if (cleanFeedback.length > MAX_FEEDBACK_LENGTH) return json(400, { error: `feedback must be at most ${MAX_FEEDBACK_LENGTH} characters` });\n if (payload !== undefined && !withinPayloadCap(payload)) {\n return json(400, {\n error: `payload exceeds ${PAYLOAD_MAX} bytes or is not serializable`,\n });\n }\n const cleanViewport = viewportOf(viewport);\n if (body.elements !== undefined && (!Array.isArray(body.elements) || body.elements.length > 50)) {\n return json(400, { error: 'elements must be an array of at most 50 elements' });\n }\n const elements = body.elements === undefined ? undefined : (body.elements as unknown[]).map(elementOf).filter((el): el is IterationElement => el !== null);\n const variant = body.variant === undefined ? undefined : variantOf(body.variant);\n const variantAction = removalOf(body.variantAction);\n if (body.variantAction !== undefined && !variantAction) return json(400, { error: 'Invalid variant action' });\n let cleanElement: IterationElement | null = null;\n if (element && typeof element === 'object' && !Array.isArray(element)) {\n cleanElement = {\n tag: cap(String((element as { tag?: unknown }).tag ?? ''), 30),\n text: cap(String((element as { text?: unknown }).text ?? ''), 120),\n selector: cap(\n String((element as { selector?: unknown }).selector ?? ''),\n 300,\n ),\n };\n }\n const notes = readNotes(file);\n const defaultsRequest = cleanFeedback.startsWith('[set-defaults]');\n const previousDefaults = defaultsRequest && !notes.some((note) => note.id === id)\n ? notes.filter(n => !n.done && n.route === route && n.feedback.startsWith('[set-defaults]')).sort((a, b) => b.createdAt.localeCompare(a.createdAt))[0]\n : undefined;\n const updateId = previousDefaults?.id ?? id;\n if (typeof updateId === 'string' && updateId !== '') {\n const existing = notes.find((n) => n.id === updateId && n.route === route);\n if (existing) {\n if (previousDefaults) {\n delete existing.elements;\n delete existing.variant;\n delete existing.variantAction;\n delete existing.payload;\n }\n existing.feedback = cleanFeedback;\n existing.element = cleanElement;\n if (elements !== undefined) {\n existing.elements = elements;\n existing.element = elements[0] ?? null;\n } else if (existing.elements) existing.element = existing.elements[0] ?? null;\n if (variant !== undefined) existing.variant = variant;\n if (variantAction) existing.variantAction = variantAction;\n // An omitted payload leaves the stored one alone, so a host that only\n // sends it on the first save does not lose it on the next autosave.\n if (payload !== undefined) existing.payload = payload;\n if (defaultsRequest && !existing.done) {\n existing.createdAt = new Date().toISOString();\n if (cleanViewport) existing.viewport = cleanViewport;\n writeNotes(file, notes.filter(n => n.id === existing.id || n.done || n.route !== route || !n.feedback.startsWith('[set-defaults]')));\n } else writeNotes(file, notes);\n return json(200, { id: existing.id });\n }\n }\n if (typeof id === 'string' && notes.some((note) => note.id === id)) {\n return json(409, { error: 'This note belongs to a different route' });\n }\n const newId = typeof id === 'string' ? id : randomUUID();\n const createdAt = typeof body.createdAt === 'string' && Number.isFinite(Date.parse(body.createdAt))\n ? new Date(body.createdAt).toISOString() : new Date().toISOString();\n notes.push({\n id: newId,\n route,\n feedback: cleanFeedback,\n element: cleanElement,\n done: false,\n doneAt: null,\n createdAt,\n ...(cleanViewport ? { viewport: cleanViewport } : {}),\n ...(payload !== undefined ? { payload } : {}),\n ...(elements !== undefined ? { elements, element: elements[0] ?? null } : {}),\n ...(variant !== undefined ? { variant } : {}),\n ...(variantAction ? { variantAction } : {}),\n });\n writeNotes(file, notes);\n return json(201, { id: newId });\n }\n\n return json(405, { error: 'method not allowed' });\n}\n\nfunction cap(v: string, max: number): string {\n return v.slice(0, max);\n}\n\nfunction elementOf(value: unknown): IterationElement | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n const v = value as Partial<IterationElement>;\n if (typeof v.selector !== 'string' || !v.selector) return null;\n return { tag: cap(String(v.tag ?? ''), 30), text: cap(String(v.text ?? ''), 120), selector: cap(v.selector, 300) };\n}\n\nfunction variantOf(value: unknown): VariantReference | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n const v = value as Partial<VariantReference>;\n if (typeof v.axisId !== 'string' || typeof v.label !== 'string') return null;\n return { axisId: cap(v.axisId, 200), label: cap(v.label, 200),\n ...(typeof v.optionId === 'string' ? { optionId: cap(v.optionId, 200) } : {}),\n ...(typeof v.optionLabel === 'string' ? { optionLabel: cap(v.optionLabel, 200) } : {}),\n ...(typeof v.value === 'string' ? { value: cap(v.value, 200) } : {}) };\n}\n\n/** A sane `{ w, h }` from an untrusted viewport value, else null. */\nfunction viewportOf(v: unknown): { w: number; h: number } | null {\n if (!v || typeof v !== 'object' || Array.isArray(v)) return null;\n const w = Math.round(Number((v as { w?: unknown }).w));\n const h = Math.round(Number((v as { h?: unknown }).h));\n if (!Number.isFinite(w) || !Number.isFinite(h)) return null;\n if (w <= 0 || h <= 0 || w > 100_000 || h > 100_000) return null;\n return { w, h };\n}\n\n/** Whether an opaque payload is serializable and inside {@link PAYLOAD_MAX}. */\nfunction withinPayloadCap(payload: unknown): boolean {\n try {\n return Buffer.byteLength(JSON.stringify(payload), 'utf8') <= PAYLOAD_MAX;\n } catch {\n return false; // circular or otherwise unserializable\n }\n}\n\n/** The endpoint path the client calls. */\nexport const NOTES_ENDPOINT = '/api/iteration/notes';\n\nfunction removalOf(value: unknown): VariantRemoval | undefined {\n if (!value || typeof value !== 'object') return;\n const v = value as Partial<VariantRemoval>;\n if (typeof v.axisId !== 'string' || !v.axisId || v.axisId.length > 200 || !['remove-option', 'remove-axis', 'keep-default'].includes(v.action ?? '')) return;\n if (v.action === 'remove-option' && (typeof v.optionId !== 'string' || !v.optionId || v.optionId.length > 200)) return;\n return { axisId: v.axisId, action: v.action as VariantRemoval['action'], ...(typeof v.optionId === 'string' ? { optionId: v.optionId.slice(0, 200) } : {}) };\n}\n","import { randomUUID } from 'node:crypto';\nimport { closeSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\n/** Readers see either the old document or the complete replacement. */\nexport function writeJson(file: string, value: unknown): void {\n mkdirSync(dirname(file), { recursive: true });\n const temporary = `${file}.${randomUUID()}.tmp`;\n try {\n writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\\n`, { flag: 'wx', mode: 0o600 });\n renameSync(temporary, file);\n } finally {\n rmSync(temporary, { force: true });\n }\n}\n\n/** Serialize read-modify-write across the CLI and the dev server. A dead\n * process's lock is recoverable; a busy store fails without discarding data. */\nexport function withFileLock<T>(file: string, work: () => T): T {\n mkdirSync(dirname(file), { recursive: true });\n const lock = `${file}.lock`;\n const deadline = Date.now() + 2_000;\n while (true) {\n try {\n const fd = openSync(lock, 'wx', 0o600);\n try { writeFileSync(fd, String(process.pid)); } finally { closeSync(fd); }\n break;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;\n try {\n const owner = Number(readFileSync(lock, 'utf8'));\n if (Number.isSafeInteger(owner) && owner > 0) {\n try { process.kill(owner, 0); } catch (cause) {\n if ((cause as NodeJS.ErrnoException).code === 'ESRCH') { rmSync(lock, { force: true }); continue; }\n }\n }\n } catch { /* The other writer may have just released its lock. */ }\n if (Date.now() >= deadline) throw new Error(`Local store is busy: ${file}. Retry after the other writer finishes.`);\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10);\n }\n }\n try { return work(); } finally { rmSync(lock, { force: true }); }\n}\n"],"mappings":"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","names":["randomUUID","mkdirSync","readFileSync","writeFileSync","dirname","readFileSync","dirname","mkdirSync","writeFileSync","randomUUID"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/id.ts","../src/core/index.ts"],"sourcesContent":["let fallbackCounter = 0;\n\n/** IDs must also work on HTTP development hosts, where randomUUID is absent. */\nexport function createNoteId(): string {\n const crypto = globalThis.crypto;\n if (typeof crypto?.randomUUID === 'function') return crypto.randomUUID();\n\n if (typeof crypto?.getRandomValues === 'function') {\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n }\n\n // Old browsers without Web Crypto still need unique, stable retry IDs.\n fallbackCounter += 1;\n return `${Date.now().toString(36)}-${fallbackCounter.toString(36)}-${Math.random().toString(36).slice(2)}`;\n}\n","/**\n * isotone — core.\n *\n * The framework-agnostic half of the internal feedback loop. Holds the note\n * model, the element descriptor, the dev-store client (file-backed via a Vite\n * plugin, `localStorage` fallback), and the route visibility matcher. This\n * module has no React and no Vite dependency and is fully unit-testable in a\n * `node` env.\n */\nimport { request } from './request';\nimport { FEEDBACK_STORAGE_KEY, readBrowserStorage, writeBrowserStorage } from './browser-storage';\nimport { MAX_FEEDBACK_LENGTH } from './limits';\nimport { createNoteId } from './id';\n\n/** A UI element picked with the panel's selector mode. */\nexport interface IterationElement {\n /** Lowercase tag name, e.g. \"button\". */\n tag: string;\n /** Trimmed text-content snippet (may be empty for visual elements). */\n text: string;\n /** Best-effort CSS path for locating the element in code. */\n selector: string;\n}\n\n/** A durable reference to a selector or one of its options, not a DOM path. */\nexport interface VariantReference {\n axisId: string;\n label: string;\n optionId?: string;\n optionLabel?: string;\n value?: string;\n}\n\nexport interface VariantRemoval {\n axisId: string;\n action: 'remove-option' | 'remove-axis' | 'keep-default';\n optionId?: string;\n}\n\nexport interface NoteContext {\n /** Pending instruction: deleting its note cancels it before the agent acts. */\n variantAction?: VariantRemoval;\n elements?: IterationElement[];\n variant?: VariantReference | null;\n}\n\n/** A note written in the panel, read and answered by the coding agent. */\nexport interface IterationNote extends NoteContext {\n id: string;\n /** The route the note was written on, e.g. \"/projects\". */\n route: string;\n feedback: string;\n element: IterationElement | null;\n done: boolean;\n doneAt?: string | null;\n createdAt: string;\n /** The window size the note was written at — layout feedback only means\n * something at the breakpoint it was seen on. */\n viewport?: { w: number; h: number };\n /** Host-specific context the store round-trips without interpreting — see\n * `StoredNote.payload`. */\n payload?: unknown;\n}\n\n/** The minimal structural surface the descriptor builder needs from a DOM\n * node. `children` is `readonly` so both a real `HTMLCollection` and a plain\n * test array satisfy it; the builder materializes it with `Array.from`. */\nexport interface NodeLike {\n tagName: string;\n id?: string | null;\n parentElement?: NodeLike | null;\n children?: readonly NodeLike[];\n textContent?: string | null;\n /** One-based child position, when the adapter can provide it cheaply. */\n indexInParent?: number;\n}\n\n/**\n * Best-effort descriptor of a picked element for locating it in code. Walks\n * up the tree collecting `#id` (preferred) or `tag:nth-child(n)` segments up\n * to a shallow depth, stopping at `BODY` or the depth cap. Kept framework-free\n * so it is unit-testable.\n */\nexport function describeIterationElement(\n el: NodeLike,\n maxDepth = 4,\n): IterationElement {\n const parts: string[] = [];\n let node: NodeLike | null | undefined = el;\n let depth = 0;\n while (node && node.tagName !== \"BODY\" && depth < maxDepth) {\n if (node.id) {\n // Escape every code point: valid for leading digits, punctuation and\n // framework-generated ids without depending on the host's CSS global.\n const id = Array.from(node.id, (c) => `\\\\${c.codePointAt(0)?.toString(16)} `).join('');\n parts.unshift(`#${/^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(node.id) ? node.id : id}`);\n break;\n }\n let part = node.tagName.toLowerCase();\n const parent: NodeLike | null | undefined = node.parentElement;\n if (parent) {\n const index = node.indexInParent ?? Array.from(parent.children ?? []).indexOf(node) + 1;\n if (index > 0) part += `:nth-child(${index})`;\n }\n parts.unshift(part);\n node = parent;\n depth++;\n }\n return {\n tag: el.tagName.toLowerCase(),\n text: (el.textContent ?? \"\").trim().replace(/\\s+/g, \" \").slice(0, 80),\n selector: parts.join(\" > \"),\n };\n}\n\n/** Lazy DOM views: describing one element never walks unrelated subtrees. */\nexport function elementAsNode(el: Element): NodeLike {\n const cache = new WeakMap<Element, NodeLike>();\n const view = (n: Element | null | undefined): NodeLike | null => {\n if (!n) return null;\n const cached = cache.get(n);\n if (cached) return cached;\n const created: NodeLike = {\n tagName: n.tagName,\n id: n.id || null,\n get textContent() { return n.textContent; },\n get parentElement() { return view(n.parentElement); },\n get children() { return Array.from(n.children, (child) => view(child) as NodeLike); },\n get indexInParent() {\n let index = 1;\n for (let sibling = n.previousElementSibling; sibling; sibling = sibling.previousElementSibling) index++;\n return index;\n },\n };\n cache.set(n, created);\n return created;\n };\n const root = view(el);\n if (root === null) {\n throw new Error('unreachable: a real element always maps to a view');\n }\n return root;\n}\n\n/** A matcher over a console route: include a page only when it is not hidden\n * (denylist) or, when a visible list is given, only when it matches. */\nexport interface RouteGateOptions {\n /** Exact routes (or prefixes ending in `*`) to NEVER show the panel on,\n * e.g. the auth flow. Defaults to the auth/login/error pages. */\n hidden?: string[];\n /** When set, visible only on these routes/prefixes (allowlist). Overrides\n * `hidden` — used when a repo wants an explicit allow-list. */\n visible?: string[];\n /** Prefixes always barred regardless of `visible` (e.g. `/api`, `/auth`). */\n alwaysHidden?: string[];\n}\n\nconst DEFAULT_HIDDEN = [\"/login\", \"/logout\", \"/register\", \"/error\", \"/_error\"];\n\nfunction matchRoutePattern(route: string, pattern: string): boolean {\n if (pattern.endsWith('*')) return route.startsWith(pattern.slice(0, -1));\n if (pattern.endsWith(\"/\")) return route.startsWith(pattern);\n return route === pattern || route.startsWith(`${pattern}/`);\n}\n\n/** Whether the panel may mount on the given route. Pure and unit-testable. */\nexport function isRouteVisible(route: string, rule: RouteGateOptions = {}): boolean {\n const hidden = rule.hidden ?? DEFAULT_HIDDEN;\n const alwaysHidden = rule.alwaysHidden ?? [\"/api\", \"/auth\", \"/login\"];\n // A prefix match on the \"always\" list is unconditionally hidden — the panel\n // must never appear on auth or API surfaces regardless of allow-list.\n for (const p of alwaysHidden) {\n if (route === p || route.startsWith(`${p}/`)) return false;\n }\n if (rule.visible && rule.visible.length > 0) {\n return rule.visible.some((v) => matchRoutePattern(route, v));\n }\n return !hidden.some((h) => matchRoutePattern(route, h));\n}\n\n/* ---------------------------------------------------------------------------\n * Store: client transport for the notes. The Vite plugin serves the endpoint\n * (same-origin, dev-only); a `localStorage` fallback keeps notes when the\n * dev server is unreachable. The endpoint and storage namespace are\n * configurable so multi-app origins don't collide.\n * ------------------------------------------------------------------------- */\n\nexport interface IterationStoreConfig {\n /** Absolute or same-origin URL of the notes endpoint. Must be set (by the\n * Vite plugin's `iteration()` options or a framework preset) for a shared\n * file-backed store; when omitted, only localStorage persists. */\n endpoint?: string | null;\n /** localStorage namespace. Default-scoped to the package; set it per hosted\n * app when two apps share an origin. */\n key?: string;\n}\n\n/** Where the last `saveNote` landed; `null` before the first one. */\nexport type SaveLocation = \"server\" | \"local\";\n\nexport function createIterationStore(cfg: IterationStoreConfig = {}) {\n const endpoint = cfg.endpoint ?? null;\n const key = cfg.key ?? FEEDBACK_STORAGE_KEY;\n let lastSave: SaveLocation | null = null;\n let migration: Promise<void> | null = null;\n\n function parseLocal(raw: string | null): IterationNote[] {\n try {\n const items = JSON.parse(raw ?? '[]') as IterationNote[];\n if (!Array.isArray(items) || !items.every((note) => note && typeof note.id === 'string' &&\n typeof note.route === 'string' && typeof note.feedback === 'string' && typeof note.createdAt === 'string')) throw new Error('Invalid notes');\n return items.map((i) => ({ ...i, done: i.done ?? false })).map((i) => ({\n ...i,\n element: i.element ?? null,\n }));\n } catch (cause) {\n throw new Error('Could not read local feedback. Browser storage has been left untouched.', { cause });\n }\n }\n\n function localAll(): IterationNote[] {\n let storage: Storage;\n try { storage = window.localStorage; } catch { return []; }\n return parseLocal(readBrowserStorage(storage, key, (current, previous) => {\n const merged = new Map([...parseLocal(previous), ...parseLocal(current)].map(note => [note.id, note]));\n return JSON.stringify([...merged.values()]);\n }));\n }\n\n function localWrite(items: IterationNote[]) {\n writeBrowserStorage(window.localStorage, key, JSON.stringify(items));\n }\n\n function acknowledge(item: IterationNote): void {\n const current = localAll();\n const snapshot = JSON.stringify(item);\n const remaining = current.filter((note) => note.id !== item.id || JSON.stringify(note) !== snapshot);\n if (remaining.length !== current.length) localWrite(remaining);\n }\n\n async function flushLocalBacklog(): Promise<void> {\n if (!endpoint) return;\n const backlog = localAll();\n if (backlog.length === 0) return;\n for (const item of backlog) {\n // Notes saved by an older client may exceed today's server limit.\n // Keep them in the browser, but let valid notes behind them sync.\n if (item.feedback.trim().length > MAX_FEEDBACK_LENGTH) continue;\n let rejected = false;\n const saved = await request(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n id: item.id,\n createdAt: item.createdAt,\n route: item.route,\n feedback: item.feedback,\n element: item.element ?? null,\n ...(item.elements !== undefined ? { elements: item.elements } : {}),\n ...(item.variant !== undefined ? { variant: item.variant } : {}),\n ...(item.variantAction !== undefined ? { variantAction: item.variantAction } : {}),\n ...(item.payload !== undefined ? { payload: item.payload } : {}),\n ...(item.viewport ? { viewport: item.viewport } : {}),\n }),\n }, async (res) => {\n if (!res.ok) {\n rejected = res.status >= 400 && res.status < 500;\n return null;\n }\n return await res.json() as { id?: unknown };\n });\n if (!saved || typeof saved.id !== 'string' || !saved.id) {\n if (rejected) continue;\n return; // A transient failure or missing acknowledgement stops the retry.\n }\n // A save may have happened while the request was in flight. Remove\n // only the exact snapshot acknowledged by the server, never the queue.\n acknowledge(item);\n }\n }\n\n function migrateLocalBacklog(): Promise<void> {\n migration ??= flushLocalBacklog().finally(() => { migration = null; });\n return migration;\n }\n\n async function readRemote(url: string): Promise<IterationNote[]> {\n await migrateLocalBacklog().catch(() => {});\n const local = localAll();\n try {\n const remote = await request(url, undefined, async (res) => {\n if (!res.ok) throw new Error(`Loading iteration notes failed (${res.status})`);\n return await res.json() as IterationNote[];\n });\n const pendingIds = new Set(local.map((note) => note.id));\n return [...remote.filter((note) => !pendingIds.has(note.id)), ...local];\n } catch (error) {\n if (local.length) return local;\n throw error;\n }\n }\n\n /** Notes for one route, or every note on every route when `route` is omitted. */\n async function listNotes(route?: string): Promise<IterationNote[]> {\n if (!endpoint) {\n return localAll()\n .filter((i) => route === undefined || i.route === route)\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n }\n return (await readRemote(\n route === undefined ? `${endpoint}?all=1` : `${endpoint}?route=${encodeURIComponent(route)}`,\n )).filter((note) => route === undefined || note.route === route)\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n }\n\n /** Every still-open note across all routes, newest first. */\n async function pendingNotes(): Promise<IterationNote[]> {\n if (!endpoint) {\n return localAll()\n .filter((i) => !i.done)\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n }\n return (await readRemote(endpoint)).filter((note) => !note.done)\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n }\n\n function saveLocal(\n route: string,\n feedback: string,\n element: IterationElement | null,\n id: string | null,\n payload?: unknown,\n viewport?: { w: number; h: number },\n context?: NoteContext,\n ): string {\n const all = localAll();\n let savedId: string;\n const defaultsRequest = feedback.startsWith('[set-defaults]');\n const existing = id ? all.find((f) => f.id === id && f.route === route) : defaultsRequest ? all.filter(n => !n.done && n.route === route && n.feedback.startsWith('[set-defaults]')).sort((a, b) => b.createdAt.localeCompare(a.createdAt))[0] : undefined;\n if (existing) {\n if (defaultsRequest && !id) {\n delete existing.elements;\n delete existing.variant;\n delete existing.variantAction;\n delete existing.payload;\n }\n existing.feedback = feedback;\n existing.element = element;\n if (payload !== undefined) existing.payload = payload;\n if (defaultsRequest) {\n existing.createdAt = new Date().toISOString();\n if (viewport) existing.viewport = viewport;\n }\n if (context) Object.assign(existing, context);\n if (existing.elements) existing.element = existing.elements[0] ?? null;\n savedId = existing.id;\n } else {\n savedId = id ?? createNoteId();\n all.push({\n id: savedId,\n route,\n feedback,\n element,\n done: false,\n createdAt: new Date().toISOString(),\n ...(viewport ? { viewport } : {}),\n ...(payload !== undefined ? { payload } : {}),\n ...context,\n ...(context?.elements ? { element: context.elements[0] ?? null } : {}),\n });\n }\n localWrite(defaultsRequest ? all.filter(n => n.id === savedId || n.done || n.route !== route || !n.feedback.startsWith('[set-defaults]')) : all);\n return savedId;\n }\n\n async function saveNote(\n route: string,\n feedback: string,\n element: IterationElement | null,\n id: string | null,\n /** Opaque host context, attached only when the caller sends it. */\n payload?: unknown,\n /** Window size at write time; attached on create only. */\n viewport?: { w: number; h: number },\n context?: NoteContext,\n ): Promise<string> {\n if (feedback.trim().length > MAX_FEEDBACK_LENGTH) {\n throw new RangeError(`Feedback must be at most ${MAX_FEEDBACK_LENGTH} characters.`);\n }\n if (!endpoint) {\n const savedId = saveLocal(route, feedback, element, id, payload, viewport, context);\n lastSave = \"local\";\n return savedId;\n }\n // Stable across a lost response and its retry: the server treats this as\n // an upsert, so reconnecting cannot create a second copy of the note.\n const savedId = id ?? (feedback.startsWith('[set-defaults]') ? null : createNoteId());\n const pendingBefore = localAll().find((note) => note.id === savedId);\n const saveOffline = () => {\n const localId = saveLocal(route, feedback, element, savedId, payload, viewport, context);\n lastSave = 'local';\n return localId;\n };\n let res: Response | undefined;\n let result: { id?: unknown; error?: unknown } | null;\n try {\n result = await request(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n id: savedId,\n route,\n feedback,\n element,\n ...context,\n ...(payload !== undefined ? { payload } : {}),\n ...(viewport ? { viewport } : {}),\n }),\n }, async (response) => {\n res = response;\n if (!response.ok && response.status >= 500) throw new Error(`Saving iteration note failed (${response.status})`);\n return await response.json().catch((error) => {\n if (response.ok) throw error;\n return null;\n }) as { id?: unknown; error?: unknown } | null;\n });\n } catch {\n if (res && !res.ok && res.status < 500) throw new Error(`Saving iteration note failed (${res.status})`);\n return saveOffline();\n }\n // Validation errors require a correction, not a permanently stuck queue.\n if (!res?.ok) {\n throw new Error(`Saving iteration note failed (${res?.status})${typeof result?.error === 'string' ? `: ${result.error}` : ''}`);\n }\n if (!result || typeof result.id !== 'string' || !result.id) return saveOffline();\n if (pendingBefore) acknowledge(pendingBefore);\n lastSave = 'server';\n return result.id;\n }\n\n async function deleteNote(id: string): Promise<void> {\n if (!endpoint) {\n localWrite(localAll().filter((f) => f.id !== id));\n return;\n }\n const res = await request(`${endpoint}?id=${encodeURIComponent(id)}`, {\n method: \"DELETE\",\n });\n if (!res.ok) throw new Error(`Deleting iteration note failed (${res.status})`);\n const local = localAll();\n if (local.some((note) => note.id === id)) localWrite(local.filter((note) => note.id !== id));\n }\n\n return {\n listNotes,\n pendingNotes,\n saveNote,\n deleteNote,\n endpoint,\n /** Where the last save landed, for the panel's sync notice. */\n get lastSave(): SaveLocation | null {\n return lastSave;\n },\n get hasUnsyncedNotes(): boolean {\n return localAll().length > 0;\n },\n };\n}\nexport * from './variants';\n"],"mappings":"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","names":["savedId"]}