@timqi/pier 0.0.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.
Files changed (79) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +97 -0
  3. package/dist/agent/config.js +133 -0
  4. package/dist/agent/credentials.js +179 -0
  5. package/dist/agent/events.js +253 -0
  6. package/dist/agent/models.js +15 -0
  7. package/dist/agent/pi.js +296 -0
  8. package/dist/boards/boards.js +200 -0
  9. package/dist/boards/pier.css +445 -0
  10. package/dist/channels/chains.js +67 -0
  11. package/dist/channels/chunk.js +28 -0
  12. package/dist/channels/commands.js +28 -0
  13. package/dist/channels/config.js +172 -0
  14. package/dist/channels/control.js +71 -0
  15. package/dist/channels/conversations.js +65 -0
  16. package/dist/channels/gatekeeper.js +63 -0
  17. package/dist/channels/panel.js +233 -0
  18. package/dist/channels/receipts.js +104 -0
  19. package/dist/channels/routes.js +110 -0
  20. package/dist/channels/runtime.js +76 -0
  21. package/dist/channels/slack-api.js +296 -0
  22. package/dist/channels/slack-directory.js +77 -0
  23. package/dist/channels/slack-outbound.js +121 -0
  24. package/dist/channels/slack-panel.js +122 -0
  25. package/dist/channels/slack-render.js +214 -0
  26. package/dist/channels/slack-tool.js +334 -0
  27. package/dist/channels/slack.js +510 -0
  28. package/dist/channels/telegram-api.js +78 -0
  29. package/dist/channels/telegram-panel.js +113 -0
  30. package/dist/channels/telegram-render.js +96 -0
  31. package/dist/channels/telegram.js +473 -0
  32. package/dist/channels/types.js +27 -0
  33. package/dist/cli.js +101 -0
  34. package/dist/core/hub.js +53 -0
  35. package/dist/core/identity.js +66 -0
  36. package/dist/core/queue.js +11 -0
  37. package/dist/core/reply.js +202 -0
  38. package/dist/core/router.js +189 -0
  39. package/dist/core/types.js +7 -0
  40. package/dist/db.js +268 -0
  41. package/dist/log.js +55 -0
  42. package/dist/main.js +183 -0
  43. package/dist/paths.js +17 -0
  44. package/dist/secrets.js +191 -0
  45. package/dist/service.js +134 -0
  46. package/dist/settings.js +57 -0
  47. package/dist/tasks/agent.js +197 -0
  48. package/dist/tasks/callbacks.js +140 -0
  49. package/dist/tasks/command.js +74 -0
  50. package/dist/tasks/definitions.js +316 -0
  51. package/dist/tasks/execution.js +141 -0
  52. package/dist/tasks/groups.js +187 -0
  53. package/dist/tasks/messages.js +248 -0
  54. package/dist/tasks/routes.js +219 -0
  55. package/dist/tasks/runs.js +104 -0
  56. package/dist/tasks/service.js +282 -0
  57. package/dist/tasks/store.js +168 -0
  58. package/dist/tasks/tool.js +281 -0
  59. package/dist/tasks/types.js +5 -0
  60. package/dist/web/auth.js +280 -0
  61. package/dist/web/files.js +167 -0
  62. package/dist/web/public/assets/index-8CinH1uR.css +2 -0
  63. package/dist/web/public/assets/index-DAgP1Gq8.js +78 -0
  64. package/dist/web/public/icon-192.png +0 -0
  65. package/dist/web/public/icon-32.png +0 -0
  66. package/dist/web/public/icon-512.png +0 -0
  67. package/dist/web/public/icon-maskable-512.png +0 -0
  68. package/dist/web/public/icon-touch-192.png +0 -0
  69. package/dist/web/public/icon.svg +19 -0
  70. package/dist/web/public/index.html +251 -0
  71. package/dist/web/public/manifest.webmanifest +16 -0
  72. package/dist/web/public/sw.js +21 -0
  73. package/dist/web/server.js +366 -0
  74. package/dist/web/session-state.js +39 -0
  75. package/docs/deploy.md +307 -0
  76. package/package.json +55 -0
  77. package/skills/pier-boards/SKILL.md +210 -0
  78. package/skills/pier-slack/SKILL.md +135 -0
  79. package/skills/pier-tasks/SKILL.md +120 -0
