@aiworkbench/vibe-cli 0.0.6 → 0.0.8

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/dist/index.js CHANGED
@@ -5853,6 +5853,9 @@ bridge.navigation.navigate("/some/host/path");
5853
5853
 
5854
5854
  This triggers a host-level route change. It is fire-and-forget — your mini-app will
5855
5855
  be unmounted as the host navigates away.
5856
+
5857
+ See the \`host-design-system\` skill for the complete list of host routes, dynamic
5858
+ segments, query parameters, and navigation code examples.
5856
5859
  `;
5857
5860
  }
5858
5861
  function getViewSwitchingExample(framework) {
@@ -6743,13 +6746,36 @@ The host application has these routes. Use \`bridge.navigation.navigate(path)\`
6743
6746
 
6744
6747
  | Route | Page |
6745
6748
  |-------|------|
6746
- | \`/chat\` | Chat with agents |
6749
+ | \`/[agentId]/chat\` | Chat with a specific agent |
6750
+ | \`/[agentId]/talk\` | Voice conversation |
6747
6751
  | \`/marketplace\` | Marketplace landing |
6748
- | \`/marketplace/agents?state=PUBLISHED\` | Published agents |
6752
+ | \`/marketplace/agents\` | Agent directory |
6753
+ | \`/marketplace/servers\` | MCP server directory |
6754
+ | \`/builder\` | Builder landing |
6755
+ | \`/builder/agent\` | Agent builder |
6749
6756
  | \`/playground\` | Prompt playground |
6750
- | \`/builder\` | Agent builder |
6757
+ | \`/playground/[appId]\` | Mini-app sandbox |
6751
6758
  | \`/documents\` | Document library |
6752
- | \`/administration\` | Admin panel (admins only) |
6759
+
6760
+ ### Dynamic Segments
6761
+
6762
+ | Segment | Description | Example |
6763
+ |---------|-------------|---------|
6764
+ | \`[agentId]\` | Agent UUID — identifies which agent to chat with or call | \`a1b2c3d4-e5f6-7890-abcd-ef1234567890\` |
6765
+ | \`[appId]\` | Mini-app ID from \`manifest.json\` — loads that app in the sandbox | \`my-mini-app\` |
6766
+
6767
+ ### Navigation Examples
6768
+
6769
+ \`\`\`typescript
6770
+ // Navigate to a specific agent's chat
6771
+ bridge.navigation.navigate(\`/\${agentId}/chat\`);
6772
+
6773
+ // Open the marketplace agent directory
6774
+ bridge.navigation.navigate("/marketplace/agents");
6775
+
6776
+ // Open a mini-app in the playground sandbox
6777
+ bridge.navigation.navigate(\`/playground/\${appId}\`);
6778
+ \`\`\`
6753
6779
 
6754
6780
  ## Dark Mode Support
6755
6781
 
@@ -7091,6 +7117,103 @@ private render() {
7091
7117
  }
7092
7118
  }
7093
7119
 
7120
+ // src/skills/platform-design-philosophy.ts
7121
+ function generatePlatformDesignPhilosophy(_config) {
7122
+ return `# Platform Design Philosophy
7123
+
7124
+ ## Core Principle: Be Invisible
7125
+
7126
+ A successful mini-app is one the user cannot distinguish from the host. If someone
7127
+ can tell where the host ends and your mini-app begins, the design has failed. Your
7128
+ goal is not to build something that "looks good" — it is to build something that
7129
+ **disappears** into the platform.
7130
+
7131
+ This means: no branding, no personality, no signature style. The host IS the style.
7132
+ You are extending it, not decorating it.
7133
+
7134
+ ## Design Thinking for Platform Consistency
7135
+
7136
+ ### Match Visual Weight
7137
+
7138
+ Every element in the host has a deliberate visual weight. Buttons are small and quiet.
7139
+ Cards have thin borders and minimal shadow. Headings are understated. If your mini-app
7140
+ introduces elements that are heavier — bolder, larger, more colorful, more shadowed —
7141
+ it will feel foreign even if the colors technically match.
7142
+
7143
+ Before adding any element, look at the host's equivalent. How heavy is it? Match that
7144
+ weight exactly.
7145
+
7146
+ ### Respect Information Hierarchy
7147
+
7148
+ The host uses a strict hierarchy:
7149
+ 1. **Content** comes first — data, text, interactive elements
7150
+ 2. **Chrome** is minimal — thin borders, subtle backgrounds, small labels
7151
+ 3. **Decoration** is absent — no gradients, no illustrations, no ornamental elements
7152
+
7153
+ Your mini-app should follow the same hierarchy. If you're spending time on decoration,
7154
+ you're diverging from the platform aesthetic.
7155
+
7156
+ ### Grayscale-First Philosophy
7157
+
7158
+ The host is intentionally grayscale. Color is used as a **signal**, not a **style**:
7159
+ - **Tertiary accent** (yellow-green) marks featured or promoted items
7160
+ - **Destructive red** marks dangerous actions
7161
+ - **Chart/data colors** convey meaning in visualizations
7162
+
7163
+ Everything else — backgrounds, borders, text, icons, cards, buttons — is grayscale.
7164
+ If your UI uses color for anything other than semantic signaling, it will clash.
7165
+
7166
+ ## What "Native" Means in This Platform
7167
+
7168
+ | Aspect | Native Approach |
7169
+ |--------|----------------|
7170
+ | **Typography** | Geist Sans and Geist Mono. No other fonts, ever. |
7171
+ | **Color palette** | OKLCh grayscale with a single accent. No brand colors, no blues, no greens. |
7172
+ | **Component style** | shadcn/UI "New York" variant — clean, dense, slightly austere. |
7173
+ | **Density** | Dense but not cramped. Cards use \`1rem\` padding, grids use \`0.75rem–1.5rem\` gaps. |
7174
+ | **Interactions** | Subtle and fast. \`150–180ms\` transitions. No bouncing, no sliding, no scaling. |
7175
+ | **Borders** | \`1px solid\` in muted gray. Never thicker. Never colored. |
7176
+ | **Shadows** | Flat by default. Shadow appears only on hover for interactive cards. |
7177
+ | **Icons** | Lucide at \`16–20px\`, stroke-only, \`currentColor\`. No filled icons, no custom icon sets. |
7178
+
7179
+ ## Quick Decision Checklist
7180
+
7181
+ Use this before writing any component:
7182
+
7183
+ - [ ] **Card radius** — \`8px\` standard, \`12px\` for marketplace-style cards, \`6px\` for buttons/inputs
7184
+ - [ ] **Grayscale chrome** — Is every non-content element (borders, backgrounds, labels) grayscale?
7185
+ - [ ] **Type scale** — Body at \`0.875rem\`, headings at \`1.125rem\`, labels at \`0.6875rem\` uppercase
7186
+ - [ ] **Transition timing** — \`180ms ease\` for hover/shadow, \`150ms ease\` for color/opacity
7187
+ - [ ] **Border width** — \`1px\` everywhere, no exceptions
7188
+ - [ ] **Shadow** — None at rest, \`0 2px 6px rgba(0,0,0,0.15)\` on hover for interactive cards only
7189
+ - [ ] **Font** — Geist Sans via \`var(--font-geist-sans)\`, Geist Mono via \`var(--font-geist-mono)\`
7190
+ - [ ] **Spacing** — Multiples of \`0.25rem\` (4px base unit), common values: 8px, 12px, 16px, 24px
7191
+
7192
+ ## Anti-Patterns
7193
+
7194
+ These immediately break the native feel. Avoid them completely:
7195
+
7196
+ | Anti-Pattern | Why It Fails |
7197
+ |-------------|-------------|
7198
+ | **Colored backgrounds** | The host uses white/near-white. Colored sections scream "third-party." |
7199
+ | **Custom fonts** | Even "nice" fonts like Inter or Roboto break consistency. Only Geist. |
7200
+ | **Animated entrances** | Fade-ins, slide-ups, scale animations on mount. The host doesn't do this. |
7201
+ | **Gradient chrome** | Gradient backgrounds, gradient borders, gradient buttons. The host is flat. |
7202
+ | **Shadows at rest** | Drop shadows on cards, panels, or containers that aren't being hovered. |
7203
+ | **Saturated color palettes** | Blues, greens, oranges for UI elements. Only grayscale + the tertiary accent. |
7204
+ | **Oversized headings** | Headings larger than \`1.125rem\`. The host's headings are deliberately small. |
7205
+ | **Thick borders** | Borders thicker than \`1px\`. The host uses hairline borders exclusively. |
7206
+ | **Rounded-full pills** | Pill-shaped elements (\`border-radius: 9999px\`). Cards are \`8–12px\`, badges are \`6px\`. |
7207
+ | **Icon-heavy UI** | Large icons, colored icons, icon grids. The host uses small, monochrome icons sparingly. |
7208
+
7209
+ ## Cross-Reference
7210
+
7211
+ This skill establishes the **design mindset**. For specific implementation values — exact
7212
+ colors, spacing tokens, component CSS, and dark mode support — load the \`host-design-system\`
7213
+ skill. Both skills should be consulted before writing any UI code.
7214
+ `;
7215
+ }
7216
+
7094
7217
  // src/scaffold/write-agent-docs.ts
