glyph-ai 0.1.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/README.md +69 -0
- package/bundled/overlay/overlay.js +63 -0
- package/bundled/server/context/brand-references.d.ts +7 -0
- package/bundled/server/context/brand-references.d.ts.map +1 -0
- package/bundled/server/context/brand-references.js +20 -0
- package/bundled/server/context/brand-references.js.map +1 -0
- package/bundled/server/context/design-philosophy.d.ts +6 -0
- package/bundled/server/context/design-philosophy.d.ts.map +1 -0
- package/bundled/server/context/design-philosophy.js +82 -0
- package/bundled/server/context/design-philosophy.js.map +1 -0
- package/bundled/server/context/design-system-loader.d.ts +11 -0
- package/bundled/server/context/design-system-loader.d.ts.map +1 -0
- package/bundled/server/context/design-system-loader.js +169 -0
- package/bundled/server/context/design-system-loader.js.map +1 -0
- package/bundled/server/context/design-system.d.ts +7 -0
- package/bundled/server/context/design-system.d.ts.map +1 -0
- package/bundled/server/context/design-system.js +75 -0
- package/bundled/server/context/design-system.js.map +1 -0
- package/bundled/server/context/prompt-builder.d.ts +15 -0
- package/bundled/server/context/prompt-builder.d.ts.map +1 -0
- package/bundled/server/context/prompt-builder.js +123 -0
- package/bundled/server/context/prompt-builder.js.map +1 -0
- package/bundled/server/context/token-template.d.ts +36 -0
- package/bundled/server/context/token-template.d.ts.map +1 -0
- package/bundled/server/context/token-template.js +226 -0
- package/bundled/server/context/token-template.js.map +1 -0
- package/bundled/server/data/design-systems/apple-design-system.md +474 -0
- package/bundled/server/data/design-systems/arc-design-system.md +922 -0
- package/bundled/server/data/design-systems/claude-ai-design-system.md +1443 -0
- package/bundled/server/data/design-systems/elevenlabs-design-system.md +669 -0
- package/bundled/server/data/design-systems/generating_design.md +9 -0
- package/bundled/server/data/design-systems/linear-design-system.md +607 -0
- package/bundled/server/data/design-systems/notion-design-system.md +866 -0
- package/bundled/server/data/design-systems/raycast-design-system.md +709 -0
- package/bundled/server/data/design-systems/stripe-design-system.md +592 -0
- package/bundled/server/data/design-systems/vercel-design-system.md +824 -0
- package/bundled/server/data/design.md +971 -0
- package/bundled/server/index.d.ts +2 -0
- package/bundled/server/index.d.ts.map +1 -0
- package/bundled/server/index.js +310 -0
- package/bundled/server/index.js.map +1 -0
- package/bundled/server/mcp/tools/apply-variation.d.ts +3 -0
- package/bundled/server/mcp/tools/apply-variation.d.ts.map +1 -0
- package/bundled/server/mcp/tools/apply-variation.js +43 -0
- package/bundled/server/mcp/tools/apply-variation.js.map +1 -0
- package/bundled/server/mcp/tools/generate-variations.d.ts +3 -0
- package/bundled/server/mcp/tools/generate-variations.d.ts.map +1 -0
- package/bundled/server/mcp/tools/generate-variations.js +58 -0
- package/bundled/server/mcp/tools/generate-variations.js.map +1 -0
- package/bundled/server/mcp/tools/index.d.ts +3 -0
- package/bundled/server/mcp/tools/index.d.ts.map +1 -0
- package/bundled/server/mcp/tools/index.js +11 -0
- package/bundled/server/mcp/tools/index.js.map +1 -0
- package/bundled/server/mcp/tools/scan-design-system.d.ts +3 -0
- package/bundled/server/mcp/tools/scan-design-system.d.ts.map +1 -0
- package/bundled/server/mcp/tools/scan-design-system.js +27 -0
- package/bundled/server/mcp/tools/scan-design-system.js.map +1 -0
- package/bundled/server/mcp/tools/submit-variations.d.ts +3 -0
- package/bundled/server/mcp/tools/submit-variations.d.ts.map +1 -0
- package/bundled/server/mcp/tools/submit-variations.js +50 -0
- package/bundled/server/mcp/tools/submit-variations.js.map +1 -0
- package/bundled/server/mcp-entry.d.ts +2 -0
- package/bundled/server/mcp-entry.d.ts.map +1 -0
- package/bundled/server/mcp-entry.js +56 -0
- package/bundled/server/mcp-entry.js.map +1 -0
- package/bundled/server/preview/css-resolver.d.ts +6 -0
- package/bundled/server/preview/css-resolver.d.ts.map +1 -0
- package/bundled/server/preview/css-resolver.js +57 -0
- package/bundled/server/preview/css-resolver.js.map +1 -0
- package/bundled/server/preview/html-builder.d.ts +6 -0
- package/bundled/server/preview/html-builder.d.ts.map +1 -0
- package/bundled/server/preview/html-builder.js +85 -0
- package/bundled/server/preview/html-builder.js.map +1 -0
- package/bundled/server/telemetry.d.ts +4 -0
- package/bundled/server/telemetry.d.ts.map +1 -0
- package/bundled/server/telemetry.js +71 -0
- package/bundled/server/telemetry.js.map +1 -0
- package/bundled/server/types.d.ts +69 -0
- package/bundled/server/types.d.ts.map +1 -0
- package/bundled/server/types.js +2 -0
- package/bundled/server/types.js.map +1 -0
- package/bundled/server/variations/file-writer.d.ts +5 -0
- package/bundled/server/variations/file-writer.d.ts.map +1 -0
- package/bundled/server/variations/file-writer.js +29 -0
- package/bundled/server/variations/file-writer.js.map +1 -0
- package/bundled/server/variations/git-utils.d.ts +3 -0
- package/bundled/server/variations/git-utils.d.ts.map +1 -0
- package/bundled/server/variations/git-utils.js +23 -0
- package/bundled/server/variations/git-utils.js.map +1 -0
- package/bundled/server/variations/store.d.ts +11 -0
- package/bundled/server/variations/store.d.ts.map +1 -0
- package/bundled/server/variations/store.js +52 -0
- package/bundled/server/variations/store.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +299 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/stop.d.ts +2 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +32 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
6
|
+
import { registerAllTools } from './mcp/tools/index.js';
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const GLYPH_PORT = process.env.GLYPH_PORT || '3001';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Auto-start the HTTP+WS server if it's not already running
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
async function ensureHttpServer() {
|
|
13
|
+
// Check if server is already healthy
|
|
14
|
+
try {
|
|
15
|
+
const res = await fetch(`http://localhost:${GLYPH_PORT}/health`);
|
|
16
|
+
if (res.ok)
|
|
17
|
+
return; // Already running
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// Not running — start it
|
|
21
|
+
}
|
|
22
|
+
const serverEntry = path.resolve(__dirname, 'index.js');
|
|
23
|
+
const child = spawn('node', [serverEntry], {
|
|
24
|
+
detached: true,
|
|
25
|
+
stdio: 'ignore',
|
|
26
|
+
env: {
|
|
27
|
+
...process.env,
|
|
28
|
+
GLYPH_PORT: String(GLYPH_PORT),
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
child.unref();
|
|
32
|
+
// Wait for it to become healthy
|
|
33
|
+
for (let i = 0; i < 10; i++) {
|
|
34
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
35
|
+
try {
|
|
36
|
+
const res = await fetch(`http://localhost:${GLYPH_PORT}/health`);
|
|
37
|
+
if (res.ok)
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Not ready yet
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
await ensureHttpServer();
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// MCP server (stdio)
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
const server = new McpServer({
|
|
50
|
+
name: 'glyph',
|
|
51
|
+
version: '0.2.0',
|
|
52
|
+
});
|
|
53
|
+
registerAllTools(server);
|
|
54
|
+
const transport = new StdioServerTransport();
|
|
55
|
+
await server.connect(transport);
|
|
56
|
+
//# sourceMappingURL=mcp-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-entry.js","sourceRoot":"","sources":["../src/mcp-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,MAAM,CAAC;AAEpD,8EAA8E;AAC9E,4DAA4D;AAC5D,8EAA8E;AAC9E,KAAK,UAAU,gBAAgB;IAC7B,qCAAqC;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,UAAU,SAAS,CAAC,CAAC;QACjE,IAAI,GAAG,CAAC,EAAE;YAAE,OAAO,CAAC,kBAAkB;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;IAC3B,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE;QACzC,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,QAAQ;QACf,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;SAC/B;KACF,CAAC,CAAC;IACH,KAAK,CAAC,KAAK,EAAE,CAAC;IAEd,gCAAgC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,UAAU,SAAS,CAAC,CAAC;YACjE,IAAI,GAAG,CAAC,EAAE;gBAAE,OAAO;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,gBAAgB,EAAE,CAAC;AAEzB,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAC9E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,OAAO;IACb,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAEzB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds the project's compiled CSS for use in iframe previews.
|
|
3
|
+
* Results are cached since CSS doesn't change frequently during a session.
|
|
4
|
+
*/
|
|
5
|
+
export declare function resolveProjectCss(projectRoot: string): Promise<string | null>;
|
|
6
|
+
//# sourceMappingURL=css-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-resolver.d.ts","sourceRoot":"","sources":["../../src/preview/css-resolver.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASnF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import { glob } from 'glob';
|
|
4
|
+
let cachedCss;
|
|
5
|
+
let cachedRoot;
|
|
6
|
+
/**
|
|
7
|
+
* Finds the project's compiled CSS for use in iframe previews.
|
|
8
|
+
* Results are cached since CSS doesn't change frequently during a session.
|
|
9
|
+
*/
|
|
10
|
+
export async function resolveProjectCss(projectRoot) {
|
|
11
|
+
if (cachedCss !== undefined && cachedRoot === projectRoot) {
|
|
12
|
+
return cachedCss;
|
|
13
|
+
}
|
|
14
|
+
const result = await resolve(projectRoot);
|
|
15
|
+
cachedCss = result;
|
|
16
|
+
cachedRoot = projectRoot;
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
async function resolve(projectRoot) {
|
|
20
|
+
// 1. Next.js — compiled CSS
|
|
21
|
+
const nextCssFiles = await glob('.next/static/css/*.css', { cwd: projectRoot });
|
|
22
|
+
if (nextCssFiles.length > 0) {
|
|
23
|
+
return readAndConcat(projectRoot, nextCssFiles);
|
|
24
|
+
}
|
|
25
|
+
// 2. Vite — compiled CSS
|
|
26
|
+
const viteCssFiles = await glob('dist/assets/*.css', { cwd: projectRoot });
|
|
27
|
+
if (viteCssFiles.length > 0) {
|
|
28
|
+
return readAndConcat(projectRoot, viteCssFiles);
|
|
29
|
+
}
|
|
30
|
+
// 3. Global CSS source files (skip if they contain unprocessed directives)
|
|
31
|
+
const globalCandidates = [
|
|
32
|
+
'src/index.css',
|
|
33
|
+
'src/globals.css',
|
|
34
|
+
'app/globals.css',
|
|
35
|
+
];
|
|
36
|
+
for (const candidate of globalCandidates) {
|
|
37
|
+
const fullPath = path.join(projectRoot, candidate);
|
|
38
|
+
if (await fs.pathExists(fullPath)) {
|
|
39
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
40
|
+
if (content.trim() && !needsCompilation(content))
|
|
41
|
+
return content;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// 4. Nothing found — caller will use Tailwind CDN fallback
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
async function readAndConcat(root, files) {
|
|
48
|
+
const contents = await Promise.all(files.map((f) => fs.readFile(path.join(root, f), 'utf-8')));
|
|
49
|
+
return contents.join('\n');
|
|
50
|
+
}
|
|
51
|
+
/** Returns true if the CSS contains directives that need a build tool (Tailwind v4, PostCSS, etc.) */
|
|
52
|
+
function needsCompilation(css) {
|
|
53
|
+
return /^@import\s+["']tailwindcss/m.test(css)
|
|
54
|
+
|| /^@tailwind\s/m.test(css)
|
|
55
|
+
|| /^@config\s/m.test(css);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=css-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-resolver.js","sourceRoot":"","sources":["../../src/preview/css-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,IAAI,SAAoC,CAAC;AACzC,IAAI,UAA8B,CAAC;AAEnC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,WAAmB;IACzD,IAAI,SAAS,KAAK,SAAS,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QAC1D,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1C,SAAS,GAAG,MAAM,CAAC;IACnB,UAAU,GAAG,WAAW,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,WAAmB;IACxC,4BAA4B;IAC5B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,wBAAwB,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IAChF,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,aAAa,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAClD,CAAC;IAED,yBAAyB;IACzB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3E,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,aAAa,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAClD,CAAC;IAED,2EAA2E;IAC3E,MAAM,gBAAgB,GAAG;QACvB,eAAe;QACf,iBAAiB;QACjB,iBAAiB;KAClB,CAAC;IAEF,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACnD,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrD,IAAI,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;gBAAE,OAAO,OAAO,CAAC;QACnE,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,KAAe;IACxD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAC3D,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,sGAAsG;AACtG,SAAS,gBAAgB,CAAC,GAAW;IACnC,OAAO,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC;WACzC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;WACzB,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-builder.d.ts","sourceRoot":"","sources":["../../src/preview/html-builder.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8DzF"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import esbuild from 'esbuild';
|
|
2
|
+
/**
|
|
3
|
+
* Transforms a variation's TSX code into a standalone HTML page
|
|
4
|
+
* that can be rendered in an iframe preview.
|
|
5
|
+
*/
|
|
6
|
+
export async function buildPreviewHtml(code, cssContent) {
|
|
7
|
+
let transpiledJs;
|
|
8
|
+
try {
|
|
9
|
+
const result = await esbuild.transform(code, {
|
|
10
|
+
loader: 'tsx',
|
|
11
|
+
jsx: 'automatic',
|
|
12
|
+
});
|
|
13
|
+
// Capture the default export so we can render it.
|
|
14
|
+
// esbuild preserves `export default` in ESM — rewrite it to assign to a known variable.
|
|
15
|
+
transpiledJs = result.code
|
|
16
|
+
.replace(/^export\s+default\s+function\s+(\w+)/m, 'const __GLYPH_COMP__ = function $1')
|
|
17
|
+
.replace(/^export\s+default\s+class\s+(\w+)/m, 'const __GLYPH_COMP__ = class $1')
|
|
18
|
+
.replace(/^export\s+default\s+/m, 'const __GLYPH_COMP__ = ');
|
|
19
|
+
// Strip remaining named exports (they'd cause errors without a bundler)
|
|
20
|
+
transpiledJs = transpiledJs.replace(/^export\s*\{[^}]*\}\s*;?\s*$/gm, '');
|
|
21
|
+
// Strip `"use client"` directive (not meaningful in standalone preview)
|
|
22
|
+
transpiledJs = transpiledJs.replace(/^"use client";\s*/m, '');
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
26
|
+
return buildErrorHtml(message);
|
|
27
|
+
}
|
|
28
|
+
const styleTag = cssContent
|
|
29
|
+
? `<style>${cssContent}</style>`
|
|
30
|
+
: `<script src="https://cdn.tailwindcss.com"></script>`;
|
|
31
|
+
return `<!DOCTYPE html>
|
|
32
|
+
<html lang="en">
|
|
33
|
+
<head>
|
|
34
|
+
<meta charset="utf-8">
|
|
35
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
36
|
+
${styleTag}
|
|
37
|
+
<script type="importmap">
|
|
38
|
+
{
|
|
39
|
+
"imports": {
|
|
40
|
+
"react": "https://esm.sh/react@19",
|
|
41
|
+
"react-dom": "https://esm.sh/react-dom@19",
|
|
42
|
+
"react-dom/client": "https://esm.sh/react-dom@19/client",
|
|
43
|
+
"react/jsx-runtime": "https://esm.sh/react@19/jsx-runtime"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
</head>
|
|
48
|
+
<body style="margin: 0; background: #0a0a0a;">
|
|
49
|
+
<div id="root"></div>
|
|
50
|
+
<script type="module">
|
|
51
|
+
import { createRoot } from "react-dom/client";
|
|
52
|
+
|
|
53
|
+
${transpiledJs}
|
|
54
|
+
|
|
55
|
+
if (typeof __GLYPH_COMP__ !== "undefined" && __GLYPH_COMP__) {
|
|
56
|
+
createRoot(document.getElementById("root")).render(
|
|
57
|
+
typeof __GLYPH_COMP__ === "function" ? __GLYPH_COMP__() : __GLYPH_COMP__
|
|
58
|
+
);
|
|
59
|
+
} else {
|
|
60
|
+
document.getElementById("root").innerHTML =
|
|
61
|
+
'<p style="color:#ef4444;font-family:monospace;padding:2rem;">No default export found.</p>';
|
|
62
|
+
}
|
|
63
|
+
</script>
|
|
64
|
+
</body>
|
|
65
|
+
</html>`;
|
|
66
|
+
}
|
|
67
|
+
function buildErrorHtml(errorMessage) {
|
|
68
|
+
const escaped = errorMessage
|
|
69
|
+
.replace(/&/g, '&')
|
|
70
|
+
.replace(/</g, '<')
|
|
71
|
+
.replace(/>/g, '>')
|
|
72
|
+
.replace(/"/g, '"');
|
|
73
|
+
return `<!DOCTYPE html>
|
|
74
|
+
<html lang="en">
|
|
75
|
+
<head>
|
|
76
|
+
<meta charset="utf-8">
|
|
77
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
78
|
+
</head>
|
|
79
|
+
<body style="margin: 0; background: #0a0a0a; color: #ef4444; font-family: monospace; padding: 2rem;">
|
|
80
|
+
<h2 style="margin-top: 0;">Build Error</h2>
|
|
81
|
+
<pre style="white-space: pre-wrap; word-break: break-word; line-height: 1.6;">${escaped}</pre>
|
|
82
|
+
</body>
|
|
83
|
+
</html>`;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=html-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-builder.js","sourceRoot":"","sources":["../../src/preview/html-builder.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY,EAAE,UAAmB;IACtE,IAAI,YAAoB,CAAC;IAEzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE;YAC3C,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,WAAW;SACjB,CAAC,CAAC;QACH,kDAAkD;QAClD,wFAAwF;QACxF,YAAY,GAAG,MAAM,CAAC,IAAI;aACvB,OAAO,CAAC,uCAAuC,EAAE,oCAAoC,CAAC;aACtF,OAAO,CAAC,oCAAoC,EAAE,iCAAiC,CAAC;aAChF,OAAO,CAAC,uBAAuB,EAAE,yBAAyB,CAAC,CAAC;QAC/D,wEAAwE;QACxE,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,gCAAgC,EAAE,EAAE,CAAC,CAAC;QAC1E,wEAAwE;QACxE,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU;QACzB,CAAC,CAAC,UAAU,UAAU,UAAU;QAChC,CAAC,CAAC,qDAAqD,CAAC;IAE1D,OAAO;;;;;IAKL,QAAQ;;;;;;;;;;;;;;;;;EAiBV,YAAY;;;;;;;;;;;;QAYN,CAAC;AACT,CAAC;AAED,SAAS,cAAc,CAAC,YAAoB;IAC1C,MAAM,OAAO,GAAG,YAAY;SACzB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE3B,OAAO;;;;;;;;kFAQyE,OAAO;;QAEjF,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AA+CA,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI,CAWhF;AAED,wBAAgB,KAAK,IAAI,IAAI,CAa5B;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAI/B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
const TELEMETRY_URL = process.env.GLYPH_TELEMETRY_URL || '';
|
|
5
|
+
const TELEMETRY_KEY = process.env.GLYPH_TELEMETRY_KEY || '';
|
|
6
|
+
const PROJECT_ROOT = process.env.GLYPH_PROJECT_ROOT || process.cwd();
|
|
7
|
+
const FLUSH_INTERVAL_MS = 5_000;
|
|
8
|
+
const MAX_BUFFER_SIZE = 100;
|
|
9
|
+
let buffer = [];
|
|
10
|
+
let deviceId = null;
|
|
11
|
+
const serverSessionId = crypto.randomUUID();
|
|
12
|
+
let intervalHandle = null;
|
|
13
|
+
function isEnabled() {
|
|
14
|
+
return TELEMETRY_URL.length > 0;
|
|
15
|
+
}
|
|
16
|
+
function getDeviceId() {
|
|
17
|
+
if (deviceId)
|
|
18
|
+
return deviceId;
|
|
19
|
+
const idPath = path.join(PROJECT_ROOT, '.glyph', 'device-id');
|
|
20
|
+
try {
|
|
21
|
+
deviceId = fs.readFileSync(idPath, 'utf-8').trim();
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
deviceId = crypto.randomUUID();
|
|
25
|
+
fs.mkdirSync(path.dirname(idPath), { recursive: true });
|
|
26
|
+
fs.writeFileSync(idPath, deviceId, 'utf-8');
|
|
27
|
+
}
|
|
28
|
+
return deviceId;
|
|
29
|
+
}
|
|
30
|
+
function ensureInterval() {
|
|
31
|
+
if (!intervalHandle) {
|
|
32
|
+
intervalHandle = setInterval(flush, FLUSH_INTERVAL_MS);
|
|
33
|
+
intervalHandle.unref();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function track(event, payload = {}) {
|
|
37
|
+
if (!isEnabled())
|
|
38
|
+
return;
|
|
39
|
+
ensureInterval();
|
|
40
|
+
buffer.push({
|
|
41
|
+
event,
|
|
42
|
+
timestamp: new Date().toISOString(),
|
|
43
|
+
session_id: serverSessionId,
|
|
44
|
+
device_id: getDeviceId(),
|
|
45
|
+
payload,
|
|
46
|
+
});
|
|
47
|
+
if (buffer.length >= MAX_BUFFER_SIZE)
|
|
48
|
+
flush();
|
|
49
|
+
}
|
|
50
|
+
export function flush() {
|
|
51
|
+
if (!isEnabled() || buffer.length === 0)
|
|
52
|
+
return;
|
|
53
|
+
const events = buffer;
|
|
54
|
+
buffer = [];
|
|
55
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
56
|
+
if (TELEMETRY_KEY) {
|
|
57
|
+
headers['Authorization'] = `Bearer ${TELEMETRY_KEY}`;
|
|
58
|
+
}
|
|
59
|
+
fetch(TELEMETRY_URL, {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers,
|
|
62
|
+
body: JSON.stringify({ events }),
|
|
63
|
+
}).catch(() => { });
|
|
64
|
+
}
|
|
65
|
+
export function shutdown() {
|
|
66
|
+
if (intervalHandle)
|
|
67
|
+
clearInterval(intervalHandle);
|
|
68
|
+
intervalHandle = null;
|
|
69
|
+
flush();
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface Variation {
|
|
2
|
+
id: string;
|
|
3
|
+
sourceFile: string;
|
|
4
|
+
code: string;
|
|
5
|
+
brand?: string;
|
|
6
|
+
createdAt: number;
|
|
7
|
+
}
|
|
8
|
+
export interface VariationSession {
|
|
9
|
+
id: string;
|
|
10
|
+
sourceFile: string;
|
|
11
|
+
variations: Variation[];
|
|
12
|
+
previewingId?: string;
|
|
13
|
+
implementedId?: string;
|
|
14
|
+
gitSnapshotHash?: string;
|
|
15
|
+
userPrompt?: string;
|
|
16
|
+
backupPath?: string;
|
|
17
|
+
createdAt: number;
|
|
18
|
+
}
|
|
19
|
+
export type WSMessageToOverlay = {
|
|
20
|
+
type: 'variations:ready';
|
|
21
|
+
payload: {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
variations: Variation[];
|
|
24
|
+
previewUrls: Record<string, string>;
|
|
25
|
+
};
|
|
26
|
+
} | {
|
|
27
|
+
type: 'variation:arrived';
|
|
28
|
+
payload: {
|
|
29
|
+
sessionId: string;
|
|
30
|
+
variation: Variation;
|
|
31
|
+
previewUrl: string;
|
|
32
|
+
};
|
|
33
|
+
} | {
|
|
34
|
+
type: 'variation:previewing';
|
|
35
|
+
payload: {
|
|
36
|
+
id: string | null;
|
|
37
|
+
index: number;
|
|
38
|
+
total: number;
|
|
39
|
+
};
|
|
40
|
+
} | {
|
|
41
|
+
type: 'variation:implemented';
|
|
42
|
+
payload: {
|
|
43
|
+
variationId: string;
|
|
44
|
+
};
|
|
45
|
+
} | {
|
|
46
|
+
type: 'state:update';
|
|
47
|
+
payload: {
|
|
48
|
+
session: VariationSession | null;
|
|
49
|
+
projectName?: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
export type WSMessageFromOverlay = {
|
|
53
|
+
type: 'variation:preview';
|
|
54
|
+
payload: {
|
|
55
|
+
id: string;
|
|
56
|
+
};
|
|
57
|
+
} | {
|
|
58
|
+
type: 'variation:cycle';
|
|
59
|
+
payload: {
|
|
60
|
+
direction: 'next' | 'prev';
|
|
61
|
+
};
|
|
62
|
+
} | {
|
|
63
|
+
type: 'variation:implement';
|
|
64
|
+
payload: Record<string, never>;
|
|
65
|
+
} | {
|
|
66
|
+
type: 'variation:discard';
|
|
67
|
+
payload: Record<string, never>;
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,SAAS,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;CAAE,GAC1H;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,SAAS,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACvG;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC9F;IAAE,IAAI,EAAE,uBAAuB,CAAC;IAAC,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE;QAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAElG,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CAAE,GACpE;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function backupFile(filePath: string): Promise<string>;
|
|
2
|
+
export declare function writeVariation(filePath: string, code: string): Promise<void>;
|
|
3
|
+
export declare function restoreBackup(backupPath: string, originalPath: string): Promise<void>;
|
|
4
|
+
export declare function cleanupBackup(backupPath: string): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=file-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-writer.d.ts","sourceRoot":"","sources":["../../src/variations/file-writer.ts"],"names":[],"mappings":"AAGA,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAWlE;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlF;AAED,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3F;AAED,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOrE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export async function backupFile(filePath) {
|
|
4
|
+
const timestamp = Date.now();
|
|
5
|
+
const basename = path.basename(filePath);
|
|
6
|
+
const projectRoot = process.env.GLYPH_PROJECT_ROOT || process.cwd();
|
|
7
|
+
const backupDir = path.join(projectRoot, '.glyph', 'backups', String(timestamp));
|
|
8
|
+
const backupPath = path.join(backupDir, basename);
|
|
9
|
+
await fs.ensureDir(backupDir);
|
|
10
|
+
await fs.copy(filePath, backupPath);
|
|
11
|
+
return backupPath;
|
|
12
|
+
}
|
|
13
|
+
export async function writeVariation(filePath, code) {
|
|
14
|
+
await fs.ensureDir(path.dirname(filePath));
|
|
15
|
+
await fs.writeFile(filePath, code, 'utf-8');
|
|
16
|
+
}
|
|
17
|
+
export async function restoreBackup(backupPath, originalPath) {
|
|
18
|
+
await fs.copy(backupPath, originalPath, { overwrite: true });
|
|
19
|
+
}
|
|
20
|
+
export async function cleanupBackup(backupPath) {
|
|
21
|
+
try {
|
|
22
|
+
const backupDir = path.dirname(backupPath);
|
|
23
|
+
await fs.remove(backupDir);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Best-effort cleanup
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=file-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-writer.js","sourceRoot":"","sources":["../../src/variations/file-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACpE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IACjF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAElD,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAEpC,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB,EAAE,IAAY;IACjE,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAkB,EAAE,YAAoB;IAC1E,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAkB;IACpD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../../src/variations/git-utils.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO7E;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAYlB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
const exec = promisify(execFile);
|
|
4
|
+
export async function getGitBlobHash(filePath) {
|
|
5
|
+
try {
|
|
6
|
+
const { stdout } = await exec('git', ['hash-object', filePath]);
|
|
7
|
+
return stdout.trim();
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function hasCommitsSince(filePath, sinceTimestamp, projectRoot) {
|
|
14
|
+
try {
|
|
15
|
+
const since = new Date(sinceTimestamp).toISOString();
|
|
16
|
+
const { stdout } = await exec('git', ['log', '--oneline', `--since=${since}`, '--', filePath], { cwd: projectRoot });
|
|
17
|
+
return stdout.trim().length > 0;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=git-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-utils.js","sourceRoot":"","sources":["../../src/variations/git-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChE,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,cAAsB,EACtB,WAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;QACrD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAC3B,KAAK,EACL,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,EACxD,EAAE,GAAG,EAAE,WAAW,EAAE,CACrB,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Variation, VariationSession } from '../types.js';
|
|
2
|
+
export declare function createSession(sourceFile: string, opts?: {
|
|
3
|
+
gitSnapshotHash?: string;
|
|
4
|
+
userPrompt?: string;
|
|
5
|
+
}): VariationSession;
|
|
6
|
+
export declare function addVariations(sessionId: string, variations: Variation[]): void;
|
|
7
|
+
export declare function getSession(sessionId?: string): VariationSession | null;
|
|
8
|
+
export declare function getSessionById(sessionId: string): VariationSession | null;
|
|
9
|
+
export declare function setPreviewing(sessionId: string, variationId: string): void;
|
|
10
|
+
export declare function clearPreviewing(sessionId: string): void;
|
|
11
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/variations/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAM/D,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACvD,gBAAgB,CAalB;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,CAM9E;AAED,wBAAgB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAQtE;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAEzE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAM1E;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAMvD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import { track } from '../telemetry.js';
|
|
3
|
+
const sessions = new Map();
|
|
4
|
+
let latestSessionId;
|
|
5
|
+
export function createSession(sourceFile, opts) {
|
|
6
|
+
const session = {
|
|
7
|
+
id: crypto.randomUUID(),
|
|
8
|
+
sourceFile,
|
|
9
|
+
variations: [],
|
|
10
|
+
gitSnapshotHash: opts?.gitSnapshotHash ?? undefined,
|
|
11
|
+
userPrompt: opts?.userPrompt ?? undefined,
|
|
12
|
+
createdAt: Date.now(),
|
|
13
|
+
};
|
|
14
|
+
sessions.set(session.id, session);
|
|
15
|
+
latestSessionId = session.id;
|
|
16
|
+
track('session:create', { sessionId: session.id, sourceFile });
|
|
17
|
+
return session;
|
|
18
|
+
}
|
|
19
|
+
export function addVariations(sessionId, variations) {
|
|
20
|
+
const session = sessions.get(sessionId);
|
|
21
|
+
if (!session) {
|
|
22
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
23
|
+
}
|
|
24
|
+
session.variations.push(...variations);
|
|
25
|
+
}
|
|
26
|
+
export function getSession(sessionId) {
|
|
27
|
+
if (sessionId) {
|
|
28
|
+
return sessions.get(sessionId) ?? null;
|
|
29
|
+
}
|
|
30
|
+
if (latestSessionId) {
|
|
31
|
+
return sessions.get(latestSessionId) ?? null;
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
export function getSessionById(sessionId) {
|
|
36
|
+
return sessions.get(sessionId) ?? null;
|
|
37
|
+
}
|
|
38
|
+
export function setPreviewing(sessionId, variationId) {
|
|
39
|
+
const session = sessions.get(sessionId);
|
|
40
|
+
if (!session) {
|
|
41
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
42
|
+
}
|
|
43
|
+
session.previewingId = variationId;
|
|
44
|
+
}
|
|
45
|
+
export function clearPreviewing(sessionId) {
|
|
46
|
+
const session = sessions.get(sessionId);
|
|
47
|
+
if (!session) {
|
|
48
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
49
|
+
}
|
|
50
|
+
session.previewingId = undefined;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/variations/store.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC,MAAM,QAAQ,GAAkC,IAAI,GAAG,EAAE,CAAC;AAC1D,IAAI,eAAmC,CAAC;AAExC,MAAM,UAAU,aAAa,CAC3B,UAAkB,EAClB,IAAwD;IAExD,MAAM,OAAO,GAAqB;QAChC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,UAAU;QACV,UAAU,EAAE,EAAE;QACd,eAAe,EAAE,IAAI,EAAE,eAAe,IAAI,SAAS;QACnD,UAAU,EAAE,IAAI,EAAE,UAAU,IAAI,SAAS;QACzC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;IACF,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAClC,eAAe,GAAG,OAAO,CAAC,EAAE,CAAC;IAC7B,KAAK,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB,EAAE,UAAuB;IACtE,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAAkB;IAC3C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;IACzC,CAAC;IACD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC;IAC/C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB,EAAE,WAAmB;IAClE,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,CAAC,YAAY,GAAG,WAAW,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AA8SA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAsD1C"}
|