g360-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.
Files changed (42) hide show
  1. package/README.md +53 -0
  2. package/package.json +27 -0
  3. package/src/assets/components/G360DragModal.jsx +40 -0
  4. package/src/assets/components/G360Signature.jsx +14 -0
  5. package/src/assets/config/project-types.json +32 -0
  6. package/src/assets/config/skills.json +54 -0
  7. package/src/assets/engine/g360-data-validator.js +44 -0
  8. package/src/assets/engine/g360-engine.js +12 -0
  9. package/src/assets/engine/g360-field-mapper.js +35 -0
  10. package/src/assets/engine/g360-skill-audit.mjs +37 -0
  11. package/src/assets/engine/g360-skill-meta-evaluator.mjs +33 -0
  12. package/src/assets/snippets/snippets.json +24 -0
  13. package/src/assets/templates/python-cli/package.json +7 -0
  14. package/src/assets/templates/python-cli/src/core/skill.json +6 -0
  15. package/src/assets/templates/python-cli/src/main.py +13 -0
  16. package/src/assets/templates/vba-excel/src/Module_Main.bas +6 -0
  17. package/src/assets/templates/vba-excel/src/g360-datamap.bas +46 -0
  18. package/src/assets/templates/vba-excel/src/skill.json +9 -0
  19. package/src/assets/templates/web-pwa/app.js +1 -0
  20. package/src/assets/templates/web-pwa/index.html +24 -0
  21. package/src/assets/templates/web-pwa/package.json +5 -0
  22. package/src/assets/templates/web-pwa/styles.css +28 -0
  23. package/src/cli.js +74 -0
  24. package/src/commands/audit.js +43 -0
  25. package/src/commands/bring.js +57 -0
  26. package/src/commands/clean.js +65 -0
  27. package/src/commands/health.js +66 -0
  28. package/src/commands/init.js +63 -0
  29. package/src/commands/list.js +71 -0
  30. package/src/commands/present.js +54 -0
  31. package/src/commands/update.js +29 -0
  32. package/src/lib/assets.js +38 -0
  33. package/src/lib/auditor.js +67 -0
  34. package/src/lib/checksum.js +27 -0
  35. package/src/lib/config.js +23 -0
  36. package/src/lib/manifest.js +43 -0
  37. package/src/lib/offline.js +33 -0
  38. package/src/lib/presenter.js +24 -0
  39. package/src/lib/progress.js +35 -0
  40. package/src/lib/rollback.js +49 -0
  41. package/src/lib/theme.js +30 -0
  42. package/src/lib/validator.js +41 -0
