@timqi/pier 0.1.3 → 0.1.4

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.
Files changed (97) hide show
  1. package/README.md +8 -3
  2. package/dist/agent/config.js +9 -3
  3. package/dist/agent/events.js +1 -2
  4. package/dist/agent/packages.js +1 -7
  5. package/dist/agent/pi.js +6 -47
  6. package/dist/channels/config.js +30 -20
  7. package/dist/channels/routes.js +0 -3
  8. package/dist/channels/slack-api.js +19 -10
  9. package/dist/channels/slack-cli.js +503 -0
  10. package/dist/channels/slack-directory.js +2 -2
  11. package/dist/channels/slack-outbound.js +1 -1
  12. package/dist/channels/slack-thread.js +41 -0
  13. package/dist/channels/slack-transcript.js +107 -0
  14. package/dist/channels/slack.js +9 -17
  15. package/dist/channels/types.js +0 -1
  16. package/dist/cli.js +158 -7
  17. package/dist/core/identity.js +20 -11
  18. package/dist/core/reply.js +16 -15
  19. package/dist/core/router.js +4 -1
  20. package/dist/db.js +28 -0
  21. package/dist/main.js +19 -32
  22. package/dist/paths.js +3 -0
  23. package/dist/secrets.js +2 -1
  24. package/dist/socket.js +95 -0
  25. package/dist/tasks/agent.js +5 -6
  26. package/dist/tasks/callbacks.js +2 -2
  27. package/dist/tasks/cli.js +215 -0
  28. package/dist/tasks/definitions.js +3 -3
  29. package/dist/tasks/execution.js +1 -3
  30. package/dist/tasks/groups.js +2 -5
  31. package/dist/tasks/messages.js +18 -158
  32. package/dist/tasks/operations.js +323 -0
  33. package/dist/tasks/routes.js +1 -11
  34. package/dist/tasks/runs.js +5 -20
  35. package/dist/tasks/service.js +18 -43
  36. package/dist/tasks/store.js +15 -15
  37. package/dist/tools.js +17 -0
  38. package/dist/vault.js +107 -0
  39. package/dist/web/auth.js +2 -1
  40. package/dist/web/public/assets/{activity-BSMeRcN2.js → activity-NLS8W9yl.js} +2 -2
  41. package/dist/web/public/assets/activity-NLS8W9yl.js.br +0 -0
  42. package/dist/web/public/assets/activity-NLS8W9yl.js.gz +0 -0
  43. package/dist/web/public/assets/{boards-BCWQMZry.js → boards-DleegoiC.js} +1 -1
  44. package/dist/web/public/assets/boards-DleegoiC.js.br +0 -0
  45. package/dist/web/public/assets/boards-DleegoiC.js.gz +0 -0
  46. package/dist/web/public/assets/{explorer-Cr4XTi4j.js → explorer-vJvV1Sx0.js} +1 -1
  47. package/dist/web/public/assets/explorer-vJvV1Sx0.js.br +0 -0
  48. package/dist/web/public/assets/explorer-vJvV1Sx0.js.gz +0 -0
  49. package/dist/web/public/assets/{index-DVIt5Gio.css → index-Bs-gol9o.css} +1 -1
  50. package/dist/web/public/assets/index-Bs-gol9o.css.br +0 -0
  51. package/dist/web/public/assets/{index-DVIt5Gio.css.gz → index-Bs-gol9o.css.gz} +0 -0
  52. package/dist/web/public/assets/index-Cyp2DKKF.js +85 -0
  53. package/dist/web/public/assets/index-Cyp2DKKF.js.br +0 -0
  54. package/dist/web/public/assets/index-Cyp2DKKF.js.gz +0 -0
  55. package/dist/web/public/assets/{runs-DdERzeac.js → runs-C5FveZ75.js} +1 -1
  56. package/dist/web/public/assets/runs-C5FveZ75.js.br +0 -0
  57. package/dist/web/public/assets/runs-C5FveZ75.js.gz +0 -0
  58. package/dist/web/public/assets/settings-nJHIBbAz.js +5 -0
  59. package/dist/web/public/assets/settings-nJHIBbAz.js.br +0 -0
  60. package/dist/web/public/assets/settings-nJHIBbAz.js.gz +0 -0
  61. package/dist/web/public/assets/{task-runs-C-dGUDsH.js → task-runs-CJJ2j5Ks.js} +1 -1
  62. package/dist/web/public/assets/task-runs-CJJ2j5Ks.js.br +0 -0
  63. package/dist/web/public/assets/task-runs-CJJ2j5Ks.js.gz +0 -0
  64. package/dist/web/public/assets/{tasks-CY30H1u1.js → tasks-R2Pv0Abg.js} +1 -1
  65. package/dist/web/public/assets/tasks-R2Pv0Abg.js.br +0 -0
  66. package/dist/web/public/assets/tasks-R2Pv0Abg.js.gz +0 -0
  67. package/dist/web/public/index.html +2 -2
  68. package/dist/web/public/index.html.br +0 -0
  69. package/dist/web/public/index.html.gz +0 -0
  70. package/dist/web/vault.js +68 -0
  71. package/docs/deploy.md +33 -10
  72. package/package.json +1 -1
  73. package/skills/pier-help/SKILL.md +10 -6
  74. package/skills/pier-slack/SKILL.md +52 -71
  75. package/skills/pier-tasks/SKILL.md +48 -145
  76. package/skills/pier-vault/SKILL.md +36 -0
  77. package/dist/channels/slack-tool.js +0 -416
  78. package/dist/tasks/tool.js +0 -416
  79. package/dist/web/public/assets/activity-BSMeRcN2.js.br +0 -0
  80. package/dist/web/public/assets/activity-BSMeRcN2.js.gz +0 -0
  81. package/dist/web/public/assets/boards-BCWQMZry.js.br +0 -0
  82. package/dist/web/public/assets/boards-BCWQMZry.js.gz +0 -0
  83. package/dist/web/public/assets/explorer-Cr4XTi4j.js.br +0 -0
  84. package/dist/web/public/assets/explorer-Cr4XTi4j.js.gz +0 -0
  85. package/dist/web/public/assets/index-C7tA0Ufu.js +0 -85
  86. package/dist/web/public/assets/index-C7tA0Ufu.js.br +0 -0
  87. package/dist/web/public/assets/index-C7tA0Ufu.js.gz +0 -0
  88. package/dist/web/public/assets/index-DVIt5Gio.css.br +0 -0
  89. package/dist/web/public/assets/runs-DdERzeac.js.br +0 -0
  90. package/dist/web/public/assets/runs-DdERzeac.js.gz +0 -0
  91. package/dist/web/public/assets/settings-CQDAHoMM.js +0 -5
  92. package/dist/web/public/assets/settings-CQDAHoMM.js.br +0 -0
  93. package/dist/web/public/assets/settings-CQDAHoMM.js.gz +0 -0
  94. package/dist/web/public/assets/task-runs-C-dGUDsH.js.br +0 -0
  95. package/dist/web/public/assets/task-runs-C-dGUDsH.js.gz +0 -0
  96. package/dist/web/public/assets/tasks-CY30H1u1.js.br +0 -0
  97. package/dist/web/public/assets/tasks-CY30H1u1.js.gz +0 -0
