@cogitato/kit-cli 0.0.0-stage → 0.2.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.
Files changed (76) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +34 -2
  3. package/bin/kit.js +4 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +245 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/doctor.d.ts +23 -0
  8. package/dist/doctor.js +86 -0
  9. package/dist/doctor.js.map +1 -0
  10. package/dist/errors.d.ts +8 -0
  11. package/dist/errors.js +9 -0
  12. package/dist/errors.js.map +1 -0
  13. package/dist/export-flows.d.ts +8 -0
  14. package/dist/export-flows.js +15 -0
  15. package/dist/export-flows.js.map +1 -0
  16. package/dist/flows.d.ts +38 -0
  17. package/dist/flows.js +141 -0
  18. package/dist/flows.js.map +1 -0
  19. package/dist/format.d.ts +3 -0
  20. package/dist/format.js +27 -0
  21. package/dist/format.js.map +1 -0
  22. package/dist/gaps.d.ts +21 -0
  23. package/dist/gaps.js +52 -0
  24. package/dist/gaps.js.map +1 -0
  25. package/dist/hook.d.ts +33 -0
  26. package/dist/hook.js +114 -0
  27. package/dist/hook.js.map +1 -0
  28. package/dist/hosting.d.ts +18 -0
  29. package/dist/hosting.js +51 -0
  30. package/dist/hosting.js.map +1 -0
  31. package/dist/index.d.ts +19 -0
  32. package/dist/index.js +21 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/issue.d.ts +17 -0
  35. package/dist/issue.js +65 -0
  36. package/dist/issue.js.map +1 -0
  37. package/dist/links.d.ts +15 -0
  38. package/dist/links.js +60 -0
  39. package/dist/links.js.map +1 -0
  40. package/dist/preview.d.ts +16 -0
  41. package/dist/preview.js +38 -0
  42. package/dist/preview.js.map +1 -0
  43. package/dist/project.d.ts +55 -0
  44. package/dist/project.js +145 -0
  45. package/dist/project.js.map +1 -0
  46. package/dist/registry.d.ts +67 -0
  47. package/dist/registry.js +227 -0
  48. package/dist/registry.js.map +1 -0
  49. package/dist/rules/css-values.d.ts +31 -0
  50. package/dist/rules/css-values.js +185 -0
  51. package/dist/rules/css-values.js.map +1 -0
  52. package/dist/rules/css.d.ts +4 -0
  53. package/dist/rules/css.js +39 -0
  54. package/dist/rules/css.js.map +1 -0
  55. package/dist/rules/tsx.d.ts +26 -0
  56. package/dist/rules/tsx.js +191 -0
  57. package/dist/rules/tsx.js.map +1 -0
  58. package/dist/save.d.ts +30 -0
  59. package/dist/save.js +164 -0
  60. package/dist/save.js.map +1 -0
  61. package/dist/scaffold.d.ts +42 -0
  62. package/dist/scaffold.js +232 -0
  63. package/dist/scaffold.js.map +1 -0
  64. package/dist/snapshots.d.ts +43 -0
  65. package/dist/snapshots.js +140 -0
  66. package/dist/snapshots.js.map +1 -0
  67. package/dist/status.d.ts +14 -0
  68. package/dist/status.js +38 -0
  69. package/dist/status.js.map +1 -0
  70. package/dist/validate.d.ts +18 -0
  71. package/dist/validate.js +72 -0
  72. package/dist/validate.js.map +1 -0
  73. package/dist/workspace.d.ts +18 -0
  74. package/dist/workspace.js +119 -0
  75. package/dist/workspace.js.map +1 -0
  76. package/package.json +52 -3
