Releases: aiperceivable/apcore-cli-typescript
Releases · aiperceivable/apcore-cli-typescript
Release 0.7.0
Added
- Canonical clap v4 / GNU-style help formatter (
src/canonical-help.ts) overriding Commander's defaultformatHelpso--helpoutput is byte-stable across SDK implementations. Disables terminal-width wrapping, uppercases<PLACEHOLDER>s, enforcesCommands:beforeOptions:, and renders-h, --help/-V, --versionlast withPrint help/Print versiondescriptions. - Cross-language conformance test harness (
tests/conformance/apcli-visibility.test.ts) now consumes the shared fixtures from theaiperceivable/apcore-clispec repo (conformance/fixtures/apcli-visibility/). Dynamically discovers scenarios and byte-matches--helpoutput against eachexpected_help.txt. SetAPCORE_CLI_SPEC_REPOto point at a non-sibling checkout; defaults to../apcore-cli/. - CI — spec-repo checkout:
.github/workflows/ci.ymlnow checks outaiperceivable/apcore-cliinto.apcore-cli-spec/and exposes it topnpm testviaAPCORE_CLI_SPEC_REPO. - FE-13: Built-in command group (
apcli) — consolidates the 13 canonical built-in commands (list,describe,exec,validate,init,health,usage,enable,disable,reload,config,completion,describe-pipeline) under a singleapclisub-group. Invocation shifts from<cli> listto<cli> apcli list. ApcliGroupclass +ApcliConfig/ApcliModetypes, exported fromsrc/index.ts.RESERVED_GROUP_NAMES = new Set(["apcli"])as the enforced collision surface (replaces the retired per-commandBUILTIN_COMMANDSconstant).- New env var
APCORE_CLI_APCLI— acceptsshow,hide,1,0,true,false(case-insensitive). - New config keys (snake_case DEFAULTS):
apcli.mode,apcli.include,apcli.exclude,apcli.disable_env. ConfigResolver.resolveObject(key)— non-leaf accessor that returns object-shaped config values without flattening.createCli({ apcli })option — acceptsboolean | object | ApcliGroupto configure the built-in group surface.- See migration guide for the full v0.7 → v0.8 timeline.
- New error-code → exit-code mappings in
src/errors.tsandsrc/main.ts:DEPENDENCY_NOT_FOUNDandDEPENDENCY_VERSION_MISMATCHboth map to exit code 44. Preserves the pre-0.19.0 exit code (MODULE_LOAD_ERROR= 44) for missing / version-mismatched module dependencies, now that apcore-js surfaces these through dedicated error types per PROTOCOL_SPEC §5.15.2. - Binding-overlay tests in
tests/display-helpers.test.ts: a tmp binding YAML is written,applyToolkitIntegrationis called, andgetDisplay()is verified to return the overlay for a descriptor that has no baked-inmetadata.display. createCli({ app })—APCoreunified client:CreateCliOptionsnow accepts anapp?: APCorefield. When provided,app.registryandapp.executorare extracted and used in place of explicitregistry/executorfields. Passingapptogether withregistryorexecutorthrows"app is mutually exclusive with registry/executor".APCoreinterface exported from package index.StrategyInfoandStrategyStepinterfaces exported from package index.Executorinterface extended with optionaldescribePipeline(strategyName?: string): StrategyInfoandstrategy?: { steps: StrategyStep[] }fields.- FE-12: Module Exposure Filtering — Declarative control over which discovered modules are exposed as CLI commands.
ExposureFilterclass inexposure.tswithisExposed(moduleId)andfilterModules(ids)methods.- Three modes:
all(default),include(whitelist),exclude(blacklist) with glob-pattern matching. ExposureFilter.fromConfig(obj)static method for loading fromapcore.yamlexposesection.CreateCliOptions.exposefield accepting object orExposureFilterinstance.list --exposure {exposed,hidden,all}filter flag in discovery commands.GroupedModuleGroupintegration: applies exposure filter during command registration.ConfigResolvergainsexpose.*config keys.- 4-tier config precedence:
CreateCliOptions.expose>--expose-modeCLI flag > env var >apcore.yaml. - Hidden modules remain invocable via
exec <module_id>. - New file:
exposure.ts.
Changed
- Built-in commands now live under the
apclisub-group. Pre-v0.7 invocations (<cli> list,<cli> describe, etc.) still work in standalone mode via deprecation shims that print aWARNINGto stderr and forward toapcli <name>. Shims are not installed in embedded mode. - Discovery flags (
--extensions-dir,--commands-dir,--binding) are now gated on standalone mode — they are only registered when noregistryis injected. - Shell-completion generators (bash/zsh/fish) enumerate registered Commander subcommands dynamically; hardcoded command lists are gone.
- Dependency bump: requires
apcore-js >= 0.19.0(was>= 0.18.0) andapcore-toolkit >= 0.5.0(was>= 0.4.0). Aligns with upstream releasesapcore-js 0.19.0(dependency graph errors, asyncbuildStrategyFromConfig, auto-schema adapter chain,BindingSchemaMissingErrorrename) andapcore-toolkit 0.5.0(BindingLoader,ScannedModule.display,apcore-toolkit/browsersubpath). - Placeholder types in
src/cli.tsrealigned with real apcore-js shapes.PipelineTrace/StepTrace/PreflightResult/StrategyStepnow use camelCase (strategyName,totalDurationMs,durationMs,skipReason,requiresApproval,timeoutMs) matching the apcore-js runtime object shape.Executor.describePipelineis typed as(): StrategyInfo(zero arguments — the previousdescribePipeline?(strategyName?: string)signature declared an argument that the real apcore-js method ignores).Executor.strategyrenamed toExecutor.currentStrategyto match the upstream getter. --traceoutput now reads the correct runtime fields.main.tspreviously readtrace.strategy_name/trace.total_duration_ms/s.duration_ms/s.skip_reason(snake_case) from the camelCasePipelineTracereturned by apcore-js, so those values surfaced asundefinedat runtime. Now readsstrategyName/totalDurationMs/durationMs/skipReasoncorrectly. JSON output keys remain snake_case to preserve the cross-language CLI output contract.formatPreflightResultnow readsresult.requiresApproval(wasresult.requires_approval). The JSON output key remainsrequires_approval.MAX_MODULE_ID_LENGTH128 → 192:validateModuleId()now enforces a 192-character limit for module IDs, up from 128, to accommodate Java/.NET deep-namespace FQN-derived IDs (PROTOCOL_SPEC §2.7 spec 1.6.0-draft).Executor.describePipeline()returnsStrategyInfo:describe-pipelinecommand instrategy.tsnow callsexecutor.describePipeline(strategyName)and consumes the returnedStrategyInfoobject (name,stepCount,stepNames,description). Pipeline header format updated toPipeline: ${info.name} (${info.stepCount} steps). Step metadata (Pure/Removable/Timeout columns) sourced fromexecutor.strategy.steps(pure: boolean,removable: boolean,timeoutMs: number). Falls back to static preset table whendescribePipelineis not available.
Deprecated
- Root-level v0.6 built-in commands continue to work in standalone mode but emit a
WARNINGand forward toapcli <name>. Scheduled for removal in v0.8.
Removed
- The per-command
BUILTIN_COMMANDSconstant and its re-export fromsrc/index.ts. Replaced byRESERVED_GROUP_NAMES. - Monolithic registrars
registerDiscoveryCommands,registerSystemCommands,registerShellCommands— replaced by per-subcommand exports invoked throughApcliGroup.
Fixed
describe-pipeline --strategy <name>now works for non-current strategies. Previously the command calledexecutor.describePipeline(strategyName)— the real apcore-js signature takes no arguments and always returns info for the executor's current strategy, so all--strategyvalues produced identical output.src/strategy.tsnow uses a two-step lookup: if the requested name matches the current strategy, usedescribePipeline(); otherwise fall back to the staticExecutor.listStrategies()(reached viaexecutor.constructor.listStrategies) to introspect other registered strategies.--binding <path>flag now actually applies display overlay.applyToolkitIntegrationpreviously instantiated aDisplayResolverand discarded it. The implementation now uses apcore-toolkit 0.5.0'sBindingLoader+DisplayResolverpipeline to parse the binding YAML, resolve the sparse overlay, and populate a module-level binding display map.display-helpers.ts#getDisplayconsults the map as a fallback when the descriptor itself has nometadata.display, socli.alias/cli.description/ tags from.binding.yamlare now honored bylist,describe, and command help output. New exports:lookupBindingDisplay(moduleId)andclearBindingDisplayMap()fromsrc/main.ts.
Breaking
- Reserved-name enforcement is now a hard exit 2 when a module's explicit group, auto-group prefix, or top-level name/alias equals
apcli. Previously this was warn-and-drop.
Release 0.6.0
Changed
- Dependency bump: requires
apcore-js >= 0.17.1(was>= 0.15.1). Adds Execution Pipeline Strategy, Config Bus enhancements, Pipeline v2 declarative step metadata,minimalstrategy preset. - Schema parser: Required schema properties now correctly enforced at Commander option level (was silently optional).
checkApproval()now acceptstimeoutparameter instead of hardcoded 60s.
Added
- FE-11: Usability Enhancements — 11 new capabilities:
--dry-runpreflight mode. Standalonevalidatecommand viaregisterValidateCommand().- System management commands:
health,usage,enable,disable,reload,config get/config setinsystem-cmd.ts. Graceful no-op when system modules unavailable. - Enhanced error output:
emitErrorJson()/emitErrorTty()with structured guidance fields. --tracepipeline visualization.CliApprovalHandlerclass implementing apcoreApprovalHandlerprotocol.--approval-timeout,--approval-tokenflags.--streamJSONL output.- Enhanced
listcommand:--search,--status,--annotation,--sort,--reverse,--deprecated,--deps,--flat. --strategyselection:standard,internal,testing,performance,minimal.describe-pipelinecommand instrategy.ts.- Output format extensions:
--format csv|yaml|jsonl,--fieldsdot-path field selection. - Multi-level grouping:
groupDepthparameter inresolveGroup(). - Custom command extension:
CreateCliOptions.extraCommandswith collision detection. Executorinterface extended with optionalvalidate(),callWithTrace(),stream(),call()methods.PreflightResult,PreflightCheck,PipelineTrace,PipelineTraceSteptypes exported.- New error code:
CONFIG_ENV_MAP_CONFLICTinEXIT_CODES. - Config defaults:
cli.approval_timeout(60),cli.strategy("standard"),cli.group_depth(1). - New files:
system-cmd.ts,strategy.ts.
Release 0.5.0
Release version 0.5.0
Release 0.4.0
Added
- Verbose help mode — Built-in apcore options (
--input,--yes,--large-input,--format,--sandbox) are now hidden from--helpoutput by default. Pass--help --verboseto display the full option list including built-in options. - Universal man page generation —
buildProgramManPage()generates a complete roff man page covering all registered commands.configureManHelp()adds--help --mansupport to any Commander program, enabling downstream projects to get man pages for free. - Documentation URL support —
setDocsUrl()sets a base URL for online docs. Per-command help showsDocs: {url}/commands/{name}, man page SEE ALSO includesFull documentation at {url}. No default — disabled when not set.
Changed
buildModuleCommand()accepts optionalverboseHelpparameter to control built-in option visibility in help.--sandboxis now always hidden from help (not yet implemented). Only four built-in options (--input,--yes,--large-input,--format) toggle with--verbose.- Improved built-in option descriptions for clarity (e.g.,
--inputnow reads "Read JSON input from a file path, or use '-' to read from stdin pipe").
Release 0.3.2
Fixed
- Handle missing
package.jsonfor version retrieval in bundled environments (e.g., Bun compile).
Release 0.3.1
Changed
- Update
tsup.config.tsentry configuration to use named entries ({ index: "src/index.ts", "bin/apcore-cli": "bin/apcore-cli.ts" }) instead of an array.
Release 0.3.0
Added
- Grouped CLI commands (FE-09) —
GroupedModuleGrouporganizes modules into nested subcommand groups by namespace prefix, enablingapcore-cli <group> <command>invocation. - Display overlay helpers —
getDisplay()andgetCliDisplayFields()resolve alias, description, and tags frommetadata["display"]. - Init command (FE-10) —
apcore-cli init module <id>scaffolds new modules with--style(decorator/convention/binding),--dir, and--descriptionoptions. - Grouped shell completions — Bash, Zsh, and Fish completions now support two-level group/command completion via
_APCORE_GRP. - Optional apcore-toolkit integration —
DisplayResolverandRegistryWritervia optionalapcore-toolkitpeer dependency with graceful fallback. - Path traversal validation —
--dirrejects paths containing..components.
Changed
BUILTIN_COMMANDSupdated to includeinit(6 items, sorted).buildModuleCommandaccepts optionalcmdNameparameter for display alias override.APCORE_EXTENSIONS_ROOTenvironment variable now used as fallback increateCli().APCORE_AUTH_API_KEYadded to man page ENVIRONMENT section.- Dependency bump:
apcore-js >= 0.14.0.
Release 0.2.1
Changed
- Help text truncation limit increased from 200 to 1000 characters (configurable via
cli.help_text_max_lengthconfig key) extractHelp: addedmaxLengthparameter (default 1000) (schema-parser.ts)schemaToCliOptions: addedmaxHelpLengthparameter (default 1000) (schema-parser.ts)buildModuleCommand: addedhelpTextMaxLengthparameter (default 1000), threaded through to schema parser (main.ts)LazyModuleGroup: constructor acceptshelpTextMaxLength(default 1000), passes tobuildModuleCommand(cli.ts)
Added
cli.help_text_max_lengthconfig key (default: 1000) inDEFAULTS(config.ts)APCORE_CLI_HELP_TEXT_MAX_LENGTHenvironment variable support- Test: "truncates help text at 1000 chars (default)"
- Test: "does not truncate text within default limit"
- Test: "truncates at custom maxLength"
- 183 tests (up from 181)
Release 0.2.0
Added
- Core dispatch pipeline:
buildModuleCommandnow fully wires schema resolution, built-in options (--input,--yes,--large-input,--format,--sandbox), input collection, approval gate, sandbox execution, audit logging, and output formatting LazyModuleGroup.getCommandnow callsbuildModuleCommandinstead of creating bare Commander commandscreateCliwired with program name resolution fromargv,--extensions-dirand--log-levelglobal options, and log level resolution fromAPCORE_CLI_LOGGING_LEVEL/APCORE_LOGGING_LEVELenv vars- Commander
.exitOverride()— custom exit code mapping viaexitCodeForErroris now active (previously dead code because Commander callsprocess.exit()internally) src/logger.ts— structured logger utility withsetLogLevel,getLogLevel,debug,info,warn,errorfunctions respectinglogging.levelconfigsetAuditLogger/getAuditLogger— module-level audit logger getter/setter (ported from Python SDK)tests/main.test.ts— 14 new tests coveringcreateCli, Commander exitOverride,buildModuleCommandaction execution, and SIGINT handlingAPCORE_CLI_LOGGING_LEVELenv var support — CLI-specific log level that takes priority overAPCORE_LOGGING_LEVEL; 3-tier precedence:--log-levelflag >APCORE_CLI_LOGGING_LEVEL>APCORE_LOGGING_LEVEL>WARNING- 181 tests total (up from 167)
Changed
schemaToCommanderOptionsrenamed toschemaToCliOptions— framework-agnostic name matching spec canonical formAuditLoggerconstructor parameter renamed fromlogPathtopath— matches spec and Python SDKConfigResolver.DEFAULTSkeys normalized to snake_case:cli.stdinBufferLimit→cli.stdin_buffer_limit,cli.autoApprove→cli.auto_approve— matches spec and Python SDKConfigResolver.DEFAULTSlogging.leveldefault changed from"INFO"to"WARNING"— matches updated specConfigEncryptor.store/ConfigEncryptor.retrievenow async — required by keytar dynamic import changeAuthProvider.getApiKey/AuthProvider.authenticateRequestnow async — propagated from ConfigEncryptor async change- Version string read from
package.jsonat runtime instead of hardcoded in 3 places readStdin()properly removes event listeners on completion/error — prevents listener accumulation- Removed duplicate
resolveFormatre-export frommain.ts(index.ts already exports from output.ts)
Fixed
- Commander exit code mapping was dead code:
program.parse()callsprocess.exit()internally; added.exitOverride()so errors throwCommanderErrorand the catch block inmain()can applyexitCodeForErrormapping LazyModuleGroup.getCommandbypassedbuildModuleCommand: was creating barenew Command(cmdName)instead of building a fully wired command with schema options and execution callbackrequire('keytar')in ESM module: replaced with dynamicawait import('keytar')via cached helper; keytar is an optional peer dependency (archived/deprecated)- README
--stdin jsonflag: corrected to--input - - README missing Features and API Overview sections: added comprehensive sections
Security
AuditLogger._hashInput: usescrypto.randomBytes(16)per-invocation salt before SHA-256 hashing, preventing cross-invocation input correlation- Added security comment on AES key derivation fallback (best-effort when OS keyring unavailable — key derived from hostname + username)