ganbatte-os 0.2.1
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/AGENTS.md +46 -0
- package/CLAUDE.md +31 -0
- package/GEMINI.md +17 -0
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/agents/profiles/architect.md +13 -0
- package/agents/profiles/dev.md +13 -0
- package/agents/profiles/devops.md +12 -0
- package/agents/profiles/ganbatte-os-master.md +444 -0
- package/agents/profiles/index.json +14 -0
- package/agents/profiles/po.md +7 -0
- package/agents/profiles/qa.md +456 -0
- package/agents/profiles/sm.md +7 -0
- package/agents/profiles/squad-creator.md +7 -0
- package/agents/profiles/ux-design-expert.md +14 -0
- package/config.json +15 -0
- package/docs/curation.md +60 -0
- package/docs/gos_installation_guide.md +114 -0
- package/docs/ide-compatibility.md +20 -0
- package/docs/plan/plan-git-operations.md +51 -0
- package/docs/plan-distribuicao-publica.md +360 -0
- package/docs/stacks/stack-git-operations.md +154 -0
- package/docs/toolchain-map.md +18 -0
- package/integrations/README.md +42 -0
- package/integrations/antigravity/README.md +29 -0
- package/integrations/antigravity/command-map.json +29 -0
- package/integrations/claude/README.md +35 -0
- package/integrations/claude/agent-map.json +46 -0
- package/integrations/claude/command-map.json +32 -0
- package/integrations/claude/litellm-proxy.md +93 -0
- package/integrations/claude/mcp-specifics.md +121 -0
- package/integrations/codex/README.md +29 -0
- package/integrations/codex/command-map.json +29 -0
- package/integrations/cursor/README.md +8 -0
- package/integrations/cursor/command-map.json +11 -0
- package/integrations/gemini/README.md +13 -0
- package/integrations/gemini/command-map.json +11 -0
- package/integrations/kilo-code/README.md +7 -0
- package/integrations/kilo-code/command-map.json +11 -0
- package/integrations/opencode/README.md +91 -0
- package/integrations/opencode/command-map.json +46 -0
- package/integrations/registry.json +20 -0
- package/manifests/g-os-runtime-manifest.json +39 -0
- package/manifests/gos-install-manifest.json +46 -0
- package/opencode.json +7 -0
- package/package.json +51 -0
- package/playbooks/feature-development-playbook.md +239 -0
- package/playbooks/sprint-planner-playbook.md +127 -0
- package/playbooks/squad-pipeline-runner.md +196 -0
- package/playbooks/ssh-multi-account-setup.md +185 -0
- package/prompts/01-search.md +18 -0
- package/prompts/02-spec.md +19 -0
- package/prompts/03-tasks.md +15 -0
- package/prompts/04-code.md +10 -0
- package/prompts/05-reviews.md +11 -0
- package/rules/plan-mode.md +60 -0
- package/scripts/cli/gos-cli.js +679 -0
- package/scripts/hooks/pre-commit-validate.js +201 -0
- package/scripts/integrations/check-ide-compat.js +44 -0
- package/scripts/integrations/setup-ide-adapters.js +87 -0
- package/scripts/tools/clickup-preprocess.js +218 -0
- package/scripts/tools/clickup.js +1058 -0
- package/skills/agent-teams/SKILL.md +78 -0
- package/skills/agent-teams/presets/team-all.yaml +14 -0
- package/skills/agent-teams/presets/team-fullstack.yaml +17 -0
- package/skills/agent-teams/presets/team-ide-minimal.yaml +9 -0
- package/skills/agent-teams/presets/team-no-ui.yaml +12 -0
- package/skills/agent-teams/presets/team-qa-focused.yaml +83 -0
- package/skills/clickup/SKILL.md +151 -0
- package/skills/component-dedup/SKILL.md +101 -0
- package/skills/design-to-code/SKILL.md +255 -0
- package/skills/figma-implement-design/SKILL.md +227 -0
- package/skills/figma-make-analyzer/SKILL.md +140 -0
- package/skills/frontend-dev/SKILL.md +271 -0
- package/skills/git-ssh-setup/SKILL.md +164 -0
- package/skills/interface-design/SKILL.md +350 -0
- package/skills/interface-design/references/audit.md +76 -0
- package/skills/interface-design/references/craft-examples.md +134 -0
- package/skills/interface-design/references/critique.md +92 -0
- package/skills/interface-design/references/extract.md +92 -0
- package/skills/interface-design/references/principles.md +348 -0
- package/skills/interface-design/references/templates/system-precision.md +73 -0
- package/skills/interface-design/references/templates/system-warmth.md +67 -0
- package/skills/interface-design/references/validation.md +137 -0
- package/skills/make-code-triage/SKILL.md +135 -0
- package/skills/make-version-diff/SKILL.md +87 -0
- package/skills/plan-to-tasks/SKILL.md +136 -0
- package/skills/react-best-practices/AGENTS.md +2975 -0
- package/skills/react-best-practices/SKILL.md +151 -0
- package/skills/react-best-practices/metadata.json +15 -0
- package/skills/react-best-practices/rules/_sections.md +46 -0
- package/skills/react-best-practices/rules/_template.md +28 -0
- package/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/skills/react-best-practices/rules/advanced-init-once.md +42 -0
- package/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/skills/react-best-practices/rules/async-dependencies.md +51 -0
- package/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/skills/react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/skills/react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/skills/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/skills/react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/skills/react-best-practices/rules/server-auth-actions.md +96 -0
- package/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/skills/react-best-practices/rules/server-dedup-props.md +65 -0
- package/skills/react-best-practices/rules/server-hoist-static-io.md +142 -0
- package/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/skills/react-doctor/SKILL.md +74 -0
- package/skills/registry.json +21 -0
- package/skills/sprint-planner/SKILL.md +434 -0
- package/squads/design-delivery/README.md +10 -0
- package/squads/design-delivery/squad.yaml +30 -0
- package/squads/design-delivery/workflows/wf-design-delivery.yaml +27 -0
- package/squads/design-squad/README.md +31 -0
- package/squads/design-squad/agents/brad-frost.md +185 -0
- package/squads/design-squad/agents/dan-mall.md +178 -0
- package/squads/design-squad/agents/dave-malouf.md +198 -0
- package/squads/design-squad/agents/design-chief.md +109 -0
- package/squads/design-squad/agents/design-system-architect.md +109 -0
- package/squads/design-squad/agents/ui-engineer.md +102 -0
- package/squads/design-squad/agents/ux-designer.md +105 -0
- package/squads/design-squad/agents/visual-generator.md +108 -0
- package/squads/design-squad/checklists/output-quality.md +76 -0
- package/squads/design-squad/config/config.yaml +65 -0
- package/squads/design-squad/data/design-patterns-catalog.yaml +276 -0
- package/squads/design-squad/data/routing-catalog.yaml +95 -0
- package/squads/design-squad/squad.yaml +88 -0
- package/squads/design-squad/tasks/audit-design.md +174 -0
- package/squads/design-squad/tasks/create-component-spec.md +185 -0
- package/squads/design-squad/tasks/create-design-system.md +179 -0
- package/squads/design-squad/tasks/design-ux-flow.md +184 -0
- package/squads/design-squad/tasks/diagnose.md +138 -0
- package/squads/design-squad/tasks/generate-handoff.md +186 -0
- package/squads/design-squad/tasks/review.md +133 -0
- package/squads/design-squad/tasks/setup-design-ops.md +177 -0
- package/squads/design-squad/workflows/wf-design-system-creation.yaml +131 -0
- package/squads/design-squad/workflows/wf-feature-design.yaml +114 -0
- package/squads/git-operations/README.md +30 -0
- package/squads/git-operations/squad.yaml +27 -0
- package/squads/git-operations/workflows/wf-safe-commit.yaml +27 -0
- package/squads/git-operations/workflows/wf-ssh-setup.yaml +27 -0
- package/squads/sprint-planning/agents/sprint-chief.md +47 -0
- package/squads/sprint-planning/agents/sprint-planner-agent.md +43 -0
- package/squads/sprint-planning/agents/sprint-tracker.md +43 -0
- package/squads/sprint-planning/agents/task-importer.md +44 -0
- package/squads/sprint-planning/checklists/sprint-readiness.md +27 -0
- package/squads/sprint-planning/config/config.yaml +65 -0
- package/squads/sprint-planning/data/clickup-field-mapping.yaml +94 -0
- package/squads/sprint-planning/squad.yaml +52 -0
- package/squads/sprint-planning/tasks/close-sprint.md +43 -0
- package/squads/sprint-planning/tasks/create-sprint.md +42 -0
- package/squads/sprint-planning/tasks/import-tasks.md +39 -0
- package/squads/sprint-planning/tasks/sync-status.md +31 -0
- package/squads/sprint-planning/workflows/wf-sprint-creation.yaml +59 -0
- package/squads/sprint-planning/workflows/wf-sprint-sync.yaml +35 -0
- package/templates/adr-tmpl.yaml +76 -0
- package/templates/sprint-clickup.template.md +80 -0
|
@@ -0,0 +1,679 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* gos-cli.js — CLI do ganbatte-os para setup, update e validacao de workspace.
|
|
5
|
+
* Zero dependencies externas. Usa apenas modulos nativos do Node.js.
|
|
6
|
+
*
|
|
7
|
+
* Comandos:
|
|
8
|
+
* gos init Setup pos-clone (remote, dirs, IDEs)
|
|
9
|
+
* gos update Fetch + merge de upstream/main
|
|
10
|
+
* gos doctor Validar integridade do workspace
|
|
11
|
+
* gos version Mostrar versao e checar atualizacoes
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const fs = require('node:fs');
|
|
15
|
+
const path = require('node:path');
|
|
16
|
+
const { execFileSync, execSync } = require('node:child_process');
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Constantes
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
const VERSION = '0.2.0';
|
|
23
|
+
const UPSTREAM_REMOTE = 'upstream';
|
|
24
|
+
const UPSTREAM_BRANCH = 'main';
|
|
25
|
+
const LOCAL_DIR = '.gos-local';
|
|
26
|
+
const MANIFEST_PATH = 'manifests/gos-install-manifest.json';
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Utilitarios
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
const log = (msg) => console.log(`[ganbatte-os] ${msg}`);
|
|
33
|
+
const info = (msg) => console.log(` i ${msg}`);
|
|
34
|
+
const ok = (msg) => console.log(` v ${msg}`);
|
|
35
|
+
const warn = (msg) => console.log(` ! ${msg}`);
|
|
36
|
+
const fail = (msg) => console.error(` x ${msg}`);
|
|
37
|
+
|
|
38
|
+
function pathExists(p) { return fs.existsSync(p); }
|
|
39
|
+
|
|
40
|
+
function ensureDir(p) {
|
|
41
|
+
if (!pathExists(p)) fs.mkdirSync(p, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function readJson(filePath, fallback = null) {
|
|
45
|
+
if (!pathExists(filePath)) return fallback;
|
|
46
|
+
try { return JSON.parse(fs.readFileSync(filePath, 'utf8')); }
|
|
47
|
+
catch { return fallback; }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function writeJson(filePath, value) {
|
|
51
|
+
ensureDir(path.dirname(filePath));
|
|
52
|
+
fs.writeFileSync(filePath, JSON.stringify(value, null, 2) + '\n');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Executa comando git via execFileSync (sem shell injection).
|
|
57
|
+
* Retorna stdout como string. Em caso de erro, retorna '' se ignoreError=true.
|
|
58
|
+
*/
|
|
59
|
+
function git(args, opts = {}) {
|
|
60
|
+
const options = { encoding: 'utf8', cwd: opts.cwd, stdio: opts.quiet ? 'pipe' : 'inherit' };
|
|
61
|
+
try {
|
|
62
|
+
return execFileSync('git', args, options);
|
|
63
|
+
} catch (e) {
|
|
64
|
+
if (opts.ignoreError) return (e.stdout || '').toString();
|
|
65
|
+
throw e;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Executa git e captura stdout silenciosamente. */
|
|
70
|
+
function gitCapture(args, opts = {}) {
|
|
71
|
+
try {
|
|
72
|
+
return execFileSync('git', args, { encoding: 'utf8', stdio: 'pipe', cwd: opts.cwd }).trim();
|
|
73
|
+
} catch {
|
|
74
|
+
return '';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Executa node script via execFileSync. */
|
|
79
|
+
function runNode(scriptPath, opts = {}) {
|
|
80
|
+
const options = { encoding: 'utf8', cwd: opts.cwd, stdio: opts.quiet ? 'pipe' : 'inherit' };
|
|
81
|
+
try {
|
|
82
|
+
return execFileSync(process.execPath, [scriptPath], options);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
if (opts.ignoreError) return '';
|
|
85
|
+
throw e;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getFlagValue(args, flag) {
|
|
90
|
+
const prefix = `--${flag}=`;
|
|
91
|
+
const found = args.find(a => a.startsWith(prefix));
|
|
92
|
+
if (found) return found.slice(prefix.length);
|
|
93
|
+
const idx = args.indexOf(`--${flag}`);
|
|
94
|
+
if (idx !== -1 && idx + 1 < args.length) return args[idx + 1];
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function getRoot() {
|
|
99
|
+
return path.resolve(__dirname, '..', '..');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Copia recursiva de diretórios (zero dependencies).
|
|
104
|
+
*/
|
|
105
|
+
function copyDirRecursive(source, target, options = {}) {
|
|
106
|
+
const { exclude = [] } = options;
|
|
107
|
+
if (!fs.existsSync(target)) fs.mkdirSync(target, { recursive: true });
|
|
108
|
+
|
|
109
|
+
const entries = fs.readdirSync(source, { withFileTypes: true });
|
|
110
|
+
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
const srcPath = path.join(source, entry.name);
|
|
113
|
+
const destPath = path.join(target, entry.name);
|
|
114
|
+
|
|
115
|
+
// Skip excluded names
|
|
116
|
+
if (exclude.includes(entry.name)) continue;
|
|
117
|
+
|
|
118
|
+
if (entry.isDirectory()) {
|
|
119
|
+
copyDirRecursive(srcPath, destPath, options);
|
|
120
|
+
} else {
|
|
121
|
+
fs.copyFileSync(srcPath, destPath);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function getManifest(root) {
|
|
127
|
+
const manifestFile = path.join(root, MANIFEST_PATH);
|
|
128
|
+
const manifest = readJson(manifestFile);
|
|
129
|
+
if (!manifest) {
|
|
130
|
+
fail(`Manifest nao encontrado: ${MANIFEST_PATH}`);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
return manifest;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
// Merge .gitignore
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
|
|
140
|
+
function mergeGitignore(root, entries) {
|
|
141
|
+
const gitignorePath = path.join(root, '.gitignore');
|
|
142
|
+
let content = '';
|
|
143
|
+
if (pathExists(gitignorePath)) {
|
|
144
|
+
content = fs.readFileSync(gitignorePath, 'utf8');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const missing = entries.filter(e => !content.includes(e.trim()));
|
|
148
|
+
if (missing.length === 0) return false;
|
|
149
|
+
|
|
150
|
+
const block = '\n# G-OS managed entries\n' + missing.join('\n') + '\n';
|
|
151
|
+
fs.writeFileSync(gitignorePath, content.trimEnd() + '\n' + block);
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// gos init
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
|
|
159
|
+
function cmdInit(root, args) {
|
|
160
|
+
const force = args.includes('--force');
|
|
161
|
+
|
|
162
|
+
log('Inicializando workspace ganbatte-os...');
|
|
163
|
+
|
|
164
|
+
// 1. Validar Node >= 18
|
|
165
|
+
const nodeVersion = parseInt(process.version.slice(1), 10);
|
|
166
|
+
if (nodeVersion < 18) {
|
|
167
|
+
fail(`Node.js >= 18 necessario. Versao atual: ${process.version}`);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 2. Checar se ja inicializado
|
|
172
|
+
const installLog = path.join(root, LOCAL_DIR, 'install-log.json');
|
|
173
|
+
if (pathExists(installLog) && !force) {
|
|
174
|
+
warn('Workspace ja inicializado.');
|
|
175
|
+
info('Use --force para reinicializar.');
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 3. Renomear remote origin -> upstream (se origin existir)
|
|
180
|
+
const remotes = gitCapture(['remote'], { cwd: root });
|
|
181
|
+
if (remotes.includes('origin') && !remotes.includes(UPSTREAM_REMOTE)) {
|
|
182
|
+
log('Renomeando remote origin -> upstream...');
|
|
183
|
+
git(['remote', 'rename', 'origin', UPSTREAM_REMOTE], { cwd: root });
|
|
184
|
+
ok('Remote renomeado: origin -> upstream');
|
|
185
|
+
info('Agora voce pode adicionar seu proprio origin com: git remote add origin <url>');
|
|
186
|
+
} else if (remotes.includes(UPSTREAM_REMOTE)) {
|
|
187
|
+
ok('Remote upstream ja existe.');
|
|
188
|
+
} else {
|
|
189
|
+
warn('Nenhum remote origin encontrado. Configure manualmente:');
|
|
190
|
+
info(` git remote add ${UPSTREAM_REMOTE} https://github.com/adrianomorais-ganbatte/ganbatte-os.git`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// 4. Criar diretorios locais
|
|
194
|
+
const localDirs = ['worktrees', 'outputs', 'task-queue'];
|
|
195
|
+
for (const dir of localDirs) {
|
|
196
|
+
ensureDir(path.join(root, LOCAL_DIR, dir));
|
|
197
|
+
}
|
|
198
|
+
ok(`Diretorio ${LOCAL_DIR}/ criado com subdirs.`);
|
|
199
|
+
|
|
200
|
+
// 5. Criar packages/ com .gitkeep
|
|
201
|
+
const packagesDir = path.join(root, 'packages');
|
|
202
|
+
if (!pathExists(packagesDir)) {
|
|
203
|
+
ensureDir(packagesDir);
|
|
204
|
+
fs.writeFileSync(path.join(packagesDir, '.gitkeep'), '');
|
|
205
|
+
ok('Diretorio packages/ criado.');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// 6. Sync IDE adapters
|
|
209
|
+
const ideSetupScript = path.join(root, 'scripts', 'integrations', 'setup-ide-adapters.js');
|
|
210
|
+
if (pathExists(ideSetupScript)) {
|
|
211
|
+
log('Sincronizando IDE adapters...');
|
|
212
|
+
runNode(ideSetupScript, { cwd: root });
|
|
213
|
+
ok('IDE adapters sincronizados.');
|
|
214
|
+
} else {
|
|
215
|
+
warn('setup-ide-adapters.js nao encontrado. Pulando sync de IDEs.');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 7. Validar IDEs
|
|
219
|
+
const ideCheckScript = path.join(root, 'scripts', 'integrations', 'check-ide-compat.js');
|
|
220
|
+
if (pathExists(ideCheckScript)) {
|
|
221
|
+
runNode(ideCheckScript, { cwd: root, ignoreError: true });
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 8. Merge .gitignore
|
|
225
|
+
const manifest = getManifest(root);
|
|
226
|
+
const gitignoreUpdated = mergeGitignore(root, manifest.gitignoreEntries || []);
|
|
227
|
+
if (gitignoreUpdated) ok('.gitignore atualizado com entradas do manifest.');
|
|
228
|
+
|
|
229
|
+
// 9. Salvar install log
|
|
230
|
+
writeJson(installLog, {
|
|
231
|
+
version: VERSION,
|
|
232
|
+
initializedAt: new Date().toISOString(),
|
|
233
|
+
nodeVersion: process.version
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// 10. Sucesso
|
|
237
|
+
console.log('');
|
|
238
|
+
ok('Workspace ganbatte-os inicializado com sucesso!');
|
|
239
|
+
console.log('');
|
|
240
|
+
console.log(` Versao: ${VERSION}`);
|
|
241
|
+
console.log(` Local dir: ${LOCAL_DIR}/`);
|
|
242
|
+
console.log(` .gitignore: ${gitignoreUpdated ? 'atualizado' : 'ja estava ok'}`);
|
|
243
|
+
console.log('');
|
|
244
|
+
console.log(' Proximos passos:');
|
|
245
|
+
|
|
246
|
+
const finalRemotes = gitCapture(['remote'], { cwd: root });
|
|
247
|
+
if (!finalRemotes.includes('origin')) {
|
|
248
|
+
console.log(' 1. Adicione seu remote: git remote add origin <seu-repo>');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
console.log(' 2. Crie projetos em packages/');
|
|
252
|
+
console.log(' 3. Para atualizar o framework: npm run gos:update');
|
|
253
|
+
console.log('');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
// gos install
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
|
|
260
|
+
function cmdInstall(args) {
|
|
261
|
+
const targetRoot = process.cwd();
|
|
262
|
+
const sourceRoot = getRoot();
|
|
263
|
+
|
|
264
|
+
// Se ja estamos na raiz do G-OS, apenas rodamos o init
|
|
265
|
+
if (path.resolve(sourceRoot) === path.resolve(targetRoot)) {
|
|
266
|
+
log('Executando na raiz do framework. Redirecionando para "init"...');
|
|
267
|
+
cmdInit(targetRoot, args);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
log(`Instalando ganbatte-os em: ${targetRoot}`);
|
|
272
|
+
|
|
273
|
+
// 1. Validar se diretorio ja tem G-OS (a menos que use --force)
|
|
274
|
+
if (pathExists(path.join(targetRoot, LOCAL_DIR)) && !args.includes('--force')) {
|
|
275
|
+
fail('Workspace ganbatte-os ja detectado neste diretorio.');
|
|
276
|
+
info('Use --force para reinstalar/sobrescrever.');
|
|
277
|
+
process.exit(1);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// 2. Copiar arquivos do framework (exceto os internos/git)
|
|
281
|
+
const exclude = ['.git', '.gos-local', 'node_modules', 'package-lock.json', 'install-log.json', 'update-log.json'];
|
|
282
|
+
log('Copiando arquivos do framework...');
|
|
283
|
+
try {
|
|
284
|
+
copyDirRecursive(sourceRoot, targetRoot, { exclude });
|
|
285
|
+
ok('Arquivos copiados com sucesso.');
|
|
286
|
+
} catch (e) {
|
|
287
|
+
fail(`Erro ao copiar arquivos: ${e.message}`);
|
|
288
|
+
process.exit(1);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// 3. Executar o init no target para finalizar configs
|
|
292
|
+
cmdInit(targetRoot, args);
|
|
293
|
+
|
|
294
|
+
// 4. Garantir que o remote upstream existe caso tenha sido instalado via npx
|
|
295
|
+
const remotes = gitCapture(['remote'], { cwd: targetRoot });
|
|
296
|
+
if (!remotes.includes(UPSTREAM_REMOTE)) {
|
|
297
|
+
try {
|
|
298
|
+
git(['remote', 'add', UPSTREAM_REMOTE, 'https://github.com/adrianomorais-ganbatte/ganbatte-os.git'], { cwd: targetRoot });
|
|
299
|
+
ok(`Remote "${UPSTREAM_REMOTE}" adicionado.`);
|
|
300
|
+
} catch {
|
|
301
|
+
warn(`Nao foi possivel adicionar o remote "${UPSTREAM_REMOTE}". Configure manualmente.`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// ---------------------------------------------------------------------------
|
|
307
|
+
// gos update
|
|
308
|
+
// ---------------------------------------------------------------------------
|
|
309
|
+
|
|
310
|
+
function cmdUpdate(root, args) {
|
|
311
|
+
const skipStash = args.includes('--no-stash');
|
|
312
|
+
|
|
313
|
+
log('Atualizando workspace ganbatte-os...');
|
|
314
|
+
|
|
315
|
+
// 1. Verificar remote upstream
|
|
316
|
+
const remotes = gitCapture(['remote'], { cwd: root });
|
|
317
|
+
if (!remotes.includes(UPSTREAM_REMOTE)) {
|
|
318
|
+
fail(`Remote "${UPSTREAM_REMOTE}" nao encontrado.`);
|
|
319
|
+
info(`Adicione com: git remote add ${UPSTREAM_REMOTE} https://github.com/adrianomorais-ganbatte/ganbatte-os.git`);
|
|
320
|
+
process.exit(1);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// 2. Checar se ha mudancas locais e fazer stash
|
|
324
|
+
const status = gitCapture(['status', '--porcelain'], { cwd: root });
|
|
325
|
+
let didStash = false;
|
|
326
|
+
if (status && !skipStash) {
|
|
327
|
+
log('Mudancas locais detectadas. Fazendo stash...');
|
|
328
|
+
git(['stash', 'push', '-m', 'gos-update-auto-stash'], { cwd: root });
|
|
329
|
+
didStash = true;
|
|
330
|
+
ok('Stash criado.');
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// 3. Fetch upstream
|
|
334
|
+
log(`Buscando atualizacoes de ${UPSTREAM_REMOTE}/${UPSTREAM_BRANCH}...`);
|
|
335
|
+
git(['fetch', UPSTREAM_REMOTE, UPSTREAM_BRANCH], { cwd: root });
|
|
336
|
+
|
|
337
|
+
// 4. Checar se ha commits novos
|
|
338
|
+
const behind = gitCapture(
|
|
339
|
+
['rev-list', '--count', `HEAD..${UPSTREAM_REMOTE}/${UPSTREAM_BRANCH}`],
|
|
340
|
+
{ cwd: root }
|
|
341
|
+
);
|
|
342
|
+
if (behind === '0') {
|
|
343
|
+
ok('Workspace ja esta atualizado.');
|
|
344
|
+
if (didStash) git(['stash', 'pop'], { cwd: root });
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const commitBefore = gitCapture(['rev-parse', '--short', 'HEAD'], { cwd: root });
|
|
349
|
+
|
|
350
|
+
// 5. Merge
|
|
351
|
+
log(`${behind} commit(s) novo(s). Fazendo merge...`);
|
|
352
|
+
const manifest = getManifest(root);
|
|
353
|
+
const frameworkPaths = manifest.frameworkManaged || [];
|
|
354
|
+
|
|
355
|
+
try {
|
|
356
|
+
git(['merge', `${UPSTREAM_REMOTE}/${UPSTREAM_BRANCH}`, '--no-edit'], { cwd: root, quiet: true });
|
|
357
|
+
ok('Merge concluido sem conflitos.');
|
|
358
|
+
} catch {
|
|
359
|
+
// Checar conflitos
|
|
360
|
+
const conflictFiles = gitCapture(['diff', '--name-only', '--diff-filter=U'], { cwd: root });
|
|
361
|
+
if (!conflictFiles) {
|
|
362
|
+
fail('Merge falhou por motivo desconhecido.');
|
|
363
|
+
if (didStash) info('Stash preservado. Rode: git stash pop');
|
|
364
|
+
process.exit(1);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const conflicts = conflictFiles.split('\n').filter(Boolean);
|
|
368
|
+
const userConflicts = [];
|
|
369
|
+
const fwConflicts = [];
|
|
370
|
+
|
|
371
|
+
for (const file of conflicts) {
|
|
372
|
+
const isFramework = frameworkPaths.some(fp => file.startsWith(fp.replace(/\/$/, '')));
|
|
373
|
+
if (isFramework) {
|
|
374
|
+
fwConflicts.push(file);
|
|
375
|
+
} else {
|
|
376
|
+
userConflicts.push(file);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Auto-resolve framework files
|
|
381
|
+
for (const file of fwConflicts) {
|
|
382
|
+
git(['checkout', '--theirs', file], { cwd: root, quiet: true });
|
|
383
|
+
git(['add', file], { cwd: root, quiet: true });
|
|
384
|
+
}
|
|
385
|
+
if (fwConflicts.length > 0) {
|
|
386
|
+
ok(`${fwConflicts.length} conflito(s) em arquivos do framework resolvidos automaticamente.`);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// User conflicts = abort
|
|
390
|
+
if (userConflicts.length > 0) {
|
|
391
|
+
fail('Conflitos em arquivos do usuario:');
|
|
392
|
+
for (const file of userConflicts) {
|
|
393
|
+
console.log(` - ${file}`);
|
|
394
|
+
}
|
|
395
|
+
info('Resolva os conflitos manualmente e rode: git merge --continue');
|
|
396
|
+
if (didStash) info('Stash preservado. Apos resolver: git stash pop');
|
|
397
|
+
process.exit(1);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Continuar merge se todos os conflitos foram resolvidos
|
|
401
|
+
git(['merge', '--continue', '--no-edit'], { cwd: root, quiet: true, ignoreError: true });
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const commitAfter = gitCapture(['rev-parse', '--short', 'HEAD'], { cwd: root });
|
|
405
|
+
|
|
406
|
+
// 6. Re-sync IDEs
|
|
407
|
+
const ideSetupScript = path.join(root, 'scripts', 'integrations', 'setup-ide-adapters.js');
|
|
408
|
+
if (pathExists(ideSetupScript)) {
|
|
409
|
+
log('Re-sincronizando IDE adapters...');
|
|
410
|
+
runNode(ideSetupScript, { cwd: root, quiet: true });
|
|
411
|
+
ok('IDE adapters atualizados.');
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// 7. Validar IDEs
|
|
415
|
+
const ideCheckScript = path.join(root, 'scripts', 'integrations', 'check-ide-compat.js');
|
|
416
|
+
if (pathExists(ideCheckScript)) {
|
|
417
|
+
runNode(ideCheckScript, { cwd: root, ignoreError: true, quiet: true });
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// 8. Pop stash
|
|
421
|
+
if (didStash) {
|
|
422
|
+
log('Restaurando mudancas locais (stash pop)...');
|
|
423
|
+
try {
|
|
424
|
+
git(['stash', 'pop'], { cwd: root, quiet: true });
|
|
425
|
+
ok('Mudancas locais restauradas.');
|
|
426
|
+
} catch {
|
|
427
|
+
warn('Falha ao restaurar stash. Rode manualmente: git stash pop');
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// 9. Salvar update log
|
|
432
|
+
const updateLog = path.join(root, LOCAL_DIR, 'update-log.json');
|
|
433
|
+
const previousLog = readJson(updateLog, {});
|
|
434
|
+
writeJson(updateLog, {
|
|
435
|
+
version: VERSION,
|
|
436
|
+
lastUpdate: new Date().toISOString(),
|
|
437
|
+
previousVersion: previousLog.version || null,
|
|
438
|
+
commitBefore,
|
|
439
|
+
commitAfter
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// 10. Changelog
|
|
443
|
+
console.log('');
|
|
444
|
+
ok(`Atualizado: ${commitBefore} -> ${commitAfter} (${behind} commits)`);
|
|
445
|
+
console.log('');
|
|
446
|
+
console.log(' Changelog:');
|
|
447
|
+
const changelog = gitCapture(
|
|
448
|
+
['log', '--oneline', `${commitBefore}..${commitAfter}`],
|
|
449
|
+
{ cwd: root }
|
|
450
|
+
);
|
|
451
|
+
if (changelog) {
|
|
452
|
+
for (const line of changelog.split('\n')) {
|
|
453
|
+
console.log(` ${line}`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
console.log('');
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// ---------------------------------------------------------------------------
|
|
460
|
+
// gos doctor
|
|
461
|
+
// ---------------------------------------------------------------------------
|
|
462
|
+
|
|
463
|
+
function cmdDoctor(root) {
|
|
464
|
+
log('Validando workspace ganbatte-os...');
|
|
465
|
+
console.log('');
|
|
466
|
+
|
|
467
|
+
let issues = 0;
|
|
468
|
+
let checks = 0;
|
|
469
|
+
|
|
470
|
+
function check(label, condition) {
|
|
471
|
+
checks++;
|
|
472
|
+
if (condition) {
|
|
473
|
+
ok(label);
|
|
474
|
+
} else {
|
|
475
|
+
fail(label);
|
|
476
|
+
issues++;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// 1. Manifest existe
|
|
481
|
+
const manifest = readJson(path.join(root, MANIFEST_PATH));
|
|
482
|
+
check('Manifest gos-install-manifest.json', !!manifest);
|
|
483
|
+
if (!manifest) {
|
|
484
|
+
fail('Sem manifest, validacao abortada.');
|
|
485
|
+
process.exit(1);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// 2. Required paths
|
|
489
|
+
const requiredPaths = manifest.requiredPaths || [];
|
|
490
|
+
for (const rp of requiredPaths) {
|
|
491
|
+
check(`Path: ${rp}`, pathExists(path.join(root, rp)));
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// 3. Runtime manifest
|
|
495
|
+
const runtime = readJson(path.join(root, 'manifests', 'g-os-runtime-manifest.json'));
|
|
496
|
+
check('Runtime manifest g-os-runtime-manifest.json', !!runtime);
|
|
497
|
+
|
|
498
|
+
// 4. Agents
|
|
499
|
+
if (runtime && runtime.modules && runtime.modules.agents) {
|
|
500
|
+
for (const agent of runtime.modules.agents) {
|
|
501
|
+
const agentFile = path.join(root, 'agents', 'profiles', `${agent}.md`);
|
|
502
|
+
check(`Agent: ${agent}`, pathExists(agentFile));
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// 5. Skills
|
|
507
|
+
const skillsRegistry = readJson(path.join(root, 'skills', 'registry.json'));
|
|
508
|
+
check('Skills registry', !!skillsRegistry);
|
|
509
|
+
|
|
510
|
+
if (runtime && runtime.modules && runtime.modules.skills) {
|
|
511
|
+
for (const skill of runtime.modules.skills) {
|
|
512
|
+
const skillFile = path.join(root, 'skills', skill, 'SKILL.md');
|
|
513
|
+
check(`Skill: ${skill}`, pathExists(skillFile));
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// 6. IDE adapters
|
|
518
|
+
const ideCheckScript = path.join(root, 'scripts', 'integrations', 'check-ide-compat.js');
|
|
519
|
+
if (pathExists(ideCheckScript)) {
|
|
520
|
+
try {
|
|
521
|
+
execFileSync(process.execPath, [ideCheckScript], { encoding: 'utf8', stdio: 'pipe', cwd: root });
|
|
522
|
+
ok('IDE adapters validados (check-ide-compat.js)');
|
|
523
|
+
checks++;
|
|
524
|
+
} catch {
|
|
525
|
+
fail('IDE adapters com problemas (check-ide-compat.js)');
|
|
526
|
+
checks++;
|
|
527
|
+
issues++;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// 7. Package.json
|
|
532
|
+
const pkg = readJson(path.join(root, 'package.json'));
|
|
533
|
+
check('package.json existe', !!pkg);
|
|
534
|
+
if (pkg) {
|
|
535
|
+
check('package.json tem scripts gos:*', !!(pkg.scripts && pkg.scripts['gos:update']));
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// 8. Git remote upstream (allow origin as fallback, especially for CI/Internal dev)
|
|
539
|
+
const remotes = gitCapture(['remote'], { cwd: root });
|
|
540
|
+
const hasUpstream = remotes.includes(UPSTREAM_REMOTE);
|
|
541
|
+
const hasOrigin = remotes.includes('origin');
|
|
542
|
+
check(`Git remote "${UPSTREAM_REMOTE}" configurado`, hasUpstream || hasOrigin);
|
|
543
|
+
|
|
544
|
+
// 9. Local dir (warn instead of fail if in CI)
|
|
545
|
+
const hasLocalDir = pathExists(path.join(root, LOCAL_DIR));
|
|
546
|
+
if (process.env.CI || process.env.GITHUB_ACTIONS) {
|
|
547
|
+
if (hasLocalDir) {
|
|
548
|
+
ok(`Diretorio ${LOCAL_DIR}/ existe`);
|
|
549
|
+
} else {
|
|
550
|
+
ok(`Diretorio ${LOCAL_DIR}/ (ignorado em CI)`);
|
|
551
|
+
}
|
|
552
|
+
checks++;
|
|
553
|
+
} else {
|
|
554
|
+
check(`Diretorio ${LOCAL_DIR}/ existe`, hasLocalDir);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// 10. Report
|
|
558
|
+
const updateLog = readJson(path.join(root, LOCAL_DIR, 'update-log.json'));
|
|
559
|
+
const installLogData = readJson(path.join(root, LOCAL_DIR, 'install-log.json'));
|
|
560
|
+
|
|
561
|
+
console.log('');
|
|
562
|
+
console.log(` Versao: ${pkg ? pkg.version || VERSION : VERSION}`);
|
|
563
|
+
console.log(` Inicializado: ${installLogData ? installLogData.initializedAt : 'N/A'}`);
|
|
564
|
+
console.log(` Ultimo update: ${updateLog ? updateLog.lastUpdate : 'N/A'}`);
|
|
565
|
+
console.log(` Node.js: ${process.version}`);
|
|
566
|
+
console.log('');
|
|
567
|
+
|
|
568
|
+
if (issues === 0) {
|
|
569
|
+
ok(`${checks} checks executados. Workspace saudavel.`);
|
|
570
|
+
} else {
|
|
571
|
+
fail(`${issues} problema(s) encontrado(s) em ${checks} checks.`);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
process.exit(issues > 0 ? 1 : 0);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// ---------------------------------------------------------------------------
|
|
578
|
+
// gos version
|
|
579
|
+
// ---------------------------------------------------------------------------
|
|
580
|
+
|
|
581
|
+
function cmdVersion(root) {
|
|
582
|
+
const pkg = readJson(path.join(root, 'package.json'), {});
|
|
583
|
+
const localVersion = pkg.version || VERSION;
|
|
584
|
+
|
|
585
|
+
console.log(`ganbatte-os v${localVersion}`);
|
|
586
|
+
|
|
587
|
+
// Checar se ha commits novos no upstream
|
|
588
|
+
const remotes = gitCapture(['remote'], { cwd: root });
|
|
589
|
+
if (!remotes.includes(UPSTREAM_REMOTE)) {
|
|
590
|
+
info(`Remote "${UPSTREAM_REMOTE}" nao configurado. Nao foi possivel checar atualizacoes.`);
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
try {
|
|
595
|
+
execFileSync('git', ['fetch', UPSTREAM_REMOTE, UPSTREAM_BRANCH], {
|
|
596
|
+
encoding: 'utf8', stdio: 'pipe', cwd: root
|
|
597
|
+
});
|
|
598
|
+
const behind = gitCapture(
|
|
599
|
+
['rev-list', '--count', `HEAD..${UPSTREAM_REMOTE}/${UPSTREAM_BRANCH}`],
|
|
600
|
+
{ cwd: root }
|
|
601
|
+
);
|
|
602
|
+
|
|
603
|
+
if (behind && behind !== '0') {
|
|
604
|
+
console.log(`\n ${behind} commit(s) novo(s) disponivel(is).`);
|
|
605
|
+
console.log(' Atualize com: npm run gos:update\n');
|
|
606
|
+
} else {
|
|
607
|
+
ok('Voce esta na versao mais recente.');
|
|
608
|
+
}
|
|
609
|
+
} catch {
|
|
610
|
+
warn('Nao foi possivel checar atualizacoes (sem conexao?).');
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// ---------------------------------------------------------------------------
|
|
615
|
+
// Main
|
|
616
|
+
// ---------------------------------------------------------------------------
|
|
617
|
+
|
|
618
|
+
function main() {
|
|
619
|
+
const args = process.argv.slice(2);
|
|
620
|
+
const command = args[0] || 'help';
|
|
621
|
+
const root = getRoot();
|
|
622
|
+
|
|
623
|
+
switch (command) {
|
|
624
|
+
case 'init':
|
|
625
|
+
cmdInit(root, args.slice(1));
|
|
626
|
+
break;
|
|
627
|
+
|
|
628
|
+
case 'install':
|
|
629
|
+
cmdInstall(args.slice(1));
|
|
630
|
+
break;
|
|
631
|
+
|
|
632
|
+
case 'update':
|
|
633
|
+
cmdUpdate(root, args.slice(1));
|
|
634
|
+
break;
|
|
635
|
+
|
|
636
|
+
case 'doctor':
|
|
637
|
+
cmdDoctor(root);
|
|
638
|
+
break;
|
|
639
|
+
|
|
640
|
+
case 'version':
|
|
641
|
+
case '-v':
|
|
642
|
+
case '--version':
|
|
643
|
+
cmdVersion(root);
|
|
644
|
+
break;
|
|
645
|
+
|
|
646
|
+
case 'help':
|
|
647
|
+
case '-h':
|
|
648
|
+
case '--help':
|
|
649
|
+
console.log(`
|
|
650
|
+
ganbatte-os CLI v${VERSION}
|
|
651
|
+
|
|
652
|
+
Comandos:
|
|
653
|
+
gos install Instalar G-OS no diretorio atual (via npx ou global)
|
|
654
|
+
gos init Setup pos-clone (remote, dirs, IDEs)
|
|
655
|
+
gos update Atualizar do upstream/main
|
|
656
|
+
gos doctor Validar integridade do workspace
|
|
657
|
+
gos version Mostrar versao e checar atualizacoes
|
|
658
|
+
gos help Exibir esta ajuda
|
|
659
|
+
|
|
660
|
+
Flags:
|
|
661
|
+
--force Sobrescrever arquivos existentes (install/init)
|
|
662
|
+
--no-stash Nao fazer stash automatico (update)
|
|
663
|
+
|
|
664
|
+
Exemplos:
|
|
665
|
+
npx ganbatte-os install
|
|
666
|
+
node scripts/cli/gos-cli.js init
|
|
667
|
+
npm run gos:update
|
|
668
|
+
npm run gos:doctor
|
|
669
|
+
`);
|
|
670
|
+
break;
|
|
671
|
+
|
|
672
|
+
default:
|
|
673
|
+
fail(`Comando desconhecido: ${command}`);
|
|
674
|
+
info('Rode: node scripts/cli/gos-cli.js help');
|
|
675
|
+
process.exit(1);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
main();
|