@flowkode/cli 1.0.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 ADDED
@@ -0,0 +1,299 @@
1
+ # @flowkode/cli
2
+
3
+ CLI officiel pour l'API Flowkode. Creez, deployez et gerez vos sites web depuis le terminal.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @flowkode/cli
9
+ ```
10
+
11
+ ## Connexion
12
+
13
+ ```bash
14
+ flowkode login
15
+ ```
16
+
17
+ Le navigateur s'ouvre, vous autorisez le CLI en un clic, c'est tout.
18
+
19
+ ```
20
+ $ flowkode login
21
+
22
+ Flowkode Login
23
+
24
+ Ouverture du navigateur...
25
+
26
+ En attente d'autorisation...
27
+
28
+ ✓ Connecte en tant que jeremy@example.com
29
+ Cle sauvegardee dans ~/.flowkode/config.json
30
+
31
+ Essayez : flowkode projects list
32
+ ```
33
+
34
+ Pour se deconnecter :
35
+ ```bash
36
+ flowkode logout
37
+ ```
38
+
39
+ ### Configuration avancee
40
+
41
+ ```bash
42
+ # Configurer manuellement une cle API
43
+ flowkode config --api-key ws_live_xxxxx
44
+
45
+ # URL personnalisee (defaut: https://app.flowkode.com)
46
+ flowkode config --base-url https://app.flowkode.com
47
+
48
+ # Voir la config actuelle
49
+ flowkode config --show
50
+ ```
51
+
52
+ La configuration est stockee dans `~/.flowkode/config.json`.
53
+
54
+ Variables d'environnement (prioritaires) :
55
+ ```bash
56
+ export FLOWKODE_API_KEY=ws_live_xxxxx
57
+ export FLOWKODE_BASE_URL=https://app.flowkode.com
58
+ ```
59
+
60
+ ## Commandes
61
+
62
+ ### Projets
63
+
64
+ ```bash
65
+ # Lister les projets
66
+ flowkode projects list
67
+ flowkode projects list --folder <folder-id>
68
+
69
+ # Detail d'un projet
70
+ flowkode projects get <id>
71
+
72
+ # Creer un projet (mode rapide, 1 page)
73
+ flowkode projects create \
74
+ --name "Mon site" \
75
+ --type vitrine \
76
+ --keywords "seo, web, freelance" \
77
+ --language fr \
78
+ --description "Portfolio developpeur"
79
+
80
+ # Modifier un projet
81
+ flowkode projects update <id> --name "Nouveau nom"
82
+ flowkode projects update <id> --folder <folder-id>
83
+
84
+ # Deployer
85
+ flowkode projects deploy <id> --provider vercel
86
+ flowkode projects deploy <id> --provider cloudflare --domain <domain-id> --configure-ns
87
+
88
+ # Re-deployer sur le dernier provider
89
+ flowkode projects redeploy <id>
90
+
91
+ # Statut d'indexation Google
92
+ flowkode projects indexing <id>
93
+ ```
94
+
95
+ ### Jobs de generation
96
+
97
+ ```bash
98
+ # Lister les jobs
99
+ flowkode jobs list
100
+ flowkode jobs list --status running
101
+
102
+ # Suivre un job
103
+ flowkode jobs get <id>
104
+ ```
105
+
106
+ ### Deploiements
107
+
108
+ ```bash
109
+ # Lister les deploiements
110
+ flowkode deployments list
111
+ flowkode deployments list --project <id> --provider vercel --status ready
112
+
113
+ # Detail d'un deploiement
114
+ flowkode deployments get <id>
115
+ ```
116
+
117
+ ### Domaines
118
+
119
+ ```bash
120
+ # Lister les domaines
121
+ flowkode domains list
122
+ flowkode domains list --registrar ovh --project <id>
123
+
124
+ # Detail d'un domaine
125
+ flowkode domains get <id>
126
+
127
+ # Verifier la disponibilite
128
+ flowkode domains check monsite.com
129
+
130
+ # Acheter un domaine
131
+ flowkode domains purchase monsite.com --registrar internetbs --years 2
132
+
133
+ # Synchroniser depuis les registrars
134
+ flowkode domains sync
135
+
136
+ # Associer un domaine a un projet
137
+ flowkode domains associate <domain-id> --project <project-id>
138
+
139
+ # Dissocier
140
+ flowkode domains dissociate <domain-id>
141
+
142
+ # Configurer les DNS
143
+ flowkode domains dns <domain-id>
144
+
145
+ # Verifier la propagation DNS
146
+ flowkode domains propagation <domain-id>
147
+
148
+ # Modifier (dossier)
149
+ flowkode domains update <id> --folder <folder-id>
150
+
151
+ # Supprimer
152
+ flowkode domains delete <id>
153
+ ```
154
+
155
+ ### Dossiers
156
+
157
+ ```bash
158
+ # Lister les dossiers
159
+ flowkode folders list
160
+
161
+ # Creer un dossier
162
+ flowkode folders create --name "Clients 2026" --color blue
163
+
164
+ # Modifier
165
+ flowkode folders update <id> --name "Nouveau nom" --color green --position 0
166
+
167
+ # Supprimer
168
+ flowkode folders delete <id>
169
+ ```
170
+
171
+ ### Blog
172
+
173
+ ```bash
174
+ # Lister les articles
175
+ flowkode blog list
176
+ flowkode blog list --project <id> --status published
177
+
178
+ # Detail d'un article
179
+ flowkode blog get <article-id>
180
+
181
+ # Generer des articles par mots-cles
182
+ flowkode blog generate <project-id> --keywords "react" "nextjs" "typescript"
183
+ flowkode blog generate <project-id> --keywords "seo" --auto-publish
184
+
185
+ # Indexation Google
186
+ flowkode blog indexing <article-id>
187
+ flowkode blog indexing-check <article-id>
188
+ flowkode blog indexing-submit <article-id>
189
+ ```
190
+
191
+ ### Formulaires de contact
192
+
193
+ ```bash
194
+ flowkode contact-forms
195
+ flowkode contact-forms --category devis
196
+ ```
197
+
198
+ ### Modeles IA
199
+
200
+ ```bash
201
+ flowkode ai-models
202
+ flowkode ai-models --category generation
203
+ ```
204
+
205
+ ### Mentions legales
206
+
207
+ ```bash
208
+ flowkode legal-notices
209
+ ```
210
+
211
+ ### Affiliation
212
+
213
+ ```bash
214
+ flowkode affiliation list
215
+ flowkode affiliation get <id>
216
+ ```
217
+
218
+ ### Google Search Console
219
+
220
+ ```bash
221
+ # Comptes connectes
222
+ flowkode search-console accounts
223
+
224
+ # Enregistrer un site
225
+ flowkode search-console add-site <project-id>
226
+
227
+ # Statut
228
+ flowkode search-console status <project-id>
229
+
230
+ # Soumettre le sitemap
231
+ flowkode search-console submit-sitemap <project-id>
232
+ ```
233
+
234
+ ## Options globales
235
+
236
+ | Option | Description |
237
+ |--------|-------------|
238
+ | `--json` | Sortie en JSON brut (utile pour scripts et CI/CD) |
239
+ | `--version` | Afficher la version |
240
+ | `--help` | Afficher l'aide |
241
+
242
+ ```bash
243
+ # Sortie JSON pour integration dans un script
244
+ flowkode --json projects list
245
+
246
+ # Pipe avec jq
247
+ flowkode --json projects list | jq '.data[].name'
248
+ ```
249
+
250
+ ## Utilisation dans un CI/CD
251
+
252
+ ```yaml
253
+ # GitHub Actions
254
+ - name: Deploy site
255
+ env:
256
+ FLOWKODE_API_KEY: ${{ secrets.FLOWKODE_API_KEY }}
257
+ run: |
258
+ npx @flowkode/cli projects deploy $PROJECT_ID --provider vercel
259
+ ```
260
+
261
+ ## Workflow type
262
+
263
+ ```bash
264
+ # 1. Creer un projet
265
+ flowkode projects create -n "Mon site" -t vitrine -k "web,dev" -l fr
266
+ # => { "jobId": "abc-123", "status": "pending" }
267
+
268
+ # 2. Suivre la generation
269
+ flowkode jobs get abc-123
270
+ # => status: "completed", project_id: "def-456"
271
+
272
+ # 3. Deployer
273
+ flowkode projects deploy def-456 --provider vercel
274
+
275
+ # 4. Acheter et associer un domaine
276
+ flowkode domains check monsite.com
277
+ flowkode domains purchase monsite.com --registrar ovh
278
+ flowkode domains sync
279
+ flowkode domains associate <domain-id> --project def-456
280
+ flowkode domains dns <domain-id>
281
+
282
+ # 5. Generer du contenu blog
283
+ flowkode blog generate def-456 --keywords "react" "nextjs" --auto-publish
284
+
285
+ # 6. Soumettre a Google
286
+ flowkode search-console add-site def-456
287
+ flowkode search-console submit-sitemap def-456
288
+ ```
289
+
290
+ ## Developpement
291
+
292
+ ```bash
293
+ cd flowkode-cli
294
+ npm install
295
+ npm run build
296
+
297
+ # Mode dev
298
+ FLOWKODE_API_KEY=ws_live_... npm run dev -- projects list
299
+ ```
@@ -0,0 +1,11 @@
1
+ export declare class FlowkodeApiClient {
2
+ private baseUrl;
3
+ private apiKey;
4
+ constructor(baseUrl: string, apiKey: string);
5
+ private headers;
6
+ get(path: string, params?: Record<string, string | undefined>): Promise<unknown>;
7
+ post(path: string, body?: unknown): Promise<unknown>;
8
+ patch(path: string, body: unknown): Promise<unknown>;
9
+ delete(path: string): Promise<unknown>;
10
+ private handleResponse;
11
+ }
@@ -0,0 +1,65 @@
1
+ export class FlowkodeApiClient {
2
+ baseUrl;
3
+ apiKey;
4
+ constructor(baseUrl, apiKey) {
5
+ this.baseUrl = baseUrl.replace(/\/$/, "");
6
+ this.apiKey = apiKey;
7
+ }
8
+ headers() {
9
+ return {
10
+ Authorization: `Bearer ${this.apiKey}`,
11
+ "Content-Type": "application/json",
12
+ };
13
+ }
14
+ async get(path, params) {
15
+ const url = new URL(`${this.baseUrl}/api/v1${path}`);
16
+ if (params) {
17
+ for (const [key, value] of Object.entries(params)) {
18
+ if (value !== undefined)
19
+ url.searchParams.set(key, value);
20
+ }
21
+ }
22
+ const res = await fetch(url.toString(), { headers: this.headers() });
23
+ return this.handleResponse(res);
24
+ }
25
+ async post(path, body) {
26
+ const res = await fetch(`${this.baseUrl}/api/v1${path}`, {
27
+ method: "POST",
28
+ headers: this.headers(),
29
+ body: body ? JSON.stringify(body) : undefined,
30
+ });
31
+ return this.handleResponse(res);
32
+ }
33
+ async patch(path, body) {
34
+ const res = await fetch(`${this.baseUrl}/api/v1${path}`, {
35
+ method: "PATCH",
36
+ headers: this.headers(),
37
+ body: JSON.stringify(body),
38
+ });
39
+ return this.handleResponse(res);
40
+ }
41
+ async delete(path) {
42
+ const res = await fetch(`${this.baseUrl}/api/v1${path}`, {
43
+ method: "DELETE",
44
+ headers: this.headers(),
45
+ });
46
+ return this.handleResponse(res);
47
+ }
48
+ async handleResponse(res) {
49
+ const text = await res.text();
50
+ let data;
51
+ try {
52
+ data = JSON.parse(text);
53
+ }
54
+ catch {
55
+ data = { raw: text };
56
+ }
57
+ if (!res.ok) {
58
+ const errorMsg = typeof data === "object" && data !== null && "error" in data
59
+ ? data.error
60
+ : `HTTP ${res.status}`;
61
+ throw new Error(errorMsg);
62
+ }
63
+ return data;
64
+ }
65
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ import type { FlowkodeApiClient } from "../api-client.js";
3
+ export declare function blogCommand(api: FlowkodeApiClient): Command;
@@ -0,0 +1,96 @@
1
+ import { Command } from "commander";
2
+ import { printTable, printSuccess, printError, printJson, } from "../output.js";
3
+ export function blogCommand(api) {
4
+ const cmd = new Command("blog").description("Gerer les articles de blog");
5
+ cmd
6
+ .command("list")
7
+ .description("Lister les articles")
8
+ .option("--project <id>", "Filtrer par projet")
9
+ .option("-s, --status <status>", "Filtrer (pending, queued, running, generated, scheduled, published, error)")
10
+ .action(async (opts) => {
11
+ try {
12
+ const res = (await api.get("/blog/articles", {
13
+ projectId: opts.project,
14
+ status: opts.status,
15
+ }));
16
+ printTable(res.data, [
17
+ { key: "id", label: "ID", width: 36 },
18
+ { key: "title", label: "Titre", width: 35 },
19
+ { key: "keyword", label: "Mot-cle", width: 20 },
20
+ { key: "status", label: "Statut", width: 12 },
21
+ ]);
22
+ }
23
+ catch (e) {
24
+ printError(e);
25
+ }
26
+ });
27
+ cmd
28
+ .command("get <articleId>")
29
+ .description("Detail d'un article")
30
+ .action(async (articleId) => {
31
+ try {
32
+ const res = await api.get(`/blog/articles/${articleId}`);
33
+ printJson(res);
34
+ }
35
+ catch (e) {
36
+ printError(e);
37
+ }
38
+ });
39
+ cmd
40
+ .command("generate <projectId>")
41
+ .description("Generer des articles par mots-cles")
42
+ .requiredOption("-k, --keywords <keywords...>", "Mots-cles (un ou plusieurs)")
43
+ .option("--auto-publish", "Publier automatiquement")
44
+ .action(async (projectId, opts) => {
45
+ try {
46
+ const res = await api.post(`/projects/${projectId}/blog/articles`, {
47
+ keywords: opts.keywords,
48
+ auto_publish: opts.autoPublish ?? false,
49
+ });
50
+ printJson(res);
51
+ printSuccess("Generation d'articles lancee.");
52
+ }
53
+ catch (e) {
54
+ printError(e);
55
+ }
56
+ });
57
+ cmd
58
+ .command("indexing <articleId>")
59
+ .description("Statut d'indexation Google d'un article")
60
+ .action(async (articleId) => {
61
+ try {
62
+ const res = await api.get(`/blog/articles/${articleId}/indexing`);
63
+ printJson(res);
64
+ }
65
+ catch (e) {
66
+ printError(e);
67
+ }
68
+ });
69
+ cmd
70
+ .command("indexing-check <articleId>")
71
+ .description("Verifier l'indexation d'un article")
72
+ .action(async (articleId) => {
73
+ try {
74
+ const res = await api.post(`/blog/articles/${articleId}/indexing/check`);
75
+ printJson(res);
76
+ printSuccess("Verification lancee.");
77
+ }
78
+ catch (e) {
79
+ printError(e);
80
+ }
81
+ });
82
+ cmd
83
+ .command("indexing-submit <articleId>")
84
+ .description("Soumettre un article pour indexation Google")
85
+ .action(async (articleId) => {
86
+ try {
87
+ const res = await api.post(`/blog/articles/${articleId}/indexing/submit`);
88
+ printJson(res);
89
+ printSuccess("Article soumis pour indexation.");
90
+ }
91
+ catch (e) {
92
+ printError(e);
93
+ }
94
+ });
95
+ return cmd;
96
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function configCommand(): Command;
@@ -0,0 +1,37 @@
1
+ import { Command } from "commander";
2
+ import { loadConfig, saveConfig } from "../config.js";
3
+ import { printSuccess, printDetail } from "../output.js";
4
+ export function configCommand() {
5
+ const cmd = new Command("config").description("Configurer la cle API et l'URL de base");
6
+ cmd
7
+ .option("-k, --api-key <key>", "Cle API Flowkode (ws_live_...)")
8
+ .option("-u, --base-url <url>", "URL de base de l'API")
9
+ .option("--show", "Afficher la configuration actuelle")
10
+ .action((opts) => {
11
+ if (opts.show) {
12
+ const config = loadConfig();
13
+ printDetail({
14
+ api_key: config.api_key
15
+ ? `${config.api_key.slice(0, 12)}...`
16
+ : undefined,
17
+ base_url: config.base_url,
18
+ }, [
19
+ { key: "api_key", label: "API Key" },
20
+ { key: "base_url", label: "Base URL" },
21
+ ]);
22
+ return;
23
+ }
24
+ const config = loadConfig();
25
+ if (opts.apiKey)
26
+ config.api_key = opts.apiKey;
27
+ if (opts.baseUrl)
28
+ config.base_url = opts.baseUrl;
29
+ if (!opts.apiKey && !opts.baseUrl) {
30
+ cmd.help();
31
+ return;
32
+ }
33
+ saveConfig(config);
34
+ printSuccess("Configuration saved to ~/.flowkode/config.json");
35
+ });
36
+ return cmd;
37
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ import type { FlowkodeApiClient } from "../api-client.js";
3
+ export declare function deploymentsCommand(api: FlowkodeApiClient): Command;
@@ -0,0 +1,51 @@
1
+ import { Command } from "commander";
2
+ import { printTable, printDetail, printError } from "../output.js";
3
+ export function deploymentsCommand(api) {
4
+ const cmd = new Command("deployments").description("Gerer les deploiements");
5
+ cmd
6
+ .command("list")
7
+ .description("Lister les deploiements")
8
+ .option("--project <id>", "Filtrer par projet")
9
+ .option("--provider <provider>", "Filtrer (vercel, cloudflare)")
10
+ .option("-s, --status <status>", "Filtrer (pending, building, ready, error, canceled)")
11
+ .action(async (opts) => {
12
+ try {
13
+ const res = (await api.get("/deployments", {
14
+ project_id: opts.project,
15
+ provider: opts.provider,
16
+ status: opts.status,
17
+ }));
18
+ printTable(res.data, [
19
+ { key: "id", label: "ID", width: 36 },
20
+ { key: "project_name", label: "Projet", width: 25 },
21
+ { key: "provider", label: "Provider", width: 12 },
22
+ { key: "status", label: "Statut", width: 10 },
23
+ { key: "url", label: "URL", width: 40 },
24
+ ]);
25
+ }
26
+ catch (e) {
27
+ printError(e);
28
+ }
29
+ });
30
+ cmd
31
+ .command("get <id>")
32
+ .description("Detail d'un deploiement")
33
+ .action(async (id) => {
34
+ try {
35
+ const res = (await api.get(`/deployments/${id}`));
36
+ printDetail(res.data, [
37
+ { key: "id", label: "ID" },
38
+ { key: "project_name", label: "Projet" },
39
+ { key: "provider", label: "Provider" },
40
+ { key: "status", label: "Statut" },
41
+ { key: "url", label: "URL" },
42
+ { key: "error_message", label: "Erreur" },
43
+ { key: "created_at", label: "Cree le" },
44
+ ]);
45
+ }
46
+ catch (e) {
47
+ printError(e);
48
+ }
49
+ });
50
+ return cmd;
51
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ import type { FlowkodeApiClient } from "../api-client.js";
3
+ export declare function domainsCommand(api: FlowkodeApiClient): Command;