- For full operational steps, read [docs/hermes-agent.md](docs/hermes-agent.md).
Resources
12Install
npx skillscat add bbggkkk/finance-cli Install via the SkillsCat registry.
SKILL.md
fin-cli AI Agent Specification and Guide
This document provides guidelines for AI agents to interact with the fin-cli tool for broker interaction.
🛠️ Auto-generated Command Documentation
Click on the links below to view the detailed commands and flag schemas for each CLI command category:
- INIT Command Group Specification
- LOGIN Command Group Specification
- MARKET Command Group Specification
- ORDER Command Group Specification
- STATUS Command Group Specification
- MAINTENANCE Command Group Specification
- Hermes Agent Monitoring Hook Guide
💡 AI Agent Execution Rules
AI Output Mode:
- Always append the
--aiflag at the end of your command when programmatic JSON output is needed. - Example:
./fin-cli status --ai - Start by running
fin-cli capabilities --aito discover the active adapter command schema, safety rules, stable error codes, monitor condition types, condition flags/test inputs, event evaluation reasons, diagnostic recommended-action fields, hook defaults, and local audit paths. - When an AI command exits non-zero, parse the JSON
errorobject instead of scraping text. Checkcapabilities --aiai.errorCategories,ai.errorCodes, andai.errorPolicies, then inspecterror.category,error.code,error.retryable,error.requiresUserInput, anderror.command; validation/auth/permission errors usually need corrected input or user action, network errors can be retried intentionally, andintegrity_check_failedmeans release asset checksums or SHA256SUMS metadata failed verification and should not be retried blindly. - Use each capability command's
mutates,requiresAuth,liveOrder, andinternalfields to decide whether the user must explicitly approve the action before execution. - Group/help-style commands such as
status,monitor,monitor event, andmonitor hookare local metadata commands in capabilities; use subcommand metadata for concrete broker or filesystem effects. - Use
fin-cli doctor --aifirst when diagnosing install, plugin, SKILL, session, monitor, event, or hook state. - Check
doctor --aimonitor.readiness.readybefore long-running monitoring. If it isfalse, resolve eachblockersid before starting or trusting the daemon. Ifmonitor.events.runnableis0or blockers includeno-runnable-monitor-events, inspect active events for futurestartsAt, expired definitions, or exhausted repeat alerts before expecting hook delivery. - Use
capabilities --aimonitor.daemonControlas the source of truth for monitor daemon start/stop/restart/status commands and result fields. A stale status must matchmonitor.daemonControl.staleStatusbefore treating it as a restartable crashed daemon. - Check
doctor --aipluginpath,sourcePath,sha256,version, andversionMatchesCLIfields before trusting a locally installed or loaded plugin. - Check
doctor --aioperationalLogsbefore long-running automation; usecapabilities --aiai.diagnosticOperationalLogFieldsandai.maintenancePruneResultFieldsas the parsing contract. IfrecommendedActionsincludesprune-operational-logs, run its dry-run command orfin-cli doctor repair --action prune-operational-logs --dry-run=true --aiand review counts before applying with--dry-run=false --confirm=true. - Check
fin-cli monitor status --aiordoctor --aimonitor.daemonStatus; if it isstale, the recorded daemon PID is not alive. Verify broker auth, run the readiness blocker action'sdryRunCommand(fin-cli monitor status --ai) to recheck state, then runfin-cli monitor restart --aiwhenrecommendedActionsincludesrestart-stale-monitor-daemon. - If
doctor --aireports active monitor events while the daemon isstopped, run the readiness blocker action'sdryRunCommand(fin-cli monitor status --ai) to confirm it is still stopped, then runfin-cli monitor start --aiwhenrecommendedActionsincludesstart-monitor-daemon. fin-cli monitor stop --aiis a local daemon-control command and does not require broker token validation; use it to stop a runaway or stale local daemon even when broker auth is broken.- Check
doctor --aimonitor.events.expired; ifrecommendedActionsincludesreview-expired-monitor-events, run its command and decide whether to update, pause, or remove stale alerts. - Check
doctor --aimonitor.events.exhausted; ifrecommendedActionsincludesreview-exhausted-monitor-events, run its list command and decide whether to remove, reset withmonitor event update --id <event-id> --reset-trigger-count=true --reset-observed-state=true --ai, or recreate completed repeat alerts. - Check
doctor --aimonitor.hook.failedEntries,retryableFailedEntries,latestFailedDeliveryId, andlatestRetryableFailedDeliveryId; ifrecommendedActionsincludesreplay-failed-monitor-hook, run its dry-run command and review the selected delivery before choosing a safefollowUpCommandsentry such as applying the latest failed replay, inspecting failed history, previewing retryable failures, or previewing a filtered batch. - Check
doctor --aimonitor.hook.failedAuditEntries; ifrecommendedActionsincludesreview-failed-monitor-hook-lifecycle, runfin-cli monitor hook audit --status failed --limit 20 --aiand inspect the sanitized lifecycle failures before retrying registration or removal. - Check
doctor --aimonitor.hook.secretConfigured; if webhook mode has a URL but no secret andrecommendedActionsincludesrepair-monitor-hook-secret, re-register withfin-cli monitor hook registerinstead of manually editing the hook file. - If
doctor --aireports the hook as not configured after a local hook-file edit or migration, treat the persisted hook file as unusable and re-register withmonitor hook register; do not hand-editevent_hook.json. - The CLI loads bundled/source plugins and the configured global plugin directory; it must not trust a
plugins/directory from the current working directory. - Prefer
doctor --airecommendedActionswhen choosing a repair command; entries includemutates,requiresAuth,requiresUserInput,dryRunCommand,applyCommand,applyRequiresConfirm, andfollowUpCommands. RundryRunCommandfirst when present, and for mutating follow-up commands run theirdryRunCommandbeforecommandunless the follow-up is explicitly read-only. - Use
capabilities --aiai.diagnosticRepairActionsto identify whichdoctor --airecommendations can be handled byfin-cli doctor repairwithout user-provided values. - For safe no-input repairs, preview
fin-cli doctor repair --dry-run=true --ai; apply only withfin-cli doctor repair --dry-run=false --confirm=true --aiafter reviewing planned actions. Checkcapabilities --aiai.diagnosticRepairResultFields,ai.diagnosticRepairActionResultFields, andai.diagnosticRepairEffectFieldsbefore automating repair result parsing. Repair dry-runs return structuredoutput.effectsfields and target paths, with mutation booleans set tofalse. - If
doctor --aireports missing, drifted, or version-mismatched SKILL assets, inspect each skill target'smissingDocs,referenceMatchesDoc, and fingerprint fields, then runfin-cli doctor repair --action repair-ai-skill --dry-run=true --aiorfin-cli skill install --dry-run=true --aibefore applyingfin-cli skill install --aito reinstall the current release's SKILL and VERSION metadata into Codex and Hermes skill directories. Checkcapabilities --aiai.diagnosticSkillFields,ai.skillInstallTargets,ai.skillInstallCommandFields,ai.skillInstallResultFields, andai.skillInstallEffectFieldsbefore automating this flow. In AI mode, each install result includes a stabletargetvalue (codexorhermes), concretepath, requestedversion, doc/reference counts,installedVersion,versionMatchesRequested, and SHA-256 fingerprints (skillSha256,docsSha256,referenceSha256,bundleSha256). Top-leveleffectsdistinguishes dry-run (downloadsSkillAssets: "none",mutatesLocalSkillFiles: false) from apply. - When installing or repairing a broker plugin directly, use
fin-cli plugin install kis --version vX.Y.Z --aiand verifystatus,pluginName,version,assetName,path,sha256,checksumVerified,effects, and captured installermessages. Checkcapabilities --aiai.pluginInstallResultFieldsandai.pluginInstallEffectFieldsbefore automating this flow; plugin install should reporteffects.downloadsPluginAssets: "release-assets"andeffects.mutatesLocalPluginFiles: trueafter a successful apply. - Use
fin-cli upgrade --version vX.Y.Z --aiwhen the user needs a reproducible pinned CLI/SKILL/plugin version instead of the latest release; installed plugins are refreshed from the same pinned release tag. In AI mode, stdout is JSON and includesstatus,requestedVersion,targetVersion,currentVersion,developmentMode,binaryUpdated,binaryInstall,skillInstallResults,corePluginsUpdated,installedPluginsAutoUpgradeAttempted,effects, and captured installermessages. Checkcapabilities --aiai.upgradeResultFieldsandai.upgradeEffectFields; verifybinaryInstall.status,path,assetName,sha256, andchecksumVerifiedwhenbinaryUpdated: true, and useeffects.mutatesBinary,effects.mutatesSkills, andeffects.mutatesPluginsas the top-level mutation summary. - Before applying the shell installer on a host, use
capabilities --aiai.installerDryRunTemplate,installerDryRunResultFields, andinstallerDryRunEffectFieldsas the contract, then preview withinstall.sh --version vX.Y.Z --dry-run --ai; requiredryRun: true,wouldWrite: false,wouldDownload: false, and alleffects.*mutation booleans to befalsebefore treating the plan as non-mutating. Use a pinned--versionwhen the dry-run must avoid the latest-release network lookup.
- Always append the
Session Persistence:
- Running
initandloginpersists session data inside.config/fin-cli/adapter_state.json. - Check if you are authenticated using
statusbefore making trading queries. - Core JSON state files are written atomically; monitor event mutations use a lock file; audit logs are append-only JSONL files.
- For long-running agents, preview local log retention with
fin-cli maintenance prune --target all --keep 10000 --older-than-days 90 --dry-run=true --ai; apply only with--dry-run=false --confirm=trueafter reviewing the counts.
- Running
Avoid Interactive Prompts:
- Provide all required flags to prevent the CLI from asking for standard input.
Order Safety:
- Always preview orders with
--dry-run=true --aibefore sending. - Use
capabilities --aiorder.buyDryRunTemplate,sellDryRunTemplate,cancelDryRunTemplate,modifyDryRunTemplate,inputValidation,liveApplyTemplateSuffix, andauditTemplateas the source of truth for AI order command composition. - Validate order details against
order.inputValidationbefore composing commands; fin-cli also rejects invalid symbols, order numbers, non-positive quantities, unsupported order types, and non-positive limit prices before broker submission. - When applying a live order, fill
order.liveApplyTemplateSuffix<audit_id>with the dry-run responseaudit_id; fin-cli validates the preview audit status, action, environment, transaction id, and request body before contacting the broker. - Live order, cancel, and modify commands are blocked unless
--confirm=trueis provided. - Do not add
--confirm=trueunless the user explicitly requested the live broker action and all order details are present. - Use returned
audit_idvalues to connect order previews and submissions tofin-cli order audit --id <audit_id> --ai; checksummary.statusCounts,summary.latestPreviewAuditId,summary.latestSubmittedAuditId, andlogIntegrity.malformedLines; narrow broader investigations with--status preview|blocked|submitted|failed,--action buy|sell|cancel|modify, and--symbol <code>.
- Always preview orders with
Monitoring Event Hooks:
- Use
fin-cli monitor hook registeras the standard setup path. Do not hardcode Hermes webhook URLs or secrets. - Use
capabilities --aimonitor.hookRegistration.registerDryRunTemplate,registerApplyTemplate,removeDryRunTemplate,testTemplate, andlistTemplateas the source of truth for hook lifecycle commands. Fill only placeholders such as<discord-channel-id>and<symbol>. - Default profile:
hermes-helper; default route:fin-cli-monitor; event type:alert_triggered. - Preview registration with
fin-cli monitor hook register --dry-run=true --profile hermes-helper --route fin-cli-monitor --events alert_triggered --deliver discord --deliver-chat-id "<discord-channel-id>" --aibefore creating the Hermes subscription. - For
--deliver discord, always provide--deliver-chat-id; dry-run validates this locally before invoking Hermes. Route and event names are also validated locally, so treat validation errors as input bugs to fix before retrying. - In hook register/remove dry-run output, check
dryRun,wouldWrite,subscription.effects.hermesSubscription,subscription.effects.localHookConfig,subscription.effects.mutatesHermes, andsubscription.effects.mutatesLocalConfig; dry-run must reportdryRun: true,wouldWrite: false, and both mutation booleans asfalse. - Register and connect a Hermes webhook with
fin-cli monitor hook register --profile hermes-helper --route fin-cli-monitor --events alert_triggered --deliver discord --deliver-chat-id "<discord-channel-id>" --timeout-ms 5000 --retries 2 --retry-delay-ms 500 --ai; fin-cli accepts Hermes text or JSON subscription output. VerifydryRun: false,wouldWrite: true, and the returned sanitizedsubscription/hookobjects instead of reading or storing the raw webhook URL/secret. - Preview low-level local hook config changes with
fin-cli monitor hook set --url "<webhook-url>" --secret "<secret>" --dry-run=true --aiorfin-cli monitor hook clear --dry-run=true --ai; dry-run must not write or delete local hook config. Webhook URLs must be validhttp://orhttps://URLs. - Validate delivery with
fin-cli monitor hook test --ai. Checkcapabilities --aimonitor.hookTest.resultFields,hookResultFields, andeffectFields; hook test sends a synthetic alert and appends delivery history, so expectdryRun: false,wouldWrite: true, and inspecthook_result.failureCategory/hook_result.retryableon failure before retrying or repairing configuration. - Applied hook configuration changes return
audit_idvalues. Usefin-cli monitor hook audit --id <audit_id> --aifor exact hook lifecycle trace lookup, orfin-cli monitor hook audit --action register --status applied --profile hermes-helper --route fin-cli-monitor --aifor broader investigations. Checksummary.actionCounts,summary.statusCounts,summary.latestFailedAuditId, andlogIntegrity.malformedLines. If hook registration/removal fails, inspectfin-cli monitor hook audit --status failed --ai; failed audit records must remain sanitized and must not expose raw webhook URLs or secrets. - Inspect the active hook with
fin-cli monitor hook show --aibefore testing or replaying delivery. Checkconfigured,source(env:webhook,env:command,file, ornone),envOverride,fileExists,disabled,invalid, sanitizedhook, andfingerprintfields. Ifinvalid: true, re-register or clear the hook instead of editingevent_hook.jsonmanually. - Inspect recent delivery results with
fin-cli monitor hook history --limit 20 --ai; delivery history must not contain webhook secrets, common token/password/authorization/API-key values, or unbounded response bodies. Checkcapabilities --aimonitor.hookHistory.recordFields,failureCategories, andretryableHttpStatuses, then inspectsummary.statusCounts,summary.failureCategoryCounts,summary.retryableFailedCount,summary.failureRate,summary.latestFailedDeliveryId,summary.latestFailedReplayDryRunCommand,summary.latestRetryableFailedReplayDryRunCommand,failureCategory,retryable,retryAfterMson rate-limited webhook records, andlogIntegrity.malformedLines; malformed JSONL delivery records are ignored so one corrupt line does not block history or replay of valid records. - Narrow hook history with
--status failed,--failure-category http_retryable,--retryable true,--event alert_triggered,--event-id <event-id>,--correlation-id <correlation-id>,--delivery-id <delivery-id>,--replay-of <delivery-id>,--symbol <code>,--since <ISO timestamp>, and/or--until <ISO timestamp>before replaying. - Check
fin-cli capabilities --aimonitor.hookReplay.resultFields,batchFilterFields,failureCategories,effectFields,dryRunEffects, andemptyBatchEffectsbefore automating replay decisions. - For failed deliveries, preview replay with
fin-cli monitor hook replay --latest-failed=true --dry-run=true --ai, then applyfin-cli monitor hook replay --latest-failed=true --aior replay a specific delivery with--id <delivery-id>. In replay dry-run output, verifywouldWrite: falseandeffects.mutatesHookTarget: false; applying replay sends the stored payload again and appends a new delivery history record. - When multiple deliveries failed, preview a filtered batch with
fin-cli monitor hook replay --batch=true --status failed --failure-category http_retryable --retryable true --event alert_triggered --correlation-id <correlation-id> --symbol <code> --since <ISO timestamp> --limit 20 --dry-run=true --ai; apply only after reviewing the selected delivery count,filters,replayedCount,failedCount,unreplayableCount, andunreplayableDeliveryIds. Add--dedupe-correlation=truewhen replaying broad batches so only the newest selected delivery per alert correlation is resent. Use--replay-of <delivery-id>to inspect or replay records created from a specific original delivery. - Manage Hermes subscriptions with
fin-cli monitor hook list --profile hermes-helper --aiand preview removal withfin-cli monitor hook remove --profile hermes-helper --route fin-cli-monitor --dry-run=true --aibefore applying without--dry-run=true. - Manage price alert events separately with
fin-cli monitor event add/update/test/list/pause/resume/export/import/audit/rollback/template/remove --ai. - Start reusable alert design from
capabilities --aimonitor.eventTemplateCatalogorfin-cli monitor event template list --ai; narrow candidates with--condition-type,--mode,--condition-mode, and--has-filter true|false, then inspect a recipe withfin-cli monitor event template show --name price-breakout --ai,--name percent-breakout, or--name krx-session-breakout; templates return required flags, defaults, conditions, and an example command. - Use
capabilities --aimonitor.eventAutomation.addDryRunTemplate,templateApplyDryRunTemplate, andtestTemplatewithmonitor.eventConditionCatalog[].exampleValueandtestExampleArgswhen composing event add/update dry-runs, template apply dry-runs, or deterministicmonitor event testcommands. - Prefer
fin-cli monitor event template apply --name price-breakout --symbol 005930 --target-price 71500 --id agent:005930:breakout --dry-run=true --aibefore applying without--dry-run=true; use--name krx-session-breakoutwhen the alert should include weekday 09:00-15:30 KRX session filters by default. Apply maps template placeholders to the concretemonitor event addflags and returnspostApplyTestCommand; run that command after applying the event to verifytest_input_coverage.deterministic. - Prefer a stable
monitor event add --id <agent-owned-id>when recreating known alerts; IDs must be unique and match[A-Za-z0-9][A-Za-z0-9_.:-]*. - Preview event mutations with
monitor event add/update/remove/pause/resume ... --dry-run=true --ai; dry-run returnsstatus: "validated",wouldWrite: false, andaudit_id: nullwithout changing event state or audit logs. Applied event mutations returnaudit_idvalues that link directly tofin-cli monitor event audit --id <audit_id> --airecords. - Narrow event lists with
--id <event-id>,--id-prefix <agent-owned-prefix>,--status active|paused,--mode once|repeat,--condition-type <type>,--symbol <code>,--runnable true|false,--started true|false,--starts-after <ISO timestamp>,--starts-before <ISO timestamp>,--expired true|false,--expires-after <ISO timestamp>, and/or--expires-before <ISO timestamp>; narrow event audits with--action,--event-id,--symbol, and--status. - Check
monitor event list --aisummaryfor active/paused/repeat/started/expired/exhausted/runnable/notRunnable counts and each event'srunnableplusrunnableBlockers(paused,status_not_active,not_started,expired,exhausted) before mutating events. IfparseErrororinvalidEntriesis non-zero, followdoctor --aireview-monitor-event-store, inspect withfin-cli monitor event list --ai, and repair or restoreevents.json; mutation commands intentionally refuse to write over an invalid event store. - Use
updateto adjust an existing event without deleting trigger history. Condition flags passed toupdatemerge by condition type unless--replace-conditions=trueis provided. - Use
test --id "<event-id>" --price <price> --aibefore starting or changing the daemon when validating complex conditions; it does not mutate event state. - Inspect
monitor event test --aireason,condition_results, andtest_input_coveragebefore changing an event: reasons includetriggered,triggered_final,conditions_not_matched,filters_not_matched,cooldown,not_started,expired, andexhausted. Usecapabilities --aimonitor.eventTestInputCatalogto map required test flags to explicit CLI inputs or implicit event-state sources. Use each condition result'sformattedThresholdto verify time/day filters without decoding numeric thresholds.test_input_coverage.deterministicshould betruebefore trusting a complex simulation; missing inputs name the exact flags to add. - If overriding simulation time, pass
--timestampas integer Unix timestamp seconds only. - For percent or amount conditions, include
--ref-price <price>inmonitor event testwhen the event definition does not already pin a reference price. - For price/percent crossing conditions, include
--previous-price <price>inmonitor event testso the simulated cross does not depend on the event file's last observed tick; for volume crossing conditions, include--previous-volume <volume>with the current--volume <volume>. - Use
capabilities --aimonitor.eventAutomation.exportTemplate,importDryRunTemplate, andimportReplaceDryRunTemplate, then runexport --file <path> --aiandimport --file <path> --replace=true --dry-run=true --aibeforeimport --file <path> --replace=true --aito preview added/updated/removed/unchanged event ids when backing up or reproducing event definitions across agent environments.monitor event export --aireturnswouldWriteandeffects.localBackupFile; it is read-only only when--fileis omitted, while--filewrites a local backup file.monitor event import --aireturnseffects.localEventStore,effects.eventAuditLog,effects.mutatesLocalEventStore, andeffects.mutatesEventAuditLog; dry-run leaves the event store and event audit log unchanged. - Import payloads must not contain duplicate event ids; fix the source file instead of relying on overwrite order.
- Imported event ids must use only
[A-Za-z0-9_.:-], start with an alphanumeric character, and be at most 128 characters; unknown enum values are rejected. - Use
audit --limit 20 --ai, checksummary.actionCounts,summary.statusCounts,summary.latestAuditId,summary.latestAppliedAuditId, andlogIntegrity.malformedLines, then runrollback --audit-id <audit-id> --dry-run=true --aibefore applyingrollback --audit-id <audit-id> --aito recover from a bad add/update/remove/import. Malformed audit JSONL lines are skipped so valid records remain inspectable. Applied rollback returns a newaudit_idfor the rollback audit record. If rollback reports a conflict, inspect the newer event changes, then userollback --audit-id <audit-id> --force=true --dry-run=true --aito reviewconflicts,conflictCount, andforceOverridesConflictsbefore intentionally applying with--force=true. - Prefer
pauseoverremovewhen the user wants to stop alerts temporarily while preserving the event definition. - Event conditions support percent movement (
--trigger-up,--trigger-down), percent crossing (--trigger-cross-up,--trigger-cross-down), absolute price (--price-above,--price-below), price crossing (--price-cross-above,--price-cross-below), absolute amount from reference (--amount-up,--amount-down), cumulative volume (--volume-above,--volume-below), volume crossing (--volume-cross-above,--volume-cross-below), local time windows (--time-after HH:MM,--time-before HH:MM), local day filters (--days mon,tue,wed,thu,fri),--condition-mode any|all,--mode once|repeat,--cooldown-sec,--max-trigger-count <n>,--starts-at <ISO timestamp>, and--expires-at <ISO timestamp>. Prefercapabilities --aimonitor.eventConditionCatalogas the authoritative flag/role/test-input map. - Use
--starts-atto pre-register future alerts,--expires-atfor one-off campaign or session-specific alerts, and--max-trigger-countto cap noisy repeat alerts; remove them withmonitor event update --id <event-id> --clear-starts-at=true --clear-expires-at=true --clear-max-trigger-count=true --ai. - After reviewing an exhausted or noisy repeat event, use
monitor event update --id <event-id> --reset-trigger-count=true --reset-observed-state=true --aito keep the definition while clearing its trigger count, last trigger timestamp, and crossing-condition observation state. - Time window and day conditions are filters, not standalone alert triggers; include at least one price/percent/amount/volume/crossing condition.
- Use
--condition-mode allwhen the user wants a combined price/percent/amount/volume filter such as "price above 71000 and volume above 1,000,000 during market hours"; omit it or useanyfor independent alert thresholds. - When a monitor alert triggers, the event JSON is POSTed to the webhook with
X-Hub-Signature-256,X-Fin-Cli-Delivery-Id,X-Fin-Cli-Correlation-Id, andX-Fin-Cli-Event-Id; command hooks receive the equivalentFIN_CLI_*environment variables. - Webhook delivery retries network errors, timeouts, HTTP 429 responses, and HTTP 5xx responses.
Retry-Afteris honored for retryable webhook responses when present. Other HTTP 4xx responses indicate hook configuration/authentication errors and are not retried. - Runtime overrides are supported with
FIN_CLI_HERMES_WEBHOOK_URL/FIN_CLI_HERMES_WEBHOOK_SECRETorFIN_CLI_EVENT_HOOK_URL/FIN_CLI_EVENT_HOOK_SECRET. - Delivery policy overrides are supported with
FIN_CLI_HERMES_WEBHOOK_TIMEOUT_MS,FIN_CLI_HERMES_WEBHOOK_RETRIES,FIN_CLI_HERMES_WEBHOOK_RETRY_DELAY_MSor the equivalentFIN_CLI_EVENT_HOOK_*variables. - For full operational steps, read docs/hermes-agent.md.
- Use