@curenorway/kode-cli 1.15.2 → 1.16.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.
package/README.md CHANGED
@@ -61,6 +61,8 @@ Creates:
61
61
  - `.cure-kode-scripts/` - Scripts directory
62
62
  - `CLAUDE.md` - Reference to KODE.md (prepended, never overwrites existing content)
63
63
  - `.mcp.json` - MCP server configuration (cure-kode, webflow, playwright)
64
+ - `.claude/skills/deploy/` - `/deploy` slash command for Claude Code
65
+ - `.claude/skills/webflow-patterns/` - Webflow DOM reference (auto-loaded by Claude when relevant)
64
66
 
65
67
  Automatically registers and injects init.js into the Webflow site's `<head>` via the Custom Code API. If injection fails, it falls back to showing the manual embed code.
66
68
 
@@ -265,6 +267,9 @@ Default: `.cure-kode-scripts/` (avoids conflicts with AI-generated `scripts/` fo
265
267
 
266
268
  ```
267
269
  your-project/
270
+ ├── .claude/skills/ # Claude Code skills
271
+ │ ├── deploy/ # /deploy — push and deploy workflow
272
+ │ └── webflow-patterns/ # Auto-loaded Webflow DOM reference
268
273
  ├── .cure-kode/
269
274
  │ ├── config.json # Project configuration (gitignored)
270
275
  │ ├── scripts.json # Sync state for conflict detection
@@ -279,6 +284,29 @@ your-project/
279
284
  └── CLAUDE.md # Reference to KODE.md (your content preserved)
280
285
  ```
281
286
 
287
+ ## Claude Code Skills
288
+
289
+ `kode init` generates two Claude Code skills in `.claude/skills/`:
290
+
291
+ ### `/deploy`
292
+
293
+ Type `/deploy` in Claude Code to push and deploy to staging. Add `--promote` to promote to production.
294
+
295
+ Both you and Claude can use this — Claude will also invoke it when it finishes making changes and needs to publish them.
296
+
297
+ ### `webflow-patterns` (auto-loaded)
298
+
299
+ Background knowledge about Webflow DOM structure, reliable selectors, component patterns, and common pitfalls. Claude loads this automatically when writing or debugging Webflow scripts — it doesn't appear in the `/` menu.
300
+
301
+ Includes:
302
+ - Reliable vs unreliable CSS selectors for Webflow
303
+ - DOM-ready patterns with Webflow's IX2 engine
304
+ - Component reference (Navbar, Tabs, Slider, Dropdown, CMS lists, Forms)
305
+ - CSS specificity rules with Webflow's stylesheet
306
+ - Cure Kode script loading order and `window.CK` API
307
+
308
+ The detailed reference lives in `webflow-patterns/reference.md` — Claude reads it when it needs specifics.
309
+
282
310
  ## Workflow Examples
283
311
 
284
312
  ### Basic Development
@@ -1201,14 +1201,14 @@ Option C: Full rollback
1201
1201
  }
1202
1202
 
1203
1203
  // src/version.ts
1204
- var CLI_VERSION = "1.15.2";
1204
+ var CLI_VERSION = "1.16.1";
1205
1205
 
1206
1206
  // src/commands/init.ts
1207
1207
  import chalk from "chalk";
1208
1208
  import ora from "ora";
1209
1209
  import enquirer from "enquirer";
1210
- import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync4, readFileSync as readFileSync4 } from "fs";
1211
- import { join as join4 } from "path";
1210
+ import { existsSync as existsSync5, mkdirSync as mkdirSync3, writeFileSync as writeFileSync5, readFileSync as readFileSync5 } from "fs";
1211
+ import { join as join5 } from "path";
1212
1212
 
1213
1213
  // src/lib/claude-md.ts
1214
1214
  import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
@@ -1379,6 +1379,10 @@ AI agents can use these tools directly:
1379
1379
  \u251C\u2500\u2500 main.js
1380
1380
  \u251C\u2500\u2500 form-handler.js
1381
1381
  \u2514\u2500\u2500 ...
1382
+
1383
+ .claude/skills/ # Claude Code skills
1384
+ \u251C\u2500\u2500 deploy/ # /deploy \u2014 push and deploy workflow
1385
+ \u2514\u2500\u2500 webflow-patterns/ # Auto-loaded Webflow DOM reference
1382
1386
  \`\`\`
1383
1387
  `;
1384
1388
  return md;
@@ -1435,6 +1439,324 @@ function pagesToInfoFormat(pages) {
1435
1439
  }
1436
1440
  var updateClaudeMd = updateKodeDocs;
1437
1441
 
