@klarocards/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -0
- package/dist/commands/cheatsheet.d.ts +3 -0
- package/dist/commands/cheatsheet.d.ts.map +1 -0
- package/dist/commands/cheatsheet.js +80 -0
- package/dist/commands/cheatsheet.js.map +1 -0
- package/dist/commands/completion.d.ts +3 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +191 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +77 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/create.d.ts +3 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +121 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/del.d.ts +3 -0
- package/dist/commands/del.d.ts.map +1 -0
- package/dist/commands/del.js +49 -0
- package/dist/commands/del.js.map +1 -0
- package/dist/commands/describe.d.ts +3 -0
- package/dist/commands/describe.d.ts.map +1 -0
- package/dist/commands/describe.js +105 -0
- package/dist/commands/describe.js.map +1 -0
- package/dist/commands/edit.d.ts +3 -0
- package/dist/commands/edit.d.ts.map +1 -0
- package/dist/commands/edit.js +91 -0
- package/dist/commands/edit.js.map +1 -0
- package/dist/commands/fetch.d.ts +3 -0
- package/dist/commands/fetch.d.ts.map +1 -0
- package/dist/commands/fetch.js +129 -0
- package/dist/commands/fetch.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +122 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +7 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +101 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +34 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/ls.d.ts +3 -0
- package/dist/commands/ls.d.ts.map +1 -0
- package/dist/commands/ls.js +174 -0
- package/dist/commands/ls.js.map +1 -0
- package/dist/commands/read.d.ts +3 -0
- package/dist/commands/read.d.ts.map +1 -0
- package/dist/commands/read.js +64 -0
- package/dist/commands/read.js.map +1 -0
- package/dist/commands/set.d.ts +3 -0
- package/dist/commands/set.d.ts.map +1 -0
- package/dist/commands/set.js +61 -0
- package/dist/commands/set.js.map +1 -0
- package/dist/commands/sync.d.ts +3 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +157 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/update.d.ts +4 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +68 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/use.d.ts +3 -0
- package/dist/commands/use.d.ts.map +1 -0
- package/dist/commands/use.js +29 -0
- package/dist/commands/use.js.map +1 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +30 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/completions/bash.d.ts +2 -0
- package/dist/completions/bash.d.ts.map +1 -0
- package/dist/completions/bash.js +134 -0
- package/dist/completions/bash.js.map +1 -0
- package/dist/completions/commands.d.ts +18 -0
- package/dist/completions/commands.d.ts.map +1 -0
- package/dist/completions/commands.js +173 -0
- package/dist/completions/commands.js.map +1 -0
- package/dist/completions/fish.d.ts +2 -0
- package/dist/completions/fish.d.ts.map +1 -0
- package/dist/completions/fish.js +84 -0
- package/dist/completions/fish.js.map +1 -0
- package/dist/completions/zsh.d.ts +2 -0
- package/dist/completions/zsh.d.ts.map +1 -0
- package/dist/completions/zsh.js +113 -0
- package/dist/completions/zsh.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +158 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +34 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +146 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/completion-cache.d.ts +34 -0
- package/dist/lib/completion-cache.d.ts.map +1 -0
- package/dist/lib/completion-cache.js +99 -0
- package/dist/lib/completion-cache.js.map +1 -0
- package/dist/lib/config.d.ts +12 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +111 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/connector.d.ts +17 -0
- package/dist/lib/connector.d.ts.map +1 -0
- package/dist/lib/connector.js +2 -0
- package/dist/lib/connector.js.map +1 -0
- package/dist/lib/defaults.d.ts +9 -0
- package/dist/lib/defaults.d.ts.map +1 -0
- package/dist/lib/defaults.js +58 -0
- package/dist/lib/defaults.js.map +1 -0
- package/dist/lib/trace.d.ts +4 -0
- package/dist/lib/trace.d.ts.map +1 -0
- package/dist/lib/trace.js +13 -0
- package/dist/lib/trace.js.map +1 -0
- package/dist/lib/types.d.ts +70 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/utils/content.d.ts +26 -0
- package/dist/utils/content.d.ts.map +1 -0
- package/dist/utils/content.js +52 -0
- package/dist/utils/content.js.map +1 -0
- package/dist/utils/dimensions.d.ts +17 -0
- package/dist/utils/dimensions.d.ts.map +1 -0
- package/dist/utils/dimensions.js +41 -0
- package/dist/utils/dimensions.js.map +1 -0
- package/dist/utils/editor.d.ts +14 -0
- package/dist/utils/editor.d.ts.map +1 -0
- package/dist/utils/editor.js +56 -0
- package/dist/utils/editor.js.map +1 -0
- package/dist/utils/format.d.ts +17 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +27 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/markdown.d.ts +24 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +50 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/objects.d.ts +12 -0
- package/dist/utils/objects.d.ts.map +1 -0
- package/dist/utils/objects.js +31 -0
- package/dist/utils/objects.js.map +1 -0
- package/dist/utils/slugify.d.ts +10 -0
- package/dist/utils/slugify.d.ts.map +1 -0
- package/dist/utils/slugify.js +18 -0
- package/dist/utils/slugify.js.map +1 -0
- package/dist/utils/story-editor.d.ts +15 -0
- package/dist/utils/story-editor.d.ts.map +1 -0
- package/dist/utils/story-editor.js +43 -0
- package/dist/utils/story-editor.js.map +1 -0
- package/dist/utils/story-markdown.d.ts +36 -0
- package/dist/utils/story-markdown.d.ts.map +1 -0
- package/dist/utils/story-markdown.js +114 -0
- package/dist/utils/story-markdown.js.map +1 -0
- package/dist/utils/table.d.ts +18 -0
- package/dist/utils/table.d.ts.map +1 -0
- package/dist/utils/table.js +57 -0
- package/dist/utils/table.js.map +1 -0
- package/dist/utils/validation.d.ts +8 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +17 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the content directory path for a project.
|
|
3
|
+
*/
|
|
4
|
+
export declare function getContentDir(project: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Ensure the content directory exists, creating it if necessary.
|
|
7
|
+
* Returns the directory path.
|
|
8
|
+
*/
|
|
9
|
+
export declare function ensureContentDir(project: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* List all markdown files in the content directory for a project.
|
|
12
|
+
* Returns an array of filenames (not full paths).
|
|
13
|
+
*/
|
|
14
|
+
export declare function listContentFiles(project: string): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Extract the card identifier from a content filename.
|
|
17
|
+
* Filename format: {identifier}-{slugified-title}.md
|
|
18
|
+
* Returns null if the filename doesn't match the expected pattern.
|
|
19
|
+
*/
|
|
20
|
+
export declare function extractIdentifierFromFilename(filename: string): number | null;
|
|
21
|
+
/**
|
|
22
|
+
* Build a content filename from identifier and title.
|
|
23
|
+
* Format: {identifier}-{slugified-title}.md
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildContentFilename(identifier: string | number, title: string): string;
|
|
26
|
+
//# sourceMappingURL=content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/utils/content.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAM1D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM7E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { existsSync, mkdirSync, readdirSync } from 'node:fs';
|
|
3
|
+
import { getConfigDir } from '../lib/config.js';
|
|
4
|
+
import { slugify } from './slugify.js';
|
|
5
|
+
/**
|
|
6
|
+
* Get the content directory path for a project.
|
|
7
|
+
*/
|
|
8
|
+
export function getContentDir(project) {
|
|
9
|
+
return join(getConfigDir(), 'content', project);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Ensure the content directory exists, creating it if necessary.
|
|
13
|
+
* Returns the directory path.
|
|
14
|
+
*/
|
|
15
|
+
export function ensureContentDir(project) {
|
|
16
|
+
const dir = getContentDir(project);
|
|
17
|
+
if (!existsSync(dir)) {
|
|
18
|
+
mkdirSync(dir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
return dir;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* List all markdown files in the content directory for a project.
|
|
24
|
+
* Returns an array of filenames (not full paths).
|
|
25
|
+
*/
|
|
26
|
+
export function listContentFiles(project) {
|
|
27
|
+
const dir = getContentDir(project);
|
|
28
|
+
if (!existsSync(dir)) {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
return readdirSync(dir).filter(f => f.endsWith('.md'));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Extract the card identifier from a content filename.
|
|
35
|
+
* Filename format: {identifier}-{slugified-title}.md
|
|
36
|
+
* Returns null if the filename doesn't match the expected pattern.
|
|
37
|
+
*/
|
|
38
|
+
export function extractIdentifierFromFilename(filename) {
|
|
39
|
+
const match = filename.match(/^(\d+)-.*\.md$/);
|
|
40
|
+
if (!match) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return parseInt(match[1], 10);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Build a content filename from identifier and title.
|
|
47
|
+
* Format: {identifier}-{slugified-title}.md
|
|
48
|
+
*/
|
|
49
|
+
export function buildContentFilename(identifier, title) {
|
|
50
|
+
return `${identifier}-${slugify(title)}.md`;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/utils/content.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,OAAO,IAAI,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,6BAA6B,CAAC,QAAgB;IAC5D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAA2B,EAAE,KAAa;IAC7E,OAAO,GAAG,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split command line args into regular args and key=value dimensions.
|
|
3
|
+
* @param args - Array of command line arguments
|
|
4
|
+
* @returns Object with regularArgs and dimensionArgs separated
|
|
5
|
+
*/
|
|
6
|
+
export declare function splitArgs(args: string[]): {
|
|
7
|
+
regularArgs: string[];
|
|
8
|
+
dimensionArgs: string[];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Parse dimension arguments from command line (key=value format).
|
|
12
|
+
* @param dimensionArgs - Array of dimension strings in "key=value" format
|
|
13
|
+
* @returns Object mapping dimension keys to values
|
|
14
|
+
* @throws Error if any dimension is not in "key=value" format
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseDimensions(dimensionArgs?: string[]): Record<string, string>;
|
|
17
|
+
//# sourceMappingURL=dimensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimensions.d.ts","sourceRoot":"","sources":["../../src/utils/dimensions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAa5F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBhF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split command line args into regular args and key=value dimensions.
|
|
3
|
+
* @param args - Array of command line arguments
|
|
4
|
+
* @returns Object with regularArgs and dimensionArgs separated
|
|
5
|
+
*/
|
|
6
|
+
export function splitArgs(args) {
|
|
7
|
+
const regularArgs = [];
|
|
8
|
+
const dimensionArgs = [];
|
|
9
|
+
for (const arg of args) {
|
|
10
|
+
if (arg.includes('=')) {
|
|
11
|
+
dimensionArgs.push(arg);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
regularArgs.push(arg);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return { regularArgs, dimensionArgs };
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Parse dimension arguments from command line (key=value format).
|
|
21
|
+
* @param dimensionArgs - Array of dimension strings in "key=value" format
|
|
22
|
+
* @returns Object mapping dimension keys to values
|
|
23
|
+
* @throws Error if any dimension is not in "key=value" format
|
|
24
|
+
*/
|
|
25
|
+
export function parseDimensions(dimensionArgs) {
|
|
26
|
+
const dimensions = {};
|
|
27
|
+
if (!dimensionArgs) {
|
|
28
|
+
return dimensions;
|
|
29
|
+
}
|
|
30
|
+
for (const arg of dimensionArgs) {
|
|
31
|
+
const eqIndex = arg.indexOf('=');
|
|
32
|
+
if (eqIndex === -1) {
|
|
33
|
+
throw new Error(`Invalid dimension format: "${arg}". Expected format: key=value`);
|
|
34
|
+
}
|
|
35
|
+
const key = arg.substring(0, eqIndex);
|
|
36
|
+
const value = arg.substring(eqIndex + 1);
|
|
37
|
+
dimensions[key] = value;
|
|
38
|
+
}
|
|
39
|
+
return dimensions;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=dimensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimensions.js","sourceRoot":"","sources":["../../src/utils/dimensions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,aAAa,GAAa,EAAE,CAAC;IAEnC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,aAAwB;IACtD,MAAM,UAAU,GAA2B,EAAE,CAAC;IAE9C,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,8BAA8B,GAAG,+BAA+B,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACzC,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the user's preferred editor from environment variables.
|
|
3
|
+
* Follows the same convention as git: $VISUAL, then $EDITOR, then 'vi'.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getEditor(): string;
|
|
6
|
+
/**
|
|
7
|
+
* Open content in the user's editor and return the edited content.
|
|
8
|
+
*
|
|
9
|
+
* @param content - Initial content to edit
|
|
10
|
+
* @param filename - Optional filename hint for the temp file (for syntax highlighting)
|
|
11
|
+
* @returns The edited content, or null if the editor exited with an error
|
|
12
|
+
*/
|
|
13
|
+
export declare function openInEditor(content: string, filename?: string): string | null;
|
|
14
|
+
//# sourceMappingURL=editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/utils/editor.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAID;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAY,GAAG,MAAM,GAAG,IAAI,CAuCjF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
import { writeFileSync, readFileSync, unlinkSync } from 'fs';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
/**
|
|
6
|
+
* Get the user's preferred editor from environment variables.
|
|
7
|
+
* Follows the same convention as git: $VISUAL, then $EDITOR, then 'vi'.
|
|
8
|
+
*/
|
|
9
|
+
export function getEditor() {
|
|
10
|
+
return process.env.VISUAL || process.env.EDITOR || 'vi';
|
|
11
|
+
}
|
|
12
|
+
const MAX_FILENAME_LENGTH = 100;
|
|
13
|
+
/**
|
|
14
|
+
* Open content in the user's editor and return the edited content.
|
|
15
|
+
*
|
|
16
|
+
* @param content - Initial content to edit
|
|
17
|
+
* @param filename - Optional filename hint for the temp file (for syntax highlighting)
|
|
18
|
+
* @returns The edited content, or null if the editor exited with an error
|
|
19
|
+
*/
|
|
20
|
+
export function openInEditor(content, filename = 'edit.md') {
|
|
21
|
+
// Truncate filename to avoid ENAMETOOLONG errors
|
|
22
|
+
const safeName = filename.length > MAX_FILENAME_LENGTH
|
|
23
|
+
? filename.slice(0, MAX_FILENAME_LENGTH - 3) + '.md'
|
|
24
|
+
: filename;
|
|
25
|
+
const tempPath = join(tmpdir(), `klaro-${Date.now()}-${safeName}`);
|
|
26
|
+
try {
|
|
27
|
+
// Write content to temp file
|
|
28
|
+
writeFileSync(tempPath, content, 'utf-8');
|
|
29
|
+
// Get editor command
|
|
30
|
+
const editor = getEditor();
|
|
31
|
+
// Spawn editor and wait for it to close
|
|
32
|
+
// Parse editor command to handle cases like "code --wait"
|
|
33
|
+
const parts = editor.split(/\s+/);
|
|
34
|
+
const cmd = parts[0];
|
|
35
|
+
const args = [...parts.slice(1), tempPath];
|
|
36
|
+
const result = spawnSync(cmd, args, {
|
|
37
|
+
stdio: 'inherit',
|
|
38
|
+
});
|
|
39
|
+
if (result.status !== 0) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
// Read edited content
|
|
43
|
+
const edited = readFileSync(tempPath, 'utf-8');
|
|
44
|
+
return edited;
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
// Clean up temp file
|
|
48
|
+
try {
|
|
49
|
+
unlinkSync(tempPath);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Ignore cleanup errors
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/utils/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC;AAC1D,CAAC;AAED,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,QAAQ,GAAG,SAAS;IAChE,iDAAiD;IACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,GAAG,mBAAmB;QACpD,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,GAAG,CAAC,CAAC,GAAG,KAAK;QACpD,CAAC,CAAC,QAAQ,CAAC;IACb,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC,CAAC;IAEnE,IAAI,CAAC;QACH,6BAA6B;QAC7B,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAE1C,qBAAqB;QACrB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAE3B,wCAAwC;QACxC,0DAA0D;QAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE;YAClC,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,sBAAsB;QACtB,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,MAAM,CAAC;IAChB,CAAC;YAAS,CAAC;QACT,qBAAqB;QACrB,IAAI,CAAC;YACH,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Truncate a string to a maximum length, adding ellipsis if truncated.
|
|
3
|
+
*/
|
|
4
|
+
export declare function truncate(str: string, maxLength: number): string;
|
|
5
|
+
/**
|
|
6
|
+
* Format dimension values for display.
|
|
7
|
+
* Shows up to 6 IDs, with ellipsis if there are more.
|
|
8
|
+
* Filters out null IDs.
|
|
9
|
+
*
|
|
10
|
+
* @param values - Array of dimension values with id and optional label
|
|
11
|
+
* @returns Formatted string of IDs
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatDimensionValues(values: Array<{
|
|
14
|
+
id: number | null;
|
|
15
|
+
label?: string;
|
|
16
|
+
}> | undefined): string;
|
|
17
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,GAC/D,MAAM,CAOR"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Truncate a string to a maximum length, adding ellipsis if truncated.
|
|
3
|
+
*/
|
|
4
|
+
export function truncate(str, maxLength) {
|
|
5
|
+
if (maxLength < 4)
|
|
6
|
+
return str.slice(0, maxLength);
|
|
7
|
+
if (str.length <= maxLength)
|
|
8
|
+
return str;
|
|
9
|
+
return str.slice(0, maxLength - 1) + '…';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Format dimension values for display.
|
|
13
|
+
* Shows up to 6 IDs, with ellipsis if there are more.
|
|
14
|
+
* Filters out null IDs.
|
|
15
|
+
*
|
|
16
|
+
* @param values - Array of dimension values with id and optional label
|
|
17
|
+
* @returns Formatted string of IDs
|
|
18
|
+
*/
|
|
19
|
+
export function formatDimensionValues(values) {
|
|
20
|
+
if (!values || values.length === 0) {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
const filtered = values.filter(v => v.id !== null);
|
|
24
|
+
const ids = filtered.slice(0, 6).map(v => v.id);
|
|
25
|
+
return filtered.length > 6 ? `${ids.join(', ')}, ...` : ids.join(', ');
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,SAAiB;IACrD,IAAI,SAAS,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAClD,IAAI,GAAG,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,GAAG,CAAC;IACxC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AAC3C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAgE;IAEhE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAChD,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render markdown text with terminal formatting (colors, styles).
|
|
3
|
+
*/
|
|
4
|
+
export declare function renderMarkdown(text: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Extract YAML frontmatter from markdown content.
|
|
7
|
+
*
|
|
8
|
+
* @param markdown - Markdown content that may contain frontmatter
|
|
9
|
+
* @returns Object with frontmatter (including delimiters) and content
|
|
10
|
+
*/
|
|
11
|
+
export declare function extractFrontmatter(markdown: string): {
|
|
12
|
+
frontmatter: string;
|
|
13
|
+
content: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Render markdown with terminal formatting, preserving YAML frontmatter as-is.
|
|
17
|
+
* Frontmatter is not rendered as markdown but preserved verbatim.
|
|
18
|
+
*
|
|
19
|
+
* @param markdown - Markdown content that may contain frontmatter
|
|
20
|
+
* @param raw - If true, return markdown unchanged
|
|
21
|
+
* @returns Formatted string with frontmatter preserved
|
|
22
|
+
*/
|
|
23
|
+
export declare function renderMarkdownWithFrontmatter(markdown: string, raw: boolean): string;
|
|
24
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAc7F;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAYpF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { marked } from 'marked';
|
|
2
|
+
import { markedTerminal } from 'marked-terminal';
|
|
3
|
+
// Configure marked with terminal renderer
|
|
4
|
+
// Type assertion needed due to outdated @types/marked-terminal
|
|
5
|
+
marked.use(markedTerminal());
|
|
6
|
+
/**
|
|
7
|
+
* Render markdown text with terminal formatting (colors, styles).
|
|
8
|
+
*/
|
|
9
|
+
export function renderMarkdown(text) {
|
|
10
|
+
return marked.parse(text);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Extract YAML frontmatter from markdown content.
|
|
14
|
+
*
|
|
15
|
+
* @param markdown - Markdown content that may contain frontmatter
|
|
16
|
+
* @returns Object with frontmatter (including delimiters) and content
|
|
17
|
+
*/
|
|
18
|
+
export function extractFrontmatter(markdown) {
|
|
19
|
+
if (!markdown.startsWith('---')) {
|
|
20
|
+
return { frontmatter: '', content: markdown };
|
|
21
|
+
}
|
|
22
|
+
const endIndex = markdown.indexOf('---', 3);
|
|
23
|
+
if (endIndex === -1) {
|
|
24
|
+
return { frontmatter: '', content: markdown };
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
frontmatter: markdown.slice(0, endIndex + 3),
|
|
28
|
+
content: markdown.slice(endIndex + 3).trim(),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Render markdown with terminal formatting, preserving YAML frontmatter as-is.
|
|
33
|
+
* Frontmatter is not rendered as markdown but preserved verbatim.
|
|
34
|
+
*
|
|
35
|
+
* @param markdown - Markdown content that may contain frontmatter
|
|
36
|
+
* @param raw - If true, return markdown unchanged
|
|
37
|
+
* @returns Formatted string with frontmatter preserved
|
|
38
|
+
*/
|
|
39
|
+
export function renderMarkdownWithFrontmatter(markdown, raw) {
|
|
40
|
+
if (raw) {
|
|
41
|
+
return markdown;
|
|
42
|
+
}
|
|
43
|
+
const { frontmatter, content } = extractFrontmatter(markdown);
|
|
44
|
+
const renderedContent = renderMarkdown(content);
|
|
45
|
+
if (frontmatter) {
|
|
46
|
+
return frontmatter + '\n\n' + renderedContent;
|
|
47
|
+
}
|
|
48
|
+
return renderedContent;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAmB,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,0CAA0C;AAC1C,+DAA+D;AAC/D,MAAM,CAAC,GAAG,CAAC,cAAc,EAAgC,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAW,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC5C,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAChD,CAAC;IAED,OAAO;QACL,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC;QAC5C,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE;KAC7C,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,6BAA6B,CAAC,QAAgB,EAAE,GAAY;IAC1E,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC9D,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAEhD,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,WAAW,GAAG,MAAM,GAAG,eAAe,CAAC;IAChD,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep merge two objects recursively.
|
|
3
|
+
* Properties from source override properties in target.
|
|
4
|
+
* Nested objects are merged recursively.
|
|
5
|
+
* Arrays and non-object values are replaced, not merged.
|
|
6
|
+
*
|
|
7
|
+
* @param target - Base object to merge into
|
|
8
|
+
* @param source - Object with values to merge from
|
|
9
|
+
* @returns New merged object
|
|
10
|
+
*/
|
|
11
|
+
export declare function deepMerge<T extends object>(target: T, source: Partial<T>): T;
|
|
12
|
+
//# sourceMappingURL=objects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objects.d.ts","sourceRoot":"","sources":["../../src/utils/objects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAuB5E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep merge two objects recursively.
|
|
3
|
+
* Properties from source override properties in target.
|
|
4
|
+
* Nested objects are merged recursively.
|
|
5
|
+
* Arrays and non-object values are replaced, not merged.
|
|
6
|
+
*
|
|
7
|
+
* @param target - Base object to merge into
|
|
8
|
+
* @param source - Object with values to merge from
|
|
9
|
+
* @returns New merged object
|
|
10
|
+
*/
|
|
11
|
+
export function deepMerge(target, source) {
|
|
12
|
+
const result = { ...target };
|
|
13
|
+
for (const key of Object.keys(source)) {
|
|
14
|
+
const sourceValue = source[key];
|
|
15
|
+
const targetValue = result[key];
|
|
16
|
+
if (sourceValue !== undefined &&
|
|
17
|
+
typeof sourceValue === 'object' &&
|
|
18
|
+
sourceValue !== null &&
|
|
19
|
+
!Array.isArray(sourceValue) &&
|
|
20
|
+
typeof targetValue === 'object' &&
|
|
21
|
+
targetValue !== null &&
|
|
22
|
+
!Array.isArray(targetValue)) {
|
|
23
|
+
result[key] = deepMerge(targetValue, sourceValue);
|
|
24
|
+
}
|
|
25
|
+
else if (sourceValue !== undefined) {
|
|
26
|
+
result[key] = sourceValue;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=objects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objects.js","sourceRoot":"","sources":["../../src/utils/objects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAmB,MAAS,EAAE,MAAkB;IACvE,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,EAAO,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAmB,EAAE,CAAC;QACxD,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,IACE,WAAW,KAAK,SAAS;YACzB,OAAO,WAAW,KAAK,QAAQ;YAC/B,WAAW,KAAK,IAAI;YACpB,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;YAC3B,OAAO,WAAW,KAAK,QAAQ;YAC/B,WAAW,KAAK,IAAI;YACpB,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAC3B,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CACrB,WAAqB,EACrB,WAAqB,CACR,CAAC;QAClB,CAAC;aAAM,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,GAAG,WAAyB,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a string to a URL-friendly slug.
|
|
3
|
+
* - Removes accents (normalizes to NFD and strips diacritics)
|
|
4
|
+
* - Converts to lowercase
|
|
5
|
+
* - Replaces spaces and special characters with dashes
|
|
6
|
+
* - Collapses multiple dashes
|
|
7
|
+
* - Trims leading/trailing dashes
|
|
8
|
+
*/
|
|
9
|
+
export declare function slugify(text: string): string;
|
|
10
|
+
//# sourceMappingURL=slugify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slugify.d.ts","sourceRoot":"","sources":["../../src/utils/slugify.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ5C"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a string to a URL-friendly slug.
|
|
3
|
+
* - Removes accents (normalizes to NFD and strips diacritics)
|
|
4
|
+
* - Converts to lowercase
|
|
5
|
+
* - Replaces spaces and special characters with dashes
|
|
6
|
+
* - Collapses multiple dashes
|
|
7
|
+
* - Trims leading/trailing dashes
|
|
8
|
+
*/
|
|
9
|
+
export function slugify(text) {
|
|
10
|
+
return text
|
|
11
|
+
.normalize('NFD') // Decompose accents (é -> e + ́)
|
|
12
|
+
.replace(/[\u0300-\u036f]/g, '') // Remove diacritics
|
|
13
|
+
.toLowerCase()
|
|
14
|
+
.replace(/[^a-z0-9]+/g, '-') // Replace non-alphanumeric with dashes
|
|
15
|
+
.replace(/^-+|-+$/g, '') // Trim leading/trailing dashes
|
|
16
|
+
.replace(/-+/g, '-'); // Collapse multiple dashes
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=slugify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slugify.js","sourceRoot":"","sources":["../../src/utils/slugify.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI;SACR,SAAS,CAAC,KAAK,CAAC,CAAoB,iCAAiC;SACrE,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAK,oBAAoB;SACxD,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAS,uCAAuC;SAC3E,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAa,+BAA+B;SACnE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAgB,2BAA2B;AACpE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Story, UpdateStoryInput } from '../lib/types.js';
|
|
2
|
+
export interface EditStoryResult {
|
|
3
|
+
changed: boolean;
|
|
4
|
+
update?: UpdateStoryInput;
|
|
5
|
+
error?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Open a story in the editor and return the parsed changes.
|
|
9
|
+
*
|
|
10
|
+
* @param story - The story to edit
|
|
11
|
+
* @param dimensions - Optional dimensions to include in YAML frontmatter
|
|
12
|
+
* @returns Result object with changed flag, update data, or error
|
|
13
|
+
*/
|
|
14
|
+
export declare function editStoryInEditor(story: Story, dimensions?: string[]): EditStoryResult;
|
|
15
|
+
//# sourceMappingURL=story-editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-editor.d.ts","sourceRoot":"","sources":["../../src/utils/story-editor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAK/D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,eAAe,CAiCtF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { formatStoryMarkdown, parseStoryMarkdown } from './story-markdown.js';
|
|
2
|
+
import { openInEditor } from './editor.js';
|
|
3
|
+
import { slugify } from './slugify.js';
|
|
4
|
+
/**
|
|
5
|
+
* Open a story in the editor and return the parsed changes.
|
|
6
|
+
*
|
|
7
|
+
* @param story - The story to edit
|
|
8
|
+
* @param dimensions - Optional dimensions to include in YAML frontmatter
|
|
9
|
+
* @returns Result object with changed flag, update data, or error
|
|
10
|
+
*/
|
|
11
|
+
export function editStoryInEditor(story, dimensions) {
|
|
12
|
+
const markdown = formatStoryMarkdown(story, dimensions);
|
|
13
|
+
const filename = `${story.identifier}-${slugify(story.title)}.md`;
|
|
14
|
+
const edited = openInEditor(markdown, filename);
|
|
15
|
+
if (edited === null) {
|
|
16
|
+
return { changed: false, error: 'Editor exited with an error' };
|
|
17
|
+
}
|
|
18
|
+
if (edited.trim() === markdown.trim()) {
|
|
19
|
+
return { changed: false };
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const parsed = parseStoryMarkdown(edited);
|
|
23
|
+
const update = {
|
|
24
|
+
identifier: parseInt(story.identifier, 10),
|
|
25
|
+
title: parsed.title,
|
|
26
|
+
specification: parsed.specification ?? '',
|
|
27
|
+
};
|
|
28
|
+
// Add dimensions if present
|
|
29
|
+
if (parsed.dimensions) {
|
|
30
|
+
for (const [key, value] of Object.entries(parsed.dimensions)) {
|
|
31
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
32
|
+
update[key] = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { changed: true, update };
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
const message = error instanceof Error ? error.message : 'Failed to parse edited content';
|
|
40
|
+
return { changed: false, error: message };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=story-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-editor.js","sourceRoot":"","sources":["../../src/utils/story-editor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAQvC;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAY,EAAE,UAAqB;IACnE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;IAClE,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAEhD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC;IAClE,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QACtC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAqB;YAC/B,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;YAC1C,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,EAAE;SAC1C,CAAC;QACF,4BAA4B;QAC5B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC3D,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,gCAAgC,CAAC;QAC1F,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Story } from '../lib/types.js';
|
|
2
|
+
export interface ParsedStory {
|
|
3
|
+
title: string;
|
|
4
|
+
specification?: string;
|
|
5
|
+
dimensions?: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Format a story as markdown output.
|
|
9
|
+
*
|
|
10
|
+
* - toptitle: first line of the title
|
|
11
|
+
* - summary: remaining lines of the title (if any)
|
|
12
|
+
* - description: the specification field
|
|
13
|
+
* - dimensions: optional array of dimension names to include as YAML frontmatter
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatStoryMarkdown(story: Story, dimensions?: string[]): string;
|
|
16
|
+
/**
|
|
17
|
+
* Parse markdown back into story fields.
|
|
18
|
+
*
|
|
19
|
+
* Format expected:
|
|
20
|
+
* ```
|
|
21
|
+
* ---
|
|
22
|
+
* dimension: value
|
|
23
|
+
* ---
|
|
24
|
+
*
|
|
25
|
+
* # toptitle
|
|
26
|
+
*
|
|
27
|
+
* [summary - optional]
|
|
28
|
+
*
|
|
29
|
+
* [description - optional]
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* If two content blocks exist (separated by blank line), first is summary, second is description.
|
|
33
|
+
* If only one content block exists, it's treated as description.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseStoryMarkdown(markdown: string): ParsedStory;
|
|
36
|
+
//# sourceMappingURL=story-markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-markdown.d.ts","sourceRoot":"","sources":["../../src/utils/story-markdown.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAwC/E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CA4DhE"}
|