7095
7218
  var PERMISSION_DOCS = {
7096
7219
  auth: `### auth
@@ -7287,6 +7410,19 @@ cleanups.forEach((fn) => fn());
7287
7410
  | "Unresolved external" build warning | Dependency not in Vite external config | Add to \`rollupOptions.external\` or bundle it |
7288
7411
  | HMR not reflecting changes | Custom element re-registration conflict | Hard refresh the page (Cmd+Shift+R / Ctrl+Shift+R) |
7289
7412
 
7413
+ ## Always-Loaded Design Skills
7414
+
7415
+ **IMPORTANT**: Always load these two skills BEFORE writing any UI code. They are
7416
+ mandatory for every task that involves creating or modifying visual components.
7417
+
7418
+ | Skill | Purpose |
7419
+ |-------|---------|
7420
+ | \`platform-design-philosophy\` | Design mindset — ensures your UI feels native to the host platform |
7421
+ | \`host-design-system\` | Design tokens — exact colors, spacing, typography, and component CSS |
7422
+
7423
+ Load both skills at the start of any UI task. The philosophy skill establishes the
7424
+ approach; the design system skill provides the implementation details.
7425
+
7290
7426
  ## Skills Reference
7291
7427
 
7292
7428
  This project includes detailed skill guides for specific topics. Skills are **not loaded by
@@ -7307,7 +7443,6 @@ reference than to guess.
7307
7443
  | \`debugging\` | Troubleshooting issues, tracing bridge calls, fixing HMR problems |
7308
7444
  | \`navigation-patterns\` | Building multi-view UIs, tabs, wizards, or steppers (no URL routing) |
7309
7445
  | \`asset-handling\` | Working with images, SVGs, fonts, or other static assets |
7310
- | \`host-design-system\` | Styling components to match the host application's design tokens and visual language |
7311
7446
  ${testing ? `| \`testing-guide\` | Writing or modifying tests, mocking the bridge, test setup |
7312
7447
  ` : ""}