1442
+ // src/lib/skills.ts
1443
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync4 } from "fs";
1444
+ import { join as join4 } from "path";
1445
+ function generateSkills(projectRoot, siteSlug) {
1446
+ const skillsDir = join4(projectRoot, ".claude", "skills");
1447
+ const created = [];
1448
+ const skipped = [];
1449
+ const deployDir = join4(skillsDir, "deploy");
1450
+ const deployPath = join4(deployDir, "SKILL.md");
1451
+ if (!existsSync4(deployPath)) {
1452
+ mkdirSync2(deployDir, { recursive: true });
1453
+ writeFileSync4(deployPath, generateDeploySkill(siteSlug));
1454
+ created.push("deploy");
1455
+ } else {
1456
+ skipped.push("deploy");
1457
+ }
1458
+ const webflowDir = join4(skillsDir, "webflow-patterns");
1459
+ const webflowSkillPath = join4(webflowDir, "SKILL.md");
1460
+ const webflowRefPath = join4(webflowDir, "reference.md");
1461
+ if (!existsSync4(webflowSkillPath)) {
1462
+ mkdirSync2(webflowDir, { recursive: true });
1463
+ writeFileSync4(webflowSkillPath, WEBFLOW_SKILL);
1464
+ writeFileSync4(webflowRefPath, WEBFLOW_REFERENCE);
1465
+ created.push("webflow-patterns");
1466
+ } else {
1467
+ skipped.push("webflow-patterns");
1468
+ }
1469
+ return { created, skipped };
1470
+ }
1471
+ function generateDeploySkill(siteSlug) {
1472
+ return `---
1473
+ name: deploy
1474
+ description: Push and deploy Cure Kode scripts to staging or production. Use when the user says "deploy", "ship it", "push and deploy", or when you have finished making script changes and need to publish them.
1475
+ argument-hint: "[--promote]"
1476
+ ---
1477
+
1478
+ Deploy scripts for **${siteSlug}** to Cure Kode CDN.
1479
+
1480
+ ## Steps
1481
+
1482
+ 1. **Push** local changes to the server:
1483
+ \`\`\`bash
1484
+ kode push
1485
+ \`\`\`
1486
+ If there are no changes to push, continue to step 2.
1487
+
1488
+ 2. **Deploy** to staging:
1489
+ \`\`\`bash
1490
+ kode deploy
1491
+ \`\`\`
1492
+
1493
+ 3. **Verify** the deployment succeeded by checking the output.
1494
+
1495
+ 4. If \`$ARGUMENTS\` includes \`--promote\` or the user asked for production:
1496
+ \`\`\`bash
1497
+ kode deploy --promote
1498
+ \`\`\`
1499
+
1500
+ ## Important
1501
+
1502
+ - Always push before deploying \u2014 unpushed changes will not be included.
1503
+ - After deploying to staging, tell the user to test before promoting.
1504
+ - If deploy fails with a lock error, suggest \`kode deploy --force\` to release it.
1505
+ - After promoting to production, remind the user it may take a few seconds to propagate.
1506
+ `;
1507
+ }
1508
+ var WEBFLOW_SKILL = `---
1509
+ name: webflow-patterns
1510
+ description: Webflow DOM structure, reliable CSS selectors, component patterns, and common pitfalls for writing scripts that target Webflow sites. Use when writing or debugging JavaScript/CSS that runs on a Webflow site.
1511
+ user-invocable: false
1512
+ ---
1513
+
1514
+ # Webflow Development Patterns
1515
+
1516
+ Use these patterns when writing scripts for Webflow sites via Cure Kode.
1517
+
1518
+ ## Reliable selectors
1519
+
1520
+ - Use **custom classes** you add in Webflow Designer (e.g. \`.hero-section\`, \`.cta-button\`)
1521
+ - Use **\`data-\` attributes** added via custom attributes in Designer (e.g. \`[data-component="pricing"]\`)
1522
+ - Use **\`data-w-id\`** to target interaction-bound elements (stable across publishes)
1523
+ - Avoid \`.w-\` prefixed classes \u2014 these are Webflow internals and can change on publish
1524
+
1525
+ ## DOM ready pattern
1526
+
1527
+ Cure Kode's init.js loads with \`defer\`, so the DOM is ready when your scripts execute.
1528
+ For code that depends on Webflow's JS (interactions, tabs, sliders):
1529
+
1530
+ \`\`\`javascript
1531
+ // Safe: wait for Webflow's IX2 engine
1532
+ window.Webflow = window.Webflow || [];
1533
+ window.Webflow.push(function () {
1534
+ // Webflow JS is fully initialized here
1535
+ });
1536
+ \`\`\`
1537
+
1538
+ Do NOT use \`DOMContentLoaded\` \u2014 it fires before Webflow's interaction engine is ready.
1539
+
1540
+ ## Common Webflow components
1541
+
1542
+ | Component | Wrapper class | Key elements | Gotchas |
1543
+ |-----------|--------------|--------------|---------|
1544
+ | Navbar | \`.w-nav\` | \`.w-nav-menu\`, \`.w-nav-link\`, \`.w-nav-overlay\` | Mobile menu uses \`.w--open\` state class |
1545
+ | Tabs | \`.w-tabs\` | \`.w-tab-menu\`, \`.w-tab-link\`, \`.w-tab-pane\` | Don't add click handlers \u2014 Webflow manages state |
1546
+ | Slider | \`.w-slider\` | \`.w-slide\`, \`.w-slider-nav\` | Auto-play conflicts with custom navigation |
1547
+ | Dropdown | \`.w-dropdown\` | \`.w-dropdown-toggle\`, \`.w-dropdown-list\` | Opens on hover by default on desktop |
1548
+ | Lightbox | \`.w-lightbox\` | Created dynamically on click | No static DOM until opened |
1549
+ | Form | \`.w-form\` | \`.w-form-done\`, \`.w-form-fail\` | Webflow shows/hides done/fail divs |
1550
+ | CMS list | \`.w-dyn-items\` | \`.w-dyn-item\` | Paginated: not all items in DOM |
1551
+ | Rich text | \`.w-richtext\` | Nested \`h2-h6\`, \`p\`, \`img\`, \`ul/ol\` | Has opinionated default styles |
1552
+
1553
+ ## Key \`data-wf-*\` attributes
1554
+
1555
+ - \`data-wf-domain\` on \`<html>\` \u2014 the Webflow staging domain
1556
+ - \`data-wf-page\` on \`<html>\` \u2014 unique page identifier
1557
+ - \`data-wf-site\` on \`<html>\` \u2014 unique site identifier
1558
+
1559
+ ## For detailed patterns
1560
+
1561
+ See [reference.md](reference.md) for:
1562
+ - CMS collection list patterns and filtering
1563
+ - Form handling and validation
1564
+ - CSS specificity with Webflow's stylesheets
1565
+ - Animation and interaction scripting
1566
+ - Cure Kode script loading and execution order
1567
+ `;
1568
+ var WEBFLOW_REFERENCE = `# Webflow Patterns \u2014 Detailed Reference
1569
+
1570
+ ## CMS Collection Lists
1571
+
1572
+ Webflow CMS items render inside \`.w-dyn-items > .w-dyn-item\`. Key patterns:
1573
+
1574
+ \`\`\`javascript
1575
+ // Wait for CMS items to render
1576
+ function onCmsReady(listSelector, callback) {
1577
+ const list = document.querySelector(listSelector);
1578
+ if (!list) return;
1579
+
1580
+ const items = list.querySelectorAll('.w-dyn-item');
1581
+ if (items.length > 0) {
1582
+ callback(items);
1583
+ return;
1584
+ }
1585
+
1586
+ // Fallback: observe for dynamic loading
1587
+ const observer = new MutationObserver((mutations, obs) => {
1588
+ const items = list.querySelectorAll('.w-dyn-item');
1589
+ if (items.length > 0) {
1590
+ obs.disconnect();
1591
+ callback(items);
1592
+ }
1593
+ });
1594
+ observer.observe(list, { childList: true, subtree: true });
1595
+ }
1596
+ \`\`\`
1597
+
1598
+ ### CMS filtering and sorting
1599
+
1600
+ Webflow has native filtering (paid plans). For custom filtering:
1601
+
1602
+ \`\`\`javascript
1603
+ // Use data attributes on CMS items for filtering
1604
+ // In Webflow: add custom attribute data-category="{Category Field}"
1605
+ document.querySelectorAll('[data-filter-btn]').forEach(btn => {
1606
+ btn.addEventListener('click', () => {
1607
+ const filter = btn.dataset.filterBtn;
1608
+ document.querySelectorAll('.w-dyn-item').forEach(item => {
1609
+ const category = item.querySelector('[data-category]')?.dataset.category;
1610
+ item.style.display = (filter === 'all' || category === filter) ? '' : 'none';
1611
+ });
1612
+ });
1613
+ });
1614
+ \`\`\`
1615
+
1616
+ ### Pagination
1617
+
1618
+ Webflow paginates CMS lists (default 100 items). Only items on the current page exist in the DOM.
1619
+ If you need all items, use the Webflow CMS API or load additional pages via fetch.
1620
+
1621
+ ## Form Handling
1622
+
1623
+ Webflow forms submit via AJAX by default. To intercept:
1624
+
1625
+ \`\`\`javascript
1626
+ // Intercept form submission
1627
+ const form = document.querySelector('.w-form form');
1628
+ if (form) {
1629
+ form.addEventListener('submit', (e) => {
1630
+ e.preventDefault();
1631
+ e.stopPropagation(); // Prevent Webflow's handler
1632
+
1633
+ const formData = new FormData(form);
1634
+ // Your custom logic here
1635
+
1636
+ // Show success state manually:
1637
+ form.style.display = 'none';
1638
+ form.closest('.w-form').querySelector('.w-form-done').style.display = 'block';
1639
+ });
1640
+ }
1641
+ \`\`\`
1642
+
1643
+ ### Form validation
1644
+
1645
+ Webflow uses native HTML5 validation. For custom validation:
1646
+
1647
+ \`\`\`javascript
1648
+ // Add custom validation before Webflow processes the form
1649
+ const form = document.querySelector('[data-form="contact"]');
1650
+ const emailField = form?.querySelector('input[type="email"]');
1651
+
1652
+ emailField?.addEventListener('invalid', (e) => {
1653
+ e.target.setCustomValidity('Vennligst skriv inn en gyldig e-postadresse');
1654
+ });
1655
+ emailField?.addEventListener('input', (e) => {
1656
+ e.target.setCustomValidity('');
1657
+ });
1658
+ \`\`\`
1659
+
1660
+ ## CSS Specificity with Webflow
1661
+
1662
+ Webflow's stylesheet loads before Cure Kode scripts. Key rules:
1663
+
1664
+ 1. **Your CSS has higher specificity** when injected via Cure Kode (loaded after Webflow's CSS)
1665
+ 2. **Webflow uses \`!important\` sparingly** but does use it for:
1666
+ - \`.w--current\` navigation states
1667
+ - Visibility utilities (\`.w-condition-invisible\`)
1668
+ - Rich text spacing
1669
+ 3. **Override Webflow styles safely**:
1670
+
1671
+ \`\`\`css
1672
+ /* Prefer class specificity over !important */
1673
+ .section.hero-section .heading {
1674
+ font-size: 4rem; /* More specific than .heading alone */
1675
+ }
1676
+
1677
+ /* If you must override !important from Webflow */
1678
+ .w-richtext h2 {
1679
+ margin-top: 2em !important; /* Only when absolutely necessary */
1680
+ }
1681
+ \`\`\`
1682
+
1683
+ 4. **Webflow responsive breakpoints**:
1684
+ - Desktop: default (no media query)
1685
+ - Tablet: \`@media (max-width: 991px)\`
1686
+ - Mobile landscape: \`@media (max-width: 767px)\`
1687
+ - Mobile portrait: \`@media (max-width: 478px)\`
1688
+
1689
+ ## Interactions and Animations
1690
+
1691
+ Webflow's IX2 engine manages interactions. Avoid conflicts:
1692
+
1693
+ \`\`\`javascript
1694
+ // DON'T: Modify styles that Webflow interactions control
1695
+ element.style.opacity = '1'; // Will fight with IX2
1696
+
1697
+ // DO: Use Webflow's API to trigger interactions
1698
+ // Or add/remove classes that don't conflict with IX2 properties
1699
+ element.classList.add('is-active');
1700
+ \`\`\`
1701
+
1702
+ ### Scroll-triggered animations
1703
+
1704
+ \`\`\`javascript
1705
+ // Use IntersectionObserver \u2014 doesn't conflict with IX2
1706
+ const observer = new IntersectionObserver((entries) => {
1707
+ entries.forEach(entry => {
1708
+ if (entry.isIntersecting) {
1709
+ entry.target.classList.add('is-visible');
1710
+ observer.unobserve(entry.target);
1711
+ }
1712
+ });
1713
+ }, { threshold: 0.2 });
1714
+
1715
+ document.querySelectorAll('[data-animate]').forEach(el => observer.observe(el));
1716
+ \`\`\`
1717
+
1718
+ ## Cure Kode Script Loading
1719
+
1720
+ ### Execution order
1721
+
1722
+ 1. Browser parses HTML, encounters init.js with \`defer\`
1723
+ 2. DOM is fully parsed
1724
+ 3. init.js executes:
1725
+ a. Global + autoLoad scripts are injected (in order of creation)
1726
+ b. Page-specific scripts are matched against current URL
1727
+ c. CSS scripts injected as \`<style>\` tags in \`<head>\`
1728
+ d. JS scripts injected as \`<script>\` tags at end of \`<body>\`
1729
+ 4. Each script executes as it's injected
1730
+
1731
+ ### The \`window.CK\` global
1732
+
1733
+ \`\`\`javascript
1734
+ // Available after init.js loads
1735
+ window.CK.loadScript('my-script'); // Manually load a script
1736
+ window.CK.getConfig(); // Get site configuration
1737
+ window.CK.version; // Current deployment version
1738
+ \`\`\`
1739
+
1740
+ ### Script communication
1741
+
1742
+ Scripts loaded by Cure Kode can communicate via custom events:
1743
+
1744
+ \`\`\`javascript
1745
+ // Script A: dispatch
1746
+ window.dispatchEvent(new CustomEvent('cart:updated', { detail: { count: 3 } }));
1747
+
1748
+ // Script B: listen
1749
+ window.addEventListener('cart:updated', (e) => {
1750
+ document.querySelector('.cart-count').textContent = e.detail.count;
1751
+ });
1752
+ \`\`\`
1753
+
1754
+ ### CSS script specificity
1755
+
1756
+ CSS scripts are injected as \`<style>\` tags in \`<head>\`, after Webflow's stylesheet.
1757
+ They naturally have higher cascade priority without needing \`!important\`.
1758
+ `;
1759
+
1438
1760
  // src/commands/init.ts
