@curenorway/kode-cli 1.17.1 → 1.18.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 CHANGED
@@ -160,6 +160,20 @@ kode pages # List all cached pages
160
160
  kode pages --json # Output as JSON
161
161
  ```
162
162
 
163
+ ### `kode library`
164
+
165
+ Browse and use the global script library (Bibliotek). Contains reusable snippets like GSAP animations, form handlers, scroll effects.
166
+
167
+ ```bash
168
+ kode library # List all library snippets
169
+ kode library search "scroll" # Search by name or tags
170
+ kode library add gsap-scroll-reveal # Copy snippet into project
171
+ kode library pull # Download all as local references
172
+ kode library push my-script.js # Push a local script to the library
173
+ ```
174
+
175
+ Library snippets are reference material — they live in `.cure-kode-scripts/library/` and are never deployed. Use `kode library add` to copy a snippet into your project scripts, then adapt it.
176
+
163
177
  ### `kode context`
164
178
 
165
179
  View and manage AI context.
@@ -279,7 +293,11 @@ your-project/
279
293
  ├── .cure-kode-scripts/ # Your scripts directory
280
294
  │ ├── main.js
281
295
  │ ├── form-handler.js
282
- └── styles.css
296
+ ├── styles.css
297
+ │ └── library/ # Reference only (never deployed)
298
+ │ ├── animations/
299
+ │ ├── forms/
300
+ │ └── utilities/
283
301
  ├── .mcp.json # MCP server configuration
284
302
  └── CLAUDE.md # Reference to KODE.md (your content preserved)
285
303
  ```
@@ -1355,6 +1355,9 @@ kode doctor # Check for issues and CLI updates
1355
1355
  | \`kode pages\` | List CDN pages |
1356
1356
  | \`kode pages create <name> -p /path\` | Create a page with URL patterns |
1357
1357
  | \`kode pages assign <page> <script>\` | Assign script to page |
1358
+ | \`kode library\` | List global library snippets |
1359
+ | \`kode library search <query>\` | Search library |
1360
+ | \`kode library add <slug>\` | Copy snippet into project |
1358
1361
 
1359
1362
  ## MCP Tools
1360
1363
 
@@ -1365,6 +1368,9 @@ AI agents can use these tools directly:
1365
1368
  - \`kode_deploy\` / \`kode_promote\` - Deploy to staging/production
1366
1369
  - \`kode_create_page\` - Create CDN page with URL patterns
1367
1370
  - \`kode_assign_script_to_page\` - Assign script to page
1371
+ - \`kode_library_list\` - Browse global script library
1372
+ - \`kode_library_get\` - Get snippet with full code
1373
+ - \`kode_library_use\` - Copy snippet into project
1368
1374
 
1369
1375
  ## File Structure
1370
1376
 
@@ -1378,7 +1384,10 @@ AI agents can use these tools directly:
1378
1384
  .cure-kode-scripts/ # Your script files
1379
1385
  \u251C\u2500\u2500 main.js
1380
1386
  \u251C\u2500\u2500 form-handler.js
1381
- \u2514\u2500\u2500 ...
1387
+ \u2514\u2500\u2500 library/ # Reference only (never deployed)
1388
+ \u251C\u2500\u2500 animations/
1389
+ \u251C\u2500\u2500 forms/
1390
+ \u2514\u2500\u2500 utilities/
1382
1391
 
1383
1392
  .claude/skills/ # Claude Code skills
1384
1393
  \u251C\u2500\u2500 deploy/ # /deploy \u2014 push and deploy workflow
@@ -1455,6 +1464,15 @@ function generateSkills(projectRoot, siteSlug) {
1455
1464
  } else {
1456
1465
  skipped.push("deploy");
1457
1466
  }
1467
+ const libraryDir = join4(skillsDir, "library");
1468
+ const libraryPath = join4(libraryDir, "SKILL.md");
1469
+ if (!existsSync4(libraryPath)) {
1470
+ mkdirSync2(libraryDir, { recursive: true });
1471
+ writeFileSync4(libraryPath, LIBRARY_SKILL);
1472
+ created.push("library");
1473
+ } else {
1474
+ skipped.push("library");
1475
+ }
1458
1476
  const webflowDir = join4(skillsDir, "webflow-patterns");
1459
1477
  const webflowSkillPath = join4(webflowDir, "SKILL.md");
1460
1478
  const webflowRefPath = join4(webflowDir, "reference.md");
@@ -1565,6 +1583,68 @@ See [reference.md](reference.md) for:
1565
1583
  - Animation and interaction scripting
1566
1584
  - Cure Kode script loading and execution order
1567
1585
  `;