7313
7448
  **How to use skills:** Read the skill file for the relevant topic before implementing. Multiple
@@ -7349,7 +7484,8 @@ function generateEmbeddedSkills(config) {
7349
7484
  { name: "Debugging", content: generateDebugging(config) },
7350
7485
  { name: "Navigation Patterns", content: generateNavigationPatterns(config) },
7351
7486
  { name: "Asset Handling", content: generateAssetHandling(config) },
7352
- { name: "Host Design System", content: generateHostDesignSystem(config) }
7487
+ { name: "Host Design System", content: generateHostDesignSystem(config) },
7488
+ { name: "Platform Design Philosophy", content: generatePlatformDesignPhilosophy(config) }
7353
7489
  ];
7354
7490
  if (config.testing) {
7355
7491
  skills.push({ name: "Testing Guide", content: generateTestingGuide(config) });
@@ -7691,6 +7827,11 @@ var SKILL_DEFS = [
7691
7827
  name: "host-design-system",
7692
7828
  description: "Host app design tokens, typography, spacing, colors, and component patterns",
7693
7829
  generate: generateHostDesignSystem
7830
+ },
7831
+ {
7832
+ name: "platform-design-philosophy",
7833
+ description: "Design mindset and principles for building UI that feels native to the host platform",
7834
+ generate: generatePlatformDesignPhilosophy
7694
7835
  }
7695
7836
  ];