@@ -1,88 +1,69 @@
1
1
  ---
2
2
  name: pier-slack
3
- description: Read and write Slack through Pier's slack tool, including the Slack-specific syntax for mentions and links. Read before answering questions about Slack conversations or posting anything to a workspace.
3
+ description: Slack from the shell with `pier slack` — read, post, edit, files — and Slack's mention syntax. Read before reading or posting to Slack.
4
4
  ---
5
5
 
6
- # Writing Slack correctly
6
+ # Slack from the shell
7
7
 
8
- The tool description lists the operations and parameters. This is what goes
9
- wrong without instructions.
8
+ `pier slack --help` lists the subcommands (`whoami`, `channels`, `user`,
9
+ `history`, `thread`, `message`, `permalink`, `file`, `upload`, `post`,
10
+ `edit`, `delete`, `react`) and their flags. There is no Slack tool. The token
11
+ is the vault's (`SLACK_TOKEN`); an `approve`-level one may pause the command
12
+ until the operator approves. A `vault:` line is the pier-vault skill's.
10
13
 
11
- ## Markdown is not Slack syntax
12
-
13
- `text` is **standard markdown** and Slack renders it natively: `**bold**`,
14
- `_italic_`, `` `code` ``, fences, headings, lists, tables, blockquotes. Never
15
- hand-convert to the older mrkdwn `*bold*` — it renders literally.
14
+ Where you are: the first speaker header ends `slack:<channel>/<thread_ts>`;
15
+ without it, name a channel explicitly.
16
16
 