1439
1761
  var { prompt } = enquirer;
1440
1762
  function showBanner() {
@@ -1580,22 +1902,22 @@ async function initCommand(options) {
1580
1902
  };
1581
1903
  spinner.start("Oppretter prosjektstruktur...");
1582
1904
  saveProjectConfig(config, cwd);
1583
- const scriptsPath = join4(cwd, DEFAULT_SCRIPTS_DIR);
1584
- if (!existsSync4(scriptsPath)) {
1585
- mkdirSync2(scriptsPath, { recursive: true });
1905
+ const scriptsPath = join5(cwd, DEFAULT_SCRIPTS_DIR);
1906
+ if (!existsSync5(scriptsPath)) {
1907
+ mkdirSync3(scriptsPath, { recursive: true });
1586
1908
  }
1587
- const gitignorePath = join4(cwd, ".cure-kode", ".gitignore");
1909
+ const gitignorePath = join5(cwd, ".cure-kode", ".gitignore");
1588
1910
  const gitignoreContent = `# Hold config.json privat - inneholder API-n\xF8kkel
1589
1911
  config.json
1590
1912
  `;
1591
- writeFileSync4(gitignorePath, gitignoreContent);
1913
+ writeFileSync5(gitignorePath, gitignoreContent);
1592
1914
  spinner.succeed("Prosjektstruktur opprettet");
1593
1915
  spinner.start("Konfigurerer MCP-servere...");
1594
- const mcpConfigPath = join4(cwd, ".mcp.json");
1916
+ const mcpConfigPath = join5(cwd, ".mcp.json");
1595
1917
  let mcpConfig = {};
1596
- if (existsSync4(mcpConfigPath)) {
1918
+ if (existsSync5(mcpConfigPath)) {
1597
1919
  try {
1598
- mcpConfig = JSON.parse(readFileSync4(mcpConfigPath, "utf-8"));
1920
+ mcpConfig = JSON.parse(readFileSync5(mcpConfigPath, "utf-8"));
1599
1921
  } catch {
1600
1922
  }
1601
1923
  }
@@ -1644,7 +1966,7 @@ config.json
1644
1966
  mcpConfig.mcpServers[server.name] = serverConfig;
1645
1967
  }
1646
1968
  }
1647
- writeFileSync4(mcpConfigPath, JSON.stringify(mcpConfig, null, 2) + "\n");
1969
+ writeFileSync5(mcpConfigPath, JSON.stringify(mcpConfig, null, 2) + "\n");
1648
1970
  spinner.succeed("MCP-servere konfigurert");
1649
1971
  if (secretWarnings.length > 0) {
1650
1972
  console.log();
@@ -1696,8 +2018,15 @@ config.json
1696
2018
  production_domain: site.production_domain
1697
2019
  };
1698
2020
  const contextMdContent = generateInitialContext(config, scripts, siteInfo);
1699
- writeFileSync4(join4(cwd, ".cure-kode", "context.md"), contextMdContent);
2021
+ writeFileSync5(join5(cwd, ".cure-kode", "context.md"), contextMdContent);
1700
2022
  spinner.succeed("AI-dokumentasjon generert");
2023
+ spinner.start("Genererer Claude Code skills...");
2024
+ const skillsResult = generateSkills(cwd, config.siteSlug);
2025
+ if (skillsResult.created.length > 0) {
2026
+ spinner.succeed(`Claude Code skills generert (${skillsResult.created.join(", ")})`);
2027
+ } else {
2028
+ spinner.succeed("Claude Code skills finnes allerede");
2029
+ }
1701
2030
  console.log();
1702
2031
  console.log(chalk.green(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
1703
2032
  console.log(chalk.green(" \u2551") + chalk.bold.green(" \u2705 Cure Kode er klar! ") + chalk.green("\u2551"));
@@ -1713,6 +2042,9 @@ config.json
1713
2042
  console.log(chalk.dim(" \u251C\u2500\u2500 CLAUDE.md ") + chalk.dim("(uendret - har allerede referanse)"));
1714
2043
  }
1715
2044
  console.log(chalk.dim(" \u251C\u2500\u2500 .mcp.json ") + chalk.green("(MCP-servere)"));
2045
+ console.log(chalk.dim(" \u251C\u2500\u2500 .claude/skills/ ") + chalk.green("(Claude Code skills)"));
2046
+ console.log(chalk.dim(" \u2502 \u251C\u2500\u2500 deploy/ (/deploy \u2014 push og deploy)"));
2047
+ console.log(chalk.dim(" \u2502 \u2514\u2500\u2500 webflow-patterns/ (Webflow DOM-referanse)"));
1716
2048
  console.log(chalk.dim(" \u251C\u2500\u2500 .cure-kode/"));
1717
2049
  console.log(chalk.dim(" \u2502 \u251C\u2500\u2500 config.json (konfigurasjon)"));
1718
2050
  console.log(chalk.dim(" \u2502 \u251C\u2500\u2500 KODE.md ") + chalk.green("(Kode-dokumentasjon)"));
@@ -2071,8 +2403,8 @@ function createApiClient(config) {
2071
2403
  // src/commands/pull.ts
2072
2404
  import chalk2 from "chalk";
2073
2405
  import ora2 from "ora";
2074
- import { writeFileSync as writeFileSync5, readFileSync as readFileSync5, mkdirSync as mkdirSync3, existsSync as existsSync5 } from "fs";
2075
- import { join as join5 } from "path";
2406
+ import { writeFileSync as writeFileSync6, readFileSync as readFileSync6, mkdirSync as mkdirSync4, existsSync as existsSync6 } from "fs";
2407
+ import { join as join6 } from "path";
2076
2408
  import { createHash } from "crypto";
2077
2409
  function hashContent(content) {
2078
2410
  return createHash("sha256").update(content).digest("hex").substring(0, 16);
@@ -2100,14 +2432,14 @@ async function pullCommand(options) {
2100
2432
  }
2101
2433
  spinner.succeed(`Fant ${scripts.length} skript`);
2102
2434
  const scriptsDir = getScriptsDir(projectRoot, config);
2103
- if (!existsSync5(scriptsDir)) {
2104
- mkdirSync3(scriptsDir, { recursive: true });
2435
+ if (!existsSync6(scriptsDir)) {
2436
+ mkdirSync4(scriptsDir, { recursive: true });
2105
2437
  }
2106
- const metadataPath = join5(projectRoot, ".cure-kode", "scripts.json");
2438
+ const metadataPath = join6(projectRoot, ".cure-kode", "scripts.json");
2107
2439
  let existingMetadata = [];
2108
- if (existsSync5(metadataPath)) {
2440
+ if (existsSync6(metadataPath)) {
2109
2441
  try {
2110
- existingMetadata = JSON.parse(readFileSync5(metadataPath, "utf-8"));
2442
+ existingMetadata = JSON.parse(readFileSync6(metadataPath, "utf-8"));
2111
2443
  } catch {
2112
2444
  }
2113
2445
  }
@@ -2128,11 +2460,11 @@ Fant ikke skript "${options.script}".`));
2128
2460
  for (const script of scriptsToPull) {
2129
2461
  const ext = script.type === "javascript" ? "js" : "css";
2130
2462
  const fileName = `${script.slug}.${ext}`;
2131
- const filePath = join5(scriptsDir, fileName);
2463
+ const filePath = join6(scriptsDir, fileName);
2132
2464
  const existingMeta = existingMetadata.find((m) => m.slug === script.slug);
2133
2465
  const lastPulledVersion = existingMeta?.lastPulledVersion || 0;
2134
- if (existsSync5(filePath) && !options.force) {
2135
- const localContent = readFileSync5(filePath, "utf-8");
2466
+ if (existsSync6(filePath) && !options.force) {
2467
+ const localContent = readFileSync6(filePath, "utf-8");
2136
2468
  const localHash = hashContent(localContent);
2137
2469
  const hasLocalChanges = existingMeta && localHash !== existingMeta.contentHash;
2138
2470
  if (hasLocalChanges) {
@@ -2155,7 +2487,7 @@ Fant ikke skript "${options.script}".`));
2155
2487
  continue;
2156
2488
  }
2157
2489
  }
2158
- writeFileSync5(filePath, script.content);
2490
+ writeFileSync6(filePath, script.content);
2159
2491
  const scopeTag = script.scope === "global" ? chalk2.blue("[G]") : chalk2.magenta("[P]");
2160
2492
  const loadTag = script.auto_load ? chalk2.green("\u26A1") : chalk2.dim("\u25CB");
2161
2493
  if (lastPulledVersion > 0 && script.current_version > lastPulledVersion) {
@@ -2187,8 +2519,8 @@ Fant ikke skript "${options.script}".`));
2187
2519
  }
2188
2520
  const now = (/* @__PURE__ */ new Date()).toISOString();
2189
2521
  const metadata = scripts.map((s) => {
2190
- const filePath = join5(scriptsDir, `${s.slug}.${s.type === "javascript" ? "js" : "css"}`);
2191
- const localContent = existsSync5(filePath) ? readFileSync5(filePath, "utf-8") : s.content;
2522
+ const filePath = join6(scriptsDir, `${s.slug}.${s.type === "javascript" ? "js" : "css"}`);
2523
+ const localContent = existsSync6(filePath) ? readFileSync6(filePath, "utf-8") : s.content;
2192
2524
  const pageAssignments = (s.pages || []).filter((p) => p.is_enabled).map((p) => {
2193
2525
  const page = pages.find((pg) => pg.id === p.page_id);
2194
2526
  return page ? { pageId: page.id, pageSlug: page.slug, pageName: page.name } : null;
@@ -2208,7 +2540,7 @@ Fant ikke skript "${options.script}".`));
2208
2540
  contentHash: hashContent(localContent)
2209
2541
  };
