@curenorway/kode-cli 1.17.1 → 2.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/dist/cli.js CHANGED
@@ -1,29 +1,44 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CLI_VERSION,
4
- KodeApiError,
5
4
  contextCommand,
6
- createApiClient,
7
5
  deletePageContext,
8
6
  deployCommand,
9
- findProjectRoot,
10
- getProjectConfig,
11
- getScriptsDir,
12
7
  htmlCommand,
13
8
  initCommand,
14
9
  listCachedPages,
15
- pagesToInfoFormat,
16
- pullCommand,
17
10
  pushCommand,
18
11
  readPageContext,
19
- scriptsToDocsFormat,
20
12
  showCompactBanner,
21
13
  statusCommand,
22
14
  syncConfigCommand,
23
- updateClaudeMd,
24
- updateKodeDocs,
25
15
  watchCommand
26
- } from "./chunk-7EPXFFNR.js";
16
+ } from "./chunk-6RYN72CO.js";
17
+ import {
18
+ typesCommand
19
+ } from "./chunk-R4KWWTS4.js";
20
+ import {
21
+ pagesToInfoFormat,
22
+ pullCommand,
23
+ scriptsToDocsFormat,
24
+ updateClaudeMd,
25
+ updateKodeDocs
26
+ } from "./chunk-GO6KLUXM.js";
27
+ import {
28
+ KodeApiError,
29
+ createApiClient,
30
+ findProjectRoot,
31
+ getProjectConfig,
32
+ getScriptsDir
33
+ } from "./chunk-TLLGB46I.js";
34
+ import {
35
+ pkgAddCommand,
36
+ pkgInfoCommand,
37
+ pkgListCommand,
38
+ pkgPublishCommand,
39
+ pkgRemoveCommand,
40
+ pkgUpdateCommand
41
+ } from "./chunk-MUW33LPZ.js";
27
42
 
28
43
  // src/cli.ts
29
44
  import { Command } from "commander";
@@ -109,6 +124,42 @@ async function upgradeCommand() {
109
124
  };
110
125
  writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2) + "\n");
111
126
  spinner.succeed("MCP-servere oppdatert");
127
+ const tsconfigPath = join(projectRoot, "tsconfig.json");
128
+ if (existsSync(tsconfigPath)) {
129
+ try {
130
+ const tsconfig = JSON.parse(readFileSync(tsconfigPath, "utf-8"));
131
+ const paths = tsconfig.compilerOptions?.paths || {};
132
+ if (!paths["@kode/*"]) {
133
+ tsconfig.compilerOptions = tsconfig.compilerOptions || {};
134
+ tsconfig.compilerOptions.baseUrl = tsconfig.compilerOptions.baseUrl || ".";
135
+ tsconfig.compilerOptions.paths = {
136
+ ...paths,
137
+ "@kode/*": [".cure-kode-scripts/packages/@kode/*"]
138
+ };
139
+ writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + "\n");
140
+ console.log(chalk.dim(" La til @kode/* paths i tsconfig.json"));
141
+ }
142
+ } catch {
143
+ }
144
+ } else {
145
+ writeFileSync(tsconfigPath, JSON.stringify({
146
+ compilerOptions: {
147
+ target: "ES2020",
148
+ module: "ESNext",
149
+ moduleResolution: "bundler",
150
+ jsx: "react-jsx",
151
+ strict: true,
152
+ noEmit: true,
153
+ skipLibCheck: true,
154
+ baseUrl: ".",
155
+ paths: {
156
+ "@kode/*": [".cure-kode-scripts/packages/@kode/*"]
157
+ }
158
+ },
159
+ include: [".cure-kode-scripts/**/*"]
160
+ }, null, 2) + "\n");
161
+ console.log(chalk.dim(" Opprettet tsconfig.json med @kode/* paths"));
162
+ }
112
163
  spinner.start("Oppdaterer context.md...");
113
164
  const contextPath = join(projectRoot, ".cure-kode", "context.md");
114
165
  if (existsSync(contextPath)) {
@@ -1787,10 +1838,452 @@ async function webflowStatusCommand() {
1787
1838
  }
1788
1839
  }
1789
1840
 