1586
+ var LIBRARY_SKILL = `---
1587
+ name: library
1588
+ description: Check the Cure Kode global library before writing common patterns from scratch. Contains reusable GSAP animations, form handlers, scroll effects, and utilities.
1589
+ user-invocable: false
1590
+ ---
1591
+
1592
+ # Cure Kode Library (Bibliotek)
1593
+
1594
+ Before writing common JavaScript/CSS patterns, check if the global library already has a reusable snippet.
1595
+
1596
+ ## Workflow
1597
+
1598
+ ### 1. Browse available snippets
1599
+
1600
+ \`\`\`
1601
+ kode library list
1602
+ \`\`\`
1603
+
1604
+ Or search for a specific pattern:
1605
+
1606
+ \`\`\`
1607
+ kode library search "scroll"
1608
+ \`\`\`
1609
+
1610
+ Via MCP: use \`kode_library_list\` or \`kode_library_get\`.
1611
+
1612
+ ### 2. Copy and adapt
1613
+
1614
+ **Direct copy** (for utilities that don't need changes):
1615
+ \`\`\`
1616
+ kode library add debounce-throttle
1617
+ kode push
1618
+ \`\`\`
1619
+
1620
+ **Copy-and-adapt** (for patterns that need project-specific selectors):
1621
+ 1. Read the snippet: \`kode library search gsap\`
1622
+ 2. Copy it: \`kode library add gsap-scroll-reveal\`
1623
+ 3. Edit the local file \u2014 update CSS selectors, classes, timing
1624
+ 4. Push: \`kode push\`
1625
+
1626
+ ### 3. Contribute back
1627
+
1628
+ If you improve a library snippet or create a reusable pattern:
1629
+ \`\`\`
1630
+ kode library push my-improved-script.js
1631
+ \`\`\`
1632
+
1633
+ ## Categories
1634
+
1635
+ | Category | Content |
1636
+ |----------|---------|
1637
+ | \`animations\` | GSAP scroll reveals, smooth scrolling, parallax, counters |
1638
+ | \`forms\` | Form validation, multi-step forms, Webflow form intercept |
1639
+ | \`utilities\` | Debounce/throttle, viewport detection, cookie helpers |
1640
+ | \`tracking\` | Event tracking, scroll depth, click maps |
1641
+ | \`integrations\` | Third-party widget loaders, API connectors |
1642
+
1643
+ ## Local reference files
1644
+
1645
+ Library snippets are downloaded to \`.cure-kode-scripts/library/\` during \`kode init\`.
1646
+ These are **reference only** \u2014 they are never deployed. Only files in the root of \`.cure-kode-scripts/\` are pushed.
1647
+ `;
1568
1648
  var WEBFLOW_REFERENCE = `# Webflow Patterns \u2014 Detailed Reference
1569
1649
 
1570
1650
  ## CMS Collection Lists
@@ -2019,6 +2099,44 @@ config.json
2019
2099
  const contextMdContent = generateInitialContext(config, scripts, siteInfo);
2020
2100
  writeFileSync5(join5(cwd, ".cure-kode", "context.md"), contextMdContent);
2021
2101
  spinner.succeed("AI-dokumentasjon generert");
2102
+ spinner.start("Laster ned bibliotek-referanser...");
2103
+ try {
2104
+ const libResponse = await fetch("https://app.cure.no/api/cdn/library", {
2105
+ headers: { "X-API-Key": apiKey }
2106
+ });
2107
+ if (libResponse.ok) {
2108
+ const libSnippets = await libResponse.json();
2109
+ if (libSnippets.length > 0) {
2110
+ const { existsSync: exists, mkdirSync: mkDir, writeFileSync: writeFile } = await import("fs");
2111
+ const { join: joinPath } = await import("path");
2112
+ const libDir = joinPath(scriptsPath, "library");
2113
+ let downloaded = 0;
2114
+ for (const s of libSnippets) {
2115
+ const catDir = joinPath(libDir, s.category || "other");
2116
+ if (!exists(catDir)) mkDir(catDir, { recursive: true });
2117
+ const ext = s.type === "javascript" ? "js" : "css";
2118
+ try {
2119
+ const snippetRes = await fetch(`https://app.cure.no/api/cdn/library/${s.slug}`, {
2120
+ headers: { "X-API-Key": apiKey }
2121
+ });
2122
+ if (snippetRes.ok) {
2123
+ const full = await snippetRes.json();
2124
+ writeFile(joinPath(catDir, `${s.slug}.${ext}`), full.code);
2125
+ downloaded++;
2126
+ }
2127
+ } catch {
2128
+ }
2129
+ }
2130
+ spinner.succeed(`${downloaded} bibliotek-referanser lastet ned`);
2131
+ } else {
2132
+ spinner.succeed("Biblioteket er tomt");
2133
+ }
2134
+ } else {
2135
+ spinner.succeed("Bibliotek ikke tilgjengelig");
2136
+ }
2137
+ } catch {
2138
+ spinner.succeed("Bibliotek hoppet over");
2139
+ }
2022
2140
  spinner.start("Genererer Claude Code skills...");