2210
2542
  });
2211
- writeFileSync5(metadataPath, JSON.stringify(metadata, null, 2));
2543
+ writeFileSync6(metadataPath, JSON.stringify(metadata, null, 2));
2212
2544
  try {
2213
2545
  const result = updateClaudeMd(
2214
2546
  projectRoot,
@@ -2239,8 +2571,8 @@ Fant ikke skript "${options.script}".`));
2239
2571
  // src/commands/push.ts
2240
2572
  import chalk3 from "chalk";
2241
2573
  import ora3 from "ora";
2242
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, existsSync as existsSync6, readdirSync } from "fs";
2243
- import { join as join6, basename, extname } from "path";
2574
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync7, existsSync as existsSync7, readdirSync } from "fs";
2575
+ import { join as join7, basename, extname } from "path";
2244
2576
  import { createHash as createHash2 } from "crypto";
2245
2577
  function hashContent2(content) {
2246
2578
  return createHash2("sha256").update(content).digest("hex").substring(0, 16);
@@ -2268,17 +2600,17 @@ async function pushCommand(options) {
2268
2600
  return;
2269
2601
  }
2270
2602
  const scriptsDir = getScriptsDir(projectRoot, config);
2271
- if (!existsSync6(scriptsDir)) {
2603
+ if (!existsSync7(scriptsDir)) {
2272
2604
  console.log(chalk3.yellow("Skriptmappen finnes ikke."));
2273
2605
  console.log(chalk3.dim(`Forventet: ${scriptsDir}`));
2274
2606
  console.log(chalk3.dim('Kj\xF8r "kode pull" f\xF8rst eller opprett skript manuelt.'));
2275
2607
  return;
2276
2608
  }
2277
- const metadataPath = join6(projectRoot, ".cure-kode", "scripts.json");
2609
+ const metadataPath = join7(projectRoot, ".cure-kode", "scripts.json");
2278
2610
  let metadata = [];
2279
- if (existsSync6(metadataPath)) {
2611
+ if (existsSync7(metadataPath)) {
2280
2612
  try {
2281
- metadata = JSON.parse(readFileSync6(metadataPath, "utf-8"));
2613
+ metadata = JSON.parse(readFileSync7(metadataPath, "utf-8"));
2282
2614
  } catch {
2283
2615
  }
2284
2616
  }
@@ -2313,8 +2645,8 @@ async function pushCommand(options) {
2313
2645
  console.log();
2314
2646
  let emptyScriptCount = 0;
2315
2647
  for (const file of filesToPush) {
2316
- const filePath = join6(scriptsDir, file);
2317
- const content = readFileSync6(filePath, "utf-8");
2648
+ const filePath = join7(scriptsDir, file);
2649
+ const content = readFileSync7(filePath, "utf-8");
2318
2650
  const slug = basename(file, extname(file));
2319
2651
  const type = extname(file) === ".js" ? "javascript" : "css";
2320
2652
  if (content.trim().length === 0) {
@@ -2397,8 +2729,8 @@ ${emptyScriptCount} tomme skript lastet opp`));
2397
2729
  const now = (/* @__PURE__ */ new Date()).toISOString();
