SKILL.md
Manage Dinox Storage
CRITICAL — Before doing anything else, first read [../dino-shared/SKILL.md](../dino-shared/SKILL.md). It contains shared auth, output, and write-safety rules.
Use this skill when the user wants to inspect custom storage configs, verify S3 connectivity, upload a file, or inspect storage usage.
Safety & Boundaries (Must Follow)
- Treat storage credentials and endpoint details as sensitive data. Never echo
secretaccesskeyback to the user. dino storage testwrites a tiny temporary object to S3.dino storage uploadwrites to both S3 and local Dinox metadata. Always show the exact command and get explicit confirmation before running the real write.- Prefer
dino storage list --format jsonbefore uploading if the target storage config is ambiguous. - Do not ask the user to paste auth tokens into chat. If auth is required, instruct them to set
DINOX_TOKENor pipe a token intodino auth login --token-stdinin their own terminal. - If the user wants to upload to a specific config without changing the active storage in the app, prefer
--storage-id. - An explicit
--keyrefuses to replace an existing main object or derived image thumbnail by default. Use--overwriteonly after the user explicitly confirms replacement of those exact keys. - Reject object keys and configured path prefixes containing dot-only
.or..segments; standard URL clients normalize those segments and can resolve the returned URL to a different object.
<!-- BEGIN GENERATED_COMMANDS -->
Command Reference
Use these commands as the canonical Dinox CLI interface for custom storage inspection, connectivity testing, uploads, and usage stats.
dino storage list # List custom storage configs from c_storage and mark the active one
dino storage test # Upload a tiny temporary object to a custom S3 storage target without persisting a c_resource row
--storage-id <id> # Explicit storage config id (otherwise use active custom config)
--dry-run # Preview the test object target without uploading
dino storage upload <file> # Upload one local file to a custom S3 storage target and persist a c_resource row
--storage-id <id> # Explicit storage config id (otherwise use active custom config)
--category <kind> # Upload category: images|audios|files|videos
--key <string> # Explicit object key override
--overwrite # Replace existing objects addressed by an explicit --key
--dry-run # Preview the upload target and resource record without uploading
dino storage stats # Summarize uploaded storage usage grouped by provider and bucket
- Prefer
--storage-idwhen you want to bypass the current active custom storage selection. - For test and upload writes, run the same command with
--dry-runfirst.
<!-- END GENERATED_COMMANDS -->
Workflow
- For browse requests, run
dino storage list --format json. - For connectivity checks, use
dino storage test --format jsonand prefer--storage-idwhen multiple custom configs exist. - For uploads, first identify the target config:
- explicit --storage-id - otherwise the active custom storage config - otherwise the only available custom storage config when exactly one exists
- Run
dino storage upload <file> ... --format json --dry-runand show the planned bucket, key, and url. - After confirmation, rerun without
--dry-run. If an explicit key already exists, prefer a new key; add--overwriteonly when the user separately confirms replacement. - Summarize
resourceId,storageKey,storageUrl,thumbnailUrl,bucket, andprovider. - For usage questions, run
dino storage stats --format json. - When the upload is for note markdown embedding, pass the returned
resourceId,storageKey,storageUrl, andthumbnailUrlinto the note-media rewrite flow described in [../dino-note/references/media-resources.md](../dino-note/references/media-resources.md).
Important Notes
dino storage uploadonly targets custom S3 configs. If no custom storage is configured, the user must create one in the app first.dino storage testalso targets only custom S3 configs and does not create ac_resourcerow.- Private buckets are allowed;
storageUrlis still recorded, but direct read access may require signed URLs elsewhere. - Upload also writes a
c_resourcerow, so the file is visible to later Dinox workflows. - Without
--overwrite, failure cleanup only attempts to remove objects created by that upload attempt. With--overwrite, once a remote object is written, a later thumbnail or metadata failure does not automatically delete it; the structured error reportsremoteObjectChanged,affectedKeys, and the main-objectstorageKeyfor verification. - When the uploaded file is an image, the CLI also generates a
400pxwidewebpthumbnail and returns its URL in the command result. The resourcechecksumcolumn is not used for thumbnail storage.
Error Handling
- If no custom storage config is available, tell the user to configure a custom storage target in the app first.
- If there is no active custom storage config and multiple configs exist, ask the user to pick one and use
--storage-id. - If S3 upload fails due to endpoint, bucket, region, or credentials, tell the user the custom storage config is incomplete or invalid and they should verify it in the app.
- If the CLI reports
INVALIDSTORAGEKEY, remove any dot-only.or..segment from--keyor the configured storage path prefix before retrying. - If the object already exists, report the conflicting key and ask the user to choose a new key or explicitly approve
--overwrite; never retry with overwrite automatically. - If an upload error reports
remoteObjectChanged: true, do not claim that the remote write was rolled back. InspectaffectedKeysandstorageKey, verify those exact objects, and choose deliberately whether to keep them or retry. - If
statsreturns no entries, tell the user there are no uploaded storage resources recorded yet.