@timqi/pier 0.1.0 → 0.1.2

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 (158) hide show
  1. package/README.md +58 -125
  2. package/dist/agent/config.js +6 -15
  3. package/dist/agent/credentials.js +11 -23
  4. package/dist/agent/events.js +42 -64
  5. package/dist/agent/listing.js +39 -92
  6. package/dist/agent/pi.js +103 -252
  7. package/dist/boards/boards.js +19 -29
  8. package/dist/channels/attach.js +14 -42
  9. package/dist/channels/chains.js +33 -37
  10. package/dist/channels/chunk.js +8 -28
  11. package/dist/channels/commands.js +3 -14
  12. package/dist/channels/config.js +33 -52
  13. package/dist/channels/control.js +4 -13
  14. package/dist/channels/conversations.js +8 -25
  15. package/dist/channels/dedup.js +8 -17
  16. package/dist/channels/gatekeeper.js +13 -23
  17. package/dist/channels/lark-api.js +23 -63
  18. package/dist/channels/lark-outbound.js +12 -44
  19. package/dist/channels/lark-panel.js +7 -23
  20. package/dist/channels/lark-render.js +18 -62
  21. package/dist/channels/lark.js +52 -141
  22. package/dist/channels/lines.js +13 -15
  23. package/dist/channels/panel.js +16 -36
  24. package/dist/channels/receipts.js +29 -52
  25. package/dist/channels/routes.js +3 -9
  26. package/dist/channels/runtime.js +12 -23
  27. package/dist/channels/slack-api.js +34 -86
  28. package/dist/channels/slack-directory.js +7 -23
  29. package/dist/channels/slack-outbound.js +12 -56
  30. package/dist/channels/slack-panel.js +4 -13
  31. package/dist/channels/slack-render.js +23 -91
  32. package/dist/channels/slack-tool.js +48 -171
  33. package/dist/channels/slack.js +73 -239
  34. package/dist/channels/telegram-api.js +8 -20
  35. package/dist/channels/telegram-panel.js +5 -21
  36. package/dist/channels/telegram-render.js +13 -40
  37. package/dist/channels/telegram.js +54 -146
  38. package/dist/channels/types.js +5 -16
  39. package/dist/cli.js +17 -41
  40. package/dist/config-sync.js +87 -4
  41. package/dist/core/hub.js +7 -20
  42. package/dist/core/identity.js +20 -59
  43. package/dist/core/inbound-file.js +15 -49
  44. package/dist/core/inbox.js +12 -34
  45. package/dist/core/queue.js +3 -5
  46. package/dist/core/reply.js +41 -142
  47. package/dist/core/router.js +209 -264
  48. package/dist/core/types.js +4 -0
  49. package/dist/db.js +88 -272
  50. package/dist/drain.js +57 -50
  51. package/dist/extensions/index.js +3 -11
  52. package/dist/extensions/web/anthropic.js +3 -9
  53. package/dist/extensions/web/artifacts.js +2 -5
  54. package/dist/extensions/web/content.js +4 -12
  55. package/dist/extensions/web/http.js +2 -6
  56. package/dist/extensions/web/language.js +8 -18
  57. package/dist/extensions/web/openai.js +1 -1
  58. package/dist/extensions/web/provider.js +5 -18
  59. package/dist/extensions/web/tools.js +19 -63
  60. package/dist/lock.js +98 -0
  61. package/dist/log.js +9 -26
  62. package/dist/main.js +84 -183
  63. package/dist/paths.js +10 -26
  64. package/dist/secrets.js +18 -45
  65. package/dist/service.js +31 -73
  66. package/dist/settings.js +19 -63
  67. package/dist/tasks/agent.js +24 -45
  68. package/dist/tasks/callbacks.js +8 -16
  69. package/dist/tasks/command.js +2 -6
  70. package/dist/tasks/definitions.js +39 -62
  71. package/dist/tasks/execution.js +41 -39
  72. package/dist/tasks/groups.js +8 -11
  73. package/dist/tasks/messages.js +88 -155
  74. package/dist/tasks/outbox.js +33 -54
  75. package/dist/tasks/routes.js +4 -7
  76. package/dist/tasks/runs.js +4 -9
  77. package/dist/tasks/service.js +29 -42
  78. package/dist/tasks/store.js +36 -27
  79. package/dist/tasks/tool.js +59 -60
  80. package/dist/tools-task.js +20 -60
  81. package/dist/tools.js +98 -325
  82. package/dist/update.js +20 -43
  83. package/dist/web/auth.js +118 -179
  84. package/dist/web/config-sync.js +2 -2
  85. package/dist/web/config.js +3 -7
  86. package/dist/web/explorer.js +10 -21
  87. package/dist/web/fs.js +20 -42
  88. package/dist/web/instance.js +35 -82
  89. package/dist/web/providers.js +5 -11
  90. package/dist/web/public/assets/{activity-Bl3vZukb.js → activity-DOr8dWeX.js} +1 -1
  91. package/dist/web/public/assets/activity-DOr8dWeX.js.br +0 -0
  92. package/dist/web/public/assets/activity-DOr8dWeX.js.gz +0 -0
  93. package/dist/web/public/assets/{boards-DYuf4Mlj.js → boards-CneyR23E.js} +1 -1
  94. package/dist/web/public/assets/boards-CneyR23E.js.br +0 -0
  95. package/dist/web/public/assets/boards-CneyR23E.js.gz +0 -0
  96. package/dist/web/public/assets/explorer-D0srXT1c.js +4 -0
  97. package/dist/web/public/assets/explorer-D0srXT1c.js.br +0 -0
  98. package/dist/web/public/assets/explorer-D0srXT1c.js.gz +0 -0
  99. package/dist/web/public/assets/index-DbFu15NN.js +85 -0
  100. package/dist/web/public/assets/index-DbFu15NN.js.br +0 -0
  101. package/dist/web/public/assets/index-DbFu15NN.js.gz +0 -0
  102. package/dist/web/public/assets/index-eqQLVS8Q.css +2 -0
  103. package/dist/web/public/assets/index-eqQLVS8Q.css.br +0 -0
  104. package/dist/web/public/assets/index-eqQLVS8Q.css.gz +0 -0
  105. package/dist/web/public/assets/{runs-BLJu7EXN.js → runs-Cv0A-e08.js} +1 -1
  106. package/dist/web/public/assets/runs-Cv0A-e08.js.br +0 -0
  107. package/dist/web/public/assets/runs-Cv0A-e08.js.gz +0 -0
  108. package/dist/web/public/assets/{settings-BrdVh-Zi.js → settings-VmCjhGBd.js} +1 -1
  109. package/dist/web/public/assets/settings-VmCjhGBd.js.br +0 -0
  110. package/dist/web/public/assets/settings-VmCjhGBd.js.gz +0 -0
  111. package/dist/web/public/assets/{task-runs-CeQS1rxa.js → task-runs-CqpTV644.js} +1 -1
  112. package/dist/web/public/assets/task-runs-CqpTV644.js.br +0 -0
  113. package/dist/web/public/assets/task-runs-CqpTV644.js.gz +0 -0
  114. package/dist/web/public/assets/tasks-BffPVgXg.js +4 -0
  115. package/dist/web/public/assets/tasks-BffPVgXg.js.br +0 -0
  116. package/dist/web/public/assets/tasks-BffPVgXg.js.gz +0 -0
  117. package/dist/web/public/index.html +30 -16
  118. package/dist/web/public/index.html.br +0 -0
  119. package/dist/web/public/index.html.gz +0 -0
  120. package/dist/web/public/sw.js +14 -2
  121. package/dist/web/public/sw.js.br +0 -0
  122. package/dist/web/public/sw.js.gz +0 -0
  123. package/dist/web/push.js +55 -77
  124. package/dist/web/route.js +3 -7
  125. package/dist/web/server.js +109 -190
  126. package/dist/web/session-state.js +13 -53
  127. package/dist/web/types.js +2 -4
  128. package/dist/web/webpush.js +10 -25
  129. package/docs/deploy.md +115 -330
  130. package/package.json +1 -1
  131. package/skills/pier-boards/SKILL.md +81 -160
  132. package/skills/pier-help/SKILL.md +23 -20
  133. package/skills/pier-slack/SKILL.md +2 -2
  134. package/skills/pier-tasks/SKILL.md +23 -15
  135. package/dist/config-sync-fetch.js +0 -84
  136. package/dist/limits.js +0 -14
  137. package/dist/web/public/assets/activity-Bl3vZukb.js.br +0 -0
  138. package/dist/web/public/assets/activity-Bl3vZukb.js.gz +0 -0
  139. package/dist/web/public/assets/boards-DYuf4Mlj.js.br +0 -0
  140. package/dist/web/public/assets/boards-DYuf4Mlj.js.gz +0 -0
  141. package/dist/web/public/assets/explorer-qJH_9nTE.js +0 -4
  142. package/dist/web/public/assets/explorer-qJH_9nTE.js.br +0 -0
  143. package/dist/web/public/assets/explorer-qJH_9nTE.js.gz +0 -0
  144. package/dist/web/public/assets/index-Dqdb-Eqt.js +0 -85
  145. package/dist/web/public/assets/index-Dqdb-Eqt.js.br +0 -0
  146. package/dist/web/public/assets/index-Dqdb-Eqt.js.gz +0 -0
  147. package/dist/web/public/assets/index-DzmMzvi_.css +0 -2
  148. package/dist/web/public/assets/index-DzmMzvi_.css.br +0 -0
  149. package/dist/web/public/assets/index-DzmMzvi_.css.gz +0 -0
  150. package/dist/web/public/assets/runs-BLJu7EXN.js.br +0 -0
  151. package/dist/web/public/assets/runs-BLJu7EXN.js.gz +0 -0
  152. package/dist/web/public/assets/settings-BrdVh-Zi.js.br +0 -0
  153. package/dist/web/public/assets/settings-BrdVh-Zi.js.gz +0 -0
  154. package/dist/web/public/assets/task-runs-CeQS1rxa.js.br +0 -0
  155. package/dist/web/public/assets/task-runs-CeQS1rxa.js.gz +0 -0
  156. package/dist/web/public/assets/tasks-bcb3fYdK.js +0 -4
  157. package/dist/web/public/assets/tasks-bcb3fYdK.js.br +0 -0
  158. package/dist/web/public/assets/tasks-bcb3fYdK.js.gz +0 -0
