@tuongaz/seeflow 0.1.18 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#34d399" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
2
+ <rect width="8" height="8" x="3" y="3" rx="2"/>
3
+ <path d="M7 11v4a2 2 0 0 0 2 2h4"/>
4
+ <rect width="8" height="8" x="13" y="13" rx="2"/>
5
+ </svg>
Binary file
Binary file
Binary file
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
2
+ <rect width="512" height="512" rx="60" ry="60" fill="#09090b"/>
3
+ <g transform="translate(76 76) scale(15)" fill="none" stroke="#34d399" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
4
+ <rect width="8" height="8" x="3" y="3" rx="2"/>
5
+ <path d="M7 11v4a2 2 0 0 0 2 2h4"/>
6
+ <rect width="8" height="8" x="13" y="13" rx="2"/>
7
+ </g>
8
+ </svg>
@@ -3,9 +3,13 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
7
+ <link rel="manifest" href="/manifest.webmanifest" />
8
+ <meta name="theme-color" content="#09090b" />
9
+ <meta name="apple-mobile-web-app-capable" content="yes" />
6
10
  <title>SeeFlow Studio</title>
7
- <script type="module" crossorigin src="/assets/index-BNOqnF2Y.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-Dkzv11xm.css">
11
+ <script type="module" crossorigin src="/assets/index-Bnmpx_Y5.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-Cu7piflE.css">
9
13
  </head>
10
14
  <body>
11
15
  <div id="root"></div>
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "SeeFlow Studio",
3
+ "short_name": "SeeFlow",
4
+ "description": "Architecture diagrams that actually run.",
5
+ "start_url": "/",
6
+ "scope": "/",
7
+ "display": "standalone",
8
+ "background_color": "#09090b",
9
+ "theme_color": "#09090b",
10
+ "icons": [
11
+ {
12
+ "src": "/icon-192.png",
13
+ "sizes": "192x192",
14
+ "type": "image/png",
15
+ "purpose": "any"
16
+ },
17
+ {
18
+ "src": "/icon-512.png",
19
+ "sizes": "512x512",
20
+ "type": "image/png",
21
+ "purpose": "any"
22
+ },
23
+ {
24
+ "src": "/icon-maskable-512.png",
25
+ "sizes": "512x512",
26
+ "type": "image/png",
27
+ "purpose": "maskable"
28
+ }
29
+ ]
30
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuongaz/seeflow",
3
- "version": "0.1.18",
3
+ "version": "0.1.22",
4
4
  "description": "Local studio that hosts file-defined demos as React Flow canvases wired to a running app via REST + SSE + Zod schema.",
