@typecaast/capture 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,37 @@
1
+ import { SkinDraft } from './draft.js';
2
+
3
+ /**
4
+ * The distiller (PLAN §10): given a chat-UI subtree, produce a sanitized,
5
+ * slotted `SkinDraft`. The pipeline is
6
+ *
7
+ * clone → inline computed styles (live capture) → drop hidden/`data-*` →
8
+ * sanitize (allowlist) → find the repeating message row → slot-ify
9
+ * (author/avatar/body/time) → carve the frame chrome → find the composer →
10
+ * extract tokens → report.
11
+ *
12
+ * Capture gets you ~80% of the way; the emitted `detection` report and
13
+ * `warnings` tell the author exactly what to confirm by hand (the §10 quality
14
+ * bar treats anything below the bar as "draft only", never a finished skin).
15
+ * The function is DOM-agnostic — the extension passes a live element, the
16
+ * saved-page importer passes a jsdom element.
17
+ */
18
+ interface WindowLike {
19
+ document: Document;
20
+ getComputedStyle?: (el: Element) => CSSStyleDeclaration;
21
+ }
22
+ interface DistillOptions {
23
+ /** DOM window (defaults to global `window`). Required in Node. */
24
+ window?: WindowLike;
25
+ /** Display name for the draft. */
26
+ name?: string;
27
+ sourceUrl?: string;
28
+ theme?: "light" | "dark";
29
+ /**
30
+ * Inline computed styles from the live page so fidelity survives losing the
31
+ * cascade. Off for saved-page import (the source CSS comes inline already).
32
+ */
33
+ inlineComputedStyles?: boolean;
34
+ }
35
+ declare function distill(root: Element, opts?: DistillOptions): SkinDraft;
36
+
37
+ export { type DistillOptions as D, distill as d };
@@ -0,0 +1,37 @@
1
+ import { SkinDraft } from './draft.cjs';
2
+
3
+ /**
4
+ * The distiller (PLAN §10): given a chat-UI subtree, produce a sanitized,
5
+ * slotted `SkinDraft`. The pipeline is
6
+ *
7
+ * clone → inline computed styles (live capture) → drop hidden/`data-*` →
8
+ * sanitize (allowlist) → find the repeating message row → slot-ify
9
+ * (author/avatar/body/time) → carve the frame chrome → find the composer →
10
+ * extract tokens → report.
11
+ *
12
+ * Capture gets you ~80% of the way; the emitted `detection` report and
13
+ * `warnings` tell the author exactly what to confirm by hand (the §10 quality
14
+ * bar treats anything below the bar as "draft only", never a finished skin).
15
+ * The function is DOM-agnostic — the extension passes a live element, the
16
+ * saved-page importer passes a jsdom element.
17
+ */
18
+ interface WindowLike {
19
+ document: Document;
20
+ getComputedStyle?: (el: Element) => CSSStyleDeclaration;
21
+ }
22
+ interface DistillOptions {
23
+ /** DOM window (defaults to global `window`). Required in Node. */
24
+ window?: WindowLike;
25
+ /** Display name for the draft. */
26
+ name?: string;
27
+ sourceUrl?: string;
28
+ theme?: "light" | "dark";
29
+ /**
30
+ * Inline computed styles from the live page so fidelity survives losing the
31
+ * cascade. Off for saved-page import (the source CSS comes inline already).
32
+ */
33
+ inlineComputedStyles?: boolean;
34
+ }
35
+ declare function distill(root: Element, opts?: DistillOptions): SkinDraft;
36
+
37
+ export { type DistillOptions as D, distill as d };
package/dist/draft.cjs ADDED
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ var zod = require('zod');
4
+
5
+ // src/draft.ts
6
+ var SLOT_TOKENS = {
7
+ messages: "{{messages}}",
8
+ author: "{{author}}",
9
+ avatar: "{{avatar}}",
10
+ body: "{{body}}",
11
+ time: "{{time}}",
12
+ composer: "{{composer}}"
13
+ };
14
+ var slotReportSchema = zod.z.object({
15
+ /** Whether this region was found at all. */
16
+ found: zod.z.boolean(),
17
+ /** Which inner slots were auto-detected (e.g. `["author","body"]`). */
18
+ detected: zod.z.array(zod.z.string()),
19
+ /** Heuristic confidence 0..1 for the auto-detection. */
20
+ confidence: zod.z.number().min(0).max(1)
21
+ });
22
+ var tokenSetSchema = zod.z.object({
23
+ colors: zod.z.record(zod.z.string(), zod.z.string()),
24
+ fonts: zod.z.record(zod.z.string(), zod.z.string()).optional(),
25
+ space: zod.z.record(zod.z.string(), zod.z.string()).optional(),
26
+ radius: zod.z.record(zod.z.string(), zod.z.string()).optional()
27
+ });
28
+ var skinDraftSchema = zod.z.object({
29
+ version: zod.z.literal(1),
30
+ meta: zod.z.object({
31
+ /** Human label, defaulted from the source title/host. */
32
+ name: zod.z.string(),
33
+ /** Source page URL, when known (informational only). */
34
+ sourceUrl: zod.z.string().optional(),
35
+ /** Theme the capture was taken under, when known. */
36
+ theme: zod.z.enum(["light", "dark"]).optional(),
37
+ /** Suggested canvas from the captured element's box. */
38
+ canvas: zod.z.object({ width: zod.z.number().int(), height: zod.z.number().int() }).optional()
39
+ }),
40
+ /**
41
+ * Slotted, sanitized HTML per region. Elements carry inline `style`
42
+ * attributes; `css` holds anything inline styles can't express.
43
+ */
44
+ slots: zod.z.object({
45
+ frame: zod.z.string().optional(),
46
+ message: zod.z.string().optional(),
47
+ composer: zod.z.string().optional(),
48
+ typing: zod.z.string().optional()
49
+ }),
50
+ /** Best-effort extra CSS (pseudo-elements, keyframes) — may be empty. */
51
+ css: zod.z.string(),
52
+ /** Extracted design tokens (best effort) — the primary/captured theme. */
53
+ tokens: tokenSetSchema,
54
+ /**
55
+ * Dark-theme tokens from a paired capture (M5.7 double-capture flow). When
56
+ * present, the skin supports both themes and switches CSS vars by theme.
57
+ */
58
+ darkTokens: tokenSetSchema.optional(),
59
+ /** Detection report per region. */
60
+ detection: zod.z.object({
61
+ frame: slotReportSchema,
62
+ message: slotReportSchema,
63
+ composer: slotReportSchema,
64
+ typing: slotReportSchema
65
+ }),
66
+ /** Human-readable warnings (hidden content dropped, slots missing, …). */
67
+ warnings: zod.z.array(zod.z.string())
68
+ });
69
+ function detectionScore(draft) {
70
+ const checks = [
71
+ draft.detection.message.detected.includes("body"),
72
+ draft.detection.message.detected.includes("author"),
73
+ draft.detection.message.detected.includes("avatar"),
74
+ draft.detection.message.detected.includes("time"),
75
+ draft.detection.composer.found
76
+ ];
77
+ return checks.filter(Boolean).length / checks.length;
78
+ }
79
+
80
+ exports.SLOT_TOKENS = SLOT_TOKENS;
81
+ exports.detectionScore = detectionScore;
82
+ exports.skinDraftSchema = skinDraftSchema;
83
+ exports.slotReportSchema = slotReportSchema;
84
+ //# sourceMappingURL=draft.cjs.map
85
+ //# sourceMappingURL=draft.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/draft.ts"],"names":["z"],"mappings":"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","file":"draft.cjs","sourcesContent":["import { z } from \"zod\";\n\n/**\n * A `SkinDraft` is what the distiller emits from a captured chat UI: sanitized,\n * slotted HTML templates (with inline styles), extracted design tokens, and a\n * detection report describing what was auto-identified vs. what still needs a\n * human pass (PLAN §10). A draft is *not* a finished skin — `scaffold-skin`\n * turns one into an editable template-skin package, and the capture quality bar\n * (§10) decides whether it ships as a skin or stays \"draft only\".\n *\n * Slot tokens are double-brace placeholders the `TemplateSkinAdapter` fills:\n * frame: `{{messages}}` — where the message list mounts\n * message: `{{author}}` `{{avatar}}` `{{body}}` `{{time}}`\n * composer: `{{composer}}`\n * typing: `{{author}}`\n */\n\nexport const SLOT_TOKENS = {\n messages: \"{{messages}}\",\n author: \"{{author}}\",\n avatar: \"{{avatar}}\",\n body: \"{{body}}\",\n time: \"{{time}}\",\n composer: \"{{composer}}\",\n} as const;\n\nexport type SlotName = \"frame\" | \"message\" | \"composer\" | \"typing\";\n\n/** Per-slot detection outcome — drives the quality-bar metric (§10). */\nexport const slotReportSchema = z.object({\n /** Whether this region was found at all. */\n found: z.boolean(),\n /** Which inner slots were auto-detected (e.g. `[\"author\",\"body\"]`). */\n detected: z.array(z.string()),\n /** Heuristic confidence 0..1 for the auto-detection. */\n confidence: z.number().min(0).max(1),\n});\nexport type SlotReport = z.infer<typeof slotReportSchema>;\n\nconst tokenSetSchema = z.object({\n colors: z.record(z.string(), z.string()),\n fonts: z.record(z.string(), z.string()).optional(),\n space: z.record(z.string(), z.string()).optional(),\n radius: z.record(z.string(), z.string()).optional(),\n});\n\nexport const skinDraftSchema = z.object({\n version: z.literal(1),\n meta: z.object({\n /** Human label, defaulted from the source title/host. */\n name: z.string(),\n /** Source page URL, when known (informational only). */\n sourceUrl: z.string().optional(),\n /** Theme the capture was taken under, when known. */\n theme: z.enum([\"light\", \"dark\"]).optional(),\n /** Suggested canvas from the captured element's box. */\n canvas: z\n .object({ width: z.number().int(), height: z.number().int() })\n .optional(),\n }),\n /**\n * Slotted, sanitized HTML per region. Elements carry inline `style`\n * attributes; `css` holds anything inline styles can't express.\n */\n slots: z.object({\n frame: z.string().optional(),\n message: z.string().optional(),\n composer: z.string().optional(),\n typing: z.string().optional(),\n }),\n /** Best-effort extra CSS (pseudo-elements, keyframes) — may be empty. */\n css: z.string(),\n /** Extracted design tokens (best effort) — the primary/captured theme. */\n tokens: tokenSetSchema,\n /**\n * Dark-theme tokens from a paired capture (M5.7 double-capture flow). When\n * present, the skin supports both themes and switches CSS vars by theme.\n */\n darkTokens: tokenSetSchema.optional(),\n /** Detection report per region. */\n detection: z.object({\n frame: slotReportSchema,\n message: slotReportSchema,\n composer: slotReportSchema,\n typing: slotReportSchema,\n }),\n /** Human-readable warnings (hidden content dropped, slots missing, …). */\n warnings: z.array(z.string()),\n});\n\nexport type SkinDraft = z.infer<typeof skinDraftSchema>;\n\n/** Overall slot-detection ratio used by the §10 quality bar (0..1). */\nexport function detectionScore(draft: SkinDraft): number {\n // The five core slots: message-row found, author, avatar, body, composer.\n const checks = [\n draft.detection.message.detected.includes(\"body\"),\n draft.detection.message.detected.includes(\"author\"),\n draft.detection.message.detected.includes(\"avatar\"),\n draft.detection.message.detected.includes(\"time\"),\n draft.detection.composer.found,\n ];\n return checks.filter(Boolean).length / checks.length;\n}\n"]}
@@ -0,0 +1,94 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * A `SkinDraft` is what the distiller emits from a captured chat UI: sanitized,
5
+ * slotted HTML templates (with inline styles), extracted design tokens, and a
6
+ * detection report describing what was auto-identified vs. what still needs a
7
+ * human pass (PLAN §10). A draft is *not* a finished skin — `scaffold-skin`
8
+ * turns one into an editable template-skin package, and the capture quality bar
9
+ * (§10) decides whether it ships as a skin or stays "draft only".
10
+ *
11
+ * Slot tokens are double-brace placeholders the `TemplateSkinAdapter` fills:
12
+ * frame: `{{messages}}` — where the message list mounts
13
+ * message: `{{author}}` `{{avatar}}` `{{body}}` `{{time}}`
14
+ * composer: `{{composer}}`
15
+ * typing: `{{author}}`
16
+ */
17
+ declare const SLOT_TOKENS: {
18
+ readonly messages: "{{messages}}";
19
+ readonly author: "{{author}}";
20
+ readonly avatar: "{{avatar}}";
21
+ readonly body: "{{body}}";
22
+ readonly time: "{{time}}";
23
+ readonly composer: "{{composer}}";
24
+ };
25
+ type SlotName = "frame" | "message" | "composer" | "typing";
26
+ /** Per-slot detection outcome — drives the quality-bar metric (§10). */
27
+ declare const slotReportSchema: z.ZodObject<{
28
+ found: z.ZodBoolean;
29
+ detected: z.ZodArray<z.ZodString>;
30
+ confidence: z.ZodNumber;
31
+ }, z.core.$strip>;
32
+ type SlotReport = z.infer<typeof slotReportSchema>;
33
+ declare const skinDraftSchema: z.ZodObject<{
34
+ version: z.ZodLiteral<1>;
35
+ meta: z.ZodObject<{
36
+ name: z.ZodString;
37
+ sourceUrl: z.ZodOptional<z.ZodString>;
38
+ theme: z.ZodOptional<z.ZodEnum<{
39
+ light: "light";
40
+ dark: "dark";
41
+ }>>;
42
+ canvas: z.ZodOptional<z.ZodObject<{
43
+ width: z.ZodNumber;
44
+ height: z.ZodNumber;
45
+ }, z.core.$strip>>;
46
+ }, z.core.$strip>;
47
+ slots: z.ZodObject<{
48
+ frame: z.ZodOptional<z.ZodString>;
49
+ message: z.ZodOptional<z.ZodString>;
50
+ composer: z.ZodOptional<z.ZodString>;
51
+ typing: z.ZodOptional<z.ZodString>;
52
+ }, z.core.$strip>;
53
+ css: z.ZodString;
54
+ tokens: z.ZodObject<{
55
+ colors: z.ZodRecord<z.ZodString, z.ZodString>;
56
+ fonts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
57
+ space: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
58
+ radius: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
59
+ }, z.core.$strip>;
60
+ darkTokens: z.ZodOptional<z.ZodObject<{
61
+ colors: z.ZodRecord<z.ZodString, z.ZodString>;
62
+ fonts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
63
+ space: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
64
+ radius: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
65
+ }, z.core.$strip>>;
66
+ detection: z.ZodObject<{
67
+ frame: z.ZodObject<{
68
+ found: z.ZodBoolean;
69
+ detected: z.ZodArray<z.ZodString>;
70
+ confidence: z.ZodNumber;
71
+ }, z.core.$strip>;
72
+ message: z.ZodObject<{
73
+ found: z.ZodBoolean;
74
+ detected: z.ZodArray<z.ZodString>;
75
+ confidence: z.ZodNumber;
76
+ }, z.core.$strip>;
77
+ composer: z.ZodObject<{
78
+ found: z.ZodBoolean;
79
+ detected: z.ZodArray<z.ZodString>;
80
+ confidence: z.ZodNumber;
81
+ }, z.core.$strip>;
82
+ typing: z.ZodObject<{
83
+ found: z.ZodBoolean;
84
+ detected: z.ZodArray<z.ZodString>;
85
+ confidence: z.ZodNumber;
86
+ }, z.core.$strip>;
87
+ }, z.core.$strip>;
88
+ warnings: z.ZodArray<z.ZodString>;
89
+ }, z.core.$strip>;
90
+ type SkinDraft = z.infer<typeof skinDraftSchema>;
91
+ /** Overall slot-detection ratio used by the §10 quality bar (0..1). */
92
+ declare function detectionScore(draft: SkinDraft): number;
93
+
94
+ export { SLOT_TOKENS, type SkinDraft, type SlotName, type SlotReport, detectionScore, skinDraftSchema, slotReportSchema };
@@ -0,0 +1,94 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * A `SkinDraft` is what the distiller emits from a captured chat UI: sanitized,
5
+ * slotted HTML templates (with inline styles), extracted design tokens, and a
6
+ * detection report describing what was auto-identified vs. what still needs a
7
+ * human pass (PLAN §10). A draft is *not* a finished skin — `scaffold-skin`
8
+ * turns one into an editable template-skin package, and the capture quality bar
9
+ * (§10) decides whether it ships as a skin or stays "draft only".
10
+ *
11
+ * Slot tokens are double-brace placeholders the `TemplateSkinAdapter` fills:
12
+ * frame: `{{messages}}` — where the message list mounts
13
+ * message: `{{author}}` `{{avatar}}` `{{body}}` `{{time}}`
14
+ * composer: `{{composer}}`
15
+ * typing: `{{author}}`
16
+ */
17
+ declare const SLOT_TOKENS: {
18
+ readonly messages: "{{messages}}";
19
+ readonly author: "{{author}}";
20
+ readonly avatar: "{{avatar}}";
21
+ readonly body: "{{body}}";
22
+ readonly time: "{{time}}";
23
+ readonly composer: "{{composer}}";
24
+ };
25
+ type SlotName = "frame" | "message" | "composer" | "typing";
26
+ /** Per-slot detection outcome — drives the quality-bar metric (§10). */
27
+ declare const slotReportSchema: z.ZodObject<{
28
+ found: z.ZodBoolean;
29
+ detected: z.ZodArray<z.ZodString>;
30
+ confidence: z.ZodNumber;
31
+ }, z.core.$strip>;
32
+ type SlotReport = z.infer<typeof slotReportSchema>;
33
+ declare const skinDraftSchema: z.ZodObject<{
34
+ version: z.ZodLiteral<1>;
35
+ meta: z.ZodObject<{
36
+ name: z.ZodString;
37
+ sourceUrl: z.ZodOptional<z.ZodString>;
38
+ theme: z.ZodOptional<z.ZodEnum<{
39
+ light: "light";
40
+ dark: "dark";
41
+ }>>;
42
+ canvas: z.ZodOptional<z.ZodObject<{
43
+ width: z.ZodNumber;
44
+ height: z.ZodNumber;
45
+ }, z.core.$strip>>;
46
+ }, z.core.$strip>;
47
+ slots: z.ZodObject<{
48
+ frame: z.ZodOptional<z.ZodString>;
49
+ message: z.ZodOptional<z.ZodString>;
50
+ composer: z.ZodOptional<z.ZodString>;
51
+ typing: z.ZodOptional<z.ZodString>;
52
+ }, z.core.$strip>;
53
+ css: z.ZodString;
54
+ tokens: z.ZodObject<{
55
+ colors: z.ZodRecord<z.ZodString, z.ZodString>;
56
+ fonts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
57
+ space: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
58
+ radius: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
59
+ }, z.core.$strip>;
60
+ darkTokens: z.ZodOptional<z.ZodObject<{
61
+ colors: z.ZodRecord<z.ZodString, z.ZodString>;
62
+ fonts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
63
+ space: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
64
+ radius: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
65
+ }, z.core.$strip>>;
66
+ detection: z.ZodObject<{
67
+ frame: z.ZodObject<{
68
+ found: z.ZodBoolean;
69
+ detected: z.ZodArray<z.ZodString>;
70
+ confidence: z.ZodNumber;
71
+ }, z.core.$strip>;
72
+ message: z.ZodObject<{
73
+ found: z.ZodBoolean;
74
+ detected: z.ZodArray<z.ZodString>;
75
+ confidence: z.ZodNumber;
76
+ }, z.core.$strip>;
77
+ composer: z.ZodObject<{
78
+ found: z.ZodBoolean;
79
+ detected: z.ZodArray<z.ZodString>;
80
+ confidence: z.ZodNumber;
81
+ }, z.core.$strip>;
82
+ typing: z.ZodObject<{
83
+ found: z.ZodBoolean;
84
+ detected: z.ZodArray<z.ZodString>;
85
+ confidence: z.ZodNumber;
86
+ }, z.core.$strip>;
87
+ }, z.core.$strip>;
88
+ warnings: z.ZodArray<z.ZodString>;
89
+ }, z.core.$strip>;
90
+ type SkinDraft = z.infer<typeof skinDraftSchema>;
91
+ /** Overall slot-detection ratio used by the §10 quality bar (0..1). */
92
+ declare function detectionScore(draft: SkinDraft): number;
93
+
94
+ export { SLOT_TOKENS, type SkinDraft, type SlotName, type SlotReport, detectionScore, skinDraftSchema, slotReportSchema };
package/dist/draft.js ADDED
@@ -0,0 +1,3 @@
1
+ export { SLOT_TOKENS, detectionScore, skinDraftSchema, slotReportSchema } from './chunk-2UORYZUZ.js';
2
+ //# sourceMappingURL=draft.js.map
3
+ //# sourceMappingURL=draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"draft.js"}