17
- Four things markdown cannot express:
18
-
19
- | Intent | Write | Not |
20
- | --- | --- | --- |
21
- | Mention a person | `<@U04B7Q2>` | `@alice` — plain text, pings nobody |
22
- | Link a channel | `<#C0123456>` | `#general` — plain text |
23
- | Notify the channel | `<!here>`, `<!channel>` | `@here` — plain text |
24
- | Hyperlink | `[label](https://…)` | — |
17
+ - `<channel>` is an id, `#name`, or a pasted message link, which also
18
+ supplies `<ts>` and the thread: `thread <link>`, `post <link> "text"`.
19
+ - Times: ISO 8601 (naive = local), epoch seconds, or a `ts`. `--after` is
20
+ strictly newer; the transcript header's `last <ts>` is your next `--after`.
21
+ - A wide range belongs on disk: `history … --threads --out raw.txt`, then
22
+ read pieces. `--json` is for scripts, not for you.
23
+ - 11 000 chars per message; split across replies in one thread.
24
+ - Slack's failures are one `slack: <method>: <code>` line: `not_in_channel` →
25
+ someone `/invite`s the bot; `channel_not_found` → see `channels`;
26
+ `missing_scope` → the operator reinstalls the app (on `channels` it means no
27
+ `im:read`/`mpim:read`; ids still work); `cant_update_message` → not yours.
28
+ Pier's own checks are `slack: channel|ts|time|user: <why>`.
25
29
 
26
- - **Never guess an id from a name.** A wrong `<@U…>` fails or pings a stranger,
27
- and both look like it worked. With no id, write the person's name as prose.
28
- - **You already have the ids** — the sender header on the message you are
29
- answering, `name[id]` on every transcript line, `context` for this channel and
30
- thread. Asking a human to paste their own user ID is never acceptable.
31
- - Escape `&` `<` `>` when they are text, not markup: `&amp;` `&lt;` `&gt;`.
32
- - Emoji as `:white_check_mark:`, not the raw glyph.
33
- - 11,000 chars per message; the tool refuses longer `text`. Split longer
34
- content across replies in one thread rather than truncating.
30
+ ## Transcript format
35
31
 
36
- ## Targeting
32
+ ```
33
+ # C079TC7GUBG 2024-06-01 00:00 → now · +0800 · 41 messages · last 1717.000400
34
+ 09:12 ada: the db is on fire [thread 3 · 1717.000100] [file log.txt F1 2KB]
35
+ 09:14 bob: restarting it [edited] [:eyes: 2]
36
+ ```
37
37
 
38
- - Omitting `channel`/`thread_ts` means "here" — the conversation that reached
39
- you. `context` names it; `inSlack:false` means a task, subagent or web session
40
- started this, so `channel` is required.
41
- - `channels` lists what Pier can reach; an id or a `#name` works anywhere a
42
- channel is wanted.
43
- - `thread_ts:"none"` is the only way to a new top-level message — a channel's
44
- main flow is wider than a thread. A `thread_ts` is never inherited across a
45
- change of `channel`.
46
- - A `ts` means nothing outside the conversation it was read in, and `edit` /
47
- `delete` always take it explicitly — no default from the thread you are in.
38
+ A date line when the day changes; replies indented under `--threads`.
39
+ Markers: `[edited]`, `[thread N · <ts>]` on a parent, `[in thread <ts>]` on
40
+ a reply met in the channel, `[file <name> <F…> <size>]`, `[:emoji: N]`,
41
+ `[attachment: t]`/`[blocks]` for empty text. `--ts` prefixes each line with
42
+ its `ts` (what `thread`, `edit`, `--after` take); `--ids` renders `name[id]`.
48
43
 
49
- ## Reading
44
+ ## Markdown is not Slack syntax
50
45
 
51
- - A channel read returns thread **parents** only; `[thread: N replies]` marks
52
- the ones worth a `read_thread`.
53
- - `read_message` also needs `thread_ts` when the message was posted inside a
54
- thread — a channel read cannot see thread replies.
55
- - The leading `ts` on a line is Slack's id: pass it back as `thread_ts` or
56
- `after`. `after` is strictly newer, for re-reading without seeing what you
57
- already saw.
58
- - `truncated` → narrow the range rather than raising `limit` (default and max
59
- 400). `incomplete` → the read stopped early for the reason given; work with a
60
- partial answer, but never report it as everything.
61
- - Resolve a vague time ("yesterday") to an explicit ISO range and say which
62
- range you used.
46
+ `text` is standard markdown (never mrkdwn `*bold*`). Beyond it:
63
47
 