@@ -0,0 +1,19 @@
1
+ export { DEFAULT_PORT, doctor, formatDoctor, machineChecks, prototypeChecks, isServerUp, type CheckStatus, type DoctorCheck, type DoctorOptions } from "./doctor.js";
2
+ export { exportFlows, type ExportOptions } from "./export-flows.js";
3
+ export { buildManifest, keptStatus, sameManifest, serializeManifest, type ExportResult } from "./flows.js";
4
+ export { formatResult } from "./format.js";
5
+ export { KIT_PATH, preview, type PreviewOptions, type PreviewResult } from "./preview.js";
6
+ export { LAYOUT, PROTOTYPE_NAME, WORKSPACE_LAYOUT, findProject, findWorkspace, listPrototypes, projectAt, projectIn, readContract, resolvePrototype, sourceFiles, workspaceAt, type ContractView, type Project, type Workspace, } from "./project.js";
7
+ export { createPrototype, validateKit, validateWorkspace, workspaceSuccess } from "./workspace.js";
8
+ export { ID_PATTERNS, humanize, readFlows, readRegistry, readScreen, type Registry, type ScreenEntry } from "./registry.js";
9
+ export { checkCssValue } from "./rules/css-values.js";
10
+ export { validate, type ValidateOptions } from "./validate.js";
11
+ export { KitError } from "./errors.js";
12
+ export { addGap, type AddGapOptions, type AddGapResult } from "./gaps.js";
13
+ export { MCP_TOOLS, checkedByHook, postEditHook, runHook, sessionStartHook, type HookEvent, type HookInput, type HookOutput } from "./hook.js";
14
+ export { CANVAS_PATH, canvasLink, previewLink, stateLink } from "./links.js";
15
+ export { SNAPSHOT_VIEWPORT, freePort, snapshotFile, snapshotManifest, takeSnapshots, type SnapshotOptions, type SnapshotResult } from "./snapshots.js";
16
+ export { FRAME_STATUSES, setStatus, statusLabel, type FrameStatusValue } from "./status.js";
17
+ export { describeChanges, saveVersion, type SaveOptions, type SaveResult } from "./save.js";
18
+ export { addEdge, addState, createScreen, type AddEdgeOptions, type AddStateOptions, type CreateScreenOptions, type ScaffoldResult, } from "./scaffold.js";
19
+ export { SHARED_INPUTS, affectedPrototypes, previewHost, slugPart } from "./hosting.js";
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ // Library entry. Hooks, skills and the kit MCP server call these; they don't reimplement them.
2
+ export { DEFAULT_PORT, doctor, formatDoctor, machineChecks, prototypeChecks, isServerUp } from "./doctor.js";
3
+ export { exportFlows } from "./export-flows.js";
4
+ export { buildManifest, keptStatus, sameManifest, serializeManifest } from "./flows.js";
5
+ export { formatResult } from "./format.js";
6
+ export { KIT_PATH, preview } from "./preview.js";
7
+ export { LAYOUT, PROTOTYPE_NAME, WORKSPACE_LAYOUT, findProject, findWorkspace, listPrototypes, projectAt, projectIn, readContract, resolvePrototype, sourceFiles, workspaceAt, } from "./project.js";
8
+ export { createPrototype, validateKit, validateWorkspace, workspaceSuccess } from "./workspace.js";
9
+ export { ID_PATTERNS, humanize, readFlows, readRegistry, readScreen } from "./registry.js";
10
+ export { checkCssValue } from "./rules/css-values.js";
11
+ export { validate } from "./validate.js";
12
+ export { KitError } from "./errors.js";
13
+ export { addGap } from "./gaps.js";
14
+ export { MCP_TOOLS, checkedByHook, postEditHook, runHook, sessionStartHook } from "./hook.js";
15
+ export { CANVAS_PATH, canvasLink, previewLink, stateLink } from "./links.js";
16
+ export { SNAPSHOT_VIEWPORT, freePort, snapshotFile, snapshotManifest, takeSnapshots } from "./snapshots.js";
17
+ export { FRAME_STATUSES, setStatus, statusLabel } from "./status.js";
18
+ export { describeChanges, saveVersion } from "./save.js";
19
+ export { addEdge, addState, createScreen, } from "./scaffold.js";
20
+ export { SHARED_INPUTS, affectedPrototypes, previewHost, slugPart } from "./hosting.js";
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAA0D,MAAM,aAAa,CAAC;AACrK,OAAO,EAAE,WAAW,EAAsB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,iBAAiB,EAAqB,MAAM,YAAY,CAAC;AAC3G,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAA2C,MAAM,cAAc,CAAC;AAC1F,OAAO,EACL,MAAM,EACN,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,cAAc,EACd,SAAS,EACT,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,WAAW,GAIZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnG,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAmC,MAAM,eAAe,CAAC;AAC5H,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAwB,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,MAAM,EAAyC,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAmD,MAAM,WAAW,CAAC;AAC/I,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAA6C,MAAM,gBAAgB,CAAC;AACvJ,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAyB,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,WAAW,EAAqC,MAAM,WAAW,CAAC;AAC5F,OAAO,EACL,OAAO,EACP,QAAQ,EACR,YAAY,GAKb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { Issue } from "@cogitato/contract";
2
+ import ts from "typescript";
3
+ export type { Issue };
4
+ /** Issue at a position in a TypeScript source file. */
5
+ export declare function issueAt(code: string, sf: ts.SourceFile, node: ts.Node, message: string, extra?: {
6
+ severity?: Issue["severity"];
7
+ suggestion?: string;
8
+ }): Issue;
9
+ export declare function parseSource(file: string, text: string): ts.SourceFile;
10
+ /** Text of a string literal or a template without substitutions; undefined for anything computed. */
11
+ export declare function literalText(node: ts.Node | undefined): string | undefined;
12
+ /** Name of an object literal property when it's written as plain text. */
13
+ export declare function propertyName(name: ts.PropertyName): string | undefined;
14
+ /** The value expression of property `key` in an object literal, if it's a plain `key: value` assignment. */
15
+ export declare function getProperty(obj: ts.ObjectLiteralExpression, key: string): ts.PropertyAssignment | undefined;
16
+ /** Calls to `name(...)` (or `x.name(...)`) anywhere in the file. */
17
+ export declare function findCalls(sf: ts.SourceFile, name: string): ts.CallExpression[];
package/dist/issue.js ADDED
@@ -0,0 +1,65 @@
1
+ import ts from "typescript";
2
+ /** Issue at a position in a TypeScript source file. */
3
+ export function issueAt(code, sf, node, message, extra = {}) {
4
+ const { line, character } = sf.getLineAndCharacterOfPosition(node.getStart(sf));
5
+ return {
6
+ code,
7
+ severity: extra.severity ?? "error",
8
+ file: sf.fileName,
9
+ path: "",
10
+ line: line + 1,
11
+ column: character + 1,
12
+ message,
13
+ ...(extra.suggestion !== undefined ? { suggestion: extra.suggestion } : {}),
14
+ };
15
+ }
16
+ export function parseSource(file, text) {
17
+ const kind = file.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
18
+ return ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true, kind);
19
+ }
20
+ /** Text of a string literal or a template without substitutions; undefined for anything computed. */
21
+ export function literalText(node) {
22
+ if (!node)
23
+ return undefined;
24
+ if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node))
25
+ return node.text;
26
+ if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isSatisfiesExpression(node)) {
27
+ return literalText(node.expression);
28
+ }
29
+ return undefined;
30
+ }
31
+ /** Name of an object literal property when it's written as plain text. */
32
+ export function propertyName(name) {
33
+ if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name) || ts.isNoSubstitutionTemplateLiteral(name)) {
34
+ return name.text;
35
+ }
36
+ return undefined;
37
+ }
38
+ /** The value expression of property `key` in an object literal, if it's a plain `key: value` assignment. */
39
+ export function getProperty(obj, key) {
40
+ for (const p of obj.properties) {
41
+ if (ts.isPropertyAssignment(p) && propertyName(p.name) === key)
42
+ return p;
43
+ }
44
+ return undefined;
45
+ }
46
+ /** Calls to `name(...)` (or `x.name(...)`) anywhere in the file. */
47
+ export function findCalls(sf, name) {
48
+ const out = [];
49
+ const visit = (node) => {
50
+ if (ts.isCallExpression(node)) {
51
+ const callee = node.expression;
52
+ const calleeName = ts.isIdentifier(callee)
53
+ ? callee.text
54
+ : ts.isPropertyAccessExpression(callee)
55
+ ? callee.name.text
56
+ : undefined;
57
+ if (calleeName === name)
58
+ out.push(node);
59
+ }
60
+ ts.forEachChild(node, visit);
61
+ };
62
+ visit(sf);
63
+ return out;
64
+ }
65
+ //# sourceMappingURL=issue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.js","sourceRoot":"","sources":["../src/issue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { type Project } from "./project.js";
2
+ export declare const CANVAS_PATH = "/__canvas";
3
+ /**
4
+ * Local address of a screen state, like http://localhost:5173/checkout/payment?fixture=card-declined.
5
+ * `node` is "{screen id}.{state}" or just a screen id (its default state).
6
+ */
7
+ export declare function stateLink(project: Project, node: string, port?: number): string;
8
+ /** Local canvas, opened on one state's frame. */
9
+ export declare function canvasLink(project: Project, node: string, port?: number): string;
10
+ /**
11
+ * Hosted canvas for a branch, from the workspace's package.json:
12
+ * `"kit": { "previewUrl": "https://{host}.cogitato-preview.app", "org": "acme-shop-demo" }`.
13
+ * `{host}` is previewHost(branch, prototype, org). Undefined when hosting isn't set up.
14
+ */
15
+ export declare function previewLink(project: Project, branch: string, node?: string): string | undefined;
package/dist/links.js ADDED
@@ -0,0 +1,60 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { DEFAULT_PORT } from "./doctor.js";
3
+ import { KitError } from "./errors.js";
4
+ import { previewHost, slugPart } from "./hosting.js";
5
+ import { sourceFiles } from "./project.js";
6
+ import { readRegistry } from "./registry.js";
7
+ export const CANVAS_PATH = "/__canvas";
8
+ /** Finds the screen and state for "{screen id}.{state}" or a bare screen id (its default state). */
9
+ function resolveNode(project, node) {
10
+ const { screens } = readRegistry(project, sourceFiles(project));
11
+ let screen = screens.find((s) => s.id === node);
12
+ let state = "default";
13
+ if (!screen) {
14
+ const dot = node.lastIndexOf(".");
15
+ screen = screens.find((s) => s.id === node.slice(0, dot));
16
+ state = node.slice(dot + 1);
17
+ }
18
+ if (!screen)
19
+ throw new KitError(`There's no screen or state called "${node}".`);
20
+ if (!screen.fixtures.some((f) => f.key === state)) {
21
+ throw new KitError(`The ${screen.title} screen has no state called "${state}".`);
22
+ }
23
+ return { screen, state };
24
+ }
25
+ /**
26
+ * Local address of a screen state, like http://localhost:5173/checkout/payment?fixture=card-declined.
27
+ * `node` is "{screen id}.{state}" or just a screen id (its default state).
28
+ */
29
+ export function stateLink(project, node, port = DEFAULT_PORT) {
30
+ const { screen, state } = resolveNode(project, node);
31
+ return `http://localhost:${port}${screen.route}?fixture=${encodeURIComponent(state)}`;
32
+ }
33
+ /** Local canvas, opened on one state's frame. */
34
+ export function canvasLink(project, node, port = DEFAULT_PORT) {
35
+ const { screen, state } = resolveNode(project, node);
36
+ return `http://localhost:${port}${CANVAS_PATH}?focus=${encodeURIComponent(`${screen.id}.${state}`)}`;
37
+ }
38
+ /**
39
+ * Hosted canvas for a branch, from the workspace's package.json:
40
+ * `"kit": { "previewUrl": "https://{host}.cogitato-preview.app", "org": "acme-shop-demo" }`.
41
+ * `{host}` is previewHost(branch, prototype, org). Undefined when hosting isn't set up.
42
+ */
43
+ export function previewLink(project, branch, node) {
44
+ const pkgPath = project.workspace.abs("package.json");
45
+ if (!existsSync(pkgPath))
46
+ return undefined;
47
+ let kit;
48
+ try {
49
+ kit = JSON.parse(readFileSync(pkgPath, "utf8")).kit;
50
+ }
51
+ catch {
52
+ return undefined;
53
+ }
54
+ if (typeof kit?.previewUrl !== "string" || !kit.previewUrl.includes("{host}") || typeof kit.org !== "string" || !slugPart(kit.org))
55
+ return undefined;
56
+ const host = previewHost({ branch, prototype: project.name, org: kit.org });
57
+ const base = kit.previewUrl.replace("{host}", host).replace(/\/+$/, "");
58
+ return `${base}${CANVAS_PATH}${node ? `?focus=${encodeURIComponent(node)}` : ""}`;
59
+ }
60
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../src/links.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ import type { Project } from "./project.js";
3
+ export declare const KIT_PATH = "/__kit";
4
+ export interface PreviewOptions {
5
+ port?: number;
6
+ open?: boolean;
7
+ /** Called with progress messages for the person running the command. */
8
+ log?: (message: string) => void;
9
+ }
10
+ export interface PreviewResult {
11
+ url: string;
12
+ /** The dev server Cogitato started, if it wasn't already running. Resolves when it exits. */
13
+ server?: ChildProcess;
14
+ }
15
+ /** Makes sure the prototype is running, then opens its /__kit page with every token and component. */
16
+ export declare function preview(project: Project, opts?: PreviewOptions): Promise<PreviewResult>;
@@ -0,0 +1,38 @@
1
+ import { spawn } from "node:child_process";
2
+ import { DEFAULT_PORT, isServerUp } from "./doctor.js";
3
+ export const KIT_PATH = "/__kit";
4
+ function openInBrowser(url) {
5
+ const [cmd, args] = process.platform === "win32"
6
+ ? ["cmd", ["/c", "start", "", url]]
7
+ : process.platform === "darwin"
8
+ ? ["open", [url]]
9
+ : ["xdg-open", [url]];
10
+ spawn(cmd, args, { stdio: "ignore", detached: true }).unref();
11
+ }
12
+ /** Makes sure the prototype is running, then opens its /__kit page with every token and component. */
13
+ export async function preview(project, opts = {}) {
14
+ const port = opts.port ?? DEFAULT_PORT;
15
+ const url = `http://localhost:${port}${KIT_PATH}`;
16
+ const log = opts.log ?? (() => { });
17
+ let server;
18
+ if (!(await isServerUp(port))) {
19
+ log("Starting the prototype...");
20
+ server = spawn("pnpm", ["exec", "vite", "--port", String(port), "--strictPort"], {
21
+ cwd: project.root,
22
+ stdio: "inherit",
23
+ shell: true,
24
+ });
25
+ const deadline = Date.now() + 30_000;
26
+ while (!(await isServerUp(port))) {
27
+ if (server.exitCode !== null || Date.now() > deadline) {
28
+ throw new Error("The prototype didn't start. Run kit doctor to see what's missing.");
29
+ }
30
+ await new Promise((r) => setTimeout(r, 300));
31
+ }
32
+ }
33
+ log(`The design kit is at ${url}`);
34
+ if (opts.open !== false)
35
+ openInBrowser(url);
36
+ return { url, ...(server ? { server } : {}) };
37
+ }
38
+ //# sourceMappingURL=preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.js","sourceRoot":"","sources":["../src/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGvD,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAejC,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GACf,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC1B,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QACnC,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAC7B,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;AAChE,CAAC;AAED,sGAAsG;AACtG,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAgB,EAAE,OAAuB,EAAE;IACvE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC;IACvC,MAAM,GAAG,GAAG,oBAAoB,IAAI,GAAG,QAAQ,EAAE,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEnC,IAAI,MAAgC,CAAC;IACrC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAC9B,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACjC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,EAAE;YAC/E,GAAG,EAAE,OAAO,CAAC,IAAI;YACjB,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;QACrC,OAAO,CAAC,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACjC,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;gBACtD,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;YACvF,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IACD,GAAG,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK;QAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC5C,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAChD,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { type ComponentManifest, type ResolvedToken } from "@cogitato/contract";
2
+ /** Workspace conventions: one design kit for every prototype (no config file). */
3
+ export declare const WORKSPACE_LAYOUT: {
4
+ readonly contract: "design/contract";
5
+ readonly kit: "kit";
6
+ readonly prototypes: "prototypes";
7
+ };
8
+ /** Conventions inside one prototype, prototypes/<name>/. */
9
+ export declare const LAYOUT: {
10
+ readonly design: "design";
11
+ readonly flowsJson: "design/flows.json";
12
+ readonly src: "src";
13
+ readonly screens: "src/screens";
14
+ readonly flowsTs: "src/flows.ts";
15
+ readonly screenFile: "screen.tsx";
16
+ };
17
+ /** A folder with paths relative to it. */
18
+ export interface Workspace {
19
+ /** Absolute path of the folder. */
20
+ root: string;
21
+ /** Absolute path for a relative path. */
22
+ abs(rel: string): string;
23
+ /** Relative path with "/" separators. */
24
+ rel(abs: string): string;
25
+ }
26
+ /** One prototype. Its paths are relative to prototypes/<name>/. */
27
+ export interface Project extends Workspace {
28
+ name: string;
29
+ workspace: Workspace;
30
+ }
31
+ export declare function workspaceAt(root: string): Workspace;
32
+ /** Finds the workspace by walking up from `from` to the first folder containing design/contract. */
33
+ export declare function findWorkspace(from?: string): Workspace | undefined;
34
+ /** What a prototype's folder name may be: lowercase words with single dashes. */
35
+ export declare const PROTOTYPE_NAME: RegExp;
36
+ /** Names of the prototypes in a workspace: folders in prototypes/ with a valid name and a package.json. Sorted. */
37
+ export declare function listPrototypes(ws: Workspace): string[];
38
+ export declare function projectIn(ws: Workspace, name: string): Project;
39
+ /** The prototype whose folder is `root` (prototypes/<name>). */
40
+ export declare function projectAt(root: string): Project;
41
+ /** The prototype `from` is inside, or the workspace's only prototype. Undefined if it's unclear. */
42
+ export declare function findProject(from?: string): Project | undefined;
43
+ /** The named prototype, else the one `from` is in, else the only one. Throws a designer-readable error otherwise. */
44
+ export declare function resolvePrototype(ws: Workspace, name?: string, from?: string): Project;
45
+ /** Every .ts, .tsx and .css file under src/, project-relative, sorted. */
46
+ export declare function sourceFiles(project: Project): string[];
47
+ export declare const isScreenFile: (rel: string) => boolean;
48
+ /** What the code rules need from the contract. Read leniently: contract problems are reported by contract validation. */
49
+ export interface ContractView {
50
+ tokens: ResolvedToken[];
51
+ /** Every CSS custom property the runtime defines, taken from the generated token CSS itself. */
52
+ cssVars: Set<string>;
53
+ manifests: Map<string, ComponentManifest>;
54
+ }
55
+ export declare function readContract(from: Workspace | Project): ContractView;
@@ -0,0 +1,145 @@
1
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
2
+ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
3
+ import { resolveTokens, tokensToCss, } from "@cogitato/contract";
4
+ import { KitError } from "./errors.js";
5
+ /** Workspace conventions: one design kit for every prototype (no config file). */
6
+ export const WORKSPACE_LAYOUT = {
7
+ contract: "design/contract",
8
+ kit: "kit",
9
+ prototypes: "prototypes",
10
+ };
11
+ /** Conventions inside one prototype, prototypes/<name>/. */
12
+ export const LAYOUT = {
13
+ design: "design",
14
+ flowsJson: "design/flows.json",
15
+ src: "src",
16
+ screens: "src/screens",
17
+ flowsTs: "src/flows.ts",
18
+ screenFile: "screen.tsx",
19
+ };
20
+ export function workspaceAt(root) {
21
+ return {
22
+ root,
23
+ abs: (rel) => (isAbsolute(rel) ? rel : join(root, rel)),
24
+ rel: (abs) => relative(root, isAbsolute(abs) ? abs : join(root, abs)).split(sep).join("/"),
25
+ };
26
+ }
27
+ /** Finds the workspace by walking up from `from` to the first folder containing design/contract. */
28
+ export function findWorkspace(from = process.cwd()) {
29
+ let dir = resolve(from);
30
+ for (;;) {
31
+ if (existsSync(join(dir, WORKSPACE_LAYOUT.contract)))
32
+ return workspaceAt(dir);
33
+ const parent = dirname(dir);
34
+ if (parent === dir)
35
+ return undefined;
36
+ dir = parent;
37
+ }
38
+ }
39
+ /** What a prototype's folder name may be: lowercase words with single dashes. */
40
+ export const PROTOTYPE_NAME = /^[a-z0-9]+(-[a-z0-9]+)*$/;
41
+ /** Names of the prototypes in a workspace: folders in prototypes/ with a valid name and a package.json. Sorted. */
42
+ export function listPrototypes(ws) {
43
+ const dir = ws.abs(WORKSPACE_LAYOUT.prototypes);
44
+ if (!existsSync(dir))
45
+ return [];
46
+ return readdirSync(dir)
47
+ .filter((name) => PROTOTYPE_NAME.test(name) && existsSync(join(dir, name, "package.json")))
48
+ .sort();
49
+ }
50
+ export function projectIn(ws, name) {
51
+ if (!listPrototypes(ws).includes(name)) {
52
+ const names = listPrototypes(ws);
53
+ throw new KitError(`There's no prototype called "${name}".${names.length ? ` The prototypes here are: ${names.join(", ")}.` : ""}`);
54
+ }
55
+ return { ...workspaceAt(ws.abs(`${WORKSPACE_LAYOUT.prototypes}/${name}`)), name, workspace: ws };
56
+ }
57
+ /** The prototype whose folder is `root` (prototypes/<name>). */
58
+ export function projectAt(root) {
59
+ const ws = findWorkspace(root);
60
+ if (!ws)
61
+ throw new KitError(`${root} isn't inside a Cogitato workspace (there's no design/contract folder above it).`);
62
+ const name = basename(resolve(root));
63
+ if (resolve(root) !== resolve(ws.abs(`${WORKSPACE_LAYOUT.prototypes}/${name}`))) {
64
+ throw new KitError(`${root} isn't a prototype folder. Prototypes live in ${WORKSPACE_LAYOUT.prototypes}/<name> inside the workspace.`);
65
+ }
66
+ return projectIn(ws, name);
67
+ }
68
+ /** The prototype `from` is inside, or the workspace's only prototype. Undefined if it's unclear. */
69
+ export function findProject(from = process.cwd()) {
70
+ const ws = findWorkspace(from);
71
+ if (!ws)
72
+ return undefined;
73
+ const name = new RegExp(`^${WORKSPACE_LAYOUT.prototypes}/([^/]+)`).exec(ws.rel(resolve(from)))?.[1];
74
+ const all = listPrototypes(ws);
75
+ if (name && all.includes(name))
76
+ return projectIn(ws, name);
77
+ return all.length === 1 ? projectIn(ws, all[0]) : undefined;
78
+ }
79
+ /** The named prototype, else the one `from` is in, else the only one. Throws a designer-readable error otherwise. */
80
+ export function resolvePrototype(ws, name, from) {
81
+ if (name)
82
+ return projectIn(ws, name);
83
+ const found = findProject(from ?? ws.root);
84
+ if (found && found.workspace.root === ws.root)
85
+ return found;
86
+ const all = listPrototypes(ws);
87
+ if (!all.length)
88
+ throw new KitError("This workspace has no prototypes yet. Ask Claude to start one.");
89
+ throw new KitError(`This workspace has several prototypes (${all.join(", ")}). Say which one.`);
90
+ }
91
+ const SOURCE = /\.(tsx?|css)$/;
92
+ /** Every .ts, .tsx and .css file under src/, project-relative, sorted. */
93
+ export function sourceFiles(project) {
94
+ const out = [];
95
+ const walk = (dir) => {
96
+ if (!existsSync(dir))
97
+ return;
98
+ for (const name of readdirSync(dir)) {
99
+ if (name === "node_modules" || name.startsWith("."))
100
+ continue;
101
+ const path = join(dir, name);
102
+ if (statSync(path).isDirectory())
103
+ walk(path);
104
+ else if (SOURCE.test(name) && !name.endsWith(".d.ts"))
105
+ out.push(project.rel(path));
106
+ }
107
+ };
108
+ walk(project.abs(LAYOUT.src));
109
+ return out.sort();
110
+ }
111
+ export const isScreenFile = (rel) => rel.startsWith(`${LAYOUT.screens}/`) && rel.endsWith(`/${LAYOUT.screenFile}`);
112
+ function readJson(path) {
113
+ try {
114
+ return JSON.parse(readFileSync(path, "utf8"));
115
+ }
116
+ catch {
117
+ return undefined;
118
+ }
119
+ }
120
+ export function readContract(from) {
121
+ const ws = "workspace" in from ? from.workspace : from;
122
+ const tokensJson = readJson(ws.abs(`${WORKSPACE_LAYOUT.contract}/tokens.json`));
123
+ let tokens = [];
124
+ let cssVars = new Set();
125
+ try {
126
+ if (tokensJson) {
127
+ tokens = resolveTokens(tokensJson);
128
+ cssVars = new Set(tokensToCss(tokensJson).match(/--kit-[A-Za-z0-9_-]+(?=:)/g) ?? []);
129
+ }
130
+ }
131
+ catch {
132
+ tokens = [];
133
+ }
134
+ const manifests = new Map();
135
+ const dir = ws.abs(`${WORKSPACE_LAYOUT.contract}/components`);
136
+ if (existsSync(dir)) {
137
+ for (const f of readdirSync(dir).filter((f) => f.endsWith(".json"))) {
138
+ const m = readJson(join(dir, f));
139
+ if (m && typeof m.name === "string")
140
+ manifests.set(m.name, m);
141
+ }
142
+ }
143
+ return { tokens, cssVars, manifests };
144
+ }
145
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import ts from "typescript";
2
+ import { type Issue } from "./issue.js";
3
+ import { type Project } from "./project.js";
4
+ export declare const ID_PATTERNS: {
5
+ screenId: RegExp;
6
+ slug: RegExp;
7
+ kitId: RegExp;
8
+ nodeRef: RegExp;
9
+ };
10
+ interface Located {
11
+ file: string;
12
+ line: number;
13
+ column: number;
14
+ }
15
+ export interface FixtureEntry extends Located {
16
+ key: string;
17
+ title: string;
18
+ }
19
+ export interface ScreenEntry extends Located {
20
+ id: string;
21
+ route: string;
22
+ title: string;
23
+ fixtures: FixtureEntry[];
24
+ /** Folder of the screen (project-relative). Files inside it belong to this screen. */
25
+ dir: string;
26
+ }
27
+ export interface EdgeEntry extends Located {
28
+ from: string;
29
+ to: string;
30
+ label?: string;
31
+ }
32
+ export interface FlowEntry extends Located {
33
+ id: string;
34
+ title: string;
35
+ nodes?: {
36
+ ref: string;
37
+ at: Located;
38
+ }[];
39
+ edges: EdgeEntry[];
40
+ }
41
+ export interface Registry {
42
+ screens: ScreenEntry[];
43
+ flows: FlowEntry[];
44
+ issues: Issue[];
45
+ /**
46
+ * False when a screen file couldn't be read as a screen. Flow checks are skipped then:
47
+ * they'd report that screen's states as missing, which only repeats the real problem.
48
+ */
49
+ complete: boolean;
50
+ }
51
+ /** "card-declined" -> "Card declined". Same rule as the runtime's fixture titles. */
52
+ export declare function humanize(key: string): string;
53
+ /** Reads the defineScreen({...}) registration in one screen.tsx. */
54
+ export declare function readScreen(sf: ts.SourceFile): {
55
+ screen?: ScreenEntry;
56
+ issues: Issue[];
57
+ };
58
+ /** Reads defineFlows([...]) from src/flows.ts. */
59
+ export declare function readFlows(sf: ts.SourceFile): {
60
+ flows: FlowEntry[];
61
+ issues: Issue[];
62
+ };
63
+ /** Parses a project file, reusing the parse while its text is unchanged (keeps repeat runs fast). */
64
+ export declare function parseProjectFile(project: Project, rel: string): ts.SourceFile;
65
+ /** Reads every screen registration and src/flows.ts. Never runs prototype code. */
66
+ export declare function readRegistry(project: Project, files: string[]): Registry;
67
+ export {};