rtistree 0.5.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/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +99 -0
- package/THIRD_PARTY_NOTICES.md +25 -0
- package/dist/art-direction.d.ts +77 -0
- package/dist/art-direction.js +186 -0
- package/dist/art-direction.js.map +1 -0
- package/dist/artifacts.d.ts +24 -0
- package/dist/artifacts.js +49 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/assets.d.ts +16 -0
- package/dist/assets.js +96 -0
- package/dist/assets.js.map +1 -0
- package/dist/benchmark.d.ts +76 -0
- package/dist/benchmark.js +118 -0
- package/dist/benchmark.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +300 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +5315 -0
- package/dist/commands.js +591 -0
- package/dist/commands.js.map +1 -0
- package/dist/components.d.ts +20 -0
- package/dist/components.js +98 -0
- package/dist/components.js.map +1 -0
- package/dist/construction.d.ts +53 -0
- package/dist/construction.js +80 -0
- package/dist/construction.js.map +1 -0
- package/dist/critique.d.ts +44 -0
- package/dist/critique.js +45 -0
- package/dist/critique.js.map +1 -0
- package/dist/detail.d.ts +5 -0
- package/dist/detail.js +52 -0
- package/dist/detail.js.map +1 -0
- package/dist/document.d.ts +64 -0
- package/dist/document.js +56 -0
- package/dist/document.js.map +1 -0
- package/dist/export.d.ts +405 -0
- package/dist/export.js +344 -0
- package/dist/export.js.map +1 -0
- package/dist/font-inspection.d.ts +8 -0
- package/dist/font-inspection.js +34 -0
- package/dist/font-inspection.js.map +1 -0
- package/dist/graphics.d.ts +9 -0
- package/dist/graphics.js +72 -0
- package/dist/graphics.js.map +1 -0
- package/dist/history-storage.d.ts +10 -0
- package/dist/history-storage.js +59 -0
- package/dist/history-storage.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.d.ts +18 -0
- package/dist/layout.js +155 -0
- package/dist/layout.js.map +1 -0
- package/dist/loader.d.ts +9 -0
- package/dist/loader.js +108 -0
- package/dist/loader.js.map +1 -0
- package/dist/mcp.d.ts +4 -0
- package/dist/mcp.js +223 -0
- package/dist/mcp.js.map +1 -0
- package/dist/merge.d.ts +6 -0
- package/dist/merge.js +49 -0
- package/dist/merge.js.map +1 -0
- package/dist/native.d.ts +3 -0
- package/dist/native.js +6 -0
- package/dist/native.js.map +1 -0
- package/dist/paint.d.ts +9 -0
- package/dist/paint.js +331 -0
- package/dist/paint.js.map +1 -0
- package/dist/path-edit.d.ts +20 -0
- package/dist/path-edit.js +30 -0
- package/dist/path-edit.js.map +1 -0
- package/dist/pdf-output.d.ts +21 -0
- package/dist/pdf-output.js +297 -0
- package/dist/pdf-output.js.map +1 -0
- package/dist/pipeline.d.ts +39 -0
- package/dist/pipeline.js +227 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/print-scene.d.ts +490 -0
- package/dist/print-scene.js +55 -0
- package/dist/print-scene.js.map +1 -0
- package/dist/production-workflow.d.ts +251 -0
- package/dist/production-workflow.js +335 -0
- package/dist/production-workflow.js.map +1 -0
- package/dist/program-worker.d.ts +1 -0
- package/dist/program-worker.js +31 -0
- package/dist/program-worker.js.map +1 -0
- package/dist/program.d.ts +85 -0
- package/dist/program.js +246 -0
- package/dist/program.js.map +1 -0
- package/dist/project-config.d.ts +91 -0
- package/dist/project-config.js +187 -0
- package/dist/project-config.js.map +1 -0
- package/dist/project.d.ts +897 -0
- package/dist/project.js +347 -0
- package/dist/project.js.map +1 -0
- package/dist/raster-edit.d.ts +61 -0
- package/dist/raster-edit.js +91 -0
- package/dist/raster-edit.js.map +1 -0
- package/dist/raster-studio.d.ts +84 -0
- package/dist/raster-studio.js +236 -0
- package/dist/raster-studio.js.map +1 -0
- package/dist/render.d.ts +79 -0
- package/dist/render.js +437 -0
- package/dist/render.js.map +1 -0
- package/dist/rich-text.d.ts +10 -0
- package/dist/rich-text.js +56 -0
- package/dist/rich-text.js.map +1 -0
- package/dist/schema.d.ts +1912 -0
- package/dist/schema.js +571 -0
- package/dist/schema.js.map +1 -0
- package/dist/spatial.d.ts +10 -0
- package/dist/spatial.js +29 -0
- package/dist/spatial.js.map +1 -0
- package/dist/studio-reference.d.ts +153 -0
- package/dist/studio-reference.js +39 -0
- package/dist/studio-reference.js.map +1 -0
- package/dist/svg.d.ts +5 -0
- package/dist/svg.js +315 -0
- package/dist/svg.js.map +1 -0
- package/dist/techniques.d.ts +74 -0
- package/dist/techniques.js +164 -0
- package/dist/techniques.js.map +1 -0
- package/dist/verify.d.ts +36 -0
- package/dist/verify.js +277 -0
- package/dist/verify.js.map +1 -0
- package/dist/viewport.d.ts +3 -0
- package/dist/viewport.js +71 -0
- package/dist/viewport.js.map +1 -0
- package/dist/workflow.d.ts +53 -0
- package/dist/workflow.js +66 -0
- package/dist/workflow.js.map +1 -0
- package/docs/agent-art-workflow.md +201 -0
- package/docs/agent-setup.md +83 -0
- package/docs/atelier.md +117 -0
- package/docs/cli-reference.md +61 -0
- package/docs/decisions/001-runtime-and-renderer.md +35 -0
- package/docs/decisions/002-composable-scenes-and-history.md +28 -0
- package/docs/decisions/003-editing-refinement-and-agent-validation.md +45 -0
- package/docs/decisions/004-print-production-and-projects.md +19 -0
- package/docs/decisions/005-programmable-digital-art.md +15 -0
- package/docs/decisions/006-staged-2d-art-production.md +13 -0
- package/docs/decisions/007-foundation-first-art-direction.md +13 -0
- package/docs/decisions/008-agent-onboarding-and-trial-lessons.md +48 -0
- package/docs/engine-overview.md +174 -0
- package/docs/evolution.md +179 -0
- package/docs/getting-started.md +107 -0
- package/docs/next-milestone.md +61 -0
- package/docs/previews/a3-production.json +36 -0
- package/docs/previews/benchmark.json +42 -0
- package/docs/previews/landscape.png +0 -0
- package/docs/previews/performance.json +24 -0
- package/docs/previews/poster.png +0 -0
- package/docs/production.md +107 -0
- package/docs/releasing.md +60 -0
- package/docs/scene-format.md +126 -0
- package/docs/studio.md +108 -0
- package/examples/hello/README.md +14 -0
- package/examples/hello/refine.json +10 -0
- package/examples/hello/render.mjs +9 -0
- package/examples/hello/scene.json +19 -0
- package/licenses/DM-Serif-Display-OFL.txt +93 -0
- package/licenses/Inter-OFL.txt +93 -0
- package/package.json +84 -0
- package/schemas/authoring.schema.json +2177 -0
- package/schemas/brief.schema.json +57 -0
- package/schemas/command.schema.json +3154 -0
- package/schemas/construction.schema.json +159 -0
- package/schemas/critique.schema.json +101 -0
- package/schemas/document.schema.json +41 -0
- package/schemas/export.schema.json +89 -0
- package/schemas/fragment.schema.json +1861 -0
- package/schemas/patch.schema.json +3177 -0
- package/schemas/pipeline.schema.json +205 -0
- package/schemas/production.schema.json +452 -0
- package/schemas/program.schema.json +152 -0
- package/schemas/project.schema.json +115 -0
- package/schemas/raster-read.schema.json +42 -0
- package/schemas/raster-write.schema.json +75 -0
- package/schemas/scene.schema.json +2014 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type VisualCritic, type VisualCritique } from './critique.js';
|
|
2
|
+
import type { Patch } from './commands.js';
|
|
3
|
+
import { Project } from './project.js';
|
|
4
|
+
import type { RenderResult } from './render.js';
|
|
5
|
+
import type { Scene } from './schema.js';
|
|
6
|
+
import { type VerificationReport } from './verify.js';
|
|
7
|
+
export interface Observation {
|
|
8
|
+
iteration: number;
|
|
9
|
+
scene: Scene;
|
|
10
|
+
render: RenderResult;
|
|
11
|
+
verification: VerificationReport;
|
|
12
|
+
critique?: VisualCritique;
|
|
13
|
+
}
|
|
14
|
+
export type EditingAgent = (observation: Observation) => Promise<Patch | null>;
|
|
15
|
+
export interface IterationOptions {
|
|
16
|
+
maxIterations?: number;
|
|
17
|
+
maxStalled?: number;
|
|
18
|
+
minimumImprovement?: number;
|
|
19
|
+
stopOnPass?: boolean;
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
critic?: VisualCritic;
|
|
22
|
+
requireCritique?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** The agent is injected. This module contains no model credentials or graphics algorithms. */
|
|
25
|
+
export declare function runIterations(project: Project, agent: EditingAgent, options?: IterationOptions): Promise<{
|
|
26
|
+
reason: string;
|
|
27
|
+
iterations: number;
|
|
28
|
+
observations: {
|
|
29
|
+
iteration: number;
|
|
30
|
+
score: number;
|
|
31
|
+
status: string;
|
|
32
|
+
scene_hash: string;
|
|
33
|
+
}[];
|
|
34
|
+
render: RenderResult;
|
|
35
|
+
verification: VerificationReport;
|
|
36
|
+
critique: {
|
|
37
|
+
scene_hash: string;
|
|
38
|
+
png_hash: string;
|
|
39
|
+
reviewer: string;
|
|
40
|
+
method: "human" | "vision-agent";
|
|
41
|
+
summary: string;
|
|
42
|
+
score: number;
|
|
43
|
+
issues: {
|
|
44
|
+
id: string;
|
|
45
|
+
category: "coherence" | "composition" | "lighting" | "semantic" | "texture" | "typography";
|
|
46
|
+
severity: "high" | "low" | "medium";
|
|
47
|
+
target?: string | undefined;
|
|
48
|
+
region?: [number, number, number, number] | undefined;
|
|
49
|
+
message: string;
|
|
50
|
+
suggestion?: string | undefined;
|
|
51
|
+
}[];
|
|
52
|
+
} | null;
|
|
53
|
+
}>;
|
package/dist/workflow.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { validateCritique } from './critique.js';
|
|
2
|
+
import { verifyRendered } from './verify.js';
|
|
3
|
+
/** The agent is injected. This module contains no model credentials or graphics algorithms. */
|
|
4
|
+
export async function runIterations(project, agent, options = {}) {
|
|
5
|
+
const max = options.maxIterations ?? 6, stallLimit = options.maxStalled ?? 2, threshold = options.minimumImprovement ?? 0.01;
|
|
6
|
+
if (!Number.isInteger(max) || max < 0 || max > 100)
|
|
7
|
+
throw new Error('maxIterations must be an integer between 0 and 100');
|
|
8
|
+
if (!Number.isInteger(stallLimit) ||
|
|
9
|
+
stallLimit < 1 ||
|
|
10
|
+
!Number.isFinite(threshold) ||
|
|
11
|
+
threshold < 0)
|
|
12
|
+
throw new Error('Invalid stopping criteria');
|
|
13
|
+
const observations = [];
|
|
14
|
+
let stalled = 0, previous = -1;
|
|
15
|
+
for (let iteration = 0; iteration <= max; iteration++) {
|
|
16
|
+
options.signal?.throwIfAborted();
|
|
17
|
+
const scene = await project.scene(), render = await project.renderer.render(scene, project.root), verification = await verifyRendered(scene, project.root, project.renderer, render);
|
|
18
|
+
const critique = options.critic
|
|
19
|
+
? validateCritique(await options.critic({ scene, render, verification, signal: options.signal }), scene, render)
|
|
20
|
+
: await project.critique();
|
|
21
|
+
if (critique)
|
|
22
|
+
await project.recordCritique(critique);
|
|
23
|
+
observations.push({
|
|
24
|
+
iteration,
|
|
25
|
+
score: verification.score,
|
|
26
|
+
status: verification.status,
|
|
27
|
+
scene_hash: render.evidence.scene.hash,
|
|
28
|
+
});
|
|
29
|
+
const qualityScore = critique ? (verification.score + critique.score) / 2 : verification.score;
|
|
30
|
+
const result = (reason) => ({
|
|
31
|
+
reason,
|
|
32
|
+
iterations: iteration,
|
|
33
|
+
observations,
|
|
34
|
+
render,
|
|
35
|
+
verification,
|
|
36
|
+
critique,
|
|
37
|
+
});
|
|
38
|
+
if ((options.stopOnPass ?? true) &&
|
|
39
|
+
verification.status === 'pass' &&
|
|
40
|
+
(!options.requireCritique || !!critique) &&
|
|
41
|
+
(!critique || !critique.issues.some((i) => i.severity === 'high' || i.severity === 'medium')))
|
|
42
|
+
return result('passed');
|
|
43
|
+
if (iteration === max)
|
|
44
|
+
return result('iteration-budget');
|
|
45
|
+
if (previous >= 0 && qualityScore - previous < threshold)
|
|
46
|
+
stalled++;
|
|
47
|
+
else
|
|
48
|
+
stalled = 0;
|
|
49
|
+
if (stalled >= stallLimit)
|
|
50
|
+
return result('stalled');
|
|
51
|
+
previous = qualityScore;
|
|
52
|
+
const patch = await agent({
|
|
53
|
+
iteration,
|
|
54
|
+
scene,
|
|
55
|
+
render,
|
|
56
|
+
verification,
|
|
57
|
+
critique: critique ?? undefined,
|
|
58
|
+
});
|
|
59
|
+
options.signal?.throwIfAborted();
|
|
60
|
+
if (!patch)
|
|
61
|
+
return result('agent-finished');
|
|
62
|
+
await project.apply({ ...patch, expected_hash: render.evidence.scene.hash });
|
|
63
|
+
}
|
|
64
|
+
throw new Error('Unreachable iteration state');
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Art direction for agents
|
|
2
|
+
|
|
3
|
+
Read this before creating illustration, painting or procedural assets. The versioned
|
|
4
|
+
protocol is returned by `graphics art-guide`, included in `graphics studio-help`
|
|
5
|
+
and MCP `studioHelp`, and exported as `artDirectionGuide` by the SDK.
|
|
6
|
+
|
|
7
|
+
MCP connections receive the core rules in the server's initialization
|
|
8
|
+
`instructions`. The full guide is also a discoverable JSON resource at
|
|
9
|
+
`rtistree://guides/art-direction`. Authoring tool descriptions point agents to it.
|
|
10
|
+
All of these surfaces share `src/art-direction.ts`; consumers do not need access
|
|
11
|
+
to this repository or its example files. SDK hosts should put the exported
|
|
12
|
+
`rtistreeAgentInstructions` in their agent context and expose the full guide.
|
|
13
|
+
CLI hosts should read `graphics art-guide` before authoring. A client decides how
|
|
14
|
+
to present instructions to its model; shipping guidance cannot force every client
|
|
15
|
+
or agent to read it, follow it, or exercise good visual judgment.
|
|
16
|
+
|
|
17
|
+
This is a repeatable process for detecting and correcting failures. It cannot guarantee better art on every attempt. The agent must be capable of drawing, observing and revising; the software cannot certify taste, anatomical understanding or the truth of a review.
|
|
18
|
+
|
|
19
|
+
## Establish the standard before producing detail
|
|
20
|
+
|
|
21
|
+
Write the brief, intended medium, audience and quality expectation in plain language. Separate **prompt compliance** from **artistic success**. A recognisable dragon may still have poor construction; a technically valid PDF may still have poor composition.
|
|
22
|
+
|
|
23
|
+
Study relevant references. Record each source, an actual observation and how it changes the drawing. Open images before making visual claims; search-result descriptions are not visual inspection. Use references for structure, gesture, lighting and quality calibration. Do not substitute tracing, imported pixels or image-generation output when the brief prohibits them. Distinguish real anatomy from invented anatomy.
|
|
24
|
+
|
|
25
|
+
For an unfamiliar subject, include both a structural reference and an example of the intended quality. A diagram can explain a joint without demonstrating good composition or expressive drawing. Sources may be URLs or project-local notes; source claims are recorded, not automatically verified by Rtistree.
|
|
26
|
+
|
|
27
|
+
## Follow the dependency of artistic decisions
|
|
28
|
+
|
|
29
|
+
For an asset family, begin with a representative sample: one character and one
|
|
30
|
+
prop that exercise the difficult construction. Establish their quality before
|
|
31
|
+
multiplying variants. The guide's `starter_plan` is a valid production plan
|
|
32
|
+
template with exploration, sample review and family review stages. Replace its
|
|
33
|
+
brief and adapt criteria before submitting it to `production`. Reference studies
|
|
34
|
+
can be supplied with the plan or appended through `study`. The template uses
|
|
35
|
+
the existing gates; it does not create an automatic visual critic.
|
|
36
|
+
|
|
37
|
+
1. **Gesture and composition.** Produce at least three substantially different proposals. Change action, balance, overlap and negative space. Scaling or translating the same drawing does not explore a new pose.
|
|
38
|
+
2. **Silhouette.** Inspect the subject at thumbnail size. Identify the focal contour, negative spaces and accidental mergers. A head merging into a wing is a drawing failure even if shading might reveal it later.
|
|
39
|
+
3. **Construction.** Name landmarks and connect them through guide curves. Establish coherent mass, joints, perspective and overlap. Attach contours to shared landmarks so corrections propagate. In a creature, distinguish the skeleton, muscle masses and surface; in lettering, establish stroke proportions and spacing; in a product illustration, establish axes, proportions and perspective.
|
|
40
|
+
4. **Values.** Use a plain background and grayscale. Group large light and shadow masses under a stated light direction. Inspect at full size and thumbnail size, then mirror the view. Examine both structure and rendering artifacts. Smooth gradients can expose form, but a set of shaded tubes is not automatically convincing anatomy.
|
|
41
|
+
5. **Targeted revision.** Name the defect, predict a correction and capture the parent. Make the structural edit, capture the revision, then compare the actual images. Record improved, unchanged or worse, with visible evidence. A local fix is not proof that the whole drawing is good.
|
|
42
|
+
6. **Foundation checkpoint.** Keep all blocking defects active. Seek human or independent review when required by the plan. Do not proceed to colour, textures, scenery or effects while construction remains inadequate.
|
|
43
|
+
7. **Materials and finish.** Only after the foundation passes, develop surface, edge hierarchy and detail. Recheck the earlier decisions after significant edits. Complexity, brush count and time spent are not quality metrics.
|
|
44
|
+
|
|
45
|
+
If two structural revisions do not improve the drawing, revisit the construction model or the pose. Further detail is unlikely to rescue it. If there are local improvements but the overall result is still weak, say so explicitly and retain the failed gate.
|
|
46
|
+
|
|
47
|
+
## Subject-specific checks learned from the asset trial
|
|
48
|
+
|
|
49
|
+
**Figures:** name and trace each shoulder–elbow–wrist and hip–knee–ankle chain,
|
|
50
|
+
including hidden portions. State which hand holds each object. In the Verdigris
|
|
51
|
+
Watch trial, the sword elbow crossed the torso beneath the shield arm. Moving
|
|
52
|
+
the elbow outside and above the body fixed that relationship. A valid landmark
|
|
53
|
+
graph can encode a bad pose; inspect balance, joint angles and negative spaces.
|
|
54
|
+
Helmet dome, eye slit, visor and jaw must read as connected forms.
|
|
55
|
+
|
|
56
|
+
**Props:** use one shared perspective grid for the body, lid, planks and fittings.
|
|
57
|
+
The first chest used unrelated angles. A reconstruction also briefly showed the
|
|
58
|
+
hidden backs of its hoops over the near lid, where they looked like handles.
|
|
59
|
+
Both shared geometry and correct occlusion matter. Distinct shaded faces and a
|
|
60
|
+
common palette are insufficient evidence of sound construction.
|
|
61
|
+
|
|
62
|
+
**Animation:** declare facing, travel direction, ground plane, stride distance,
|
|
63
|
+
cycle duration and contact/recovery phases. Play a full loop against ground
|
|
64
|
+
markers and inspect contact, passing and recovery frames at the intended size.
|
|
65
|
+
For ordinary forward walking, planted feet move backward relative to the body;
|
|
66
|
+
their relative velocity plus body velocity should approximately cancel in world
|
|
67
|
+
space. Recovering feet move forward while lifted. Check reachability, segment
|
|
68
|
+
lengths, knee flexion, lift, pivots, frame order and the loop boundary. Bind those
|
|
69
|
+
checks to the actual rig source used to draw the frames.
|
|
70
|
+
|
|
71
|
+
The original trial produced eight different PNGs but walked backward. Correcting
|
|
72
|
+
direction still left excessive knee bend, an odd helmet and crossed guard arms.
|
|
73
|
+
The user eventually called revision 4 “much better.” Record that as relative
|
|
74
|
+
improvement, without extrapolating it into approval of every asset. The distilled
|
|
75
|
+
lessons are embedded in the shipped guide; the full trial history lives in
|
|
76
|
+
`examples/warden-asset-trial` in the source repository and is not required by the
|
|
77
|
+
installed package.
|
|
78
|
+
|
|
79
|
+
Report three separate axes: **technical** (valid files and reproducibility),
|
|
80
|
+
**functional** (subject-specific behaviour/geometry), and **visual** (observed
|
|
81
|
+
appearance against the brief). An unobserved image or loop is unreviewed. A user
|
|
82
|
+
rejection supersedes an earlier favourable agent review. Keep failed candidates
|
|
83
|
+
and parent-linked corrections. Technical checks cannot override visual failures.
|
|
84
|
+
|
|
85
|
+
## Enforced gates and their limits
|
|
86
|
+
|
|
87
|
+
Production plans support these stage fields:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"minimum_alternatives": 3,
|
|
92
|
+
"require_references": true,
|
|
93
|
+
"required_reviewer": "human"
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Use minimum alternatives on the exploration stage. Use the human checkpoint when
|
|
98
|
+
the user or agreed plan requires human acceptance; do not invent an approval
|
|
99
|
+
requirement for every task. Set concrete `criteria` and appropriate numerical
|
|
100
|
+
thresholds as well. Do not lower thresholds after seeing a weak result merely to advance.
|
|
101
|
+
|
|
102
|
+
- `minimum_alternatives` counts initial candidates with distinct PNG hashes. Revisions do not count as independent alternatives. The software can verify pixel differences; the reviewer must verify meaningful compositional differences.
|
|
103
|
+
- `require_references` requires a reference log. The software does not know whether the agent actually studied it.
|
|
104
|
+
- `required_reviewer: "human"` prevents a review declared as `vision-agent` from approving the stage. Reviewer identities and methods are declarations in a trusted local project, not authenticated identities. An agent must never mark its own opinion as human feedback.
|
|
105
|
+
- Blocking review issues prevent selection and advancement regardless of high overall scores. A criterion cannot simultaneously pass and have a blocking issue.
|
|
106
|
+
- Revision reviews must compare against the declared parent. A revision judged unchanged or worse cannot be selected.
|
|
107
|
+
- Re-reviewing a candidate appends to `review_history`. Earlier criticism is retained.
|
|
108
|
+
- `status` reports candidate readiness and `compare` reports gate reasons. Existing technical, stale-hash, candidate-restoration and undo checks continue to apply.
|
|
109
|
+
|
|
110
|
+
The engine cannot stop an observer from writing an inaccurate review. These gates expose decisions and prevent common shortcuts; they do not replace artistic judgment. A completed workflow means its declared checks passed, not that excellent art has been objectively established.
|
|
111
|
+
|
|
112
|
+
## Requests an agent should use
|
|
113
|
+
|
|
114
|
+
Reference study can be supplied in the initial plan's `references` array, or appended during work:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"action": "study",
|
|
119
|
+
"session": "creature",
|
|
120
|
+
"reference": {
|
|
121
|
+
"id": "wing-construction",
|
|
122
|
+
"source": "<reference URL or project-local study>",
|
|
123
|
+
"observation": "The elbow precedes the wrist; the long fingers radiate from the wrist.",
|
|
124
|
+
"application": "Move the wrist independently from the shoulder and attach membrane contours to the finger ends."
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Reference IDs are unique. Appending a study does not rewrite criteria or earlier reviews.
|
|
130
|
+
|
|
131
|
+
Capture a revision after making the edit:
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"action": "capture",
|
|
136
|
+
"session": "creature",
|
|
137
|
+
"candidate": "separated-jaw",
|
|
138
|
+
"expected_hash": "<current scene hash>",
|
|
139
|
+
"revision": {
|
|
140
|
+
"parent": "first-values",
|
|
141
|
+
"hypothesis": "Lowering the far wing will open a clear gap beneath the jaw."
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
A review includes the normal candidate hashes, reviewer, method, strengths, weaknesses, scores and complete criterion verdicts. Add explicit issues and a comparison for revisions:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"issues": [
|
|
151
|
+
{
|
|
152
|
+
"criterion": "construction",
|
|
153
|
+
"severity": "blocking",
|
|
154
|
+
"observation": "The wing and foreleg terminate at one unexplained joint.",
|
|
155
|
+
"correction": "Design separate attachments and the intervening torso mass before adding detail."
|
|
156
|
+
}
|
|
157
|
+
],
|
|
158
|
+
"comparison": {
|
|
159
|
+
"parent": "first-values",
|
|
160
|
+
"verdict": "improved",
|
|
161
|
+
"evidence": "The jaw is now separated from the far wing, but the shared shoulder joint is still unresolved."
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The construction criterion must be `pass: false` in this example. A comparison can truthfully say improved while the candidate remains blocked.
|
|
167
|
+
|
|
168
|
+
## Named 2D construction guides
|
|
169
|
+
|
|
170
|
+
```js
|
|
171
|
+
const drawing = art.guides({
|
|
172
|
+
points: {
|
|
173
|
+
shoulder: [200, 300],
|
|
174
|
+
elbow: { anchor: 'shoulder', offset: [-70, -20] },
|
|
175
|
+
wrist: { anchor: 'elbow', offset: [-40, -90] },
|
|
176
|
+
tip: { anchor: 'wrist', offset: [-120, -40] },
|
|
177
|
+
},
|
|
178
|
+
paths: {
|
|
179
|
+
leadingEdge: [
|
|
180
|
+
{ op: 'M', to: 'shoulder' },
|
|
181
|
+
{ op: 'Q', control: 'elbow', to: 'wrist' },
|
|
182
|
+
{ op: 'L', to: 'tip' },
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
ctx.stroke(art.path(drawing.paths.leadingEdge));
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Points can be coordinates, aliases or anchored offsets. Paths support M/L/Q/C/Z segments with shared point references. Moving the shoulder above moves its dependent elbow, wrist and tip. Use absolute points where independent articulation is intended. Cycles, unknown points, invalid coordinates and malformed paths fail validation.
|
|
190
|
+
|
|
191
|
+
This is a general construction graph, not inverse kinematics or anatomical knowledge. It is useful for creatures, botanical forms, lettering, diagrams and other drawings whose contours share control points. Programs still have native Canvas and raw pixels for anything the abstraction cannot express.
|
|
192
|
+
|
|
193
|
+
## The dragon trials are calibration evidence
|
|
194
|
+
|
|
195
|
+
The original oil-style dragon met the requested subject beats and reproduced deterministically, but the user rejected its artistic quality. Its earlier favourable scores were false positives. Do not use that result as a passing quality reference.
|
|
196
|
+
|
|
197
|
+
The follow-up in `examples/dragon-foundation` studies anatomy references, rejects two silhouettes for losing the head in a wing, then makes two structural/value revisions to the remaining pose. It preserves failed reviews and stops at the foundation checkpoint. The image remains a weak construction study; improved separation and reproducibility do not make it excellent art.
|
|
198
|
+
|
|
199
|
+
Read `examples/dragon-foundation/README.md` for the actual observations, limitations and replay evidence. Treat the process as a way to learn from visible failures rather than manufacture a successful score.
|
|
200
|
+
|
|
201
|
+
The narrower experiment in `examples/dragon-head-study` draws a head illuminated by green fire. Replacing regular scale rows with irregular cells and a glowing line with turbulent fire improved those specific defects. The result still falls short in anatomy, light interaction and purposeful painting. A brush treatment over a weak drawing remains a weak drawing. This was a single-composition lighting experiment, not a successful run of the full foundation protocol; its assessment keeps the artistic failures explicit.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Connect an agent
|
|
2
|
+
|
|
3
|
+
Rtistree provides a CLI, an MCP server and a TypeScript SDK. The engine renders locally;
|
|
4
|
+
your host supplies the model and any vision capability.
|
|
5
|
+
|
|
6
|
+
## MCP over stdio
|
|
7
|
+
|
|
8
|
+
Install Rtistree in a project and create a scene using the [quickstart](getting-started.md).
|
|
9
|
+
Use this configuration shape in an MCP client that accepts `mcpServers`:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"mcpServers": {
|
|
14
|
+
"rtistree": {
|
|
15
|
+
"command": "node",
|
|
16
|
+
"args": [
|
|
17
|
+
"/absolute/path/to/my-art/node_modules/rtistree/dist/cli.js",
|
|
18
|
+
"serve",
|
|
19
|
+
"/absolute/path/to/my-art/scene.json"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Replace both paths with real absolute paths. Use an absolute path to your Node executable
|
|
27
|
+
if the host does not inherit your terminal's PATH. Configuration location and field wrappers
|
|
28
|
+
vary by client; the underlying command is always `node <cli.js> serve <scene>`.
|
|
29
|
+
The server writes protocol messages only to stdout.
|
|
30
|
+
|
|
31
|
+
On connection, the client receives concise art-direction instructions. The full versioned
|
|
32
|
+
guide is available as the `rtistree://guides/art-direction` resource and through `studioHelp`.
|
|
33
|
+
Some clients do not automatically expose server instructions or resources to the model;
|
|
34
|
+
in that case, explicitly tell the agent to call `studioHelp` first.
|
|
35
|
+
|
|
36
|
+
Example task:
|
|
37
|
+
|
|
38
|
+
> Read Rtistree's art-direction guide, inspect this project and render it. Create one
|
|
39
|
+
> representative asset before expanding the family. Compare its silhouette and grayscale
|
|
40
|
+
> values, inspect it at the intended display size, and record technical, functional and
|
|
41
|
+
> visual findings separately. Revise failed criteria before exporting.
|
|
42
|
+
|
|
43
|
+
The server exposes inspection, rendering, crop inspection, typed edits, undo/redo, verification,
|
|
44
|
+
critiques, program execution, pipelines and staged production. Rendering tools return PNG image
|
|
45
|
+
content; use a vision-capable agent to judge appearance. Structured inspection alone cannot
|
|
46
|
+
establish that an image looks good.
|
|
47
|
+
|
|
48
|
+
## CLI agents
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npx graphics art-guide
|
|
52
|
+
npx graphics inspect scene.json
|
|
53
|
+
npx graphics render scene.json -o review.png
|
|
54
|
+
npx graphics studio-help
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Read the JSON guide, open the rendered image, then choose a focused edit. Do not substitute a
|
|
58
|
+
successful `verify` result for visual review. CLI command details are in the [reference](cli-reference.md).
|
|
59
|
+
|
|
60
|
+
## SDK hosts
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import { rtistreeAgentInstructions, artDirectionGuide, Project } from 'rtistree';
|
|
64
|
+
|
|
65
|
+
const project = await Project.open('./scene.json');
|
|
66
|
+
const image = await project.render();
|
|
67
|
+
// Include rtistreeAgentInstructions in your host's agent instructions.
|
|
68
|
+
// Expose artDirectionGuide and image.png to the agent through your host's tools.
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
These exports contain guidance; importing them does not automatically insert anything into
|
|
72
|
+
an external agent's context. The host must perform that integration. The renderer has no
|
|
73
|
+
built-in model client, API key handling or automatic visual critic.
|
|
74
|
+
|
|
75
|
+
## Trust and review
|
|
76
|
+
|
|
77
|
+
Run only painting programs and recipes you trust. The JavaScript VM is not a security sandbox.
|
|
78
|
+
Normal rendering does not execute recipes. Keep an agent's access scoped to the intended
|
|
79
|
+
project, and inspect its proposed changes and outputs as appropriate to your workflow.
|
|
80
|
+
|
|
81
|
+
The [art-direction workflow](agent-art-workflow.md) documents sample selection, connected
|
|
82
|
+
construction, ground contact and existing production review gates. It makes lessons available;
|
|
83
|
+
it does not guarantee model compliance or artistic quality.
|
package/docs/atelier.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Producing art in stages
|
|
2
|
+
|
|
3
|
+
Start with [Art direction for agents](agent-art-workflow.md): reference study, distinct silhouettes, construction, grayscale values and targeted revision. Its protocol is included in CLI/MCP `studioHelp`.
|
|
4
|
+
|
|
5
|
+
Rtistree provides the tools and records; a human or agent still makes visual decisions. No image-generation service or 3D renderer is required. Start with `graphics studio-help` for the synchronous painting API and technique catalogue.
|
|
6
|
+
|
|
7
|
+
## Working sequence
|
|
8
|
+
|
|
9
|
+
1. Describe the brief and create a production plan. Set stage-specific criteria before making candidates: composition at thumbnail size; value masses at block-in; anatomy and lighting at form; directional paint and depth at materials; focal hierarchy and consistency at finishing. Do not demand finished texture from thumbnails.
|
|
10
|
+
2. Author separate painting programs and an editable pipeline JSON. Generate two or three inexpensive compositions by reducing node dimensions. Auto-created raster layers fill the scene canvas, so small assets can serve as previews.
|
|
11
|
+
3. Build explicitly, capture each candidate and compare their images. Open the returned PNG and relevant detail crops. Record what you actually see against every criterion.
|
|
12
|
+
4. Select an eligible candidate. Selection restores its layers, assets and frozen inline pipeline, and can be undone. A candidate cannot replace an incumbent with a lower fidelity or quality rating. Unreviewed candidates and technical failures cannot be selected.
|
|
13
|
+
5. Advance only while the selected scene is still current. Repeat at the next stage and higher resolution. If a criterion fails, make another candidate; do not lower the criterion merely to finish.
|
|
14
|
+
6. Export the selected scene and audit a cold render, portable render and recipe replay. Report remaining aesthetic limitations separately from technical checks.
|
|
15
|
+
|
|
16
|
+
CLI actions also have SDK equivalents (`buildPipeline`, `production`) and MCP tools (`buildPipeline`, `production`). Structured errors stop the operation. Normal rendering reads baked images and never runs program code.
|
|
17
|
+
|
|
18
|
+
## Editable dependency graph
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"version": 1,
|
|
23
|
+
"id": "painting",
|
|
24
|
+
"shared": { "warmth": 0.4 },
|
|
25
|
+
"nodes": [
|
|
26
|
+
{
|
|
27
|
+
"id": "ground",
|
|
28
|
+
"target": "ground",
|
|
29
|
+
"source": "programs/ground.js",
|
|
30
|
+
"width": 1200,
|
|
31
|
+
"height": 800,
|
|
32
|
+
"bindings": { "warmth": "warmth" },
|
|
33
|
+
"seed": 42
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "glaze",
|
|
37
|
+
"target": "glaze",
|
|
38
|
+
"code": "const c=art.input('base'); art.techniques.glaze(c,'#a88152',0.08); return c;",
|
|
39
|
+
"width": 1200,
|
|
40
|
+
"height": 800,
|
|
41
|
+
"inputs": { "base": { "node": "ground" } }
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`graphics pipeline my-project pipeline.json` reports `built` or `cached` for each node. An input can instead use `{ "asset": "registered-asset-id" }`. Source and inline code are mutually exclusive. Only subscribed shared parameters enter a node's key. Per-node parameters override nothing implicitly: an explicit binding takes precedence over a parameter of the same name. A changed node whose PNG is identical need not rebuild its dependants. Node array order defines auto-created layer order; dependency order defines execution order. Existing layer geometry is preserved. Changing output resolution changes cache keys. Removing a node does not remove previously authored layers or assets; use normal scene commands for removal.
|
|
48
|
+
|
|
49
|
+
All node artifacts are baked before one scene transaction. A failed build can leave unused immutable files in the cache, but never a partially updated scene. Identical builds add no history. Use `expected_hash` with the SDK/MCP to reject a scene changed since inspection.
|
|
50
|
+
|
|
51
|
+
The exact executed graph, including inline source, is stored under `scene.metadata.pipeline_<id>`. After restoring a candidate, use that graph to resume its settings; a working `pipeline.json` file is deliberately not overwritten by selection. Portable export includes the selected graph and registered input assets, so it can rebuild without the original source files.
|
|
52
|
+
|
|
53
|
+
## Production requests
|
|
54
|
+
|
|
55
|
+
Create a plan with `graphics production my-project plan.json`:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"action": "plan",
|
|
60
|
+
"plan": {
|
|
61
|
+
"id": "landscape",
|
|
62
|
+
"brief": "A quiet mountain valley at dawn",
|
|
63
|
+
"stages": [
|
|
64
|
+
{
|
|
65
|
+
"id": "thumbnails",
|
|
66
|
+
"goal": "Choose the value composition",
|
|
67
|
+
"minimum_fidelity": 0.7,
|
|
68
|
+
"minimum_quality": 0.7,
|
|
69
|
+
"criteria": [
|
|
70
|
+
{ "id": "depth", "description": "Three distance planes read at thumbnail size" }
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Use `{ "action": "capture", "session": "landscape", "candidate": "warm-dawn", "expected_hash": "<current scene hash>", "crops": [[100,100,200,150]] }`. The result includes a directory containing the image, thumbnail, scene and requested `detail-N.png` files. Candidate IDs cannot be overwritten. Capture supports up to 8 integer canvas-space crops. Session capacity is 64 candidates.
|
|
79
|
+
|
|
80
|
+
Use `compare` with the session ID for a labelled contact sheet and ranked reviews. Ranking is eligibility first, then artistic quality, then brief fidelity; it never blends technical and visual scores.
|
|
81
|
+
|
|
82
|
+
A `review` request includes session and a review object with `candidate`, exact `scene_hash` and `png_hash` from capture, `reviewer`, `method` (`human` or `vision-agent`), `fidelity` and `quality` in 0–1, `strengths`, `weaknesses`, and `criteria: [{id, pass, evidence}]`. Every criterion must be covered exactly once. These fields must be authored after visual inspection; Rtistree does not provide an automatic critic.
|
|
83
|
+
|
|
84
|
+
Use `select` with session, candidate and current `expected_hash`, then `advance` with session and the resulting scene hash. The final advance marks the session complete. `status` returns the plan, stage, candidates and selections. Session metadata writes are locked; scene writes use the existing journal lock and stale-scene guard. A failure writing session metadata after selection may require repeating selection; the scene transaction remains undoable.
|
|
85
|
+
|
|
86
|
+
JSON schemas: `schemas/pipeline.schema.json` and `schemas/production.schema.json`.
|
|
87
|
+
|
|
88
|
+
## Painting techniques and escape hatches
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
const canvas = art.canvas();
|
|
92
|
+
const ctx = canvas.getContext('2d');
|
|
93
|
+
ctx.fillStyle = '#263e45';
|
|
94
|
+
ctx.fillRect(0, 0, art.width, art.height);
|
|
95
|
+
ctx.save();
|
|
96
|
+
ctx.clip(art.path('M20 180 Q160 30 300 180 L300 230 L20 230Z'));
|
|
97
|
+
art.techniques.stroke(
|
|
98
|
+
canvas,
|
|
99
|
+
[
|
|
100
|
+
{ x: 30, y: 170, pressure: 0.3 },
|
|
101
|
+
{ x: 130, y: 120, pressure: 1 },
|
|
102
|
+
{ x: 260, y: 170, pressure: 0.2 },
|
|
103
|
+
],
|
|
104
|
+
{ preset: 'oil', size: 24, colour: '#c7b685', dryness: 0.25, opacity: 0.6 },
|
|
105
|
+
);
|
|
106
|
+
art.techniques.glaze(canvas, '#b69357', 0.08);
|
|
107
|
+
ctx.restore();
|
|
108
|
+
return canvas;
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`oil`, `filbert`, `scumble` and `ink` presets expose size, bristle count, variation, opacity, dryness and taper. Pressure controls width; overlapping strands accumulate paint. Presets are starting settings, not complete art styles. All methods respect current clipping and transforms, preserve context state and use the seeded RNG. Keep the runtime and technique version pinned for replay.
|
|
112
|
+
|
|
113
|
+
`art.techniques.mix` interpolates sRGB palette colours. `atmosphere` is the same operation applied toward a haze colour; it does not establish perspective for you. `weave` overlays sparse crossed lines; it should remain subordinate to form. See `examples/technique-study` for an executable swatch sheet.
|
|
114
|
+
|
|
115
|
+
For anything these helpers cannot express, use `canvas.getContext('2d')`, `art.path(svgPathData)`, pixel buffers, coordinate warps, custom masks and explicit raster edits. No new abstraction is required to paint a new subject.
|
|
116
|
+
|
|
117
|
+
The user rejected the artistic quality of the first dragon trial. The follow-up in `examples/dragon-foundation` retains failed reviews and stops before decoration. The original trial in `examples/dragon-oil-trial` records three composition candidates, successive stage reviews, editable source and a reproducibility audit. It is one stylized painting trial, not evidence of universal artistic excellence.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# CLI reference
|
|
2
|
+
|
|
3
|
+
Installing Rtistree exposes `graphics`. In a local npm project, use `npx graphics`.
|
|
4
|
+
Run `graphics --help` for the complete installed-version reference. Structured results go to
|
|
5
|
+
stdout as JSON; errors go to stderr. Verification failure exits 2; other errors exit 1.
|
|
6
|
+
|
|
7
|
+
## Inspect and edit
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
graphics inspect scene.json
|
|
11
|
+
graphics inspect scene.json --layer title
|
|
12
|
+
graphics inspect-region scene.json 0 0 100 100
|
|
13
|
+
graphics render scene.json -o image.png
|
|
14
|
+
graphics render-region scene.json 0 0 100 100 -o crop.png
|
|
15
|
+
graphics apply scene.json patch.json
|
|
16
|
+
graphics undo scene.json
|
|
17
|
+
graphics redo scene.json
|
|
18
|
+
graphics history scene.json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Coordinates are `x y width height` in canvas pixels. A patch contains a reason and a typed
|
|
22
|
+
commands array. Supply the current `expected_hash` when coordinating concurrent edits.
|
|
23
|
+
See [scene format](scene-format.md) for command shapes and coordinate rules.
|
|
24
|
+
|
|
25
|
+
## Verify, review and export
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
graphics verify scene.json -o report.json --heatmap heatmap.png
|
|
29
|
+
graphics critique scene.json critique.json
|
|
30
|
+
graphics export scene.json -o portable/scene.json
|
|
31
|
+
graphics export scene.json --format png -o image.png
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Verification measures configured technical constraints. Critiques are authored after inspecting
|
|
35
|
+
images and bound to the current scene. Exports for physical documents and printer profiles are
|
|
36
|
+
described in [print production](production.md).
|
|
37
|
+
|
|
38
|
+
## Studio and production
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
graphics art-guide
|
|
42
|
+
graphics studio-help
|
|
43
|
+
graphics program scene.json program.json
|
|
44
|
+
graphics program-replay scene.json asset-id
|
|
45
|
+
graphics pipeline scene.json pipeline.json
|
|
46
|
+
graphics production scene.json request.json
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Read [studio](studio.md) for program requests and [staged production](atelier.md) for plans,
|
|
50
|
+
candidate captures, reviews and selection. Program execution is for trusted code only.
|
|
51
|
+
|
|
52
|
+
## Project creation and integration
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
graphics project new artwork --size A3 --orientation landscape --ppi 300 --bleed 3mm
|
|
56
|
+
graphics schema --kind scene
|
|
57
|
+
graphics schema --kind command
|
|
58
|
+
graphics serve /absolute/path/to/scene.json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The MCP server uses stdio. See [agent setup](agent-setup.md).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# ADR 001: TypeScript control plane and native CPU Skia renderer
|
|
2
|
+
|
|
3
|
+
Status: accepted for the MVP. Later extensions and superseded limitations are documented in [ADR 003](003-editing-refinement-and-agent-validation.md).
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
The architecture proposal suggests TypeScript and a Canvas-style renderer. This is not a requirement. The implementation needs reproducible text, paths, assets, masks, compositing, raster operations, and an ergonomic agent interface. It does not need a browser, interactive GUI, or GPU. The user explicitly authorized choosing any suitable language and ecosystem.
|
|
8
|
+
|
|
9
|
+
## Decision
|
|
10
|
+
|
|
11
|
+
Use TypeScript on Node.js 22+, with native Skia supplied by `@napi-rs/canvas`. Use Zod for runtime validation and typed commands, YAML/JSON for authoring, and the official MCP TypeScript SDK for stdio agent tools. Keep renderer, verifier, and agent decisions separate. Use ordinary modules in one package, rather than prematurely publishing a monorepo of packages.
|
|
12
|
+
|
|
13
|
+
TypeScript serves the structured data and agent-facing control plane. CPU Skia supplies the expensive graphics primitives in native code. Pixel adjustments currently use typed arrays in TypeScript; that is the first candidate for profiling-driven native optimization.
|
|
14
|
+
|
|
15
|
+
This is **not a WebGL implementation**. There is no browser, DOM, canvas element, GPU driver requirement, or browser automation in the rendering path. The native package offers a familiar Canvas 2D API, which is an API shape rather than a browser dependency.
|
|
16
|
+
|
|
17
|
+
## Alternatives considered
|
|
18
|
+
|
|
19
|
+
| Alternative | Strength | Reason not selected initially |
|
|
20
|
+
| --------------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
21
|
+
| Python + Pillow/Cairo | Mature image analysis and raster tooling | More integration work to unify paths, font layout, compositing and the chosen typed command surface; remains reasonable for verification extensions. |
|
|
22
|
+
| Rust + Skia/tiny-skia | Tight memory control and efficient pixels | Larger build/distribution surface before proving the agent representation. A native raster kernel can be added behind the same API. |
|
|
23
|
+
| Browser Canvas/WebGL/WebGPU | Interactive previews and GPU throughput | Browser/driver variation and setup add complexity to a CPU-first, headless engine. |
|
|
24
|
+
| SVG + rasterization | Excellent vector composition | Local raster editing, operation history and tiles still need a separate raster subsystem. |
|
|
25
|
+
|
|
26
|
+
## Consequences
|
|
27
|
+
|
|
28
|
+
- Rendering works locally with prebuilt native binaries, bundled fonts and no service credentials.
|
|
29
|
+
- Same input bytes, package lock, font bytes, renderer version and runtime/platform produce repeatable PNGs. Cross-platform or cross-version byte identity is not claimed.
|
|
30
|
+
- System font loading is disabled by the native adapter. Latin font packages and hashes are explicit dependencies. Applications embedding the SDK should not preload a separate native canvas font registry.
|
|
31
|
+
- Region rendering initially composites the full canvas, then crops exact pixels. Draft is a downsampled full render. These are correctness features, not performance optimizations.
|
|
32
|
+
- Full-canvas layer surfaces trade memory for simple correct composition. A surface budget rejects oversized scenes. Dirty-tile caches and region-aware kernels are later work.
|
|
33
|
+
- An external agent can supply natural-language planning and visual critique through MCP; the engine does not call a particular model provider.
|
|
34
|
+
|
|
35
|
+
References: [native Canvas/Skia binding](https://github.com/Brooooooklyn/canvas), [Zod validation](https://zod.dev/basics), [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk).
|