Repository navigation
Conversation
Unknown-command telemetry only said "unknown command", so we could not tell an agent typing a Wrangler habit apart from a real leaf given an extra positional (for example `cf zones get <id>`). Some failures were not reported at all: several unknown words, root-level typos with a suggestion, and flag-only invocations. `.fail` now captures where resolution stopped while yargs still holds that level's context, and the parse-error reporter adds resolutionFailure, knownCommand, knownCommandIsLeaf, unknownTokens (at most three), unknownTokenCount, suggestedCommand and unknownFlagCount. A token is sent only when it is a word from cf's command catalogue; anything else becomes a shape label such as <hex>, <domain> or <path>, so IDs and resource names never leave the machine. Flag names are kept only when they are cf options. The `command` value is unchanged for continuity, except that the plural "Unknown commands:" message is now treated like the singular one. The catalogue is loaded lazily on this error path, and only when telemetry is enabled.
Restore the existing command values so dashboards stay continuous: only yargs' singular "Unknown command:" message, or a failure at the top level, reports command "unknown command". Plural and in-group typo failures keep the group or leaf name and carry the new resolution fields instead. Near-miss typos of cli telemetry are now resolved to the intended command before the telemetry exclusion check, so they are not reported. Surplus positionals after a complete command are always sent as a shape label, never as a matching catalogue word, because they are almost always user values.
commit: |
|
| mean | stddev | min | max | |
|---|---|---|---|---|
| PR | 168.1 ms | 3.0 ms | 164.1 ms | 177.3 ms |
| base | 170.5 ms | 2.6 ms | 164.6 ms | 174.5 ms |
Δ (PR vs base): ↓ -2.4 ms (-1.4%)
Measured with hyperfine on ubuntu-latest (3 warmup runs, 20 timed runs). CI numbers carry ±a few ms of runner jitter; treat small deltas as noise.
|
💬 Approved with comments — The unknown-command telemetry is well scoped: it sends only cf catalogue words or shape labels, never flag values, and it is skipped when telemetry is disabled. The only finding is a WARNING with no runtime impact: the docs say unrecognised flags are counted, but unknown short flags are not. Findings: 1 warning The decision is advisory: this comment never approves, blocks or requests changes on the pull request. 🔧 Fix with your agentPaste the following into your coding agent to investigate and fix these issues. 📝 Documentation:
|
| // Surplus positionals at a leaf are almost always resource values, so a | ||
| // value that happens to be a cf word (`test`, `cache`) is still labelled. | ||
| const commandWords = | ||
| failure.kind === "surplus-positional" | ||
| ? new Set<string>() | ||
| : vocabulary.commands; | ||
| const suggestedCommand = | ||
| failure.kind === "suggested-command" ? failure.suggestedCommand : undefined; | ||
|
|
||
| return { | ||
| resolutionFailure: failure.kind, | ||
| knownCommand: failure.knownCommand.join(" "), | ||
| knownCommandIsLeaf: failure.knownCommandIsLeaf, | ||
| unknownTokens: failure.unknownTokens | ||
| .slice(0, MAX_UNKNOWN_TOKENS) | ||
| .map((token) => sanitizeCommandToken(token, commandWords)), |
There was a problem hiding this comment.
When resolution stops at a group, every remaining positional is passed through the global command-word allowlist. For example, cf workers deploy zones records both deploy and zones; after the unknown deploy, zones can be a positional/resource value for the intended command rather than a command slot. This contradicts the updated policy that positional values are never collected. Only the first unresolved token is known to be in a command position; force later tokens to shape labels.
| // Surplus positionals at a leaf are almost always resource values, so a | |
| // value that happens to be a cf word (`test`, `cache`) is still labelled. | |
| const commandWords = | |
| failure.kind === "surplus-positional" | |
| ? new Set<string>() | |
| : vocabulary.commands; | |
| const suggestedCommand = | |
| failure.kind === "suggested-command" ? failure.suggestedCommand : undefined; | |
| return { | |
| resolutionFailure: failure.kind, | |
| knownCommand: failure.knownCommand.join(" "), | |
| knownCommandIsLeaf: failure.knownCommandIsLeaf, | |
| unknownTokens: failure.unknownTokens | |
| .slice(0, MAX_UNKNOWN_TOKENS) | |
| .map((token) => sanitizeCommandToken(token, commandWords)), | |
| unknownTokens: failure.unknownTokens | |
| .slice(0, MAX_UNKNOWN_TOKENS) | |
| .map((token, index) => | |
| sanitizeCommandToken( | |
| token, | |
| index === 0 ? commandWords : new Set<string>() | |
| ) | |
| ), |
| ): SanitizedCommandResolution { | ||
| const known = new Set<string>(); | ||
| const unknown = new Set<string>(); | ||
| for (const flag of passedFlags(rawArgv)) { |
There was a problem hiding this comment.
passedFlags() defaults to only the global aliases, but this new path never supplies aliases from the resolved command. Valid command-specific short options are therefore neither named nor counted. For instance, cf smart-shield health-checks delete id extra -f reaches this surplus-positional path, although the generated command registers -f for force; this event reports argsUsed: [] and unknownFlagCount: 0. Build a short-alias map from the command metadata (plus the global aliases) while loading the vocabulary and pass it here.
| for (const flag of passedFlags(rawArgv)) { | |
| for (const flag of passedFlags(rawArgv, vocabulary.shortFlagAliases)) { |
|
🤖 I've done a thorough review of your PR. Adds sanitized telemetry context for command-resolution failures. Posted 2 actionable inline findings. |
Unknown-command telemetry only reported
command: "unknown command"with empty args, so we could not see what was attempted. That bucket also mixed unrelated failures: the most common case is a real leaf given an extra positional (cf zones get <id>,cf dns records list example.com), because yargs' strict-commands check runs at leaf level too. Several failures were not reported at all: multiple unknown words at the root, root-level typos with a "Did you mean" suggestion, and flag-only invocations such ascf --bogus..failnow captures where resolution stopped while yargs still holds that level's context, and the parse-error reporter adds:resolutionFailure:unknown-subcommand | surplus-positional | suggested-command | missing-commandknownCommandandknownCommandIsLeafunknownTokens(at most three) andunknownTokenCountsuggestedCommandunknownFlagCount, with known cf flag names inargsUsedA token is sent only when it is a word from cf's command catalogue and sits where a command name was expected. Everything else, including any surplus positional after a complete command, becomes a shape label (
<hex>,<uuid>,<domain>,<path>,<email>,<word>…), so IDs and resource names are not sent. Flag values are never sent.Existing
commandvalues are kept for dashboard continuity: in-group typos and plural "Unknown commands:" failures still report the group or leaf name, now with the extra fields. Near-miss typos ofcli telemetryare resolved before the exclusion check, so they stay unreported.The catalogue is loaded lazily on this error path only, and not at all when telemetry is disabled.
telemetry.mdis updated.Example (
cf zones get 023e…353 --zone-id abc):{"command":"unknown command","resolutionFailure":"surplus-positional","knownCommand":"zones get","knownCommandIsLeaf":true,"unknownTokens":["<hex>"],"unknownTokenCount":1,"unknownFlagCount":0,"argsUsed":["zone-id"]}Expect a small rise in
unknown commandvolume from the root-level cases that were previously dropped.Validation:
pnpm checkpnpm test src/__tests__/telemetry-errors.test.ts src/__tests__/lib/telemetry/command-resolution.test.tsbin/cfrun withDEBUG=1and no Sparrow key against adversarial argv (IDs, domains, paths, emails,--flag=value, tokens after--)