@herbertgao/pi-impeccable 0.0.0-stage → 0.0.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 +191 -0
- package/NOTICE.md +11 -0
- package/README.md +33 -2
- package/package.json +51 -4
- package/skills/impeccable/SKILL.md +89 -0
- package/skills/impeccable/reference/adapt.md +318 -0
- package/skills/impeccable/reference/adapt.native.md +58 -0
- package/skills/impeccable/reference/android.md +46 -0
- package/skills/impeccable/reference/animate.md +89 -0
- package/skills/impeccable/reference/audit.md +139 -0
- package/skills/impeccable/reference/audit.native.md +139 -0
- package/skills/impeccable/reference/bolder.md +33 -0
- package/skills/impeccable/reference/clarify.md +94 -0
- package/skills/impeccable/reference/colorize.md +86 -0
- package/skills/impeccable/reference/component-review.md +63 -0
- package/skills/impeccable/reference/craft-floor.md +44 -0
- package/skills/impeccable/reference/craft.md +5 -0
- package/skills/impeccable/reference/critique.md +819 -0
- package/skills/impeccable/reference/degraded/asset-producer.md +42 -0
- package/skills/impeccable/reference/degraded/documenter.md +24 -0
- package/skills/impeccable/reference/degraded/finish-reviewer.md +38 -0
- package/skills/impeccable/reference/degraded/manual-edit-applier.md +92 -0
- package/skills/impeccable/reference/delight.md +70 -0
- package/skills/impeccable/reference/distill.md +111 -0
- package/skills/impeccable/reference/doctor.md +54 -0
- package/skills/impeccable/reference/document.md +416 -0
- package/skills/impeccable/reference/extract.md +69 -0
- package/skills/impeccable/reference/generate.md +101 -0
- package/skills/impeccable/reference/harden.md +362 -0
- package/skills/impeccable/reference/hooks.md +114 -0
- package/skills/impeccable/reference/init.md +131 -0
- package/skills/impeccable/reference/ios.md +51 -0
- package/skills/impeccable/reference/layout.md +84 -0
- package/skills/impeccable/reference/live-setup.md +104 -0
- package/skills/impeccable/reference/live.md +325 -0
- package/skills/impeccable/reference/mode-operate.md +21 -0
- package/skills/impeccable/reference/mode-persuade.md +19 -0
- package/skills/impeccable/reference/mode-read.md +21 -0
- package/skills/impeccable/reference/new-work.md +152 -0
- package/skills/impeccable/reference/onboard.md +234 -0
- package/skills/impeccable/reference/operate.md +61 -0
- package/skills/impeccable/reference/optimize.md +257 -0
- package/skills/impeccable/reference/overdrive.md +127 -0
- package/skills/impeccable/reference/polish.md +105 -0
- package/skills/impeccable/reference/quieter.md +99 -0
- package/skills/impeccable/reference/region-map.md +26 -0
- package/skills/impeccable/reference/routing.md +24 -0
- package/skills/impeccable/reference/shape.md +59 -0
- package/skills/impeccable/reference/typeset.md +90 -0
- package/skills/impeccable/reference/visualize.md +47 -0
- package/skills/impeccable/scripts/VERSION +1 -0
- package/skills/impeccable/scripts/command-metadata.json +98 -0
- package/skills/impeccable/scripts/data/font-index-failures.json +121 -0
- package/skills/impeccable/scripts/data/font-index.json +1 -0
- package/skills/impeccable/scripts/engine-checksums.txt +9 -0
- package/skills/impeccable/scripts/impeccable +249 -0
- package/skills/impeccable/scripts/impeccable.cmd +278 -0
- package/skills/impeccable/scripts/live-browser-dom.js +320 -0
- package/skills/impeccable/scripts/live-browser-ignores.js +246 -0
- package/skills/impeccable/scripts/live-browser-session.js +183 -0
- package/skills/impeccable/scripts/live-browser.js +13645 -0
- package/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-side durable session helpers for Impeccable live mode.
|
|
3
|
+
*
|
|
4
|
+
* Kept separate from live-browser.js so recovery state can be tested without
|
|
5
|
+
* booting the full overlay UI. Served before live-browser.js and attached to
|
|
6
|
+
* window.__IMPECCABLE_LIVE_SESSION__.
|
|
7
|
+
*/
|
|
8
|
+
(function (root) {
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
// crypto.randomUUID() exists only in secure contexts (HTTPS, localhost), so a
|
|
12
|
+
// dev site on a LAN IP, a Tailscale address, or a custom hostname over plain
|
|
13
|
+
// HTTP has no randomUUID at all (issue #1055). getRandomValues() is available
|
|
14
|
+
// in every context; Math.random() covers runtimes with no crypto. Live ids
|
|
15
|
+
// only have to be unique per session, not unguessable.
|
|
16
|
+
function randomUUID(cryptoImpl) {
|
|
17
|
+
const c = cryptoImpl === undefined ? root.crypto : cryptoImpl;
|
|
18
|
+
try {
|
|
19
|
+
if (c && typeof c.randomUUID === 'function') return c.randomUUID();
|
|
20
|
+
} catch { /* fall through to getRandomValues */ }
|
|
21
|
+
const bytes = new Uint8Array(16);
|
|
22
|
+
let filled = false;
|
|
23
|
+
try {
|
|
24
|
+
if (c && typeof c.getRandomValues === 'function') {
|
|
25
|
+
c.getRandomValues(bytes);
|
|
26
|
+
filled = true;
|
|
27
|
+
}
|
|
28
|
+
} catch { /* fall through to Math.random */ }
|
|
29
|
+
if (!filled) {
|
|
30
|
+
for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256);
|
|
31
|
+
}
|
|
32
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4
|
|
33
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80; // RFC 4122 variant
|
|
34
|
+
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
35
|
+
return hex.slice(0, 8) + '-' + hex.slice(8, 12) + '-' + hex.slice(12, 16)
|
|
36
|
+
+ '-' + hex.slice(16, 20) + '-' + hex.slice(20);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function randomId8(cryptoImpl) {
|
|
40
|
+
return randomUUID(cryptoImpl).replace(/-/g, '').slice(0, 8);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function createLiveBrowserSessionState({ prefix, storage, idFactory }) {
|
|
44
|
+
if (!prefix) throw new Error('prefix required');
|
|
45
|
+
let store = storage;
|
|
46
|
+
if (!store) {
|
|
47
|
+
try { store = root.localStorage; } catch { store = null; /* storage denied */ }
|
|
48
|
+
}
|
|
49
|
+
const makeId = idFactory || function () { return randomId8(); };
|
|
50
|
+
const sessionKey = prefix + '-session';
|
|
51
|
+
const handledKey = sessionKey + '-handled';
|
|
52
|
+
const scrollKey = sessionKey + '-scroll';
|
|
53
|
+
let checkpointRevision = 0;
|
|
54
|
+
const owner = makeId();
|
|
55
|
+
|
|
56
|
+
function safeRead(key) {
|
|
57
|
+
try { return store.getItem(key); } catch { return null; }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function safeWrite(key, value) {
|
|
61
|
+
try { store.setItem(key, value); } catch { /* quota exceeded or private mode */ }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function safeRemove(key) {
|
|
65
|
+
try { store.removeItem(key); } catch { /* unavailable storage */ }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function loadSession() {
|
|
69
|
+
try {
|
|
70
|
+
const raw = safeRead(sessionKey);
|
|
71
|
+
if (!raw) return null;
|
|
72
|
+
const parsed = JSON.parse(raw);
|
|
73
|
+
if (Number.isInteger(parsed.checkpointRevision)) {
|
|
74
|
+
checkpointRevision = Math.max(checkpointRevision, parsed.checkpointRevision);
|
|
75
|
+
}
|
|
76
|
+
return parsed;
|
|
77
|
+
} catch { return null; }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function saveSession(session) {
|
|
81
|
+
if (!session || !session.id) return;
|
|
82
|
+
// Adopt a revision another tab stored so this write does not lower it.
|
|
83
|
+
// localStorage has no compare-and-set, so a save from another tab that
|
|
84
|
+
// lands between this read and the write below can still be overwritten.
|
|
85
|
+
loadSession();
|
|
86
|
+
const payload = {
|
|
87
|
+
...session,
|
|
88
|
+
checkpointRevision,
|
|
89
|
+
};
|
|
90
|
+
safeWrite(sessionKey, JSON.stringify(payload));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function clearSession() {
|
|
94
|
+
safeRemove(sessionKey);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function nextCheckpointRevision() {
|
|
98
|
+
const existing = loadSession();
|
|
99
|
+
checkpointRevision += 1;
|
|
100
|
+
if (existing?.id) saveSession(existing);
|
|
101
|
+
return checkpointRevision;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function seedCheckpointRevision(value) {
|
|
105
|
+
if (Number.isInteger(value)) checkpointRevision = Math.max(checkpointRevision, value);
|
|
106
|
+
return checkpointRevision;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function currentCheckpointRevision() {
|
|
110
|
+
return checkpointRevision;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function readHandledIds() {
|
|
114
|
+
const raw = safeRead(handledKey);
|
|
115
|
+
if (!raw) return [];
|
|
116
|
+
try {
|
|
117
|
+
const parsed = JSON.parse(raw);
|
|
118
|
+
if (Array.isArray(parsed)) {
|
|
119
|
+
return parsed.filter(id => typeof id === 'string' && id);
|
|
120
|
+
}
|
|
121
|
+
if (typeof parsed === 'string' && parsed) return [parsed];
|
|
122
|
+
} catch { /* legacy values were stored as a plain session id */ }
|
|
123
|
+
return [raw];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function markHandled(id) {
|
|
127
|
+
if (!id) return;
|
|
128
|
+
const ids = readHandledIds().filter(existing => existing !== id);
|
|
129
|
+
ids.push(id);
|
|
130
|
+
safeWrite(handledKey, JSON.stringify(ids.slice(-8)));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function isHandled(id) {
|
|
134
|
+
return !!id && readHandledIds().includes(id);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function clearHandled(id) {
|
|
138
|
+
if (!id) {
|
|
139
|
+
safeRemove(handledKey);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const remaining = readHandledIds().filter(existing => existing !== id);
|
|
143
|
+
if (remaining.length > 0) safeWrite(handledKey, JSON.stringify(remaining));
|
|
144
|
+
else safeRemove(handledKey);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function writeScrollY(y) {
|
|
148
|
+
safeWrite(scrollKey, String(y));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function readScrollY() {
|
|
152
|
+
const raw = safeRead(scrollKey);
|
|
153
|
+
if (raw == null) return null;
|
|
154
|
+
const n = parseFloat(raw);
|
|
155
|
+
return isFinite(n) ? n : null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function clearScrollY() {
|
|
159
|
+
safeRemove(scrollKey);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
owner,
|
|
164
|
+
sessionKey,
|
|
165
|
+
handledKey,
|
|
166
|
+
scrollKey,
|
|
167
|
+
saveSession,
|
|
168
|
+
loadSession,
|
|
169
|
+
clearSession,
|
|
170
|
+
nextCheckpointRevision,
|
|
171
|
+
seedCheckpointRevision,
|
|
172
|
+
currentCheckpointRevision,
|
|
173
|
+
markHandled,
|
|
174
|
+
isHandled,
|
|
175
|
+
clearHandled,
|
|
176
|
+
writeScrollY,
|
|
177
|
+
readScrollY,
|
|
178
|
+
clearScrollY,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
root.__IMPECCABLE_LIVE_SESSION__ = { createLiveBrowserSessionState, randomUUID, randomId8 };
|
|
183
|
+
})(typeof window !== 'undefined' ? window : globalThis);
|