refactor(cli): restructure cmd packages into subdirectories
- Move CLI commands into subdirectories matching command hierarchy:
dev/, go/, php/, build/, ci/, sdk/, pkg/, vm/, docs/, setup/, doctor/, test/, ai/
- Create shared/ package for common styles and utilities
- Add new `core ai` root command with claude subcommand
- Update package declarations and imports across all files
- Create commands.go entry points for each package
- Remove GUI-related files (moved to core-gui repo)
This makes the filesystem structure match the CLI command structure,
improving context capture and code organization.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 18:02:43 +00:00
|
|
|
package vm
|
2026-01-28 18:59:45 +00:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
refactor(cli): move commands from cmd/ to pkg/ with self-registration
Implements defence in depth through build variants - only compiled code
exists in the binary. Commands now self-register via cli.RegisterCommands()
in their init() functions, mirroring the i18n.RegisterLocales() pattern.
Structure changes:
- cmd/{ai,build,ci,dev,docs,doctor,go,php,pkg,sdk,setup,test,vm}/ → pkg/*/cmd_*.go
- cmd/core_dev.go, cmd/core_ci.go → cmd/variants/{full,ci,php,minimal}.go
- Added pkg/cli/commands.go with RegisterCommands API
- Updated pkg/cli/runtime.go to attach registered commands
Build variants:
- go build → full (21MB, all 13 command groups)
- go build -tags ci → ci (18MB, build/ci/sdk/doctor)
- go build -tags php → php (14MB, php/doctor)
- go build -tags minimal → minimal (11MB, doctor only)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:55:55 +00:00
|
|
|
"errors"
|
2026-01-28 18:59:45 +00:00
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"os/exec"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"strings"
|
|
|
|
|
"text/tabwriter"
|
|
|
|
|
|
|
|
|
|
"github.com/host-uk/core/pkg/container"
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
"github.com/host-uk/core/pkg/i18n"
|
2026-02-04 15:33:22 +00:00
|
|
|
"github.com/host-uk/core/pkg/io"
|
2026-01-30 00:47:54 +00:00
|
|
|
"github.com/spf13/cobra"
|
2026-01-28 18:59:45 +00:00
|
|
|
)
|
|
|
|
|
|
2026-02-04 15:33:22 +00:00
|
|
|
var templateManager = container.NewTemplateManager(io.Local)
|
|
|
|
|
|
2026-01-29 11:35:22 +00:00
|
|
|
// addVMTemplatesCommand adds the 'templates' command under vm.
|
2026-01-30 00:47:54 +00:00
|
|
|
func addVMTemplatesCommand(parent *cobra.Command) {
|
|
|
|
|
templatesCmd := &cobra.Command{
|
|
|
|
|
Use: "templates",
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
Short: i18n.T("cmd.vm.templates.short"),
|
|
|
|
|
Long: i18n.T("cmd.vm.templates.long"),
|
2026-01-30 00:47:54 +00:00
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
|
|
|
return listTemplates()
|
|
|
|
|
},
|
|
|
|
|
}
|
2026-01-28 18:59:45 +00:00
|
|
|
|
|
|
|
|
// Add subcommands
|
|
|
|
|
addTemplatesShowCommand(templatesCmd)
|
|
|
|
|
addTemplatesVarsCommand(templatesCmd)
|
2026-01-30 00:47:54 +00:00
|
|
|
|
|
|
|
|
parent.AddCommand(templatesCmd)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// addTemplatesShowCommand adds the 'templates show' subcommand.
|
2026-01-30 00:47:54 +00:00
|
|
|
func addTemplatesShowCommand(parent *cobra.Command) {
|
|
|
|
|
showCmd := &cobra.Command{
|
|
|
|
|
Use: "show <template-name>",
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
Short: i18n.T("cmd.vm.templates.show.short"),
|
|
|
|
|
Long: i18n.T("cmd.vm.templates.show.long"),
|
2026-01-30 00:47:54 +00:00
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
|
|
|
if len(args) == 0 {
|
refactor(cli): move commands from cmd/ to pkg/ with self-registration
Implements defence in depth through build variants - only compiled code
exists in the binary. Commands now self-register via cli.RegisterCommands()
in their init() functions, mirroring the i18n.RegisterLocales() pattern.
Structure changes:
- cmd/{ai,build,ci,dev,docs,doctor,go,php,pkg,sdk,setup,test,vm}/ → pkg/*/cmd_*.go
- cmd/core_dev.go, cmd/core_ci.go → cmd/variants/{full,ci,php,minimal}.go
- Added pkg/cli/commands.go with RegisterCommands API
- Updated pkg/cli/runtime.go to attach registered commands
Build variants:
- go build → full (21MB, all 13 command groups)
- go build -tags ci → ci (18MB, build/ci/sdk/doctor)
- go build -tags php → php (14MB, php/doctor)
- go build -tags minimal → minimal (11MB, doctor only)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:55:55 +00:00
|
|
|
return errors.New(i18n.T("cmd.vm.error.template_required"))
|
2026-01-30 00:47:54 +00:00
|
|
|
}
|
|
|
|
|
return showTemplate(args[0])
|
|
|
|
|
},
|
|
|
|
|
}
|
2026-01-28 18:59:45 +00:00
|
|
|
|
2026-01-30 00:47:54 +00:00
|
|
|
parent.AddCommand(showCmd)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// addTemplatesVarsCommand adds the 'templates vars' subcommand.
|
2026-01-30 00:47:54 +00:00
|
|
|
func addTemplatesVarsCommand(parent *cobra.Command) {
|
|
|
|
|
varsCmd := &cobra.Command{
|
|
|
|
|
Use: "vars <template-name>",
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
Short: i18n.T("cmd.vm.templates.vars.short"),
|
|
|
|
|
Long: i18n.T("cmd.vm.templates.vars.long"),
|
2026-01-30 00:47:54 +00:00
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
|
|
|
if len(args) == 0 {
|
refactor(cli): move commands from cmd/ to pkg/ with self-registration
Implements defence in depth through build variants - only compiled code
exists in the binary. Commands now self-register via cli.RegisterCommands()
in their init() functions, mirroring the i18n.RegisterLocales() pattern.
Structure changes:
- cmd/{ai,build,ci,dev,docs,doctor,go,php,pkg,sdk,setup,test,vm}/ → pkg/*/cmd_*.go
- cmd/core_dev.go, cmd/core_ci.go → cmd/variants/{full,ci,php,minimal}.go
- Added pkg/cli/commands.go with RegisterCommands API
- Updated pkg/cli/runtime.go to attach registered commands
Build variants:
- go build → full (21MB, all 13 command groups)
- go build -tags ci → ci (18MB, build/ci/sdk/doctor)
- go build -tags php → php (14MB, php/doctor)
- go build -tags minimal → minimal (11MB, doctor only)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:55:55 +00:00
|
|
|
return errors.New(i18n.T("cmd.vm.error.template_required"))
|
2026-01-30 00:47:54 +00:00
|
|
|
}
|
|
|
|
|
return showTemplateVars(args[0])
|
|
|
|
|
},
|
|
|
|
|
}
|
2026-01-28 18:59:45 +00:00
|
|
|
|
2026-01-30 00:47:54 +00:00
|
|
|
parent.AddCommand(varsCmd)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func listTemplates() error {
|
2026-02-04 15:33:22 +00:00
|
|
|
templates := templateManager.ListTemplates()
|
2026-01-28 18:59:45 +00:00
|
|
|
|
|
|
|
|
if len(templates) == 0 {
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Println(i18n.T("cmd.vm.templates.no_templates"))
|
2026-01-28 18:59:45 +00:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Printf("%s\n\n", repoNameStyle.Render(i18n.T("cmd.vm.templates.title")))
|
2026-01-28 18:59:45 +00:00
|
|
|
|
|
|
|
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
feat: infrastructure packages and lint cleanup (#281)
* ci: consolidate duplicate workflows and merge CodeQL configs
Remove 17 duplicate workflow files that were split copies of the
combined originals. Each family (CI, CodeQL, Coverage, PR Build,
Alpha Release) had the same job duplicated across separate
push/pull_request/schedule/manual trigger files.
Merge codeql.yml and codescan.yml into a single codeql.yml with
a language matrix covering go, javascript-typescript, python,
and actions — matching the previous default setup coverage.
Remaining workflows (one per family):
- ci.yml (push + PR + manual)
- codeql.yml (push + PR + schedule, all languages)
- coverage.yml (push + PR + manual)
- alpha-release.yml (push + manual)
- pr-build.yml (PR + manual)
- release.yml (tag push)
- agent-verify.yml, auto-label.yml, auto-project.yml
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add collect, config, crypt, plugin packages and fix all lint issues
Add four new infrastructure packages with CLI commands:
- pkg/config: layered configuration (defaults → file → env → flags)
- pkg/crypt: crypto primitives (Argon2id, AES-GCM, ChaCha20, HMAC, checksums)
- pkg/plugin: plugin system with GitHub-based install/update/remove
- pkg/collect: collection subsystem (GitHub, BitcoinTalk, market, papers, excavate)
Fix all golangci-lint issues across the entire codebase (~100 errcheck,
staticcheck SA1012/SA1019/ST1005, unused, ineffassign fixes) so that
`core go qa` passes with 0 issues.
Closes #167, #168, #170, #250, #251, #252, #253, #254, #255, #256
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 11:34:43 +00:00
|
|
|
_, _ = fmt.Fprintln(w, i18n.T("cmd.vm.templates.header"))
|
|
|
|
|
_, _ = fmt.Fprintln(w, "----\t-----------")
|
2026-01-28 18:59:45 +00:00
|
|
|
|
|
|
|
|
for _, tmpl := range templates {
|
|
|
|
|
desc := tmpl.Description
|
|
|
|
|
if len(desc) > 60 {
|
|
|
|
|
desc = desc[:57] + "..."
|
|
|
|
|
}
|
feat: infrastructure packages and lint cleanup (#281)
* ci: consolidate duplicate workflows and merge CodeQL configs
Remove 17 duplicate workflow files that were split copies of the
combined originals. Each family (CI, CodeQL, Coverage, PR Build,
Alpha Release) had the same job duplicated across separate
push/pull_request/schedule/manual trigger files.
Merge codeql.yml and codescan.yml into a single codeql.yml with
a language matrix covering go, javascript-typescript, python,
and actions — matching the previous default setup coverage.
Remaining workflows (one per family):
- ci.yml (push + PR + manual)
- codeql.yml (push + PR + schedule, all languages)
- coverage.yml (push + PR + manual)
- alpha-release.yml (push + manual)
- pr-build.yml (PR + manual)
- release.yml (tag push)
- agent-verify.yml, auto-label.yml, auto-project.yml
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add collect, config, crypt, plugin packages and fix all lint issues
Add four new infrastructure packages with CLI commands:
- pkg/config: layered configuration (defaults → file → env → flags)
- pkg/crypt: crypto primitives (Argon2id, AES-GCM, ChaCha20, HMAC, checksums)
- pkg/plugin: plugin system with GitHub-based install/update/remove
- pkg/collect: collection subsystem (GitHub, BitcoinTalk, market, papers, excavate)
Fix all golangci-lint issues across the entire codebase (~100 errcheck,
staticcheck SA1012/SA1019/ST1005, unused, ineffassign fixes) so that
`core go qa` passes with 0 issues.
Closes #167, #168, #170, #250, #251, #252, #253, #254, #255, #256
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 11:34:43 +00:00
|
|
|
_, _ = fmt.Fprintf(w, "%s\t%s\n", repoNameStyle.Render(tmpl.Name), desc)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
feat: infrastructure packages and lint cleanup (#281)
* ci: consolidate duplicate workflows and merge CodeQL configs
Remove 17 duplicate workflow files that were split copies of the
combined originals. Each family (CI, CodeQL, Coverage, PR Build,
Alpha Release) had the same job duplicated across separate
push/pull_request/schedule/manual trigger files.
Merge codeql.yml and codescan.yml into a single codeql.yml with
a language matrix covering go, javascript-typescript, python,
and actions — matching the previous default setup coverage.
Remaining workflows (one per family):
- ci.yml (push + PR + manual)
- codeql.yml (push + PR + schedule, all languages)
- coverage.yml (push + PR + manual)
- alpha-release.yml (push + manual)
- pr-build.yml (PR + manual)
- release.yml (tag push)
- agent-verify.yml, auto-label.yml, auto-project.yml
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add collect, config, crypt, plugin packages and fix all lint issues
Add four new infrastructure packages with CLI commands:
- pkg/config: layered configuration (defaults → file → env → flags)
- pkg/crypt: crypto primitives (Argon2id, AES-GCM, ChaCha20, HMAC, checksums)
- pkg/plugin: plugin system with GitHub-based install/update/remove
- pkg/collect: collection subsystem (GitHub, BitcoinTalk, market, papers, excavate)
Fix all golangci-lint issues across the entire codebase (~100 errcheck,
staticcheck SA1012/SA1019/ST1005, unused, ineffassign fixes) so that
`core go qa` passes with 0 issues.
Closes #167, #168, #170, #250, #251, #252, #253, #254, #255, #256
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 11:34:43 +00:00
|
|
|
_ = w.Flush()
|
2026-01-28 18:59:45 +00:00
|
|
|
|
|
|
|
|
fmt.Println()
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Printf("%s %s\n", i18n.T("cmd.vm.templates.hint.show"), dimStyle.Render("core vm templates show <name>"))
|
|
|
|
|
fmt.Printf("%s %s\n", i18n.T("cmd.vm.templates.hint.vars"), dimStyle.Render("core vm templates vars <name>"))
|
|
|
|
|
fmt.Printf("%s %s\n", i18n.T("cmd.vm.templates.hint.run"), dimStyle.Render("core vm run --template <name> --var SSH_KEY=\"...\""))
|
2026-01-28 18:59:45 +00:00
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func showTemplate(name string) error {
|
2026-02-04 15:33:22 +00:00
|
|
|
content, err := templateManager.GetTemplate(name)
|
2026-01-28 18:59:45 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
refactor(i18n): consolidate duplicate translation keys into common section
Add common.* keys for reusable translations:
- common.label.* - UI labels (error, done, status, version, etc.)
- common.status.* - status words (running, stopped, dirty, synced)
- common.error.* - error messages (failed, not_found, working_dir)
- common.flag.* - CLI flag descriptions (registry, verbose, etc.)
- common.count.* - count templates (failed, passed, skipped)
- common.result.* - result messages (all_passed, no_issues)
- common.progress.* - progress messages (running, checking)
- common.hint.* - help hints (install_with, fix_deps)
Update all cmd/* files to use common keys instead of duplicated
command-specific keys. Reduces translation maintenance burden
and ensures consistency across the CLI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:32:25 +00:00
|
|
|
fmt.Printf("%s %s\n\n", dimStyle.Render(i18n.T("common.label.template")), repoNameStyle.Render(name))
|
2026-01-28 18:59:45 +00:00
|
|
|
fmt.Println(content)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func showTemplateVars(name string) error {
|
2026-02-04 15:33:22 +00:00
|
|
|
content, err := templateManager.GetTemplate(name)
|
2026-01-28 18:59:45 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
required, optional := container.ExtractVariables(content)
|
|
|
|
|
|
refactor(i18n): consolidate duplicate translation keys into common section
Add common.* keys for reusable translations:
- common.label.* - UI labels (error, done, status, version, etc.)
- common.status.* - status words (running, stopped, dirty, synced)
- common.error.* - error messages (failed, not_found, working_dir)
- common.flag.* - CLI flag descriptions (registry, verbose, etc.)
- common.count.* - count templates (failed, passed, skipped)
- common.result.* - result messages (all_passed, no_issues)
- common.progress.* - progress messages (running, checking)
- common.hint.* - help hints (install_with, fix_deps)
Update all cmd/* files to use common keys instead of duplicated
command-specific keys. Reduces translation maintenance burden
and ensures consistency across the CLI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:32:25 +00:00
|
|
|
fmt.Printf("%s %s\n\n", dimStyle.Render(i18n.T("common.label.template")), repoNameStyle.Render(name))
|
2026-01-28 18:59:45 +00:00
|
|
|
|
|
|
|
|
if len(required) > 0 {
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Printf("%s\n", errorStyle.Render(i18n.T("cmd.vm.templates.vars.required")))
|
2026-01-28 18:59:45 +00:00
|
|
|
for _, v := range required {
|
|
|
|
|
fmt.Printf(" %s\n", varStyle.Render("${"+v+"}"))
|
|
|
|
|
}
|
|
|
|
|
fmt.Println()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(optional) > 0 {
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Printf("%s\n", successStyle.Render(i18n.T("cmd.vm.templates.vars.optional")))
|
2026-01-28 18:59:45 +00:00
|
|
|
for v, def := range optional {
|
|
|
|
|
fmt.Printf(" %s = %s\n",
|
|
|
|
|
varStyle.Render("${"+v+"}"),
|
|
|
|
|
defaultStyle.Render(def))
|
|
|
|
|
}
|
|
|
|
|
fmt.Println()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(required) == 0 && len(optional) == 0 {
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Println(i18n.T("cmd.vm.templates.vars.none"))
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RunFromTemplate builds and runs a LinuxKit image from a template.
|
|
|
|
|
func RunFromTemplate(templateName string, vars map[string]string, runOpts container.RunOptions) error {
|
|
|
|
|
// Apply template with variables
|
2026-02-04 15:33:22 +00:00
|
|
|
content, err := templateManager.ApplyTemplate(templateName, vars)
|
2026-01-28 18:59:45 +00:00
|
|
|
if err != nil {
|
2026-01-30 11:44:45 +00:00
|
|
|
return fmt.Errorf(i18n.T("common.error.failed", map[string]any{"Action": "apply template"})+": %w", err)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a temporary directory for the build
|
|
|
|
|
tmpDir, err := os.MkdirTemp("", "core-linuxkit-*")
|
|
|
|
|
if err != nil {
|
2026-01-30 11:44:45 +00:00
|
|
|
return fmt.Errorf(i18n.T("common.error.failed", map[string]any{"Action": "create temp directory"})+": %w", err)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
feat: infrastructure packages and lint cleanup (#281)
* ci: consolidate duplicate workflows and merge CodeQL configs
Remove 17 duplicate workflow files that were split copies of the
combined originals. Each family (CI, CodeQL, Coverage, PR Build,
Alpha Release) had the same job duplicated across separate
push/pull_request/schedule/manual trigger files.
Merge codeql.yml and codescan.yml into a single codeql.yml with
a language matrix covering go, javascript-typescript, python,
and actions — matching the previous default setup coverage.
Remaining workflows (one per family):
- ci.yml (push + PR + manual)
- codeql.yml (push + PR + schedule, all languages)
- coverage.yml (push + PR + manual)
- alpha-release.yml (push + manual)
- pr-build.yml (PR + manual)
- release.yml (tag push)
- agent-verify.yml, auto-label.yml, auto-project.yml
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add collect, config, crypt, plugin packages and fix all lint issues
Add four new infrastructure packages with CLI commands:
- pkg/config: layered configuration (defaults → file → env → flags)
- pkg/crypt: crypto primitives (Argon2id, AES-GCM, ChaCha20, HMAC, checksums)
- pkg/plugin: plugin system with GitHub-based install/update/remove
- pkg/collect: collection subsystem (GitHub, BitcoinTalk, market, papers, excavate)
Fix all golangci-lint issues across the entire codebase (~100 errcheck,
staticcheck SA1012/SA1019/ST1005, unused, ineffassign fixes) so that
`core go qa` passes with 0 issues.
Closes #167, #168, #170, #250, #251, #252, #253, #254, #255, #256
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 11:34:43 +00:00
|
|
|
defer func() { _ = os.RemoveAll(tmpDir) }()
|
2026-01-28 18:59:45 +00:00
|
|
|
|
|
|
|
|
// Write the YAML file
|
|
|
|
|
yamlPath := filepath.Join(tmpDir, templateName+".yml")
|
|
|
|
|
if err := os.WriteFile(yamlPath, []byte(content), 0644); err != nil {
|
2026-01-30 11:44:45 +00:00
|
|
|
return fmt.Errorf(i18n.T("common.error.failed", map[string]any{"Action": "write template"})+": %w", err)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
refactor(i18n): consolidate duplicate translation keys into common section
Add common.* keys for reusable translations:
- common.label.* - UI labels (error, done, status, version, etc.)
- common.status.* - status words (running, stopped, dirty, synced)
- common.error.* - error messages (failed, not_found, working_dir)
- common.flag.* - CLI flag descriptions (registry, verbose, etc.)
- common.count.* - count templates (failed, passed, skipped)
- common.result.* - result messages (all_passed, no_issues)
- common.progress.* - progress messages (running, checking)
- common.hint.* - help hints (install_with, fix_deps)
Update all cmd/* files to use common keys instead of duplicated
command-specific keys. Reduces translation maintenance burden
and ensures consistency across the CLI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:32:25 +00:00
|
|
|
fmt.Printf("%s %s\n", dimStyle.Render(i18n.T("common.label.template")), repoNameStyle.Render(templateName))
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Printf("%s %s\n", dimStyle.Render(i18n.T("cmd.vm.label.building")), yamlPath)
|
2026-01-28 18:59:45 +00:00
|
|
|
|
|
|
|
|
// Build the image using linuxkit
|
|
|
|
|
outputPath := filepath.Join(tmpDir, templateName)
|
|
|
|
|
if err := buildLinuxKitImage(yamlPath, outputPath); err != nil {
|
2026-01-30 11:44:45 +00:00
|
|
|
return fmt.Errorf(i18n.T("common.error.failed", map[string]any{"Action": "build image"})+": %w", err)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find the built image (linuxkit creates .iso or other format)
|
|
|
|
|
imagePath := findBuiltImage(outputPath)
|
|
|
|
|
if imagePath == "" {
|
refactor(cli): move commands from cmd/ to pkg/ with self-registration
Implements defence in depth through build variants - only compiled code
exists in the binary. Commands now self-register via cli.RegisterCommands()
in their init() functions, mirroring the i18n.RegisterLocales() pattern.
Structure changes:
- cmd/{ai,build,ci,dev,docs,doctor,go,php,pkg,sdk,setup,test,vm}/ → pkg/*/cmd_*.go
- cmd/core_dev.go, cmd/core_ci.go → cmd/variants/{full,ci,php,minimal}.go
- Added pkg/cli/commands.go with RegisterCommands API
- Updated pkg/cli/runtime.go to attach registered commands
Build variants:
- go build → full (21MB, all 13 command groups)
- go build -tags ci → ci (18MB, build/ci/sdk/doctor)
- go build -tags php → php (14MB, php/doctor)
- go build -tags minimal → minimal (11MB, doctor only)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:55:55 +00:00
|
|
|
return errors.New(i18n.T("cmd.vm.error.no_image_found"))
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
refactor(i18n): consolidate duplicate translation keys into common section
Add common.* keys for reusable translations:
- common.label.* - UI labels (error, done, status, version, etc.)
- common.status.* - status words (running, stopped, dirty, synced)
- common.error.* - error messages (failed, not_found, working_dir)
- common.flag.* - CLI flag descriptions (registry, verbose, etc.)
- common.count.* - count templates (failed, passed, skipped)
- common.result.* - result messages (all_passed, no_issues)
- common.progress.* - progress messages (running, checking)
- common.hint.* - help hints (install_with, fix_deps)
Update all cmd/* files to use common keys instead of duplicated
command-specific keys. Reduces translation maintenance burden
and ensures consistency across the CLI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:32:25 +00:00
|
|
|
fmt.Printf("%s %s\n", dimStyle.Render(i18n.T("common.label.image")), imagePath)
|
2026-01-28 18:59:45 +00:00
|
|
|
fmt.Println()
|
|
|
|
|
|
|
|
|
|
// Run the image
|
2026-02-04 15:33:22 +00:00
|
|
|
manager, err := container.NewLinuxKitManager(io.Local)
|
2026-01-28 18:59:45 +00:00
|
|
|
if err != nil {
|
2026-01-30 11:44:45 +00:00
|
|
|
return fmt.Errorf(i18n.T("common.error.failed", map[string]any{"Action": "initialize container manager"})+": %w", err)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Printf("%s %s\n", dimStyle.Render(i18n.T("cmd.vm.label.hypervisor")), manager.Hypervisor().Name())
|
2026-01-28 18:59:45 +00:00
|
|
|
fmt.Println()
|
|
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
c, err := manager.Run(ctx, imagePath, runOpts)
|
|
|
|
|
if err != nil {
|
2026-02-04 15:33:22 +00:00
|
|
|
return fmt.Errorf(i18n.T("i18n.fail.run", "container")+": %w", err)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if runOpts.Detach {
|
refactor(i18n): consolidate duplicate translation keys into common section
Add common.* keys for reusable translations:
- common.label.* - UI labels (error, done, status, version, etc.)
- common.status.* - status words (running, stopped, dirty, synced)
- common.error.* - error messages (failed, not_found, working_dir)
- common.flag.* - CLI flag descriptions (registry, verbose, etc.)
- common.count.* - count templates (failed, passed, skipped)
- common.result.* - result messages (all_passed, no_issues)
- common.progress.* - progress messages (running, checking)
- common.hint.* - help hints (install_with, fix_deps)
Update all cmd/* files to use common keys instead of duplicated
command-specific keys. Reduces translation maintenance burden
and ensures consistency across the CLI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:32:25 +00:00
|
|
|
fmt.Printf("%s %s\n", successStyle.Render(i18n.T("common.label.started")), c.ID)
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Printf("%s %d\n", dimStyle.Render(i18n.T("cmd.vm.label.pid")), c.PID)
|
2026-01-28 18:59:45 +00:00
|
|
|
fmt.Println()
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Println(i18n.T("cmd.vm.hint.view_logs", map[string]interface{}{"ID": c.ID[:8]}))
|
|
|
|
|
fmt.Println(i18n.T("cmd.vm.hint.stop", map[string]interface{}{"ID": c.ID[:8]}))
|
2026-01-28 18:59:45 +00:00
|
|
|
} else {
|
feat(i18n): add translation keys to all CLI commands
Replace hardcoded strings with i18n.T() calls across all cmd/* packages:
- ai, build, ci, dev, docs, doctor, go, php, pkg, sdk, setup, test, vm
Adds 500+ translation keys to en.json for command descriptions,
flag descriptions, labels, messages, and error strings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:37:57 +00:00
|
|
|
fmt.Printf("\n%s %s\n", dimStyle.Render(i18n.T("cmd.vm.label.container_stopped")), c.ID)
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// buildLinuxKitImage builds a LinuxKit image from a YAML file.
|
|
|
|
|
func buildLinuxKitImage(yamlPath, outputPath string) error {
|
|
|
|
|
// Check if linuxkit is available
|
|
|
|
|
lkPath, err := lookupLinuxKit()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build the image
|
2026-01-31 23:36:43 +00:00
|
|
|
// linuxkit build --format iso-bios --name <output> <yaml>
|
2026-01-28 18:59:45 +00:00
|
|
|
cmd := exec.Command(lkPath, "build",
|
2026-01-31 23:36:43 +00:00
|
|
|
"--format", "iso-bios",
|
|
|
|
|
"--name", outputPath,
|
2026-01-28 18:59:45 +00:00
|
|
|
yamlPath)
|
|
|
|
|
|
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
|
|
|
|
|
return cmd.Run()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// findBuiltImage finds the built image file.
|
|
|
|
|
func findBuiltImage(basePath string) string {
|
|
|
|
|
// LinuxKit can create different formats
|
|
|
|
|
extensions := []string{".iso", "-bios.iso", ".qcow2", ".raw", ".vmdk"}
|
|
|
|
|
|
|
|
|
|
for _, ext := range extensions {
|
|
|
|
|
path := basePath + ext
|
|
|
|
|
if _, err := os.Stat(path); err == nil {
|
|
|
|
|
return path
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check directory for any image file
|
|
|
|
|
dir := filepath.Dir(basePath)
|
|
|
|
|
base := filepath.Base(basePath)
|
|
|
|
|
|
|
|
|
|
entries, err := os.ReadDir(dir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, entry := range entries {
|
|
|
|
|
name := entry.Name()
|
|
|
|
|
if strings.HasPrefix(name, base) {
|
|
|
|
|
for _, ext := range []string{".iso", ".qcow2", ".raw", ".vmdk"} {
|
|
|
|
|
if strings.HasSuffix(name, ext) {
|
|
|
|
|
return filepath.Join(dir, name)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// lookupLinuxKit finds the linuxkit binary.
|
|
|
|
|
func lookupLinuxKit() (string, error) {
|
|
|
|
|
// Check PATH first
|
|
|
|
|
if path, err := exec.LookPath("linuxkit"); err == nil {
|
|
|
|
|
return path, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check common locations
|
|
|
|
|
paths := []string{
|
|
|
|
|
"/usr/local/bin/linuxkit",
|
|
|
|
|
"/opt/homebrew/bin/linuxkit",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, p := range paths {
|
|
|
|
|
if _, err := os.Stat(p); err == nil {
|
|
|
|
|
return p, nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
refactor(cli): move commands from cmd/ to pkg/ with self-registration
Implements defence in depth through build variants - only compiled code
exists in the binary. Commands now self-register via cli.RegisterCommands()
in their init() functions, mirroring the i18n.RegisterLocales() pattern.
Structure changes:
- cmd/{ai,build,ci,dev,docs,doctor,go,php,pkg,sdk,setup,test,vm}/ → pkg/*/cmd_*.go
- cmd/core_dev.go, cmd/core_ci.go → cmd/variants/{full,ci,php,minimal}.go
- Added pkg/cli/commands.go with RegisterCommands API
- Updated pkg/cli/runtime.go to attach registered commands
Build variants:
- go build → full (21MB, all 13 command groups)
- go build -tags ci → ci (18MB, build/ci/sdk/doctor)
- go build -tags php → php (14MB, php/doctor)
- go build -tags minimal → minimal (11MB, doctor only)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:55:55 +00:00
|
|
|
return "", errors.New(i18n.T("cmd.vm.error.linuxkit_not_found"))
|
2026-01-28 18:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ParseVarFlags parses --var flags into a map.
|
|
|
|
|
// Format: --var KEY=VALUE or --var KEY="VALUE"
|
|
|
|
|
func ParseVarFlags(varFlags []string) map[string]string {
|
|
|
|
|
vars := make(map[string]string)
|
|
|
|
|
|
|
|
|
|
for _, v := range varFlags {
|
|
|
|
|
parts := strings.SplitN(v, "=", 2)
|
|
|
|
|
if len(parts) == 2 {
|
|
|
|
|
key := strings.TrimSpace(parts[0])
|
|
|
|
|
value := strings.TrimSpace(parts[1])
|
|
|
|
|
// Remove surrounding quotes if present
|
|
|
|
|
value = strings.Trim(value, "\"'")
|
|
|
|
|
vars[key] = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return vars
|
|
|
|
|
}
|