2023
2141
  const skillsResult = generateSkills(cwd, config.siteSlug);
2024
2142
  if (skillsResult.created.length > 0) {
@@ -2043,7 +2161,8 @@ config.json
2043
2161
  console.log(chalk.dim(" \u251C\u2500\u2500 .mcp.json ") + chalk.green("(MCP-servere)"));
2044
2162
  console.log(chalk.dim(" \u251C\u2500\u2500 .claude/skills/ ") + chalk.green("(Claude Code skills)"));
2045
2163
  console.log(chalk.dim(" \u2502 \u251C\u2500\u2500 deploy/ (/deploy \u2014 push og deploy)"));
2046
- console.log(chalk.dim(" \u2502 \u2514\u2500\u2500 webflow-patterns/ (Webflow DOM-referanse)"));
2164
+ console.log(chalk.dim(" \u2502 \u251C\u2500\u2500 webflow-patterns/ (Webflow DOM-referanse)"));
2165
+ console.log(chalk.dim(" \u2502 \u2514\u2500\u2500 library/ (Bibliotek-referanse)"));
2047
2166
  console.log(chalk.dim(" \u251C\u2500\u2500 .cure-kode/"));
2048
2167
  console.log(chalk.dim(" \u2502 \u251C\u2500\u2500 config.json (konfigurasjon)"));
2049
2168
  console.log(chalk.dim(" \u2502 \u251C\u2500\u2500 KODE.md ") + chalk.green("(Kode-dokumentasjon)"));
@@ -2365,6 +2484,25 @@ var KodeApiClient = class {
2365
2484
  body: JSON.stringify({ siteId })
2366
2485
  });
2367
2486
  }
2487
+ // Library (global snippets)
2488
+ async listLibrary(search) {
2489
+ const params = new URLSearchParams();
2490
+ if (search) params.set("search", search);
2491
+ const qs = params.toString();
2492
+ return this.request(`/api/cdn/library${qs ? `?${qs}` : ""}`);
2493
+ }
2494
+ async getLibrarySnippet(slugOrId) {
2495
+ return this.request(`/api/cdn/library/${encodeURIComponent(slugOrId)}`);
2496
+ }
2497
+ async createLibrarySnippet(data) {
2498
+ return this.request("/api/cdn/library", {
2499
+ method: "POST",
2500
+ body: JSON.stringify(data)
2501
+ });
2502
+ }
2503
+ async recordLibraryUsage(snippetId) {
2504
+ await this.request(`/api/cdn/library/${snippetId}`);
2505
+ }
2368
2506
  // Webflow Custom Code injection
2369
2507
  async getWebflowCustomCodeStatus(siteId) {
2370
2508
  return this.request(`/api/cdn/sites/${siteId}/webflow/custom-code`);
@@ -2600,7 +2738,7 @@ async function pushCommand(options) {
2600
2738
  }
2601
2739
  }
2602
2740
  const files = readdirSync(scriptsDir).filter(
2603
- (f) => f.endsWith(".js") || f.endsWith(".css")
2741
+ (f) => (f.endsWith(".js") || f.endsWith(".css")) && f !== "library"
2604
2742
  );
2605
2743
  if (files.length === 0) {
2606
2744
  console.log(chalk3.yellow("Ingen skriptfiler funnet."));
package/dist/cli.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  updateClaudeMd,
24
24
  updateKodeDocs,
25
25
  watchCommand
26
- } from "./chunk-7EPXFFNR.js";
26
+ } from "./chunk-MSXS4ARI.js";
27
27
 
28
28
  // src/cli.ts
29
29
  import { Command } from "commander";
@@ -1787,6 +1787,223 @@ async function webflowStatusCommand() {
1787
1787
  }
1788
1788
  }
