Skip to content

refactor(kit): Expose core Kit CLI functionality as a reusable Go library #905#1097

Open
arnab2001 wants to merge 8 commits intokitops-ml:mainfrom
arnab2001:refactor(kit)-extract-command-logic-into-pkg/kit-and-wire-CLI-commands
Open

refactor(kit): Expose core Kit CLI functionality as a reusable Go library #905#1097
arnab2001 wants to merge 8 commits intokitops-ml:mainfrom
arnab2001:refactor(kit)-extract-command-logic-into-pkg/kit-and-wire-CLI-commands

Conversation

@arnab2001
Copy link
Copy Markdown
Contributor

@arnab2001 arnab2001 commented Feb 26, 2026

Description

Refactors CLI command implementations into a reusable Go API under pkg/kit.

  • Adds pkg/kit operations for Info, Inspect, List, Login, Logout, Pull, Push, Remove, Tag, and Unpack wrappers.
  • Updates CLI command entrypoints (pkg/cmd/*/cmd.go) to call pkg/kit instead of local command-specific logic.
  • Removes migrated legacy command implementation files from pkg/cmd/*.
  • Moves list helper tests to pkg/kit/list_test.go.
  • Adds package docs (pkg/kit/doc.go, pkg/kit/README.md).
  • Updates .gitignore to ignore root-only binaries (/kit, /kit.exe).
  • Validation: go test ./... passes.

Closes #905

AI-Assisted Code

  • This PR contains AI-generated code that I have reviewed and tested
  • I take full responsibility for all code in this PR, regardless of how it was created

Signed-off-by: Arnab Chatterjee <arnabchat2001@gmail.com>
@arnab2001 arnab2001 changed the title refactor(kit): extract command logic into pkg/kit and wire CLI commands refactor(kit): Expose core Kit CLI functionality as a reusable Go library Feb 26, 2026
Signed-off-by: Arnab Chatterjee <arnabchat2001@gmail.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6da19a0973

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}

desc, err := localRepo.PullModel(ctx, repo, *opts.modelRef, &opts.NetworkOptions)
desc, err := localRepo.PullModel(ctx, repo, *opts.ModelRef, &opts.NetworkOptions)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Normalize Pull concurrency before invoking repository pull

The new kit.Pull API forwards opts.NetworkOptions directly into localRepo.PullModel without running NetworkOptions.Complete or otherwise enforcing a minimum concurrency, so zero-value PullOptions (a common Go usage) pass Concurrency=0. In pkg/lib/repo/local/pull.go:65-85, that becomes semaphore.NewWeighted(0) followed by Acquire(..., 1), which blocks until context cancellation and makes pulls hang/fail even for valid references; the old CLI path avoided this because flag parsing set a default and Complete validated >=1.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 95e4e52kit.Pull now initializes Concurrency to 5 when the caller leaves it at zero, and sets CredentialsPath + TLSVerify defaults. Same guard was also added to kit.Push in 022577d for consistency.

if err != nil {
return err
}
reg, err := remote.NewRegistry(opts.Registry, &opts.NetworkOptions)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Default TLS verification to enabled for kit API calls

This new library entrypoint passes opts.NetworkOptions straight to remote.NewRegistry, so callers who use zero-value LoginOptions get TLSVerify=false; pkg/lib/network/auth.go:71 then sets InsecureSkipVerify = !opts.TLSVerify, silently disabling certificate verification. The CLI previously defaulted --tls-verify to true via flag wiring, but the extracted pkg/kit API now exposes an insecure default for normal programmatic use and can allow MITM interception of registry credentials unless every caller manually overrides it.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 95e4e52kit.Login now defaults TLSVerify to true when CredentialsPath is empty (same pattern as kit.Pull). The kit.Push entrypoint also got the same guard in 022577d.

Signed-off-by: Arnab Chatterjee <arnabchat2001@gmail.com>
Signed-off-by: Arnab Chatterjee <arnabchat2001@gmail.com>
@arnab2001
Copy link
Copy Markdown
Contributor Author

Addressed both Codex P1 suggestions by adding safe default normalization in pkg/kit API entrypoints (pull/login), and re-ran targeted tests for kit/network/repo packages.

@arnab2001 arnab2001 changed the title refactor(kit): Expose core Kit CLI functionality as a reusable Go library refactor(kit): Expose core Kit CLI functionality as a reusable Go library #905 Feb 26, 2026
Comment on lines 45 to 72
@@ -66,17 +91,15 @@ func removeAllModels(ctx context.Context, opts *removeOptions) error {
output.Errorf("Failed to remove %s@%s: %s", repository, manifestDesc.Digest, err)
continue
}
// Skip future manifest descriptors with this digest, since we just removed it.
skipManifests[manifestDesc.Digest] = true
output.Infof("Removed %s@%s", repository, manifestDesc.Digest)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have all the comments on this file been removed?

Copy link
Copy Markdown
Contributor Author

@arnab2001 arnab2001 Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comments were accidentally stripped during the initial refactor. Restored all comments in pkg/kit/remove.go (the new home for this logic) in 95e4e52, including the skipManifests explanation, untag-vs-delete rationale, and the oras Untagger interface note.

Comment on lines +168 to +175
kitOpts := &kit.RemoveOptions{
NetworkOptions: opts.NetworkOptions,
ConfigHome: opts.configHome,
ForceDelete: opts.forceDelete,
RemoveAll: opts.removeAll,
Remote: opts.remote,
ModelRef: opts.modelRef,
ExtraTags: opts.extraTags,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're now duplicating the options for every command twice -- once in the cmd package and once in the kit package. Why not import the e.g. kit.RemoveOptions struct here and bind flags into it instead of defining it twice?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, this was unnecessary duplication. Fixed in 95e4e52 — all cmd packages now embed kit.*Options directly (e.g. type removeOptions struct { kit.RemoveOptions }) and pass &opts.RemoveOptions to the kit function. CLI-specific fields like format/template in list or username/password in login are the only local additions. No more manual field-by-field copy.

@arnab2001 arnab2001 force-pushed the refactor(kit)-extract-command-logic-into-pkg/kit-and-wire-CLI-commands branch from 022577d to 503f383 Compare April 3, 2026 15:58
Resolve merge conflicts with upstream/main, incorporating:
- artifact.FormatRepositoryForDisplay/ReferenceIsDigest renames
- --filter support for kit list
- kitfile.FilterConf/ParseFilter relocation

Address reviewer feedback:
- Eliminate options duplication by embedding kit.*Options in cmd structs
- Restore comments removed during initial refactor
- Use kit.ModelInfo directly in cmd/list via type alias

Fix review findings:
- Fix %ws typo in removeModelRef error wrapping
- Add credential/concurrency initialization to kit.Push
- Fix TagCommand to use declared opts variable

Signed-off-by: Arnab Chatterjee <arnabchat2001@gmail.com>
@arnab2001 arnab2001 force-pushed the refactor(kit)-extract-command-logic-into-pkg/kit-and-wire-CLI-commands branch from 503f383 to b9ad61f Compare April 3, 2026 16:16
@arnab2001 arnab2001 requested a review from amisevsk April 3, 2026 17:34
Add pkg/kit wrappers for pack, kitinit, and diff commands:
- kit.Pack: packs ModelKits with cwd save/restore for library safety
- kit.Init: generates Kitfiles from local dirs or HF repos, returns bytes
- kit.Diff: compares two ModelKits concurrently, returns DiffResult
- kit.CompareManifests: re-exported pure comparison function

Fix review bugs:
- Extract applyNetworkDefaults helper for consistent TLS/credential
  defaults across all remote-capable functions (Pull, Push, Login,
  Inspect, Info, List, Diff)
- Fix %w verb in output.Errorf (only valid in fmt.Errorf)

Wire CLI commands to delegate to pkg/kit, move tests accordingly.

Signed-off-by: Arnab Chatterjee <arnabchat2001@gmail.com>
Signed-off-by: Arnab Chatterjee <arnabchat2001@gmail.com>
Signed-off-by: Arnab Chatterjee <arnabchat2001@gmail.com>
@arnab2001
Copy link
Copy Markdown
Contributor Author

arnab2001 commented Apr 3, 2026

Known limitations & follow-up work

Not yet wrapped in pkg/kit

  • kitimport — git/HuggingFace import (external deps)
  • kitcache — cache management (easy)
  • version — version string (trivial)
  • dev — local LLM server (interactive/long-running, poor fit for library API — intentionally deferred)

These can be follow-up PRs without touching the current refactor, @amisevsk @gorkem let me know what do you think.

Library-layer side effects

Several pkg/kit functions call output.Infof/Debugf for progress logging (e.g., Login prints "Log in successful", Remove logs each deleted manifest). This matches the existing CLI behavior and uses the project's pkg/output logging layer, which consumers can redirect via output.SetOut() / output.SetLogLevel(). A future improvement could return structured results instead.

kit.Pack is not goroutine-safe

Pack temporarily changes the process CWD (required for correct tar relative paths) and restores it via defer. This matches the original CLI behavior but means concurrent Pack calls will race. Documented in the function's godoc.

@arnab2001
Copy link
Copy Markdown
Contributor Author

@amisevsk Let me know of your thoughts if dev, kitimport, kitcache and version should be included in this PR. also waiting for your review
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose core Kit CLI functionality as a reusable Go library

2 participants