@neonwatty/limner 0.1.2 → 0.1.4
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/README.md +35 -0
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/ledger.d.ts +43 -0
- package/dist/commands/ledger.js +102 -0
- package/dist/commands/ledger.js.map +1 -0
- package/dist/commands/loop-cli.d.ts +2 -0
- package/dist/commands/loop-cli.js +71 -0
- package/dist/commands/loop-cli.js.map +1 -0
- package/dist/commands/loop-comparison-adapters.d.ts +17 -0
- package/dist/commands/loop-comparison-adapters.js +85 -0
- package/dist/commands/loop-comparison-adapters.js.map +1 -0
- package/dist/commands/loop.d.ts +41 -0
- package/dist/commands/loop.js +151 -0
- package/dist/commands/loop.js.map +1 -0
- package/dist/core/agent-comparison-pack.d.ts +1 -1
- package/dist/core/agent-comparison-profiles.d.ts +1 -1
- package/dist/core/agent-comparison-profiles.js +11 -2
- package/dist/core/agent-comparison-profiles.js.map +1 -1
- package/dist/core/ledger-db.d.ts +6 -0
- package/dist/core/ledger-db.js +106 -0
- package/dist/core/ledger-db.js.map +1 -0
- package/dist/core/ledger-events.d.ts +3 -0
- package/dist/core/ledger-events.js +12 -0
- package/dist/core/ledger-events.js.map +1 -0
- package/dist/core/ledger-ids.d.ts +3 -0
- package/dist/core/ledger-ids.js +12 -0
- package/dist/core/ledger-ids.js.map +1 -0
- package/dist/core/ledger-paths.d.ts +9 -0
- package/dist/core/ledger-paths.js +14 -0
- package/dist/core/ledger-paths.js.map +1 -0
- package/dist/core/ledger-store.d.ts +64 -0
- package/dist/core/ledger-store.js +173 -0
- package/dist/core/ledger-store.js.map +1 -0
- package/dist/core/loop-instructions.d.ts +2 -0
- package/dist/core/loop-instructions.js +8 -0
- package/dist/core/loop-instructions.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/schemas/comparison.d.ts +1 -0
- package/dist/schemas/comparison.js +1 -1
- package/dist/schemas/comparison.js.map +1 -1
- package/dist/schemas/ledger.d.ts +25 -0
- package/dist/schemas/ledger.js +7 -0
- package/dist/schemas/ledger.js.map +1 -0
- package/docs/agent-workflow.md +18 -0
- package/docs/superpowers/plans/2026-06-12-global-loop-ledger.md +160 -0
- package/docs/superpowers/specs/2026-06-12-global-loop-ledger-design.md +254 -0
- package/package.json +3 -1
- package/skills/limner/SKILL.md +16 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const ledgerModeSchema = z.enum(['image-mockup', 'mockup-implementation', 'image-implementation']);
|
|
3
|
+
export const trajectoryStatusSchema = z.enum(['active', 'closed']);
|
|
4
|
+
export const iterationStatusSchema = z.enum(['active', 'closed']);
|
|
5
|
+
export const ledgerEventActorSchema = z.enum(['user', 'agent', 'cli']);
|
|
6
|
+
export const agentFeedbackSchema = z.string().max(255).optional();
|
|
7
|
+
//# sourceMappingURL=ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../src/schemas/ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,uBAAuB,EAAE,sBAAsB,CAAC,CAAC,CAAC;AAC1G,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAClE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AACvE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC"}
|
package/docs/agent-workflow.md
CHANGED
|
@@ -4,6 +4,24 @@ Limner is designed for agent-in-the-loop visual fidelity work.
|
|
|
4
4
|
|
|
5
5
|
Prompt profiles: `ideal-to-mockup` for Phase 1, and `mockup-to-implementation` for Phase 2.
|
|
6
6
|
|
|
7
|
+
Loop modes: `image-mockup`, `mockup-implementation`, and `image-implementation`.
|
|
8
|
+
|
|
9
|
+
## Loop Ledger
|
|
10
|
+
|
|
11
|
+
Use `limner loop` when a screen will need Ralph Loop-style iteration. Limner stores loop state and events in the global local-only ledger at `~/.limner/ledger.sqlite`.
|
|
12
|
+
|
|
13
|
+
1. Start a trajectory with `limner loop start --mode <mode> --target <name> --name <human-name> --max-iterations <count>`.
|
|
14
|
+
2. Run `limner loop compare --trajectory <trajectory-id>`.
|
|
15
|
+
3. Read the generated agent comparison prompt and response target.
|
|
16
|
+
4. Write or validate the agent response.
|
|
17
|
+
5. Use `limner loop status --trajectory <trajectory-id>` to inspect current state.
|
|
18
|
+
6. Use `limner loop next --trajectory <trajectory-id>` to begin the next scoped fix.
|
|
19
|
+
7. Use `limner loop close --trajectory <trajectory-id>` when the trajectory is done.
|
|
20
|
+
|
|
21
|
+
Every meaningful loop interaction writes a ledger event. Use `--feedback "<short note>"` on loop status for a 255-character `agentFeedback` note about improving the current process.
|
|
22
|
+
|
|
23
|
+
Use `limner ledger export <trajectory-id> --format markdown` when an agent needs a compact case file for a trajectory.
|
|
24
|
+
|
|
7
25
|
## Phase 1: Image To Reference
|
|
8
26
|
|
|
9
27
|
1. Run `limner init <image> --target <name>`.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Global Loop Ledger Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Add a global, local-only Limner loop ledger with trajectory-scoped Ralph Loop commands for `image-mockup`, `mockup-implementation`, and `image-implementation`.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Use `better-sqlite3` for `~/.limner/ledger.sqlite`, with a small storage layer under `src/core/ledger-*`. Add `limner loop` for trajectory lifecycle and `limner ledger` for query/export. Keep every meaningful interaction append-only in `ledger_events`, mirror current state in focused tables, and route all three comparison modes through loop adapters.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** TypeScript, Commander, Zod, better-sqlite3, Vitest, Node 20+.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## File Map
|
|
14
|
+
|
|
15
|
+
- Modify `package.json` and `package-lock.json` to add `better-sqlite3` and `@types/better-sqlite3`.
|
|
16
|
+
- Create `src/schemas/ledger.ts` for modes, statuses, events, and input validation.
|
|
17
|
+
- Create `src/core/ledger-paths.ts` for global home resolution and test overrides.
|
|
18
|
+
- Create `src/core/ledger-db.ts` for SQLite opening, migrations, and transactions.
|
|
19
|
+
- Create `src/core/ledger-store.ts` for trajectory, iteration, event, note, and export operations.
|
|
20
|
+
- Create `src/core/ledger-store.test.ts` for storage behavior.
|
|
21
|
+
- Create `src/core/loop-comparison-adapters.ts` for mode-specific compare execution.
|
|
22
|
+
- Create `src/commands/loop.ts` and `src/commands/loop.test.ts`.
|
|
23
|
+
- Create `src/commands/ledger.ts` and `src/commands/ledger.test.ts`.
|
|
24
|
+
- Modify `src/cli.ts` and `src/index.ts` to register/export the new surfaces.
|
|
25
|
+
- Modify `README.md`, `docs/agent-workflow.md`, and `skills/limner/SKILL.md`.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
### Task 1: Add SQLite Dependency And Schemas
|
|
30
|
+
|
|
31
|
+
**Files:** `package.json`, `package-lock.json`, `src/schemas/ledger.ts`, `src/index.ts`
|
|
32
|
+
|
|
33
|
+
- [ ] Run `npm install better-sqlite3@12.10.0`.
|
|
34
|
+
- [ ] Run `npm install -D @types/better-sqlite3@7.6.13`.
|
|
35
|
+
- [ ] Create `src/schemas/ledger.ts` with:
|
|
36
|
+
- `ledgerModeSchema = z.enum(['image-mockup', 'mockup-implementation', 'image-implementation'])`
|
|
37
|
+
- `trajectoryStatusSchema = z.enum(['active', 'closed'])`
|
|
38
|
+
- `iterationStatusSchema = z.enum(['active', 'closed'])`
|
|
39
|
+
- `ledgerEventActorSchema = z.enum(['user', 'agent', 'cli'])`
|
|
40
|
+
- `agentFeedbackSchema = z.string().max(255).optional()`
|
|
41
|
+
- exported TypeScript types for each schema.
|
|
42
|
+
- [ ] Export the new schemas/types from `src/index.ts`.
|
|
43
|
+
- [ ] Run `npm run typecheck`; expect pass.
|
|
44
|
+
|
|
45
|
+
### Task 2: Global Ledger Paths
|
|
46
|
+
|
|
47
|
+
**Files:** `src/core/ledger-paths.ts`, `src/core/ledger-paths.test.ts`
|
|
48
|
+
|
|
49
|
+
- [ ] Write tests for default home path and env override:
|
|
50
|
+
- default returns `<homedir>/.limner/ledger.sqlite`
|
|
51
|
+
- `LIMNER_LEDGER_HOME=/tmp/x` returns `/tmp/x/ledger.sqlite`
|
|
52
|
+
- snapshot dir resolves to `<home>/snapshots`
|
|
53
|
+
- [ ] Implement `resolveLedgerHome(env = process.env)` and `resolveLedgerPaths(env = process.env)`.
|
|
54
|
+
- [ ] Run `npm test -- src/core/ledger-paths.test.ts`; expect pass.
|
|
55
|
+
|
|
56
|
+
### Task 3: SQLite Migrations
|
|
57
|
+
|
|
58
|
+
**Files:** `src/core/ledger-db.ts`, `src/core/ledger-db.test.ts`
|
|
59
|
+
|
|
60
|
+
- [ ] Write tests that opening a temp ledger creates tables:
|
|
61
|
+
- `trajectories`
|
|
62
|
+
- `iterations`
|
|
63
|
+
- `runs`
|
|
64
|
+
- `artifacts`
|
|
65
|
+
- `instruction_versions`
|
|
66
|
+
- `notes`
|
|
67
|
+
- `ledger_events`
|
|
68
|
+
- [ ] Implement `openLedgerDatabase(paths)` using `better-sqlite3`.
|
|
69
|
+
- [ ] Enable `PRAGMA foreign_keys = ON`.
|
|
70
|
+
- [ ] Implement idempotent schema migrations with a `schema_meta` table and `schemaVersion = 1`.
|
|
71
|
+
- [ ] Run `npm test -- src/core/ledger-db.test.ts`; expect pass.
|
|
72
|
+
|
|
73
|
+
### Task 4: Ledger Store Core
|
|
74
|
+
|
|
75
|
+
**Files:** `src/core/ledger-store.ts`, `src/core/ledger-store.test.ts`
|
|
76
|
+
|
|
77
|
+
- [ ] Write tests for `startTrajectory`, `appendEvent`, `resolveTrajectory`, `advanceIteration`, `closeTrajectory`, and `exportTrajectoryJson`.
|
|
78
|
+
- [ ] `startTrajectory` creates:
|
|
79
|
+
- `traj_<hash>` trajectory id
|
|
80
|
+
- `iter_001`
|
|
81
|
+
- `loop.started` event
|
|
82
|
+
- initial instruction version
|
|
83
|
+
- [ ] `appendEvent` rejects `agentFeedback` longer than 255 chars.
|
|
84
|
+
- [ ] `resolveTrajectory` returns one match or an ambiguity error with candidates.
|
|
85
|
+
- [ ] `advanceIteration` closes the active iteration, creates the next `iter_NNN`, and writes `loop.next.started`.
|
|
86
|
+
- [ ] `closeTrajectory` closes trajectory plus active iteration and writes `loop.iteration.closed`.
|
|
87
|
+
- [ ] `exportTrajectoryJson` returns trajectory, iterations, events, notes, and artifacts.
|
|
88
|
+
- [ ] Run `npm test -- src/core/ledger-store.test.ts`; expect pass.
|
|
89
|
+
|
|
90
|
+
### Task 5: Loop CLI
|
|
91
|
+
|
|
92
|
+
**Files:** `src/commands/loop.ts`, `src/commands/loop.test.ts`, `src/cli.ts`
|
|
93
|
+
|
|
94
|
+
- [ ] Write CLI tests with `LIMNER_LEDGER_HOME` pointing at a temp dir.
|
|
95
|
+
- [ ] Test `loop start --mode image-mockup --target checkout --name checkout-mobile --max-iterations 5` prints `Trajectory: traj_`.
|
|
96
|
+
- [ ] Test implementation modes accept `--url`, `--storage-state`, and `--full-page` and store them in trajectory instructions/context.
|
|
97
|
+
- [ ] Test `loop status --trajectory <id>` prints mode, status, active iteration, iteration count, and max.
|
|
98
|
+
- [ ] Test `loop next --trajectory <id>` advances from `iter_001` to `iter_002`.
|
|
99
|
+
- [ ] Test `loop close --trajectory <id>` closes the trajectory.
|
|
100
|
+
- [ ] Test `--feedback` records short agent feedback and rejects overlong feedback.
|
|
101
|
+
- [ ] Register `limner loop` in `src/cli.ts`.
|
|
102
|
+
- [ ] Run `npm test -- src/commands/loop.test.ts`; expect pass.
|
|
103
|
+
|
|
104
|
+
### Task 6: Loop Compare Adapter
|
|
105
|
+
|
|
106
|
+
**Files:** `src/commands/loop.ts`, `src/core/loop-comparison-adapters.ts`, `src/core/ledger-store.ts`, `src/commands/loop.test.ts`
|
|
107
|
+
|
|
108
|
+
- [ ] Add `loop compare --trajectory <id>` with ledger events before and after command execution.
|
|
109
|
+
- [ ] Implement first-class adapters:
|
|
110
|
+
- `image-mockup` to `compareImageReference`
|
|
111
|
+
- `mockup-implementation` to `compareReferenceImplementation`
|
|
112
|
+
- `image-implementation` to source image versus implementation URL capture, with source image as expected and implementation screenshot as actual
|
|
113
|
+
- [ ] For `image-implementation`, require a stored or supplied implementation URL and write the same agent-comparison pack shape as other image comparisons.
|
|
114
|
+
- [ ] Write `loop.compare.started`, `loop.compare.awaiting_agent`, `loop.compare.validated`, or `loop.compare.failed`.
|
|
115
|
+
- [ ] Snapshot compact artifacts: prompts, agent response, summaries, reports, and compact JSON metadata.
|
|
116
|
+
- [ ] Run `npm test -- src/commands/loop.test.ts && npm run typecheck`; expect pass.
|
|
117
|
+
|
|
118
|
+
### Task 7: Ledger CLI
|
|
119
|
+
|
|
120
|
+
**Files:** `src/commands/ledger.ts`, `src/commands/ledger.test.ts`, `src/cli.ts`
|
|
121
|
+
|
|
122
|
+
- [ ] Write tests for:
|
|
123
|
+
- `ledger list --active`
|
|
124
|
+
- `ledger list --mode image-implementation`
|
|
125
|
+
- `ledger status --trajectory <id>`
|
|
126
|
+
- `ledger show <id>`
|
|
127
|
+
- `ledger next --trajectory <id>`
|
|
128
|
+
- `ledger export <id> --format json`
|
|
129
|
+
- `ledger export <id> --format markdown`
|
|
130
|
+
- [ ] Implement concise terminal output for agents.
|
|
131
|
+
- [ ] Register `limner ledger` in `src/cli.ts`.
|
|
132
|
+
- [ ] Run `npm test -- src/commands/ledger.test.ts`; expect pass.
|
|
133
|
+
|
|
134
|
+
### Task 8: Docs And Skills
|
|
135
|
+
|
|
136
|
+
**Files:** `README.md`, `docs/agent-workflow.md`, `skills/limner/SKILL.md`
|
|
137
|
+
|
|
138
|
+
- [ ] Document global local-only ledger storage at `~/.limner/ledger.sqlite`.
|
|
139
|
+
- [ ] Document the three modes: `image-mockup`, `mockup-implementation`, `image-implementation`.
|
|
140
|
+
- [ ] Document `loop start`, `loop compare`, `loop status`, `loop next`, and `loop close`.
|
|
141
|
+
- [ ] Document `agentFeedback` as a 255-character process-improvement field.
|
|
142
|
+
- [ ] Run `rg -n "image-mockup|mockup-implementation|image-implementation|agentFeedback|ledger.sqlite" README.md docs/agent-workflow.md skills/limner/SKILL.md`; expect all files to mention the workflow.
|
|
143
|
+
|
|
144
|
+
### Task 9: Full Verification
|
|
145
|
+
|
|
146
|
+
**Files:** no edits
|
|
147
|
+
|
|
148
|
+
- [ ] Run `npm test`; expect pass.
|
|
149
|
+
- [ ] Run `npm run typecheck`; expect pass.
|
|
150
|
+
- [ ] Run `npm run check:size`; expect pass.
|
|
151
|
+
- [ ] Run `npm run build`; expect pass.
|
|
152
|
+
- [ ] Run `npm run check`; expect pass.
|
|
153
|
+
- [ ] Smoke `npm run dev -- loop --help`; expect loop commands.
|
|
154
|
+
- [ ] Smoke `npm run dev -- ledger --help`; expect ledger commands.
|
|
155
|
+
|
|
156
|
+
## Self-Review
|
|
157
|
+
|
|
158
|
+
- Spec coverage: Covers global SQLite storage, trajectory-scoped commands, all three modes, event logging for every interaction, 255-character `agentFeedback`, snapshots, exports, max iteration state, ambiguity handling, and tests.
|
|
159
|
+
- Placeholder scan: No TODO/TBD placeholders remain.
|
|
160
|
+
- Type consistency: Uses `trajectoryId`, `iterationId`, `agentFeedback`, `image-mockup`, `mockup-implementation`, and `image-implementation` consistently.
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Global Loop Ledger Design
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Add a global, local-only Limner ledger for dogfooding visual fidelity loops across multiple projects at once. The ledger should help agents and package maintainers understand what was compared, which trajectory it belonged to, what iteration was active, what artifacts were produced, what failed, what the agent recommended, and what the agent noticed about improving Limner itself.
|
|
6
|
+
|
|
7
|
+
This builds on `docs/superpowers/plans/2026-06-12-agent-comparison-scores.md`, which replaces artifact-only comparisons with agent-authored comparison artifacts. This design turns those artifacts into durable Ralph Loop-style trajectories.
|
|
8
|
+
|
|
9
|
+
## Decisions
|
|
10
|
+
|
|
11
|
+
- The ledger is global-first and local-only.
|
|
12
|
+
- Primary storage is SQLite at `~/.limner/ledger.sqlite`.
|
|
13
|
+
- Limner sends no telemetry.
|
|
14
|
+
- Project artifacts stay in their original workspaces by default.
|
|
15
|
+
- The ledger stores artifact paths and hashes, then snapshots compact agent-readable files.
|
|
16
|
+
- Full screenshots are referenced in-place by default; a later pinning feature can copy selected images into `~/.limner`.
|
|
17
|
+
- Every meaningful loop interaction writes a ledger event, including failures, status views, exports, and ambiguous command resolution.
|
|
18
|
+
- Loop commands are trajectory-scoped. There is no project-wide current trajectory because multiple Codex sessions may polish multiple screens in the same project concurrently.
|
|
19
|
+
- `loop compare` is the blessed path for active loop work.
|
|
20
|
+
|
|
21
|
+
## Modes
|
|
22
|
+
|
|
23
|
+
The loop layer uses the future comparison vocabulary:
|
|
24
|
+
|
|
25
|
+
- `image-mockup`: source image to editable HTML mockup.
|
|
26
|
+
- `mockup-implementation`: approved mockup to real implementation.
|
|
27
|
+
- `image-implementation`: source image directly to real implementation.
|
|
28
|
+
|
|
29
|
+
Temporary mappings to older internal compare commands may exist during migration, but those names should not appear in the loop UX.
|
|
30
|
+
|
|
31
|
+
## Identity Model
|
|
32
|
+
|
|
33
|
+
The ledger separates trajectories, iterations, and command executions.
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
trajectory
|
|
37
|
+
trajectoryId: traj_...
|
|
38
|
+
humanId/name: checkout-mobile-polish
|
|
39
|
+
mode: image-mockup | mockup-implementation | image-implementation
|
|
40
|
+
projectRoot, workspaceRoot, target
|
|
41
|
+
source/artifact fingerprints
|
|
42
|
+
status, maxIterations
|
|
43
|
+
current instructions
|
|
44
|
+
|
|
45
|
+
iteration
|
|
46
|
+
iterationId: iter_001
|
|
47
|
+
trajectoryId
|
|
48
|
+
focus
|
|
49
|
+
effective instruction snapshot
|
|
50
|
+
status
|
|
51
|
+
|
|
52
|
+
run
|
|
53
|
+
runId
|
|
54
|
+
trajectoryId, iterationId
|
|
55
|
+
command
|
|
56
|
+
timestamps
|
|
57
|
+
result status
|
|
58
|
+
artifacts
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Trajectory IDs are stable machine IDs. Human names make work readable. Iteration IDs are scoped to a trajectory. Run IDs describe individual CLI executions and may map to the existing Limner run logger.
|
|
62
|
+
|
|
63
|
+
## CLI Shape
|
|
64
|
+
|
|
65
|
+
Primary loop commands:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
limner loop start --mode image-mockup --target checkout --name checkout-mobile-polish --max-iterations 5
|
|
69
|
+
limner loop compare --trajectory traj_abc123
|
|
70
|
+
limner loop status --trajectory traj_abc123
|
|
71
|
+
limner loop next --trajectory traj_abc123
|
|
72
|
+
limner loop close --trajectory traj_abc123
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Trajectory resolution may accept explicit context:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
limner loop status --target checkout --mode image-mockup
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
If more than one active trajectory matches, Limner refuses to guess, records a ledger event, and lists candidate trajectories.
|
|
82
|
+
|
|
83
|
+
Ledger commands are query/export tools:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
limner ledger list --active
|
|
87
|
+
limner ledger list --project /path/to/app
|
|
88
|
+
limner ledger list --mode image-implementation
|
|
89
|
+
limner ledger status --trajectory traj_abc123
|
|
90
|
+
limner ledger show traj_abc123
|
|
91
|
+
limner ledger next --trajectory traj_abc123
|
|
92
|
+
limner ledger export traj_abc123 --format markdown
|
|
93
|
+
limner ledger export traj_abc123 --format json
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Mode Skills
|
|
97
|
+
|
|
98
|
+
Limner should grow a plugin with three mode-specific skills backed by the same loop and ledger engine:
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
limner-image-mockup-loop
|
|
102
|
+
limner-mockup-implementation-loop
|
|
103
|
+
limner-image-implementation-loop
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Each skill shares the same state ritual: inspect the trajectory, run `limner loop compare`, read the agent comparison output, make one scoped fix, record feedback or notes, and advance or close the iteration.
|
|
107
|
+
|
|
108
|
+
The skills differ by editable surface and inspection rules:
|
|
109
|
+
|
|
110
|
+
- `image-mockup` edits `targets/<target>/reference/` and treats the source image as canonical.
|
|
111
|
+
- `mockup-implementation` edits real app source, uses the approved mockup as canonical, and needs implementation URL/auth/framework/test guidance.
|
|
112
|
+
- `image-implementation` edits real app source and treats the source image as canonical. Because there is no approved mockup bridge, it should call out ambiguity between product interpretation and implementation drift.
|
|
113
|
+
|
|
114
|
+
## Instructions
|
|
115
|
+
|
|
116
|
+
The ledger stores effective trajectory instructions. Skills provide defaults, but each trajectory records the actual edit and inspection instructions for the current work.
|
|
117
|
+
|
|
118
|
+
Instruction changes are mutable but versioned. Each iteration snapshots the effective instructions so future agents can see which rules were active for each pass.
|
|
119
|
+
|
|
120
|
+
Examples:
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
editInstructions
|
|
124
|
+
Only edit targets/<target>/reference/index.html.
|
|
125
|
+
Only edit targets/<target>/reference/styles.css.
|
|
126
|
+
Do not change the source image unless explicitly asked.
|
|
127
|
+
|
|
128
|
+
inspectInstructions
|
|
129
|
+
Read comparison-summary.json before editing.
|
|
130
|
+
Treat agent-response.json as the current critique.
|
|
131
|
+
Make one scoped fix per iteration.
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
For implementation modes, instructions may include app source paths, test commands, framework constraints, implementation URL, storage state path, or auth requirements.
|
|
135
|
+
|
|
136
|
+
## Ledger Data
|
|
137
|
+
|
|
138
|
+
The ledger uses state tables for query speed and an append-only event stream for debugging and product improvement.
|
|
139
|
+
|
|
140
|
+
Core entities:
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
trajectories
|
|
144
|
+
iterations
|
|
145
|
+
runs
|
|
146
|
+
artifacts
|
|
147
|
+
instruction_versions
|
|
148
|
+
notes
|
|
149
|
+
events
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Useful derived fields:
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
lastScore
|
|
156
|
+
lastConfidence
|
|
157
|
+
activeIterationId
|
|
158
|
+
iterationCount
|
|
159
|
+
maxIterations
|
|
160
|
+
lastMajorDiffAreas
|
|
161
|
+
nextRecommendedFix
|
|
162
|
+
lastAgentStatus
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The event stream is the source of behavioral insight. State tables are current mirrors or indexes.
|
|
166
|
+
|
|
167
|
+
## Event Logging
|
|
168
|
+
|
|
169
|
+
Every meaningful loop interaction writes a ledger event, even when it does not change state.
|
|
170
|
+
|
|
171
|
+
Example event types:
|
|
172
|
+
|
|
173
|
+
```text
|
|
174
|
+
loop.started
|
|
175
|
+
loop.status.viewed
|
|
176
|
+
loop.compare.started
|
|
177
|
+
loop.compare.awaiting_agent
|
|
178
|
+
loop.compare.validated
|
|
179
|
+
loop.compare.failed
|
|
180
|
+
loop.compare.invalid_agent_response
|
|
181
|
+
loop.next.started
|
|
182
|
+
loop.iteration.closed
|
|
183
|
+
loop.instructions.updated
|
|
184
|
+
loop.max_iterations.changed
|
|
185
|
+
loop.max_iterations.reached
|
|
186
|
+
loop.resolution_ambiguous
|
|
187
|
+
loop.note.added
|
|
188
|
+
ledger.exported
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Each event should include:
|
|
192
|
+
|
|
193
|
+
```text
|
|
194
|
+
eventId
|
|
195
|
+
timestamp
|
|
196
|
+
trajectoryId
|
|
197
|
+
iterationId?
|
|
198
|
+
runId?
|
|
199
|
+
command
|
|
200
|
+
eventType
|
|
201
|
+
actor: user | agent | cli
|
|
202
|
+
inputsSummary
|
|
203
|
+
resultStatus
|
|
204
|
+
artifactRefs
|
|
205
|
+
agentFeedback?
|
|
206
|
+
notes?
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
`agentFeedback` is an optional short text field for feedback on the current process or possible Limner improvements. It is capped at 255 characters. Longer commentary belongs in a note linked to the same trajectory, iteration, or event.
|
|
210
|
+
|
|
211
|
+
## Snapshots
|
|
212
|
+
|
|
213
|
+
The ledger references original artifacts by absolute path and hash. It also snapshots compact agent-readable files under `~/.limner/snapshots/`.
|
|
214
|
+
|
|
215
|
+
```text
|
|
216
|
+
~/.limner/
|
|
217
|
+
ledger.sqlite
|
|
218
|
+
snapshots/
|
|
219
|
+
traj_.../
|
|
220
|
+
iter_001/
|
|
221
|
+
comparison-summary.json
|
|
222
|
+
agent-response.json
|
|
223
|
+
agent-prompt.codex.md
|
|
224
|
+
report.md
|
|
225
|
+
notes.md
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Snapshot selection should prefer agent prompts, agent responses, comparison summaries, reports, notes, and compact JSON metadata. Full screenshots remain in their source workspace by default.
|
|
229
|
+
|
|
230
|
+
## Max Iterations
|
|
231
|
+
|
|
232
|
+
Max iteration count is trajectory state in the ledger. When a trajectory reaches its max, Limner writes `loop.max_iterations.reached`, warns by default, and allows intentional continuation. A strict hard-stop mode can be added later for scripted workflows.
|
|
233
|
+
|
|
234
|
+
## Error Handling
|
|
235
|
+
|
|
236
|
+
Errors and refusals are ledgered:
|
|
237
|
+
|
|
238
|
+
- ambiguous trajectory resolution writes `loop.resolution_ambiguous`;
|
|
239
|
+
- missing artifacts write `loop.compare.failed` with path/hash context;
|
|
240
|
+
- invalid agent responses write `loop.compare.invalid_agent_response` with schema errors and response path;
|
|
241
|
+
- instruction updates write `loop.instructions.updated` and snapshot the new instruction version;
|
|
242
|
+
- exports write `ledger.exported`.
|
|
243
|
+
|
|
244
|
+
## Testing And Handoff
|
|
245
|
+
|
|
246
|
+
Use a temporary global ledger path in tests so the real `~/.limner` is never touched. Unit tests should cover trajectory ID generation, trajectory resolution, event append, the 255-character `agentFeedback` limit, instruction versioning, and snapshot selection.
|
|
247
|
+
|
|
248
|
+
CLI tests should cover `loop start`, `compare`, `status`, `next`, and `close`; ambiguous resolution; max iteration warnings; all three modes; and feedback recorded on loop events. Integration-style tests should cover invalid agent responses, markdown export, and JSON export. Exports must include current state, latest diffs, notes, artifacts, feedback, and event timeline.
|
|
249
|
+
|
|
250
|
+
The repository quality gate remains `npm run check`.
|
|
251
|
+
|
|
252
|
+
Top realistic failure modes are agents forgetting `--trajectory`, event streams becoming noisy, and mode-specific skills drifting from the shared loop engine.
|
|
253
|
+
|
|
254
|
+
Negative cases to preserve are ambiguous trajectory selection, missing artifacts, invalid or schema-invalid agent responses, max iterations reached, overlong `agentFeedback`, and multiple active trajectories for the same project.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neonwatty/limner",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Agent-guided visual fidelity workbench for turning images into HTML references and comparing references to real apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"node": ">=20"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
+
"better-sqlite3": "^12.10.0",
|
|
48
49
|
"commander": "^15.0.0",
|
|
49
50
|
"playwright": "^1.57.0",
|
|
50
51
|
"sharp": "^0.34.5",
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@eslint/js": "^10.0.1",
|
|
56
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
55
57
|
"@types/node": "^25.0.0",
|
|
56
58
|
"eslint": "^10.4.1",
|
|
57
59
|
"knip": "^6.16.1",
|
package/skills/limner/SKILL.md
CHANGED
|
@@ -9,6 +9,22 @@ Use Limner for structured visual fidelity loops.
|
|
|
9
9
|
|
|
10
10
|
Prompt profiles: `ideal-to-mockup` for Image To Reference, and `mockup-to-implementation` for Reference To Implementation.
|
|
11
11
|
|
|
12
|
+
Loop modes: `image-mockup`, `mockup-implementation`, and `image-implementation`.
|
|
13
|
+
|
|
14
|
+
## Loop Ledger
|
|
15
|
+
|
|
16
|
+
Use `limner loop` for Ralph Loop-style polishing across one or more trajectories. Limner stores loop state and events in a global local-only SQLite ledger at `~/.limner/ledger.sqlite`; it does not send telemetry.
|
|
17
|
+
|
|
18
|
+
1. Start with `limner loop start --mode <mode> --target <name> --name <human-name> --max-iterations <count>`.
|
|
19
|
+
2. Compare with `limner loop compare --trajectory <trajectory-id>`.
|
|
20
|
+
3. Read the generated comparison prompt and response target.
|
|
21
|
+
4. Write or validate the agent response.
|
|
22
|
+
5. Check state with `limner loop status --trajectory <trajectory-id>`.
|
|
23
|
+
6. Move to the next scoped fix with `limner loop next --trajectory <trajectory-id>`.
|
|
24
|
+
7. Close with `limner loop close --trajectory <trajectory-id>`.
|
|
25
|
+
|
|
26
|
+
Every meaningful loop interaction writes a ledger event. Use `--feedback "<short note>"` for a 255-character `agentFeedback` note about improving the current process. Use `limner ledger export <trajectory-id> --format markdown` to hand a compact trajectory history to another agent.
|
|
27
|
+
|
|
12
28
|
## Image To Reference
|
|
13
29
|
|
|
14
30
|
1. Run `limner init <image> --target <name>` if the target does not exist.
|