@@ -1,36 +1,21 @@
1
- // One reason: a tools switch has to become exactly one run of the one task
2
- // Pier owns — which takes knowing what that task runs, keeping it the task
3
- // Pier wrote, and turning a burst of switches into one run of it.
4
- //
5
- // It lives beside tools.ts rather than inside it because tools.ts may not
6
- // import tasks/, and outside main.ts because main.ts is wiring: this is the
7
- // only rule in the instance layer that is neither construction nor a callback.
8
- // The task's run history *is* the tools status surface — the install, the daily
9
- // update and every failure are runs with output, so there is no second place to
10
- // look (§5b).
1
+ // A tools switch becomes exactly one run of the one task Pier owns. Beside
2
+ // tools.ts because tools.ts may not import tasks/; the task's run history is
3
+ // the tools status surface (§5).
11
4
  import { existsSync } from "node:fs";
12
5
  import { fileURLToPath } from "node:url";
13
6
  import { logger } from "./log.js";
14
7
  import { PIER_HOME } from "./paths.js";
15
8
  import { isTerminal } from "./tasks/types.js";
16
9
  import { coalescedSync } from "./tools.js";
17
- /** Marks the daily update task as Pier's own — this file finds the one it owns
18
- * rather than one a person wrote, and names itself with it when it writes the
19
- * definition back (the owner guard in tasks/definitions.ts). */
10
+ /** The owner guard in tasks/definitions.ts: only this creator may write it back. */
20
11
  const TOOLS_TASK_CREATOR = "tools";