64
- ## Files
48
+ | Intent | Write | Not |
49
+ | --- | --- | --- |
50
+ | Mention a person | `<@U04B7Q2>` | `@alice` — pings nobody |
51
+ | Link a channel | `<#C0123456>` | `#general` |
52
+ | Notify the channel | `<!here>`, `<!channel>` | `@here` |
53
+ | `& < >` as text | `&amp; &lt; &gt;` | |
65
54
 
66
- `[file: <name> <F… id> <size>]` on a line is an upload, never its bytes.
67
- `fetch_file` with that `F…` id (no `channel` needed) saves it and replies with a
68
- marker line — `[postmortem.pdf](file:///…)` — so you read it only if the
69
- question needs its contents. Over 32 MB or refused by Slack: `[attachment lost:
70
- <name> — <reason>]`.
55
+ **Never guess an id**: a wrong `<@U…>` pings a stranger. Ids come from the
56
+ speaker header, `--ids` or `user`; never ask a human for theirs.
71
57
 
72
58
  ## Rules
73
59
 
74
- - Read before you write. A summary of the wrong thread is worse than none.
75
- - **In a busy thread, say nothing unless you are needed.** You are handed every
76
- message, including humans talking to each other. `<silent>why</silent>` sends
77
- nothing at all — prefer it to acknowledging what was not addressed to you.
78
- - `edit` replaces `text` outright; read the message first if you are changing
79
- part of it. Slack keeps no version a reader can open and may not mark the
80
- message as edited, so when the previous wording mattered to people, say what
81
- changed instead of quietly rewriting history. A running status or tally is
82
- better as one message edited in place than one message per change.
83
- - `delete` cannot be undone, and deleting a thread parent leaves its replies.
84
- Say what you removed; a message vanishing with no word looks like a bug.
85
- - Never post credentials, tokens or file contents you were not asked to share:
86
- a channel is usually wider than the conversation you are in.
87
- - "Slack agent access is switched off" means the operator disabled it on
88
- purpose. Say so and stop; do not look for another route.
60
+ - **Reply in the thread you were reached in** (`--thread <thread_ts>`); a
61
+ top-level post is a stated choice.
62
+ - **Edit and delete only what you posted** (`whoami`); `edit` replaces the
63
+ whole text, `delete` has no undo.
64
+ - **Your reply is itself a new message** in this thread — even a `<silent>`
65
+ turn posts one muted footer line — so you cannot leave the thread with none
66
+ of your messages; say so once.
67
+ - **In a busy thread say nothing unless needed**: `<silent>why</silent>`.
68
+ - Never post credentials or file contents you were not asked to share: a
69
+ channel is wider than this conversation.
@@ -1,170 +1,73 @@
1
1
  ---
2
2
  name: pier-tasks
3
- description: Delegate work to Pier subagents with the task tool — one-shot, parallel fan-out, chains, mid-run control. Read before delegating to a subagent, coordinating agents, or running long background work.
3
+ description: Subagents and scheduled tasks with `pier task`. Read before delegating work, coordinating agents, or scheduling anything.
4
4
  ---
5
5
 
6
6
  # Pier tasks
7
7
 
8
- ## Delegate, then wait
8
+ `pier task --help` lists the five commands and their flags. Each prints one
9
+ JSON receipt, exit 0; a refusal is a `task:` line, exit 1 (`--model` with no
10
+ or several hits lists the menu under it); a bad flag is `task:` plus the
11
+ usage, exit 2. `--prompt -` reads stdin.
9
12
 
10
- ```json
11
- {"operation":"run","prompt":"Review src/auth/*.ts. Return file:line, issue, fix."}
12
- ```
13
+ ## Delegate, then end your turn
13
14
 
