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.
- package/README.md +53 -0
- package/package.json +27 -0
- package/src/assets/components/G360DragModal.jsx +40 -0
- package/src/assets/components/G360Signature.jsx +14 -0
- package/src/assets/config/project-types.json +32 -0
- package/src/assets/config/skills.json +54 -0
- package/src/assets/engine/g360-data-validator.js +44 -0
- package/src/assets/engine/g360-engine.js +12 -0
- package/src/assets/engine/g360-field-mapper.js +35 -0
- package/src/assets/engine/g360-skill-audit.mjs +37 -0
- package/src/assets/engine/g360-skill-meta-evaluator.mjs +33 -0
- package/src/assets/snippets/snippets.json +24 -0
- package/src/assets/templates/python-cli/package.json +7 -0
- package/src/assets/templates/python-cli/src/core/skill.json +6 -0
- package/src/assets/templates/python-cli/src/main.py +13 -0
- package/src/assets/templates/vba-excel/src/Module_Main.bas +6 -0
- package/src/assets/templates/vba-excel/src/g360-datamap.bas +46 -0
- package/src/assets/templates/vba-excel/src/skill.json +9 -0
- package/src/assets/templates/web-pwa/app.js +1 -0
- package/src/assets/templates/web-pwa/index.html +24 -0
- package/src/assets/templates/web-pwa/package.json +5 -0
- package/src/assets/templates/web-pwa/styles.css +28 -0
- package/src/cli.js +74 -0
- package/src/commands/audit.js +43 -0
- package/src/commands/bring.js +57 -0
- package/src/commands/clean.js +65 -0
- package/src/commands/health.js +66 -0
- package/src/commands/init.js +63 -0
- package/src/commands/list.js +71 -0
- package/src/commands/present.js +54 -0
- package/src/commands/update.js +29 -0
- package/src/lib/assets.js +38 -0
- package/src/lib/auditor.js +67 -0
- package/src/lib/checksum.js +27 -0
- package/src/lib/config.js +23 -0
- package/src/lib/manifest.js +43 -0
- package/src/lib/offline.js +33 -0
- package/src/lib/presenter.js +24 -0
- package/src/lib/progress.js +35 -0
- package/src/lib/rollback.js +49 -0
- package/src/lib/theme.js +30 -0
- package/src/lib/validator.js +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# g360-cli
|
|
2
|
+
|
|
3
|
+
CLI tool for bootstrapping G360 ecosystem projects with standardized structure.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Initialize a new project
|
|
9
|
+
g360 init my-project
|
|
10
|
+
|
|
11
|
+
# Bring G360 assets into your project
|
|
12
|
+
g360 bring
|
|
13
|
+
|
|
14
|
+
# List available templates
|
|
15
|
+
g360 list templates
|
|
16
|
+
|
|
17
|
+
# Present your project structure
|
|
18
|
+
g360 present
|
|
19
|
+
|
|
20
|
+
# Audit your project
|
|
21
|
+
g360 audit
|
|
22
|
+
|
|
23
|
+
# Clean embedded assets before deployment
|
|
24
|
+
g360 clean
|
|
25
|
+
|
|
26
|
+
# Check system health
|
|
27
|
+
g360 health
|
|
28
|
+
|
|
29
|
+
# Update to latest version
|
|
30
|
+
g360 update
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
- `g360 init <name>` - Initialize a new G360 project
|
|
36
|
+
- `g360 bring <asset>` - Bring assets into current project
|
|
37
|
+
- `g360 list [type]` - List available templates/components/skills
|
|
38
|
+
- `g360 present [path]` - Present project structure
|
|
39
|
+
- `g360 audit [path]` - Audit project for G360 compliance
|
|
40
|
+
- `g360 clean [path]` - Clean embedded assets
|
|
41
|
+
- `g360 health` - Check system health
|
|
42
|
+
- `g360 update` - Update g360-cli to latest version
|
|
43
|
+
|
|
44
|
+
## Options
|
|
45
|
+
|
|
46
|
+
- `--dry-run` - Preview changes without applying
|
|
47
|
+
- `--force` - Overwrite existing files
|
|
48
|
+
- `--verbose` - Verbose output
|
|
49
|
+
- `--offline` - Work offline (use cached assets)
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "g360-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI tool for bootstrapping G360 ecosystem projects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/cli.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"g360": "./src/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"prepublishOnly": "node -e \"console.log('Use: npm install -g g360-cli')\"",
|
|
12
|
+
"test": "echo \"No tests configured\""
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["g360", "cli", "scaffolding", "generator"],
|
|
15
|
+
"author": "Carlos Cusi",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"chalk": "^5.3.0",
|
|
19
|
+
"commander": "^11.1.0",
|
|
20
|
+
"fs-extra": "^11.2.0",
|
|
21
|
+
"inquirer": "^9.2.15",
|
|
22
|
+
"ora": "^7.0.1"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18.0.0"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export default function G360DragModal({ isOpen, onClose, title, children }) {
|
|
2
|
+
if (!isOpen) return null;
|
|
3
|
+
|
|
4
|
+
return `
|
|
5
|
+
<div class="g360-modal-overlay" style="
|
|
6
|
+
position: fixed;
|
|
7
|
+
top: 0;
|
|
8
|
+
left: 0;
|
|
9
|
+
right: 0;
|
|
10
|
+
bottom: 0;
|
|
11
|
+
background: rgba(0,0,0,0.5);
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
z-index: 1000;
|
|
16
|
+
">
|
|
17
|
+
<div class="g360-modal" style="
|
|
18
|
+
background: white;
|
|
19
|
+
border-radius: 8px;
|
|
20
|
+
box-shadow: 0 4px 20px rgba(59, 130, 246, 0.3);
|
|
21
|
+
min-width: 400px;
|
|
22
|
+
max-width: 90vw;
|
|
23
|
+
">
|
|
24
|
+
<div class="g360-modal-header" style="
|
|
25
|
+
background: #3B82F6;
|
|
26
|
+
color: white;
|
|
27
|
+
padding: 15px 20px;
|
|
28
|
+
border-radius: 8px 8px 0 0;
|
|
29
|
+
cursor: move;
|
|
30
|
+
">
|
|
31
|
+
<span>${title}</span>
|
|
32
|
+
<button onclick="(${onClose})()" style="float: right; background: none; border: none; color: white; cursor: pointer;">✕</button>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="g360-modal-body" style="padding: 20px;">
|
|
35
|
+
${children}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
`;
|
|
40
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export default function G360Signature({ name, role, company = 'G360', email, phone }) {
|
|
2
|
+
return `
|
|
3
|
+
<div style="font-family: Arial, sans-serif; color: #333;">
|
|
4
|
+
<strong style="color: #3B82F6;">${name}</strong>
|
|
5
|
+
${role ? `<span> | ${role}</span>` : ''}
|
|
6
|
+
${company ? `<span> | ${company}</span>` : ''}
|
|
7
|
+
<br>
|
|
8
|
+
${email ? `<span>📧 ${email}</span>` : ''}
|
|
9
|
+
${phone ? `<span> 📱 ${phone}</span>` : ''}
|
|
10
|
+
<hr style="border: 1px solid #3B82F6; margin: 5px 0;">
|
|
11
|
+
<small style="color: #666;">G360 Ecosystem</small>
|
|
12
|
+
</div>
|
|
13
|
+
`;
|
|
14
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"projectTypes": [
|
|
3
|
+
{
|
|
4
|
+
"id": "web-pwa",
|
|
5
|
+
"name": "Web PWA",
|
|
6
|
+
"description": "Progressive Web App with offline support",
|
|
7
|
+
"framework": "vanilla",
|
|
8
|
+
"features": ["pwa", "offline", "service-worker"]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": "web-svelte",
|
|
12
|
+
"name": "Web Svelte",
|
|
13
|
+
"description": "Svelte web application",
|
|
14
|
+
"framework": "svelte",
|
|
15
|
+
"features": ["routing", "stores", "ssr"]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "python-cli",
|
|
19
|
+
"name": "Python CLI",
|
|
20
|
+
"description": "Python command-line tool",
|
|
21
|
+
"framework": "python",
|
|
22
|
+
"features": ["cli", "argparse", "rich"]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "vba-excel",
|
|
26
|
+
"name": "VBA Excel",
|
|
27
|
+
"description": "Excel VBA macros",
|
|
28
|
+
"framework": "vba",
|
|
29
|
+
"features": ["excel", "macros", "forms"]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skills": [
|
|
3
|
+
{
|
|
4
|
+
"name": "code-audit",
|
|
5
|
+
"description": "Audit code quality and G360 compliance",
|
|
6
|
+
"files": ["g360-skill-audit.mjs"]
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"name": "meta-audit",
|
|
10
|
+
"description": "Audit meta tags for SEO",
|
|
11
|
+
"files": ["g360-skill-meta-evaluator.mjs"]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "structure-audit",
|
|
15
|
+
"description": "Audit project structure",
|
|
16
|
+
"files": []
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "frontend",
|
|
20
|
+
"description": "Frontend development agent",
|
|
21
|
+
"files": []
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "backend",
|
|
25
|
+
"description": "Backend development agent",
|
|
26
|
+
"files": []
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "calculations",
|
|
30
|
+
"description": "Calculations and data processing",
|
|
31
|
+
"files": []
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "data",
|
|
35
|
+
"description": "Data management agent",
|
|
36
|
+
"files": []
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "export",
|
|
40
|
+
"description": "Export and reporting agent",
|
|
41
|
+
"files": []
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "security",
|
|
45
|
+
"description": "Security audit agent",
|
|
46
|
+
"files": []
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "repo-presenter",
|
|
50
|
+
"description": "Repository presentation and documentation",
|
|
51
|
+
"files": []
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function validate(data, rules) {
|
|
2
|
+
const results = {
|
|
3
|
+
valid: true,
|
|
4
|
+
errors: [],
|
|
5
|
+
warnings: []
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
for (const [field, rule] of Object.entries(rules)) {
|
|
9
|
+
const value = data[field];
|
|
10
|
+
|
|
11
|
+
if (rule.required && (value === undefined || value === null || value === '')) {
|
|
12
|
+
results.errors.push({ field, message: `${field} is required` });
|
|
13
|
+
results.valid = false;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (rule.type && value !== undefined) {
|
|
18
|
+
const actualType = Array.isArray(value) ? 'array' : typeof value;
|
|
19
|
+
if (actualType !== rule.type) {
|
|
20
|
+
results.errors.push({ field, message: `${field} should be ${rule.type}` });
|
|
21
|
+
results.valid = false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (rule.min !== undefined && typeof value === 'number' && value < rule.min) {
|
|
26
|
+
results.errors.push({ field, message: `${field} must be >= ${rule.min}` });
|
|
27
|
+
results.valid = false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (rule.max !== undefined && typeof value === 'number' && value > rule.max) {
|
|
31
|
+
results.errors.push({ field, message: `${field} must be <= ${rule.max}` });
|
|
32
|
+
results.valid = false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (rule.pattern && typeof value === 'string' && !rule.pattern.test(value)) {
|
|
36
|
+
results.errors.push({ field, message: `${field} format is invalid` });
|
|
37
|
+
results.valid = false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return results;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default { validate };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function mapField(sourceField, fieldMap) {
|
|
2
|
+
const mapping = fieldMap[sourceField];
|
|
3
|
+
if (!mapping) {
|
|
4
|
+
return {
|
|
5
|
+
success: false,
|
|
6
|
+
targetField: null,
|
|
7
|
+
message: `No mapping found for: ${sourceField}`
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
success: true,
|
|
12
|
+
targetField: mapping.target,
|
|
13
|
+
transformations: mapping.transform || []
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function validateMapping(sourceData, fieldMap) {
|
|
18
|
+
const results = {
|
|
19
|
+
valid: true,
|
|
20
|
+
errors: [],
|
|
21
|
+
warnings: []
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
for (const sourceField of Object.keys(sourceData)) {
|
|
25
|
+
const mapping = mapField(sourceField, fieldMap);
|
|
26
|
+
if (!mapping.success) {
|
|
27
|
+
results.warnings.push(mapping.message);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
results.valid = results.errors.length === 0;
|
|
32
|
+
return results;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default { mapField, validateMapping };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export async function audit(code, options = {}) {
|
|
2
|
+
const results = {
|
|
3
|
+
score: 0,
|
|
4
|
+
issues: [],
|
|
5
|
+
suggestions: []
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
if (!code || code.length === 0) {
|
|
9
|
+
results.issues.push({ line: 0, message: 'Empty code' });
|
|
10
|
+
return results;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const lines = code.split('\n');
|
|
14
|
+
let score = 100;
|
|
15
|
+
|
|
16
|
+
lines.forEach((line, index) => {
|
|
17
|
+
if (line.length > 120) {
|
|
18
|
+
results.issues.push({ line: index + 1, message: 'Line too long (>120 chars)' });
|
|
19
|
+
score -= 2;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (line.includes('TODO') || line.includes('FIXME')) {
|
|
23
|
+
results.suggestions.push({ line: index + 1, message: 'Unresolved TODO/FIXME' });
|
|
24
|
+
score -= 1;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (!code.includes('g360') && !code.includes('G360')) {
|
|
29
|
+
results.suggestions.push({ line: 0, message: 'Consider adding G360 identity' });
|
|
30
|
+
score -= 5;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
results.score = Math.max(0, score);
|
|
34
|
+
return results;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default { audit };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export async function evaluateMetaTags(html) {
|
|
2
|
+
const results = {
|
|
3
|
+
score: 0,
|
|
4
|
+
tags: [],
|
|
5
|
+
issues: [],
|
|
6
|
+
suggestions: []
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const requiredTags = ['title', 'description', 'viewport'];
|
|
10
|
+
const metaTags = html.match(/<meta[^>]+>/gi) || [];
|
|
11
|
+
|
|
12
|
+
requiredTags.forEach(tag => {
|
|
13
|
+
if (html.includes(`name="${tag}"`) || html.includes(`property="${tag}"`)) {
|
|
14
|
+
results.tags.push({ tag, found: true });
|
|
15
|
+
} else {
|
|
16
|
+
results.issues.push({ tag, message: `Missing ${tag} tag` });
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const ogTags = ['og:title', 'og:description', 'og:image'];
|
|
21
|
+
ogTags.forEach(tag => {
|
|
22
|
+
if (html.includes(`property="${tag}"`)) {
|
|
23
|
+
results.tags.push({ tag, found: true, type: 'og' });
|
|
24
|
+
} else {
|
|
25
|
+
results.suggestions.push({ tag, message: `Consider adding Open Graph: ${tag}` });
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
results.score = Math.round((results.tags.length / (requiredTags.length + ogTags.length)) * 100);
|
|
30
|
+
return results;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default { evaluateMetaTags };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"snippets": [
|
|
3
|
+
{
|
|
4
|
+
"name": "g360-header",
|
|
5
|
+
"description": "Standard G360 header",
|
|
6
|
+
"code": "<header class='g360-header'>...</header>"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"name": "g360-button",
|
|
10
|
+
"description": "G360 styled button",
|
|
11
|
+
"code": "<button class='g360-btn'>Click</button>"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "g360-card",
|
|
15
|
+
"description": "G360 card component",
|
|
16
|
+
"code": "<div class='g360-card'>...</div>"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "g360-badge",
|
|
20
|
+
"description": "G360 status badge",
|
|
21
|
+
"code": "<span class='g360-badge g360-badge-success'>Active</span>"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
' ============================================================================
|
|
2
|
+
' G360 DataMap VBA
|
|
3
|
+
' ============================================================================
|
|
4
|
+
' Funciones de mapeo de campos para VBA Excel
|
|
5
|
+
' ============================================================================
|
|
6
|
+
|
|
7
|
+
Option Explicit
|
|
8
|
+
|
|
9
|
+
' ============================================================================
|
|
10
|
+
' TIPOS
|
|
11
|
+
' ============================================================================
|
|
12
|
+
|
|
13
|
+
Public Type G360FieldMap
|
|
14
|
+
LocalName As String
|
|
15
|
+
StandardName As String
|
|
16
|
+
DataType As String
|
|
17
|
+
End Type
|
|
18
|
+
|
|
19
|
+
' ============================================================================
|
|
20
|
+
' FUNCIONES DE MAPEO
|
|
21
|
+
' ============================================================================
|
|
22
|
+
|
|
23
|
+
Public Function G360_NormalizeFieldName(fieldName As String, dominio As String) As String
|
|
24
|
+
Dim normalized As String
|
|
25
|
+
normalized = LCase(Replace(Replace(fieldName, "_", ""), " ", ""))
|
|
26
|
+
|
|
27
|
+
Select Case normalized
|
|
28
|
+
Case "codigo", "sku", "cod", "producto", "item"
|
|
29
|
+
G360_NormalizeFieldName = "codigo"
|
|
30
|
+
Case "nombre", "descripcion", "producto", "nombreproducto"
|
|
31
|
+
G360_NormalizeFieldName = "nombre"
|
|
32
|
+
Case "cantidad", "cant", "qty", "stock"
|
|
33
|
+
G360_NormalizeFieldName = "cantidad"
|
|
34
|
+
Case "precio", "tarifa", "monto", "valor", "importe"
|
|
35
|
+
G360_NormalizeFieldName = "precio"
|
|
36
|
+
Case "fecha", "fec", "date"
|
|
37
|
+
G360_NormalizeFieldName = "fecha"
|
|
38
|
+
Case Else
|
|
39
|
+
G360_NormalizeFieldName = fieldName
|
|
40
|
+
End Select
|
|
41
|
+
End Function
|
|
42
|
+
|
|
43
|
+
Public Function G360_MapRow(rowData As Object, dominio As String) As Object
|
|
44
|
+
' Placeholder para mapeo de fila completa
|
|
45
|
+
Set G360_MapRow = rowData
|
|
46
|
+
End Function
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log('G360 Project initialized');
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="es">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<meta name="description" content="G360 Project">
|
|
7
|
+
<meta name="theme-color" content="#3B82F6">
|
|
8
|
+
<title>G360 Project</title>
|
|
9
|
+
<link rel="manifest" href="/manifest.json">
|
|
10
|
+
<link rel="stylesheet" href="/styles.css">
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<header class="g360-header">
|
|
14
|
+
<h1>G360 Project</h1>
|
|
15
|
+
</header>
|
|
16
|
+
<main>
|
|
17
|
+
<p>Your G360 project is ready!</p>
|
|
18
|
+
</main>
|
|
19
|
+
<footer class="g360-footer">
|
|
20
|
+
<small>Powered by G360 Ecosystem</small>
|
|
21
|
+
</footer>
|
|
22
|
+
<script src="/app.js"></script>
|
|
23
|
+
</body>
|
|
24
|
+
</html>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--g360-primary: #3B82F6;
|
|
3
|
+
--g360-secondary: #10B981;
|
|
4
|
+
--g360-accent: #8B5CF6;
|
|
5
|
+
--g360-bg: #ffffff;
|
|
6
|
+
--g360-text: #1f2937;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
10
|
+
|
|
11
|
+
body {
|
|
12
|
+
font-family: system-ui, sans-serif;
|
|
13
|
+
background: var(--g360-bg);
|
|
14
|
+
color: var(--g360-text);
|
|
15
|
+
line-height: 1.6;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.g360-header {
|
|
19
|
+
background: var(--g360-primary);
|
|
20
|
+
color: white;
|
|
21
|
+
padding: 1rem 2rem;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.g360-footer {
|
|
25
|
+
text-align: center;
|
|
26
|
+
padding: 1rem;
|
|
27
|
+
color: #6b7280;
|
|
28
|
+
}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { init } from './commands/init.js';
|
|
6
|
+
import { bring } from './commands/bring.js';
|
|
7
|
+
import { list } from './commands/list.js';
|
|
8
|
+
import { present } from './commands/present.js';
|
|
9
|
+
import { audit } from './commands/audit.js';
|
|
10
|
+
import { clean } from './commands/clean.js';
|
|
11
|
+
import { health } from './commands/health.js';
|
|
12
|
+
import { update } from './commands/update.js';
|
|
13
|
+
|
|
14
|
+
const program = new Command();
|
|
15
|
+
|
|
16
|
+
program
|
|
17
|
+
.name('g360')
|
|
18
|
+
.description('CLI tool for bootstrapping G360 ecosystem projects')
|
|
19
|
+
.version('1.0.0');
|
|
20
|
+
|
|
21
|
+
program
|
|
22
|
+
.command('init')
|
|
23
|
+
.argument('<name>', 'Project name')
|
|
24
|
+
.option('-t, --template <type>', 'Project template type', 'web-pwa')
|
|
25
|
+
.option('-d, --dir <path>', 'Target directory', '.')
|
|
26
|
+
.option('--dry-run', 'Preview without creating files')
|
|
27
|
+
.option('--force', 'Overwrite existing files')
|
|
28
|
+
.action(init);
|
|
29
|
+
|
|
30
|
+
program
|
|
31
|
+
.command('bring')
|
|
32
|
+
.argument('[asset]', 'Specific asset to bring (template/component/skill/all)')
|
|
33
|
+
.option('-p, --path <path>', 'Target path', '.')
|
|
34
|
+
.option('--dry-run', 'Preview without copying')
|
|
35
|
+
.option('--force', 'Overwrite existing files')
|
|
36
|
+
.action(bring);
|
|
37
|
+
|
|
38
|
+
program
|
|
39
|
+
.command('list')
|
|
40
|
+
.argument('[type]', 'Type to list (templates/components/skills/all)', 'all')
|
|
41
|
+
.option('--json', 'Output as JSON')
|
|
42
|
+
.action(list);
|
|
43
|
+
|
|
44
|
+
program
|
|
45
|
+
.command('present')
|
|
46
|
+
.argument('[path]', 'Project path to present', '.')
|
|
47
|
+
.option('--depth <n>', 'Max depth to display', '3')
|
|
48
|
+
.action(present);
|
|
49
|
+
|
|
50
|
+
program
|
|
51
|
+
.command('audit')
|
|
52
|
+
.argument('[path]', 'Path to audit', '.')
|
|
53
|
+
.option('--fix', 'Auto-fix issues when possible')
|
|
54
|
+
.option('--verbose', 'Show detailed output')
|
|
55
|
+
.action(audit);
|
|
56
|
+
|
|
57
|
+
program
|
|
58
|
+
.command('clean')
|
|
59
|
+
.argument('[path]', 'Path to clean', '.')
|
|
60
|
+
.option('--dry-run', 'Preview files to be removed')
|
|
61
|
+
.option('--force', 'Skip confirmation')
|
|
62
|
+
.action(clean);
|
|
63
|
+
|
|
64
|
+
program
|
|
65
|
+
.command('health')
|
|
66
|
+
.option('--verbose', 'Show detailed health info')
|
|
67
|
+
.action(health);
|
|
68
|
+
|
|
69
|
+
program
|
|
70
|
+
.command('update')
|
|
71
|
+
.option('--check', 'Check for updates without installing')
|
|
72
|
+
.action(update);
|
|
73
|
+
|
|
74
|
+
program.parse();
|