Path: @/src
- Contains all source modules for the CLI: entry point, argument parsing, error formatting, pagination merging, fuzzy method suggestion, the known-methods catalog, and the method metadata registry
- Compiles from
src/todist/via TypeScript (ES2022 target, Node16 module resolution)
- index.ts is the CLI entry point (shebang
#!/usr/bin/env node), compiled todist/index.jsand exposed as thenori-slackbinary via thebinfield in ../package.json. The compileddist/directory is produced at pack time by thepreparescript and shipped to the npm registry via thefilesallowlist -- see ../docs.md for the full packaging chain - parse-args.ts, errors.ts, and paginate.ts are pure utility modules with no side effects -- they are independently testable and tested in @/test
- methods.ts is a static data file; it is only used by the
list-methodssubcommand and has no effect on which methods the CLI can actually call
Entry point (index.ts)
- Sets up Commander with three subcommands:
list-methods,describe, and the default dynamic method handler - The dynamic handler: optionally reads JSON from stdin, parses CLI flags, merges params (CLI flags win over stdin), then branches into three paths:
--dry-run: short-circuits immediately after param resolution -- outputs a JSON preview withok,dry_run,method,params,token_present,paginate, and optionally awarningfor unknown methods. Does not require a token. Always exits 0.--paginate: validates token, then callsclient.paginate()+mergePages()- Default: validates token, then calls
client.apiCall()
- When no arguments are provided (
process.argv.length <= 2), help text and error go to stderr and the process exits with code 2 - The
list-methodssubcommand supports two options that compose together:--namespace <ns>filters the method list to those starting with the given prefix (e.g.,chat.), and--descriptionschanges the output shape fromstring[]toArray<{ method, description }>by pulling descriptions fromgetMethodMetadata(). When--namespaceis provided, anamespacefield is added to the response JSON.
Pagination merging (paginate.ts)
mergePages(pages)takes anAsyncIterableof page objects and returns a single merged object- Array-valued keys are concatenated across pages; scalar/metadata keys (
ok,response_metadata,headers,warning) are overwritten with the last page's value - This design means the function works generically with any Slack method's response shape -- it does not need to know which key holds the data (e.g.,
channels,members,messages)
Argument parsing (parse-args.ts)
parseArgs(argv)walks the args array linearly, handling three patterns:--key value,--key=value, and standalone--flag(boolean true)kebabToSnakeconverts all flag names from CLI convention to Slack API conventioncoerceValueapplies type inference:"true"/"false"become booleans, numeric strings become numbers (except those with leading zeros), and strings starting with[or{are attempted as JSON parse
Error formatting (errors.ts)
formatError(error, sourceDir)returns aCliErrorobject with fields:ok,error,message,suggestion,source- Handles four specific
@slack/web-apierror codes:slack_webapi_platform_error,slack_webapi_rate_limited_error,slack_webapi_request_error, and the customno_token - The
SUGGESTIONSmap provides agent-friendly remediation text for common Slack platform errors likechannel_not_found,not_in_channel,invalid_auth,rate_limited, etc.
Fuzzy method suggestion (suggest.ts)
findSimilarMethods(input, methods?, maxResults?)returns up to 3 similar method names fromKNOWN_METHODSfor typo correction- Three-tier matching: exact match returns
[](no suggestions needed), case-insensitive exact match returns the correctly-cased method as a fast path, then Levenshtein distance ranking with a dynamic threshold ofmax(3, floor(input.length * 0.4)) - Levenshtein comparison is case-insensitive (both sides lowercased) to maximize match quality
- Used in
index.tsat two integration points: the--dry-runpath addssuggestionsarray and enrichedwarningto the JSON output, and the pre-API-call path emits a stderr warning with "Did you mean: X?"
Methods catalog (methods.ts)
KNOWN_METHODSis a static string array of Slack Web API methods available to bot tokens- Serves as a discoverability aid only; the comment in the file explicitly notes the CLI is not limited to these methods
Method metadata (method-metadata.ts)
METHOD_METADATAis a staticRecord<string, MethodMetadata>map providing parameter documentation for every method inKNOWN_METHODS- Each entry includes:
description,required_params,optional_params(bothRecord<string, string>mapping param name to human-readable description),supports_pagination(boolean), optionaldeprecatednotice, anddocs_url getMethodMetadata(method)looks up the map and returns the entry if present; for unknown methods, it returns a fallback with empty params and a generated docs URL- The
docsUrl()helper constructs URLs in the formhttps://api.slack.com/methods/{method} - The
describecommand in index.ts wrapsgetMethodMetadataoutput withok,method, andknownfields (whereknownistrueonly when the method has a curated entry inMETHOD_METADATA)
--json-input,--paginate, and--dry-runare consumed by Commander as known options; all other flags pass through viaallowUnknownOption()and are parsed byparseArgsfromprocess.argv- The raw args filter explicitly strips
--json-input,--paginate, and--dry-runbefore passing toparseArgs, preventing them from being sent as Slack API parameters - When both stdin JSON and CLI flags provide the same key, the CLI flag value wins due to spread order:
{ ...stdinParams, ...cliParams } - Non-flag arguments (tokens not starting with
--) are silently skipped byparseArgs-- they do not cause errors - Rate limit errors extract
retryAfterfrom the@slack/web-apierror object and include the retry duration in the message
Created and maintained by Nori.