@@ -0,0 +1,135 @@
1
+ ---
2
+ name: pier-slack
3
+ description: Read and write Slack through Pier's slack tool — a channel's history for a time range, one thread, posting into a thread, and the Slack-specific syntax for mentions and links. Read before answering questions about Slack conversations or posting anything to a workspace.
4
+ ---
5
+
6
+ # Reading and writing Slack
7
+
8
+ Pier holds the bot token and makes every call itself. State what you want; it
9
+ resolves the channel, pages the API and hands back a finished transcript. Reads
10
+ are live and nothing is kept between calls — write down what you need to keep.
11
+
12
+ ## Where am I
13
+
14
+ If this conversation reached you *through* Slack, omitting `channel` means
15
+ "here":
16
+
17
+ - `{"operation":"post","text":"..."}` replies in the thread you are in
18
+ - `{"operation":"read_thread"}` reads it
19
+ - `{"operation":"context"}` names it: `channel`, `channelName`, `kind`,
20
+ `threadTs`
21
+
22
+ `inSlack:false` from `context` means a task, subagent or web session started
23
+ this: there is no current conversation and `channel` is required.
24
+
25
+ `{"operation":"channels"}` lists what Pier can reach (`id`, `name`, `kind`,
26
+ `respondsToMessages`); pass either an id or a `#name` anywhere a channel is
27
+ wanted. `not_in_channel` means someone must run `/invite @Pier`.
28
+
29
+ ## Never ask for an id
30
+
31
+ You already have them:
32
+
33
+ - **The person talking to you** — a message may start with `[name<id> time]`,
34
+ added by Pier, not typed by them. It appears only when the speaker or the day
35
+ changes, so the last one you saw still applies.
36
+ - **Anyone in a transcript** — every line carries `name[id]`.
37
+ - **This channel and thread** — from `context`.
38
+
39
+ Asking a human to paste their own user ID is never acceptable.
40
+
41
+ ## Reading
42
+
43
+ ```json
44
+ {"operation":"read_channel","channel":"#incidents",
45
+ "since":"2024-06-01T00:00:00Z","until":"2024-06-02T00:00:00Z"}
46
+ ```
47
+
48
+ ```json
49
+ {"operation":"read_thread"}
50
+ ```
51
+
52
+ Omit both arguments for the thread you are in; pass `channel` + `thread_ts` for
53
+ another. A thread read returns the parent plus every reply, with `threadTs` at
54
+ the top of the reply rather than on each line.
55
+
56
+ ```json
57
+ {"operation":"read_message","channel":"#ops","ts":"1717243800.000100"}
58
+ ```
59
+
60
+ One message and nothing else, when that is the whole question. Add `thread_ts`
61
+ when it was posted inside a thread — a channel read cannot see thread replies,
62
+ and the error will say so.
63
+
64
+ - `since` / `until` / `after` take **ISO 8601, epoch seconds, or a `ts` from an
65
+ earlier read**. Omitting `until` reads up to now.
66
+ - `after` returns only what is strictly newer than that message — use it to
67
+ re-read a channel or thread without seeing what you saw last time.
68
+ - `limit` caps the result (default and max 400). When `truncated` is true,
69
+ narrow the range rather than raising the limit.
70
+ - Messages are oldest-first, one line each, shaped as the reply's `format`
71
+ field says — `<ts> | <time, UTC> | <name>[<id>] | <text>`:
72
+
73
+ ```
74
+ 1717243800.000100 | 2024-06-01T12:10Z | Ada[U1] | deploy? [thread: 4 replies]
75
+ ```
76
+
77
+ The leading `ts` is Slack's id: pass it back as `thread_ts` or `after`.
78
+ - A channel read returns thread **parents** only; `[thread: N replies]` marks
79
+ the ones worth opening with `read_thread`.
80
+ - `incomplete` means the read stopped early and its value says why. Retry or
81
+ work with a partial answer, but do not report it as everything.
82
+
83
+ ## Posting
84
+
85
+ ```json
86
+ {"operation":"post","text":"**Deploy done** — 3 services, 0 rollbacks."}
87
+ ```
88
+
89
+ | Goal | Arguments |
90
+ | --- | --- |
91
+ | Reply where you are | omit `channel` and `thread_ts` |
92
+ | Reply in a specific thread | `channel` + `thread_ts` |
93
+ | Start a new top-level message | `thread_ts: "none"` |
94
+
95
+ Going top-level takes the explicit `"none"`: a channel's main flow is wider
96
+ than a thread. A `thread_ts` is never inherited across a change of `channel`.
97
+ The response carries `ts` and `threadTs` for replying under what you posted.
98
+
99
+ ## Message syntax
100
+
101
+ `text` is **standard markdown** and Slack renders it natively: `**bold**`,
102
+ `_italic_`, `` `code` ``, fenced blocks, `# headings`, `- lists`, tables and
103
+ blockquotes. Never hand-convert to the older `*bold*` mrkdwn; it renders
104
+ literally.
105
+
106
+ Four things are Slack syntax, which markdown cannot express:
107
+
108
+ | Intent | Write | Not |
109
+ | --- | --- | --- |
110
+ | Mention a person | `<@U04B7Q2>` | `@alice` — plain text, no ping |
111
+ | Link a channel | `<#C0123456>` | `#general` — plain text |
112
+ | Notify a group | `<!here>`, `<!channel>` | `@here` — plain text |
113
+ | Hyperlink | `[label](https://…)` | — |
114
+
115
+ - **Never guess an id from a name.** A wrong `<@U…>` either fails or pings a
116
+ stranger, and both look like it worked. With no id, write the person's name
117
+ as prose.
118
+ - **Escape `&`, `<`, `>`** when they are text and not markup: `&amp;`, `&lt;`,
119
+ `&gt;`.
120
+ - Emoji as `:white_check_mark:`, not the raw glyph.
121
+ - ~11,000 characters per message. Split longer content across replies in one
122
+ thread rather than truncating.
123
+
124
+ ## Rules
125
+
126
+ - **In a busy thread, say nothing unless you are needed.** You are handed every
127
+ message, including humans talking to each other. `<silent>why</silent>` sends
128
+ nothing at all — prefer it to acknowledging what was not addressed to you.
129
+ - Read before you write. A summary of the wrong thread is worse than none.
130
+ - Never post credentials, tokens or file contents you were not asked to share:
131
+ a channel is usually wider than the conversation you are in.
132
+ - "Slack agent access is switched off" means the operator disabled it on
133
+ purpose. Say so and stop; do not look for another route.
134
+ - Resolve vague times ("yesterday") to an explicit ISO range and say which
135
+ range you used.
@@ -0,0 +1,120 @@
1
+ ---
2
+ name: pier-tasks
3
+ description: Delegate work to Pier subagents with the task tool — one-shot delegation, core-joined parallel fan-out, chained steps, and mid-run control (steer/resume/contact). Read before delegating to a subagent, coordinating multiple agents, or running long background work.
4
+ ---
5
+
6
+ # Orchestrating Pier tasks
7
+
8
+ ## Core model
9
+
10
+ - Every run executes a persisted task definition. An inline `task` draft
11
+ (`operation:"run"` without `task_id`) creates and runs a one-shot subagent
12
+ atomically; it is tagged `kind:"subagent"` and hidden from task lists.
13
+ - **Nothing blocks.** Every operation returns immediately; results, group
14
+ joins, and decision replies arrive later as system follow-up messages in
15
+ your session. Your only waiting primitive is ending your turn.
16
+ - The child session survives the run — `resume` continues it with full
17
+ context intact. Poll state without blocking via `{"operation":"get",
18
+ "run_id":"..."}` (or `group_id`, or `task_id` for that task's recent runs).
19
+
20
+ ## Single delegation (the common case)
21
+
22
+ ```json
23
+ {"operation":"run","task":{"name":"review-auth","action":{
24
+ "type":"agent","session":{"mode":"fresh","cwd":"/abs/project"},
25
+ "prompt":"Review src/auth/*.ts for injection risks. Output: file:line + issue + fix."}}}
26
+ ```
27
+
28
+ Returns a run summary (`runId`, `state:"queued"`, ids). Finish your turn; the
29
+ result arrives as a follow-up. `callback:"none"` silences it.
30
+
31
+ A summary's `triggerSource` is who fired that run (`agent` when you did, plus
32
+ `manual` / `cron` / `watch` / `task`); a definition's `trigger` is only its
33
+ schedule policy, where `manual` means on-demand — by a human or by you.
34
+
35
+ - `fresh`: clean context, requires `cwd`. `fork`: child starts with a copy of
36
+ your conversation — use when the task needs your context. `reuse`: sends
37
+ work to an existing session by id.
38
+ - The child inherits your current model unless `launch.model` is set.
39
+ Unknown models fail with the available list in the error. `launch` applies to
40
+ `fresh` and `fork` only — a `reuse` session owns its own model and tools.
41
+ - The child has the same tools you do; there is no capability knob to pick.
42
+ - Runs time out after 900s by default; set `timeoutSeconds` in the draft for
43
+ longer jobs.
44
+
45
+ ## Parallel fan-out (core-joined)
46
+
47
+ Pass `tasks[]` (each entry a draft or `{"task_id":"..."}`) and Pier joins the
48
+ group in core — you never track run ids across turns:
49
+
50
+ ```json
51
+ {"operation":"run","join":"all","tasks":[
52
+ {"name":"review-correctness","action":{...}},
53
+ {"name":"review-tests","action":{...}}]}
54
+ ```
55
+
56
+ - `join:"all"` (default): one aggregated follow-up when every member
57
+ finishes, listing each member's name, state, and result.
58
+ - `join:"first"`: the first finished run wins; the rest are cancelled but
59
+ their sessions stay resumable (ids are in the callback).
60
+ - `get`/`cancel` accept `group_id`: observe or stop the whole group as one
61
+ unit.
62
+ - Limits: 4 agents active at once, 16 children per tree, nesting caps at
63
+ you → child → grandchild. Extra members queue rather than fail.
64
+
65
+ ## Chains
66
+
67
+ Run step 1, end your turn, receive its callback, splice the needed part into
68
+ step 2's prompt. Children share nothing implicitly (except fork's copied
69
+ history) — every prompt must be self-contained: paths, acceptance criteria,
70
+ expected output format. Branching and retries are your own logic between
71
+ turns.
72
+
73
+ ## Choosing a model
74
+
75
+ Omit `launch.model` to inherit your own model — the right default. Override
76
+ only when the task profile clearly differs:
77
+
78
+ - `anthropic/claude-opus-5` — hardest reasoning: architecture, gnarly debugging
79
+ - `anthropic/claude-fable-5` — long autonomous implementation runs
80
+ - `anthropic/claude-sonnet-5` — balanced default: implementation, review
81
+ - `anthropic/claude-haiku-5` — cheap and fast: listings, extraction, simple checks
82
+ - `openai/gpt-5.6` series (e.g. `gpt-5.6-sol`) — cross-vendor second opinion
83
+
84
+ An unknown id fails with the available models listed in the error.
85
+
86
+ ## Mid-run control
87
+
88
+ - `steer` — interrupt a running child with corrected instructions
89
+ - `follow_up` — queue a message for after its current turn
90
+ - `resume` — continue a finished child in its same session; this expires any
91
+ unanswered decision on that run
92
+ - `cancel` — stop a run (or a whole group via `group_id`); cancellation
93
+ cascades to the run's own children
94
+
95
+ ## Supervisor decisions (as a child)
96
+
97
+ `{"operation":"contact","reason":"decision","message":"..."}` returns a
98
+ receipt immediately. State what you are waiting for and **end your turn** —
99
+ never spin or poll. The answer arrives as a follow-up if your run is still
100
+ active; if your run already finished, Pier resumes your session with the
101
+ reply as the prompt. One open decision per run.
102
+
103
+ As a parent: the question arrives as a system input with a message id, steered
104
+ into your current turn at the next step boundary so a blocked child is not
105
+ waiting on the end of your turn; answer
106
+ with `{"operation":"reply","message_id":"...","message":"..."}`. A run that
107
+ finished while awaiting your answer shows `pendingDecisionId` in `get` and
108
+ sends no completion callback — the question is the notification.
109
+
110
+ `reason:"progress"` is fire-and-forget status for the parent.
111
+
112
+ ## Rules
113
+
114
+ - One concern per child. For fan-out, let core join via `tasks[]` — never
115
+ hand-aggregate run ids across turns.
116
+ - Repeating the same role? Create a durable task once (`operation:"create"`)
117
+ and run it by `task_id` — cheaper than re-sending the draft every time.
118
+ - Inline drafts must use `action.type:"agent"`; triggers are forced manual;
119
+ do not target another session with `reuse` from an inline draft.
120
+ - After launching work, end your turn. The callback starts your next one.