14
- One concern per child. `run` with `prompt` or a full `task` draft atomically
15
- creates a persisted one-shot (`kind:"subagent"`, hidden from `list`); do not
16
- `create` it. Name defaults to the prompt's first line; `name` overrides it.
17
-
18
- All operations return immediately. Results and decision replies arrive by
19
- callback; **end your turn after launching work**. Default callbacks are system
20
- follow-ups, batched when several are due. A long turn delays them; there is no
21
- status query. The receipt's `next` tells you where/how delivery happens:
22
-
23
- - `callback:"origin"` (default): result returns to you after your turn.
24
- - `callback:"steer"`: interrupts at a step boundary; use when needed mid-turn,
25
- not for work you launch and forget. Receipt echoes `callbackMode`.
26
- - `callback:"none"`: no delivery; means you do not want the result, not pull later.
27
- - Single-run `callback_session_id`: deliver to another existing session.
28
- Top-level sessions only, and never with `callback:"none"` or `tasks[]`;
29
- inside a run it is refused, so your result always returns to you.
30
-
31
- Receipts include `runId`, `taskId`, state. Keep IDs: the callback also names
32
- `Run:`, and there is no lookup by task. `triggerSource` names the actual invoker
33
- (`agent/manual/cron/watch/task`); the definition's `trigger` is scheduling
34
- policy (`manual` means on demand).
35
-
36
- ## Sessions and prompts
37
-
38
- - Default `fresh`: clean context. `cwd` defaults to your directory, accepts an
39
- absolute path or one relative to yours, and must exist.
40
- - `reuse`: existing session by `sessionId`; continues its history after it is
41
- idle. `launch` applies only to fresh sessions; reused sessions own their
42
- model/tools. Children otherwise have your tools, including `task`.
43
- - **The prompt is the handoff**: no implicit copy of your discussion. Include
44
- the goal, current decisions, latest constraints, absolute paths, acceptance
45
- criteria, verification and output format. `input` accepts any JSON, appended
46
- in `<task_input>`.
47
- - For more work on an existing result, `resume` that run with a delta prompt;
48
- its session/context survives. Start fresh for unrelated work or stale context.
49
- - Stored role: `run` with `task_id` and optional `input`;
50
- `session_mode:"fresh"` overrides a stored reuse policy. Archived tasks refuse.
51
-
52
- `timeoutSeconds` also works in the shorthand and in a `tasks[]` entry; use a
53
- `task` draft for reuse:
54
-
55
- ```json
56
- {"operation":"run","task":{"timeoutSeconds":7200,"action":{"type":"agent","session":{"mode":"reuse","sessionId":"..."},"prompt":"Check the result"}}}
15
+ ```sh
16
+ pier task run --prompt "Review src/auth/*.ts. Return file:line, issue, fix."
57
17
  ```
58
18
 
59
- Inline drafts may omit `trigger`; only `manual` is allowed. A nested
60
- `callback` is refused: use the top-level delivery options above. Nested
61
- callbacks matter for saved schedules (below).
62
-
63
- ## Groups and chains
19
+ The prompt is the whole handoff (goal, constraints, absolute paths, output
20
+ format); the child sees nothing of your conversation. `--cwd` defaults to
21
+ yours; `--timeout` (default 3600 s) starts when the run does.
64
22
 
65
- `tasks[]` needs 2+ entries: prompt strings,
66
- `{prompt,cwd?,launch?,name?,timeoutSeconds?}`, full drafts, or `{task_id}`. Do not combine it with `task`, `task_id` or `session_mode`.
67
-
68
- ```json
69
- {"operation":"run","tasks":["Review correctness","Review test gaps"],"join":"all"}
70
- ```
23
+ **Callbacks are the only delivery; there is no status query.** The result
24
+ arrives as a system message once your turn ends, so **end your turn after
25
+ launching** — never poll. Keep the receipt's `runId`; the callback names
26
+ `Run:`. `--callback steer` interrupts your running turn instead; `none`
27
+ drops the result; `--callback-session <id>` delivers elsewhere.
71
28
 
72
- - `join:"all"` (default): one callback with every member's name, state and result
73
- when all are terminal.
74
- - `join:"first"`: first **any terminal state**, including failure/overlap skip,
75
- wins. Others are cancelled; their sessions remain resumable, IDs in callback.
76
- - Core owns the join; never hand-aggregate member IDs across turns. Members have
77
- no individual callbacks; `none`/`steer` applies to the group. `cancel` and
78
- `recover` accept `group_id`. Admission failure (e.g. limit or missing cwd)
79
- rolls back the group: nothing runs.
29
+ | Flags | Run |
30
+ | --- | --- |
31
+ | `--task-id <id>` | a saved definition, as is |
32
+ | `--session <id> --prompt …` | continue an idle session (it keeps its cwd and model) |
33
+ | `--run <id> --prompt …` | existing run: running → steer; `--after` → after its turn; finished → resume (`--callback*` apply only then). The receipt's `delivery` says which |
34
+ | `--member --prompt … --member …` | batch: flags before the first `--member` are defaults, ≥2 members, `--join all` (default) or `first`; the callback is the group's |
80
35
 
81
- For a chain: launch step 1 → end turn → receive callback → put needed results
82
- in step 2's self-contained prompt. Branching and retries are your responsibility.
36
+ A child that needs your answer ends its turn with the question as its result;
37
+ answer it with `--run <id> --prompt`. Core owns the join: never aggregate
38
+ members by hand.
83
39
 
84
40
  ## Model choice
85
41
 
86
- Default: inherit your current model. For harder reasoning, raise
87
- `launch.thinking` first (`off/minimal/low/medium/high/xhigh/max`). For cheap bulk
88
- work, choose the same provider's smallest current model with low/off thinking;
89
- for an independent vendor's opinion, choose its flagship.
42
+ Default: your model. Harder reasoning: `--thinking` first
43
+ (`off/minimal/low/medium/high/xhigh/max`). `--model <name>` is matched
44
+ against the operator's menu (substring of provider, id or note — "let gpt
45
+ review it" is `--model gpt`); none or several hits lists the pins, pick one.
46
+ `--model ?` prints the menu. Never name a model id from memory.
90
47
 
91
- Before naming a model, call `{"operation":"models"}`; never use IDs from memory.
92
- It returns operator pins (`source:"menu"`, intent notes/usual thinking) or the
93
- live catalog (`source:"catalog"`). Prefer a matching pin and its thinking level.
94
- `launch.model` overrides inheritance. Unknown model IDs fail the run and report
95
- available IDs by callback; invalid `launch.thinking` fails the call.
48
+ ## Cancel · recover
96
49
 
97
- ## Control and decisions
50
+ `pier task cancel --run <id> | --group <id>` — the runs you launched.
98
51
 
99
- `message` must be non-empty, at most 16 KiB. Controls require ownership: your delegated
100
- trees, or only descendants when you are a subagent.
52
+ `pier task recover (--run <id> | --group <id>) --reason <text>` — the full
53
+ result after its callback settled, for text truncated (8000 chars; 2000 per
54
+ member) or lost to compaction. **Never to check progress**: the refusal
55
+ reveals no state.
101
56
 
102
- - `steer`: interrupt a child with corrections.
103
- - `follow_up`: queue guidance after its current turn.
104
- - `resume`: terminal run only; same session, new run ID/callback, same depth,
105
- message as prompt. Expires its unanswered decision. Being a new run, it takes
106
- the same `callback` and `callback_session_id` as `run`, under the same rule:
107
- a subagent may not redirect them.
108
- - `cancel`: run or group; cascades to descendants, terminal runs unchanged.
57
+ ## Saved definitions
109
58
 
110
- `steer`/`follow_up` require a non-terminal run; undelivered guidance expires when
111
- it ends. For finished work use `resume`.
112
-
113
- Child → supervisor:
114
-
115
- ```json
116
- {"operation":"contact","reason":"decision","message":"Use API A or B?"}
59
+ ```sh
60
+ pier task save --name nightly --bash "make check" --cwd /repo --cron "0 3 * * *" --tz UTC
117
61
  ```