7696
7837
  async function writeFolderSkill(baseDir, skill, content) {
@@ -8772,7 +8913,47 @@ async function configCommand(args) {
8772
8913
  // src/commands/release.ts
8773
8914
  import { resolve as resolve4 } from "node:path";
8774
8915
  import { readFile as readFile11, writeFile as writeFile9 } from "node:fs/promises";
8775
- import { execSync as execSync2 } from "node:child_process";
8916
+ import { execFileSync } from "node:child_process";
8917
+ var REQUIRED_ENV_VARS = [
8918
+ "VIBE_STORAGE_ACCOUNT_NAME",
8919
+ "VIBE_STORAGE_ACCOUNT_KEY",
8920
+ "VIBE_STORAGE_CONTAINER_NAME",
8921
+ "VIBE_REGISTRY_REPO",
8922
+ "VIBE_REGISTRY_TOKEN"
8923
+ ];
8924
+ function parseDotenv(content) {
8925
+ const env = {};
8926
+ for (const line of content.split(`
8927
+ `)) {
8928
+ const trimmed = line.trim();
8929
+ if (!trimmed || trimmed.startsWith("#"))
8930
+ continue;
8931
+ const eqIdx = trimmed.indexOf("=");
8932
+ if (eqIdx === -1)
8933
+ continue;
8934
+ const key = trimmed.slice(0, eqIdx).trim();
8935
+ let value = trimmed.slice(eqIdx + 1).trim();
8936
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
8937
+ value = value.slice(1, -1);
8938
+ }
8939
+ env[key] = value;
8940
+ }
8941
+ return env;
8942
+ }
8943
+ async function validateEnvVars(cwd) {
8944
+ let dotenv = {};
8945
+ try {
8946
+ const content = await readFile11(resolve4(cwd, ".env"), "utf-8");
8947
+ dotenv = parseDotenv(content);
8948
+ } catch {}
8949
+ const missing = [];
8950
+ for (const key of REQUIRED_ENV_VARS) {
8951
+ if (!dotenv[key] && !process.env[key]) {
8952
+ missing.push(key);
8953
+ }
8954
+ }
8955
+ return missing.length === 0 ? { ok: true } : { ok: false, missing };
8956
+ }
8776
8957
  function bumpVersion(version, type) {
8777
8958
  if (type === "keep")
8778
8959
  return version;
@@ -8792,8 +8973,8 @@ function bumpVersion(version, type) {
8792
8973
  return `${major + 1}.0.0`;
8793
8974
  }
8794
8975
  }
8795
- function git(cmd, cwd) {
8796
- return execSync2(`git ${cmd}`, { cwd, encoding: "utf-8" }).trim();
8976
+ function git(args, cwd) {
8977
+ return execFileSync("git", args, { cwd, encoding: "utf-8" }).trim();
8797
8978
  }
8798
8979
  function parseGitHubRepo(remoteUrl, host = "github.com") {
8799
8980
  const escaped = host.replace(/\./g, "\\.");
@@ -8840,6 +9021,47 @@ async function releaseCommand(dir) {
8840
9021
  });
8841
9022
  const newVersion = bumpVersion(currentVersion, bumpType);
8842
9023
  const tag = `v${newVersion}`;
9024
+ const publishMode = await dist_default5({
9025
+ message: "Publish method:",
9026
+ choices: [
9027
+ {
9028
+ name: "Local publish (uses .env credentials)",
9029
+ value: "local"
9030
+ },
9031
+ {
9032
+ name: "CI publish (push tag → GitHub Actions)",
9033
+ value: "ci"
9034
+ }
9035
+ ]
9036
+ });
9037
+ let environment = "dev";
9038
+ if (publishMode === "local") {
9039
+ environment = await dist_default5({
9040
+ message: "Target environment:",
9041
+ choices: [
9042
+ { name: "dev", value: "dev" },
9043
+ { name: "staging", value: "staging" },
9044
+ { name: "prod", value: "prod" }
9045
+ ]
9046
+ });
9047
+ const envResult = await validateEnvVars(outputDir);
9048
+ if (!envResult.ok) {
9049
+ blank();
9050
+ error("Missing required environment variables for local publish:");
9051
+ for (const key of envResult.missing) {
9052
+ info(` • ${key}`);
9053
+ }
9054
+ blank();
9055
+ info("Add them to a .env file in your project root, or export them in your shell.");
9056
+ info("Example .env:");
9057
+ blank();
9058
+ for (const key of REQUIRED_ENV_VARS) {
9059
+ info(` ${key}=your-value-here`);
9060
+ }
9061
+ blank();
9062
+ process.exit(1);
9063
+ }
9064
+ }
8843
9065
  blank();
8844
9066
  if (bumpType === "keep") {
8845
9067
  info(`Version: ${currentVersion} (unchanged)`);
@@ -8847,6 +9069,7 @@ async function releaseCommand(dir) {
8847
9069
  info(`Version: ${currentVersion} → ${newVersion}`);
8848
9070
  }
8849
9071
  info(`Tag: ${tag}`);
9072
+ info(`Mode: ${publishMode === "local" ? `Local publish → ${environment}` : "CI publish"}`);
8850
9073
  blank();
8851
9074
  const proceed = await dist_default3({
8852
9075
  message: "Proceed with release?",
@@ -8863,9 +9086,28 @@ async function releaseCommand(dir) {
8863
9086
  `, "utf-8");
8864
9087
  success(`Updated manifest.json to ${newVersion}`);
8865
9088
  }
9089
+ if (publishMode === "local") {
9090
+ info("Building mini-app...");
9091
+ try {
9092
+ execFileSync("bun", ["run", "build"], { cwd: outputDir, stdio: "inherit" });
9093
+ success("Build complete.");
9094
+ } catch {
9095
+ error("Build failed. Fix the errors above and retry.");
9096
+ process.exit(1);
9097
+ }
9098
+ info(`Publishing to ${environment}...`);
9099
+ try {
9100
+ execFileSync("npx", ["@aiworkbench/vibe-publish", "-e", environment, "--direct-push", "--app-dir", "."], { cwd: outputDir, stdio: "inherit" });
9101
+ success(`Published to ${environment} registry.`);
9102
+ } catch {
9103
+ error("Publish failed. Fix the error above and retry.");
9104
+ info("Your manifest.json has been updated but no git operations were performed.");
9105
+ process.exit(1);
9106
+ }
9107
+ }
8866
9108
  try {
8867
- git(`add manifest.json`, outputDir);
8868
- git(`commit -m "release: ${tag}"`, outputDir);
9109
+ git(["add", "manifest.json"], outputDir);
9110
+ git(["commit", "-m", `release: ${tag}`], outputDir);
8869
9111
  success(`Committed: release: ${tag}`);
8870
9112
  } catch (err) {
8871
9113
  const msg = err instanceof Error ? err.message : String(err);
@@ -8881,7 +9123,7 @@ async function releaseCommand(dir) {
8881
9123
  }
8882
9124
  }
8883
9125
  try {
8884
- git(`tag ${tag}`, outputDir);
9126
+ git(["tag", tag], outputDir);
8885
9127
  success(`Tagged: ${tag}`);
8886
9128
  } catch (err) {
8887
9129
  const msg = err instanceof Error ? err.message : String(err);
@@ -8894,8 +9136,8 @@ async function releaseCommand(dir) {
8894
9136
  process.exit(1);
8895
9137
  }
8896
9138
  try {
8897
- git(`push`, outputDir);
8898
- git(`push --tags`, outputDir);
9139
+ git(["push"], outputDir);
9140
+ git(["push", "--tags"], outputDir);
8899
9141
  success(`Pushed commit and tag.`);
8900
9142
  } catch (err) {
8901
9143
  const msg = err instanceof Error ? err.message : String(err);
@@ -8906,20 +9148,24 @@ async function releaseCommand(dir) {
8906
9148
  process.exit(1);
8907
9149
  }
8908
9150
  blank();
8909
- success(`Released ${tag} CI will now build and publish your mini-app.`);
8910
- try {
8911
- const remoteUrl = git("remote get-url origin", outputDir);
8912
- const globalConfig = await loadGlobalConfig();
8913
- const host = globalConfig.githubHost ?? "github.com";
8914
- const repo = parseGitHubRepo(remoteUrl, host);
8915
- if (repo) {
8916
- blank();
8917
- info(`Check CI progress: https://${host}/${repo}/actions`);
8918
- if (globalConfig.registryRepo) {
8919
- info(`After CI completes, your app will appear in: https://${host}/${globalConfig.registryRepo}`);
9151
+ if (publishMode === "local") {
9152
+ success(`Released ${tag} — published locally to ${environment} registry.`);
9153
+ } else {
9154
+ success(`Released ${tag} CI will now build and publish your mini-app.`);
9155
+ try {
9156
+ const remoteUrl = git(["remote", "get-url", "origin"], outputDir);
9157
+ const globalConfig = await loadGlobalConfig();
9158
+ const host = globalConfig.githubHost ?? "github.com";
9159
+ const repo = parseGitHubRepo(remoteUrl, host);
9160
+ if (repo) {
9161
+ blank();
9162
+ info(`Check CI progress: https://${host}/${repo}/actions`);
9163
+ if (globalConfig.registryRepo) {
9164
+ info(`After CI completes, your app will appear in: https://${host}/${globalConfig.registryRepo}`);
9165
+ }
8920
9166
  }
8921
- }
8922
- } catch {}
9167
+ } catch {}
9168
+ }
8923
9169
  blank();
8924
9170
  }
8925
9171
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiworkbench/vibe-cli",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -3,6 +3,9 @@ import react from "@vitejs/plugin-react";
3
3
 
4
4
  export default defineConfig({
5
5
  plugins: [react()],
6
+ define: {
7
+ "process.env.NODE_ENV": JSON.stringify("production"),
8
+ },
6
9
  build: {
7
10
  lib: {
8
11
  entry: "./src/main.tsx",
@@ -11,7 +14,7 @@ export default defineConfig({
11
14
  formats: ["es"],
12
15
  },
13
16
  rollupOptions: {
14
- external: ["react", "react-dom"],
17
+ external: ["react", "react-dom", "react-dom/client", "react/jsx-runtime"],
15
18
  output: {
16
19
  globals: {
17
20
  react: "React",
@@ -1,6 +1,9 @@
1
1
  import { defineConfig } from "vite";
2
2
 
3
3
  export default defineConfig({
4
+ define: {
5
+ "process.env.NODE_ENV": JSON.stringify("production"),
6
+ },
4
7
  build: {
5
8
  lib: {
6
9
  entry: "./src/main.ts",
@@ -3,6 +3,9 @@ import vue from "@vitejs/plugin-vue";
3
3
 
4
4
  export default defineConfig({
5
5
  plugins: [vue()],
6
+ define: {
7
+ "process.env.NODE_ENV": JSON.stringify("production"),
8
+ },
6
9
  build: {
7
10
  lib: {
8
11
  entry: "./src/main.ts",