Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions .agents/skills/use-ocis-cli/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: use-ocis-cli
description: Safely operate oCIS servers through the installed ocis command-line client. Use when an AI agent is asked to inspect, list, search, transfer, synchronize, share, restore, or administer files, Spaces, shares, users, or groups in oCIS. Do not use for developing the ocis-cli source code.
description: Safely operate oCIS servers through the installed ocis command-line client. Use when an AI agent is asked to inspect, list, search, transfer, synchronize, share, restore, manage notifications, or administer files, Spaces, shares, users, or groups in oCIS. Do not use for developing the ocis-cli source code.
---

# Use oCIS CLI
Expand Down Expand Up @@ -44,8 +44,8 @@ protocol-level work.
parse human-readable tables when structured output is available.
- Use read-only discovery commands such as `ls`, `stat`, `search`, `tree`,
`space list`, `share overview`, `federation connection list`, `trash list`,
and admin `list` or `info` commands to resolve names and IDs before changing
anything.
`notification list`, and admin `list` or `info` commands to resolve names and
IDs before changing anything.
- Interpret a remote path in the selected Space. Keep local filesystem paths and
remote oCIS paths distinct according to the command help.

Expand All @@ -61,6 +61,9 @@ protocol-level work.
file or folder is a separate explicit operation.
- Use `trash` for recoverable deletion management and `version` for historical
file versions.
- Use `notification list` and `notification info` to inspect unread events.
In oCIS, `notification dismiss` is the server's mark-as-read operation; it
does not delete the resource referenced by the notification.
- Use `admin` only when the user explicitly requests administration. A normal
user may not have permission; report authorization failures without trying to
bypass them.
Expand All @@ -82,7 +85,7 @@ Never add `--yes` merely to avoid a prompt. Use it only when the user has
explicitly authorized that exact operation. Do not silently overwrite files,
empty trash, permanently delete resources, disable or delete accounts, change
roles, accept federation invitations, remove federation connections, accept or
decline shares, or execute unreviewed batch input.
decline shares, clear all notifications, or execute unreviewed batch input.

## Protect authentication and secrets

Expand Down
14 changes: 14 additions & 0 deletions .agents/skills/use-ocis-cli/references/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ same command.
- Spaces
- Sharing
- Federation
- Notifications
- Metadata, trash, and versions
- Administration
- CLI utilities and global flags
Expand Down Expand Up @@ -116,6 +117,19 @@ An invitation token establishes identity trust; it does not share a resource.
Treat invitation tokens as secrets and never accept one without an explicit
user request.

## Notifications

| Command | Purpose |
| --- | --- |
| `notification list, notification ls` | List unread in-app notifications; optionally filter them with a search argument. |
| `notification info` | Inspect one unread notification by its opaque ID. |
| `notification dismiss, notification read` | Remove one or more notifications from the unread list. |
| `notification clear, notification read-all` | Remove every notification from the unread list after confirmation. |

In oCIS, dismissing is the server's mark-as-read operation. It does not delete
the resource mentioned by the notification. Preview dismissal or clearing with
`--dry-run`; never clear all notifications without an explicit user request.

## Metadata, trash, and versions

| Command | Purpose |
Expand Down
11 changes: 7 additions & 4 deletions .claude/skills/use-ocis-cli/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: use-ocis-cli
description: Safely operate oCIS servers through the installed ocis command-line client. Use when an AI agent is asked to inspect, list, search, transfer, synchronize, share, restore, or administer files, Spaces, shares, users, or groups in oCIS. Do not use for developing the ocis-cli source code.
description: Safely operate oCIS servers through the installed ocis command-line client. Use when an AI agent is asked to inspect, list, search, transfer, synchronize, share, restore, manage notifications, or administer files, Spaces, shares, users, or groups in oCIS. Do not use for developing the ocis-cli source code.
---