1789
1789
 
1790
+ // src/commands/library.ts
1791
+ import chalk12 from "chalk";
1792
+ import ora8 from "ora";
1793
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
1794
+ import { join as join5, basename as basename2, extname as extname2 } from "path";
1795
+ async function libraryListCommand(options) {
1796
+ const projectRoot = findProjectRoot();
1797
+ if (!projectRoot) {
1798
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
1799
+ return;
1800
+ }
1801
+ const config = getProjectConfig(projectRoot);
1802
+ if (!config) {
1803
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
1804
+ return;
1805
+ }
1806
+ const spinner = ora8("Henter bibliotek...").start();
1807
+ try {
1808
+ const client = createApiClient(config);
1809
+ const snippets = await client.listLibrary();
1810
+ spinner.stop();
1811
+ if (snippets.length === 0) {
1812
+ console.log(chalk12.dim("Biblioteket er tomt."));
1813
+ return;
1814
+ }
1815
+ if (options.json) {
1816
+ console.log(JSON.stringify(snippets, null, 2));
1817
+ return;
1818
+ }
1819
+ console.log();
1820
+ console.log(chalk12.bold(` Bibliotek (${snippets.length} snippets)`));
1821
+ console.log();
1822
+ const grouped = /* @__PURE__ */ new Map();
1823
+ for (const s of snippets) {
1824
+ const cat = s.category || "other";
1825
+ if (!grouped.has(cat)) grouped.set(cat, []);
1826
+ grouped.get(cat).push(s);
1827
+ }
1828
+ for (const [category, items] of grouped) {
1829
+ console.log(chalk12.dim(` ${category}/`));
1830
+ for (const s of items) {
1831
+ const typeLabel = s.type === "javascript" ? chalk12.yellow("JS") : chalk12.blue("CSS");
1832
+ const tags = s.tags.length > 0 ? chalk12.dim(` [${s.tags.join(", ")}]`) : "";
1833
+ console.log(` ${typeLabel} ${s.name}${chalk12.dim(` v${s.version}`)}${tags}`);
1834
+ }
1835
+ }
1836
+ console.log();
1837
+ } catch (error) {
1838
+ spinner.fail("Kunne ikke hente bibliotek");
1839
+ console.error(chalk12.red("Feil:"), error);
1840
+ }
1841
+ }
1842
+ async function librarySearchCommand(query) {
1843
+ const projectRoot = findProjectRoot();
1844
+ if (!projectRoot) {
1845
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
1846
+ return;
1847
+ }
1848
+ const config = getProjectConfig(projectRoot);
1849
+ if (!config) {
1850
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
1851
+ return;
1852
+ }
1853
+ const spinner = ora8(`S\xF8ker etter "${query}"...`).start();
1854
+ try {
1855
+ const client = createApiClient(config);
1856
+ const snippets = await client.listLibrary(query);
1857
+ spinner.stop();
1858
+ if (snippets.length === 0) {
1859
+ console.log(chalk12.dim(`Ingen treff for "${query}".`));
1860
+ return;
1861
+ }
1862
+ console.log();
1863
+ console.log(chalk12.bold(` ${snippets.length} treff for "${query}"`));
1864
+ console.log();
1865
+ for (const s of snippets) {
1866
+ const typeLabel = s.type === "javascript" ? chalk12.yellow("JS") : chalk12.blue("CSS");
1867
+ const desc = s.description ? chalk12.dim(` \u2014 ${s.description}`) : "";
1868
+ console.log(` ${typeLabel} ${s.name}${chalk12.dim(` v${s.version}`)}${desc}`);
1869
+ }
1870
+ console.log();
1871
+ } catch (error) {
1872
+ spinner.fail("S\xF8k feilet");
1873
+ console.error(chalk12.red("Feil:"), error);
1874
+ }
1875
+ }
1876
+ async function libraryAddCommand(slug) {
1877
+ const projectRoot = findProjectRoot();
1878
+ if (!projectRoot) {
1879
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
1880
+ return;
1881
+ }
1882
+ const config = getProjectConfig(projectRoot);
1883
+ if (!config) {
1884
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
1885
+ return;
1886
+ }
1887
+ const spinner = ora8(`Henter snippet "${slug}"...`).start();
1888
+ try {
1889
+ const client = createApiClient(config);
1890
+ const snippet = await client.getLibrarySnippet(slug);
1891
+ const ext = snippet.type === "javascript" ? "js" : "css";
1892
+ const scriptsDir = getScriptsDir(projectRoot, config);
1893
+ if (!existsSync5(scriptsDir)) {
1894
+ mkdirSync2(scriptsDir, { recursive: true });
1895
+ }
1896
+ const filePath = join5(scriptsDir, `${snippet.slug}.${ext}`);
1897
+ if (existsSync5(filePath)) {
1898
+ spinner.fail(`Filen finnes allerede: ${snippet.slug}.${ext}`);
1899
+ console.log(chalk12.dim("Slett den f\xF8rst eller bruk et annet navn."));
1900
+ return;
1901
+ }
1902
+ writeFileSync3(filePath, snippet.code);
1903
+ try {
1904
+ await client.recordLibraryUsage(snippet.id);
1905
+ } catch {
1906
+ }
1907
+ spinner.succeed(chalk12.green(`${snippet.slug}.${ext}`) + chalk12.dim(` \u2190 ${snippet.name}`));
1908
+ console.log();
1909
+ console.log(chalk12.dim(" Filen er kopiert til prosjektet ditt."));
1910
+ console.log(chalk12.dim(" Kj\xF8r ") + chalk12.cyan("kode push") + chalk12.dim(" for \xE5 laste opp til CDN."));
1911
+ console.log();
1912
+ } catch (error) {
1913
+ spinner.fail(`Fant ikke snippet "${slug}"`);
1914
+ console.error(chalk12.red("Feil:"), error);
1915
+ }
1916
+ }
1917
+ async function libraryPullCommand() {
1918
+ const projectRoot = findProjectRoot();
1919
+ if (!projectRoot) {
1920
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
1921
+ return;
1922
+ }
1923
+ const config = getProjectConfig(projectRoot);
1924
+ if (!config) {
1925
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
1926
+ return;
1927
+ }
1928
+ const spinner = ora8("Henter bibliotek...").start();
1929
+ try {
1930
+ const client = createApiClient(config);
1931
+ const snippets = await client.listLibrary();
1932
+ if (snippets.length === 0) {
1933
+ spinner.succeed("Biblioteket er tomt \u2014 ingenting \xE5 laste ned.");
1934
+ return;
1935
+ }
1936
+ const scriptsDir = getScriptsDir(projectRoot, config);
1937
+ const libraryDir = join5(scriptsDir, "library");
1938
+ let downloaded = 0;
1939
+ for (const s of snippets) {
1940
+ const categoryDir = join5(libraryDir, s.category || "other");
1941
+ if (!existsSync5(categoryDir)) {
1942
+ mkdirSync2(categoryDir, { recursive: true });
1943
+ }
1944
+ const ext = s.type === "javascript" ? "js" : "css";
1945
+ const filePath = join5(categoryDir, `${s.slug}.${ext}`);
1946
+ try {
1947
+ const full = await client.getLibrarySnippet(s.slug);
1948
+ writeFileSync3(filePath, full.code);
1949
+ downloaded++;
1950
+ } catch {
1951
+ }
1952
+ }
1953
+ spinner.succeed(`Lastet ned ${downloaded} snippets til ${chalk12.dim("library/")}`);
1954
+ console.log(chalk12.dim(" Disse filene er kun referanse \u2014 de deployes ikke."));
1955
+ console.log();
1956
+ } catch (error) {
1957
+ spinner.fail("Kunne ikke laste ned bibliotek");
1958
+ console.error(chalk12.red("Feil:"), error);
1959
+ }
1960
+ }
1961
+ async function libraryPushCommand(file) {
1962
+ const projectRoot = findProjectRoot();
1963
+ if (!projectRoot) {
1964
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
1965
+ return;
1966
+ }
1967
+ const config = getProjectConfig(projectRoot);
1968
+ if (!config) {
1969
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
1970
+ return;
1971
+ }
1972
+ const scriptsDir = getScriptsDir(projectRoot, config);
1973
+ const filePath = existsSync5(file) ? file : join5(scriptsDir, file);
1974
+ if (!existsSync5(filePath)) {
1975
+ console.log(chalk12.red(`Filen finnes ikke: ${file}`));
1976
+ return;
1977
+ }
1978
+ const content = readFileSync5(filePath, "utf-8");
1979
+ const name = basename2(file, extname2(file));
1980
+ const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
1981
+ const type = extname2(filePath) === ".css" ? "css" : "javascript";
1982
+ console.log();
1983
+ console.log(chalk12.bold(" Push til globalt bibliotek"));
1984
+ console.log();
1985
+ console.log(chalk12.dim(` Fil: ${basename2(filePath)}`));
1986
+ console.log(chalk12.dim(` Slug: ${slug}`));
1987
+ console.log(chalk12.dim(` Type: ${type}`));
1988
+ console.log(chalk12.dim(` St\xF8rrelse: ${content.length} tegn`));
1989
+ console.log();
1990
+ const spinner = ora8("Laster opp til bibliotek...").start();
1991
+ try {
1992
+ const client = createApiClient(config);
1993
+ await client.createLibrarySnippet({
1994
+ name: name.charAt(0).toUpperCase() + name.slice(1).replace(/-/g, " "),
1995
+ slug,
1996
+ type,
1997
+ code: content
1998
+ });
1999
+ spinner.succeed(chalk12.green(`"${name}" lagt til i biblioteket`));
2000
+ console.log();
2001
+ } catch (error) {
2002
+ spinner.fail("Kunne ikke laste opp til bibliotek");
2003
+ console.error(chalk12.red("Feil:"), error?.message || error);
2004
+ }
2005
+ }
2006
+
1790
2007
  // src/cli.ts