@@ -0,0 +1,24 @@
1
+ import chalk from 'chalk';
2
+
3
+ export const presenter = {
4
+ formatTree(items, prefix = '', isLast = true) {
5
+ return items.map((item, index) => {
6
+ const isLastItem = index === items.length - 1;
7
+ const connector = isLastItem ? '└── ' : '├── ';
8
+ return `${prefix}${connector}${item}`;
9
+ }).join('\n');
10
+ },
11
+
12
+ formatList(items, columns = 2) {
13
+ const rows = [];
14
+ for (let i = 0; i < items.length; i += columns) {
15
+ const row = items.slice(i, i + columns);
16
+ rows.push(row.join('\t'));
17
+ }
18
+ return rows.join('\n');
19
+ },
20
+
21
+ formatJson(data) {
22
+ return JSON.stringify(data, null, 2);
23
+ }
24
+ };
@@ -0,0 +1,35 @@
1
+ class ProgressBar {
2
+ constructor(message) {
3
+ this.message = message;
4
+ this.current = 0;
5
+ this.total = 100;
6
+ this.spinner = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
7
+ this.index = 0;
8
+ this.interval = null;
9
+ }
10
+
11
+ start() {
12
+ this.interval = setInterval(() => {
13
+ this.index = (this.index + 1) % this.spinner.length;
14
+ const bar = '█'.repeat(Math.floor(this.current / 5)) + '░'.repeat(20 - Math.floor(this.current / 5));
15
+ process.stdout.write(`\r${this.spinner[this.index]} ${this.message} [${bar}] ${this.current}%`);
16
+ }, 100);
17
+ }
18
+
19
+ update(current) {
20
+ this.current = Math.min(Math.max(current, 0), 100);
21
+ }
22
+
23
+ stop() {
24
+ if (this.interval) {
25
+ clearInterval(this.interval);
26
+ process.stdout.write('\r' + ' '.repeat(80) + '\r');
27
+ }
28
+ }
29
+ }
30
+
31
+ export const progress = (message) => {
32
+ const bar = new ProgressBar(message);
33
+ bar.start();
34
+ return bar;
35
+ };
@@ -0,0 +1,49 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+
4
+ export const rollback = {
5
+ history: new Map(),
6
+
7
+ async snapshot(projectDir, label) {
8
+ const snapshot = {
9
+ timestamp: new Date().toISOString(),
10
+ label,
11
+ files: []
12
+ };
13
+
14
+ const g360Dir = path.join(projectDir, 'g360');
15
+ if (fs.existsSync(g360Dir)) {
16
+ const files = fs.readdirSync(g360Dir, { recursive: true, withFileTypes: true });
17
+ snapshot.files = files.map(f => ({
18
+ path: f.fullPath || path.join(g360Dir, f.name),
19
+ type: f.isDirectory() ? 'dir' : 'file'
20
+ }));
21
+ }
22
+
23
+ this.history.set(projectDir, snapshot);
24
+ return snapshot;
25
+ },
26
+
27
+ async restore(projectDir) {
28
+ const snapshot = this.history.get(projectDir);
29
+ if (!snapshot) {
30
+ throw new Error('No snapshot found for this project');
31
+ }
32
+
33
+ const g360Dir = path.join(projectDir, 'g360');
34
+
35
+ if (fs.existsSync(g360Dir)) {
36
+ await fs.remove(g360Dir);
37
+ }
38
+
39
+ for (const file of snapshot.files) {
40
+ if (file.type === 'dir') {
41
+ await fs.ensureDir(file.path);
42
+ } else {
43
+ await fs.ensureFile(file.path);
44
+ }
45
+ }
46
+
47
+ return snapshot;
48
+ }
49
+ };
@@ -0,0 +1,30 @@
1
+ import chalk from 'chalk';
2
+
3
+ export const theme = {
4
+ colors: {
5
+ primary: '#3B82F6',
6
+ secondary: '#10B981',
7
+ accent: '#8B5CF6',
8
+ success: '#22C55E',
9
+ warning: '#F59E0B',
10
+ error: '#EF4444',
11
+ info: '#06B6D4'
12
+ },
13
+
14
+ styles: {
15
+ header: chalk.bold.cyan,
16
+ success: chalk.green,
17
+ error: chalk.red,
18
+ warning: chalk.yellow,
19
+ info: chalk.blue,
20
+ muted: chalk.gray
21
+ },
22
+
23
+ format: {
24
+ title: (text) => chalk.bold.cyan(`\n${text}\n`),
25
+ section: (text) => chalk.bold.yellow(text),
26
+ item: (text) => chalk.white(text),
27
+ key: (text) => chalk.cyan(text),
28
+ value: (text) => chalk.white(text)
29
+ }
30
+ };
@@ -0,0 +1,41 @@
1
+ import fs from 'fs-extra';
2
+
3
+ export const validator = {
4
+ isValidProjectName(name) {
5
+ return /^[a-z0-9][a-z0-9-]*$/.test(name);
6
+ },
7
+
8
+ isValidPath(path) {
9
+ try {
10
+ return fs.existsSync(path);
11
+ } catch {
12
+ return false;
13
+ }
14
+ },
15
+
16
+ validateProject(projectDir) {
17
+ const errors = [];
18
+ const warnings = [];
19
+
20
+ if (!fs.existsSync(projectDir)) {
21
+ errors.push('Project directory does not exist');
22
+ return { valid: false, errors, warnings };
23
+ }
24
+
25
+ const manifestPath = `${projectDir}/g360-manifest.json`;
26
+ if (!fs.existsSync(manifestPath)) {
27
+ warnings.push('No g360-manifest.json found');
28
+ }
29
+
30
+ const g360Dir = `${projectDir}/g360`;
31
+ if (!fs.existsSync(g360Dir)) {
32
+ warnings.push('No g360 directory found');
33
+ }
34
+
35
+ return {
36
+ valid: errors.length === 0,
37
+ errors,
38
+ warnings
39
+ };
40
+ }
41
+ };