21
- // The area these lines have always logged under: the move must not rename
22
- // anything an operator greps the journal for.
12
+ // "pier", not "tools": what an operator greps the journal for.
23
13
  const log = logger("pier");
24
- /** POSIX single quotes: `$`, a backtick and a backslash mean things inside
25
- * double quotes, and this string is run by bash months from now. */
14
+ /** POSIX single quotes: this string is run by bash months from now. */
26
15
  const shellQuote = (value) => `'${value.replaceAll("'", `'\\''`)}'`;
27
- /**
28
- * How this Pier runs `pier tools sync`. Installed, that is the built CLI beside
29
- * main.js. From a source checkout there is no `cli.js` and node cannot strip
30
- * types through imports that still say `.js`, so it is the same command under
31
- * tsx — which is what a source checkout has. Neither available is a refusal
32
- * with a reason, never a task whose script cannot run.
33
- */
16
+ /** From a source checkout there is no `cli.js` and node cannot strip types
17
+ * through `.js` imports, so it is the same command under tsx. Neither
18
+ * available is a refusal with a reason, never a task whose script cannot run. */
34
19
  const toolsSyncScript = () => {
35
20
  const built = fileURLToPath(new URL("./cli.js", import.meta.url));
36
21
  if (existsSync(built))
@@ -49,22 +34,10 @@ const toolsSyncScript = () => {
49
34
  }
50
35
  };
51
36
  export function toolsTask(tasks) {
52
- /** Which task is Pier's, and the id every managed run goes through. */
53
37
  let toolsTaskId = null;
54
- /**
55
- * The one task Pier owns, brought in line with what it should be.
56
- *
57
- * Created once and never retired: a task that comes and goes is a state class
58
- * of its own (two boots racing to create it, a retirement racing a switch),
59
- * and the run it would have been retired for already says "no tools switched
60
- * on".
61
- *
62
- * It repairs rather than trusts because of what came before the owner guard
63
- * (tasks/definitions.ts): a definition edited by an older Pier, or by a
64
- * release where the routes could still write it, is brought back to the one
65
- * Pier owns here. Nothing can edit it any more — so this is a boot-time
66
- * repair of state that already exists, not a defence.
67
- */
38
+ /** Created once and never retired: a task that comes and goes is a state
39
+ * class of its own, and a run with nothing on already says so. Repairs a
40
+ * definition an older Pier could still edit. */
68
41
  const ensureToolsTask = async () => {
69
42
  const command = toolsSyncScript();
70
43
  if ("problem" in command)
@@ -83,40 +56,31 @@ export function toolsTask(tasks) {
83
56
  callback: { type: "none" },
84
57
  timeoutSeconds: 1800,
85
58
  };
86
- // Archived is not "owned but edited": nothing can un-archive a task, so the
87
- // replacement is a new one and the old one keeps its history.
59
+ // Nothing can un-archive a task, so an archived one is replaced, history kept.
88
60
  const owned = tasks.list().filter((task) => task.creator === TOOLS_TASK_CREATOR && !task.archived);
89
- // One per creator. Two would fight over ubix's state lock every night, each
90
- // reporting the other's run as an overlap.
61
+ // Two would fight over ubix's state lock every night.
91
62
  for (const extra of owned.slice(1)) {
92
63
  log.warn(`archiving a second tools update task (${extra.id})`);
93
64
  tasks.archive(extra.id, TOOLS_TASK_CREATOR);
94
65
  }
95
66
  const task = owned[0];
96
- // Every field Pier owns, not just the command: a paused task, a renamed one
97
- // or one pointed at a callback still claims to be keeping the tools current
98
- // while the daily run never happens.
67
+ // Every field, not just the command: a paused or renamed task still claims
68
+ // to keep the tools current while the daily run never happens.
99
69
  if (task && Object.entries(draft).some(([key, value]) => JSON.stringify(task[key]) !== JSON.stringify(value))) {
100
70
  log.warn("the tools update task was edited — restoring the definition Pier owns");
101
- // Named as the owner: this is the one path allowed to write it back
102
- // (tasks/definitions.ts).
103
71
  await tasks.update(task.id, draft, TOOLS_TASK_CREATOR);
104
72
  }
105
73
  const id = task ? task.id : (await tasks.create(draft, TOOLS_TASK_CREATOR)).id;
106
74
  toolsTaskId = id;
107
75
  return { id };
108
76
  };
109
- /** The half of `coalescedSync` (tools.ts, which has the rule and why) that
110
- * knows what a task is: start a run, and hand back what to wait for — our own
111
- * run, or the one already in flight that made ours a `skipped` row. */
77
+ /** The half of `coalescedSync` (tools.ts) that knows what a task is. */
112
78
  const requestSync = coalescedSync(() => {
113
79
  if (!toolsTaskId)
114
80
  throw new Error("no tools update task to run");
115
81
  const settled = (id) => tasks.waitForRun(id).then(() => undefined);
116
- // Bounded, because the only way round this loop is a run that finished
117
- // between being in flight and being asked about: real, rare, and not
118
- // something to spin on. Three refusals in a row with nothing running is a
119
- // bug, and it is reported as one rather than retried forever.
82
+ // A run can finish between being in flight and being asked about; three
83
+ // refusals with nothing running is a bug, reported rather than retried.
120
84
  for (let attempt = 0; attempt < 3; attempt++) {
121
85
  const mine = tasks.run(toolsTaskId, null, "manual");
122
86
  if (!isTerminal(mine.state))
@@ -127,8 +91,6 @@ export function toolsTask(tasks) {
127
91
  }
128
92
  throw new Error("the tools sync was refused as an overlap three times with nothing running");
129
93
  }, (err) => log.error("the tools sync could not be run", err));
130
- /** A switch was flipped: make sure the task is the one Pier means, then ask
131
- * for a sync. Answers with what that switch should say about it. */
132
94
  const toolsChanged = async () => {
133
95
  try {
134
96
  const task = await ensureToolsTask();
@@ -144,10 +106,8 @@ export function toolsTask(tasks) {
144
106
  }
145
107
  };
146
108
  return {
147
- /** Reconcile now. At boot, before any route exists: two first flips could
148
- * otherwise both find no task and create one each. */
109
+ /** At boot, before any route exists: two first flips could otherwise both create one. */
149
110
  reconcile: ensureToolsTask,
150
- /** The task whose runs are the status surface, null until there is one. */
151
111
  id: () => toolsTaskId,
152
112
  changed: toolsChanged,
153
113
  };