2398
2730
  const updatedMetadata = updatedScripts.map((s) => {
2399
2731
  const ext = s.type === "javascript" ? "js" : "css";
2400
- const filePath = join6(scriptsDir, `${s.slug}.${ext}`);
2401
- const localContent = existsSync6(filePath) ? readFileSync6(filePath, "utf-8") : s.content;
2732
+ const filePath = join7(scriptsDir, `${s.slug}.${ext}`);
2733
+ const localContent = existsSync7(filePath) ? readFileSync7(filePath, "utf-8") : s.content;
2402
2734
  const pageAssignments = (s.pages || []).filter((p) => p.is_enabled).map((p) => {
2403
2735
  const page = pages.find((pg) => pg.id === p.page_id);
2404
2736
  return page ? { pageId: page.id, pageSlug: page.slug, pageName: page.name } : null;
@@ -2418,7 +2750,7 @@ ${emptyScriptCount} tomme skript lastet opp`));
2418
2750
  contentHash: hashContent2(localContent)
2419
2751
  };
2420
2752
  });
2421
- writeFileSync6(metadataPath, JSON.stringify(updatedMetadata, null, 2));
2753
+ writeFileSync7(metadataPath, JSON.stringify(updatedMetadata, null, 2));
2422
2754
  try {
2423
2755
  const result = updateClaudeMd(
2424
2756
  projectRoot,
@@ -2448,8 +2780,8 @@ ${emptyScriptCount} tomme skript lastet opp`));
2448
2780
  // src/commands/watch.ts
2449
2781
  import chalk4 from "chalk";
2450
2782
  import chokidar from "chokidar";
2451
- import { readFileSync as readFileSync7, existsSync as existsSync7 } from "fs";
2452
- import { join as join7, basename as basename2, extname as extname2 } from "path";
2783
+ import { readFileSync as readFileSync8, existsSync as existsSync8 } from "fs";
2784
+ import { join as join8, basename as basename2, extname as extname2 } from "path";
2453
2785
  async function watchCommand(options) {
2454
2786
  const projectRoot = findProjectRoot();
2455
2787
  if (!projectRoot) {
@@ -2463,7 +2795,7 @@ async function watchCommand(options) {
2463
2795
  return;
2464
2796
  }
2465
2797
  const scriptsDir = getScriptsDir(projectRoot, config);
2466
- if (!existsSync7(scriptsDir)) {
2798
+ if (!existsSync8(scriptsDir)) {
2467
2799
  console.log(chalk4.yellow("\u26A0\uFE0F Scripts directory not found."));
2468
2800
  console.log(chalk4.dim(` Expected: ${scriptsDir}`));
2469
2801
  console.log(chalk4.dim(' Run "kode pull" first.'));
@@ -2479,10 +2811,10 @@ async function watchCommand(options) {
2479
2811
  console.log();
2480
2812
  console.log(chalk4.dim("Press Ctrl+C to stop.\n"));
2481
2813
  const client = createApiClient(config);
2482
- const metadataPath = join7(projectRoot, ".cure-kode", "scripts.json");
2814
+ const metadataPath = join8(projectRoot, ".cure-kode", "scripts.json");
2483
2815
  let metadata = [];
2484
- if (existsSync7(metadataPath)) {
2485
- metadata = JSON.parse(readFileSync7(metadataPath, "utf-8"));
2816
+ if (existsSync8(metadataPath)) {
2817
+ metadata = JSON.parse(readFileSync8(metadataPath, "utf-8"));
2486
2818
  }
2487
2819
  let remoteScripts = [];
2488
2820
  try {
@@ -2514,7 +2846,7 @@ async function watchCommand(options) {
2514
2846
  };
2515
2847
  const retryFailedSyncs = async () => {
2516
2848
  for (const [filePath, failed] of failedSyncs.entries()) {
2517
- if (!existsSync7(filePath)) {
2849
+ if (!existsSync8(filePath)) {
2518
2850
  failedSyncs.delete(filePath);
2519
2851
  continue;
2520
2852
  }
@@ -2548,7 +2880,7 @@ async function watchCommand(options) {
2548
2880
  }
2549
2881
  const syncFile = async () => {
2550
2882
  try {
2551
- const content = readFileSync7(filePath, "utf-8");
2883
+ const content = readFileSync8(filePath, "utf-8");
2552
2884
  const remoteScript = remoteScripts.find((s) => s.slug === slug);
2553
2885
  const localMeta = metadata.find((m) => m.slug === slug);
2554
2886
  const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("nb-NO");
@@ -2662,7 +2994,7 @@ async function watchCommand(options) {
2662
2994
  }, DEBOUNCE_MS);
2663
2995
  pendingChanges.set(filePath, timeout);
2664
2996
  };
2665
- const watcher = chokidar.watch(join7(scriptsDir, "**/*.{js,css}"), {
2997
+ const watcher = chokidar.watch(join8(scriptsDir, "**/*.{js,css}"), {
2666
2998
  persistent: true,
2667
2999
  ignoreInitial: true,
2668
3000
  awaitWriteFinish: {
@@ -2703,8 +3035,8 @@ async function watchCommand(options) {
2703
3035
  // src/commands/deploy.ts
2704
3036
  import chalk5 from "chalk";
2705
3037
  import ora4 from "ora";
2706
- import { readFileSync as readFileSync8, existsSync as existsSync8, readdirSync as readdirSync2 } from "fs";
2707
- import { join as join8, basename as basename3, extname as extname3 } from "path";
3038
+ import { readFileSync as readFileSync9, existsSync as existsSync9, readdirSync as readdirSync2 } from "fs";
3039
+ import { join as join9, basename as basename3, extname as extname3 } from "path";
2708
3040
  function formatBytes(bytes) {
2709
3041
  if (bytes < 1024) return `${bytes} B`;
2710
3042
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
@@ -2741,19 +3073,19 @@ async function showDeploymentPreview(config, projectRoot) {
2741
3073
  }
2742
3074
  console.log();
2743
3075
  const scriptsDir = getScriptsDir(projectRoot, config);
2744
- const localFiles = existsSync8(scriptsDir) ? readdirSync2(scriptsDir).filter((f) => f.endsWith(".js") || f.endsWith(".css")) : [];
2745
- const metadataPath = join8(projectRoot, ".cure-kode", "scripts.json");
3076
+ const localFiles = existsSync9(scriptsDir) ? readdirSync2(scriptsDir).filter((f) => f.endsWith(".js") || f.endsWith(".css")) : [];
3077
+ const metadataPath = join9(projectRoot, ".cure-kode", "scripts.json");
2746
3078
  let metadata = [];
2747
- if (existsSync8(metadataPath)) {
3079
+ if (existsSync9(metadataPath)) {
2748
3080
  try {
2749
- metadata = JSON.parse(readFileSync8(metadataPath, "utf-8"));
3081
+ metadata = JSON.parse(readFileSync9(metadataPath, "utf-8"));
2750
3082
  } catch {
2751
3083
  }
2752
3084
  }
2753
3085
  const localBySlug = /* @__PURE__ */ new Map();
2754
3086
  for (const file of localFiles) {
2755
3087
  const slug = basename3(file, extname3(file));
2756
- const content = readFileSync8(join8(scriptsDir, file), "utf-8");
3088
+ const content = readFileSync9(join9(scriptsDir, file), "utf-8");
2757
3089
  localBySlug.set(slug, { content, size: Buffer.byteLength(content, "utf-8") });
2758
3090
  }
2759
3091
  const remoteBySlug = /* @__PURE__ */ new Map();
@@ -2985,8 +3317,8 @@ import chalk6 from "chalk";
2985
3317
  import ora5 from "ora";
2986
3318
 
2987
3319
  // src/lib/page-cache.ts
2988
- import { existsSync as existsSync9, mkdirSync as mkdirSync4, readdirSync as readdirSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync7, unlinkSync } from "fs";
2989
- import { join as join9, basename as basename4 } from "path";
3320
+ import { existsSync as existsSync10, mkdirSync as mkdirSync5, readdirSync as readdirSync3, readFileSync as readFileSync10, writeFileSync as writeFileSync8, unlinkSync } from "fs";
3321
+ import { join as join10, basename as basename4 } from "path";
2990
3322
  var PROJECT_CONFIG_DIR3 = ".cure-kode";
2991
3323
  var PAGES_DIR = "pages";
2992
3324
  function urlToSlug(url) {
@@ -3000,32 +3332,32 @@ function urlToSlug(url) {
3000
3332
  }
3001
3333
  }
3002
3334
  function getPagesDir(projectRoot) {
3003
- return join9(projectRoot, PROJECT_CONFIG_DIR3, PAGES_DIR);
3335
+ return join10(projectRoot, PROJECT_CONFIG_DIR3, PAGES_DIR);
3004
3336
  }
3005
3337
  function getPageCachePath(projectRoot, urlOrSlug) {
3006
3338
  const slug = urlOrSlug.startsWith("http") ? urlToSlug(urlOrSlug) : urlOrSlug;
3007
- return join9(getPagesDir(projectRoot), `${slug}.json`);
3339
+ return join10(getPagesDir(projectRoot), `${slug}.json`);
3008
3340
  }
3009
3341
  function ensurePagesDir(projectRoot) {
3010
3342
  const pagesDir = getPagesDir(projectRoot);
3011
- if (!existsSync9(pagesDir)) {
3012
- mkdirSync4(pagesDir, { recursive: true });
3343
+ if (!existsSync10(pagesDir)) {
3344
+ mkdirSync5(pagesDir, { recursive: true });
3013
3345
  }
3014
3346
  }
3015
3347
  function savePageContext(projectRoot, context) {
3016
3348
  ensurePagesDir(projectRoot);
3017
3349
  const slug = urlToSlug(context.url);
3018
3350
  const cachePath = getPageCachePath(projectRoot, slug);
3019
- writeFileSync7(cachePath, JSON.stringify(context, null, 2), "utf-8");
3351
+ writeFileSync8(cachePath, JSON.stringify(context, null, 2), "utf-8");
3020
3352
  return slug;
3021
3353
  }
3022
3354
  function readPageContext(projectRoot, urlOrSlug) {
3023
3355
  const cachePath = getPageCachePath(projectRoot, urlOrSlug);
3024
- if (!existsSync9(cachePath)) {
3356
+ if (!existsSync10(cachePath)) {
3025
3357
  return null;
3026
3358
  }
3027
3359
  try {
3028
- const content = readFileSync9(cachePath, "utf-8");
3360
+ const content = readFileSync10(cachePath, "utf-8");
3029
3361
  return JSON.parse(content);
3030
3362
  } catch {
3031
3363
  return null;
@@ -3033,7 +3365,7 @@ function readPageContext(projectRoot, urlOrSlug) {
3033
3365
  }
3034
3366
  function deletePageContext(projectRoot, urlOrSlug) {
3035
3367
  const cachePath = getPageCachePath(projectRoot, urlOrSlug);
3036
- if (existsSync9(cachePath)) {
3368
+ if (existsSync10(cachePath)) {
3037
3369
  unlinkSync(cachePath);
3038
3370
  return true;
3039
3371
  }
@@ -3041,7 +3373,7 @@ function deletePageContext(projectRoot, urlOrSlug) {
3041
3373
  }
3042
3374
  function listCachedPages(projectRoot) {
3043
3375
  const pagesDir = getPagesDir(projectRoot);
3044
- if (!existsSync9(pagesDir)) {
3376
+ if (!existsSync10(pagesDir)) {
3045
3377
  return [];
3046
3378
  }
3047
3379
  const files = readdirSync3(pagesDir).filter((f) => f.endsWith(".json"));
@@ -3324,8 +3656,8 @@ function printPageContext(context) {
3324
3656
  // src/commands/status.ts
3325
3657
  import chalk7 from "chalk";
3326
3658
  import ora6 from "ora";
3327
- import { readFileSync as readFileSync10, existsSync as existsSync10, readdirSync as readdirSync4, statSync } from "fs";
3328
- import { join as join10, basename as basename5, extname as extname4 } from "path";
3659
+ import { readFileSync as readFileSync11, existsSync as existsSync11, readdirSync as readdirSync4, statSync } from "fs";
3660
+ import { join as join11, basename as basename5, extname as extname4 } from "path";
3329
3661
  import { createHash as createHash3 } from "crypto";
3330
3662
  function hashContent3(content) {
3331
3663
  return createHash3("sha256").update(content).digest("hex").substring(0, 16);
@@ -3372,11 +3704,11 @@ async function statusCommand(options) {
3372
3704
  console.log(chalk7.red("\u274C Could not read project configuration."));
3373
3705
  return;
3374
3706
  }
3375
- const metadataPath = join10(projectRoot, ".cure-kode", "scripts.json");
3707
+ const metadataPath = join11(projectRoot, ".cure-kode", "scripts.json");
3376
3708
  let syncMetadata = [];
3377
- if (existsSync10(metadataPath)) {
3709
+ if (existsSync11(metadataPath)) {
3378
3710
  try {
3379
- syncMetadata = JSON.parse(readFileSync10(metadataPath, "utf-8"));
3711
+ syncMetadata = JSON.parse(readFileSync11(metadataPath, "utf-8"));
3380
3712
  } catch {
3381
3713
  }
3382
3714
  }
@@ -3457,12 +3789,12 @@ async function statusCommand(options) {
3457
3789
  }
3458
3790
  console.log();
3459
3791
  const scriptsDir = getScriptsDir(projectRoot, config);
3460
- const localFiles = existsSync10(scriptsDir) ? readdirSync4(scriptsDir).filter((f) => f.endsWith(".js") || f.endsWith(".css")) : [];
3792
+ const localFiles = existsSync11(scriptsDir) ? readdirSync4(scriptsDir).filter((f) => f.endsWith(".js") || f.endsWith(".css")) : [];
3461
3793
  const localBySlug = /* @__PURE__ */ new Map();
3462
3794
  for (const file of localFiles) {
3463
3795
  const slug = basename5(file, extname4(file));
3464
- const filePath = join10(scriptsDir, file);
3465
- const content = readFileSync10(filePath, "utf-8");
3796
+ const filePath = join11(scriptsDir, file);
3797
+ const content = readFileSync11(filePath, "utf-8");
3466
3798
  const stats = statSync(filePath);
3467
3799
  localBySlug.set(slug, { file, content, modified: stats.mtime });
3468
3800
  }
@@ -3738,8 +4070,8 @@ async function contextCommand(options) {
3738
4070
  // src/commands/sync-config.ts
3739
4071
  import chalk9 from "chalk";
3740
4072
  import ora8 from "ora";
3741
- import { existsSync as existsSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "fs";
3742
- import { join as join11 } from "path";
4073
+ import { existsSync as existsSync12, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
4074
+ import { join as join12 } from "path";
3743
4075
  async function syncConfigCommand() {
3744
4076
  const cwd = process.cwd();
3745
4077
  const projectRoot = findProjectRoot(cwd);
@@ -3770,11 +4102,11 @@ async function syncConfigCommand() {
3770
4102
  }
3771
4103
  const projectCtx = await response.json();
3772
4104
  spinner.succeed("Prosjektkonfigurasjon hentet");
3773
- const mcpConfigPath = join11(projectRoot, ".mcp.json");
4105
+ const mcpConfigPath = join12(projectRoot, ".mcp.json");
3774
4106
  let mcpConfig = {};
3775
- if (existsSync11(mcpConfigPath)) {
4107
+ if (existsSync12(mcpConfigPath)) {
3776
4108
  try {
3777
- mcpConfig = JSON.parse(readFileSync11(mcpConfigPath, "utf-8"));
4109
+ mcpConfig = JSON.parse(readFileSync12(mcpConfigPath, "utf-8"));
3778
4110
  } catch {
3779
4111
  }
3780
4112
  }
@@ -3818,7 +4150,7 @@ async function syncConfigCommand() {
3818
4150
  added.push(server.name);
3819
4151
  }
3820
4152
  }
3821
- writeFileSync8(mcpConfigPath, JSON.stringify(mcpConfig, null, 2) + "\n");
4153
+ writeFileSync9(mcpConfigPath, JSON.stringify(mcpConfig, null, 2) + "\n");
3822
4154
  spinner.start("Oppdaterer dokumentasjon...");
3823
4155
  let scripts = [];
3824
4156
  let pages = [];
package/dist/cli.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  updateClaudeMd,
24
24
  updateKodeDocs,
25
25
  watchCommand
26
- } from "./chunk-RUJGSFLC.js";
26
+ } from "./chunk-A6XTFKGI.js";
27
27
 
28
28
  // src/cli.ts
29
29
  import { Command } from "commander";
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  updateScriptPurpose,
29
29
  watchCommand,
30
30
  writeContext
31
- } from "./chunk-RUJGSFLC.js";
31
+ } from "./chunk-A6XTFKGI.js";
32
32
  export {
33
33
  KodeApiClient,
34
34
  KodeApiError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curenorway/kode-cli",
3
- "version": "1.15.2",
3
+ "version": "1.16.1",
4
4
  "description": "CLI for Cure Kode CDN - manage, deploy, and sync JS/CSS scripts for Webflow sites with AI agent support",
5
5
  "type": "module",
6
6
  "bin": {