Skip to content
Open
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
5 changes: 3 additions & 2 deletions packaging/src/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ export const setDependencies = sdk.setupDependencies(async ({ effects }) => {
await sdk.action.createTask(effects, 'dependency-id', someAction, 'critical', {
input: {
kind: 'partial',
value: { /* fields matching the action's input spec */ },
accept: [{ /* one or more acceptable partial inputs */ }],
set: { /* the value to pre-fill when none are accepted */ },
},
when: { condition: 'input-not-matches', once: false },
reason: i18n('Human-readable reason shown to user'),
Expand All @@ -88,7 +89,7 @@ sdk.action.createTask(
action: ActionDefinition, // imported from the dependency package
severity: 'critical' | 'high' | 'medium' | 'low',
options?: {
input?: { kind: 'partial', value: Partial<InputSpec> },
input?: { kind: 'partial', accept: Partial<InputSpec>[], set: Partial<InputSpec> },
when?: { condition: 'input-not-matches', once: boolean },
reason: string,
replayId?: string, // prevents duplicate task execution
Expand Down
2 changes: 1 addition & 1 deletion packaging/src/recipe-enforce-dependency.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Sometimes your service requires specific configuration on a dependency — Bitco

## Solution

In `setupDependencies()`, call `sdk.action.createTask()` targeting the dependency's autoconfig action (imported from the dependency's package). Pass `input: { kind: 'partial', value: { ... } }` with the required field values, and `when: { condition: 'input-not-matches', once: false }` so the task re-fires whenever the dependency's config drifts. The autoconfig action must be exported by the dependency and added to your `package.json` dependencies.
In `setupDependencies()`, call `sdk.action.createTask()` targeting the dependency's autoconfig action (imported from the dependency's package). Pass `input: { kind: 'partial', accept: [{ ... }], set: { ... } }` — `accept` lists the partial inputs that satisfy the task and `set` is pre-filled when none match — and `when: { condition: 'input-not-matches', once: false }` so the task re-fires whenever the dependency's config drifts. The autoconfig action must be exported by the dependency and added to your `package.json` dependencies.

**Reference:** [Dependencies](dependencies.md) · [Tasks](tasks.md)

Expand Down
9 changes: 6 additions & 3 deletions packaging/src/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ export const setDependencies = sdk.setupDependencies(async ({ effects }) => {
await sdk.action.createTask(effects, 'dependency-id', someAction, 'critical', {
input: {
kind: 'partial',
value: { /* fields matching the action's input spec */ },
accept: [{ /* one or more acceptable partial inputs */ }],
set: { /* the value to pre-fill when none are accepted */ },
},
when: { condition: 'input-not-matches', once: false },
reason: i18n('Configure the dependency for use with this service'),
Expand Down Expand Up @@ -98,11 +99,13 @@ export const setDependencies = sdk.setupDependencies(async ({ effects }) => {

| Field | Type | Description |
| ---------- | ----------------------------------------------------- | ---------------------------------------------------------------- |
| `input` | `{ kind: 'partial', value: Partial<InputSpec> }` | Pre-fill fields in the action's input form |
| `when` | `{ condition: 'input-not-matches', once: boolean }` | Re-trigger until the action's input matches the provided values |
| `input` | `{ kind: 'partial', accept: Partial<InputSpec>[], set: Partial<InputSpec> }` | `accept` lists the partial inputs that satisfy the task; `set` pre-fills the action's input form when none of them match |
| `when` | `{ condition: 'input-not-matches', once: boolean }` | Re-trigger until the action's input matches one of the `accept` values |
| `reason` | `string` | Human-readable explanation shown to the user |
| `replayId` | `string` (optional) | Overrides the default idempotency key (see below) |

With `condition: 'input-not-matches'`, the task is **satisfied** when the action's current input is a superset of **any** entry in `accept` (each entry is matched partially — only the fields you list must agree). When none match, the task is shown and the action form is pre-filled with `set`. Use multiple `accept` entries to tolerate several already-good configurations while still steering the user to one recommended value; for the common case where any value but one specific target is unacceptable, pass a single `accept` entry equal to `set`.

> [!NOTE]
> The dependency must be listed in your `package.json` so the action can be imported (e.g., `"synapse-startos": "file:../synapse-wrapper"`). See [Dependencies](./dependencies.md) for more on cross-service integration.

Expand Down