Skip to content

Add AI-agent help text to application commands#81

Open
ehl-jf wants to merge 4 commits into
jfrog:mainfrom
ehl-jf:JGC-473-ai-context-help
Open

Add AI-agent help text to application commands#81
ehl-jf wants to merge 4 commits into
jfrog:mainfrom
ehl-jf:JGC-473-ai-context-help

Conversation

@ehl-jf
Copy link
Copy Markdown
Contributor

@ehl-jf ehl-jf commented May 21, 2026

Summary

Adds AI-agent-oriented help text (AIDescription) so commands render richer help when JFROG_CLI_AI_HELP is truthy or an AI agent is auto-detected. Empty AIDescription falls back to Description; human-mode output is unchanged.

Scope: 13 components.Command literals across apptrust/commands/* + 1 namespace in cli/cli.go.

Dependency on jfrog-cli-core

jfrog-cli-core's JGC-473 PR (#1563) has MERGED. This PR's go.mod now requires the merged core master pseudo-version v2.60.1-0.20260601130310-8d52a530da18 directly — no temporary replace directive. Ready to merge on its own.

Linked

Populate components.Command.AIDescription on commands. The new field
(added in jfrog-cli-core JGC-473) makes the conversion layer render
agent-oriented text when JFROG_CLI_AI_HELP is truthy or an AI agent is
auto-detected. Empty AIDescription falls back to Description, so
command output is unchanged in human mode.

Scope: 13 components.Command literals across apptrust/commands/{system,version,package,application}/ + 1 namespace in cli/cli.go.

TEMPORARY go.mod pin: the require for github.com/jfrog/jfrog-cli-core/v2
points at JGC-473-devbase (commit d507b5c6) - a coordination branch
that cherry-picks JGC-473 onto core's pinned commit 908527b4 (the last
commit before core master removed yarn.IsVersionSupported and
IsInstalledYarnVersionSupported, which downstream callers in
jfrog-cli-artifactory still depend on). This require MUST be updated to
the merged master commit's pseudo-version after the jfrog-cli-core
JGC-473 PR merges. Do not merge this PR until the require is re-pinned.
@ehl-jf ehl-jf force-pushed the JGC-473-ai-context-help branch from 5ae7420 to 2b10f4d Compare June 1, 2026 13:06
@ehl-jf ehl-jf changed the title JGC-473 - Add AI-agent help text to application commands Add AI-agent help text to application commands Jun 1, 2026
Run gofumpt across apptrust/ and cli/ to fix struct-field alignment in the
new AIDescription literals.

Note: the repo's Static-Check also fails independently of this change because
golangci-lint-action@v6 installs golangci-lint v1.64.8 (built with go1.24),
which cannot load a go.mod targeting go 1.25.5. That CI-infra mismatch
predates this PR and needs a separate fix (bump the action to v9 + migrate
.golangci.yml to v2 format, as already done in jfrog-cli-platform-services).
@ehl-jf ehl-jf force-pushed the JGC-473-ai-context-help branch from 1677d56 to 384beb1 Compare June 1, 2026 14:24
@shayshim
Copy link
Copy Markdown
Collaborator

shayshim commented Jun 4, 2026

Bug: --overwrite-strategy=fail is not a valid value

Two AIDescription examples reference --overwrite-strategy=fail, which the CLI will reject at runtime:

  • promote_app_version_cmd.go: ... PROD --overwrite-strategy=fail --dry-run
  • release_app_version_cmd.go: ... 1.0.0 --overwrite-strategy=fail

The only valid values, as defined in apptrust/model/promote_app_version_request.go and enforced by ParseOverwriteStrategyValidateEnumFlag at runtime, are:

disabled   – skip conflicting artifacts
latest     – overwrite only if the source is newer
all        – overwrite unconditionally

An AI agent following these examples would generate a command that immediately errors out. Suggest replacing fail with disabled (the most conservative choice) in both examples.

@shayshim
Copy link
Copy Markdown
Collaborator

shayshim commented Jun 4, 2026

Style / Accuracy notes (non-blocking but worth fixing before merge)

An AI agent treats AIDescription as ground truth, so inaccurate claims get amplified into confidently-wrong advice.


1. version-create — SemVer claim is not enforced by the CLI

Gotcha: The version argument must be a valid SemVer string.

The CLI does not validate SemVer at parse time — validateCreateAppVersionContext only checks argument count and source flags. The argument description says "in SemVer format" as guidance, but nothing rejects 2024.1, v1, or other non-SemVer strings. An AI following this gotcha would refuse to generate commands with perfectly legal version strings.

Suggest: change to "The version should follow SemVer convention (e.g. 1.0.0, 1.2.3-rc1); the CLI does not validate the format but the platform may reject non-conforming values."


2. version-delete — misleading rollback suggestion

Gotcha: Deletion is irreversible; consider version-rollback first if you only want to undo a promotion.

This is confusing because rollback undoes artifact placement from a stage — it is not an alternative to deletion. A reader (human or AI) could interpret this as "rollback is a softer version of delete", which is wrong. Rollback and delete are orthogonal operations.

Suggest: "Deletion is irreversible and removes the version record itself. To undo a promotion without deleting the version, use version-rollback instead."


3. version-update — properties format not explained in Gotchas

The example uses:

--properties="env=prod;owner=team-a,team-b"

The code (ParseListPropertiesFlag) confirms: semicolons separate key-value pairs, commas separate multiple values for the same key. This dual-separator format is non-obvious and easy to get wrong, but the Gotchas section doesn't mention it.

Suggest adding: "--properties uses semicolons to separate key=value pairs and commas to separate multiple values for a single key: key1=v1,v2;key2=v3."


4. app-update — owner replacement behavior should be verified

Gotcha: --user-owners and --group-owners replace the full owner list each time they are specified.

The update command code doesn't appear to contain any owner-related logic (no UserOwner/GroupOwner field handling visible in the command file). Please confirm this replace-vs-merge behavior is actually implemented and that the claim is accurate — if it's wrong, it's a high-impact footgun for an AI agent.

Addresses review from @shayshim:
- promote/release: fix invalid --overwrite-strategy=fail example -> =disabled
  (valid values are disabled/latest/all per model.OverwriteStrategyValues).
- version-create: soften the SemVer gotcha; the CLI does not validate the
  format at parse time (validateCreateAppVersionContext only checks arg count
  and source flags).
- version-delete: clarify that version-rollback is a separate, orthogonal
  operation (undo a promotion), not a softer form of delete.
- version-update: document the --properties dual separator (';' between
  key=value pairs, ',' between multiple values for one key) per
  ParseListPropertiesFlag.
- app-update: describe what the CLI actually sends for --user-owners /
  --group-owners (the full provided list; no incremental add/remove-owner
  flags) instead of asserting server-side replace semantics.
@ehl-jf
Copy link
Copy Markdown
Contributor Author

ehl-jf commented Jun 4, 2026

Thanks @shayshim — really valuable review, especially the point about agents treating AIDescription as ground truth. Applied all of it in baaffa1:

Bug — --overwrite-strategy=fail: fixed in both promote_app_version_cmd.go and release_app_version_cmd.go--overwrite-strategy=disabled. Confirmed against model.OverwriteStrategyValues (disabled/latest/all) — fail would indeed error at runtime.

1. version-create SemVer: agreed — validateCreateAppVersionContext only checks arg count + source flags, no SemVer validation. Reworded to: "The version should follow SemVer convention (e.g. 1.0.0, 1.2.3-rc1); the CLI does not validate the format, but the platform may reject non-conforming values."

2. version-delete rollback: agreed it conflated two orthogonal operations. Reworded to make clear rollback undoes a promotion and is not a softer delete.

3. version-update properties: good catch — confirmed ParseListPropertiesFlag splits ; for pairs and , for values. Added a gotcha spelling out the dual separator (key1=v1,v2;key2=v3).

4. app-update owners: one clarification — the --user-owners/--group-owners flags are wired for app-update (they're in the AppUpdate flag set in flags.go and handled via populateApplicationFromFlagsAppDescriptor.UserOwners/GroupOwners), so the command does accept them. But your underlying point is fair: the old gotcha asserted server-side replace semantics the CLI can't guarantee. Reworded to describe what the CLI actually sends (the full list you provide; no incremental add/remove-owner flags, unlike labels).

Tests pass and gofumpt is clean.

@shayshim
Copy link
Copy Markdown
Collaborator

shayshim commented Jun 4, 2026

Bug: --delete-properties example and gotcha use the wrong separator

In version-update's AIDescription:

Example: --delete-properties="env,owner"
Gotcha: "--delete-properties takes a comma-separated list of keys and removes those keys entirely."

Both are wrong. The flag is parsed by utils.ParseSliceFlag, which splits on semicolon, not comma:

// utils.go
func ParseSliceFlag(flagValue string) []string {
    ...
    values := strings.Split(flagValue, ";")  // semicolon
    ...
}

(Note: the function's own doc comment says "comma-separated" — that's also a pre-existing bug in the comment.)

With --delete-properties="env,owner", ParseSliceFlag returns a single key "env,owner" — it never deletes env and owner separately. The correct invocation is:

--delete-properties="env;owner"

Fix needed in update_app_version_cmd.go:

  • Example: --delete-properties="env;owner"
  • Gotcha: change "comma-separated" → "semicolon-separated"

And separately, the doc comment on ParseSliceFlag in utils.go should be corrected from "comma-separated" to "semicolon-separated".

Addresses review from @shayshim:
- version-update AIDescription: --delete-properties is parsed by
  utils.ParseSliceFlag, which splits on ';' (not ','). Fixed the example
  ("env,owner" -> "env;owner") and the gotcha ("comma-separated" ->
  "semicolon-separated"); a comma-joined value was treated as one literal key.
- Corrected the pre-existing inaccurate doc comment on ParseSliceFlag in
  utils.go ("comma-separated" -> "semicolon-separated").
@ehl-jf
Copy link
Copy Markdown
Contributor Author

ehl-jf commented Jun 5, 2026

Fixed in d6e5fba. Confirmed --delete-properties is parsed by ParseSliceFlag, which splits on ;, so "env,owner" was being treated as a single literal key. Updated the example to "env;owner" and the gotcha to "semicolon-separated", and corrected the stale "comma-separated" doc comment on ParseSliceFlag itself while I was there.

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.

2 participants