legal-markdown-js 2.15.0 ā 2.16.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/interactive/index.js +88 -35
- package/dist/cli/interactive/index.js.map +1 -1
- package/dist/cli/interactive/prompts/file-selector.js +5 -80
- package/dist/cli/interactive/prompts/file-selector.js.map +1 -1
- package/dist/cli/interactive/prompts/ftux-handler.d.ts +20 -0
- package/dist/cli/interactive/prompts/ftux-handler.d.ts.map +1 -0
- package/dist/cli/interactive/prompts/ftux-handler.js +356 -0
- package/dist/cli/interactive/prompts/ftux-handler.js.map +1 -0
- package/dist/cli/interactive/utils/file-input-helpers.d.ts +17 -0
- package/dist/cli/interactive/utils/file-input-helpers.d.ts.map +1 -0
- package/dist/cli/interactive/utils/file-input-helpers.js +96 -0
- package/dist/cli/interactive/utils/file-input-helpers.js.map +1 -0
- package/dist/cli/interactive/utils/installation-detector.d.ts +33 -0
- package/dist/cli/interactive/utils/installation-detector.d.ts.map +1 -0
- package/dist/cli/interactive/utils/installation-detector.js +107 -0
- package/dist/cli/interactive/utils/installation-detector.js.map +1 -0
- package/dist/examples/README.md +267 -0
- package/dist/examples/advanced/complex-nda/README.md +40 -0
- package/dist/examples/advanced/complex-nda/examples/output/nda-metadata.yaml +16 -0
- package/dist/examples/advanced/complex-nda/nda-data.json +71 -0
- package/dist/examples/advanced/complex-nda/nda-template.md +52 -0
- package/dist/examples/advanced/complex-nda/nda-with-data.md +107 -0
- package/dist/examples/advanced/complex-nda/run.sh +59 -0
- package/dist/examples/advanced/office-lease-complete/README.md +41 -0
- package/dist/examples/advanced/office-lease-complete/lease-agreement.md +217 -0
- package/dist/examples/advanced/office-lease-complete/lease-data.json +123 -0
- package/dist/examples/advanced/office-lease-complete/lease-with-data.md +283 -0
- package/dist/examples/advanced/office-lease-complete/run.sh +62 -0
- package/dist/examples/basic-processing/simple-document/README.md +39 -0
- package/dist/examples/basic-processing/simple-document/example.html +64 -0
- package/dist/examples/basic-processing/simple-document/example.md +92 -0
- package/dist/examples/basic-processing/simple-document/example.output.md +64 -0
- package/dist/examples/basic-processing/simple-document/examples/output/metadata.json +20 -0
- package/dist/examples/basic-processing/simple-document/input.html +34 -0
- package/dist/examples/basic-processing/simple-document/input.md +12 -0
- package/dist/examples/basic-processing/simple-document/input.output.md +6 -0
- package/dist/examples/basic-processing/simple-document/run.sh +46 -0
- package/dist/examples/basic-processing/yaml-frontmatter/README.md +37 -0
- package/dist/examples/basic-processing/yaml-frontmatter/document.md +72 -0
- package/dist/examples/basic-processing/yaml-frontmatter/run.sh +45 -0
- package/dist/examples/cross-references/basic-references/README.md +37 -0
- package/dist/examples/cross-references/basic-references/agreement.md +111 -0
- package/dist/examples/cross-references/basic-references/correct-example.md +60 -0
- package/dist/examples/cross-references/basic-references/internal-references.md +48 -0
- package/dist/examples/cross-references/basic-references/run.sh +46 -0
- package/dist/examples/cross-references/complex-references/agreement-data.json +24 -0
- package/dist/examples/data/advanced-metadata.json +8 -0
- package/dist/examples/data/agreement-metadata.json +24 -0
- package/dist/examples/data/ticket-data.json +71 -0
- package/dist/examples/force-commands/README.md +164 -0
- package/dist/examples/force-commands/contract-with-forced-options.md +75 -0
- package/dist/examples/headers/header-tracking/README.md +35 -0
- package/dist/examples/headers/header-tracking/run.sh +40 -0
- package/dist/examples/headers/header-tracking/tracked-document.md +32 -0
- package/dist/examples/headers/mixed-header-styles/README.md +35 -0
- package/dist/examples/headers/mixed-header-styles/document.md +48 -0
- package/dist/examples/headers/mixed-header-styles/run.sh +40 -0
- package/dist/examples/headers/multiple-headers/README.md +35 -0
- package/dist/examples/headers/multiple-headers/contract.md +61 -0
- package/dist/examples/headers/multiple-headers/run.sh +40 -0
- package/dist/examples/imports/frontmatter-merging/README.md +268 -0
- package/dist/examples/imports/frontmatter-merging/components/client-info.md +139 -0
- package/dist/examples/imports/frontmatter-merging/components/service-levels.md +178 -0
- package/dist/examples/imports/frontmatter-merging/components/standard-terms.md +100 -0
- package/dist/examples/imports/frontmatter-merging/main-contract.md +169 -0
- package/dist/examples/imports/frontmatter-merging/output/contract-metadata.json +220 -0
- package/dist/examples/imports/frontmatter-merging/output/contract-metadata.yaml +182 -0
- package/dist/examples/imports/frontmatter-merging/run.sh +274 -0
- package/dist/examples/imports/frontmatter-merging/templates/basic-service-agreement.md +83 -0
- package/dist/examples/imports/frontmatter-merging/templates/complex-enterprise-contract.md +260 -0
- package/dist/examples/imports/frontmatter-merging/templates/output/enterprise-contract-metadata.json +226 -0
- package/dist/examples/imports/frontmatter-merging/templates/output/enterprise-contract-metadata.yaml +188 -0
- package/dist/examples/imports/partial-imports/README.md +38 -0
- package/dist/examples/imports/partial-imports/clauses/confidentiality.md +12 -0
- package/dist/examples/imports/partial-imports/main-contract.md +52 -0
- package/dist/examples/imports/partial-imports/partials/footer.md +3 -0
- package/dist/examples/imports/partial-imports/partials/header.md +3 -0
- package/dist/examples/imports/partial-imports/partials/terms.md +3 -0
- package/dist/examples/imports/partial-imports/run.sh +48 -0
- package/dist/examples/input/README.md +66 -0
- package/dist/examples/input/demo-contract.md +60 -0
- package/dist/examples/input/example.md +92 -0
- package/dist/examples/input/examples/output/metadata.json +20 -0
- package/dist/examples/input/metadata-example.md +94 -0
- package/dist/examples/input/office-lease-with-data.md +297 -0
- package/dist/examples/input/purchase-ticket.md +94 -0
- package/dist/examples/input/simple-contract.md +61 -0
- package/dist/examples/input/ticket-with-data.md +92 -0
- package/dist/examples/input/ticket.md +52 -0
- package/dist/examples/integration/cli-usage/README.md +40 -0
- package/dist/examples/integration/cli-usage/demo-contract.md +60 -0
- package/dist/examples/integration/cli-usage/run.sh +62 -0
- package/dist/examples/integration/cli-usage/simple-contract.md +61 -0
- package/dist/examples/mixins/helper-functions/README.md +36 -0
- package/dist/examples/mixins/helper-functions/contract-data.json +8 -0
- package/dist/examples/mixins/helper-functions/formatted-contract.md +45 -0
- package/dist/examples/mixins/helper-functions/run.sh +55 -0
- package/dist/examples/mixins/template-loops/README.md +34 -0
- package/dist/examples/mixins/template-loops/items-list.md +56 -0
- package/dist/examples/mixins/template-loops/run.sh +40 -0
- package/dist/examples/optional-clauses/boolean-logic/README.md +34 -0
- package/dist/examples/optional-clauses/boolean-logic/complex-conditions.md +101 -0
- package/dist/examples/optional-clauses/boolean-logic/examples/output/nda-metadata.yaml +10 -0
- package/dist/examples/optional-clauses/boolean-logic/run.sh +40 -0
- package/dist/examples/optional-clauses/conditional-content/README.md +35 -0
- package/dist/examples/optional-clauses/conditional-content/nda-template.md +82 -0
- package/dist/examples/optional-clauses/conditional-content/run.sh +40 -0
- package/dist/examples/output/demo-contract-simple.md +44 -0
- package/dist/examples/output-formats/metadata-export/README.md +36 -0
- package/dist/examples/output-formats/metadata-export/document-with-meta.md +94 -0
- package/dist/examples/output-formats/metadata-export/run.sh +44 -0
- package/dist/examples/output-formats/pdf-generation/README.md +36 -0
- package/dist/examples/output-formats/pdf-generation/printable-agreement.md +200 -0
- package/dist/examples/output-formats/pdf-generation/run.sh +44 -0
- package/dist/examples/run-all.sh +105 -0
- package/dist/examples/styles/contract.css +346 -0
- package/dist/examples/styles/ticket.css +100 -0
- package/dist/examples/templates/README.md +30 -0
- package/dist/examples/templates/run.sh +101 -0
- package/package.json +3 -2
|
@@ -29,8 +29,85 @@ import { selectCssFile } from './prompts/css-selector.js';
|
|
|
29
29
|
import { promptOutputFilename } from './prompts/filename.js';
|
|
30
30
|
import { promptArchiveOptions } from './prompts/archive-options.js';
|
|
31
31
|
import { confirmConfiguration } from './prompts/confirmation.js';
|
|
32
|
+
import { handleFirstTimeUserExperience } from './prompts/ftux-handler.js';
|
|
32
33
|
import { InteractiveService } from './service.js';
|
|
33
34
|
import { formatSuccessMessage, formatErrorMessage } from './utils/format-helpers.js';
|
|
35
|
+
/**
|
|
36
|
+
* Run FTUX (First-Time User Experience) mode
|
|
37
|
+
*
|
|
38
|
+
* Provides a guided onboarding experience for new users with options to:
|
|
39
|
+
* - Set up configuration files
|
|
40
|
+
* - Try demo examples
|
|
41
|
+
* - Get help and tutorials
|
|
42
|
+
* - Browse for files manually
|
|
43
|
+
*
|
|
44
|
+
* @returns Promise that resolves when FTUX completes
|
|
45
|
+
* @throws Error when FTUX fails or user cancels
|
|
46
|
+
*/
|
|
47
|
+
async function runFtuxMode() {
|
|
48
|
+
try {
|
|
49
|
+
console.log(chalk.bold.blue('\nš Legal Markdown - First-Time User Experience\n'));
|
|
50
|
+
console.log(chalk.gray("Welcome! Let's get you started with Legal Markdown processing.\n"));
|
|
51
|
+
// Run the FTUX flow
|
|
52
|
+
const selectedFile = await handleFirstTimeUserExperience();
|
|
53
|
+
// If a file was selected from FTUX, continue with normal processing
|
|
54
|
+
if (selectedFile) {
|
|
55
|
+
console.log(chalk.green(`\nā
Selected: ${selectedFile}`));
|
|
56
|
+
console.log(chalk.gray('Continuing with normal processing flow...\n'));
|
|
57
|
+
// Continue with the normal interactive flow starting from step 2
|
|
58
|
+
await continueInteractiveFlow(selectedFile);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
63
|
+
console.log(chalk.yellow('\nš Thanks for trying Legal Markdown!\n'));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log(formatErrorMessage(error instanceof Error ? error.message : String(error)));
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Continue interactive flow from a selected file (used after FTUX)
|
|
72
|
+
*
|
|
73
|
+
* @param inputFile - The file selected from FTUX
|
|
74
|
+
*/
|
|
75
|
+
async function continueInteractiveFlow(inputFile) {
|
|
76
|
+
// Step 2: Select output formats
|
|
77
|
+
const outputFormats = await selectOutputFormats();
|
|
78
|
+
// Step 3: Configure processing options
|
|
79
|
+
const processingOptions = await promptProcessingOptions(outputFormats);
|
|
80
|
+
// Step 4: Select CSS file (if needed)
|
|
81
|
+
const cssFile = await selectCssFile(outputFormats);
|
|
82
|
+
// Step 5: Enter output filename
|
|
83
|
+
const outputFilename = await promptOutputFilename(inputFile);
|
|
84
|
+
// Step 6: Configure archive options
|
|
85
|
+
const archiveResult = await promptArchiveOptions();
|
|
86
|
+
const archiveOptions = {
|
|
87
|
+
enabled: archiveResult.enableArchiving,
|
|
88
|
+
directory: archiveResult.archiveDirectory,
|
|
89
|
+
};
|
|
90
|
+
// Build configuration
|
|
91
|
+
const config = {
|
|
92
|
+
inputFile,
|
|
93
|
+
outputFilename,
|
|
94
|
+
outputFormats,
|
|
95
|
+
processingOptions,
|
|
96
|
+
archiveOptions,
|
|
97
|
+
cssFile,
|
|
98
|
+
};
|
|
99
|
+
// Step 7: Confirm configuration
|
|
100
|
+
const confirmed = await confirmConfiguration(config);
|
|
101
|
+
if (!confirmed) {
|
|
102
|
+
console.log(chalk.yellow('\nā Operation cancelled.\n'));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Step 8: Process files
|
|
106
|
+
const service = new InteractiveService(config);
|
|
107
|
+
const result = await service.processFile(inputFile);
|
|
108
|
+
// Step 9: Show results
|
|
109
|
+
console.log(formatSuccessMessage(result.outputFiles, result.archiveResult));
|
|
110
|
+
}
|
|
34
111
|
/**
|
|
35
112
|
* Main interactive flow that guides users through the complete Legal Markdown processing workflow
|
|
36
113
|
*
|
|
@@ -53,40 +130,8 @@ async function runInteractiveMode() {
|
|
|
53
130
|
console.log(chalk.gray('Follow the prompts to configure your document processing.\n'));
|
|
54
131
|
// Step 1: Select input file
|
|
55
132
|
const inputFile = await selectInputFile();
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
// Step 3: Configure processing options
|
|
59
|
-
const processingOptions = await promptProcessingOptions(outputFormats);
|
|
60
|
-
// Step 4: Select CSS file (if needed)
|
|
61
|
-
const cssFile = await selectCssFile(outputFormats);
|
|
62
|
-
// Step 5: Enter output filename
|
|
63
|
-
const outputFilename = await promptOutputFilename(inputFile);
|
|
64
|
-
// Step 6: Configure archive options
|
|
65
|
-
const archiveResult = await promptArchiveOptions();
|
|
66
|
-
const archiveOptions = {
|
|
67
|
-
enabled: archiveResult.enableArchiving,
|
|
68
|
-
directory: archiveResult.archiveDirectory,
|
|
69
|
-
};
|
|
70
|
-
// Build configuration
|
|
71
|
-
const config = {
|
|
72
|
-
inputFile,
|
|
73
|
-
outputFilename,
|
|
74
|
-
outputFormats,
|
|
75
|
-
processingOptions,
|
|
76
|
-
archiveOptions,
|
|
77
|
-
cssFile,
|
|
78
|
-
};
|
|
79
|
-
// Step 7: Confirm configuration
|
|
80
|
-
const confirmed = await confirmConfiguration(config);
|
|
81
|
-
if (!confirmed) {
|
|
82
|
-
console.log(chalk.yellow('\nā Operation cancelled.\n'));
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
// Step 8: Process files
|
|
86
|
-
const service = new InteractiveService(config);
|
|
87
|
-
const result = await service.processFile(inputFile);
|
|
88
|
-
// Step 9: Show results
|
|
89
|
-
console.log(formatSuccessMessage(result.outputFiles, result.archiveResult));
|
|
133
|
+
// Continue with the rest of the flow
|
|
134
|
+
await continueInteractiveFlow(inputFile);
|
|
90
135
|
}
|
|
91
136
|
catch (error) {
|
|
92
137
|
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
@@ -104,7 +149,15 @@ program
|
|
|
104
149
|
.name('legal-md-ui')
|
|
105
150
|
.description('Interactive CLI for Legal Markdown document processing')
|
|
106
151
|
.version('0.1.0')
|
|
107
|
-
.
|
|
152
|
+
.option('--ftux', 'Launch First-Time User Experience (setup wizard)')
|
|
153
|
+
.action(async (options) => {
|
|
154
|
+
if (options.ftux) {
|
|
155
|
+
await runFtuxMode();
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
await runInteractiveMode();
|
|
159
|
+
}
|
|
160
|
+
});
|
|
108
161
|
// Parse command line arguments
|
|
109
162
|
program.parse();
|
|
110
163
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/interactive/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAElF
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/interactive/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAElF;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,WAAW;IACxB,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC;QACnF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC,CAAC;QAE5F,oBAAoB;QACpB,MAAM,YAAY,GAAG,MAAM,6BAA6B,EAAE,CAAC;QAE3D,oEAAoE;QACpE,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,YAAY,EAAE,CAAC,CAAC,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC,CAAC;YAEvE,iEAAiE;YACjE,MAAM,uBAAuB,CAAC,YAAY,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0CAA0C,CAAC,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,uBAAuB,CAAC,SAAiB;IACtD,gCAAgC;IAChC,MAAM,aAAa,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAElD,uCAAuC;IACvC,MAAM,iBAAiB,GAAG,MAAM,uBAAuB,CAAC,aAAa,CAAC,CAAC;IAEvE,sCAAsC;IACtC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,CAAC;IAEnD,gCAAgC;IAChC,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAE7D,oCAAoC;IACpC,MAAM,aAAa,GAAG,MAAM,oBAAoB,EAAE,CAAC;IACnD,MAAM,cAAc,GAAG;QACrB,OAAO,EAAE,aAAa,CAAC,eAAe;QACtC,SAAS,EAAE,aAAa,CAAC,gBAAgB;KAC1C,CAAC;IAEF,sBAAsB;IACtB,MAAM,MAAM,GAAsB;QAChC,SAAS;QACT,cAAc;QACd,aAAa;QACb,iBAAiB;QACjB,cAAc;QACd,OAAO;KACR,CAAC;IAEF,gCAAgC;IAChC,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAErD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACxD,OAAO;IACT,CAAC;IAED,wBAAwB;IACxB,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IAEpD,uBAAuB;IACvB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,KAAK,UAAU,kBAAkB;IAC/B,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC,CAAC;QAEvF,4BAA4B;QAC5B,MAAM,SAAS,GAAG,MAAM,eAAe,EAAE,CAAC;QAE1C,qCAAqC;QACrC,MAAM,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,iBAAiB;AACjB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,wBAAwB;AACxB,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,wDAAwD,CAAC;KACrE,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,QAAQ,EAAE,kDAAkD,CAAC;KACpE,MAAM,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;IACtB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,WAAW,EAAE,CAAC;IACtB,CAAC;SAAM,CAAC;QACN,MAAM,kBAAkB,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,+BAA+B;AAC/B,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
|
-
import { select
|
|
11
|
-
import * as path from 'path';
|
|
12
|
-
import * as fs from 'fs';
|
|
10
|
+
import { select } from '@inquirer/prompts';
|
|
13
11
|
import chalk from 'chalk';
|
|
14
12
|
import { RESOLVED_PATHS } from '../../../constants/index.js';
|
|
15
|
-
import { scanDirectory
|
|
13
|
+
import { scanDirectory } from '../utils/file-scanner.js';
|
|
16
14
|
import { formatWarningMessage } from '../utils/format-helpers.js';
|
|
15
|
+
import { handleFirstTimeUserExperience } from './ftux-handler.js';
|
|
16
|
+
import { handleBrowseFolder, handleManualInput } from '../utils/file-input-helpers.js';
|
|
17
17
|
/** Option for browsing alternative directories */
|
|
18
18
|
const BROWSE_OPTION = 'š Browse other folder...';
|
|
19
19
|
/** Option for manual path entry */
|
|
@@ -35,7 +35,7 @@ export async function selectInputFile() {
|
|
|
35
35
|
const files = scanDirectory(RESOLVED_PATHS.DEFAULT_INPUT_DIR);
|
|
36
36
|
if (files.length === 0) {
|
|
37
37
|
console.log(formatWarningMessage('No supported files found in the default directory.'));
|
|
38
|
-
return await
|
|
38
|
+
return await handleFirstTimeUserExperience();
|
|
39
39
|
}
|
|
40
40
|
const choices = [
|
|
41
41
|
...files.map(file => ({
|
|
@@ -63,79 +63,4 @@ export async function selectInputFile() {
|
|
|
63
63
|
return selectedFile;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
/**
|
|
67
|
-
* Handle browsing to a different folder
|
|
68
|
-
*/
|
|
69
|
-
async function handleBrowseFolder() {
|
|
70
|
-
const folderPath = await input({
|
|
71
|
-
message: 'Enter folder path to browse:',
|
|
72
|
-
default: RESOLVED_PATHS.DEFAULT_INPUT_DIR,
|
|
73
|
-
validate: (value) => {
|
|
74
|
-
const resolvedPath = path.resolve(value);
|
|
75
|
-
try {
|
|
76
|
-
if (!fs.existsSync(resolvedPath)) {
|
|
77
|
-
return 'Folder does not exist';
|
|
78
|
-
}
|
|
79
|
-
if (!fs.statSync(resolvedPath).isDirectory()) {
|
|
80
|
-
return 'Path is not a directory';
|
|
81
|
-
}
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
return 'Invalid folder path';
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
const resolvedPath = path.resolve(folderPath);
|
|
90
|
-
console.log(chalk.cyan(`š Searching for files in: ${resolvedPath}\n`));
|
|
91
|
-
const files = scanDirectory(resolvedPath);
|
|
92
|
-
if (files.length === 0) {
|
|
93
|
-
console.log(formatWarningMessage('No supported files found in this directory.'));
|
|
94
|
-
return await handleManualInput();
|
|
95
|
-
}
|
|
96
|
-
const choices = [
|
|
97
|
-
...files.map(file => ({
|
|
98
|
-
name: file.name,
|
|
99
|
-
value: file.path,
|
|
100
|
-
})),
|
|
101
|
-
{ name: MANUAL_OPTION, value: MANUAL_OPTION },
|
|
102
|
-
{ name: EXIT_OPTION, value: EXIT_OPTION },
|
|
103
|
-
];
|
|
104
|
-
const selectedFile = await select({
|
|
105
|
-
message: 'Select an input file:',
|
|
106
|
-
choices,
|
|
107
|
-
});
|
|
108
|
-
if (selectedFile === MANUAL_OPTION) {
|
|
109
|
-
return await handleManualInput();
|
|
110
|
-
}
|
|
111
|
-
if (selectedFile === EXIT_OPTION) {
|
|
112
|
-
console.log(chalk.yellow('š Goodbye!'));
|
|
113
|
-
process.exit(0);
|
|
114
|
-
}
|
|
115
|
-
return selectedFile;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Handle manual file path input
|
|
119
|
-
*/
|
|
120
|
-
async function handleManualInput() {
|
|
121
|
-
const filePath = await input({
|
|
122
|
-
message: 'Enter file path:',
|
|
123
|
-
validate: (value) => {
|
|
124
|
-
if (!value.trim()) {
|
|
125
|
-
return 'File path is required';
|
|
126
|
-
}
|
|
127
|
-
const resolvedPath = path.resolve(value.trim());
|
|
128
|
-
if (!isValidFile(resolvedPath)) {
|
|
129
|
-
return 'File does not exist or is not readable';
|
|
130
|
-
}
|
|
131
|
-
const ext = path.extname(resolvedPath).toLowerCase();
|
|
132
|
-
const supportedExts = ['.md', '.markdown', '.rst', '.tex', '.latex', '.txt'];
|
|
133
|
-
if (!supportedExts.includes(ext)) {
|
|
134
|
-
return `Unsupported file type. Supported: ${supportedExts.join(', ')}`;
|
|
135
|
-
}
|
|
136
|
-
return true;
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
return path.resolve(filePath.trim());
|
|
140
|
-
}
|
|
141
66
|
//# sourceMappingURL=file-selector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-selector.js","sourceRoot":"","sources":["../../../../src/cli/interactive/prompts/file-selector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"file-selector.js","sourceRoot":"","sources":["../../../../src/cli/interactive/prompts/file-selector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEpF,kDAAkD;AAClD,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAClD,mCAAmC;AACnC,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAClD,yCAAyC;AACzC,MAAM,WAAW,GAAG,QAAQ,CAAC;AAE7B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8BAA8B,cAAc,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC;IAE5F,MAAM,KAAK,GAAG,aAAa,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAE9D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,oDAAoD,CAAC,CAAC,CAAC;QACxF,OAAO,MAAM,6BAA6B,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,OAAO,GAAG;QACd,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,IAAI;SACjB,CAAC,CAAC;QACH,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE;QAC7C,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE;QAC7C,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE;KAC1C,CAAC;IAEF,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC;QAChC,OAAO,EAAE,uBAAuB;QAChC,OAAO;KACR,CAAC,CAAC;IAEH,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,aAAa;YAChB,OAAO,MAAM,kBAAkB,EAAE,CAAC;QACpC,KAAK,aAAa;YAChB,OAAO,MAAM,iBAAiB,EAAE,CAAC;QACnC,KAAK,WAAW;YACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,MAAM;QACR;YACE,OAAO,YAAY,CAAC;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First Time User Experience (FTUX) handler for Interactive CLI
|
|
3
|
+
*
|
|
4
|
+
* This module provides an improved onboarding experience for new users
|
|
5
|
+
* when no files are found in the default directory, offering setup
|
|
6
|
+
* assistance, demo examples, and guided configuration.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Handle first-time user experience when no files are found
|
|
12
|
+
*
|
|
13
|
+
* Provides a friendly onboarding flow with multiple options to help
|
|
14
|
+
* new users get started with Legal Markdown processing.
|
|
15
|
+
*
|
|
16
|
+
* @returns Promise resolving to the selected input file path
|
|
17
|
+
* @throws Error when user cancels or no valid option is selected
|
|
18
|
+
*/
|
|
19
|
+
export declare function handleFirstTimeUserExperience(): Promise<string>;
|
|
20
|
+
//# sourceMappingURL=ftux-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ftux-handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/interactive/prompts/ftux-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAwCH;;;;;;;;GAQG;AACH,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,MAAM,CAAC,CAuCrE"}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First Time User Experience (FTUX) handler for Interactive CLI
|
|
3
|
+
*
|
|
4
|
+
* This module provides an improved onboarding experience for new users
|
|
5
|
+
* when no files are found in the default directory, offering setup
|
|
6
|
+
* assistance, demo examples, and guided configuration.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { select, input, confirm } from '@inquirer/prompts';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import chalk from 'chalk';
|
|
14
|
+
// import { RESOLVED_PATHS } from '../../../constants/index.js';
|
|
15
|
+
import { scanDirectory } from '../utils/file-scanner.js';
|
|
16
|
+
import { formatWarningMessage } from '../utils/format-helpers.js';
|
|
17
|
+
import { handleBrowseFolder, handleManualInput } from '../utils/file-input-helpers.js';
|
|
18
|
+
import { getEnvFilePath, getInstallationDescription } from '../utils/installation-detector.js';
|
|
19
|
+
/**
|
|
20
|
+
* Get current directory path in a way that works for both ESM and CJS
|
|
21
|
+
* Since we're building from dist, we can use relative paths from the script location
|
|
22
|
+
*/
|
|
23
|
+
function getCurrentDir() {
|
|
24
|
+
// Use process.argv[1] to determine script location - works for both ESM and CJS
|
|
25
|
+
const scriptPath = process.argv[1] || process.cwd();
|
|
26
|
+
return path.dirname(scriptPath);
|
|
27
|
+
}
|
|
28
|
+
/** Option for setting up configuration */
|
|
29
|
+
const SETUP_CONFIG_OPTION = 'š ļø Setup configuration (.env)';
|
|
30
|
+
/** Option for trying a demo example */
|
|
31
|
+
const TRY_DEMO_OPTION = 'šÆ Try a demo example';
|
|
32
|
+
/** Option for browsing different folder */
|
|
33
|
+
const BROWSE_FOLDER_OPTION = 'š Browse different folder';
|
|
34
|
+
/** Option for manual file input */
|
|
35
|
+
const MANUAL_INPUT_OPTION = 'š Enter file path manually';
|
|
36
|
+
/** Option for getting help/tutorial */
|
|
37
|
+
const GET_HELP_OPTION = 'š Show help & tutorial';
|
|
38
|
+
/** Option for exiting */
|
|
39
|
+
const EXIT_OPTION = 'ā Exit';
|
|
40
|
+
/**
|
|
41
|
+
* Handle first-time user experience when no files are found
|
|
42
|
+
*
|
|
43
|
+
* Provides a friendly onboarding flow with multiple options to help
|
|
44
|
+
* new users get started with Legal Markdown processing.
|
|
45
|
+
*
|
|
46
|
+
* @returns Promise resolving to the selected input file path
|
|
47
|
+
* @throws Error when user cancels or no valid option is selected
|
|
48
|
+
*/
|
|
49
|
+
export async function handleFirstTimeUserExperience() {
|
|
50
|
+
console.log(chalk.yellow('\nš Welcome to Legal Markdown!'));
|
|
51
|
+
console.log(chalk.gray("It looks like you're getting started. Let me help you with that.\n"));
|
|
52
|
+
const choice = await select({
|
|
53
|
+
message: 'What would you like to do?',
|
|
54
|
+
choices: [
|
|
55
|
+
{ name: SETUP_CONFIG_OPTION, value: 'setup' },
|
|
56
|
+
{ name: TRY_DEMO_OPTION, value: 'demo' },
|
|
57
|
+
{ name: BROWSE_FOLDER_OPTION, value: 'browse' },
|
|
58
|
+
{ name: MANUAL_INPUT_OPTION, value: 'manual' },
|
|
59
|
+
{ name: GET_HELP_OPTION, value: 'help' },
|
|
60
|
+
{ name: EXIT_OPTION, value: 'exit' },
|
|
61
|
+
],
|
|
62
|
+
});
|
|
63
|
+
switch (choice) {
|
|
64
|
+
case 'setup':
|
|
65
|
+
return await handleSetupConfiguration();
|
|
66
|
+
case 'demo':
|
|
67
|
+
return await handleDemoExample();
|
|
68
|
+
case 'browse':
|
|
69
|
+
return await handleBrowseFolder();
|
|
70
|
+
case 'manual':
|
|
71
|
+
return await handleManualInput();
|
|
72
|
+
case 'help':
|
|
73
|
+
await showHelpAndTutorial();
|
|
74
|
+
// After showing help, ask again
|
|
75
|
+
return await handleFirstTimeUserExperience();
|
|
76
|
+
case 'exit':
|
|
77
|
+
console.log(chalk.yellow('\nš Thanks for trying Legal Markdown!'));
|
|
78
|
+
console.log(chalk.gray('Run ') + chalk.cyan('legal-md-ui') + chalk.gray(" again when you're ready."));
|
|
79
|
+
process.exit(0);
|
|
80
|
+
break;
|
|
81
|
+
default:
|
|
82
|
+
throw new Error('Invalid option selected');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Handle setup configuration workflow
|
|
87
|
+
*/
|
|
88
|
+
async function handleSetupConfiguration() {
|
|
89
|
+
console.log(chalk.cyan('\nš ļø Configuration Setup'));
|
|
90
|
+
console.log(chalk.gray("Let's set up your preferred directories for Legal Markdown processing."));
|
|
91
|
+
console.log(chalk.gray(getInstallationDescription() + '\n'));
|
|
92
|
+
// Ask for input directory
|
|
93
|
+
const inputDir = await input({
|
|
94
|
+
message: 'Where do you keep your markdown files? (input directory)',
|
|
95
|
+
default: process.cwd(),
|
|
96
|
+
validate: value => {
|
|
97
|
+
const resolvedPath = path.resolve(value);
|
|
98
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
99
|
+
return 'Directory does not exist. Please enter a valid path.';
|
|
100
|
+
}
|
|
101
|
+
if (!fs.statSync(resolvedPath).isDirectory()) {
|
|
102
|
+
return 'Path is not a directory.';
|
|
103
|
+
}
|
|
104
|
+
return true;
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
// Ask for output directory
|
|
108
|
+
const outputDir = await input({
|
|
109
|
+
message: 'Where should processed files be saved? (output directory)',
|
|
110
|
+
default: path.join(path.resolve(inputDir), 'output'),
|
|
111
|
+
validate: value => {
|
|
112
|
+
const resolvedPath = path.resolve(value);
|
|
113
|
+
const parentDir = path.dirname(resolvedPath);
|
|
114
|
+
if (!fs.existsSync(parentDir)) {
|
|
115
|
+
return 'Parent directory does not exist.';
|
|
116
|
+
}
|
|
117
|
+
return true;
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
// Create .env configuration using installation-aware path
|
|
121
|
+
const envPath = getEnvFilePath();
|
|
122
|
+
const envContent = `# Legal Markdown Configuration
|
|
123
|
+
# Generated by interactive setup
|
|
124
|
+
|
|
125
|
+
LEGALMD_INPUT_DIR="${path.resolve(inputDir)}"
|
|
126
|
+
LEGALMD_OUTPUT_DIR="${path.resolve(outputDir)}"
|
|
127
|
+
LEGALMD_STYLES_DIR="${path.resolve(inputDir, 'styles')}"
|
|
128
|
+
LEGALMD_ARCHIVE_DIR="${path.resolve(outputDir, 'archive')}"
|
|
129
|
+
`;
|
|
130
|
+
// Check if .env already exists
|
|
131
|
+
if (fs.existsSync(envPath)) {
|
|
132
|
+
const overwrite = await confirm({
|
|
133
|
+
message: 'A .env file already exists. Overwrite it?',
|
|
134
|
+
default: false,
|
|
135
|
+
});
|
|
136
|
+
if (!overwrite) {
|
|
137
|
+
console.log(chalk.yellow('ā ļø Setup cancelled. Using existing configuration.'));
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
fs.writeFileSync(envPath, envContent);
|
|
141
|
+
console.log(chalk.green(`ā
Configuration saved to ${envPath}`));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
fs.writeFileSync(envPath, envContent);
|
|
146
|
+
console.log(chalk.green(`ā
Configuration saved to ${envPath}`));
|
|
147
|
+
}
|
|
148
|
+
// Create output directory if it doesn't exist
|
|
149
|
+
const resolvedOutputDir = path.resolve(outputDir);
|
|
150
|
+
if (!fs.existsSync(resolvedOutputDir)) {
|
|
151
|
+
fs.mkdirSync(resolvedOutputDir, { recursive: true });
|
|
152
|
+
console.log(chalk.green(`ā
Created output directory: ${resolvedOutputDir}`));
|
|
153
|
+
}
|
|
154
|
+
// Now scan for files in the configured input directory
|
|
155
|
+
console.log(chalk.cyan(`\nš Scanning for files in: ${path.resolve(inputDir)}\n`));
|
|
156
|
+
const files = scanDirectory(path.resolve(inputDir));
|
|
157
|
+
if (files.length === 0) {
|
|
158
|
+
console.log(formatWarningMessage('No supported files found in the configured directory.'));
|
|
159
|
+
console.log(chalk.gray('You can add .md, .markdown, .rst, .tex, or .txt files to get started.\n'));
|
|
160
|
+
const nextAction = await select({
|
|
161
|
+
message: 'What would you like to do next?',
|
|
162
|
+
choices: [
|
|
163
|
+
{ name: TRY_DEMO_OPTION, value: 'demo' },
|
|
164
|
+
{ name: MANUAL_INPUT_OPTION, value: 'manual' },
|
|
165
|
+
{ name: EXIT_OPTION, value: 'exit' },
|
|
166
|
+
],
|
|
167
|
+
});
|
|
168
|
+
switch (nextAction) {
|
|
169
|
+
case 'demo':
|
|
170
|
+
return await handleDemoExample();
|
|
171
|
+
case 'manual':
|
|
172
|
+
return await handleManualInput();
|
|
173
|
+
case 'exit':
|
|
174
|
+
process.exit(0);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Show available files
|
|
178
|
+
const choices = [
|
|
179
|
+
...files.map(file => ({
|
|
180
|
+
name: file.name,
|
|
181
|
+
value: file.path,
|
|
182
|
+
})),
|
|
183
|
+
{ name: TRY_DEMO_OPTION, value: 'demo' },
|
|
184
|
+
{ name: EXIT_OPTION, value: 'exit' },
|
|
185
|
+
];
|
|
186
|
+
const selectedFile = await select({
|
|
187
|
+
message: 'Select a file to process:',
|
|
188
|
+
choices,
|
|
189
|
+
});
|
|
190
|
+
if (selectedFile === 'demo') {
|
|
191
|
+
return await handleDemoExample();
|
|
192
|
+
}
|
|
193
|
+
if (selectedFile === 'exit') {
|
|
194
|
+
process.exit(0);
|
|
195
|
+
}
|
|
196
|
+
return selectedFile;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Handle demo example selection
|
|
200
|
+
*/
|
|
201
|
+
async function handleDemoExample() {
|
|
202
|
+
console.log(chalk.cyan('\nšÆ Demo Examples'));
|
|
203
|
+
console.log(chalk.gray('Try Legal Markdown with these built-in examples.\n'));
|
|
204
|
+
// Get examples from the package - try multiple locations
|
|
205
|
+
const currentDir = getCurrentDir();
|
|
206
|
+
const possibleExamplesDirs = [
|
|
207
|
+
// In dist for development or when running from source
|
|
208
|
+
path.join(currentDir, '../../..', 'dist', 'examples'),
|
|
209
|
+
// In node_modules for installed package
|
|
210
|
+
path.join(process.cwd(), 'node_modules', 'legal-markdown-js', 'dist', 'examples'),
|
|
211
|
+
path.join(process.cwd(), 'node_modules', 'legal-markdown-js', 'examples'),
|
|
212
|
+
// Global installation paths
|
|
213
|
+
path.join(path.dirname(process.argv[1] || ''), '..', 'examples'),
|
|
214
|
+
path.join(path.dirname(process.argv[1] || ''), '..', 'dist', 'examples'),
|
|
215
|
+
];
|
|
216
|
+
const availableExamples = [];
|
|
217
|
+
let examplesDir = '';
|
|
218
|
+
// Find the first existing examples directory
|
|
219
|
+
for (const dir of possibleExamplesDirs) {
|
|
220
|
+
if (fs.existsSync(dir)) {
|
|
221
|
+
examplesDir = dir;
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (examplesDir) {
|
|
226
|
+
const basicExample = path.join(examplesDir, 'basic-processing', 'simple-document', 'example.md');
|
|
227
|
+
const advancedExample = path.join(examplesDir, 'advanced', 'complex-nda', 'nda-with-data.md');
|
|
228
|
+
if (fs.existsSync(basicExample)) {
|
|
229
|
+
availableExamples.push({
|
|
230
|
+
name: 'š Basic Document Processing',
|
|
231
|
+
path: basicExample,
|
|
232
|
+
description: 'Simple markdown with template fields',
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
if (fs.existsSync(advancedExample)) {
|
|
236
|
+
availableExamples.push({
|
|
237
|
+
name: 'š Advanced NDA Contract',
|
|
238
|
+
path: advancedExample,
|
|
239
|
+
description: 'Complex contract with conditional clauses',
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Fallback: create a simple demo file in current directory
|
|
244
|
+
if (availableExamples.length === 0) {
|
|
245
|
+
const demoPath = path.join(process.cwd(), 'legal-markdown-demo.md');
|
|
246
|
+
const demoContent = `---
|
|
247
|
+
title: "Sample Legal Document"
|
|
248
|
+
party1: "Acme Corporation"
|
|
249
|
+
party2: "[Enter Client Name]"
|
|
250
|
+
date: "{{formatDate(today, 'MMMM dd, yyyy')}}"
|
|
251
|
+
jurisdiction: "California"
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
# {{title}}
|
|
255
|
+
|
|
256
|
+
This agreement is entered into on {{date}} between {{party1}} and {{party2}}.
|
|
257
|
+
|
|
258
|
+
## 1. Terms and Conditions
|
|
259
|
+
|
|
260
|
+
l. **Effective Date**: This agreement becomes effective on {{date}}.
|
|
261
|
+
|
|
262
|
+
l. **Jurisdiction**: This agreement shall be governed by the laws of {{jurisdiction}}.
|
|
263
|
+
|
|
264
|
+
{{#if party2}}
|
|
265
|
+
l. **Parties**: The contracting parties are {{party1}} and {{party2}}.
|
|
266
|
+
{{else}}
|
|
267
|
+
l. **Party**: The contracting party is {{party1}}.
|
|
268
|
+
{{/if}}
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
*This is a demo document showing Legal Markdown features:*
|
|
273
|
+
- *Template fields: {{party1}}, {{party2}}*
|
|
274
|
+
- *Date formatting: {{date}}*
|
|
275
|
+
- *Conditional clauses: {{#if party2}}*
|
|
276
|
+
- *Automatic numbering: l.*
|
|
277
|
+
`;
|
|
278
|
+
try {
|
|
279
|
+
fs.writeFileSync(demoPath, demoContent);
|
|
280
|
+
availableExamples.push({
|
|
281
|
+
name: 'šÆ Generated Demo Document',
|
|
282
|
+
path: demoPath,
|
|
283
|
+
description: 'A sample document created just for you',
|
|
284
|
+
});
|
|
285
|
+
console.log(chalk.green(`ā
Created demo file: ${demoPath}`));
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
console.log(chalk.yellow(`ā ļø Could not create demo file: ${error instanceof Error ? error.message : String(error)}`));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
if (availableExamples.length === 0) {
|
|
292
|
+
console.log(chalk.red('ā No demo examples available.'));
|
|
293
|
+
return await handleManualInput();
|
|
294
|
+
}
|
|
295
|
+
const choices = [
|
|
296
|
+
...availableExamples.map(example => ({
|
|
297
|
+
name: `${example.name}\n ${chalk.gray(example.description)}`,
|
|
298
|
+
value: example.path,
|
|
299
|
+
})),
|
|
300
|
+
{ name: 'ā Back to main menu', value: 'back' },
|
|
301
|
+
];
|
|
302
|
+
const selectedExample = await select({
|
|
303
|
+
message: 'Choose a demo example:',
|
|
304
|
+
choices,
|
|
305
|
+
});
|
|
306
|
+
if (selectedExample === 'back') {
|
|
307
|
+
return await handleFirstTimeUserExperience();
|
|
308
|
+
}
|
|
309
|
+
console.log(chalk.green(`\nā
Selected demo: ${selectedExample}`));
|
|
310
|
+
console.log(chalk.gray('You can examine this file after processing to see how Legal Markdown works.\n'));
|
|
311
|
+
return selectedExample;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Show help and tutorial information
|
|
315
|
+
*/
|
|
316
|
+
async function showHelpAndTutorial() {
|
|
317
|
+
console.log(chalk.cyan('\nš Legal Markdown Help & Tutorial\n'));
|
|
318
|
+
console.log(chalk.bold('What is Legal Markdown?'));
|
|
319
|
+
console.log(chalk.gray('Legal Markdown is a tool for processing legal documents written in Markdown'));
|
|
320
|
+
console.log(chalk.gray('with YAML metadata and template fields.\n'));
|
|
321
|
+
console.log(chalk.bold('Key Features:'));
|
|
322
|
+
console.log(chalk.gray('⢠š Template fields: {{party1}}, {{date}}, etc.'));
|
|
323
|
+
console.log(chalk.gray('⢠š¢ Auto-numbering: l. for numbered clauses'));
|
|
324
|
+
console.log(chalk.gray('⢠ā Conditional clauses: {{#if condition}}...{{/if}}'));
|
|
325
|
+
console.log(chalk.gray('⢠š
Date formatting: {{formatDate(date, "MMM dd, yyyy")}}'));
|
|
326
|
+
console.log(chalk.gray('⢠š Multiple output formats: HTML, PDF, Markdown'));
|
|
327
|
+
console.log(chalk.gray('⢠šØ Custom styling with CSS\n'));
|
|
328
|
+
console.log(chalk.bold('Example Document Structure:'));
|
|
329
|
+
console.log(chalk.gray('```'));
|
|
330
|
+
console.log(chalk.gray('---'));
|
|
331
|
+
console.log(chalk.gray('title: "My Contract"'));
|
|
332
|
+
console.log(chalk.gray('party1: "Company A"'));
|
|
333
|
+
console.log(chalk.gray('date: "2024-01-15"'));
|
|
334
|
+
console.log(chalk.gray('---'));
|
|
335
|
+
console.log(chalk.gray(''));
|
|
336
|
+
console.log(chalk.gray('# {{title}}'));
|
|
337
|
+
console.log(chalk.gray(''));
|
|
338
|
+
console.log(chalk.gray('Agreement between {{party1}} dated {{formatDate(date, "MMMM dd, yyyy")}}.'));
|
|
339
|
+
console.log(chalk.gray(''));
|
|
340
|
+
console.log(chalk.gray('l. First clause'));
|
|
341
|
+
console.log(chalk.gray('l. Second clause'));
|
|
342
|
+
console.log(chalk.gray('```\n'));
|
|
343
|
+
console.log(chalk.bold('Getting Started:'));
|
|
344
|
+
console.log(chalk.gray('1. š ļø Setup: Configure your input/output directories'));
|
|
345
|
+
console.log(chalk.gray('2. š Files: Create .md files with YAML frontmatter'));
|
|
346
|
+
console.log(chalk.gray('3. šÆ Process: Use this interactive CLI to convert documents'));
|
|
347
|
+
console.log(chalk.gray('4. š Output: Get HTML, PDF, or processed Markdown\n'));
|
|
348
|
+
console.log(chalk.bold('Useful Commands:'));
|
|
349
|
+
console.log(chalk.gray('⢠') + chalk.cyan('legal-md-ui') + chalk.gray(' - Interactive processing'));
|
|
350
|
+
console.log(chalk.gray('⢠') + chalk.cyan('legal-md input.md') + chalk.gray(' - Direct processing'));
|
|
351
|
+
console.log(chalk.gray('⢠') + chalk.cyan('legal-md --help') + chalk.gray(' - Command line help\n'));
|
|
352
|
+
await input({
|
|
353
|
+
message: 'Press Enter to continue...',
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
//# sourceMappingURL=ftux-handler.js.map
|