1791
2008
  var program = new Command();
1792
2009
  program.name("kode").description("CLI for Cure Kode - manage JS/CSS scripts for Webflow sites").version(CLI_VERSION);
@@ -1876,6 +2093,22 @@ webflowCmd.command("remove").description("Remove Cure Kode init.js from Webflow"
1876
2093
  webflowCmd.command("status", { isDefault: true }).description("Show current Webflow injection status").action(() => {
1877
2094
  webflowStatusCommand();
1878
2095
  });
2096
+ var libraryCmd = program.command("library").description("Browse and use the global script library (Bibliotek)");
2097
+ libraryCmd.command("list", { isDefault: true }).description("List all library snippets").option("-j, --json", "Output as JSON").action((options) => {
2098
+ libraryListCommand(options);
2099
+ });
2100
+ libraryCmd.command("search <query>").description("Search library by name or tags").action((query) => {
2101
+ librarySearchCommand(query);
2102
+ });
2103
+ libraryCmd.command("add <slug>").description("Copy a library snippet into your project scripts").action((slug) => {
2104
+ libraryAddCommand(slug);
2105
+ });
2106
+ libraryCmd.command("pull").description("Download all library snippets as local references").action(() => {
2107
+ libraryPullCommand();
2108
+ });
2109
+ libraryCmd.command("push <file>").description("Push a local script to the global library").action((file) => {
2110
+ libraryPushCommand(file);
2111
+ });
1879
2112
  program.command("doctor").description("Diagnose configuration and environment issues").action(() => {
1880
2113
  doctorCommand();
1881
2114
  });
package/dist/index.d.ts CHANGED
@@ -240,6 +240,44 @@ declare class KodeApiClient {
240
240
  acquiredAt?: string;
241
241
  duration_ms?: number;
242
242
  }>;
243
+ listLibrary(search?: string): Promise<Array<{
244
+ id: string;
245
+ name: string;
246
+ slug: string;
247
+ description: string | null;
248
+ type: 'javascript' | 'css';
249
+ category: string | null;
250
+ tags: string[];
251
+ version: number;
252
+ usage_count: number;
253
+ }>>;
254
+ getLibrarySnippet(slugOrId: string): Promise<{
255
+ id: string;
256
+ name: string;
257
+ slug: string;
258
+ description: string | null;
259
+ type: 'javascript' | 'css';
260
+ code: string;
261
+ category: string | null;
262
+ tags: string[];
263
+ version: number;
264
+ usage_count: number;
265
+ example_usage: string | null;
266
+ }>;
267
+ createLibrarySnippet(data: {
268
+ name: string;
269
+ slug: string;
270
+ type: 'javascript' | 'css';
271
+ code: string;
272
+ description?: string;
273
+ category?: string;
274
+ tags?: string[];
275
+ exampleUsage?: string;
276
+ }): Promise<{
277
+ id: string;
278
+ slug: string;
279
+ }>;
280
+ recordLibraryUsage(snippetId: string): Promise<void>;
243
281
  getWebflowCustomCodeStatus(siteId: string): Promise<{
244
282
  injected: boolean;
245
283
  scriptId: string | null;
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  updateScriptPurpose,
29
29
  watchCommand,
30
30
  writeContext
31
- } from "./chunk-7EPXFFNR.js";
31
+ } from "./chunk-MSXS4ARI.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.17.1",
3
+ "version": "1.18.0",
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": {