@curenorway/kode-cli 1.12.0 → 1.13.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 +51 -11
- package/dist/{chunk-XU4YS3JQ.js → chunk-C2BM7IJ6.js} +63 -15
- package/dist/cli.js +13 -3
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,12 +4,14 @@ Command-line tool for managing JavaScript and CSS scripts for Webflow sites via
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Pull/Push scripts** - Sync scripts between local files and remote CDN
|
|
7
|
+
- **Pull/Push scripts** - Sync scripts between local files and remote CDN with conflict detection
|
|
8
|
+
- **Sync awareness** - Staleness indicators show when local state is out of date
|
|
9
|
+
- **Deploy dry-run** - Preview what will be deployed before executing
|
|
10
|
+
- **Doctor command** - Diagnose configuration issues and check for CLI updates
|
|
8
11
|
- **Watch mode** - Auto-sync on file changes with retry on failure
|
|
9
12
|
- **Staging/Production** - Separate environments with explicit production enable
|
|
10
13
|
- **Rollback** - Quick recovery to previous deployments
|
|
11
|
-
- **AI
|
|
12
|
-
- **Page Context Caching** - Save page structures for AI development
|
|
14
|
+
- **AI-ready** - Auto-generates KODE.md documentation for AI agents
|
|
13
15
|
- **MCP Integration** - Works with Cure Kode MCP for AI agents
|
|
14
16
|
|
|
15
17
|
## Installation
|
|
@@ -53,9 +55,10 @@ kode init
|
|
|
53
55
|
|
|
54
56
|
Creates:
|
|
55
57
|
- `.cure-kode/config.json` - Site configuration and API key
|
|
58
|
+
- `.cure-kode/KODE.md` - Auto-generated documentation (scripts, pages, commands)
|
|
56
59
|
- `.cure-kode/context.md` - AI context file
|
|
57
60
|
- `.cure-kode-scripts/` - Scripts directory
|
|
58
|
-
- `CLAUDE.md` -
|
|
61
|
+
- `CLAUDE.md` - Reference to KODE.md (prepended, never overwrites existing content)
|
|
59
62
|
- `.mcp.json` - MCP server configuration (cure-kode, webflow, playwright)
|
|
60
63
|
|
|
61
64
|
### `kode pull`
|
|
@@ -104,9 +107,9 @@ Deploy scripts to staging or production.
|
|
|
104
107
|
|
|
105
108
|
```bash
|
|
106
109
|
kode deploy # Deploy to staging (default)
|
|
110
|
+
kode deploy --dry-run # Preview deployment without executing
|
|
107
111
|
kode deploy --promote # Promote staging to production
|
|
108
112
|
kode deploy --force # Force release stale deploy lock
|
|
109
|
-
kode deploy -n "Release v2" # Deploy with notes
|
|
110
113
|
```
|
|
111
114
|
|
|
112
115
|
**Note:** Production must be enabled before promoting. See `kode production`.
|
|
@@ -165,7 +168,7 @@ kode context --json # Output as JSON
|
|
|
165
168
|
|
|
166
169
|
### `kode status`
|
|
167
170
|
|
|
168
|
-
Show current project status.
|
|
171
|
+
Show current project status with staleness indicators.
|
|
169
172
|
|
|
170
173
|
```bash
|
|
171
174
|
kode status
|
|
@@ -174,9 +177,44 @@ kode status
|
|
|
174
177
|
Shows:
|
|
175
178
|
- Site info and CDN URL
|
|
176
179
|
- Production enabled state
|
|
177
|
-
- Script sync status
|
|
180
|
+
- Script sync status with staleness warnings
|
|
181
|
+
- Per-script indicators: modified locally, server updated, conflicts
|
|
178
182
|
- Deployment versions
|
|
179
183
|
|
|
184
|
+
### `kode doctor`
|
|
185
|
+
|
|
186
|
+
Diagnose configuration and environment issues.
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
kode doctor
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Checks:
|
|
193
|
+
- Project configuration and API key validity
|
|
194
|
+
- Network connectivity and API access
|
|
195
|
+
- MCP server configuration
|
|
196
|
+
- KODE.md and CLAUDE.md setup
|
|
197
|
+
- Security (.gitignore for API key)
|
|
198
|
+
- Sync state staleness
|
|
199
|
+
- CLI version and available updates
|
|
200
|
+
|
|
201
|
+
### `kode diff <script>`
|
|
202
|
+
|
|
203
|
+
Show differences between local and remote script versions.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
kode diff my-script # Compare local vs remote
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### `kode sync`
|
|
210
|
+
|
|
211
|
+
Bidirectional sync with conflict detection.
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
kode sync # Sync both directions
|
|
215
|
+
kode sync --dry-run # Preview what would change
|
|
216
|
+
```
|
|
217
|
+
|
|
180
218
|
## Configuration
|
|
181
219
|
|
|
182
220
|
### Project Config (`.cure-kode/config.json`)
|
|
@@ -206,15 +244,17 @@ Default: `.cure-kode-scripts/` (avoids conflicts with AI-generated `scripts/` fo
|
|
|
206
244
|
```
|
|
207
245
|
your-project/
|
|
208
246
|
├── .cure-kode/
|
|
209
|
-
│ ├── config.json # Project configuration
|
|
247
|
+
│ ├── config.json # Project configuration (gitignored)
|
|
248
|
+
│ ├── scripts.json # Sync state for conflict detection
|
|
249
|
+
│ ├── KODE.md # Auto-generated documentation
|
|
210
250
|
│ ├── context.md # AI context (notes, discoveries)
|
|
211
251
|
│ └── pages/ # Cached page contexts
|
|
212
252
|
├── .cure-kode-scripts/ # Your scripts directory
|
|
213
|
-
│ ├──
|
|
214
|
-
│ ├──
|
|
253
|
+
│ ├── main.js
|
|
254
|
+
│ ├── form-handler.js
|
|
215
255
|
│ └── styles.css
|
|
216
256
|
├── .mcp.json # MCP server configuration
|
|
217
|
-
└── CLAUDE.md #
|
|
257
|
+
└── CLAUDE.md # Reference to KODE.md (your content preserved)
|
|
218
258
|
```
|
|
219
259
|
|
|
220
260
|
## Workflow Examples
|
|
@@ -1201,7 +1201,7 @@ Option C: Full rollback
|
|
|
1201
1201
|
}
|
|
1202
1202
|
|
|
1203
1203
|
// src/version.ts
|
|
1204
|
-
var CLI_VERSION = "1.12.
|
|
1204
|
+
var CLI_VERSION = "1.12.1";
|
|
1205
1205
|
|
|
1206
1206
|
// src/commands/init.ts
|
|
1207
1207
|
import chalk from "chalk";
|
|
@@ -1288,6 +1288,29 @@ Page-specific scripts only load when URL matches these patterns:
|
|
|
1288
1288
|
`;
|
|
1289
1289
|
}
|
|
1290
1290
|
md += `
|
|
1291
|
+
`;
|
|
1292
|
+
}
|
|
1293
|
+
const pageSpecificScripts = scripts.filter(
|
|
1294
|
+
(s) => s.scope === "page-specific" && s.pageAssignments && s.pageAssignments.length > 0
|
|
1295
|
+
);
|
|
1296
|
+
if (pageSpecificScripts.length > 0) {
|
|
1297
|
+
md += `---
|
|
1298
|
+
|
|
1299
|
+
## Script \u2192 Page Assignments
|
|
1300
|
+
|
|
1301
|
+
| Script | Pages |
|
|
1302
|
+
|--------|-------|
|
|
1303
|
+
`;
|
|
1304
|
+
for (const script of pageSpecificScripts) {
|
|
1305
|
+
const pageList = script.pageAssignments.map((pa) => {
|
|
1306
|
+
const page = pages.find((p) => p.slug === pa.pageSlug);
|
|
1307
|
+
const patterns = page ? ` (\`${page.patterns.join("`, `")}\`)` : "";
|
|
1308
|
+
return `\`${pa.pageSlug}\`${patterns}`;
|
|
1309
|
+
}).join(", ");
|
|
1310
|
+
md += `| \`${script.slug}\` | ${pageList} |
|
|
1311
|
+
`;
|
|
1312
|
+
}
|
|
1313
|
+
md += `
|
|
1291
1314
|
`;
|
|
1292
1315
|
}
|
|
1293
1316
|
md += `---
|
|
@@ -1383,15 +1406,22 @@ function updateKodeDocs(projectRoot, siteName, siteSlug, scripts, pages) {
|
|
|
1383
1406
|
const claudeMd = ensureClaudeMdReference(projectRoot);
|
|
1384
1407
|
return { kodeMd, claudeMd };
|
|
1385
1408
|
}
|
|
1386
|
-
function scriptsToDocsFormat(scripts) {
|
|
1387
|
-
return scripts.map((s) =>
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1409
|
+
function scriptsToDocsFormat(scripts, pages) {
|
|
1410
|
+
return scripts.map((s) => {
|
|
1411
|
+
const pageAssignments = (s.pages || []).filter((p) => p.is_enabled).map((p) => {
|
|
1412
|
+
const page = pages?.find((pg) => pg.id === p.page_id);
|
|
1413
|
+
return page ? { pageId: page.id, pageSlug: page.slug, pageName: page.name } : null;
|
|
1414
|
+
}).filter((p) => p !== null);
|
|
1415
|
+
return {
|
|
1416
|
+
slug: s.slug,
|
|
1417
|
+
name: s.name,
|
|
1418
|
+
type: s.type,
|
|
1419
|
+
scope: s.scope,
|
|
1420
|
+
autoLoad: s.auto_load,
|
|
1421
|
+
purpose: s.metadata?.purpose || s.description,
|
|
1422
|
+
pageAssignments: pageAssignments.length > 0 ? pageAssignments : void 0
|
|
1423
|
+
};
|
|
1424
|
+
});
|
|
1395
1425
|
}
|
|
1396
1426
|
function pagesToInfoFormat(pages) {
|
|
1397
1427
|
return pages.filter((p) => p.is_active).map((p) => ({
|
|
@@ -1584,7 +1614,7 @@ config.json
|
|
|
1584
1614
|
cwd,
|
|
1585
1615
|
config.siteName,
|
|
1586
1616
|
config.siteSlug,
|
|
1587
|
-
scriptsToDocsFormat(scripts),
|
|
1617
|
+
scriptsToDocsFormat(scripts, pages),
|
|
1588
1618
|
pagesToInfoFormat(pages)
|
|
1589
1619
|
);
|
|
1590
1620
|
const siteInfo = {
|
|
@@ -2034,10 +2064,19 @@ Fant ikke skript "${options.script}".`));
|
|
|
2034
2064
|
if (skipped > 0) {
|
|
2035
2065
|
console.log(chalk2.dim(`Hoppet over ${skipped} skript`));
|
|
2036
2066
|
}
|
|
2067
|
+
let pages = [];
|
|
2068
|
+
try {
|
|
2069
|
+
pages = await client.listPages(config.siteId);
|
|
2070
|
+
} catch {
|
|
2071
|
+
}
|
|
2037
2072
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2038
2073
|
const metadata = scripts.map((s) => {
|
|
2039
2074
|
const filePath = join5(scriptsDir, `${s.slug}.${s.type === "javascript" ? "js" : "css"}`);
|
|
2040
2075
|
const localContent = existsSync5(filePath) ? readFileSync5(filePath, "utf-8") : s.content;
|
|
2076
|
+
const pageAssignments = (s.pages || []).filter((p) => p.is_enabled).map((p) => {
|
|
2077
|
+
const page = pages.find((pg) => pg.id === p.page_id);
|
|
2078
|
+
return page ? { pageId: page.id, pageSlug: page.slug, pageName: page.name } : null;
|
|
2079
|
+
}).filter((p) => p !== null);
|
|
2041
2080
|
return {
|
|
2042
2081
|
id: s.id,
|
|
2043
2082
|
slug: s.slug,
|
|
@@ -2047,6 +2086,7 @@ Fant ikke skript "${options.script}".`));
|
|
|
2047
2086
|
autoLoad: s.auto_load,
|
|
2048
2087
|
version: s.current_version,
|
|
2049
2088
|
loadOrder: s.load_order,
|
|
2089
|
+
pageAssignments: pageAssignments.length > 0 ? pageAssignments : void 0,
|
|
2050
2090
|
lastPulledVersion: s.current_version,
|
|
2051
2091
|
lastPulledAt: now,
|
|
2052
2092
|
contentHash: hashContent(localContent)
|
|
@@ -2054,12 +2094,11 @@ Fant ikke skript "${options.script}".`));
|
|
|
2054
2094
|
});
|
|
2055
2095
|
writeFileSync5(metadataPath, JSON.stringify(metadata, null, 2));
|
|
2056
2096
|
try {
|
|
2057
|
-
const pages = await client.listPages(config.siteId);
|
|
2058
2097
|
const result = updateClaudeMd(
|
|
2059
2098
|
projectRoot,
|
|
2060
2099
|
config.siteName,
|
|
2061
2100
|
config.siteSlug,
|
|
2062
|
-
scriptsToDocsFormat(scripts),
|
|
2101
|
+
scriptsToDocsFormat(scripts, pages),
|
|
2063
2102
|
pagesToInfoFormat(pages)
|
|
2064
2103
|
);
|
|
2065
2104
|
if (result.kodeMd.created) {
|
|
@@ -2233,12 +2272,21 @@ ${conflicts} skript med konflikter (bruk --force for \xE5 overskrive)`));
|
|
|
2233
2272
|
${emptyScriptCount} tomme skript lastet opp`));
|
|
2234
2273
|
console.log(chalk3.dim("Tomme skript har ingen effekt ved deploy."));
|
|
2235
2274
|
}
|
|
2275
|
+
let pages = [];
|
|
2276
|
+
try {
|
|
2277
|
+
pages = await client.listPages(config.siteId);
|
|
2278
|
+
} catch {
|
|
2279
|
+
}
|
|
2236
2280
|
const updatedScripts = await client.listScripts(config.siteId);
|
|
2237
2281
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2238
2282
|
const updatedMetadata = updatedScripts.map((s) => {
|
|
2239
2283
|
const ext = s.type === "javascript" ? "js" : "css";
|
|
2240
2284
|
const filePath = join6(scriptsDir, `${s.slug}.${ext}`);
|
|
2241
2285
|
const localContent = existsSync6(filePath) ? readFileSync6(filePath, "utf-8") : s.content;
|
|
2286
|
+
const pageAssignments = (s.pages || []).filter((p) => p.is_enabled).map((p) => {
|
|
2287
|
+
const page = pages.find((pg) => pg.id === p.page_id);
|
|
2288
|
+
return page ? { pageId: page.id, pageSlug: page.slug, pageName: page.name } : null;
|
|
2289
|
+
}).filter((p) => p !== null);
|
|
2242
2290
|
return {
|
|
2243
2291
|
id: s.id,
|
|
2244
2292
|
slug: s.slug,
|
|
@@ -2248,6 +2296,7 @@ ${emptyScriptCount} tomme skript lastet opp`));
|
|
|
2248
2296
|
autoLoad: s.auto_load,
|
|
2249
2297
|
version: s.current_version,
|
|
2250
2298
|
loadOrder: s.load_order,
|
|
2299
|
+
pageAssignments: pageAssignments.length > 0 ? pageAssignments : void 0,
|
|
2251
2300
|
lastPulledVersion: s.current_version,
|
|
2252
2301
|
lastPulledAt: now,
|
|
2253
2302
|
contentHash: hashContent2(localContent)
|
|
@@ -2255,12 +2304,11 @@ ${emptyScriptCount} tomme skript lastet opp`));
|
|
|
2255
2304
|
});
|
|
2256
2305
|
writeFileSync6(metadataPath, JSON.stringify(updatedMetadata, null, 2));
|
|
2257
2306
|
try {
|
|
2258
|
-
const pages = await client.listPages(config.siteId);
|
|
2259
2307
|
const result = updateClaudeMd(
|
|
2260
2308
|
projectRoot,
|
|
2261
2309
|
config.siteName,
|
|
2262
2310
|
config.siteSlug,
|
|
2263
|
-
scriptsToDocsFormat(updatedScripts),
|
|
2311
|
+
scriptsToDocsFormat(updatedScripts, pages),
|
|
2264
2312
|
pagesToInfoFormat(pages)
|
|
2265
2313
|
);
|
|
2266
2314
|
if (result.kodeMd.created) {
|
package/dist/cli.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
updateClaudeMd,
|
|
22
22
|
updateKodeDocs,
|
|
23
23
|
watchCommand
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-C2BM7IJ6.js";
|
|
25
25
|
|
|
26
26
|
// src/cli.ts
|
|
27
27
|
import { Command } from "commander";
|
|
@@ -65,7 +65,7 @@ async function upgradeCommand() {
|
|
|
65
65
|
projectRoot,
|
|
66
66
|
config.siteName,
|
|
67
67
|
config.siteSlug,
|
|
68
|
-
scriptsToDocsFormat(scripts),
|
|
68
|
+
scriptsToDocsFormat(scripts, pages),
|
|
69
69
|
pagesToInfoFormat(pages)
|
|
70
70
|
);
|
|
71
71
|
if (result.kodeMd.created) {
|
|
@@ -845,7 +845,7 @@ async function updateClaudeMdCommand() {
|
|
|
845
845
|
projectRoot,
|
|
846
846
|
config.siteName,
|
|
847
847
|
config.siteSlug,
|
|
848
|
-
scriptsToDocsFormat(scripts),
|
|
848
|
+
scriptsToDocsFormat(scripts, pages),
|
|
849
849
|
pagesToInfoFormat(pages)
|
|
850
850
|
);
|
|
851
851
|
if (result.kodeMd.created) {
|
|
@@ -1077,11 +1077,20 @@ async function syncCommand(options) {
|
|
|
1077
1077
|
console.log(chalk7.dim(' Bruk "kode pull --force <script>" for \xE5 overskrive lokalt'));
|
|
1078
1078
|
}
|
|
1079
1079
|
const updatedScripts = await client.listScripts(config.siteId);
|
|
1080
|
+
let pages = [];
|
|
1081
|
+
try {
|
|
1082
|
+
pages = await client.listPages(config.siteId);
|
|
1083
|
+
} catch {
|
|
1084
|
+
}
|
|
1080
1085
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1081
1086
|
const updatedMetadata = updatedScripts.map((s) => {
|
|
1082
1087
|
const ext = s.type === "javascript" ? "js" : "css";
|
|
1083
1088
|
const filePath = join2(scriptsDir, `${s.slug}.${ext}`);
|
|
1084
1089
|
const localContent = existsSync2(filePath) ? readFileSync2(filePath, "utf-8") : s.content;
|
|
1090
|
+
const pageAssignments = (s.pages || []).filter((p) => p.is_enabled).map((p) => {
|
|
1091
|
+
const page = pages.find((pg) => pg.id === p.page_id);
|
|
1092
|
+
return page ? { pageId: page.id, pageSlug: page.slug, pageName: page.name } : null;
|
|
1093
|
+
}).filter((p) => p !== null);
|
|
1085
1094
|
return {
|
|
1086
1095
|
id: s.id,
|
|
1087
1096
|
slug: s.slug,
|
|
@@ -1091,6 +1100,7 @@ async function syncCommand(options) {
|
|
|
1091
1100
|
autoLoad: s.auto_load,
|
|
1092
1101
|
version: s.current_version,
|
|
1093
1102
|
loadOrder: s.load_order,
|
|
1103
|
+
pageAssignments: pageAssignments.length > 0 ? pageAssignments : void 0,
|
|
1094
1104
|
lastPulledVersion: s.current_version,
|
|
1095
1105
|
lastPulledAt: now,
|
|
1096
1106
|
contentHash: hashContent(localContent)
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED