chore: initial commit

This commit is contained in:
Stevan Freeborn committed 2026-10-01 14:43:01 -05:00
commit 433471fd24
12 files changed
+1073

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
validate-skill:
name: Validate Agent Skill
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: lts/*
- name: Validate skill specification
run: npx skills-ref validate .
+50
View File
@@ -0,0 +1,50 @@
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
publish-release:
name: Package and Release Skill
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: lts/*
- name: Validate skill specification
run: npx skills-ref validate .
- name: Package skill archives
shell: bash
run: |
VERSION="${GITHUB_REF_NAME}"
ARCHIVE_NAME="onx-skill-${VERSION}"
STAGE_DIR="staging/${ARCHIVE_NAME}"
mkdir -p "${STAGE_DIR}"
cp -r SKILL.md README.md LICENSE.md references scripts "${STAGE_DIR}/"
tar -czf "${ARCHIVE_NAME}.tar.gz" -C staging "${ARCHIVE_NAME}"
sha256sum "${ARCHIVE_NAME}.tar.gz" > "${ARCHIVE_NAME}.tar.gz.sha256"
zip -r "${ARCHIVE_NAME}.zip" staging/"${ARCHIVE_NAME}"
sha256sum "${ARCHIVE_NAME}.zip" > "${ARCHIVE_NAME}.zip.sha256"
mkdir dist
mv "${ARCHIVE_NAME}".* dist/
cd dist
cat *.sha256 > SHA256SUMS.txt
- name: Create GitHub Release
uses: softprops/action-gh-release@v3
with:
name: Release ${{ github.ref_name }}
generate_release_notes: true
files: |
dist/*.tar.gz
dist/*.zip
dist/*.sha256
dist/SHA256SUMS.txt
+3
View File
@@ -0,0 +1,3 @@
*.tar.gz
*.zip
*.sha256
+19
View File
@@ -0,0 +1,19 @@
# Copyright (c) 2026 Stevan Freeborn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+65
View File
@@ -0,0 +1,65 @@
# onx-skill
An Agent Skill adhering to the [Agent Skills Specification](https://agentskills.io) enabling AI agents to interact with the Onspring platform via the [`onx`](https://github.com/StevanFreeborn/onx) CLI.
## Overview
This skill equips agents with the instructions, progressive documentation, and bootstrap scripts necessary to perform Onspring operations.
## Installation
### Using `skills` Package Manager
Install directly using [`skills`](https://skills.sh) to automatically configure the skill for any of your installed agents:
```bash
# Install to your project
npx skills add StevanFreeborn/onx-skill
# Or install globally for all sessions
npx skills add StevanFreeborn/onx-skill -g
```
To update the skill to the latest version:
```bash
npx skills update onx-skill
```
### Manual Installation (Git Clone or Download)
Clone or symlink the repository into your agent's skills directory:
```bash
git clone https://github.com/StevanFreeborn/onx-skill.git <path-to-agent-skills>/onx-skill
```
Packaged `.tar.gz` and `.zip` archives are also available on the [Releases](https://github.com/StevanFreeborn/onx-skill/releases) page.
> [!NOTE]
> The skill includes automated bootstrap scripts in `scripts/` to install the `onx` CLI binary on Windows, Linux, and macOS if it is not already present in `PATH`.
## Configuration
`onx` authenticates with the Onspring API using credentials resolved in the following priority order:
1. **Command-line options**: `--api-key <KEY> --base-url <URL>`
2. **Configuration file**: `~/.config/onx/config.json` (or via `--config <PATH>`)
3. **Environment variables**: `ONSPRING_API_KEY`, `ONSPRING_BASE_URL`
### Environment Variables
```bash
export ONSPRING_API_KEY="your-api-key"
export ONSPRING_BASE_URL="https://api.onspring.com"
```
### Configuration File (`~/.config/onx/config.json`)
```json
{
"apiKey": "your-api-key",
"baseUrl": "https://api.onspring.com",
"pretty": true
}
```
+200
View File
@@ -0,0 +1,200 @@
---
name: onx-skill
description: Interact with the Onspring platform via the onx CLI. Manage apps, records, fields, files, lists, and reports. Use when querying Onspring records, modifying data, fetching schema metadata, or automating Onspring operations.
license: MIT
compatibility: Requires onx CLI binary, network access to Onspring API instance, and an Onspring API Key.
metadata:
author: Stevan Freeborn
version: "0.0.0"
---
# Onspring Agent Skill (`onx-skill`)
Use this skill to interact with the Onspring platform using the `onx` command-line tool.
All capabilities, options, and JSON payload structures in this skill are grounded directly in the `onx` CLI source and the [Onspring API v2 Specification](https://onspringapidocs.stevanfreeborn.com/).
## Ground Truth & CLI Introspection
> **Important**: The `onx` CLI is the ultimate source of truth. Always run `onx <command> --help` to inspect real-time arguments, options, and commands if unsure of syntax:
>
> ```bash
> onx --help
> onx <subcommand> --help
> ```
---
## Prerequisites & Installation
Verify if `onx` is installed:
```bash
onx --version
```
If `onx` is not installed or not in `PATH`, install it using one of the helper scripts in `scripts/`:
### Windows (PowerShell)
```powershell
.\scripts\install-onx.ps1
```
Or directly from GitHub:
```powershell
irm https://raw.githubusercontent.com/StevanFreeborn/onx/main/scripts/install.ps1 | iex
```
### Linux & macOS (Bash)
```bash
bash scripts/install-onx.sh
```
Or directly from GitHub:
```bash
curl -fsSL https://raw.githubusercontent.com/StevanFreeborn/onx/main/scripts/install.sh | bash
```
---
## Authentication & Configuration
`onx` reads credentials using the following precedence:
1. **Command-line flags**: `--api-key <KEY> --base-url <URL>`
2. **Configuration file**: `~/.config/onx/config.json` (or `--config <PATH>`)
3. **Environment variables**: `ONSPRING_API_KEY`, `ONSPRING_BASE_URL`
### Recommended Agent Setup (Environment Variables)
```bash
export ONSPRING_API_KEY="your-api-key"
export ONSPRING_BASE_URL="https://api.onspring.com"
```
On Windows PowerShell:
```powershell
$env:ONSPRING_API_KEY = "your-api-key"
$env:ONSPRING_BASE_URL = "https://api.onspring.com"
```
For more configuration details and file templates, see [references/configuration.md](references/configuration.md).
---
## Core Workflows
> [!NOTE]
> Global flags (e.g. `--pretty`, `--api-key`) must precede subcommands:
> `onx --pretty ping` or `onx --pretty apps list`
### Connectivity Check
```bash
onx ping
```
### Schema Discovery (Apps & Fields)
Before operating on records, discover the target App ID and Field IDs:
```bash
# List all apps
onx apps list
# Get details of a specific app
onx apps get --app 195
# List fields within an app
onx fields list --app 195
# Get field metadata (type, multiplicity, list values, formula output type)
onx fields get --field 6983
```
### Querying Records
Retrieve records matching filter expressions. String values in filters must use single quotes `'`. Date filters must be preceded by `datetime` (e.g., `datetime'2026-01-01T00:00:00Z'`):
```bash
onx records query --json '{"appId": 195, "filter": "6983 eq '\''Active'\''"}'
```
With pagination and specific field IDs:
```bash
onx records query --page-number 1 --page-size 20 --json '{
"appId": 195,
"filter": "6983 eq '\''Active'\'' and 6987 gt 100",
"fieldIds": [6983, 6986, 6987],
"dataFormat": "Formatted"
}'
```
### Retrieving Records
```bash
# Get single record by system Record ID
onx records get --app 195 --record 1
# Batch get records by IDs
onx records batch-get --json '{"appId": 195, "recordIds": [1, 2]}'
```
### Creating or Updating Records
Use `records save` with a JSON payload. Pass field values mapped by string Field IDs:
```bash
# Create record (omit recordId or set to null)
onx records save --json '{
"appId": 195,
"recordId": null,
"fields": {
"6983": "New Task",
"6986": "4118d53a-9121-4345-8682-07f23d606daa",
"6987": [4]
}
}'
# Update existing record
onx records save --json '{
"appId": 195,
"recordId": 140,
"fields": {
"6983": "Updated Task Title"
}
}'
```
### Deleting Records
```bash
# Single record
onx records delete --app 195 --record 140
# Batch delete records
onx records batch-delete --json '{"appId": 195, "recordIds": [140, 141]}'
```
### Files, Lists, & Reports
- **Files**: Inspect metadata (`onx files info --record 1 --field 6989 --file 89`), download content (`onx files get --record 1 --field 6989 --file 89 --output ./download.txt`), upload attachments (`onx files upload --record 140 --field 6989 --input ./doc.pdf`), or delete (`onx files delete --record 140 --field 6989 --file 1904`).
- **Lists**: Add or update list options (`onx lists save-item --list 906 --json '{"name": "Reviewed", "numericValue": 1.0}'`), or delete list values (`onx lists delete-item --list 906 --item 4118d53a-9121-4345-8682-07f23d606daa`).
- **Reports**: List available reports in an app (`onx reports list --app 195`) or fetch report data (`onx reports get --report 613 --format formatted`).
---
## Deep-Dive References
For detailed request schemas, Onspring data types, and full command syntax, consult:
- [references/cli-reference.md](references/cli-reference.md): Complete list of commands, subcommands, and flags.
- [references/record-payloads.md](references/record-payloads.md): Exact schemas, filter operators (`eq`, `ne`, `lt`, `gt`, `contains`, `isnull`, `notnull`), date formatting in UTC, and `Raw` vs `Formatted` responses.
- [references/configuration.md](references/configuration.md): Precedence rules and config file examples.
- [Onspring API Docs](https://onspringapidocs.stevanfreeborn.com/): Official API v2 reference guide.
+277
View File
@@ -0,0 +1,277 @@
# Onx CLI Reference
This reference documents the exact top-level commands, subcommands, arguments, and options provided by the `onx` CLI, grounded in the CLI implementation and the [Onspring API v2 Specification](https://onspringapidocs.stevanfreeborn.com/).
> [!TIP]
> **Source of Truth**: Always run `onx <command> --help` to inspect live command options and subcommands in real-time.
## Global Options
The following flags are available on the top-level command:
| Option | Short | Description |
| :---------------------- | :---- | :------------------------------------------------------------------------- |
| `--api-key <API_KEY>` | `-k` | The API key for the Onspring instance |
| `--base-url <BASE_URL>` | `-u` | The base URL for the Onspring API (defaults to `https://api.onspring.com`) |
| `--config <CONFIG>` | `-c` | Path to a configuration JSON file |
| `--pretty` | `-p` | Pretty-print JSON output |
| `--help` | `-h` | Print help |
| `--version` | `-V` | Print version |
> [!NOTE]
> Global flags (such as `--pretty`, `--api-key`, `--base-url`, `--config`) must precede the subcommand in invocation:
>
> ```bash
> onx --pretty ping
> onx --pretty records list --app 195
> ```
## `ping`
Check connectivity to the Onspring API.
```bash
onx ping
```
**Output on Success:**
```json
{
"ok": true
}
```
## `apps`
Perform operations against the apps in the instance.
### `onx apps list`
Get a paged list of apps in the instance.
- `--page-number <PAGE_NUMBER>`, `-n`: The page number to retrieve (default: 1)
- `--page-size <PAGE_SIZE>`, `-s`: The size of the page to retrieve (default: 50, max: 1000)
**Output:**
```json
{
"pageNumber": 1,
"pageSize": 50,
"totalPages": 1,
"totalRecords": 2,
"items": [
{
"href": "https://api.onspring.com/apps/id/195",
"id": 195,
"name": "Projects"
}
]
}
```
### `onx apps get`
Get information about a specific app by ID.
- `--app <APP_ID>`, `-a`: App ID to get (required, positive integer)
### `onx apps batch-get`
Get information for a batch of apps.
- `--apps <APP_IDS>`, `-a`: Comma-separated list of app IDs to get (required, e.g. `--apps 195,196`)
## `fields`
Perform operations against the fields in the instance.
### `onx fields list`
Get a paged list of fields in an app.
- `--app <APP_ID>`, `-a`: App ID whose fields will be retrieved (required)
- `--page-number <PAGE_NUMBER>`, `-n`: Page number
- `--page-size <PAGE_SIZE>`, `-s`: Page size
### `onx fields get`
Get detailed metadata about a field (type, multiplicity, list values, formula output type).
- `--field <FIELD_ID>`, `-f`: Field ID to get (required)
### `onx fields batch-get`
Get information for a batch of fields by IDs (maximum 100).
- `--fields <FIELD_IDS>`, `-f`: Comma-separated list of field IDs to get (required, e.g. `--fields 6983,6986`)
## `records`
Perform operations against records in the instance.
### `onx records list`
Get a paged list of records from an app.
- `--app <APP_ID>`, `-a`: App ID whose records will be retrieved (required)
- `--fields <FIELD_IDS>`, `-f`: Comma-separated list of field IDs to include in the response
- `--data-format <raw|formatted>`: Format of data in the response (default: `raw`)
- `--page-number <PAGE_NUMBER>`, `-n`: Page number
- `--page-size <PAGE_SIZE>`, `-s`: Page size
### `onx records get`
Get information for a single record.
- `--app <APP_ID>`, `-a`: App ID (required)
- `--record <RECORD_ID>`, `-r`: System Record ID (required)
- `--fields <FIELD_IDS>`, `-f`: Comma-separated list of field IDs to include
- `--format <raw|formatted>`, `-d`: Format of data in response (default: `raw`)
### `onx records save`
Add or update a record.
- Input body source (choose one):
- `--json <JSON>`, `-j`: Inline JSON request body
- `--file <FILE>`, `-f`: Path to a JSON request body file
- `--stdin`: Read JSON request body from stdin
**Request Format:**
```json
{
"appId": 195,
"recordId": null,
"fields": {
"6983": "New Task",
"6986": "4118d53a-9121-4345-8682-07f23d606daa"
}
}
```
### `onx records query`
Query for records using a filter expression.
- Input body source (choose one):
- `--json <JSON>`, `-j`: Inline JSON request body
- `--file <FILE>`, `-f`: Path to a JSON request body file
- `--stdin`: Read JSON request body from stdin
- Pagination options:
- `--page-number <PAGE_NUMBER>`, `-n`: Page number
- `--page-size <PAGE_SIZE>`, `-s`: Page size
### `onx records delete`
Delete a single record.
- `--app <APP_ID>`, `-a`: App ID (required)
- `--record <RECORD_ID>`, `-r`: System Record ID (required)
### `onx records batch-get`
Get information for a batch of records (maximum 100).
- `--json <JSON>`, `-j` / `--file <FILE>`, `-f` / `--stdin`: JSON body `{ "appId": 195, "recordIds": [1, 2], "fieldIds": [...], "dataFormat": "Raw" }`
### `onx records batch-delete`
Delete a batch of records (maximum 100).
- `--json <JSON>`, `-j` / `--file <FILE>`, `-f` / `--stdin`: JSON body `{ "appId": 195, "recordIds": [138, 139] }`
## `files`
Perform operations against files held in `Attachment` and `Image` fields.
### `onx files info`
Get metadata info for a file.
- `--record <RECORD_ID>`, `-r`: Record ID where the file is held (required)
- `--field <FIELD_ID>`, `-f`: Field ID where the file is held (required)
- `--file <FILE_ID>`, `-l`: The ID of the file (required)
### `onx files get`
Download the content of a file.
- `--record <RECORD_ID>`, `-r`: Record ID (required)
- `--field <FIELD_ID>`, `-f`: Field ID (required)
- `--file <FILE_ID>`, `-l`: File ID (required)
- `--output <PATH>`, `-o`: Optional output path to write the downloaded file to disk (if omitted, writes binary to stdout)
### `onx files upload`
Upload a file to a field on a record.
- `--record <RECORD_ID>`, `-r`: Record ID (required)
- `--field <FIELD_ID>`, `-f`: Field ID (required)
- File source (choose one):
- `--input <PATH>`, `-i`: Path of local file to upload
- `--stdin`, `-s`: Read file data from stdin
- Optional metadata:
- `--name <NAME>`, `-n`: File name (required if reading from stdin; defaults to filename if `--input` is used)
- `--type <MIME>`, `-t`: Content MIME type (e.g. `application/pdf`; inferred if omitted)
- `--notes <NOTES>`: Optional notes to attach to the file
- `--modified-date <TIMESTAMP>`: Optional last modified date as RFC3339 timestamp (e.g. `2026-10-01T12:00:00Z`)
### `onx files delete`
Delete a file from an attachment/image field on a record.
- `--record <RECORD_ID>`, `-r`: Record ID (required)
- `--field <FIELD_ID>`, `-f`: Field ID (required)
- `--file <FILE_ID>`, `-l`: File ID (required)
## `lists`
Perform operations against custom lists and list values in the instance.
### `onx lists save-item`
Add or update an item for a specific list.
- `--list <LIST_ID>`, `-l`: List ID where the item should be saved (required)
- `--json <JSON>`, `-j` / `--file <FILE>`, `-f` / `--stdin`: JSON body:
```json
{
"id": null,
"name": "In Review",
"numericValue": 1.5,
"color": "#ffaa00"
}
```
_(Omit `id` or pass `null` to create; provide item GUID to update)_
### `onx lists delete-item`
Delete a list item from a list.
- `--list <LIST_ID>`, `-l`: List ID (required)
- `--item <ITEM_ID>`, `-i`: GUID of the item to delete (required, e.g. `4118d53a-9121-4345-8682-07f23d606daa`)
## `reports`
Perform operations against reports in an app or survey.
### `onx reports list`
List reports available in an app or survey.
- `--app <APP_ID>`, `-a`: App ID (required)
- `--page-number <PAGE_NUMBER>`, `-n`: Page number
- `--page-size <PAGE_SIZE>`, `-s`: Page size
### `onx reports get`
Get the tabular or chart data for a specific report.
- `--report <REPORT_ID>`, `-r`: Report ID (required)
- `--format <raw|formatted>`, `-f`: Format of report data (`raw` or `formatted`, default: `raw`)
- `--type <reportData|chartData>`, `-t`: Type of report data to retrieve (`reportData` or `chartData`, default: `reportData`)
- `--page-number <PAGE_NUMBER>`, `-n`: Page number
- `--page-size <PAGE_SIZE>`, `-s`: Page size
+69
View File
@@ -0,0 +1,69 @@
# Configuration Reference for `onx`
`onx` can be configured using command-line arguments, a JSON configuration file, or environment variables.
## Precedence
Settings are resolved in the following priority order (highest to lowest):
1. **Command-line flags** (`--api-key`, `--base-url`, `--pretty`, `--config`)
2. **Configuration file** (`~/.config/onx/config.json` or path specified by `--config`)
3. **Environment variables** (`ONSPRING_API_KEY`, `ONSPRING_BASE_URL`)
## Environment Variables
Recommended for automated agent sessions, CI/CD, and containers:
| Variable | Description | Example |
| :------------------ | :-------------------------------------------------------------------------- | :------------------------- |
| `ONSPRING_API_KEY` | Your Onspring API Key | `abcd-1234-efgh-5678` |
| `ONSPRING_BASE_URL` | Base URL of your Onspring instance (defaults to `https://api.onspring.com`) | `https://api.onspring.com` |
### Setting in Unix (Bash / Zsh)
```bash
export ONSPRING_API_KEY="your-api-key"
export ONSPRING_BASE_URL="https://api.onspring.com"
```
### Setting in Windows (PowerShell)
```powershell
$env:ONSPRING_API_KEY = "your-api-key"
$env:ONSPRING_BASE_URL = "https://api.onspring.com"
```
---
## Configuration File
By default, `onx` checks for a configuration file at:
- **Unix / macOS**: `~/.config/onx/config.json`
- **Windows**: `%USERPROFILE%\.config\onx\config.json`
### Format
```json
{
"apiKey": "your-api-key",
"baseUrl": "https://api.onspring.com",
"pretty": true
}
```
### Custom Config Location
You can supply a custom config file path to any command with `--config`:
```bash
onx apps list --config ./my-onspring-config.json
```
## Command-Line Options
Every command supports passing credentials directly:
```bash
onx ping --api-key "your-api-key" --base-url "https://api.onspring.com" --pretty
```
+186
View File
@@ -0,0 +1,186 @@
# Onspring Record Payloads & API Data Types Reference
This reference describes the exact JSON structures, data formats, and filter syntax used with `onx records save`, `onx records query`, `onx records batch-get`, and `onx records batch-delete`, grounded in the [Onspring API v2 Specification](https://onspringapidocs.stevanfreeborn.com/).
## `records save` Payload
Used for creating or updating records:
```bash
onx records save --json '<JSON_STRING>'
# or
onx records save --file ./record.json
# or
cat ./record.json | onx records save --stdin
```
### JSON Structure
```json
{
"appId": 195,
"recordId": null,
"fields": {
"6983": "A New Test Task",
"6984": "<p>This is a test task.</p>",
"6985": "2026-10-01T06:00:00Z",
"6986": "4118d53a-9121-4345-8682-07f23d606daa",
"6987": [4],
"6988": 100.5
}
}
```
### Input Fields Specification
| Property | Type | Description |
| :--------- | :--------------- | :------------------------------------------------------------------------------------------------------------------------------------- |
| `appId` | `number` | The ID of the app that contains or will contain the record (required). |
| `recordId` | `number \| null` | The ID of the record to update. If `null` or omitted, a new record is created. |
| `fields` | `object` | Key-value mapping where each key is the string representation of a **Field ID**, and the value is formatted per the field's data type. |
### Field Value Types When Saving
- **Text / Multi-line Text**: `string` (e.g., `"Title"` or HTML `"<p>Description</p>"`).
- **Number / Currency**: `number` (e.g., `42`, `100.50`).
- **Date / Time**: `string` in UTC ISO 8601 format (e.g., `"2026-10-01T12:00:00Z"`). Dates are always passed back and forth in UTC.
- **List (Single-Select)**: `string` containing the GUID of the chosen list value (e.g., `"4118d53a-9121-4345-8682-07f23d606daa"`).
- **List (Multi-Select)**: Array of GUID strings `string[]` (e.g., `["4118d53a-...", "1c1c5f7e-..."]`).
- **Reference (Single-Select)**: Array with one integer record ID `[140]` or integer `140`.
- **Reference (Multi-Select)**: Array of integer record IDs (e.g., `[140, 141]`).
- **Attachment / File**: Uploaded separately via `onx files upload`.
### Output on Success (`onx records save`)
```json
{
"id": 140,
"warnings": []
}
```
## `records query` Payload & Filter Syntax
Used for filtering and querying records across an app:
```bash
onx records query --json '<JSON_STRING>'
```
### JSON Structure
```json
{
"appId": 195,
"filter": "6983 eq 'Test Task' and 6987 gt 50",
"fieldIds": [6983, 6986, 6987],
"dataFormat": "Formatted"
}
```
### Request Fields
| Property | Type | Description |
| :----------- | :--------- | :------------------------------------------------------------------------------------------- |
| `appId` | `number` | App ID containing the records (required). |
| `filter` | `string` | Filter expression referencing Field IDs (required). |
| `fieldIds` | `number[]` | Optional array of field IDs to include in the response. If omitted, all fields are returned. |
| `dataFormat` | `string` | Optional: `"Raw"` or `"Formatted"` (defaults to `"Raw"`). |
### Query Filter Operators & Rules
Filter expressions evaluate field values using Field IDs as identifiers.
| Operator | Description | Applicable Field Types |
| :--------- | :----------------------------------- | :----------------------------------------------------------- |
| `eq` | Equals | Text, Number, Date, Auto-Number, Formulas (text/number/date) |
| `ne` | Not equals | Text, Number, Date, Auto-Number, Formulas (text/number/date) |
| `lt` | Less than | Number, Date, Auto-Number, Formulas (number/date) |
| `gt` | Greater than | Number, Date, Auto-Number, Formulas (number/date) |
| `contains` | List contains item (by name or GUID) | List fields, List formulas |
| `isnull` | Field has no value | Text, Number, Date, Auto-Number, Formulas |
| `notnull` | Field has a value | Text, Number, Date, Auto-Number, Formulas |
#### Literal Delimiters
- **String values**: Must be enclosed in single quotes `'` (e.g., `6983 eq 'Active'`).
- **Date values**: Must be enclosed in single quotes `'` preceded by `datetime` (e.g., `6985 gt datetime'2026-01-01T00:00:00Z'`).
- **Logical combination**: Combine with `and`, `or`, and negate with `not`. Group expressions using parentheses `( ... )`.
Example:
```text
(6983 eq 'Active' or 6983 eq 'Pending') and 6987 gt 100 and 6985 notnull
```
## `records batch-get` Payload
Used to fetch specific records in bulk (maximum 100 records per request):
```bash
onx records batch-get --json '{
"appId": 195,
"recordIds": [1, 2, 3],
"fieldIds": [6983, 6986],
"dataFormat": "Formatted"
}'
```
Output:
```json
{
"count": 3,
"items": [
{
"appId": 195,
"recordId": 1,
"fieldData": [
{
"type": "String",
"fieldId": 6983,
"value": "Task 1"
}
]
}
]
}
```
## `records batch-delete` Payload
Used to delete records in bulk (maximum 100 records per request):
```bash
onx records batch-delete --json '{
"appId": 195,
"recordIds": [138, 139]
}'
```
Output on success:
```json
{
"ok": true
}
```
## Understanding `dataFormat`: `Raw` vs `Formatted`
When retrieving records (`list`, `get`, `batch-get`, `query`) or reports, `dataFormat` controls the output format:
| Field Type | `Raw` Format | `Formatted` Format |
| :-------------------- | :------------------------------------------------------------------------ | :--------------------------------------------------------------- |
| **AutoNumber** | `number` (e.g. `1`) | Formatted `string` (e.g. `"APP-001"`) |
| **Date/Time** | ISO 8601 UTC string (e.g. `"2026-10-01T06:00:00Z"`) | Display string with user formatting (e.g. `"10/1/2026 6:00 AM"`) |
| **List** | Value GUID string(s) | Value name string(s) (e.g. `"In Progress"`) |
| **Number / Currency** | `number` (e.g. `100.5`) | Display string with symbol (e.g. `"$100.50"`) |
| **Text** | HTML string (e.g. `"<p>Sample</p>"`) | Plain string with HTML stripped (e.g. `"Sample"`) |
| **TimeSpan** | Object `{ "quantity": 10, "increment": "Minutes", "recurrence": "None" }` | Display string (e.g. `"10 Minutes"`) |
## Record ID vs Display Field
> [!IMPORTANT]
> The `recordId` used in `onx` CLI commands (`--record <ID>`) and API routes is the integer **system record ID** (e.g., `140`).
> Do not confuse this with the text value formatted by an **AutoNumber** or Display field in the Onspring GUI (e.g., `"INC-1002"`).
+34
View File
@@ -0,0 +1,34 @@
[CmdletBinding()]
param(
[Alias("v")]
[string]$Version,
[Alias("t")]
[string]$InstallDir = "$HOME\.onx\bin"
)
$ErrorActionPreference = "Stop"
$Existing = Get-Command "onx" -ErrorAction SilentlyContinue
if ($Existing) {
Write-Host "onx is already installed at: $($Existing.Source)" -ForegroundColor Green
& onx --version
exit 0
}
Write-Host "onx CLI not found in PATH. Installing via official installer..." -ForegroundColor Cyan
$InstallerUrl = "https://raw.githubusercontent.com/StevanFreeborn/onx/main/scripts/install.ps1"
$InstallScript = [scriptblock]::Create((Invoke-RestMethod -Uri $InstallerUrl))
$Params = @{
InstallDir = $InstallDir
}
if ($Version) {
$Params["Version"] = $Version
}
& $InstallScript @Params
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
if command -v onx >/dev/null 2>&1; then
echo "onx is already installed at: $(command -v onx)"
onx --version
exit 0
fi
echo "onx CLI not found in PATH. Installing via official installer..."
INSTALLER_URL="https://raw.githubusercontent.com/StevanFreeborn/onx/main/scripts/install.sh"
if command -v curl >/dev/null 2>&1; then
curl -fsSL "${INSTALLER_URL}" | bash -s -- "$@"
elif command -v wget >/dev/null 2>&1; then
wget -qO- "${INSTALLER_URL}" | bash -s -- "$@"
else
echo "Error: Neither curl nor wget was found." >&2
exit 1
fi
+128
View File
@@ -0,0 +1,128 @@
[CmdletBinding()]
param(
[string]$OnxPath
)
$ErrorActionPreference = "Stop"
function Get-ClapCommands {
param(
[string]$HelpText
)
$Commands = @()
$InCommandsSection = $false
foreach ($Line in ($HelpText -split "`r?`n")) {
if ($Line -match '^Commands:') {
$InCommandsSection = $true
continue
}
if ($InCommandsSection) {
if ($Line -match '^[A-Z][a-zA-Z0-9 ]*:' -or $Line.Trim() -eq "") {
if ($Line.Trim() -ne "") {
break
}
continue
}
if ($Line -match '^\s{2}([a-z0-9][a-z0-9\-_]*)\s+(.+)$') {
$CmdName = $Matches[1].Trim()
if ($CmdName -ne "help") {
$Commands += $CmdName
}
}
}
}
return $Commands
}
if (-not $OnxPath) {
$Cmd = Get-Command "onx" -ErrorAction SilentlyContinue
if ($Cmd) {
$OnxPath = $Cmd.Source
}
}
if (-not $OnxPath -or -not (Test-Path $OnxPath)) {
Write-Error "Could not locate onx executable. Ensure 'onx' is in PATH or provide -OnxPath <path_to_onx>."
exit 1
}
Write-Host "Deriving commands dynamically from onx binary at: $OnxPath" -ForegroundColor Cyan
$RootHelp = & $OnxPath --help | Out-String
$TopCommands = Get-ClapCommands -HelpText $RootHelp
if ($TopCommands.Count -eq 0) {
Write-Error "Failed to dynamically discover any commands from '$OnxPath --help'."
exit 1
}
Write-Host "Discovered top-level commands: $($TopCommands -join ', ')" -ForegroundColor Gray
$CommandHierarchy = @{}
foreach ($cmd in $TopCommands) {
$CmdHelp = & $OnxPath $cmd --help | Out-String
$SubCommands = Get-ClapCommands -HelpText $CmdHelp
$CommandHierarchy[$cmd] = $SubCommands
if ($SubCommands.Count -gt 0) {
Write-Host " -> ${cmd}: $($SubCommands -join ', ')" -ForegroundColor Gray
} else {
Write-Host " -> ${cmd} (standalone command)" -ForegroundColor Gray
}
}
$DocFile = Join-Path $PSScriptRoot "..\references\cli-reference.md"
if (-not (Test-Path $DocFile)) {
Write-Error "cli-reference.md not found at $DocFile"
exit 1
}
$DocText = Get-Content $DocFile -Raw
$HasErrors = $false
foreach ($cmd in $CommandHierarchy.Keys) {
$SubCommands = $CommandHierarchy[$cmd]
if ($SubCommands.Count -eq 0) {
$Pattern = "onx $cmd"
if ($DocText -notmatch [regex]::Escape($Pattern)) {
Write-Warning "Documentation drift! Command '$Pattern' is not documented in $DocFile"
$HasErrors = $true
}
} else {
foreach ($sub in $SubCommands) {
$Pattern = "onx $cmd $sub"
if ($DocText -notmatch [regex]::Escape($Pattern)) {
Write-Warning "Documentation drift! Subcommand '$Pattern' is not documented in $DocFile"
$HasErrors = $true
}
}
}
}
if ($HasErrors) {
Write-Error "CLI docs verification failed due to drift."
exit 1
}
Write-Host "`nAll dynamically derived commands and subcommands from the onx binary are documented in cli-reference.md!" -ForegroundColor Green