showpane 0.2.0 → 0.2.1

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 (2) hide show
  1. package/dist/index.js +34 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3,12 +3,15 @@
3
3
  // src/index.ts
4
4
  import { createInterface } from "readline";
5
5
  import { execSync, spawn, exec } from "child_process";
6
- import { mkdirSync, readFileSync, writeFileSync } from "fs";
6
+ import fs from "fs";
7
7
  import { randomBytes } from "crypto";
8
8
  import { createServer } from "net";
9
- import { resolve, dirname, join } from "path";
10
- import { homedir } from "os";
9
+ import path from "path";
10
+ import os from "os";
11
11
  import { fileURLToPath } from "url";
12
+ var { mkdirSync, readFileSync, writeFileSync } = fs;
13
+ var { resolve, dirname, join } = path;
14
+ var { homedir } = os;
12
15
  var RESET = "\x1B[0m";
13
16
  var BOLD = "\x1B[1m";
14
17
  var DIM = "\x1B[2m";
@@ -129,17 +132,44 @@ AUTH_SECRET="${authSecret}"
129
132
  } catch {
130
133
  blue("Skipped example portal (seed failed \u2014 not a problem)");
131
134
  }
135
+ const skillsSource = path.join(dirName, "skills");
136
+ const skillsTarget = path.join(os.homedir(), ".claude", "skills");
137
+ const oldSymlink = path.join(skillsTarget, "showpane");
138
+ try {
139
+ const stat = fs.lstatSync(oldSymlink);
140
+ if (stat.isSymbolicLink()) fs.unlinkSync(oldSymlink);
141
+ } catch {
142
+ }
143
+ fs.mkdirSync(skillsTarget, { recursive: true });
144
+ const skillDirs = fs.readdirSync(skillsSource, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.startsWith("portal-"));
145
+ for (const dir of skillDirs) {
146
+ const targetDir = path.join(skillsTarget, dir.name);
147
+ fs.mkdirSync(targetDir, { recursive: true });
148
+ const skillFile = path.join(targetDir, "SKILL.md");
149
+ try {
150
+ fs.unlinkSync(skillFile);
151
+ } catch {
152
+ }
153
+ fs.symlinkSync(
154
+ path.join(skillsSource, dir.name, "SKILL.md"),
155
+ skillFile
156
+ );
157
+ }
158
+ green(`${skillDirs.length} Claude Code skills installed`);
132
159
  const port = await findFreePort(3e3);
133
160
  green(`Server starting on port ${port}`);
134
161
  const url = `http://localhost:${port}`;
135
162
  blue(`Opening ${url}`);
136
163
  console.log();
137
- console.log(` ${GREEN}Ready!${RESET} Open Claude Code and create your first portal:`);
164
+ console.log(` ${GREEN}Ready!${RESET} ${skillDirs.length} Claude Code skills installed.`);
138
165
  console.log();
166
+ console.log(` Open Claude Code and create your first portal:`);
139
167
  console.log(` ${DIM}cd ${dirName}/app${RESET}`);
140
168
  console.log(` ${BOLD}claude${RESET}`);
141
169
  console.log(` ${DIM}> Create a portal for my call with [client name]${RESET}`);
142
170
  console.log();
171
+ console.log(` Available skills: /portal-create, /portal-deploy, /portal-list, ...`);
172
+ console.log();
143
173
  console.log(` ${DIM}Don't have Claude Code? Install from https://claude.ai/code${RESET}`);
144
174
  console.log();
145
175
  const devServer = spawn("npm", ["run", "dev"], {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "showpane",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "CLI for Showpane — AI-generated client portals",
5
5
  "type": "module",
6
6
  "bin": {