5
5
  "keywords": [
6
6
  "seeflow",
package/src/cli.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env bun
2
2
  import { cpSync, existsSync } from 'node:fs';
3
- import { homedir } from 'node:os';
4
3
  import { isAbsolute, join, resolve } from 'node:path';
5
4
  import { createEventBus } from './events.ts';
5
+ import { seeflowHome } from './paths.ts';
6
6
  import { defaultProcessSpawner } from './process-spawner.ts';
7
7
  import { type Registry, createRegistry } from './registry.ts';
8
8
  import {
@@ -139,7 +139,7 @@ async function seedExamples(registry: Registry) {
139
139
  }
140
140
 
141
141
  async function seedExample(registry: Registry, exampleName: string) {
142
- const destDir = join(homedir(), '.seeflow', exampleName);
142
+ const destDir = join(seeflowHome(), exampleName);
143
143
  const demoPath = '.seeflow/seeflow.json';
144
144
 
145
145
  // Always sync from source so that schema changes and example updates are
package/src/operations.ts CHANGED
@@ -8,9 +8,9 @@
8
8
  // Future stories add patch_node + connector helpers alongside these.
9
9
 
10
10
  import { existsSync, mkdirSync, renameSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
11
- import { homedir } from 'node:os';
12
11
  import { dirname, isAbsolute, join } from 'node:path';
13
12
  import { type ZodIssue, z } from 'zod';
13
+ import { seeflowHome } from './paths.ts';
14
14
  import { type Registry, slugify } from './registry.ts';
15
15
  import {
16
16
  ColorTokenSchema,
@@ -171,7 +171,11 @@ export const mergeNodeUpdates = (node: Record<string, unknown>, updates: NodePat
171
171
  export interface OperationsDeps {
172
172
  registry: Registry;
173
173
  watcher?: DemoWatcher;
174
- /** Override the base directory for new projects. Defaults to ~/.seeflow. Tests inject a tmp dir. */
174
+ /**
175
+ * Override the base directory for new projects. Defaults to seeflowHome()
176
+ * — `${SEEFLOW_WORKSPACE}/.seeflow` inside Docker, `~/.seeflow` locally.
177
+ * Tests inject a tmp dir.
178
+ */
175
179
  projectBaseDir?: string;
176
180
  }
177
181
 
@@ -621,7 +625,7 @@ export async function createProjectImpl(
621
625
  ): Promise<CreateProjectOutcome> {
622
626
  const { registry, watcher } = deps;
623
627
  const { name } = body;
624
- const baseDir = deps.projectBaseDir ?? join(homedir(), '.seeflow');
628
+ const baseDir = deps.projectBaseDir ?? seeflowHome();
625
629
  const folderPath = join(baseDir, slugify(name));
626
630
 
627
631
  const demoFullPath = join(folderPath, DEFAULT_DEMO_RELATIVE_PATH);
package/src/paths.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { homedir } from 'node:os';
2
+ import { join } from 'node:path';
3
+
4
+ // Base dir for studio state (registry.json, config.json, seeflow.pid, and
5
+ // newly-created project folders). When SEEFLOW_WORKSPACE is set — notably
6
+ // inside the Docker image, where it defaults to /workspace — state lands in
7
+ // the bind-mounted workspace so it survives `docker run --rm`. Otherwise it
8
+ // falls back to ~/.seeflow for local installs.
9
+ export function seeflowHome(): string {
10
+ const workspace = process.env.SEEFLOW_WORKSPACE;
11
+ if (workspace && workspace.length > 0) return join(workspace, '.seeflow');
12
+ return join(homedir(), '.seeflow');
13
+ }
package/src/registry.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { homedir } from 'node:os';
3
2
  import { dirname, join } from 'node:path';
3
+ import { seeflowHome } from './paths.ts';
4
4
 
5
5
  export interface DemoEntry {
6
6
  id: string;
@@ -31,7 +31,7 @@ export interface Registry {
31
31
  }
32
32
 
33
33
  export function defaultRegistryPath(): string {
34
- return join(homedir(), '.seeflow', 'registry.json');
34
+ return join(seeflowHome(), 'registry.json');
35
35
  }
36
36
 
37
37
  export function slugify(name: string): string {
package/src/runtime.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
2
- import { homedir } from 'node:os';
3
2
  import { dirname, join } from 'node:path';
3
+ import { seeflowHome } from './paths.ts';
4
4
 
5
5
  export interface StudioConfig {
6
6
  port: number;
@@ -10,11 +10,11 @@ export interface StudioConfig {
10
10
  export const DEFAULT_CONFIG: StudioConfig = { port: 4321, host: '0.0.0.0' };
11
11
 
12
12
  export function defaultConfigPath(): string {
13
- return join(homedir(), '.seeflow', 'config.json');
13
+ return join(seeflowHome(), 'config.json');
14
14
  }
15
15
 
16
16
  export function defaultPidPath(): string {
17
- return join(homedir(), '.seeflow', 'seeflow.pid');
17
+ return join(seeflowHome(), 'seeflow.pid');
18
18
  }
19
19
 
20
20
  export function readConfig(path = defaultConfigPath()): StudioConfig {