🟠 Draft | Swiss knife for ical & caldav calendars
Find a file
Glenn Y. Rolland 8977da3619
All checks were successful
continuous-integration/drone/push Build is passing
docs(commands): Clarify default format inference for file operations
This change improves the documentation for `cal-load`, `cal-save`,
`stack-load`, and `stack-save` commands, as well as the general
overview, to explicitly state that when the --format option is omitted
and the input/output path has no file extension, the format defaults to
ICS or KMX, respectively. This prevents potential confusion for users
who might expect format inference to fail in such cases, ensuring a more
predictable user experience.

- Added a new user story to cal-load.md, cal-save.md, stack-load.md, and
  stack-save.md to cover the scenario where --format is omitted and the
  path has no extension, clarifying the default format behavior.
- Updated the "When reading from stdin" and "When writing to stdout"
  sections in cal-load.md, cal-save.md, stack-load.md, and stack-save.md
  to include the "or when the path has no extension" condition for
  default format application.
- Modified the overview.md to refine the explanation of format
  inference, specifically addressing cases where inference is not
  possible (stdin/stdout or no extension) and the default format is
  applied.
- Added a new test case, TestResolveFormat_NoExtensionDefaultsToICS, to
  pkg/basetypes/file_format_test.go to verify that ResolveFormat
  correctly defaults to ICS when no extension is present.

Signed-off-by: Glenn Y. Rolland <glenux@glenux.net>
2026-03-09 21:48:38 +01:00
cmd feat(cli): Improve help command and output suppression 2026-03-08 09:28:46 +01:00
docs docs(commands): Clarify default format inference for file operations 2026-03-09 21:48:38 +01:00
pkg docs(commands): Clarify default format inference for file operations 2026-03-09 21:48:38 +01:00
.drone.yml ci: Disable Docker-in-Docker service 2026-02-22 00:22:50 +01:00
.gitignore feat: improve build process and ignore generated files 2026-02-16 16:29:30 +01:00
2445AllExamples.ics feat: Add license and iCalendar examples 2026-02-22 00:33:00 +01:00
go.mod chore: update dependencies 2024-05-03 21:17:13 +02:00
go.sum chore: update dependencies 2024-05-03 21:17:13 +02:00
go.work feat: Introduce Go workspace for multi-module development 2026-02-16 17:39:42 +01:00
go.work.sum feat: Introduce Go workspace for multi-module development 2026-02-16 17:39:42 +01:00
kiwimix.cdx.json feat: Add SBOM generation with Trivy 2026-02-17 11:20:51 +01:00
kiwimix.spdx feat: Add SBOM generation with Trivy 2026-02-17 11:20:51 +01:00
LICENSE.txt feat: Add license and iCalendar examples 2026-02-22 00:33:00 +01:00
Makefile feat(developer-experience): Add watch target for continuous builds 2026-03-07 11:40:25 +01:00
NOTE.txt docs: Add note about ICS example source 2026-02-22 00:34:18 +01:00
README.md docs: Add license information to README 2026-03-07 11:47:11 +01:00
ROADMAP.md docs: Add detailed use cases to command documentation 2026-02-22 22:00:08 +01:00

Kiwimix

Build Status License: GPL-3.0

Stack-based CLI for building and transforming calendars.

Kiwimix operates on a calendar stack. Each operator maps to an operation, popping and pushing calendars as it runs. Use @ to chain operators in a single run.

Features

  • Stack-based execution with preflight validation.
  • Chain operators with @ in one CLI call.
  • Works with .ics calendars; supports ICS and JSON formats.
  • stdin/stdout support via - for load and save.

Usage

Quick start

Merge and anonymize a calendar:

kiwimix \
    cal-load alice.ics \
  @ filter-merge \
  @ filter-anonymize --all \
  @ cal-save alice-public.ics

Union by occupied time ranges:

kiwimix \
    cal-load alice.ics \
  @ load bob.ics \
  @ bool-union --ranges \
  @ cal-save busy.ics

Compute free time slots by ranges:

kiwimix \
    cal-load alice.ics \
  @ cal-load bob.ics \
  @ bool-union --ranges \
  @ bool-substract --ranges \
  @ cal-save free-time.ics

Find free time:

kiwimix \
    cal-generate --from-date XXX --to-date YYY --from-time 9:00 --to-time 19:00 \
  @ cal-load agenda.ics \
  @ bool-substract --ranges \
  @ cal-save free.ics

Find free time for a meeting:

kiwimix \
    cal-generate --from-date XXX --to-date YYY --from-time 9:00 --to-time 19:00 \
  @ cal-load alice.ics \
  @ cal-load bob.ics \
  @ bool-union --ranges \
  @ bool-substract --ranges \
  @ cal-save free.ics

Rewrite events:

kiwimix \
    cal-load alice.ics \
  @ filter-merge \
  @ filter-anonymize --all \
  @ cal-save alice-public.ics

Stack chain example (formerly noted as V2):

kiwimix \
    cal-generate --from-date XXX --to-date YYY --from-time 9:00 --to-time 19:00 \
  @ cal-load alice.ics \
  @ filter-merge \
  @ filter-anonymize --all \
  @ cal-load bob.ics \
  @ filter-merge \
  @ filter-anonymize --all \
  @ bool-union --ranges \
  @ bool-substract --ranges \
  @ cal-save result.ics

CLI model

  • The stack holds calendars in memory.
  • Operators pop one or two calendars and push the result back.
  • stack-swap and stack-drop only operate on the stack (no files).
  • Preflight validation enforces that the pipeline ends with an empty stack.

Operator reference

  • Overview: `[docs/overview.md]

Format conventions

  • Dates: YYYY-MM-DD
  • Times: H:MM or HH:MM (24h)
  • For load and save, - means stdin/stdout.
  • Supported formats: ICS (default), JSON (case-insensitive).
  • If --format is omitted, the format is inferred from the file extension.
  • When using stdin/stdout (-), the format defaults to ICS unless specified.

Installation

Build and install from source:

make prepare
make build
make install

Install with Go directly:

go install ./...

Build and test

Build binaries and templates:

make build

Run tests:

make test

References

Contributing

FIXME: Contributing guidelines are not yet documented. Please open an issue to discuss changes or submit a PR with context and tests where applicable.

License

GNU GPL-3.0