typeclaw 0.33.0 → 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/auth.schema.json +66 -0
- package/cron.schema.json +26 -2
- package/package.json +1 -1
- package/secrets.schema.json +66 -0
- package/src/agent/index.ts +7 -3
- package/src/agent/session-origin.ts +17 -0
- package/src/agent/subagent-completion-reminder.ts +14 -1
- package/src/agent/subagent-drain.ts +2 -0
- package/src/agent/subagents.ts +21 -7
- package/src/agent/tools/channel-disengage.ts +66 -0
- package/src/agent/tools/channel-log.ts +3 -2
- package/src/agent/tools/spawn-subagent.ts +25 -5
- package/src/agent/tools/subagent-output.ts +13 -1
- package/src/bundled-plugins/github-cli-auth/git-askpass.ts +65 -0
- package/src/bundled-plugins/github-cli-auth/git-command.ts +492 -0
- package/src/bundled-plugins/github-cli-auth/index.ts +97 -36
- package/src/bundled-plugins/guard/policies/managed-config.ts +1 -1
- package/src/bundled-plugins/memory/memory-logger.ts +7 -0
- package/src/bundled-plugins/researcher/researcher.ts +14 -11
- package/src/bundled-plugins/security/policies/outbound-secret-scan.ts +1 -0
- package/src/channels/adapters/line-channel-resolver.ts +129 -0
- package/src/channels/adapters/line-classify.ts +80 -0
- package/src/channels/adapters/line-format.ts +11 -0
- package/src/channels/adapters/line.ts +350 -0
- package/src/channels/engagement.ts +4 -2
- package/src/channels/manager.ts +65 -6
- package/src/channels/router.ts +186 -41
- package/src/channels/schema.ts +6 -1
- package/src/cli/channel.ts +112 -1
- package/src/cli/cron.ts +22 -4
- package/src/cli/oauth-callbacks.ts +5 -4
- package/src/config/providers.ts +62 -0
- package/src/cron/consumer.ts +33 -0
- package/src/cron/count-state.ts +208 -0
- package/src/cron/index.ts +4 -17
- package/src/cron/list.ts +24 -6
- package/src/cron/scheduler.ts +84 -9
- package/src/cron/schema.ts +100 -13
- package/src/doctor/channel-checks.ts +28 -0
- package/src/hostd/daemon.ts +14 -6
- package/src/hostd/protocol.ts +6 -2
- package/src/init/gitignore.ts +1 -1
- package/src/init/index.ts +36 -3
- package/src/init/line-auth.ts +98 -0
- package/src/init/models-dev.ts +1 -0
- package/src/init/run-owner-claim.ts +1 -0
- package/src/init/validate-api-key.ts +2 -0
- package/src/inspect/label.ts +1 -0
- package/src/permissions/match-rule.ts +28 -12
- package/src/permissions/resolve.ts +8 -1
- package/src/role-claim/match-rule.ts +5 -1
- package/src/run/index.ts +41 -4
- package/src/secrets/line-store.ts +112 -0
- package/src/secrets/oauth-xai.ts +1 -1
- package/src/secrets/schema.ts +25 -0
- package/src/server/index.ts +17 -4
- package/src/shared/protocol.ts +4 -1
- package/src/skills/typeclaw-channel-line/SKILL.md +46 -0
- package/src/skills/typeclaw-channels/SKILL.md +153 -0
- package/src/skills/typeclaw-config/SKILL.md +54 -184
- package/src/skills/typeclaw-config/references/dockerfile.md +66 -0
- package/src/skills/typeclaw-cron/SKILL.md +68 -14
- package/src/skills/typeclaw-permissions/SKILL.md +3 -3
- package/typeclaw.schema.json +167 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: typeclaw-cron
|
|
3
|
-
description: Use this skill whenever the user asks you to schedule recurring work, run something on a cron, do something every day/hour/week, set up a periodic task, list or inspect scheduled jobs, or read or edit your cron schedule. Triggers include "every morning", "every Monday", "schedule a", "remind me every", "set up a cron", "run X periodically", "list cron jobs", "list scheduled jobs", "show me the cron", "what cron jobs do you have", "what's on my cron", "when does X run", or any mention of `cron.json`. Read it before touching `cron.json` — the file has a strict schema, restart semantics, and a best-effort execution model that you must not misrepresent to the user.
|
|
3
|
+
description: Use this skill whenever the user asks you to schedule recurring work OR a one-off future task/reminder, run something on a cron, do something every day/hour/week, do something once at a future time, set up a periodic task, list or inspect scheduled jobs, or read or edit your cron schedule. Triggers include "every morning", "every Monday", "schedule a", "remind me every", "set up a cron", "run X periodically", "remind me in 3 days", "remind me tomorrow", "remind me at 9am", "remind me next Monday", "in N hours/days do X", "do X once at hh:mm", "stop after N times", "until <date>", "list cron jobs", "list scheduled jobs", "show me the cron", "what cron jobs do you have", "what's on my cron", "when does X run", or any mention of `cron.json`. Read it before touching `cron.json` — the file has a strict schema, restart semantics, and a best-effort execution model that you must not misrepresent to the user.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# typeclaw-cron
|
|
@@ -25,12 +25,17 @@ Tell the user this if they ask about reliability. Do not invent guarantees the r
|
|
|
25
25
|
|
|
26
26
|
### Shared fields (all jobs)
|
|
27
27
|
|
|
28
|
-
| Field | Required
|
|
29
|
-
| ---------- |
|
|
30
|
-
| `id` | yes
|
|
31
|
-
| `schedule` |
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
28
|
+
| Field | Required | Notes |
|
|
29
|
+
| ---------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
30
|
+
| `id` | yes | Unique. Letters, digits, hyphens, underscores. Used in logs and to coalesce. |
|
|
31
|
+
| `schedule` | one of these | Standard 5-field cron expression (`min hr dom mon dow`) or 6-field with seconds. Recurring. See "Schedule syntax" below. |
|
|
32
|
+
| `at` | one of these | One-shot ISO instant — fires **once** then retires. Mutually exclusive with `schedule`; set exactly one. See "One-shot reminders (`at`)" below. |
|
|
33
|
+
| `until` | no | Recurring only. Absolute ISO instant; last allowed fire (inclusive). The job retires after this. |
|
|
34
|
+
| `count` | no | Recurring only. Stop after N accepted fires. Coexists with `until` — whichever boundary is reached first wins. |
|
|
35
|
+
| `enabled` | no | Defaults to `true`. Set to `false` to keep a job in the file but skip it. |
|
|
36
|
+
| `timezone` | no | IANA name like `Asia/Seoul`. Recurring (`schedule`) only — NOT valid with `at`. Defaults to UTC (the container's timezone). |
|
|
37
|
+
|
|
38
|
+
**`schedule` XOR `at`:** every job has exactly one of `schedule` (recurring) or `at` (one-shot). Setting both, or neither, is rejected. `at` jobs may not set `until`, `timezone`, or `count` > 1 (the instant already pins the single fire).
|
|
34
39
|
|
|
35
40
|
### `kind: "prompt"` — fire a prompt into a fresh session
|
|
36
41
|
|
|
@@ -69,6 +74,49 @@ Use `exec` only for jobs that are pure mechanics — no judgement required. Exam
|
|
|
69
74
|
|
|
70
75
|
`command` is an array. Index 0 is the executable, the rest are argv. Do **not** put a single shell pipeline in `command[0]` — that won't be parsed by a shell. If you need shell features (`|`, `>`, `&&`), wrap explicitly: `["sh", "-c", "your | pipeline | here"]`.
|
|
71
76
|
|
|
77
|
+
## One-shot reminders and future tasks (`at`)
|
|
78
|
+
|
|
79
|
+
When the user wants something to happen **once at a future time** — "remind me in 3 days to cancel the subscription", "ping me tomorrow at 9", "in 2 hours, check if the build finished" — use `at` instead of `schedule`. The job fires exactly once at that instant, then retires (the scheduler stops arming it; it never fires again).
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"id": "cancel-sub",
|
|
84
|
+
"at": "2026-06-11T09:00:00+09:00",
|
|
85
|
+
"kind": "prompt",
|
|
86
|
+
"prompt": "Remind the user to cancel the subscription they mentioned on 2026-06-08. If they already handled it, say so and move on.",
|
|
87
|
+
"scheduledByRole": "owner"
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`at` works with any `kind` (`prompt` for "remind me / do this judgement task", `exec` for a one-off mechanical command). The same best-effort rules apply: if the container is down at the `at` instant, the fire is **lost, not replayed**. Say so if the user is relying on it for something important.
|
|
92
|
+
|
|
93
|
+
### The `at` value MUST carry an explicit zone or offset
|
|
94
|
+
|
|
95
|
+
`at` is parsed as an **absolute instant**, so it requires a trailing `Z` or a numeric offset. A bare local-time string is rejected (it would silently resolve to UTC and surprise the user).
|
|
96
|
+
|
|
97
|
+
- ✅ `2026-06-11T09:00:00+09:00` (Seoul morning) or `2026-06-11T00:00:00Z`
|
|
98
|
+
- ❌ `2026-06-11T09:00:00` (no zone — rejected by `parseCronFile`)
|
|
99
|
+
|
|
100
|
+
**The `at` instant must be in the future.** Writing an enabled `at` in the past is **rejected at write time** (the `reload`/guard validation returns `"at" is in the past`), because a past reminder would be retired immediately and never fire — a silent no-op the user would mistake for a scheduled reminder. If you get this error, recompute the instant (you probably botched the timezone offset) and write again. (An already-_fired_ one-shot left on disk is the one exception — it stays valid so it can't brick reload — but you never author one of those by hand.)
|
|
101
|
+
|
|
102
|
+
**Resolving "9am" / "tomorrow" / "in 3 days" to an instant:**
|
|
103
|
+
|
|
104
|
+
1. Get the user's timezone. Check `USER.md` for a recorded zone; if it's not there and the wall-clock matters, ask once.
|
|
105
|
+
2. Compute the absolute instant in that zone. "Remind me in 3 days" → take now, add 3×24h (or the next 09:00 in their zone if they said a time), and emit it with the zone's offset, e.g. `+09:00`.
|
|
106
|
+
3. Use `bash` (`date`) if you need to compute the offset precisely rather than guessing — e.g. `date -u -d '+3 days' +%Y-%m-%dT%H:%M:%SZ`. Don't hand-roll DST math.
|
|
107
|
+
|
|
108
|
+
Do not invent `until`, `timezone`, or `count` > 1 on an `at` job — they're rejected. The single instant is the whole schedule.
|
|
109
|
+
|
|
110
|
+
### Clean up after a one-shot fires (self-prune)
|
|
111
|
+
|
|
112
|
+
A fired `at` job does **not** delete itself from `cron.json` — it stays on disk as an inert, already-retired entry (the runtime never writes back to `cron.json`; that's by design). On its own this is harmless: the scheduler sees the past instant and retires it without firing, so it will not run again and will not break reload.
|
|
113
|
+
|
|
114
|
+
But to keep `cron.json` clean, **a one-shot `prompt` job should remove its own entry as the last step of its fire.** Because the fire runs in a full agent session with all your tools, end the reminder prompt with a self-cleanup instruction. Write your `prompt` so your future self does this:
|
|
115
|
+
|
|
116
|
+
> "... After delivering the reminder, remove the cron job with id `cancel-sub` from `cron.json` and call the `reload` tool so the dead one-shot doesn't linger."
|
|
117
|
+
|
|
118
|
+
Removing a job needs **no** `cronPromotion` ack — deletions pass the guard freely (only _adding_ a job or elevating its role requires `acknowledgeGuards`). If the cleanup is ever skipped (model error, crash mid-session), the worst case is a harmless leftover entry you can prune on any later edit — never a broken schedule. This self-prune only applies to `prompt` jobs; an `at` `exec` job has no LLM to clean up after itself, so its entry just lingers until a human or a later prompt removes it.
|
|
119
|
+
|
|
72
120
|
## `exec → LLM`: write a plugin cron handler (best practice)
|
|
73
121
|
|
|
74
122
|
If a scheduled job needs imperative control flow that mixes shell calls and LLM calls (probe → maybe prompt → write file), the best practice is a **plugin cron handler**: a TypeScript function the plugin registers under its own `cronJobs` with `kind: 'handler'`. The cron consumer invokes it directly — no shell-out, no WS round-trip, no `Bun.spawn`. Prefer this whenever the cadence and the logic both belong to the same plugin (which is almost always — see "When to reach for the exec bridge instead" below for the two narrow exceptions).
|
|
@@ -322,11 +370,13 @@ For every job you add:
|
|
|
322
370
|
|
|
323
371
|
- `id` is unique within the file
|
|
324
372
|
- `id` matches `[a-zA-Z0-9_-]+` (no spaces, no slashes, no dots)
|
|
325
|
-
- `schedule`
|
|
373
|
+
- Exactly one of `schedule` or `at` is set (never both, never neither)
|
|
374
|
+
- If recurring: `schedule` parses as cron
|
|
375
|
+
- If one-shot: `at` is a future ISO instant **with an explicit `Z` or numeric offset**, and `until`/`timezone`/`count` > 1 are absent
|
|
326
376
|
- `kind` is exactly `"prompt"` or `"exec"`
|
|
327
377
|
- If `prompt`: `prompt` is non-empty
|
|
328
378
|
- If `exec`: `command` is a non-empty array of non-empty strings
|
|
329
|
-
- If a wall-clock schedule was requested: `timezone` is set
|
|
379
|
+
- If a wall-clock `schedule` was requested: `timezone` is set
|
|
330
380
|
|
|
331
381
|
### Applying changes — the `reload` tool
|
|
332
382
|
|
|
@@ -345,19 +395,23 @@ If you finished an edit and the user only sees an in-flight job from the previou
|
|
|
345
395
|
- **Do not promise sub-second precision or guaranteed execution.** This is best-effort — see "What cron actually does" above.
|
|
346
396
|
- **Do not invent fields the schema doesn't support** (no `retry`, `timeout`, `onFailure`, `concurrency`, etc.). They will be silently ignored at best, or rejected at worst.
|
|
347
397
|
|
|
348
|
-
## When the user says "every X"
|
|
398
|
+
## When the user says "every X" or "do X once"
|
|
399
|
+
|
|
400
|
+
0. **Recurring or one-shot?** This is the first fork.
|
|
401
|
+
- **Recurring** ("every morning", "every Monday", "hourly") → use `schedule`. Continue with step 1 below.
|
|
402
|
+
- **One-shot / future task** ("remind me in 3 days", "tomorrow at 9", "in 2 hours", "do X once at hh:mm") → use `at` with an absolute instant (explicit zone/offset). See "One-shot reminders and future tasks (`at`)" above for resolving the instant and self-prune. Then pick the kind (almost always `prompt` for a reminder) and skip straight to step 4. Don't set `schedule`, `timezone`, `until`, or `count` on it.
|
|
349
403
|
|
|
350
|
-
|
|
404
|
+
For a **recurring** job:
|
|
351
405
|
|
|
352
406
|
1. **Pick the kind.**
|
|
353
407
|
- **Pure mechanics, no judgement** (git snapshots, log rotation, calling an existing script) → `kind: 'exec'` in `cron.json`. Done.
|
|
354
|
-
- **One
|
|
408
|
+
- **One natural-language instruction, no shell pre-work, no conditional logic** → `kind: 'prompt'` in `cron.json`. Done.
|
|
355
409
|
- **Imperative control flow mixing shell calls and LLM calls** (probe → maybe prompt → write file, "if there are new emails then triage", etc.) → **write a `kind: 'handler'` plugin cron job** (see "`exec → LLM`: write a plugin cron handler" above). This is the default for scheduled `exec → LLM` work.
|
|
356
410
|
- **Reuse a CLI command on a custom cadence** — the same logic must ALSO be invocable from the TUI / manual shell / `compose` orchestration, or the schedule is owned by the user (`cron.json`) rather than the plugin author, or the work must run as a `surface: 'host'` command → `kind: 'exec'` in `cron.json` with `command: ["typeclaw", "<plugin-command>", ...]`. Reach for this ONLY when reusability is the actual requirement, not just because the work is scheduled. See "When to reach for the exec bridge instead" above.
|
|
357
|
-
2. **Translate the cadence to cron.** "Every morning at 7" → `0 7 * * *`. "Every weekday at 9:30" → `30 9 * * 1-5`. "Every five minutes" → `*/5 * * * *`. If you are not sure, ask once. Don't guess on tricky cases like "every other Friday".
|
|
411
|
+
2. **Translate the cadence to cron.** "Every morning at 7" → `0 7 * * *`. "Every weekday at 9:30" → `30 9 * * 1-5`. "Every five minutes" → `*/5 * * * *`. If you are not sure, ask once. Don't guess on tricky cases like "every other Friday". If the user wants the recurrence to stop ("until end of quarter", "only 5 times"), add `until` (absolute ISO instant) and/or `count` (N fires).
|
|
358
412
|
3. **Timezone.** If the user mentioned a wall-clock time, set `timezone` to their zone. If unknown, ask once or default to the timezone in `USER.md` if it's recorded there.
|
|
359
413
|
4. **Pick a stable `id`.** Use kebab-case that describes the job, not the schedule. `daily-summary` not `0-23-30`.
|
|
360
|
-
5. **Write it. Call `reload`. If reload succeeded, commit it.** If reload failed, fix `cron.json` based on the error and retry — do not commit a broken file.
|
|
414
|
+
5. **Write it. Call `reload`. If reload succeeded, commit it.** If reload failed, fix `cron.json` based on the error and retry — do not commit a broken file. **Adding any new job (recurring or one-shot) requires `acknowledgeGuards: { cronPromotion: true }` in the write** — but never ack a job scheduled on behalf of a channel speaker asking to elevate themselves (see step 3 of "Editing `cron.json` safely").
|
|
361
415
|
|
|
362
416
|
## Listing what is currently scheduled
|
|
363
417
|
|
|
@@ -141,7 +141,7 @@ Probable causes, in descending order of frequency:
|
|
|
141
141
|
|
|
142
142
|
1. **No match rule covers the speaking author's coordinates.** Read `typeclaw.json` `roles`, compare every `match[]` entry to the channel ID and author ID the user is reporting. If nothing matches, the author resolves to `guest`, which has no `channel.respond`, so every inbound is dropped at the router. The fix is to append a match rule to `roles.<role>.match[]` for that channel (or DM bucket).
|
|
143
143
|
2. **The match rule exists but the role has `permissions: []`** (or otherwise lacks `channel.respond`). A user-declared role replaces the built-in's permissions wholesale. Re-add `channel.respond` or use a built-in role name (`member`, `trusted`, `owner`) that carries it by default.
|
|
144
|
-
3. **Engagement triggers are filtering admitted messages.** This is a different problem — the inbound was admitted by permissions but engagement (`channels.<adapter>.engagement.trigger`) decided not to wake you. See the `typeclaw-
|
|
144
|
+
3. **Engagement triggers are filtering admitted messages.** This is a different problem — the inbound was admitted by permissions but engagement (`channels.<adapter>.engagement.trigger`) decided not to wake you. See the `typeclaw-channels` skill for the engagement model.
|
|
145
145
|
|
|
146
146
|
To distinguish cause 1/2 from cause 3: if `typeclaw logs <container> -f` (host stage) shows `[channels] ... denied by permissions (channel.respond)`, it's a permissions problem. If it shows the message being admitted but no LLM call follows, it's engagement.
|
|
147
147
|
|
|
@@ -160,7 +160,7 @@ This is a `roles` edit. The full procedure:
|
|
|
160
160
|
Two interpretations — clarify if ambiguous:
|
|
161
161
|
|
|
162
162
|
- **"Stop everything"** — remove the match rule from `roles.<role>.match[]`. The author resolves to `guest`, and the channel router silently drops every inbound. You lose all visibility into their messages. Restart-required.
|
|
163
|
-
- **"Just stop auto-replying"** — keep the match rule, but narrow `channels.<adapter>.engagement.trigger` and/or `stickiness`. See `typeclaw-
|
|
163
|
+
- **"Just stop auto-replying"** — keep the match rule, but narrow `channels.<adapter>.engagement.trigger` and/or `stickiness`. See `typeclaw-channels`. The agent still receives the messages and can still post if you tell it to. The solo-human fallback (single human in a channel) overrides `trigger: []`, so this approach can't fully silence you in a 1:1; only removing the match rule does.
|
|
164
164
|
|
|
165
165
|
## When the user asks "what role am I in this session?"
|
|
166
166
|
|
|
@@ -192,7 +192,7 @@ If you see a cron job mysteriously failing every fire with `denied by permission
|
|
|
192
192
|
|
|
193
193
|
## What this skill does not cover
|
|
194
194
|
|
|
195
|
-
- **The `channels.<adapter>` block** — engagement, history, stickiness, alias. See `typeclaw-
|
|
195
|
+
- **The `channels.<adapter>` block behavior** — engagement, history, stickiness, alias matching. See `typeclaw-channels`. Engagement decides whether an _admitted_ inbound wakes the loop; this skill is only about admission. The `channels`/`alias` schema and edit mechanics live in `typeclaw-config`.
|
|
196
196
|
- **The full `typeclaw.json` schema** — model, mounts, plugins, docker, git.ignore. See `typeclaw-config`.
|
|
197
197
|
- **Cron job authoring** — schedule syntax, `prompt` vs `exec`, the `reload` tool. See `typeclaw-cron`. This skill only covers the `scheduledByRole` field and its provenance semantics.
|
|
198
198
|
- **Plugin authoring** — `definePlugin`, contributing permissions, custom `tool.before` hooks. See `typeclaw-plugins`. The bundled security plugin is an example of a plugin that contributes `security.bypass.*` strings and uses `permissions.has()` to gate its own guards.
|
package/typeclaw.schema.json
CHANGED
|
@@ -50,7 +50,9 @@
|
|
|
50
50
|
"minimax/MiniMax-M2.7",
|
|
51
51
|
"minimax/MiniMax-M2.5",
|
|
52
52
|
"minimax/MiniMax-M2.1",
|
|
53
|
-
"minimax/MiniMax-M2"
|
|
53
|
+
"minimax/MiniMax-M2",
|
|
54
|
+
"deepseek/deepseek-v4-flash",
|
|
55
|
+
"deepseek/deepseek-v4-pro"
|
|
54
56
|
]
|
|
55
57
|
},
|
|
56
58
|
{
|
|
@@ -87,7 +89,9 @@
|
|
|
87
89
|
"minimax/MiniMax-M2.7",
|
|
88
90
|
"minimax/MiniMax-M2.5",
|
|
89
91
|
"minimax/MiniMax-M2.1",
|
|
90
|
-
"minimax/MiniMax-M2"
|
|
92
|
+
"minimax/MiniMax-M2",
|
|
93
|
+
"deepseek/deepseek-v4-flash",
|
|
94
|
+
"deepseek/deepseek-v4-pro"
|
|
91
95
|
]
|
|
92
96
|
}
|
|
93
97
|
}
|
|
@@ -602,6 +606,166 @@
|
|
|
602
606
|
}
|
|
603
607
|
}
|
|
604
608
|
},
|
|
609
|
+
"line": {
|
|
610
|
+
"type": "object",
|
|
611
|
+
"properties": {
|
|
612
|
+
"engagement": {
|
|
613
|
+
"default": {
|
|
614
|
+
"trigger": [
|
|
615
|
+
"mention",
|
|
616
|
+
"reply",
|
|
617
|
+
"dm"
|
|
618
|
+
],
|
|
619
|
+
"stickiness": {
|
|
620
|
+
"perReply": {
|
|
621
|
+
"window": 900000
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
"type": "object",
|
|
626
|
+
"properties": {
|
|
627
|
+
"trigger": {
|
|
628
|
+
"default": [
|
|
629
|
+
"mention",
|
|
630
|
+
"reply",
|
|
631
|
+
"dm"
|
|
632
|
+
],
|
|
633
|
+
"type": "array",
|
|
634
|
+
"items": {
|
|
635
|
+
"type": "string",
|
|
636
|
+
"enum": [
|
|
637
|
+
"mention",
|
|
638
|
+
"reply",
|
|
639
|
+
"dm"
|
|
640
|
+
]
|
|
641
|
+
}
|
|
642
|
+
},
|
|
643
|
+
"stickiness": {
|
|
644
|
+
"default": {
|
|
645
|
+
"perReply": {
|
|
646
|
+
"window": 900000
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
"anyOf": [
|
|
650
|
+
{
|
|
651
|
+
"type": "string",
|
|
652
|
+
"const": "off"
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
"type": "object",
|
|
656
|
+
"properties": {
|
|
657
|
+
"perReply": {
|
|
658
|
+
"type": "object",
|
|
659
|
+
"properties": {
|
|
660
|
+
"window": {
|
|
661
|
+
"type": "integer",
|
|
662
|
+
"minimum": 1,
|
|
663
|
+
"maximum": 86400000
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
"required": [
|
|
667
|
+
"window"
|
|
668
|
+
]
|
|
669
|
+
}
|
|
670
|
+
},
|
|
671
|
+
"required": [
|
|
672
|
+
"perReply"
|
|
673
|
+
]
|
|
674
|
+
}
|
|
675
|
+
]
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
"history": {
|
|
680
|
+
"default": {
|
|
681
|
+
"prefetch": {
|
|
682
|
+
"thread": {
|
|
683
|
+
"head": 3,
|
|
684
|
+
"tail": 10
|
|
685
|
+
},
|
|
686
|
+
"channel": {
|
|
687
|
+
"tail": 10
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
},
|
|
691
|
+
"type": "object",
|
|
692
|
+
"properties": {
|
|
693
|
+
"prefetch": {
|
|
694
|
+
"default": {
|
|
695
|
+
"thread": {
|
|
696
|
+
"head": 3,
|
|
697
|
+
"tail": 10
|
|
698
|
+
},
|
|
699
|
+
"channel": {
|
|
700
|
+
"tail": 10
|
|
701
|
+
}
|
|
702
|
+
},
|
|
703
|
+
"type": "object",
|
|
704
|
+
"properties": {
|
|
705
|
+
"thread": {
|
|
706
|
+
"default": {
|
|
707
|
+
"head": 3,
|
|
708
|
+
"tail": 10
|
|
709
|
+
},
|
|
710
|
+
"type": "object",
|
|
711
|
+
"properties": {
|
|
712
|
+
"head": {
|
|
713
|
+
"default": 3,
|
|
714
|
+
"type": "integer",
|
|
715
|
+
"minimum": 0,
|
|
716
|
+
"maximum": 200
|
|
717
|
+
},
|
|
718
|
+
"tail": {
|
|
719
|
+
"default": 10,
|
|
720
|
+
"type": "integer",
|
|
721
|
+
"minimum": 0,
|
|
722
|
+
"maximum": 200
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
},
|
|
726
|
+
"channel": {
|
|
727
|
+
"default": {
|
|
728
|
+
"tail": 10
|
|
729
|
+
},
|
|
730
|
+
"type": "object",
|
|
731
|
+
"properties": {
|
|
732
|
+
"tail": {
|
|
733
|
+
"default": 10,
|
|
734
|
+
"type": "integer",
|
|
735
|
+
"minimum": 0,
|
|
736
|
+
"maximum": 200
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
},
|
|
744
|
+
"enabled": {
|
|
745
|
+
"default": true,
|
|
746
|
+
"type": "boolean"
|
|
747
|
+
},
|
|
748
|
+
"quotedReply": {
|
|
749
|
+
"default": {
|
|
750
|
+
"enabled": true,
|
|
751
|
+
"queueDelayMs": 10000
|
|
752
|
+
},
|
|
753
|
+
"type": "object",
|
|
754
|
+
"properties": {
|
|
755
|
+
"enabled": {
|
|
756
|
+
"default": true,
|
|
757
|
+
"type": "boolean"
|
|
758
|
+
},
|
|
759
|
+
"queueDelayMs": {
|
|
760
|
+
"default": 10000,
|
|
761
|
+
"type": "integer",
|
|
762
|
+
"minimum": 0,
|
|
763
|
+
"maximum": 9007199254740991
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
},
|
|
605
769
|
"kakaotalk": {
|
|
606
770
|
"type": "object",
|
|
607
771
|
"properties": {
|
|
@@ -1304,7 +1468,7 @@
|
|
|
1304
1468
|
"type": "array",
|
|
1305
1469
|
"items": {
|
|
1306
1470
|
"type": "string",
|
|
1307
|
-
"pattern": "^(tui|cron|subagent(:[a-z][a-z0-9-]*)?|\\*|(slack|discord|telegram|kakao|github):[^\\s]+)(\\s+[a-zA-Z][a-zA-Z0-9_]*:[^\\s]+)*$"
|
|
1471
|
+
"pattern": "^(tui|cron|subagent(:[a-z][a-z0-9-]*)?|\\*|(slack|discord|telegram|line|kakao|github):[^\\s]+)(\\s+[a-zA-Z][a-zA-Z0-9_]*:[^\\s]+)*$"
|
|
1308
1472
|
}
|
|
1309
1473
|
},
|
|
1310
1474
|
"permissions": {
|