@pinepaper.studio/mcp-server 1.6.16 → 1.6.18
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.de.md +1 -1
- package/README.es.md +1 -1
- package/README.fr.md +1 -1
- package/README.hi.md +1 -1
- package/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +142 -4
- package/README.pt-BR.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/browser/puppeteer-controller.d.ts +61 -1
- package/dist/browser/puppeteer-controller.d.ts.map +1 -1
- package/dist/browser/puppeteer-controller.js +168 -6
- package/dist/browser/puppeteer-controller.js.map +1 -1
- package/dist/build-info.json +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +75 -10
- package/dist/index.js.map +1 -1
- package/dist/ontology/ontology-validator.d.ts.map +1 -1
- package/dist/ontology/ontology-validator.js +9 -5
- package/dist/ontology/ontology-validator.js.map +1 -1
- package/dist/ontology/upstream-vocabulary.d.ts +2 -2
- package/dist/ontology/upstream-vocabulary.js +2 -2
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +198 -47
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/engine-lists.d.ts +20 -0
- package/dist/tools/engine-lists.d.ts.map +1 -0
- package/dist/tools/engine-lists.js +86 -0
- package/dist/tools/engine-lists.js.map +1 -0
- package/dist/tools/engine-methods.d.ts.map +1 -1
- package/dist/tools/engine-methods.js +8 -0
- package/dist/tools/engine-methods.js.map +1 -1
- package/dist/tools/engine-surface.d.ts +1 -1
- package/dist/tools/engine-surface.d.ts.map +1 -1
- package/dist/tools/engine-surface.js +20 -4
- package/dist/tools/engine-surface.js.map +1 -1
- package/dist/tools/handlers/beats.d.ts +64 -0
- package/dist/tools/handlers/beats.d.ts.map +1 -0
- package/dist/tools/handlers/beats.js +83 -0
- package/dist/tools/handlers/beats.js.map +1 -0
- package/dist/tools/handlers/brand-intake.d.ts +95 -0
- package/dist/tools/handlers/brand-intake.d.ts.map +1 -0
- package/dist/tools/handlers/brand-intake.js +242 -0
- package/dist/tools/handlers/brand-intake.js.map +1 -0
- package/dist/tools/handlers.d.ts +23 -11
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/tools/handlers.js +265 -14
- package/dist/tools/handlers.js.map +1 -1
- package/dist/tools/minimal-descriptions.d.ts.map +1 -1
- package/dist/tools/minimal-descriptions.js +5 -3
- package/dist/tools/minimal-descriptions.js.map +1 -1
- package/dist/tools/shape-params.d.ts +2 -2
- package/dist/tools/shape-params.js +2 -2
- package/dist/tools/stick-vocabulary.d.ts +1 -1
- package/dist/tools/stick-vocabulary.js +1 -1
- package/dist/tools/toolkits.d.ts.map +1 -1
- package/dist/tools/toolkits.js +2 -0
- package/dist/tools/toolkits.js.map +1 -1
- package/dist/types/code-generator.d.ts +63 -2
- package/dist/types/code-generator.d.ts.map +1 -1
- package/dist/types/code-generator.js +533 -49
- package/dist/types/code-generator.js.map +1 -1
- package/dist/types/schemas.d.ts +2199 -640
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/schemas.js +186 -50
- package/dist/types/schemas.js.map +1 -1
- package/dist/utils/a11y.d.ts +2 -0
- package/dist/utils/a11y.d.ts.map +1 -1
- package/dist/utils/a11y.js +1 -1
- package/dist/utils/a11y.js.map +1 -1
- package/dist/utils/beats.d.ts +58 -0
- package/dist/utils/beats.d.ts.map +1 -0
- package/dist/utils/beats.js +110 -0
- package/dist/utils/beats.js.map +1 -0
- package/dist/utils/mcp-log.d.ts +16 -0
- package/dist/utils/mcp-log.d.ts.map +1 -0
- package/dist/utils/mcp-log.js +10 -0
- package/dist/utils/mcp-log.js.map +1 -0
- package/dist/utils/progress.d.ts +28 -0
- package/dist/utils/progress.d.ts.map +1 -0
- package/dist/utils/progress.js +24 -0
- package/dist/utils/progress.js.map +1 -0
- package/dist/utils/svg-size.d.ts +22 -0
- package/dist/utils/svg-size.d.ts.map +1 -0
- package/dist/utils/svg-size.js +43 -0
- package/dist/utils/svg-size.js.map +1 -0
- package/dist/vendor/design/design-style.js +1 -1
- package/manifest.json +9 -1
- package/package.json +7 -4
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pinepaper_beat_cuts (plan B2): music → audio_beats analysis → a beat grid →
|
|
3
|
+
* cut points on beats or bars, and optionally a clip split at each one.
|
|
4
|
+
*
|
|
5
|
+
* Orchestrated here through the real tools (audio_beats analyze, media
|
|
6
|
+
* split), so their checks apply: large sources are staged, ids resolve,
|
|
7
|
+
* a refused split is named.
|
|
8
|
+
*/
|
|
9
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { type HandlerOptions } from '../handlers.js';
|
|
12
|
+
export declare const BeatCutsArgsSchema: z.ZodEffects<z.ZodObject<{
|
|
13
|
+
source: z.ZodOptional<z.ZodString>;
|
|
14
|
+
beats: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
15
|
+
bpm: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
bpmHint: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
17
|
+
every: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["beat", "bar"]>, z.ZodNumber]>>;
|
|
18
|
+
beatsPerBar: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
range: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
20
|
+
clipId: z.ZodOptional<z.ZodString>;
|
|
21
|
+
includeOnsets: z.ZodOptional<z.ZodBoolean>;
|
|
22
|
+
}, "strip", z.ZodTypeAny, {
|
|
23
|
+
every?: number | "bar" | "beat" | undefined;
|
|
24
|
+
source?: string | undefined;
|
|
25
|
+
beats?: number[] | undefined;
|
|
26
|
+
range?: [number, number] | undefined;
|
|
27
|
+
bpm?: number | undefined;
|
|
28
|
+
bpmHint?: [number, number] | undefined;
|
|
29
|
+
includeOnsets?: boolean | undefined;
|
|
30
|
+
beatsPerBar?: number | undefined;
|
|
31
|
+
clipId?: string | undefined;
|
|
32
|
+
}, {
|
|
33
|
+
every?: number | "bar" | "beat" | undefined;
|
|
34
|
+
source?: string | undefined;
|
|
35
|
+
beats?: number[] | undefined;
|
|
36
|
+
range?: [number, number] | undefined;
|
|
37
|
+
bpm?: number | undefined;
|
|
38
|
+
bpmHint?: [number, number] | undefined;
|
|
39
|
+
includeOnsets?: boolean | undefined;
|
|
40
|
+
beatsPerBar?: number | undefined;
|
|
41
|
+
clipId?: string | undefined;
|
|
42
|
+
}>, {
|
|
43
|
+
every?: number | "bar" | "beat" | undefined;
|
|
44
|
+
source?: string | undefined;
|
|
45
|
+
beats?: number[] | undefined;
|
|
46
|
+
range?: [number, number] | undefined;
|
|
47
|
+
bpm?: number | undefined;
|
|
48
|
+
bpmHint?: [number, number] | undefined;
|
|
49
|
+
includeOnsets?: boolean | undefined;
|
|
50
|
+
beatsPerBar?: number | undefined;
|
|
51
|
+
clipId?: string | undefined;
|
|
52
|
+
}, {
|
|
53
|
+
every?: number | "bar" | "beat" | undefined;
|
|
54
|
+
source?: string | undefined;
|
|
55
|
+
beats?: number[] | undefined;
|
|
56
|
+
range?: [number, number] | undefined;
|
|
57
|
+
bpm?: number | undefined;
|
|
58
|
+
bpmHint?: [number, number] | undefined;
|
|
59
|
+
includeOnsets?: boolean | undefined;
|
|
60
|
+
beatsPerBar?: number | undefined;
|
|
61
|
+
clipId?: string | undefined;
|
|
62
|
+
}>;
|
|
63
|
+
export declare const beatHandlers: Record<string, (args: Record<string, unknown>, options: HandlerOptions) => Promise<CallToolResult>>;
|
|
64
|
+
//# sourceMappingURL=beats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beats.d.ts","sourceRoot":"","sources":["../../../src/tools/handlers/beats.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAiD,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIpG,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU2F,CAAC;AAO3H,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,cAAc,CAAC,CA2D5H,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { errorResult, getExecutionMode, handleToolCall } from '../handlers.js';
|
|
3
|
+
import { ErrorCodes } from '../../types/schemas.js';
|
|
4
|
+
import { beatGrid, cutPoints, tempoCandidates } from '../../utils/beats.js';
|
|
5
|
+
export const BeatCutsArgsSchema = z.object({
|
|
6
|
+
source: z.string().min(1).optional(),
|
|
7
|
+
beats: z.array(z.number().min(0)).optional(),
|
|
8
|
+
bpm: z.number().positive().max(400).optional(),
|
|
9
|
+
bpmHint: z.tuple([z.number().positive(), z.number().positive()]).optional(),
|
|
10
|
+
every: z.union([z.enum(['beat', 'bar']), z.number().int().min(1).max(64)]).optional(),
|
|
11
|
+
beatsPerBar: z.number().int().min(1).max(16).optional(),
|
|
12
|
+
range: z.tuple([z.number().min(0), z.number().min(0)]).optional(),
|
|
13
|
+
clipId: z.string().min(1).optional(),
|
|
14
|
+
includeOnsets: z.boolean().optional(),
|
|
15
|
+
}).refine((v) => !!(v.source || v.beats), { message: 'give source (music to analyse) or beats (times you already have)' });
|
|
16
|
+
const firstJson = (r) => {
|
|
17
|
+
const c = r.content?.[0];
|
|
18
|
+
try {
|
|
19
|
+
return c && 'text' in c ? JSON.parse(c.text) : null;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
export const beatHandlers = {
|
|
26
|
+
'pinepaper_beat_cuts': async (args, options) => {
|
|
27
|
+
const a = BeatCutsArgsSchema.parse(args);
|
|
28
|
+
let beats = a.beats ? [...a.beats].sort((x, y) => x - y) : null;
|
|
29
|
+
let bpm = a.bpm ?? null;
|
|
30
|
+
let grid = null;
|
|
31
|
+
if (!beats) {
|
|
32
|
+
if ((options.executionMode ?? getExecutionMode()) === 'code' || !options.executeInBrowser) {
|
|
33
|
+
return errorResult(ErrorCodes.VALIDATION_ERROR, 'beat_cuts analyses the music in the studio, so it needs a live studio — or pass beats (times in seconds) you already have.');
|
|
34
|
+
}
|
|
35
|
+
const analysed = await handleToolCall('pinepaper_audio_beats', { action: 'analyze', source: a.source }, options);
|
|
36
|
+
const body = firstJson(analysed);
|
|
37
|
+
const r = body?.result ?? body;
|
|
38
|
+
if (analysed.isError || !r || r.success === false || !Array.isArray(r.onsets) || !(r.bpm > 0)) {
|
|
39
|
+
return errorResult(ErrorCodes.EXECUTION_ERROR, `the music could not be analysed: ${(r && r.error) || JSON.stringify(body).slice(0, 300)}`);
|
|
40
|
+
}
|
|
41
|
+
const duration = Number(r.duration) || Math.max(...r.onsets, 0);
|
|
42
|
+
// The studio's tempo can lock onto a related one (a 120 track read as
|
|
43
|
+
// 162 = 4:3). Its usual confusions are scored against the onsets and
|
|
44
|
+
// the best is used — or the caller's bpm, or the best inside bpmHint.
|
|
45
|
+
const candidates = tempoCandidates(r.onsets, r.bpm, duration, a.bpmHint);
|
|
46
|
+
const chosen = a.bpm ?? candidates[0]?.bpm ?? r.bpm;
|
|
47
|
+
const g = beatGrid(r.onsets, chosen, duration);
|
|
48
|
+
beats = g.beats;
|
|
49
|
+
bpm = g.bpm;
|
|
50
|
+
const conf = candidates.find((c) => c.bpm === Math.round(chosen * 10) / 10)?.confidence ?? null;
|
|
51
|
+
grid = { bpm: g.bpm, phase: g.phase, period: Math.round(g.period * 1000) / 1000, confidence: conf, detected: { bpm: r.bpm, confidence: r.confidence }, duration: r.duration,
|
|
52
|
+
candidates: candidates.slice(0, 4), ...(a.includeOnsets ? { onsets: r.onsets } : {}), ...(a.bpm ? { bpmFrom: 'caller' } : a.bpmHint ? { bpmFrom: 'bpmHint' } : { bpmFrom: 'best candidate' }) };
|
|
53
|
+
if (!a.bpm && (conf === null || conf < 0.4)) {
|
|
54
|
+
grid.lowConfidence = true;
|
|
55
|
+
grid.warning = `the tempo is uncertain (confidence ${conf ?? 'unknown'} at ${g.bpm} bpm; the studio detected ${r.bpm} at ${r.confidence}). If you know it, pass bpm (or bpmHint: [min, max]); the candidates above are the likely alternatives.`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const cuts = cutPoints(beats, a.every ?? 'beat', a.beatsPerBar ?? 4, a.range);
|
|
59
|
+
const out = { success: true, every: a.every ?? 'beat', ...(bpm ? { bpm } : {}), ...(grid ? { grid } : {}), cuts, count: cuts.length };
|
|
60
|
+
// Split a clip at each cut, in order: each split leaves the rest of the clip
|
|
61
|
+
// on the right-hand piece, which is where the next cut falls.
|
|
62
|
+
if (a.clipId && cuts.length) {
|
|
63
|
+
const pieces = [a.clipId];
|
|
64
|
+
let current = a.clipId;
|
|
65
|
+
const refused = [];
|
|
66
|
+
for (const at of cuts) {
|
|
67
|
+
const r = await handleToolCall('pinepaper_media', { action: 'split', id: current, at }, options);
|
|
68
|
+
const body = firstJson(r);
|
|
69
|
+
const res = body?.result ?? body;
|
|
70
|
+
if (r.isError || !res || res.success === false) {
|
|
71
|
+
const e = res?.error;
|
|
72
|
+
refused.push({ at, reason: typeof e === 'string' ? e : (e?.message ?? JSON.stringify(e ?? 'refused')) });
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
current = res.rightId ?? current;
|
|
76
|
+
pieces.push(current);
|
|
77
|
+
}
|
|
78
|
+
out.split = { clipId: a.clipId, pieces, made: pieces.length - 1, ...(refused.length ? { skipped: refused, note: 'cuts outside the clip (before its start or after its end) are skipped.' } : {}) };
|
|
79
|
+
}
|
|
80
|
+
return { content: [{ type: 'text', text: JSON.stringify(out, null, 2) }] };
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=beats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beats.js","sourceRoot":"","sources":["../../../src/tools/handlers/beats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pinepaper_brand_kit `from_url` — a product's real brand, read from its own
|
|
3
|
+
* site, before anything is animated (G4, the brand half).
|
|
4
|
+
*
|
|
5
|
+
* An agent asked for "a promo for <product>" used to invent the brand: a
|
|
6
|
+
* plausible blue, a default font, no logo. This reads the live site instead:
|
|
7
|
+
* screenshots, the logo, and the colours and fonts the site's CSS actually
|
|
8
|
+
* computes, and proposes a kit in the exact shape `plan` / `apply` take, so
|
|
9
|
+
* the agent reviews it and applies it with one more call.
|
|
10
|
+
*
|
|
11
|
+
* The engine has nothing for this, so it runs here, in the MCP server's
|
|
12
|
+
* browser, in an ISOLATED context (controller.withIsolatedPage): the studio
|
|
13
|
+
* tab is never navigated away, and the site's cookies never meet the studio's.
|
|
14
|
+
* The page only measures; choosing which colour is "primary" is a pure
|
|
15
|
+
* function below, so it is unit-tested without a browser.
|
|
16
|
+
*/
|
|
17
|
+
import type { Page } from 'puppeteer';
|
|
18
|
+
/** One colour seen on the page, weighted by how much of the page it covers and how it is used. */
|
|
19
|
+
export interface SeenColor {
|
|
20
|
+
hex: string;
|
|
21
|
+
rgb: [number, number, number];
|
|
22
|
+
weight: number;
|
|
23
|
+
/** Weight per use: 'action-bg' (button/link fill), 'action' (button/link text), 'heading', 'text', 'bg'. */
|
|
24
|
+
roles: Record<string, number>;
|
|
25
|
+
}
|
|
26
|
+
export interface PageMeasure {
|
|
27
|
+
title: string;
|
|
28
|
+
background: [number, number, number];
|
|
29
|
+
text: [number, number, number] | null;
|
|
30
|
+
colors: SeenColor[];
|
|
31
|
+
headingFont: string | null;
|
|
32
|
+
bodyFont: string | null;
|
|
33
|
+
logo: {
|
|
34
|
+
kind: 'img';
|
|
35
|
+
src: string;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'svg';
|
|
38
|
+
markup: string;
|
|
39
|
+
} | null;
|
|
40
|
+
icons: string[];
|
|
41
|
+
ogImage: string | null;
|
|
42
|
+
pageHeight: number;
|
|
43
|
+
}
|
|
44
|
+
export interface BrandKitProposal {
|
|
45
|
+
name: string;
|
|
46
|
+
colors: {
|
|
47
|
+
primary: string;
|
|
48
|
+
secondary?: string;
|
|
49
|
+
accent?: string;
|
|
50
|
+
background?: string;
|
|
51
|
+
text?: string;
|
|
52
|
+
};
|
|
53
|
+
fonts?: {
|
|
54
|
+
heading?: string;
|
|
55
|
+
body?: string;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** The first family in a CSS font-family list that is a real face, not a generic or OS fallback. */
|
|
59
|
+
export declare function firstRealFont(stack: string | null): string | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Pick the kit's roles from what the page measured.
|
|
62
|
+
*
|
|
63
|
+
* primary: the most-used SATURATED colour, with buttons and links counting
|
|
64
|
+
* extra (a brand colour is the one on the call to action, not the one on the
|
|
65
|
+
* largest panel). secondary / accent: the next ones distinct from it. A page
|
|
66
|
+
* with no saturated colour at all is a monochrome brand, and its primary is
|
|
67
|
+
* its text colour. background / text: what body computes.
|
|
68
|
+
*/
|
|
69
|
+
export declare function chooseKit(m: PageMeasure): BrandKitProposal;
|
|
70
|
+
export interface BrandIntakeResult {
|
|
71
|
+
url: string;
|
|
72
|
+
kit: BrandKitProposal;
|
|
73
|
+
screenshots: string[];
|
|
74
|
+
logo: {
|
|
75
|
+
file: string;
|
|
76
|
+
source: string;
|
|
77
|
+
} | null;
|
|
78
|
+
icon: string | null;
|
|
79
|
+
ogImage: string | null;
|
|
80
|
+
measured: {
|
|
81
|
+
colors: Array<{
|
|
82
|
+
hex: string;
|
|
83
|
+
weight: number;
|
|
84
|
+
roles: string[];
|
|
85
|
+
}>;
|
|
86
|
+
headingFont: string | null;
|
|
87
|
+
bodyFont: string | null;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Read a site into a folder: screenshots down the page, the logo, and a kit.
|
|
92
|
+
* `page` is an isolated page the caller owns.
|
|
93
|
+
*/
|
|
94
|
+
export declare function intakeBrand(page: Page, url: string, outDir: string, shots?: number): Promise<BrandIntakeResult>;
|
|
95
|
+
//# sourceMappingURL=brand-intake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brand-intake.d.ts","sourceRoot":"","sources":["../../../src/tools/handlers/brand-intake.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,kGAAkG;AAClG,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,4GAA4G;IAC5G,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACtC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrG,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C;AAgBD,oGAAoG;AACpG,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAOtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,WAAW,GAAG,gBAAgB,CAuC1D;AAsED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,gBAAgB,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE;QAAE,MAAM,EAAE,KAAK,CAAC;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CACpI;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA0DhH"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pinepaper_brand_kit `from_url` — a product's real brand, read from its own
|
|
3
|
+
* site, before anything is animated (G4, the brand half).
|
|
4
|
+
*
|
|
5
|
+
* An agent asked for "a promo for <product>" used to invent the brand: a
|
|
6
|
+
* plausible blue, a default font, no logo. This reads the live site instead:
|
|
7
|
+
* screenshots, the logo, and the colours and fonts the site's CSS actually
|
|
8
|
+
* computes, and proposes a kit in the exact shape `plan` / `apply` take, so
|
|
9
|
+
* the agent reviews it and applies it with one more call.
|
|
10
|
+
*
|
|
11
|
+
* The engine has nothing for this, so it runs here, in the MCP server's
|
|
12
|
+
* browser, in an ISOLATED context (controller.withIsolatedPage): the studio
|
|
13
|
+
* tab is never navigated away, and the site's cookies never meet the studio's.
|
|
14
|
+
* The page only measures; choosing which colour is "primary" is a pure
|
|
15
|
+
* function below, so it is unit-tested without a browser.
|
|
16
|
+
*/
|
|
17
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
const hex = ([r, g, b]) => '#' + [r, g, b].map((v) => Math.round(v).toString(16).padStart(2, '0')).join('');
|
|
20
|
+
const dist = (a, b) => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
|
|
21
|
+
/** HSL saturation, 0..1. Greys, near-black and near-white are not brand colours. */
|
|
22
|
+
function saturation([r, g, b]) {
|
|
23
|
+
const max = Math.max(r, g, b) / 255;
|
|
24
|
+
const min = Math.min(r, g, b) / 255;
|
|
25
|
+
const l = (max + min) / 2;
|
|
26
|
+
if (max === min)
|
|
27
|
+
return 0;
|
|
28
|
+
return l > 0.5 ? (max - min) / (2 - max - min) : (max - min) / (max + min);
|
|
29
|
+
}
|
|
30
|
+
const GENERIC_FONTS = new Set(['serif', 'sans-serif', 'monospace', 'cursive', 'fantasy', 'system-ui', 'ui-sans-serif', 'ui-serif', '-apple-system', 'blinkmacsystemfont', 'segoe ui', 'helvetica', 'arial', 'times new roman', 'times']);
|
|
31
|
+
/** The first family in a CSS font-family list that is a real face, not a generic or OS fallback. */
|
|
32
|
+
export function firstRealFont(stack) {
|
|
33
|
+
if (!stack)
|
|
34
|
+
return undefined;
|
|
35
|
+
for (const raw of stack.split(',')) {
|
|
36
|
+
const f = raw.trim().replace(/^["']|["']$/g, '');
|
|
37
|
+
if (f && !GENERIC_FONTS.has(f.toLowerCase()) && !f.startsWith('var('))
|
|
38
|
+
return f;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Pick the kit's roles from what the page measured.
|
|
44
|
+
*
|
|
45
|
+
* primary: the most-used SATURATED colour, with buttons and links counting
|
|
46
|
+
* extra (a brand colour is the one on the call to action, not the one on the
|
|
47
|
+
* largest panel). secondary / accent: the next ones distinct from it. A page
|
|
48
|
+
* with no saturated colour at all is a monochrome brand, and its primary is
|
|
49
|
+
* its text colour. background / text: what body computes.
|
|
50
|
+
*/
|
|
51
|
+
export function chooseKit(m) {
|
|
52
|
+
const bg = m.background;
|
|
53
|
+
const text = m.text;
|
|
54
|
+
const scored = m.colors
|
|
55
|
+
.filter((c) => saturation(c.rgb) >= 0.25)
|
|
56
|
+
.filter((c) => dist(c.rgb, bg) > 40 && (!text || dist(c.rgb, text) > 40))
|
|
57
|
+
.map((c) => ({ c, score: c.weight + 3 * ((c.roles['action-bg'] ?? 0) + (c.roles['action'] ?? 0)) + 2 * (c.roles['heading'] ?? 0) }))
|
|
58
|
+
.sort((a, b) => b.score - a.score);
|
|
59
|
+
const picked = [];
|
|
60
|
+
// THE CALL TO ACTION DECIDES. Measured on pinepaper.studio: a light indigo
|
|
61
|
+
// used as link and heading TEXT across the page outscored the indigo that
|
|
62
|
+
// fills the "Open Editor" buttons, so the kit's primary was a text tint.
|
|
63
|
+
// When any saturated colour fills a button or link, the one filling the most
|
|
64
|
+
// of them is primary; the rest are ranked as before.
|
|
65
|
+
const cta = scored
|
|
66
|
+
.filter(({ c }) => (c.roles['action-bg'] ?? 0) > 0)
|
|
67
|
+
.sort((a, b) => (b.c.roles['action-bg'] ?? 0) - (a.c.roles['action-bg'] ?? 0))[0];
|
|
68
|
+
if (cta)
|
|
69
|
+
picked.push(cta.c);
|
|
70
|
+
for (const { c } of scored) {
|
|
71
|
+
if (picked.every((p) => dist(p.rgb, c.rgb) > 60))
|
|
72
|
+
picked.push(c);
|
|
73
|
+
if (picked.length === 3)
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
const primary = picked[0]?.hex ?? (text ? hex(text) : '#000000');
|
|
77
|
+
const fonts = {};
|
|
78
|
+
const heading = firstRealFont(m.headingFont);
|
|
79
|
+
const body = firstRealFont(m.bodyFont);
|
|
80
|
+
if (heading)
|
|
81
|
+
fonts.heading = heading;
|
|
82
|
+
if (body)
|
|
83
|
+
fonts.body = body;
|
|
84
|
+
return {
|
|
85
|
+
name: m.title.trim().slice(0, 60) || 'Brand',
|
|
86
|
+
colors: {
|
|
87
|
+
primary,
|
|
88
|
+
...(picked[1] ? { secondary: picked[1].hex } : {}),
|
|
89
|
+
...(picked[2] ? { accent: picked[2].hex } : {}),
|
|
90
|
+
background: hex(bg),
|
|
91
|
+
...(text ? { text: hex(text) } : {}),
|
|
92
|
+
},
|
|
93
|
+
...(Object.keys(fonts).length ? { fonts } : {}),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** Runs IN the site's page. Measures only; decides nothing. */
|
|
97
|
+
function measurePage() {
|
|
98
|
+
const parse = (c) => {
|
|
99
|
+
const m = c && c.match(/rgba?\(([^)]+)\)/);
|
|
100
|
+
if (!m)
|
|
101
|
+
return null;
|
|
102
|
+
const p = m[1].split(/[,\s/]+/).filter(Boolean).map(parseFloat);
|
|
103
|
+
if (p.length >= 4 && p[3] < 0.5)
|
|
104
|
+
return null;
|
|
105
|
+
return [p[0], p[1], p[2]];
|
|
106
|
+
};
|
|
107
|
+
const toHex = (rgb) => '#' + rgb.map((v) => Math.round(v).toString(16).padStart(2, '0')).join('');
|
|
108
|
+
const tally = {};
|
|
109
|
+
const add = (rgb, w, role) => {
|
|
110
|
+
if (!rgb || !(w > 0))
|
|
111
|
+
return;
|
|
112
|
+
const h = toHex(rgb);
|
|
113
|
+
const t = tally[h] || (tally[h] = { hex: h, rgb, weight: 0, roles: {} });
|
|
114
|
+
t.weight += w;
|
|
115
|
+
t.roles[role] = (t.roles[role] || 0) + w;
|
|
116
|
+
};
|
|
117
|
+
const vw = window.innerWidth;
|
|
118
|
+
const vh = window.innerHeight;
|
|
119
|
+
const els = Array.from(document.querySelectorAll('body *')).slice(0, 5000);
|
|
120
|
+
for (const el of els) {
|
|
121
|
+
const r = el.getBoundingClientRect();
|
|
122
|
+
if (r.width < 2 || r.height < 2)
|
|
123
|
+
continue;
|
|
124
|
+
const cs = getComputedStyle(el);
|
|
125
|
+
if (cs.visibility === 'hidden' || cs.display === 'none' || parseFloat(cs.opacity) === 0)
|
|
126
|
+
continue;
|
|
127
|
+
const area = Math.min(r.width * r.height, vw * vh);
|
|
128
|
+
const tag = el.tagName;
|
|
129
|
+
const interactive = tag === 'A' || tag === 'BUTTON' || el.getAttribute('role') === 'button';
|
|
130
|
+
add(parse(cs.backgroundColor), area, interactive ? 'action-bg' : 'bg');
|
|
131
|
+
const hasText = Array.from(el.childNodes).some((n) => n.nodeType === 3 && (n.textContent || '').trim() !== '');
|
|
132
|
+
if (hasText)
|
|
133
|
+
add(parse(cs.color), Math.min(area, 20000), /^H[1-3]$/.test(tag) ? 'heading' : interactive ? 'action' : 'text');
|
|
134
|
+
}
|
|
135
|
+
const body = getComputedStyle(document.body);
|
|
136
|
+
const background = parse(body.backgroundColor) || parse(getComputedStyle(document.documentElement).backgroundColor) || [255, 255, 255];
|
|
137
|
+
const heading = document.querySelector('h1') || document.querySelector('h2');
|
|
138
|
+
const para = document.querySelector('main p, article p, p') || document.body;
|
|
139
|
+
const abs = (u) => { try {
|
|
140
|
+
return u ? new URL(u, location.href).href : null;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return null;
|
|
144
|
+
} };
|
|
145
|
+
const meta = (sel) => document.querySelector(sel)?.content || null;
|
|
146
|
+
let logo = null;
|
|
147
|
+
const img = document.querySelector('header img, nav img, [class*="logo" i] img, img[alt*="logo" i], img[src*="logo" i], img[class*="logo" i]');
|
|
148
|
+
const svg = document.querySelector('header svg, [class*="logo" i] svg, a[href="/"] svg, nav svg');
|
|
149
|
+
if (img && (img.currentSrc || img.src))
|
|
150
|
+
logo = { kind: 'img', src: abs(img.currentSrc || img.src) };
|
|
151
|
+
else if (svg && svg.outerHTML.length < 200_000)
|
|
152
|
+
logo = { kind: 'svg', markup: svg.outerHTML };
|
|
153
|
+
const icons = Array.from(document.querySelectorAll('link[rel~="icon"], link[rel="apple-touch-icon"]'))
|
|
154
|
+
.map((l) => ({ href: abs(l.getAttribute('href')), size: parseInt((l.getAttribute('sizes') || '0').split('x')[0], 10) || 0 }))
|
|
155
|
+
.filter((i) => !!i.href)
|
|
156
|
+
.sort((a, b) => b.size - a.size)
|
|
157
|
+
.map((i) => i.href);
|
|
158
|
+
return {
|
|
159
|
+
title: meta('meta[property="og:site_name"]') || document.title || location.hostname,
|
|
160
|
+
background,
|
|
161
|
+
text: parse(body.color),
|
|
162
|
+
colors: Object.values(tally).sort((a, b) => b.weight - a.weight).slice(0, 40),
|
|
163
|
+
headingFont: heading ? getComputedStyle(heading).fontFamily : null,
|
|
164
|
+
bodyFont: getComputedStyle(para).fontFamily,
|
|
165
|
+
logo,
|
|
166
|
+
icons,
|
|
167
|
+
ogImage: abs(meta('meta[property="og:image"]')),
|
|
168
|
+
pageHeight: Math.max(document.documentElement.scrollHeight, document.body.scrollHeight),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
const EXT_BY_TYPE = { 'image/png': 'png', 'image/jpeg': 'jpg', 'image/webp': 'webp', 'image/svg+xml': 'svg', 'image/gif': 'gif', 'image/x-icon': 'ico', 'image/vnd.microsoft.icon': 'ico' };
|
|
172
|
+
/**
|
|
173
|
+
* Read a site into a folder: screenshots down the page, the logo, and a kit.
|
|
174
|
+
* `page` is an isolated page the caller owns.
|
|
175
|
+
*/
|
|
176
|
+
export async function intakeBrand(page, url, outDir, shots = 3) {
|
|
177
|
+
await page.setViewport({ width: 1440, height: 900 });
|
|
178
|
+
await page.goto(url, { waitUntil: 'networkidle2', timeout: 45_000 });
|
|
179
|
+
const m = await page.evaluate(measurePage);
|
|
180
|
+
await mkdir(outDir, { recursive: true });
|
|
181
|
+
const screenshots = [];
|
|
182
|
+
const maxY = Math.max(0, m.pageHeight - 900);
|
|
183
|
+
for (let i = 0; i < shots; i++) {
|
|
184
|
+
const y = shots === 1 ? 0 : Math.round((maxY * i) / (shots - 1));
|
|
185
|
+
await page.evaluate((top) => window.scrollTo(0, top), y);
|
|
186
|
+
await new Promise((r) => setTimeout(r, 400));
|
|
187
|
+
const file = join(outDir, `screenshot-${i + 1}.png`);
|
|
188
|
+
await writeFile(file, await page.screenshot({ type: 'png' }));
|
|
189
|
+
screenshots.push(file);
|
|
190
|
+
}
|
|
191
|
+
// The logo: the header's own image or SVG, else the largest icon, else og:image.
|
|
192
|
+
let logo = null;
|
|
193
|
+
const fetchTo = async (src, base) => {
|
|
194
|
+
const res = await fetch(src);
|
|
195
|
+
if (!res.ok)
|
|
196
|
+
return null;
|
|
197
|
+
const type = (res.headers.get('content-type') || '').split(';')[0].trim();
|
|
198
|
+
const ext = EXT_BY_TYPE[type] || (src.match(/\.(png|jpe?g|webp|svg|gif|ico)(\?|$)/i)?.[1]?.toLowerCase().replace('jpeg', 'jpg')) || 'img';
|
|
199
|
+
const file = join(outDir, `${base}.${ext}`);
|
|
200
|
+
await writeFile(file, Buffer.from(await res.arrayBuffer()));
|
|
201
|
+
return file;
|
|
202
|
+
};
|
|
203
|
+
try {
|
|
204
|
+
if (m.logo?.kind === 'svg') {
|
|
205
|
+
const file = join(outDir, 'logo.svg');
|
|
206
|
+
const markup = m.logo.markup.includes('xmlns=') ? m.logo.markup : m.logo.markup.replace('<svg', '<svg xmlns="http://www.w3.org/2000/svg"');
|
|
207
|
+
await writeFile(file, markup);
|
|
208
|
+
logo = { file, source: 'inline svg in the page header' };
|
|
209
|
+
}
|
|
210
|
+
else if (m.logo?.kind === 'img') {
|
|
211
|
+
const file = await fetchTo(m.logo.src, 'logo');
|
|
212
|
+
if (file)
|
|
213
|
+
logo = { file, source: m.logo.src };
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch { /* fall through to the icon */ }
|
|
217
|
+
let icon = null;
|
|
218
|
+
if (m.icons[0]) {
|
|
219
|
+
try {
|
|
220
|
+
icon = await fetchTo(m.icons[0], 'icon');
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
icon = null;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (!logo && icon)
|
|
227
|
+
logo = { file: icon, source: `${m.icons[0]} (site icon: no header logo found)` };
|
|
228
|
+
return {
|
|
229
|
+
url,
|
|
230
|
+
kit: chooseKit(m),
|
|
231
|
+
screenshots,
|
|
232
|
+
logo,
|
|
233
|
+
icon,
|
|
234
|
+
ogImage: m.ogImage,
|
|
235
|
+
measured: {
|
|
236
|
+
colors: m.colors.slice(0, 8).map((c) => ({ hex: c.hex, weight: Math.round(c.weight), roles: Object.keys(c.roles) })),
|
|
237
|
+
headingFont: m.headingFont,
|
|
238
|
+
bodyFont: m.bodyFont,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=brand-intake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brand-intake.js","sourceRoot":"","sources":["../../../src/tools/handlers/brand-intake.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/handlers.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export type ScreenshotMode = 'on_request' | 'always' | 'never';
|
|
|
23
23
|
* Defaults to 'on_request' for optimal performance.
|
|
24
24
|
*/
|
|
25
25
|
export declare function getScreenshotMode(): ScreenshotMode;
|
|
26
|
+
export declare function getExportDir(): string;
|
|
26
27
|
export declare const ALWAYS_SAVE_FORMATS: Set<string>;
|
|
27
28
|
export declare function fetchImageAsDataUrl(url: string): Promise<{
|
|
28
29
|
src: string;
|
|
@@ -72,20 +73,30 @@ export interface HandlerOptions {
|
|
|
72
73
|
saveToFile?: boolean;
|
|
73
74
|
}
|
|
74
75
|
export declare function errorResult(code: string, message: string, rawDetails?: unknown, context?: ErrorContext): CallToolResult;
|
|
76
|
+
type RollbackController = {
|
|
77
|
+
executeCode: (code: string, screenshot?: boolean, opts?: {
|
|
78
|
+
bypassGovernor?: boolean;
|
|
79
|
+
}) => Promise<{
|
|
80
|
+
success: boolean;
|
|
81
|
+
result?: unknown;
|
|
82
|
+
}>;
|
|
83
|
+
};
|
|
75
84
|
/**
|
|
76
|
-
*
|
|
85
|
+
* Remove what agent-written code created before it failed, and say so.
|
|
77
86
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* Default is 'on_request' for optimal performance per best practices.
|
|
87
|
+
* A run stopped by the loop deadline after drawing 42 strokes left them on
|
|
88
|
+
* the canvas: a half-painted scene. Undo cannot fix that. The governor's one
|
|
89
|
+
* history entry only covers mutations that announce themselves, and raw
|
|
90
|
+
* `new paper.Path(...)` does not (measured: report.mutated false, 30 paths
|
|
91
|
+
* left behind). So the rollback is by identity instead: every item that was
|
|
92
|
+
* not on the canvas before the call goes, through app.deleteItem where the
|
|
93
|
+
* engine knows the item (registry, trackers) and item.remove() otherwise.
|
|
94
|
+
* Edits to items that already existed are NOT reverted; the note says so.
|
|
88
95
|
*/
|
|
96
|
+
export declare function customCodeRollback(controller: RollbackController, error: string | undefined): Promise<{
|
|
97
|
+
rolledBack: boolean;
|
|
98
|
+
note: string;
|
|
99
|
+
}>;
|
|
89
100
|
export declare function executeOrGenerate(code: string, description: string, options: HandlerOptions, toolName: string,
|
|
90
101
|
/**
|
|
91
102
|
* Values too large to live inside the generated code. Written to
|
|
@@ -109,4 +120,5 @@ export declare function innerFailure(value: unknown): string | null;
|
|
|
109
120
|
export declare function getLocalizedSuccessMessage(i18n: I18nManager | undefined, key: string, params: Record<string, string | number>): string;
|
|
110
121
|
export declare function ignoredArgumentsNote(toolName: string, args: Record<string, unknown>): string | null;
|
|
111
122
|
export declare function handleToolCall(toolName: string, args: Record<string, unknown>, options?: HandlerOptions): Promise<CallToolResult>;
|
|
123
|
+
export {};
|
|
112
124
|
//# sourceMappingURL=handlers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/tools/handlers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAA6B,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/tools/handlers.ts"],"names":[],"mappings":"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"}
|