# Use oCIS CLI
Expand Down Expand Up @@ -44,8 +44,8 @@ protocol-level work.
parse human-readable tables when structured output is available.
- Use read-only discovery commands such as `ls`, `stat`, `search`, `tree`,
`space list`, `share overview`, `federation connection list`, `trash list`,
and admin `list` or `info` commands to resolve names and IDs before changing
anything.
`notification list`, and admin `list` or `info` commands to resolve names and
IDs before changing anything.
- Interpret a remote path in the selected Space. Keep local filesystem paths and
remote oCIS paths distinct according to the command help.

Expand All @@ -61,6 +61,9 @@ protocol-level work.
file or folder is a separate explicit operation.
- Use `trash` for recoverable deletion management and `version` for historical
file versions.
- Use `notification list` and `notification info` to inspect unread events.
In oCIS, `notification dismiss` is the server's mark-as-read operation; it
does not delete the resource referenced by the notification.
- Use `admin` only when the user explicitly requests administration. A normal
user may not have permission; report authorization failures without trying to
bypass them.
Expand All @@ -82,7 +85,7 @@ Never add `--yes` merely to avoid a prompt. Use it only when the user has
explicitly authorized that exact operation. Do not silently overwrite files,
empty trash, permanently delete resources, disable or delete accounts, change
roles, accept federation invitations, remove federation connections, accept or
decline shares, or execute unreviewed batch input.
decline shares, clear all notifications, or execute unreviewed batch input.

## Protect authentication and secrets

Expand Down
14 changes: 14 additions & 0 deletions .claude/skills/use-ocis-cli/references/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ same command.
- Spaces
- Sharing
- Federation
- Notifications
- Metadata, trash, and versions
- Administration
- CLI utilities and global flags
Expand Down Expand Up @@ -116,6 +117,19 @@ An invitation token establishes identity trust; it does not share a resource.
Treat invitation tokens as secrets and never accept one without an explicit
user request.

## Notifications

| Command | Purpose |
| --- | --- |
| `notification list, notification ls` | List unread in-app notifications; optionally filter them with a search argument. |
| `notification info` | Inspect one unread notification by its opaque ID. |
| `notification dismiss, notification read` | Remove one or more notifications from the unread list. |
| `notification clear, notification read-all` | Remove every notification from the unread list after confirmation. |

In oCIS, dismissing is the server's mark-as-read operation. It does not delete
the resource mentioned by the notification. Preview dismissal or clearing with
`--dry-run`; never clear all notifications without an explicit user request.

## Metadata, trash, and versions

| Command | Purpose |
Expand Down
14 changes: 12 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ internal/
graph/ LibreGraph Spaces, directory, and permission client
httpapi/ authenticated retrying HTTP transport
logging/ opt-in diagnostic logging abstraction
notifications/ authenticated oCIS userlog/OCS notification client
output/ terminal and JSON/JSONL rendering
retry/ shared bounded retry and backoff policy
search/ WebDAV search-files REPORT client and response mapping
Expand Down Expand Up @@ -57,6 +58,7 @@ without starting a subprocess.
`batch_service.go`, `filesystem_service.go`, `filesystem_tree_service.go`,
`filesystem_du_service.go`, `filesystem_touch_service.go`,
`filesystem_walk.go`, `metadata_service.go`,
`notification_service.go`,
`share_overview_service.go`,
`space_member_service.go`, `space_update_service.go`,
`space_lifecycle_service.go`, and
Expand Down Expand Up @@ -87,6 +89,10 @@ without starting a subprocess.
- `internal/httpapi`: send replayable authenticated API requests with bounded
retries for non-WebDAV protocols, using the shared `internal/retry` policy.
- `internal/logging`: provide an injected no-op or text diagnostic logger.
- `internal/notifications`: list and dismiss the authenticated user's unread
in-app notifications through the bounded oCIS userlog OCS API. It does not
invent a separate read state: dismissing is the server's mark-as-read
operation.
- `internal/output`: render human-readable output and versioned JSON/JSONL
envelopes through injected writers.
- `internal/retry`: decide which responses may be retried and how long to wait,
Expand Down Expand Up @@ -130,8 +136,9 @@ without starting a subprocess.
scalar custom-property `PROPFIND`/`PROPPATCH` operations.