118
62
 
119
- Requires an active delegated Agent run with a supervisor (scheduled cron/watch
120
- runs have none). `progress` is fire-and-forget; `decision` steers the supervisor
121
- and permits one open question per run. State what you await and **end your
122
- turn**, never spin/poll. A finished run with an open question suppresses its
123
- completion callback: the question is the notification.
63
+ Only for schedules or roles run more than once; `--task-id` updates. A
64
+ schedule's results reach nobody unless `--callback-session <id>` names a
65
+ session; `pier task list` shows definitions, never runs.
124
66
 
125
- Supervisor → child:
126
-
127
- ```json
128
- {"operation":"reply","message_id":"...","message":"Use API A"}
129
- ```
67
+ ## Limits
130
68
 
131
- Only the addressed supervisor may reply. Same text twice is a no-op; different
132
- text errors. The answer steers an active child or auto-resumes a terminal one
133
- with the reply as prompt; the continuation's callback returns to the replier.
134
-
135
- ## Recover lost information only
136
-
137
- `recover` requires `run_id` or `group_id` plus `reason` (e.g. text truncated,
138
- context lost to compaction). **Never use it to check progress.**
139
-
140
- - Run must be terminal and its callback settled: delivered, abandoned, or none.
141
- Group members wait for their group callback; a terminal race winner is
142
- readable while losers are still cancelling.
143
- - Whole-group recovery additionally requires every member terminal. An open
144
- decision directs you to `reply`. Other premature requests get a refusal
145
- that reveals no state.
146
- - Callbacks truncate each result at 8000 characters; recovered groups truncate
147
- member results at 2000. Notes point to `recover run_id`, which returns full
148
- text. `none` remains a no-result preference, not a polling workflow.
149
-
150
- ## Persistence and limits
151
-
152
- `create` files an operator-visible definition only for recurring roles or
153
- cron/watch schedules; the operator must archive it. `update` takes the entire
154
- draft, including `trigger`. Schedules notify only with nested
155
- `callback:{"type":"session","sessionId":"..."}`; `origin` needs an invoker,
156
- which scheduled runs lack.
157
-
158
- - Inside a run: Agent actions only (stored/inline), no reuse or create/update.
159
- - Depth 0–2: three levels of nesting below the invoking session; a fourth
160
- level errors. Each root allows 16 descendant runs (depth ≥1, resumes included). Your direct
161
- children are separate roots and do not count toward that limit.
162
- - 6 Agent runs execute instance-wide; others queue without error. A queued run
163
- waits **unbounded**, ended only by cancellation or a restart.
164
- - Default timeout 3600s; `timeoutSeconds:1–86400` in a draft, the `prompt`
165
- shorthand or a `tasks[]` entry. It starts when the run does, not at enqueue,
166
- and reports `failed / task timed out`.
167
- - Restart marks queued/running runs `interrupted`; callbacks still apply.
168
- During drain, new roots are refused: retry after restart.
169
- - Watch probes that matched nothing are kept only 50 deep per watch; older
170
- ones are deleted unless a message, a pending callback or a resume needs them.
69
+ - A delegated run does not delegate: `pier task` is refused inside a run
70
+ someone waits on — ask in your result; your supervisor runs it.
71
+ - 6 agent runs execute at once instance-wide; the rest queue until cancelled
72
+ or a restart marks them `interrupted` (callbacks still fire).
73
+ - During a restart drain new runs are refused: retry after.
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: pier-vault
3
+ description: Run a command with a named vault secret via `pier vault run`, never seeing the value. Read before anything needing a token, key or password, or on a `vault:` error.
4
+ ---
5
+
6
+ # Pier vault
7
+
8
+ ```
9
+ pier vault run SLACK_BOT_TOKEN=SLACK_TOKEN -- ./fetch_weekly.py --out raw/weekly
10
+ ```
11
+
12
+ `ENV=NAME` puts the secret `NAME` into the command's environment as `ENV`;
13
+ `NAME` alone is `NAME=NAME`; list as many as needed. Everything after `--`
14
+ runs as is (same cwd and stdio, its exit code is yours). Use the name a
15
+ skill gives you; never invent one.
16
+
17
+ - **No value is ever printed** — not by `pier vault run`, not by you: no
18
+ `echo`, log line, file or config. The command reads its environment.
19
+ - **No workaround for a missing secret**: you cannot obtain the value another
20
+ way; ask the operator with the link from the error.
21
+ - **`approve` secrets may pause**: every use asks the operator through `vt`
22
+ and the command waits. Say so when a step may sit waiting; do not retry in
23
+ a loop.
24
+
25
+ ## When it fails
26
+
27
+ One stderr line, exit 2, the command did not run.
28
+
29
+ | stderr | Do |
30
+ | --- | --- |
31
+ | `vault: no secret named X — file it at <link>` | Stop. Give the operator that exact link (it opens the Console with the name filled in); the value goes there, never to you. |
32
+ | `vault: locked — <reason>` | The operator unlocks Pier's key store (Console → Settings → Security). Nothing you run helps. |
33
+ | `vault: vt is required for X (approve level) and was not found` | `vt` is not on PATH here. Tell the operator; you cannot change the level. |
34
+ | `pier: Pier is not running (no …/pier.sock)` | Only Pier's own machine has the socket. Report it. |
35
+ | `pier: PIER_SESSION_ID is required` / `pier: … is not a session of this Pier` | You are not inside a Pier session with Pier's `pier` on PATH. Report it. |
36
+ | `usage: pier vault run …` | Check `--` is present and each name is `ENV=NAME` or `NAME`. |