1841
+ // src/commands/library.ts
1842
+ import chalk12 from "chalk";
1843
+ import ora8 from "ora";
1844
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
1845
+ import { join as join5, basename as basename2, extname as extname2 } from "path";
1846
+ async function libraryListCommand(options) {
1847
+ const projectRoot = findProjectRoot();
1848
+ if (!projectRoot) {
1849
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
1850
+ return;
1851
+ }
1852
+ const config = getProjectConfig(projectRoot);
1853
+ if (!config) {
1854
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
1855
+ return;
1856
+ }
1857
+ const spinner = ora8("Henter bibliotek...").start();
1858
+ try {
1859
+ const client = createApiClient(config);
1860
+ const [snippets, folders] = await Promise.all([
1861
+ client.listLibrary(),
1862
+ client.listLibraryFolders()
1863
+ ]);
1864
+ spinner.stop();
1865
+ if (snippets.length === 0 && folders.length === 0) {
1866
+ console.log(chalk12.dim("Biblioteket er tomt."));
1867
+ return;
1868
+ }
1869
+ if (options.json) {
1870
+ console.log(JSON.stringify({ folders, snippets }, null, 2));
1871
+ return;
1872
+ }
1873
+ console.log();
1874
+ console.log(chalk12.bold(` Bibliotek (${snippets.length} snippets, ${folders.length} mapper)`));
1875
+ console.log();
1876
+ if (options.tree) {
1877
+ const snippetsByFolder = /* @__PURE__ */ new Map();
1878
+ for (const s of snippets) {
1879
+ const key = s.folder_id || null;
1880
+ if (!snippetsByFolder.has(key)) snippetsByFolder.set(key, []);
1881
+ snippetsByFolder.get(key).push(s);
1882
+ }
1883
+ const renderFolder = (folder, indent) => {
1884
+ console.log(`${indent}\u{1F4C1} ${folder.name}${chalk12.dim(` (${folder.snippet_count})`)}`);
1885
+ const children = folders.filter((f) => f.parent_id === folder.id);
1886
+ for (const child of children) {
1887
+ renderFolder(child, indent + " ");
1888
+ }
1889
+ const folderSnippets = snippetsByFolder.get(folder.id) || [];
1890
+ for (const s of folderSnippets) {
1891
+ const typeLabel = s.type === "javascript" ? chalk12.yellow("JS") : chalk12.blue("CSS");
1892
+ console.log(`${indent} ${typeLabel} ${s.name}${chalk12.dim(` v${s.version}`)}`);
1893
+ }
1894
+ };
1895
+ const rootFolders = folders.filter((f) => !f.parent_id);
1896
+ for (const folder of rootFolders) {
1897
+ renderFolder(folder, " ");
1898
+ }
1899
+ const rootSnippets = snippetsByFolder.get(null) || [];
1900
+ if (rootSnippets.length > 0) {
1901
+ for (const s of rootSnippets) {
1902
+ const typeLabel = s.type === "javascript" ? chalk12.yellow("JS") : chalk12.blue("CSS");
1903
+ const tags = s.tags.length > 0 ? chalk12.dim(` [${s.tags.join(", ")}]`) : "";
1904
+ console.log(` ${typeLabel} ${s.name}${chalk12.dim(` v${s.version}`)}${tags}`);
1905
+ }
1906
+ }
1907
+ } else {
1908
+ const grouped = /* @__PURE__ */ new Map();
1909
+ for (const s of snippets) {
1910
+ const cat = s.category || "other";
1911
+ if (!grouped.has(cat)) grouped.set(cat, []);
1912
+ grouped.get(cat).push(s);
1913
+ }
1914
+ for (const [category, items] of grouped) {
1915
+ console.log(chalk12.dim(` ${category}/`));
1916
+ for (const s of items) {
1917
+ const typeLabel = s.type === "javascript" ? chalk12.yellow("JS") : chalk12.blue("CSS");
1918
+ const tags = s.tags.length > 0 ? chalk12.dim(` [${s.tags.join(", ")}]`) : "";
1919
+ console.log(` ${typeLabel} ${s.name}${chalk12.dim(` v${s.version}`)}${tags}`);
1920
+ }
1921
+ }
1922
+ }
1923
+ console.log();
1924
+ } catch (error) {
1925
+ spinner.fail("Kunne ikke hente bibliotek");
1926
+ console.error(chalk12.red("Feil:"), error);
1927
+ }
1928
+ }
1929
+ async function librarySearchCommand(query) {
1930
+ const projectRoot = findProjectRoot();
1931
+ if (!projectRoot) {
1932
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
1933
+ return;
1934
+ }
1935
+ const config = getProjectConfig(projectRoot);
1936
+ if (!config) {
1937
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
1938
+ return;
1939
+ }
1940
+ const spinner = ora8(`S\xF8ker etter "${query}"...`).start();
1941
+ try {
1942
+ const client = createApiClient(config);
1943
+ const snippets = await client.listLibrary(query);
1944
+ spinner.stop();
1945
+ if (snippets.length === 0) {
1946
+ console.log(chalk12.dim(`Ingen treff for "${query}".`));
1947
+ return;
1948
+ }
1949
+ console.log();
1950
+ console.log(chalk12.bold(` ${snippets.length} treff for "${query}"`));
1951
+ console.log();
1952
+ for (const s of snippets) {
1953
+ const typeLabel = s.type === "javascript" ? chalk12.yellow("JS") : chalk12.blue("CSS");
1954
+ const desc = s.description ? chalk12.dim(` \u2014 ${s.description}`) : "";
1955
+ console.log(` ${typeLabel} ${s.name}${chalk12.dim(` v${s.version}`)}${desc}`);
1956
+ }
1957
+ console.log();
1958
+ } catch (error) {
1959
+ spinner.fail("S\xF8k feilet");
1960
+ console.error(chalk12.red("Feil:"), error);
1961
+ }
1962
+ }
1963
+ async function libraryAddCommand(slug) {
1964
+ const projectRoot = findProjectRoot();
1965
+ if (!projectRoot) {
1966
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
1967
+ return;
1968
+ }
1969
+ const config = getProjectConfig(projectRoot);
1970
+ if (!config) {
1971
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
1972
+ return;
1973
+ }
1974
+ const spinner = ora8(`Henter snippet "${slug}"...`).start();
1975
+ try {
1976
+ const client = createApiClient(config);
1977
+ const snippet = await client.getLibrarySnippet(slug);
1978
+ const ext = snippet.type === "javascript" ? "js" : "css";
1979
+ const scriptsDir = getScriptsDir(projectRoot, config);
1980
+ if (!existsSync5(scriptsDir)) {
1981
+ mkdirSync2(scriptsDir, { recursive: true });
1982
+ }
1983
+ const filePath = join5(scriptsDir, `${snippet.slug}.${ext}`);
1984
+ if (existsSync5(filePath)) {
1985
+ spinner.fail(`Filen finnes allerede: ${snippet.slug}.${ext}`);
1986
+ console.log(chalk12.dim("Slett den f\xF8rst eller bruk et annet navn."));
1987
+ return;
1988
+ }
1989
+ writeFileSync3(filePath, snippet.code);
1990
+ try {
1991
+ await client.recordLibraryUsage(snippet.id);
1992
+ } catch {
1993
+ }
1994
+ spinner.succeed(chalk12.green(`${snippet.slug}.${ext}`) + chalk12.dim(` \u2190 ${snippet.name}`));
1995
+ console.log();
1996
+ console.log(chalk12.dim(" Filen er kopiert til prosjektet ditt."));
1997
+ console.log(chalk12.dim(" Kj\xF8r ") + chalk12.cyan("kode push") + chalk12.dim(" for \xE5 laste opp til CDN."));
1998
+ console.log();
1999
+ } catch (error) {
2000
+ spinner.fail(`Fant ikke snippet "${slug}"`);
2001
+ console.error(chalk12.red("Feil:"), error);
2002
+ }
2003
+ }
2004
+ async function libraryPullCommand() {
2005
+ const projectRoot = findProjectRoot();
2006
+ if (!projectRoot) {
2007
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
2008
+ return;
2009
+ }
2010
+ const config = getProjectConfig(projectRoot);
2011
+ if (!config) {
2012
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
2013
+ return;
2014
+ }
2015
+ const spinner = ora8("Henter bibliotek...").start();
2016
+ try {
2017
+ const client = createApiClient(config);
2018
+ const [snippets, folders] = await Promise.all([
2019
+ client.listLibrary(),
2020
+ client.listLibraryFolders()
2021
+ ]);
2022
+ if (snippets.length === 0) {
2023
+ spinner.succeed("Biblioteket er tomt \u2014 ingenting \xE5 laste ned.");
2024
+ return;
2025
+ }
2026
+ const scriptsDir = getScriptsDir(projectRoot, config);
2027
+ const libraryDir = join5(scriptsDir, "library");
2028
+ const folderMap = /* @__PURE__ */ new Map();
2029
+ for (const f of folders) {
2030
+ folderMap.set(f.id, f.slug);
2031
+ }
2032
+ let downloaded = 0;
2033
+ for (const s of snippets) {
2034
+ const folderId = s.folder_id;
2035
+ const dirName = folderId && folderMap.get(folderId) || s.category || "other";
2036
+ const targetDir = join5(libraryDir, dirName);
2037
+ if (!existsSync5(targetDir)) {
2038
+ mkdirSync2(targetDir, { recursive: true });
2039
+ }
2040
+ const ext = s.type === "javascript" ? "js" : "css";
2041
+ const filePath = join5(targetDir, `${s.slug}.${ext}`);
2042
+ try {
2043
+ const full = await client.getLibrarySnippet(s.slug);
2044
+ writeFileSync3(filePath, full.code);
2045
+ downloaded++;
2046
+ } catch {
2047
+ }
2048
+ }
2049
+ spinner.succeed(`Lastet ned ${downloaded} snippets til ${chalk12.dim("library/")}`);
2050
+ console.log(chalk12.dim(" Disse filene er kun referanse \u2014 de deployes ikke."));
2051
+ console.log();
2052
+ } catch (error) {
2053
+ spinner.fail("Kunne ikke laste ned bibliotek");
2054
+ console.error(chalk12.red("Feil:"), error);
2055
+ }
2056
+ }
2057
+ async function libraryPushCommand(file, options = {}) {
2058
+ const projectRoot = findProjectRoot();
2059
+ if (!projectRoot) {
2060
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
2061
+ return;
2062
+ }
2063
+ const config = getProjectConfig(projectRoot);
2064
+ if (!config) {
2065
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
2066
+ return;
2067
+ }
2068
+ const scriptsDir = getScriptsDir(projectRoot, config);
2069
+ const filePath = existsSync5(file) ? file : join5(scriptsDir, file);
2070
+ if (!existsSync5(filePath)) {
2071
+ console.log(chalk12.red(`Filen finnes ikke: ${file}`));
2072
+ return;
2073
+ }
2074
+ const content = readFileSync5(filePath, "utf-8");
2075
+ const name = basename2(file, extname2(file));
2076
+ const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2077
+ const type = extname2(filePath) === ".css" ? "css" : "javascript";
2078
+ console.log();
2079
+ console.log(chalk12.bold(" Push til globalt bibliotek"));
2080
+ console.log();
2081
+ console.log(chalk12.dim(` Fil: ${basename2(filePath)}`));
2082
+ console.log(chalk12.dim(` Slug: ${slug}`));
2083
+ console.log(chalk12.dim(` Type: ${type}`));
2084
+ if (options.folder) console.log(chalk12.dim(` Mappe: ${options.folder}`));
2085
+ console.log(chalk12.dim(` St\xF8rrelse: ${content.length} tegn`));
2086
+ console.log();
2087
+ const spinner = ora8("Laster opp til bibliotek...").start();
2088
+ try {
2089
+ const client = createApiClient(config);
2090
+ let folderId;
2091
+ if (options.folder) {
2092
+ const folders = await client.listLibraryFolders();
2093
+ const existing = folders.find((f) => f.slug === options.folder || f.name.toLowerCase() === options.folder.toLowerCase());
2094
+ if (existing) {
2095
+ folderId = existing.id;
2096
+ } else {
2097
+ const folderSlug = options.folder.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2098
+ const created = await client.createLibraryFolder({
2099
+ name: options.folder.charAt(0).toUpperCase() + options.folder.slice(1),
2100
+ slug: folderSlug
2101
+ });
2102
+ folderId = created.id;
2103
+ }
2104
+ }
2105
+ await client.createLibrarySnippet({
2106
+ name: name.charAt(0).toUpperCase() + name.slice(1).replace(/-/g, " "),
2107
+ slug,
2108
+ type,
2109
+ code: content,
2110
+ ...folderId ? { folderId } : {}
2111
+ });
2112
+ spinner.succeed(chalk12.green(`"${name}" lagt til i biblioteket`));
2113
+ console.log();
2114
+ } catch (error) {
2115
+ spinner.fail("Kunne ikke laste opp til bibliotek");
2116
+ console.error(chalk12.red("Feil:"), error?.message || error);
2117
+ }
2118
+ }
2119
+ async function libraryUpdateCommand(slug, options = {}) {
2120
+ const projectRoot = findProjectRoot();
2121
+ if (!projectRoot) {
2122
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
2123
+ return;
2124
+ }
2125
+ const config = getProjectConfig(projectRoot);
2126
+ if (!config) {
2127
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
2128
+ return;
2129
+ }
2130
+ const scriptsDir = getScriptsDir(projectRoot, config);
2131
+ let filePath = null;
2132
+ if (options.file) {
2133
+ filePath = existsSync5(options.file) ? options.file : join5(scriptsDir, options.file);
2134
+ } else {
2135
+ for (const ext of ["js", "css"]) {
2136
+ const candidate = join5(scriptsDir, `${slug}.${ext}`);
2137
+ if (existsSync5(candidate)) {
2138
+ filePath = candidate;
2139
+ break;
2140
+ }
2141
+ const libCandidate = join5(scriptsDir, "library", `${slug}.${ext}`);
2142
+ if (existsSync5(libCandidate)) {
2143
+ filePath = libCandidate;
2144
+ break;
2145
+ }
2146
+ }
2147
+ }
2148
+ if (!filePath || !existsSync5(filePath)) {
2149
+ console.log(chalk12.red(`Fant ikke lokal fil for "${slug}". Bruk --file for \xE5 spesifisere.`));
2150
+ return;
2151
+ }
2152
+ const content = readFileSync5(filePath, "utf-8");
2153
+ const spinner = ora8(`Oppdaterer "${slug}" i biblioteket...`).start();
2154
+ try {
2155
+ const client = createApiClient(config);
2156
+ const result = await client.updateLibrarySnippet(slug, { code: content });
2157
+ spinner.succeed(chalk12.green(`"${slug}" oppdatert til v${result.version}`));
2158
+ console.log();
2159
+ } catch (error) {
2160
+ spinner.fail(`Kunne ikke oppdatere "${slug}"`);
2161
+ console.error(chalk12.red("Feil:"), error?.message || error);
2162
+ }
2163
+ }
2164
+ async function libraryTrashCommand(options) {
2165
+ const projectRoot = findProjectRoot();
2166
+ if (!projectRoot) {
2167
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
2168
+ return;
2169
+ }
2170
+ const config = getProjectConfig(projectRoot);
2171
+ if (!config) {
2172
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
2173
+ return;
2174
+ }
2175
+ const client = createApiClient(config);
2176
+ if (options.restore) {
2177
+ const spinner2 = ora8(`Gjenoppretter "${options.restore}"...`).start();
2178
+ try {
2179
+ await client.restoreLibrarySnippet(options.restore);
2180
+ spinner2.succeed(chalk12.green(`"${options.restore}" gjenopprettet`));
2181
+ } catch (error) {
2182
+ spinner2.fail("Kunne ikke gjenopprette snippet");
2183
+ console.error(chalk12.red("Feil:"), error?.message || error);
2184
+ }
2185
+ return;
2186
+ }
2187
+ if (options.empty) {
2188
+ const spinner2 = ora8("T\xF8mmer papirkurven...").start();
2189
+ try {
2190
+ const trashed = await client.listLibraryTrash();
2191
+ for (const s of trashed) {
2192
+ await client.permanentDeleteLibrarySnippet(s.id);
2193
+ }
2194
+ spinner2.succeed(chalk12.green(`Slettet ${trashed.length} snippets permanent`));
2195
+ } catch (error) {
2196
+ spinner2.fail("Kunne ikke t\xF8mme papirkurven");
2197
+ console.error(chalk12.red("Feil:"), error?.message || error);
2198
+ }
2199
+ return;
2200
+ }
2201
+ const spinner = ora8("Henter papirkurv...").start();
2202
+ try {
2203
+ const trashed = await client.listLibraryTrash();
2204
+ spinner.stop();
2205
+ if (trashed.length === 0) {
2206
+ console.log(chalk12.dim("Papirkurven er tom."));
2207
+ return;
2208
+ }
2209
+ console.log();
2210
+ console.log(chalk12.bold(` Papirkurv (${trashed.length} snippets)`));
2211
+ console.log();
2212
+ for (const s of trashed) {
2213
+ const typeLabel = s.type === "javascript" ? chalk12.yellow("JS") : chalk12.blue("CSS");
2214
+ const deletedDate = new Date(s.deleted_at);
2215
+ const daysAgo = Math.floor((Date.now() - deletedDate.getTime()) / (1e3 * 60 * 60 * 24));
2216
+ const timeStr = daysAgo === 0 ? "i dag" : daysAgo === 1 ? "i g\xE5r" : `${daysAgo} dager siden`;
2217
+ console.log(` ${typeLabel} ${s.name} ${chalk12.dim(`(slettet ${timeStr})`)}`);
2218
+ }
2219
+ console.log();
2220
+ console.log(chalk12.dim(" Gjenopprett: kode library trash --restore <snippet-id>"));
2221
+ console.log(chalk12.dim(" T\xF8m alt: kode library trash --empty"));
2222
+ console.log();
2223
+ } catch (error) {
2224
+ spinner.fail("Kunne ikke hente papirkurv");
2225
+ console.error(chalk12.red("Feil:"), error);
2226
+ }
2227
+ }
2228
+ async function libraryFoldersCommand(options) {
2229
+ const projectRoot = findProjectRoot();
2230
+ if (!projectRoot) {
2231
+ console.log(chalk12.red('Feil: Ikke i et Cure Kode-prosjekt. Kj\xF8r "kode init" f\xF8rst.'));
2232
+ return;
2233
+ }
2234
+ const config = getProjectConfig(projectRoot);
2235
+ if (!config) {
2236
+ console.log(chalk12.red("Feil: Kunne ikke lese prosjektkonfigurasjon."));
2237
+ return;
2238
+ }
2239
+ const client = createApiClient(config);
2240
+ if (options.create) {
2241
+ const spinner2 = ora8(`Oppretter mappe "${options.create}"...`).start();
2242
+ try {
2243
+ const slug = options.create.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2244
+ await client.createLibraryFolder({
2245
+ name: options.create,
2246
+ slug,
2247
+ description: options.description
2248
+ });
2249
+ spinner2.succeed(chalk12.green(`Mappe "${options.create}" opprettet`));
2250
+ } catch (error) {
2251
+ spinner2.fail("Kunne ikke opprette mappe");
2252
+ console.error(chalk12.red("Feil:"), error?.message || error);
2253
+ }
2254
+ return;
2255
+ }
2256
+ const spinner = ora8("Henter mapper...").start();
2257
+ try {
2258
+ const folders = await client.listLibraryFolders();
2259
+ spinner.stop();
2260
+ if (folders.length === 0) {
2261
+ console.log(chalk12.dim("Ingen mapper i biblioteket."));
2262
+ return;
2263
+ }
2264
+ console.log();
2265
+ console.log(chalk12.bold(` Mapper (${folders.length})`));
2266
+ console.log();
2267
+ const renderFolderTree = (parentId, indent) => {
2268
+ const children = folders.filter((f) => f.parent_id === parentId);
2269
+ for (const f of children) {
2270
+ const desc = f.description ? chalk12.dim(` \u2014 ${f.description}`) : "";
2271
+ console.log(`${indent}\u{1F4C1} ${f.name} ${chalk12.dim(`(${f.snippet_count} snippets)`)}${desc}`);
2272
+ renderFolderTree(f.id, indent + " ");
2273
+ }
2274
+ };
2275
+ renderFolderTree(null, " ");
2276
+ console.log();
2277
+ } catch (error) {
2278
+ spinner.fail("Kunne ikke hente mapper");
2279
+ console.error(chalk12.red("Feil:"), error);
2280
+ }
2281
+ }
2282
+
1790
2283
  // src/cli.ts
