spec-up-t 1.3.1 → 1.4.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.
Files changed (130) hide show
  1. package/.github/copilot-instructions.md +13 -0
  2. package/assets/compiled/body.js +17 -11
  3. package/assets/compiled/head.css +6 -4
  4. package/assets/css/collapse-definitions.css +0 -1
  5. package/assets/css/create-pdf.css +4 -2
  6. package/assets/css/create-term-filter.css +4 -4
  7. package/assets/css/definition-buttons-container.css +60 -0
  8. package/assets/css/insert-trefs.css +7 -0
  9. package/assets/css/sidebar-toc.css +2 -1
  10. package/assets/css/terms-and-definitions.css +73 -22
  11. package/assets/js/add-href-to-snapshot-link.js +16 -9
  12. package/assets/js/addAnchorsToTerms.js +1 -1
  13. package/assets/js/charts.js +10 -0
  14. package/assets/js/collapse-definitions.js +13 -2
  15. package/assets/js/collapse-meta-info.js +11 -9
  16. package/assets/js/definition-button-container-utils.js +82 -0
  17. package/assets/js/edit-term-buttons.js +77 -20
  18. package/assets/js/github-issues.js +35 -0
  19. package/assets/js/github-repo-info.js +144 -0
  20. package/assets/js/highlight-heading-plus-sibling-nodes.test.js +18 -0
  21. package/assets/js/insert-trefs.js +62 -13
  22. package/assets/js/mermaid-diagrams.js +11 -0
  23. package/assets/js/terminology-section-utility-container/README.md +107 -0
  24. package/assets/js/terminology-section-utility-container/create-alphabet-index.js +17 -0
  25. package/assets/js/{create-term-filter.js → terminology-section-utility-container/create-term-filter.js} +11 -44
  26. package/assets/js/terminology-section-utility-container/hide-show-utility-container.js +21 -0
  27. package/assets/js/terminology-section-utility-container/search.js +203 -0
  28. package/assets/js/terminology-section-utility-container.js +203 -0
  29. package/assets/js/tooltips.js +283 -0
  30. package/config/asset-map.json +24 -16
  31. package/index.js +57 -390
  32. package/package.json +5 -2
  33. package/src/add-remove-xref-source.js +20 -21
  34. package/src/collect-external-references.js +8 -337
  35. package/src/collect-external-references.test.js +440 -33
  36. package/src/configure.js +8 -109
  37. package/src/create-docx.js +7 -6
  38. package/src/create-pdf.js +15 -14
  39. package/src/freeze-spec-data.js +46 -0
  40. package/src/git-info.test.js +76 -0
  41. package/src/health-check/destination-gitignore-checker.js +5 -3
  42. package/src/health-check/external-specs-checker.js +5 -4
  43. package/src/health-check/specs-configuration-checker.js +2 -1
  44. package/src/health-check/term-references-checker.js +5 -3
  45. package/src/health-check/terms-intro-checker.js +2 -1
  46. package/src/health-check/tref-term-checker.js +8 -7
  47. package/src/health-check.js +8 -7
  48. package/src/init.js +3 -2
  49. package/src/install-from-boilerplate/add-gitignore-entries.js +3 -2
  50. package/src/install-from-boilerplate/add-scripts-keys.js +5 -4
  51. package/src/install-from-boilerplate/boilerplate/README.md +1 -1
  52. package/src/install-from-boilerplate/boilerplate/spec/example-markup-in-markdown.md +1 -1
  53. package/src/install-from-boilerplate/boilerplate/spec/spec-head.md +1 -1
  54. package/src/install-from-boilerplate/boilerplate/specs.json +2 -1
  55. package/src/install-from-boilerplate/config-scripts-keys.js +3 -3
  56. package/src/install-from-boilerplate/copy-boilerplate.js +2 -1
  57. package/src/install-from-boilerplate/copy-system-files.js +4 -3
  58. package/src/install-from-boilerplate/custom-update.js +12 -1
  59. package/src/install-from-boilerplate/help.txt +1 -1
  60. package/src/install-from-boilerplate/menu.sh +6 -6
  61. package/src/json-key-validator.js +17 -11
  62. package/src/markdown-it/README.md +207 -0
  63. package/src/markdown-it/definition-lists.js +397 -0
  64. package/src/markdown-it/index.js +83 -0
  65. package/src/markdown-it/link-enhancement.js +98 -0
  66. package/src/markdown-it/plugins.js +118 -0
  67. package/src/markdown-it/table-enhancement.js +97 -0
  68. package/src/markdown-it/template-tag-syntax.js +152 -0
  69. package/src/parsers/index.js +16 -0
  70. package/src/parsers/spec-parser.js +152 -0
  71. package/src/parsers/spec-parser.test.js +109 -0
  72. package/src/parsers/template-tag-parser.js +277 -0
  73. package/src/parsers/template-tag-parser.test.js +107 -0
  74. package/src/pipeline/configuration/configure-starterpack.js +200 -0
  75. package/src/{create-external-specs-list.js → pipeline/configuration/create-external-specs-list.js} +13 -12
  76. package/src/{create-term-index.js → pipeline/configuration/create-term-index.js} +19 -18
  77. package/src/{create-versions-index.js → pipeline/configuration/create-versions-index.js} +4 -3
  78. package/src/{insert-term-index.js → pipeline/configuration/insert-term-index.js} +2 -2
  79. package/src/pipeline/configuration/prepare-spec-configuration.js +70 -0
  80. package/src/pipeline/parsing/apply-markdown-it-extensions.js +35 -0
  81. package/src/pipeline/parsing/create-markdown-parser.js +94 -0
  82. package/src/pipeline/parsing/create-markdown-parser.test.js +49 -0
  83. package/src/{html-dom-processor.js → pipeline/postprocessing/definition-list-postprocessor.js} +69 -10
  84. package/src/{escape-handler.js → pipeline/preprocessing/escape-processor.js} +3 -1
  85. package/src/{fix-markdown-files.js → pipeline/preprocessing/normalize-terminology-markdown.js} +41 -31
  86. package/src/pipeline/references/collect-external-references.js +307 -0
  87. package/src/pipeline/references/external-references-service.js +231 -0
  88. package/src/pipeline/references/fetch-terms-from-index.js +198 -0
  89. package/src/pipeline/references/match-term.js +34 -0
  90. package/src/{collectExternalReferences/matchTerm.test.js → pipeline/references/match-term.test.js} +8 -2
  91. package/src/pipeline/references/process-xtrefs-data.js +94 -0
  92. package/src/pipeline/references/xtref-utils.js +166 -0
  93. package/src/pipeline/rendering/render-spec-document.js +146 -0
  94. package/src/pipeline/rendering/render-utils.js +154 -0
  95. package/src/utils/LOGGER.md +81 -0
  96. package/src/utils/{doesUrlExist.js → does-url-exist.js} +4 -3
  97. package/src/utils/fetch.js +5 -4
  98. package/src/utils/file-opener.js +3 -2
  99. package/src/utils/git-info.js +77 -0
  100. package/src/utils/logger.js +74 -0
  101. package/src/utils/regex-patterns.js +471 -0
  102. package/src/utils/regex-patterns.test.js +281 -0
  103. package/templates/template.html +56 -21
  104. package/assets/js/create-alphabet-index.js +0 -60
  105. package/assets/js/hide-show-utility-container.js +0 -16
  106. package/assets/js/index.js +0 -87
  107. package/assets/js/search.js +0 -365
  108. package/src/collectExternalReferences/fetchTermsFromIndex.js +0 -284
  109. package/src/collectExternalReferences/matchTerm.js +0 -32
  110. package/src/collectExternalReferences/processXTrefsData.js +0 -108
  111. package/src/freeze.js +0 -90
  112. package/src/markdown-it-extensions.js +0 -395
  113. package/src/references.js +0 -114
  114. /package/assets/css/{bootstrap.min.css → embedded-libraries/bootstrap.min.css} +0 -0
  115. /package/assets/css/{prism.css → embedded-libraries/prism.css} +0 -0
  116. /package/assets/css/{prism.dark.css → embedded-libraries/prism.dark.css} +0 -0
  117. /package/assets/css/{prism.default.css → embedded-libraries/prism.default.css} +0 -0
  118. /package/assets/js/{bootstrap.bundle.min.js → embedded-libraries/bootstrap.bundle.min.js} +0 -0
  119. /package/assets/js/{chart.js → embedded-libraries/chart.js} +0 -0
  120. /package/assets/js/{diff.min.js → embedded-libraries/diff.min.js} +0 -0
  121. /package/assets/js/{font-awesome.js → embedded-libraries/font-awesome.js} +0 -0
  122. /package/assets/js/{mermaid.js → embedded-libraries/mermaid.js} +0 -0
  123. /package/assets/js/{notyf.js → embedded-libraries/notyf.js} +0 -0
  124. /package/assets/js/{popper.js → embedded-libraries/popper.js} +0 -0
  125. /package/assets/js/{prism.dark.js → embedded-libraries/prism.dark.js} +0 -0
  126. /package/assets/js/{prism.default.js → embedded-libraries/prism.default.js} +0 -0
  127. /package/assets/js/{prism.js → embedded-libraries/prism.js} +0 -0
  128. /package/assets/js/{tippy.js → embedded-libraries/tippy.js} +0 -0
  129. /package/src/{escape-mechanism.js → pipeline/preprocessing/escape-placeholder-utils.js} +0 -0
  130. /package/src/utils/{isLineWithDefinition.js → is-line-with-definition.js} +0 -0
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Utility functions for rendering and processing specs.
3
+ * This module centralizes helper functions to reduce complexity in index.js.
4
+ * These functions handle tasks like path normalization, term lookups, and markdown processing.
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const path = require('path');
9
+ const { templateTags, paths, whitespace } = require('../../utils/regex-patterns.js');
10
+
11
+ // Constants used in rendering and processing
12
+ const katexRules = ['math_block', 'math_inline'];
13
+ const replacerRegex = templateTags.replacer;
14
+ const replacerArgsRegex = templateTags.argsSeparator;
15
+ const replacers = [
16
+ {
17
+ test: 'insert',
18
+ transform: function (originalMatch, type, path) {
19
+ if (!path) return '';
20
+ return fs.readFileSync(path, 'utf8');
21
+ }
22
+ }
23
+ ];
24
+
25
+ /**
26
+ * Creates a script element containing XTref data for embedding in HTML.
27
+ * Tests if xtrefs-data.js exists; if not, returns an empty string.
28
+ * @returns {string} The script element or empty string.
29
+ */
30
+ function createScriptElementWithXTrefDataForEmbeddingInHtml() {
31
+ const inputPath = path.join('.cache', 'xtrefs-data.js');
32
+ let xtrefsData = '';
33
+ if (fs.existsSync(inputPath)) {
34
+ xtrefsData = '<script>' + fs.readFileSync(inputPath, 'utf8') + '</script>';
35
+ }
36
+ return xtrefsData;
37
+ }
38
+
39
+ /**
40
+ * Looks up an xref term from the allXTrefs data.
41
+ * @param {string} externalSpec - The external spec identifier.
42
+ * @param {string} termName - The term name to look up.
43
+ * @returns {Object|null} The term object if found, null otherwise.
44
+ */
45
+ function lookupXrefTerm(externalSpec, termName) {
46
+ try {
47
+ const xtrefsPath = path.join('.cache', 'xtrefs-data.json');
48
+ if (!fs.existsSync(xtrefsPath)) {
49
+ return null;
50
+ }
51
+
52
+ const allXTrefs = fs.readJsonSync(xtrefsPath);
53
+ if (!allXTrefs || !allXTrefs.xtrefs) {
54
+ return null;
55
+ }
56
+
57
+ const termKey = termName.replace(whitespace.oneOrMore, '-').toLowerCase();
58
+ const foundTerm = allXTrefs.xtrefs.find(xtref =>
59
+ xtref.externalSpec === externalSpec &&
60
+ xtref.term === termKey &&
61
+ xtref.source === 'xref'
62
+ );
63
+
64
+ return foundTerm || null;
65
+ } catch (error) {
66
+ console.warn(`Error looking up xref term ${externalSpec}:${termName}:`, error.message);
67
+ return null;
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Processes custom tag patterns in markdown content and applies transformation functions.
73
+ * Scans for patterns like [[tref:spec,term]] and replaces them with HTML equivalents.
74
+ * @param {string} doc - The markdown document to process.
75
+ * @returns {string} The processed document with tags replaced.
76
+ */
77
+ function applyReplacers(doc) {
78
+ const { processWithEscapes } = require('../preprocessing/escape-processor.js');
79
+ return processWithEscapes(doc, function (content) {
80
+ return content.replace(replacerRegex, function (match, type, args) {
81
+ let replacer = replacers.find(r => type.trim().match(r.test));
82
+ if (replacer) {
83
+ let argsArray = args ? args.trim().split(replacerArgsRegex) : [];
84
+ return replacer.transform(match, type, ...argsArray);
85
+ }
86
+ return match;
87
+ });
88
+ });
89
+ }
90
+
91
+ /**
92
+ * Normalizes a path by trimming trailing slashes and adding a leading slash.
93
+ * @param {string} path - The path to normalize.
94
+ * @returns {string} The normalized path.
95
+ */
96
+ function normalizePath(path) {
97
+ return path.trim().replace(paths.trailingSlash, '') + '/';
98
+ }
99
+
100
+ /**
101
+ * Renders a reference group for a given type.
102
+ * @param {string} type - The type of reference group.
103
+ * @param {Object} specGroups - The spec groups object.
104
+ * @returns {string} The rendered HTML for the reference group.
105
+ */
106
+ function renderRefGroup(type, specGroups) {
107
+ let group = specGroups[type];
108
+ if (!group) return '';
109
+
110
+ let html = Object.keys(group).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).reduce((html, name) => {
111
+ let ref = group[name];
112
+ return html += `
113
+ <dt id="ref:${name}">${name}</dt>
114
+ <dd>
115
+ <cite><a href="${ref.href}">${ref.title}</a></cite>.
116
+ ${ref.authors.join('; ')}; ${ref.rawDate}. <span class="reference-status">Status: ${ref.status}</span>.
117
+ </dd>
118
+ `;
119
+ }, '<dl class="reference-list">');
120
+ return `\n${html}\n</dl>\n`;
121
+ }
122
+
123
+ /**
124
+ * Finds the KaTeX distribution path.
125
+ * Checks common locations for the KaTeX package.
126
+ * @returns {string} The path to the KaTeX distribution.
127
+ * @throws {Error} If KaTeX distribution cannot be located.
128
+ */
129
+ function findKatexDist() {
130
+ const relpath = "node_modules/katex/dist";
131
+ const paths = [
132
+ path.join(process.cwd(), relpath),
133
+ path.join(__dirname, relpath),
134
+ ];
135
+ for (const abspath of paths) {
136
+ if (fs.existsSync(abspath)) {
137
+ return abspath;
138
+ }
139
+ }
140
+ throw new Error("katex distribution could not be located");
141
+ }
142
+
143
+ module.exports = {
144
+ katexRules,
145
+ replacerRegex,
146
+ replacerArgsRegex,
147
+ replacers,
148
+ createScriptElementWithXTrefDataForEmbeddingInHtml,
149
+ lookupXrefTerm,
150
+ applyReplacers,
151
+ normalizePath,
152
+ renderRefGroup,
153
+ findKatexDist
154
+ };
@@ -0,0 +1,81 @@
1
+ # Logger Utility
2
+
3
+ A centralized logging utility for the spec-up-t project that provides consistent, color-coded console output using chalk.
4
+
5
+ ## Features
6
+
7
+ - **Color-coded messages** for different log levels
8
+ - **Consistent icons** and formatting
9
+ - **Progress indicators** with visual progress bars
10
+ - **Section separators** for organized output
11
+ - **Terminal-friendly** symbols that work across platforms
12
+
13
+ ## Usage
14
+
15
+ ```javascript
16
+ const Logger = require('./src/utils/logger');
17
+
18
+ // Success messages (green with checkmark)
19
+ Logger.success('Operation completed successfully');
20
+
21
+ // Error messages (red with X mark)
22
+ Logger.error('Failed to process request');
23
+
24
+ // Warning messages (yellow with warning symbol)
25
+ Logger.warn('Configuration file not found, using defaults');
26
+
27
+ // Info messages (blue with info symbol)
28
+ Logger.info('Processing 42 external references');
29
+
30
+ // Processing status (cyan with arrow)
31
+ Logger.process('Processing repository: owner/repo (15 terms)');
32
+
33
+ // Highlighted information (magenta with star)
34
+ Logger.highlight('Grouped 42 terms into 6 repositories');
35
+
36
+ // Progress indicators
37
+ Logger.progress(3, 5, 'Processing terms'); // Shows: [████████████░░░░░░░░] 60% Processing terms
38
+
39
+ // Section separators
40
+ Logger.separator(); // Shows: ════════════════════════════════════════════════════════════
41
+ ```
42
+
43
+ ## Log Levels
44
+
45
+ | Method | Color | Icon | Purpose |
46
+ |--------|-------|------|---------|
47
+ | `success()` | Green | ✓ | Successful operations |
48
+ | `error()` | Red | ✗ | Errors and failures |
49
+ | `warn()` | Yellow | ⚠ | Warnings and non-critical issues |
50
+ | `info()` | Blue | ℹ | General information |
51
+ | `process()` | Cyan | → | Processing status updates |
52
+ | `highlight()` | Magenta | ★ | Important data/summaries |
53
+ | `debug()` | Gray | ◦ | Debug information |
54
+
55
+ ## Migration from console.log
56
+
57
+ **Before:**
58
+ ```javascript
59
+ console.log(`✅ Successfully processed ${count} items`);
60
+ console.log(`❌ Failed to fetch data from ${url}`);
61
+ console.log(`⚠️ Missing configuration file`);
62
+ ```
63
+
64
+ **After:**
65
+ ```javascript
66
+ Logger.success(`Successfully processed ${count} items`);
67
+ Logger.error(`Failed to fetch data from ${url}`);
68
+ Logger.warn('Missing configuration file');
69
+ ```
70
+
71
+ ## Dependencies
72
+
73
+ - `chalk@4` - For terminal colors (CommonJS compatible version)
74
+
75
+ ## Installation
76
+
77
+ The logger is automatically available when chalk v4 is installed:
78
+
79
+ ```bash
80
+ npm install chalk@4
81
+ ```
@@ -1,4 +1,5 @@
1
1
  const axios = require('axios');
2
+ const Logger = require('./logger');
2
3
 
3
4
  /**
4
5
  * Checks if a URL returns a 200 status code.
@@ -12,11 +13,11 @@ async function doesUrlExist(url) {
12
13
  } catch (error) {
13
14
  // Handle specific error cases for better logging/debugging
14
15
  if (error.response && error.response.status === 404) {
15
- console.debug('URL does not exist:', url);
16
+ Logger.debug('URL does not exist:', url);
16
17
  } else if (error.code === 'ENOTFOUND' || error.code === 'ECONNABORTED') {
17
- console.debug('Network issues with URL:', url);
18
+ Logger.debug('Network issues with URL:', url);
18
19
  } else {
19
- console.debug('Failed to check URL:', url, error.message);
20
+ Logger.debug('Failed to check URL:', url, error.message);
20
21
  }
21
22
  return false;
22
23
  }
@@ -3,6 +3,7 @@
3
3
  */
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
+ const Logger = require('./logger');
6
7
 
7
8
  /**
8
9
  * Fetches the .cache/specs-generated.json file and returns it as a JavaScript object
@@ -21,7 +22,7 @@ function fetchSpecs() {
21
22
 
22
23
  return specs;
23
24
  } catch (error) {
24
- console.error('Error fetching .cache/specs-generated.json:', error.message);
25
+ Logger.error('Error fetching .cache/specs-generated.json:', error.message);
25
26
  return null;
26
27
  }
27
28
  }
@@ -43,7 +44,7 @@ function fetchExternalTerms() {
43
44
 
44
45
  return xtrefs;
45
46
  } catch (error) {
46
- console.error('Error fetching .cache/xtrefs-data.json:', error.message);
47
+ Logger.error('Error fetching .cache/xtrefs-data.json:', error.message);
47
48
  return null;
48
49
  }
49
50
  }
@@ -65,7 +66,7 @@ async function fetchSpecsAsync() {
65
66
 
66
67
  return specs;
67
68
  } catch (error) {
68
- console.error('Error fetching .cache/specs-generated.json:', error.message);
69
+ Logger.error('Error fetching .cache/specs-generated.json:', error.message);
69
70
  return null;
70
71
  }
71
72
  }
@@ -87,7 +88,7 @@ async function fetchExternalTermsAsync() {
87
88
 
88
89
  return xtrefs;
89
90
  } catch (error) {
90
- console.error('Error fetching .cache/xtrefs-data.json:', error.message);
91
+ Logger.error('Error fetching .cache/xtrefs-data.json:', error.message);
91
92
  return null;
92
93
  }
93
94
  }
@@ -1,5 +1,6 @@
1
1
  const fs = require('fs');
2
2
  const { spawnSync } = require('child_process');
3
+ const Logger = require('./logger');
3
4
 
4
5
  /**
5
6
  * Helper function to get the absolute path of a command
@@ -35,7 +36,7 @@ function getCommandPath(command) {
35
36
 
36
37
  // If we can't find the absolute path, return the command name as fallback
37
38
  // This maintains functionality while logging the issue
38
- console.warn(`Warning: Could not find absolute path for command '${command}', using relative path as fallback`);
39
+ Logger.warn(`Could not find absolute path for command '${command}', using relative path as fallback`);
39
40
  return command;
40
41
  }
41
42
 
@@ -67,7 +68,7 @@ function openFile(filePath) {
67
68
  const result = spawnSync(openCommand, [filePath], { stdio: 'ignore' });
68
69
  return result.status === 0;
69
70
  } catch (error) {
70
- console.error('Failed to open file:', error);
71
+ Logger.error('Failed to open file:', error);
71
72
  return false;
72
73
  }
73
74
  }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Git information utility
3
+ *
4
+ * Provides functions to extract Git repository information including
5
+ * the current branch name and repository details from the working directory.
6
+ *
7
+ * @author Spec-Up-T Team
8
+ * @since 2025-08-31
9
+ */
10
+
11
+ const { execSync } = require('child_process');
12
+ const Logger = require('./logger');
13
+
14
+ /**
15
+ * Gets the current Git branch name
16
+ *
17
+ * @returns {string} The current branch name, or 'main' as fallback
18
+ */
19
+ function getCurrentBranch() {
20
+ try {
21
+ const branch = execSync('git branch --show-current', {
22
+ encoding: 'utf8',
23
+ timeout: 5000,
24
+ stdio: ['pipe', 'pipe', 'pipe']
25
+ }).trim();
26
+
27
+ if (branch) {
28
+ Logger.info(`Current git branch: ${branch}`);
29
+ return branch;
30
+ }
31
+
32
+ // Fallback to checking HEAD if branch name is empty (detached HEAD)
33
+ const head = execSync('git rev-parse --abbrev-ref HEAD', {
34
+ encoding: 'utf8',
35
+ timeout: 5000,
36
+ stdio: ['pipe', 'pipe', 'pipe']
37
+ }).trim();
38
+
39
+ if (head && head !== 'HEAD') {
40
+ Logger.info(`Current git branch (from HEAD): ${head}`);
41
+ return head;
42
+ }
43
+
44
+ Logger.warn('Could not determine git branch, using fallback: main');
45
+ return 'main';
46
+ } catch (error) {
47
+ Logger.warn(`Could not get git branch (${error.message}), using fallback: main`);
48
+ return 'main';
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Creates GitHub repository information meta tag content
54
+ *
55
+ * @param {Object} spec - The spec configuration object
56
+ * @returns {string} Meta tag content in format "username,repo,branch"
57
+ */
58
+ function getGithubRepoInfo(spec) {
59
+ try {
60
+ const source = spec.source || {};
61
+ const account = source.account || 'unknown';
62
+ const repo = source.repo || 'unknown';
63
+ const branch = getCurrentBranch();
64
+
65
+ const content = `${account},${repo},${branch}`;
66
+ Logger.info(`GitHub repo info: ${content}`);
67
+ return content;
68
+ } catch (error) {
69
+ Logger.warn(`Error generating GitHub repo info: ${error.message}`);
70
+ return 'unknown,unknown,main';
71
+ }
72
+ }
73
+
74
+ module.exports = {
75
+ getCurrentBranch,
76
+ getGithubRepoInfo
77
+ };
@@ -0,0 +1,74 @@
1
+ const chalk = require('chalk');
2
+
3
+ /**
4
+ * Logger utility with color-coded console output
5
+ * Provides consistent logging across the spec-up-t application
6
+ */
7
+ class Logger {
8
+ /**
9
+ * Success messages - green with checkmark
10
+ */
11
+ static success(message, ...args) {
12
+ console.log(chalk.green('✅'), chalk.green(message), ...args);
13
+ }
14
+
15
+ /**
16
+ * Error messages - red with X mark
17
+ */
18
+ static error(message, ...args) {
19
+ console.log(chalk.red('❌'), chalk.red(message), ...args);
20
+ }
21
+
22
+ /**
23
+ * Warning messages - yellow with warning symbol
24
+ */
25
+ static warn(message, ...args) {
26
+ console.log(chalk.yellow('🟡'), chalk.yellow(message), ...args);
27
+ }
28
+
29
+ /**
30
+ * Info messages - blue with info symbol
31
+ */
32
+ static info(message, ...args) {
33
+ console.log(chalk.blue('📒'), chalk.blue(message), ...args);
34
+ }
35
+
36
+ /**
37
+ * Processing messages - cyan
38
+ */
39
+ static process(message, ...args) {
40
+ console.log(chalk.cyan('🔄'), chalk.cyan(message), ...args);
41
+ }
42
+
43
+ /**
44
+ * Debug messages - gray
45
+ */
46
+ static debug(message, ...args) {
47
+ console.log(chalk.gray('🔍'), chalk.gray(message), ...args);
48
+ }
49
+
50
+ /**
51
+ * Highlight important data - magenta
52
+ */
53
+ static highlight(message, ...args) {
54
+ console.log(chalk.magenta('✨'), chalk.magenta(message), ...args);
55
+ }
56
+
57
+ /**
58
+ * Section separators
59
+ */
60
+ static separator() {
61
+ console.log(chalk.gray('═'.repeat(60)));
62
+ }
63
+
64
+ /**
65
+ * Progress indicator with counts
66
+ */
67
+ static progress(current, total, message) {
68
+ const percentage = Math.round((current / total) * 100);
69
+ const bar = '█'.repeat(Math.floor(percentage / 5)) + '░'.repeat(20 - Math.floor(percentage / 5));
70
+ console.log(chalk.cyan(`📊 [${bar}] ${percentage}% ${message}`));
71
+ }
72
+ }
73
+
74
+ module.exports = Logger;