Protocol-specific behavior belongs in dedicated `internal/auth`,
`internal/federation`, `internal/graph`, `internal/search`, `internal/sharing`,
`internal/trash`, `internal/versions`, and `internal/webdav` adapters. Recursive local/remote
`internal/federation`, `internal/graph`, `internal/notifications`,
`internal/search`, `internal/sharing`, `internal/trash`, `internal/versions`,
and `internal/webdav` adapters. Recursive local/remote
traversal belongs in `internal/transfer`.

Configuration, credentials, protected upload-session storage, named sync jobs,
Expand Down Expand Up @@ -169,6 +176,9 @@ Fast package tests remain Docker-independent.
resolve only server-returned users of type `Federated` using the exact oCIS
Graph filter. Federated roles are requested from the server separately from
local-user roles.
- Clearing all unread notifications requires explicit intent in both the Cobra
and application layers. Dismissal resolves every requested opaque ID against
the authenticated user's current unread list before changing server state.
- Space names and aliases are convenience selectors. Destructive operations
on disabled Spaces use stable IDs.
- Server-advertised permissions and roles are authoritative; the CLI does not
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ check: fmt

coverage:
go run ./tools/covercheck -min $(COVERAGE_MIN) \
app auth federation graph httpapi retry search sharing sync trash transfer versions \
app auth federation graph httpapi notifications retry search sharing sync trash transfer versions \
webdav

fmt:
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,44 @@ sharing restrictions, and resource permissions. A user may be able to read a
file without being allowed to share it, update a share, or remove another
user's permission.

## Notifications

List and inspect the authenticated user's unread in-app notifications:

```sh
ocis notification list
ocis notification list report
ocis notification info NOTIFICATION_ID
ocis --json notification list
```

The optional `list` argument searches locally across the notification ID,
actor, subject, message, application, and related object. Human output shows
the newest notifications first; JSON and JSONL retain the full mapped server
record for automation.

In oCIS, marking a notification as read removes it from the unread userlog.
The CLI calls that operation `dismiss`; `read` is an equivalent alias. It does
not delete a file, share, or other referenced resource:

```sh
ocis notification dismiss NOTIFICATION_ID --dry-run
ocis notification dismiss NOTIFICATION_ID
ocis notification read NOTIFICATION_ID
```

Multiple IDs are dismissed in one server request. Clearing the complete unread
list is explicit, prompts for confirmation, and can be previewed safely:

```sh
ocis notification clear --dry-run
ocis notification clear
```

The server controls which events create notifications and whether its
notification service is enabled. These commands manage only notifications
visible to the currently selected CLI profile.

## Machine-readable output

`--json` writes one indented result and `--jsonl` writes one compact record per
Expand Down
37 changes: 37 additions & 0 deletions internal/app/notification_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package app

import "context"

// NotificationOperation identifies an unread-notification use case.
type NotificationOperation string

const (
NotificationList NotificationOperation = "list"
NotificationInfo NotificationOperation = "info"
NotificationDismiss NotificationOperation = "dismiss"
NotificationClear NotificationOperation = "clear"
)

// NotificationRequest describes one notification operation.
type NotificationRequest struct {
Operation NotificationOperation
IDs []string
Search string
Confirmed bool
DryRun bool
}

// RunNotificationWithOptions manages unread in-app notifications.
func RunNotificationWithOptions(
ctx context.Context,
request NotificationRequest,
selectedProfile string,
options RunOptions,
) error {
return classifyProtocolError(
"notification "+string(request.Operation),
runNotification(
ctx, request, selectedProfile, options.normalized(),
),
)
}
Loading