flowbook 0.2.0 → 0.2.2
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 +1 -3
- package/dist/cli.js +207 -253
- package/package.json +1 -1
- package/src/node/init.ts +4 -43
package/README.md
CHANGED
|
@@ -36,8 +36,6 @@ flowbook skill <agent> [-g] Install AI agent skill & /flowbook command
|
|
|
36
36
|
### `flowbook init`
|
|
37
37
|
|
|
38
38
|
- Adds `"flowbook"` and `"build-flowbook"` scripts to your `package.json`
|
|
39
|
-
- Creates `flows/example.flow.md` as a starter template
|
|
40
|
-
- Installs AI agent skills to all supported agent directories
|
|
41
39
|
|
|
42
40
|
### `flowbook dev`
|
|
43
41
|
|
|
@@ -93,7 +91,7 @@ Ignores `node_modules/`, `.git/`, and `dist/`.
|
|
|
93
91
|
|
|
94
92
|
## AI Agent Skill
|
|
95
93
|
|
|
96
|
-
`flowbook
|
|
94
|
+
Use `flowbook skill` to install AI agent skills and `/flowbook` slash commands for your coding agents.
|
|
97
95
|
When a coding agent (Claude Code, OpenAI Codex, VS Code Copilot, Cursor, Gemini CLI, etc.) detects the keyword **"flowbook"** in your prompt, it will:
|
|
98
96
|
|
|
99
97
|
1. Analyze your codebase for logical flows (API routes, auth, state management, business logic, etc.)
|
package/dist/cli.js
CHANGED
|
@@ -1,235 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/node/init.ts
|
|
4
|
-
import { readFileSync, writeFileSync, existsSync
|
|
5
|
-
import { resolve
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
5
|
+
import { resolve } from "path";
|
|
6
6
|
import { execSync } from "child_process";
|
|
7
|
-
|
|
8
|
-
// src/node/skill.ts
|
|
9
|
-
import { existsSync, mkdirSync, copyFileSync } from "fs";
|
|
10
|
-
import { resolve, dirname } from "path";
|
|
11
|
-
import { fileURLToPath } from "url";
|
|
12
|
-
import { homedir } from "os";
|
|
13
|
-
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
|
-
var AGENTS = [
|
|
15
|
-
{
|
|
16
|
-
name: "Claude Code",
|
|
17
|
-
aliases: ["claude"],
|
|
18
|
-
skill: {
|
|
19
|
-
project: ".claude/skills/flowbook",
|
|
20
|
-
global: ".claude/skills/flowbook"
|
|
21
|
-
},
|
|
22
|
-
command: {
|
|
23
|
-
project: ".claude/commands",
|
|
24
|
-
global: ".claude/commands",
|
|
25
|
-
format: "frontmatter"
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
name: "OpenAI Codex",
|
|
30
|
-
aliases: ["codex"],
|
|
31
|
-
skill: {
|
|
32
|
-
project: ".agents/skills/flowbook",
|
|
33
|
-
global: ".codex/skills/flowbook"
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
name: "VS Code / GitHub Copilot",
|
|
38
|
-
aliases: ["copilot", "vscode"],
|
|
39
|
-
skill: {
|
|
40
|
-
project: ".github/skills/flowbook",
|
|
41
|
-
global: ".copilot/skills/flowbook"
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
name: "Google Antigravity",
|
|
46
|
-
aliases: ["antigravity"],
|
|
47
|
-
skill: {
|
|
48
|
-
project: ".agent/skills/flowbook",
|
|
49
|
-
global: ".gemini/antigravity/skills/flowbook"
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
name: "Gemini CLI",
|
|
54
|
-
aliases: ["gemini"],
|
|
55
|
-
skill: {
|
|
56
|
-
project: ".gemini/skills/flowbook",
|
|
57
|
-
global: ".gemini/skills/flowbook"
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: "Cursor",
|
|
62
|
-
aliases: ["cursor"],
|
|
63
|
-
skill: {
|
|
64
|
-
project: ".cursor/skills/flowbook",
|
|
65
|
-
global: ".cursor/skills/flowbook"
|
|
66
|
-
},
|
|
67
|
-
command: {
|
|
68
|
-
project: ".cursor/commands",
|
|
69
|
-
global: ".cursor/commands",
|
|
70
|
-
format: "plain"
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
name: "Windsurf",
|
|
75
|
-
aliases: ["windsurf"],
|
|
76
|
-
skill: {
|
|
77
|
-
project: ".windsurf/skills/flowbook",
|
|
78
|
-
global: ".codeium/windsurf/skills/flowbook"
|
|
79
|
-
},
|
|
80
|
-
command: {
|
|
81
|
-
project: ".windsurf/workflows",
|
|
82
|
-
global: ".codeium/windsurf/workflows",
|
|
83
|
-
format: "plain"
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
name: "AmpCode",
|
|
88
|
-
aliases: ["amp"],
|
|
89
|
-
skill: {
|
|
90
|
-
project: ".amp/skills/flowbook",
|
|
91
|
-
global: ".config/agents/skills/flowbook"
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
name: "OpenCode",
|
|
96
|
-
aliases: ["opencode"],
|
|
97
|
-
skill: {
|
|
98
|
-
project: ".opencode/skills/flowbook",
|
|
99
|
-
global: ".config/opencode/skills/flowbook"
|
|
100
|
-
},
|
|
101
|
-
command: {
|
|
102
|
-
project: ".opencode/command",
|
|
103
|
-
global: ".config/opencode/command",
|
|
104
|
-
format: "frontmatter"
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
];
|
|
108
|
-
function getSkillSrc() {
|
|
109
|
-
return resolve(__dirname, "..", "src", "skills", "flowbook", "SKILL.md");
|
|
110
|
-
}
|
|
111
|
-
function getCommandSrc(format) {
|
|
112
|
-
const file = format === "frontmatter" ? "flowbook.md" : "flowbook.plain.md";
|
|
113
|
-
return resolve(__dirname, "..", "src", "commands", file);
|
|
114
|
-
}
|
|
115
|
-
function resolveAgents(agentArg) {
|
|
116
|
-
if (agentArg === "all") return AGENTS;
|
|
117
|
-
const lower = agentArg.toLowerCase();
|
|
118
|
-
const found = AGENTS.filter(
|
|
119
|
-
(a) => a.aliases.includes(lower) || a.name.toLowerCase().includes(lower)
|
|
120
|
-
);
|
|
121
|
-
if (found.length === 0) {
|
|
122
|
-
console.error(` Unknown agent: "${agentArg}"`);
|
|
123
|
-
console.error(` Available: all, ${AGENTS.flatMap((a) => a.aliases).join(", ")}`);
|
|
124
|
-
process.exit(1);
|
|
125
|
-
}
|
|
126
|
-
return found;
|
|
127
|
-
}
|
|
128
|
-
function installFile(src, destDir, destFilename) {
|
|
129
|
-
const dest = resolve(destDir, destFilename);
|
|
130
|
-
if (existsSync(dest)) return false;
|
|
131
|
-
mkdirSync(destDir, { recursive: true });
|
|
132
|
-
copyFileSync(src, dest);
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
function installSkills(agentArg, global) {
|
|
136
|
-
const agents = resolveAgents(agentArg);
|
|
137
|
-
const base = global ? homedir() : process.cwd();
|
|
138
|
-
const skillSrc = getSkillSrc();
|
|
139
|
-
if (!existsSync(skillSrc)) {
|
|
140
|
-
console.error(" \u2717 Skill source file not found. Reinstall flowbook.");
|
|
141
|
-
process.exit(1);
|
|
142
|
-
}
|
|
143
|
-
let skillCount = 0;
|
|
144
|
-
let cmdCount = 0;
|
|
145
|
-
for (const agent of agents) {
|
|
146
|
-
const skillDir = resolve(base, global ? agent.skill.global : agent.skill.project);
|
|
147
|
-
if (installFile(skillSrc, skillDir, "SKILL.md")) {
|
|
148
|
-
skillCount++;
|
|
149
|
-
}
|
|
150
|
-
if (agent.command) {
|
|
151
|
-
const cmdSrc = getCommandSrc(agent.command.format);
|
|
152
|
-
if (existsSync(cmdSrc)) {
|
|
153
|
-
const cmdDir = resolve(base, global ? agent.command.global : agent.command.project);
|
|
154
|
-
if (installFile(cmdSrc, cmdDir, "flowbook.md")) {
|
|
155
|
-
cmdCount++;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
const scope = global ? "global" : "project";
|
|
161
|
-
const agentNames = agents.map((a) => a.name).join(", ");
|
|
162
|
-
if (skillCount > 0 || cmdCount > 0) {
|
|
163
|
-
if (skillCount > 0) console.log(` \u2713 Installed skill to ${skillCount} ${scope} director${skillCount > 1 ? "ies" : "y"}`);
|
|
164
|
-
if (cmdCount > 0) console.log(` \u2713 Installed /flowbook command to ${cmdCount} ${scope} director${cmdCount > 1 ? "ies" : "y"}`);
|
|
165
|
-
console.log(` Agents: ${agentNames}`);
|
|
166
|
-
} else {
|
|
167
|
-
console.log(` \u2713 Already installed for: ${agentNames}`);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
function installAllProjectSkills() {
|
|
171
|
-
const cwd = process.cwd();
|
|
172
|
-
const skillSrc = getSkillSrc();
|
|
173
|
-
if (!existsSync(skillSrc)) return 0;
|
|
174
|
-
let installed = 0;
|
|
175
|
-
for (const agent of AGENTS) {
|
|
176
|
-
const dir = resolve(cwd, agent.skill.project);
|
|
177
|
-
if (installFile(skillSrc, dir, "SKILL.md")) {
|
|
178
|
-
installed++;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return installed;
|
|
182
|
-
}
|
|
183
|
-
function printSkillUsage() {
|
|
184
|
-
console.log(`
|
|
185
|
-
flowbook skill \u2014 Install AI agent skill & /flowbook command
|
|
186
|
-
|
|
187
|
-
Usage:
|
|
188
|
-
flowbook skill <agent> Install to project
|
|
189
|
-
flowbook skill <agent> --global Install globally
|
|
190
|
-
flowbook skill <agent> -g Install globally (short)
|
|
191
|
-
|
|
192
|
-
Agents:
|
|
193
|
-
all All supported agents
|
|
194
|
-
claude Claude Code
|
|
195
|
-
codex OpenAI Codex
|
|
196
|
-
copilot VS Code / GitHub Copilot
|
|
197
|
-
antigravity Google Antigravity
|
|
198
|
-
gemini Gemini CLI
|
|
199
|
-
cursor Cursor
|
|
200
|
-
windsurf Windsurf (Codeium)
|
|
201
|
-
amp AmpCode
|
|
202
|
-
opencode OpenCode / oh-my-opencode
|
|
203
|
-
|
|
204
|
-
Examples:
|
|
205
|
-
flowbook skill all Install to all agents (project)
|
|
206
|
-
flowbook skill opencode -g Install globally for OpenCode
|
|
207
|
-
flowbook skill claude --global Install globally for Claude Code
|
|
208
|
-
`);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// src/node/init.ts
|
|
212
|
-
var EXAMPLE_FLOW = `---
|
|
213
|
-
title: Example Flow
|
|
214
|
-
category: Getting Started
|
|
215
|
-
tags: [example]
|
|
216
|
-
order: 1
|
|
217
|
-
description: An example flowchart to get you started
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
\`\`\`mermaid
|
|
221
|
-
flowchart TD
|
|
222
|
-
A[Start] --> B{Decision}
|
|
223
|
-
B -->|Yes| C[Action A]
|
|
224
|
-
B -->|No| D[Action B]
|
|
225
|
-
C --> E[End]
|
|
226
|
-
D --> E
|
|
227
|
-
\`\`\`
|
|
228
|
-
`;
|
|
229
7
|
async function initFlowbook() {
|
|
230
8
|
const cwd = process.cwd();
|
|
231
|
-
const pkgPath =
|
|
232
|
-
if (!
|
|
9
|
+
const pkgPath = resolve(cwd, "package.json");
|
|
10
|
+
if (!existsSync(pkgPath)) {
|
|
233
11
|
console.error(" No package.json found. Run 'npm init' first.");
|
|
234
12
|
process.exit(1);
|
|
235
13
|
}
|
|
@@ -260,40 +38,26 @@ async function initFlowbook() {
|
|
|
260
38
|
} else {
|
|
261
39
|
console.log(" \u2713 Scripts already exist in package.json");
|
|
262
40
|
}
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
if (!existsSync2(examplePath)) {
|
|
266
|
-
mkdirSync2(flowsDir, { recursive: true });
|
|
267
|
-
writeFileSync(examplePath, EXAMPLE_FLOW);
|
|
268
|
-
console.log(" \u2713 Created flows/example.flow.md");
|
|
269
|
-
} else {
|
|
270
|
-
console.log(" \u2713 Example flow already exists");
|
|
271
|
-
}
|
|
272
|
-
const gitignorePath = resolve2(cwd, ".gitignore");
|
|
273
|
-
if (existsSync2(gitignorePath)) {
|
|
41
|
+
const gitignorePath = resolve(cwd, ".gitignore");
|
|
42
|
+
if (existsSync(gitignorePath)) {
|
|
274
43
|
const gitignore = readFileSync(gitignorePath, "utf-8");
|
|
275
44
|
if (!gitignore.includes("flowbook-static")) {
|
|
276
45
|
writeFileSync(gitignorePath, gitignore.trimEnd() + "\nflowbook-static\n");
|
|
277
46
|
console.log(" \u2713 Added flowbook-static to .gitignore");
|
|
278
47
|
}
|
|
279
48
|
}
|
|
280
|
-
const installed = installAllProjectSkills();
|
|
281
|
-
if (installed > 0) {
|
|
282
|
-
console.log(` \u2713 Installed AI agent skill to ${installed} agent directories`);
|
|
283
|
-
} else {
|
|
284
|
-
console.log(" \u2713 AI agent skills already installed");
|
|
285
|
-
}
|
|
286
49
|
const run = pm === "yarn" ? "yarn" : `${pm} run`;
|
|
287
50
|
console.log("");
|
|
288
51
|
console.log(" Next steps:");
|
|
289
|
-
console.log(` ${run} flowbook
|
|
290
|
-
console.log(` ${run} build-flowbook
|
|
52
|
+
console.log(` ${run} flowbook Start the dev server`);
|
|
53
|
+
console.log(` ${run} build-flowbook Build static site`);
|
|
54
|
+
console.log(` flowbook skill <agent> [-g] Install AI skill & /flowbook command`);
|
|
291
55
|
console.log("");
|
|
292
56
|
}
|
|
293
57
|
function detectPackageManager(cwd) {
|
|
294
|
-
if (
|
|
295
|
-
if (
|
|
296
|
-
if (
|
|
58
|
+
if (existsSync(resolve(cwd, "bun.lockb")) || existsSync(resolve(cwd, "bun.lock"))) return "bun";
|
|
59
|
+
if (existsSync(resolve(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
60
|
+
if (existsSync(resolve(cwd, "yarn.lock"))) return "yarn";
|
|
297
61
|
return "npm";
|
|
298
62
|
}
|
|
299
63
|
function getInstallCommand(pm) {
|
|
@@ -400,11 +164,11 @@ function flowbookPlugin(options = {}) {
|
|
|
400
164
|
}
|
|
401
165
|
|
|
402
166
|
// src/node/server.ts
|
|
403
|
-
import { resolve as
|
|
404
|
-
import { fileURLToPath
|
|
405
|
-
var
|
|
167
|
+
import { resolve as resolve2, dirname } from "path";
|
|
168
|
+
import { fileURLToPath } from "url";
|
|
169
|
+
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
406
170
|
function getClientDir() {
|
|
407
|
-
return
|
|
171
|
+
return resolve2(__dirname, "..", "src", "client");
|
|
408
172
|
}
|
|
409
173
|
function createConfig(options) {
|
|
410
174
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -425,7 +189,7 @@ function createConfig(options) {
|
|
|
425
189
|
port: options.port ?? 6200
|
|
426
190
|
},
|
|
427
191
|
build: {
|
|
428
|
-
outDir:
|
|
192
|
+
outDir: resolve2(cwd, options.outDir ?? "flowbook-static"),
|
|
429
193
|
emptyOutDir: true
|
|
430
194
|
}
|
|
431
195
|
};
|
|
@@ -444,6 +208,196 @@ async function buildStatic(options) {
|
|
|
444
208
|
`);
|
|
445
209
|
}
|
|
446
210
|
|
|
211
|
+
// src/node/skill.ts
|
|
212
|
+
import { existsSync as existsSync2, mkdirSync, copyFileSync } from "fs";
|
|
213
|
+
import { resolve as resolve3, dirname as dirname2 } from "path";
|
|
214
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
215
|
+
import { homedir } from "os";
|
|
216
|
+
var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
|
|
217
|
+
var AGENTS = [
|
|
218
|
+
{
|
|
219
|
+
name: "Claude Code",
|
|
220
|
+
aliases: ["claude"],
|
|
221
|
+
skill: {
|
|
222
|
+
project: ".claude/skills/flowbook",
|
|
223
|
+
global: ".claude/skills/flowbook"
|
|
224
|
+
},
|
|
225
|
+
command: {
|
|
226
|
+
project: ".claude/commands",
|
|
227
|
+
global: ".claude/commands",
|
|
228
|
+
format: "frontmatter"
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: "OpenAI Codex",
|
|
233
|
+
aliases: ["codex"],
|
|
234
|
+
skill: {
|
|
235
|
+
project: ".agents/skills/flowbook",
|
|
236
|
+
global: ".codex/skills/flowbook"
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: "VS Code / GitHub Copilot",
|
|
241
|
+
aliases: ["copilot", "vscode"],
|
|
242
|
+
skill: {
|
|
243
|
+
project: ".github/skills/flowbook",
|
|
244
|
+
global: ".copilot/skills/flowbook"
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: "Google Antigravity",
|
|
249
|
+
aliases: ["antigravity"],
|
|
250
|
+
skill: {
|
|
251
|
+
project: ".agent/skills/flowbook",
|
|
252
|
+
global: ".gemini/antigravity/skills/flowbook"
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: "Gemini CLI",
|
|
257
|
+
aliases: ["gemini"],
|
|
258
|
+
skill: {
|
|
259
|
+
project: ".gemini/skills/flowbook",
|
|
260
|
+
global: ".gemini/skills/flowbook"
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
name: "Cursor",
|
|
265
|
+
aliases: ["cursor"],
|
|
266
|
+
skill: {
|
|
267
|
+
project: ".cursor/skills/flowbook",
|
|
268
|
+
global: ".cursor/skills/flowbook"
|
|
269
|
+
},
|
|
270
|
+
command: {
|
|
271
|
+
project: ".cursor/commands",
|
|
272
|
+
global: ".cursor/commands",
|
|
273
|
+
format: "plain"
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
name: "Windsurf",
|
|
278
|
+
aliases: ["windsurf"],
|
|
279
|
+
skill: {
|
|
280
|
+
project: ".windsurf/skills/flowbook",
|
|
281
|
+
global: ".codeium/windsurf/skills/flowbook"
|
|
282
|
+
},
|
|
283
|
+
command: {
|
|
284
|
+
project: ".windsurf/workflows",
|
|
285
|
+
global: ".codeium/windsurf/workflows",
|
|
286
|
+
format: "plain"
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
name: "AmpCode",
|
|
291
|
+
aliases: ["amp"],
|
|
292
|
+
skill: {
|
|
293
|
+
project: ".amp/skills/flowbook",
|
|
294
|
+
global: ".config/agents/skills/flowbook"
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: "OpenCode",
|
|
299
|
+
aliases: ["opencode"],
|
|
300
|
+
skill: {
|
|
301
|
+
project: ".opencode/skills/flowbook",
|
|
302
|
+
global: ".config/opencode/skills/flowbook"
|
|
303
|
+
},
|
|
304
|
+
command: {
|
|
305
|
+
project: ".opencode/command",
|
|
306
|
+
global: ".config/opencode/command",
|
|
307
|
+
format: "frontmatter"
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
];
|
|
311
|
+
function getSkillSrc() {
|
|
312
|
+
return resolve3(__dirname2, "..", "src", "skills", "flowbook", "SKILL.md");
|
|
313
|
+
}
|
|
314
|
+
function getCommandSrc(format) {
|
|
315
|
+
const file = format === "frontmatter" ? "flowbook.md" : "flowbook.plain.md";
|
|
316
|
+
return resolve3(__dirname2, "..", "src", "commands", file);
|
|
317
|
+
}
|
|
318
|
+
function resolveAgents(agentArg) {
|
|
319
|
+
if (agentArg === "all") return AGENTS;
|
|
320
|
+
const lower = agentArg.toLowerCase();
|
|
321
|
+
const found = AGENTS.filter(
|
|
322
|
+
(a) => a.aliases.includes(lower) || a.name.toLowerCase().includes(lower)
|
|
323
|
+
);
|
|
324
|
+
if (found.length === 0) {
|
|
325
|
+
console.error(` Unknown agent: "${agentArg}"`);
|
|
326
|
+
console.error(` Available: all, ${AGENTS.flatMap((a) => a.aliases).join(", ")}`);
|
|
327
|
+
process.exit(1);
|
|
328
|
+
}
|
|
329
|
+
return found;
|
|
330
|
+
}
|
|
331
|
+
function installFile(src, destDir, destFilename) {
|
|
332
|
+
const dest = resolve3(destDir, destFilename);
|
|
333
|
+
if (existsSync2(dest)) return false;
|
|
334
|
+
mkdirSync(destDir, { recursive: true });
|
|
335
|
+
copyFileSync(src, dest);
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
function installSkills(agentArg, global) {
|
|
339
|
+
const agents = resolveAgents(agentArg);
|
|
340
|
+
const base = global ? homedir() : process.cwd();
|
|
341
|
+
const skillSrc = getSkillSrc();
|
|
342
|
+
if (!existsSync2(skillSrc)) {
|
|
343
|
+
console.error(" \u2717 Skill source file not found. Reinstall flowbook.");
|
|
344
|
+
process.exit(1);
|
|
345
|
+
}
|
|
346
|
+
let skillCount = 0;
|
|
347
|
+
let cmdCount = 0;
|
|
348
|
+
for (const agent of agents) {
|
|
349
|
+
const skillDir = resolve3(base, global ? agent.skill.global : agent.skill.project);
|
|
350
|
+
if (installFile(skillSrc, skillDir, "SKILL.md")) {
|
|
351
|
+
skillCount++;
|
|
352
|
+
}
|
|
353
|
+
if (agent.command) {
|
|
354
|
+
const cmdSrc = getCommandSrc(agent.command.format);
|
|
355
|
+
if (existsSync2(cmdSrc)) {
|
|
356
|
+
const cmdDir = resolve3(base, global ? agent.command.global : agent.command.project);
|
|
357
|
+
if (installFile(cmdSrc, cmdDir, "flowbook.md")) {
|
|
358
|
+
cmdCount++;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
const scope = global ? "global" : "project";
|
|
364
|
+
const agentNames = agents.map((a) => a.name).join(", ");
|
|
365
|
+
if (skillCount > 0 || cmdCount > 0) {
|
|
366
|
+
if (skillCount > 0) console.log(` \u2713 Installed skill to ${skillCount} ${scope} director${skillCount > 1 ? "ies" : "y"}`);
|
|
367
|
+
if (cmdCount > 0) console.log(` \u2713 Installed /flowbook command to ${cmdCount} ${scope} director${cmdCount > 1 ? "ies" : "y"}`);
|
|
368
|
+
console.log(` Agents: ${agentNames}`);
|
|
369
|
+
} else {
|
|
370
|
+
console.log(` \u2713 Already installed for: ${agentNames}`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
function printSkillUsage() {
|
|
374
|
+
console.log(`
|
|
375
|
+
flowbook skill \u2014 Install AI agent skill & /flowbook command
|
|
376
|
+
|
|
377
|
+
Usage:
|
|
378
|
+
flowbook skill <agent> Install to project
|
|
379
|
+
flowbook skill <agent> --global Install globally
|
|
380
|
+
flowbook skill <agent> -g Install globally (short)
|
|
381
|
+
|
|
382
|
+
Agents:
|
|
383
|
+
all All supported agents
|
|
384
|
+
claude Claude Code
|
|
385
|
+
codex OpenAI Codex
|
|
386
|
+
copilot VS Code / GitHub Copilot
|
|
387
|
+
antigravity Google Antigravity
|
|
388
|
+
gemini Gemini CLI
|
|
389
|
+
cursor Cursor
|
|
390
|
+
windsurf Windsurf (Codeium)
|
|
391
|
+
amp AmpCode
|
|
392
|
+
opencode OpenCode / oh-my-opencode
|
|
393
|
+
|
|
394
|
+
Examples:
|
|
395
|
+
flowbook skill all Install to all agents (project)
|
|
396
|
+
flowbook skill opencode -g Install globally for OpenCode
|
|
397
|
+
flowbook skill claude --global Install globally for Claude Code
|
|
398
|
+
`);
|
|
399
|
+
}
|
|
400
|
+
|
|
447
401
|
// src/node/cli.ts
|
|
448
402
|
async function main() {
|
|
449
403
|
const args = process.argv.slice(2);
|
package/package.json
CHANGED
package/src/node/init.ts
CHANGED
|
@@ -1,26 +1,6 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, existsSync
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { execSync } from "node:child_process";
|
|
4
|
-
import { installAllProjectSkills } from "./skill";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const EXAMPLE_FLOW = `---
|
|
8
|
-
title: Example Flow
|
|
9
|
-
category: Getting Started
|
|
10
|
-
tags: [example]
|
|
11
|
-
order: 1
|
|
12
|
-
description: An example flowchart to get you started
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
\`\`\`mermaid
|
|
16
|
-
flowchart TD
|
|
17
|
-
A[Start] --> B{Decision}
|
|
18
|
-
B -->|Yes| C[Action A]
|
|
19
|
-
B -->|No| D[Action B]
|
|
20
|
-
C --> E[End]
|
|
21
|
-
D --> E
|
|
22
|
-
\`\`\`
|
|
23
|
-
`;
|
|
24
4
|
|
|
25
5
|
export async function initFlowbook() {
|
|
26
6
|
const cwd = process.cwd();
|
|
@@ -65,18 +45,6 @@ export async function initFlowbook() {
|
|
|
65
45
|
console.log(" ✓ Scripts already exist in package.json");
|
|
66
46
|
}
|
|
67
47
|
|
|
68
|
-
// 3. Create example flow file
|
|
69
|
-
const flowsDir = resolve(cwd, "flows");
|
|
70
|
-
const examplePath = resolve(flowsDir, "example.flow.md");
|
|
71
|
-
|
|
72
|
-
if (!existsSync(examplePath)) {
|
|
73
|
-
mkdirSync(flowsDir, { recursive: true });
|
|
74
|
-
writeFileSync(examplePath, EXAMPLE_FLOW);
|
|
75
|
-
console.log(" ✓ Created flows/example.flow.md");
|
|
76
|
-
} else {
|
|
77
|
-
console.log(" ✓ Example flow already exists");
|
|
78
|
-
}
|
|
79
|
-
|
|
80
48
|
// 4. Add flowbook-static to .gitignore
|
|
81
49
|
const gitignorePath = resolve(cwd, ".gitignore");
|
|
82
50
|
if (existsSync(gitignorePath)) {
|
|
@@ -87,19 +55,12 @@ export async function initFlowbook() {
|
|
|
87
55
|
}
|
|
88
56
|
}
|
|
89
57
|
|
|
90
|
-
// 5. Install AI agent skill to all supported agent directories
|
|
91
|
-
const installed = installAllProjectSkills();
|
|
92
|
-
if (installed > 0) {
|
|
93
|
-
console.log(` ✓ Installed AI agent skill to ${installed} agent directories`);
|
|
94
|
-
} else {
|
|
95
|
-
console.log(" ✓ AI agent skills already installed");
|
|
96
|
-
}
|
|
97
|
-
|
|
98
58
|
const run = pm === "yarn" ? "yarn" : `${pm} run`;
|
|
99
59
|
console.log("");
|
|
100
60
|
console.log(" Next steps:");
|
|
101
|
-
console.log(` ${run} flowbook
|
|
102
|
-
console.log(` ${run} build-flowbook
|
|
61
|
+
console.log(` ${run} flowbook Start the dev server`);
|
|
62
|
+
console.log(` ${run} build-flowbook Build static site`);
|
|
63
|
+
console.log(` flowbook skill <agent> [-g] Install AI skill & /flowbook command`);
|
|
103
64
|
console.log("");
|
|
104
65
|
}
|
|
105
66
|
|