1791
2284
  var program = new Command();
1792
2285
  program.name("kode").description("CLI for Cure Kode - manage JS/CSS scripts for Webflow sites").version(CLI_VERSION);
1793
- program.command("init").description("Initialize Cure Kode in current directory").option("-k, --api-key <key>", "API key (from Cure App)").option("-f, --force", "Reinitialize even if already configured").action((options) => {
2286
+ program.command("init").description("Initialize Cure Kode in current directory").option("-k, --api-key <key>", "API key (from Cure App)").option("-f, --force", "Reinitialize even if already configured").option("-d, --dev", "Development mode (use localhost:3000)").action((options) => {
1794
2287
  initCommand(options);
1795
2288
  });
1796
2289
  program.command("upgrade").description("Upgrade existing project to latest CLI version").action(() => {
@@ -1811,6 +2304,9 @@ program.command("diff <script>").description("Show differences between local and
1811
2304
  program.command("delete <script>").description("Delete a script from Cure Kode CDN").option("-f, --force", "Confirm deletion").action((script, options) => {
1812
2305
  deleteCommand(script, options);
1813
2306
  });
2307
+ program.command("types").description("Generate TypeScript types from Webflow CMS collections").action(() => {
2308
+ typesCommand();
2309
+ });
1814
2310
  program.command("watch").description("Watch for changes and auto-push").option("-d, --deploy", "Auto-deploy after each push").action((options) => {
1815
2311
  watchCommand(options);
1816
2312
  });
@@ -1876,6 +2372,50 @@ webflowCmd.command("remove").description("Remove Cure Kode init.js from Webflow"
1876
2372
  webflowCmd.command("status", { isDefault: true }).description("Show current Webflow injection status").action(() => {
1877
2373
  webflowStatusCommand();
1878
2374
  });
2375
+ var libraryCmd = program.command("library").description("Browse and use the global script library (Bibliotek)");
2376
+ libraryCmd.command("list", { isDefault: true }).description("List all library snippets").option("-j, --json", "Output as JSON").option("-t, --tree", "Show folder tree view").action((options) => {
2377
+ libraryListCommand(options);
2378
+ });
2379
+ libraryCmd.command("search <query>").description("Search library by name or tags").action((query) => {
2380
+ librarySearchCommand(query);
2381
+ });
2382
+ libraryCmd.command("add <slug>").description("Copy a library snippet into your project scripts").action((slug) => {
2383
+ libraryAddCommand(slug);
2384
+ });
2385
+ libraryCmd.command("pull").description("Download all library snippets as local references").action(() => {
2386
+ libraryPullCommand();
2387
+ });
2388
+ libraryCmd.command("push <file>").description("Push a local script to the global library").option("-f, --folder <name>", "Target folder (created if needed)").action((file, options) => {
2389
+ libraryPushCommand(file, options);
2390
+ });
2391
+ libraryCmd.command("update <slug>").description("Update a library snippet from a local file").option("-f, --file <path>", "Path to local file (auto-detected if omitted)").action((slug, options) => {
2392
+ libraryUpdateCommand(slug, options);
2393
+ });
2394
+ libraryCmd.command("trash").description("View and manage trashed library snippets").option("-r, --restore <id>", "Restore a trashed snippet by ID").option("--empty", "Permanently delete all trashed snippets").action((options) => {
2395
+ libraryTrashCommand(options);
2396
+ });
2397
+ libraryCmd.command("folders").description("List and manage library folders").option("-c, --create <name>", "Create a new folder").option("-d, --description <text>", "Folder description (used with --create)").action((options) => {
2398
+ libraryFoldersCommand(options);
2399
+ });
2400
+ var pkgCmd = program.command("pkg").description("Package manager for @kode/* packages");
2401
+ pkgCmd.command("add <name>").description("Install a package from the registry").action((name) => {
2402
+ pkgAddCommand(name);
2403
+ });
2404
+ pkgCmd.command("remove <name>").description("Uninstall a package").action((name) => {
2405
+ pkgRemoveCommand(name);
2406
+ });
2407
+ pkgCmd.command("publish").description("Publish a component to the registry").requiredOption("-p, --path <path>", "Path relative to .cure-kode-scripts/").requiredOption("-s, --slug <slug>", "Package slug").option("-d, --description <text>", "Package description").option("-t, --tags <tags>", "Comma-separated tags").action((options) => {
2408
+ pkgPublishCommand(options);
2409
+ });
2410
+ pkgCmd.command("list", { isDefault: true }).description("List available packages").action(() => {
2411
+ pkgListCommand();
2412
+ });
2413
+ pkgCmd.command("info <name>").description("Show package details").action((name) => {
2414
+ pkgInfoCommand(name);
2415
+ });
2416
+ pkgCmd.command("update <name>").description("Update an installed package").action((name) => {
2417
+ pkgUpdateCommand(name);
2418
+ });
1879
2419
  program.command("doctor").description("Diagnose configuration and environment issues").action(() => {
1880
2420
  doctorCommand();
1881
2421
  });