@timqi/pier 0.0.29 → 0.1.0

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 (94) hide show
  1. package/dist/agent/config.js +22 -0
  2. package/dist/agent/events.js +4 -1
  3. package/dist/agent/listing.js +114 -16
  4. package/dist/agent/pi.js +158 -16
  5. package/dist/channels/lark-panel.js +1 -1
  6. package/dist/core/inbox.js +1 -1
  7. package/dist/core/router.js +4 -0
  8. package/dist/core/types.js +13 -1
  9. package/dist/db.js +30 -0
  10. package/dist/drain.js +1 -1
  11. package/dist/extensions/web/content.js +2 -2
  12. package/dist/main.js +8 -1
  13. package/dist/secrets.js +1 -1
  14. package/dist/service.js +2 -2
  15. package/dist/settings.js +31 -10
  16. package/dist/tasks/agent.js +109 -73
  17. package/dist/tasks/callbacks.js +1 -3
  18. package/dist/tasks/command.js +27 -8
  19. package/dist/tasks/execution.js +6 -4
  20. package/dist/tasks/groups.js +35 -26
  21. package/dist/tasks/messages.js +33 -27
  22. package/dist/tasks/outbox.js +48 -21
  23. package/dist/tasks/routes.js +1 -4
  24. package/dist/tasks/runs.js +10 -4
  25. package/dist/tasks/service.js +24 -12
  26. package/dist/tasks/store.js +17 -3
  27. package/dist/tasks/tool.js +97 -25
  28. package/dist/tools.js +2 -2
  29. package/dist/update.js +1 -1
  30. package/dist/web/instance.js +10 -3
  31. package/dist/web/providers.js +9 -2
  32. package/dist/web/public/assets/{activity-D3m4L2IL.js → activity-Bl3vZukb.js} +2 -2
  33. package/dist/web/public/assets/activity-Bl3vZukb.js.br +0 -0
  34. package/dist/web/public/assets/activity-Bl3vZukb.js.gz +0 -0
  35. package/dist/web/public/assets/boards-DYuf4Mlj.js +1 -0
  36. package/dist/web/public/assets/boards-DYuf4Mlj.js.br +0 -0
  37. package/dist/web/public/assets/boards-DYuf4Mlj.js.gz +0 -0
  38. package/dist/web/public/assets/explorer-qJH_9nTE.js +4 -0
  39. package/dist/web/public/assets/explorer-qJH_9nTE.js.br +0 -0
  40. package/dist/web/public/assets/explorer-qJH_9nTE.js.gz +0 -0
  41. package/dist/web/public/assets/index-Dqdb-Eqt.js +85 -0
  42. package/dist/web/public/assets/index-Dqdb-Eqt.js.br +0 -0
  43. package/dist/web/public/assets/index-Dqdb-Eqt.js.gz +0 -0
  44. package/dist/web/public/assets/index-DzmMzvi_.css +2 -0
  45. package/dist/web/public/assets/index-DzmMzvi_.css.br +0 -0
  46. package/dist/web/public/assets/index-DzmMzvi_.css.gz +0 -0
  47. package/dist/web/public/assets/runs-BLJu7EXN.js +1 -0
  48. package/dist/web/public/assets/runs-BLJu7EXN.js.br +0 -0
  49. package/dist/web/public/assets/runs-BLJu7EXN.js.gz +0 -0
  50. package/dist/web/public/assets/settings-BrdVh-Zi.js +5 -0
  51. package/dist/web/public/assets/settings-BrdVh-Zi.js.br +0 -0
  52. package/dist/web/public/assets/settings-BrdVh-Zi.js.gz +0 -0
  53. package/dist/web/public/assets/task-runs-CeQS1rxa.js +3 -0
  54. package/dist/web/public/assets/task-runs-CeQS1rxa.js.br +0 -0
  55. package/dist/web/public/assets/task-runs-CeQS1rxa.js.gz +0 -0
  56. package/dist/web/public/assets/tasks-bcb3fYdK.js +4 -0
  57. package/dist/web/public/assets/tasks-bcb3fYdK.js.br +0 -0
  58. package/dist/web/public/assets/tasks-bcb3fYdK.js.gz +0 -0
  59. package/dist/web/public/index.html +76 -120
  60. package/dist/web/public/index.html.br +0 -0
  61. package/dist/web/public/index.html.gz +0 -0
  62. package/dist/web/public/manifest.webmanifest +2 -2
  63. package/dist/web/public/manifest.webmanifest.br +0 -0
  64. package/dist/web/public/manifest.webmanifest.gz +0 -0
  65. package/dist/web/server.js +40 -8
  66. package/dist/web/session-state.js +5 -5
  67. package/package.json +2 -1
  68. package/skills/pier-tasks/SKILL.md +145 -160
  69. package/dist/web/public/assets/activity-D3m4L2IL.js.br +0 -0
  70. package/dist/web/public/assets/activity-D3m4L2IL.js.gz +0 -0
  71. package/dist/web/public/assets/boards-BIObcQeX.js +0 -1
  72. package/dist/web/public/assets/boards-BIObcQeX.js.br +0 -0
  73. package/dist/web/public/assets/boards-BIObcQeX.js.gz +0 -0
  74. package/dist/web/public/assets/explorer-C_rSWPNB.js +0 -4
  75. package/dist/web/public/assets/explorer-C_rSWPNB.js.br +0 -0
  76. package/dist/web/public/assets/explorer-C_rSWPNB.js.gz +0 -0
  77. package/dist/web/public/assets/index-CX3fYZY5.css +0 -2
  78. package/dist/web/public/assets/index-CX3fYZY5.css.br +0 -0
  79. package/dist/web/public/assets/index-CX3fYZY5.css.gz +0 -0
  80. package/dist/web/public/assets/index-uFsZkKOQ.js +0 -85
  81. package/dist/web/public/assets/index-uFsZkKOQ.js.br +0 -0
  82. package/dist/web/public/assets/index-uFsZkKOQ.js.gz +0 -0
  83. package/dist/web/public/assets/runs-Ch6DZq6O.js +0 -1
  84. package/dist/web/public/assets/runs-Ch6DZq6O.js.br +0 -0
  85. package/dist/web/public/assets/runs-Ch6DZq6O.js.gz +0 -0
  86. package/dist/web/public/assets/settings-BWcEIEcv.js +0 -5
  87. package/dist/web/public/assets/settings-BWcEIEcv.js.br +0 -0
  88. package/dist/web/public/assets/settings-BWcEIEcv.js.gz +0 -0
  89. package/dist/web/public/assets/task-runs-DPkwv2UE.js +0 -3
  90. package/dist/web/public/assets/task-runs-DPkwv2UE.js.br +0 -0
  91. package/dist/web/public/assets/task-runs-DPkwv2UE.js.gz +0 -0
  92. package/dist/web/public/assets/tasks-DTiCi2mH.js +0 -4
  93. package/dist/web/public/assets/tasks-DTiCi2mH.js.br +0 -0
  94. package/dist/web/public/assets/tasks-DTiCi2mH.js.gz +0 -0
@@ -3,175 +3,160 @@ name: pier-tasks
3
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.
4
4
  ---
5
5
 
6
- # Orchestrating Pier tasks
7
-
8
- ## Core model
9
-
10
- - Every run executes a persisted task definition. A `run` without `task_id`
11
- — a bare `prompt`, or a full `task` draft — creates and runs a one-shot
12
- subagent atomically: `kind:"subagent"`, hidden from `list`, named by the
13
- prompt's first line. You never file it.
14
- - **Nothing blocks.** Every operation returns immediately; results, group
15
- joins and decision replies arrive as system follow-up messages once your
16
- turn ends (batched when several are due). Ending your turn is the only wait.
17
- - The child session survives the run — `resume` continues it with context
18
- intact. `get` polls: `run_id` (full result), `group_id`, or `task_id` (10
19
- most recent runs). Lists truncate results at 2000 chars, callbacks at 8000,
20
- both saying so; `get run_id` is whole.
21
- - Limits: a tree is ≤3 runs deep below the session that started it (depth
22
- 0–2; the fourth `run` errors) and holds ≤16 runs below its root (depth ≥ 1,
23
- resumes included) — your direct children are each a root, uncounted. 4
24
- agent runs execute at once instance-wide; the rest wait for a slot without
25
- error, but the timeout clock starts at queue time, so a run queued behind
26
- long ones can time out unstarted.
27
- - Timeout: 900s default → `failed` / `task timed out`; `timeoutSeconds`
28
- 1–86400, draft form only. A Pier restart ends queued/running runs as
29
- `interrupted` (callback still arrives) and refuses new root runs while
30
- draining — retry after.
31
-
32
- ## Single delegation (the common case)
6
+ # Pier tasks
7
+
8
+ ## Delegate, then wait
33
9
 
34
10
  ```json
35
- {"operation":"run","prompt":"Review src/auth/*.ts for injection risks. Output: file:line + issue + fix."}
11
+ {"operation":"run","prompt":"Review src/auth/*.ts. Return file:line, issue, fix."}
36
12
  ```
37
13
 
38
- That is the whole call: a fresh session in **your own directory**. `cwd`
39
- places it elsewhere — absolute, or relative to yours (`"cwd":"../pier.x"` for
40
- a sibling worktree); it must exist. `launch` picks model/thinking, `name`
41
- overrides the label, `input` (any JSON) is appended to the prompt as
42
- `<task_input>`. The `task` draft form is for what the shorthand cannot say —
43
- `timeoutSeconds`, or `reuse` of an existing session:
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
+
29
+ Receipts include `runId`, `taskId`, state. Keep IDs: the callback also names
30
+ `Run:`, and there is no lookup by task. `triggerSource` names the actual invoker
31
+ (`agent/manual/cron/watch/task`); the definition's `trigger` is scheduling
32
+ policy (`manual` means on demand).
33
+
34
+ ## Sessions and prompts
35
+
36
+ - Default `fresh`: clean context. `cwd` defaults to your directory, accepts an
37
+ absolute path or one relative to yours, and must exist.
38
+ - `reuse`: existing session by `sessionId`; continues its history after it is
39
+ idle. `launch` applies only to fresh sessions; reused sessions own their
40
+ model/tools. Children otherwise have your tools, including `task`.
41
+ - **The prompt is the handoff**: no implicit copy of your discussion. Include
42
+ the goal, current decisions, latest constraints, absolute paths, acceptance
43
+ criteria, verification and output format. `input` accepts any JSON, appended
44
+ in `<task_input>`.
45
+ - For more work on an existing result, `resume` that run with a delta prompt;
46
+ its session/context survives. Start fresh for unrelated work or stale context.
47
+ - Stored role: `run` with `task_id` and optional `input`;
48
+ `session_mode:"fresh"` overrides a stored reuse policy. Archived tasks refuse.
49
+
50
+ Use a `task` draft for `timeoutSeconds` or reuse:
44
51
 
45
52
  ```json
46
- {"operation":"run","task":{"name":"long build","timeoutSeconds":3600,"action":{"type":"agent","session":{"mode":"fresh","cwd":"/abs/path"},"prompt":"..."}}}
53
+ {"operation":"run","task":{"timeoutSeconds":3600,"action":{"type":"agent","session":{"mode":"reuse","sessionId":"..."},"prompt":"Check the result"}}}
47
54
  ```
48
55
 
49
- Omit `trigger` in a draft (anything but `manual` errors); a draft's `callback`
50
- is ignored on runs you fire — the result comes to you — and matters only for
51
- `create`d schedules. Returns a run summary (`runId`, `taskId`,
52
- `state:"queued"`, …); `callback:"none"` silences the result,
53
- `callback_session_id` routes it to another existing session. A summary's
54
- `triggerSource` is who fired the run (`agent` / `manual` / `cron` / `watch` /
55
- `task`); a definition's `trigger` is only its schedule, `manual` meaning
56
- on-demand — by a human or by you.
57
-
58
- - `fresh`: clean context in a `cwd` (yours when omitted) — the normal start.
59
- `reuse`: an existing session by id, continuing its history; the run waits
60
- for it to go idle. Nothing copies your context into a child: what the child
61
- needs, you write down.
62
- - **The handoff is the prompt.** A child cannot see your discussion, so state
63
- the goal, the decisions *currently* in force (not the ones argued out of),
64
- late constraints, absolute paths, what "done" means and how to verify it.
65
- Writing it is the check — a decision you cannot state in a sentence was not
66
- settled.
67
- - The child inherits your current model unless `launch.model` is set, and has
68
- the same tools you do, `task` included. An unknown model id fails the *run*,
69
- not the call — the error, with the first available ids, arrives in the
70
- callback; an unknown `launch.thinking` fails the call. `launch` applies to
71
- `fresh` only — a `reuse` session owns its own model and tools.
72
- - Stored roles: `run` with `task_id` (+ optional `input`);
73
- `session_mode:"fresh"` runs a `reuse`-mode role in a fresh session instead.
74
- Archived tasks refuse to run.
75
-
76
- ## Parallel fan-out (core-joined)
77
-
78
- `tasks[]` — 2+ entries, each a prompt string, `{"prompt","cwd"?,"launch"?,
79
- "name"?}`, a full draft, or `{"task_id":"..."}`; never with `task`, `task_id`
80
- or `session_mode` — and Pier joins the group in core; you never track run ids:
56
+ Inline drafts may omit `trigger`; only `manual` is allowed. Their nested
57
+ `callback` is ignored: use top-level delivery options above. Nested callbacks
58
+ matter for saved schedules (below).
59
+
60
+ ## Groups and chains
61
+
62
+ `tasks[]` needs 2+ entries: prompt strings, `{prompt,cwd?,launch?,name?}`, full
63
+ drafts, or `{task_id}`. Do not combine it with `task`, `task_id` or `session_mode`.
64
+
65
+ ```json
66
+ {"operation":"run","tasks":["Review correctness","Review test gaps"],"join":"all"}
67
+ ```
68
+
69
+ - `join:"all"` (default): one callback with every member's name, state and result
70
+ when all are terminal.
71
+ - `join:"first"`: first **any terminal state**, including failure/overlap skip,
72
+ wins. Others are cancelled; their sessions remain resumable, IDs in callback.
73
+ - Core owns the join; never hand-aggregate member IDs across turns. Members have
74
+ no individual callbacks; `none`/`steer` applies to the group. `cancel` and
75
+ `recover` accept `group_id`. Admission failure (e.g. limit or missing cwd)
76
+ rolls back the group: nothing runs.
77
+
78
+ For a chain: launch step 1 → end turn → receive callback → put needed results
79
+ in step 2's self-contained prompt. Branching and retries are your responsibility.
80
+
81
+ ## Model choice
82
+
83
+ Default: inherit your current model. For harder reasoning, raise
84
+ `launch.thinking` first (`off/minimal/low/medium/high/xhigh/max`). For cheap bulk
85
+ work, choose the same provider's smallest current model with low/off thinking;
86
+ for an independent vendor's opinion, choose its flagship.
87
+
88
+ Before naming a model, call `{"operation":"models"}`; never use IDs from memory.
89
+ It returns operator pins (`source:"menu"`, intent notes/usual thinking) or the
90
+ live catalog (`source:"catalog"`). Prefer a matching pin and its thinking level.
91
+ `launch.model` overrides inheritance. Unknown model IDs fail the run and report
92
+ available IDs by callback; invalid `launch.thinking` fails the call.
93
+
94
+ ## Control and decisions
95
+
96
+ `message` must be non-empty, <16 KiB. Controls require ownership: your delegated
97
+ trees, or only descendants when you are a subagent.
98
+
99
+ - `steer`: interrupt a child with corrections.
100
+ - `follow_up`: queue guidance after its current turn.
101
+ - `resume`: terminal run only; same session, new run ID/callback, same depth,
102
+ message as prompt. Expires its unanswered decision.
103
+ - `cancel`: run or group; cascades to descendants, terminal runs unchanged.
104
+
105
+ `steer`/`follow_up` require a non-terminal run; undelivered guidance expires when
106
+ it ends. For finished work use `resume`.
107
+
108
+ Child → supervisor:
109
+
110
+ ```json
111
+ {"operation":"contact","reason":"decision","message":"Use API A or B?"}
112
+ ```
113
+
114
+ Requires an active delegated Agent run with a supervisor (scheduled cron/watch
115
+ runs have none). `progress` is fire-and-forget; `decision` steers the supervisor
116
+ and permits one open question per run. State what you await and **end your
117
+ turn**, never spin/poll. A finished run with an open question suppresses its
118
+ completion callback: the question is the notification.
119
+
120
+ Supervisor → child:
81
121
 
82
122
  ```json
83
- {"operation":"run","join":"all","tasks":[
84
- "Review src/ for correctness bugs. Output: file:line + issue.",
85
- {"prompt":"Review the tests for gaps. Output: missing case + file.","cwd":"packages/web"}]}
123
+ {"operation":"reply","message_id":"...","message":"Use API A"}
86
124
  ```
87
125
 
88
- - `join:"all"` (default): one aggregated follow-up when every member is
89
- terminal — each member's name, state, result.
90
- - `join:"first"`: the first member to reach *any* terminal state wins, a
91
- failure included; the rest are cancelled, their sessions resumable (run ids
92
- in the callback).
93
- - Members send no individual callbacks; `callback:"none"` silences the
94
- group's. `get`/`cancel` take `group_id` for the whole group. A member that
95
- cannot enqueue (limit, missing `cwd`) rolls the group back — nothing runs.
96
-
97
- ## Chains
98
-
99
- Run step 1, end your turn, receive its callback, splice the needed part into
100
- step 2's prompt. Children share nothing implicitly — every prompt is
101
- self-contained: paths, acceptance criteria, output format. Branching and
102
- retries are your own logic between turns.
103
-
104
- ## Choosing a model and thinking level
105
-
106
- Omit `launch.model` to inherit your own model — the right default. When the
107
- task profile clearly differs, adjust in this order:
108
-
109
- - **Harder reasoning → raise `launch.thinking` first**, on the inherited
110
- model (`off` … `minimal` `low` `medium` `high` `xhigh` `max`): no model
111
- name needed, usually cheaper than switching models.
112
- - **Cheap bulk work** (listings, extraction, simple checks) → the same
113
- provider's smallest current model, thinking low or off.
114
- - **Cross-vendor second opinion** → another vendor's flagship.
115
-
116
- Never write a model id from memory — catalogs move under you.
117
- `{"operation":"models"}` is the authority: operator-pinned models when set
118
- (`source:"menu"`, each with an intent note and often a usual `thinking`
119
- level), else the curated live catalog (`source:"catalog"`). Prefer a pinned
120
- entry whose note matches the task and start from its thinking level.
121
-
122
- ## Mid-run control
123
-
124
- - `steer` — interrupt a running child with corrected instructions
125
- - `follow_up` — queue a message for after its current turn
126
- - `resume` — continue a finished child in its same session, `message` as the
127
- prompt: a new run (new `runId`, own callback, same depth); expires any
128
- unanswered decision on that run
129
- - `cancel` — stop a run, or a whole group via `group_id`; cascades to the
130
- run's children; a terminal run is returned unchanged
131
-
132
- `steer`/`follow_up` need a non-terminal run (else `resume`); one undelivered
133
- when the run ends expires. `resume` needs a terminal run. All four accept only
134
- runs you own — trees you started, or, inside a run, your own descendants.
135
- `message`: non-empty, <16 KiB.
136
-
137
- ## Supervisor decisions (as a child)
138
-
139
- `{"operation":"contact","reason":"decision","message":"..."}` returns a
140
- receipt immediately. State what you await and **end your turn** — never spin
141
- or poll. The answer is steered into your current turn if your run is still
142
- active; if it finished, Pier resumes your session with the reply as the
143
- prompt. One open decision per run. `contact` works only inside a run a session
144
- delegated — a cron/watch run has no supervisor. `reason:"progress"` is
145
- fire-and-forget status for the parent.
146
-
147
- As a parent: the question arrives as a system input with a message id, steered
148
- into your current turn at the next step boundary so the child does not wait
149
- out your turn. Answer with `{"operation":"reply","message_id":"...",
150
- "message":"..."}` — only the addressed supervisor may; same text twice is a
151
- no-op, different text an error. A run that finished while awaiting your answer
152
- shows `pendingDecisionId` in `get` and sends no completion callback — the
153
- question is the notification; your reply resumes it, and that continuation's
154
- callback comes to you.
155
-
156
- ## Rules
157
-
158
- - One concern per child. For fan-out, let core join via `tasks[]` — never
159
- hand-aggregate run ids across turns.
160
- - **A change to work a child already did → `resume` that run**, not a new
161
- child: its session still holds the files it read and the decisions it made,
162
- so the message can be a delta ("same file, also handle the empty input").
163
- Go `fresh` when the new work shares nothing with the old — different area,
164
- different goal — or when that session is long and mostly dead ends: clean
165
- context plus a self-contained prompt beats a child sifting its own noise.
166
- Lost the `run_id`? `get` with the summary's `task_id` lists that task's
167
- recent runs — a one-shot subagent has one too.
168
- - `create` is for definitions that outlive one job: a schedule (`cron` /
169
- `watch`), or a role run by `task_id` again and again. It files a task the
170
- operator sees and must archive by hand — never for a one-off; that is `run`
171
- with a prompt. `update` takes the whole draft again, `trigger` included. A
172
- schedule reports to nobody unless its `callback` is
173
- `{"type":"session","sessionId":"..."}` — `origin` is the invoker, which a
174
- cron run lacks.
175
- - Inside a run: Agent tasks only (stored or inline), no `reuse`, no
176
- `create`/`update`.
177
- - After launching work, end your turn. The callback starts your next one.
126
+ Only the addressed supervisor may reply. Same text twice is a no-op; different
127
+ text errors. The answer steers an active child or auto-resumes a terminal one
128
+ with the reply as prompt; the continuation's callback returns to the replier.
129
+
130
+ ## Recover lost information only
131
+
132
+ `recover` requires `run_id` or `group_id` plus `reason` (e.g. text truncated,
133
+ context lost to compaction). **Never use it to check progress.**
134
+
135
+ - Run must be terminal and its callback settled: delivered, abandoned, or none.
136
+ Group members wait for their group callback; a terminal race winner is
137
+ readable while losers are still cancelling.
138
+ - Whole-group recovery additionally requires every member terminal. An open
139
+ decision directs you to `reply`. Other premature requests get a refusal
140
+ that reveals no state.
141
+ - Callbacks truncate each result at 8000 characters; recovered groups truncate
142
+ member results at 2000. Notes point to `recover run_id`, which returns full
143
+ text. `none` remains a no-result preference, not a polling workflow.
144
+
145
+ ## Persistence and limits
146
+
147
+ `create` files an operator-visible definition only for recurring roles or
148
+ cron/watch schedules; the operator must archive it. `update` takes the entire
149
+ draft, including `trigger`. Schedules notify only with nested
150
+ `callback:{"type":"session","sessionId":"..."}`; `origin` needs an invoker,
151
+ which scheduled runs lack.
152
+
153
+ - Inside a run: Agent actions only (stored/inline), no reuse or create/update.
154
+ - Depth 0–2: at most 3 runs below the invoking session; a fourth errors. Each
155
+ root allows 16 descendant runs (depth ≥1, resumes included). Your direct
156
+ children are separate roots and do not count toward that limit.
157
+ - 4 Agent runs execute instance-wide; others queue without error. Timeout
158
+ starts **at enqueue**, so a run can time out before starting.
159
+ - Default timeout 900s; `timeoutSeconds:1–86400` in draft form only. Timeout
160
+ reports `failed / task timed out`.
161
+ - Restart marks queued/running runs `interrupted`; callbacks still apply.
162
+ During drain, new roots are refused: retry after restart.
@@ -1 +0,0 @@
1
- import{F as e,G as t,H as n,K as r,P as i,R as a,U as o,g as s,k as c,z as l}from"./index-uFsZkKOQ.js";var u=e=>e.public&&e.token?`/p/${e.slug}-${e.token}/`:`/boards/${e.slug}/`;function d(d,f){let p=[],m=``,h=a(`header`,`sticky top-0 z-30 flex h-10 items-center gap-3 border-b border-neutral-200 bg-white px-4`,a(`span`,`font-medium max-md:hidden`,`Boards`)),g=a(`div`,`px-4 py-5`);d.append(a(`div`,`min-h-0 flex-1 overflow-y-auto`,h,g));async function _(e,t){let i=await r(`/api/boards/${e.slug}`,{public:t},`PATCH`);if(i.ok)return e.token=(await i.json().catch(()=>({}))).token??``,x();m=await n(i,`Could not change ${e.slug}`),await S()}async function v(e){m=await t(`/api/boards/${e}`,`DELETE`,`Could not delete ${e}`)??``,await S()}function y(t){let n=a(`div`,`group flex flex-col gap-1 border-b border-neutral-200/70 px-1 py-2.5 last:border-b-0`),r=document.createElement(`a`);r.className=`truncate font-medium text-neutral-800 hover:text-indigo-700`,r.href=u(t),r.target=`_blank`,r.rel=`noreferrer`,r.textContent=t.title;let i=a(`div`,`flex items-center gap-2`,r,a(`span`,`flex-none font-mono text-[11.5px] text-neutral-400`,t.slug)),o=c(``,``,t.public,e=>{t.public=e,_(t,e)});o.className=`ml-auto flex flex-none cursor-pointer items-center gap-1.5 text-[11.5px] text-neutral-500`,o.append(a(`span`,``,`Public`));let d=s(`Delete`,`flex-none cursor-pointer text-[11.5px] text-neutral-400 opacity-0 transition-opacity hover:text-red-600 group-hover:opacity-100`);d.title=`Renames the folder on disk; nothing is erased`,d.onclick=()=>void v(t.slug);let p=e(`flex-none cursor-pointer text-[11.5px] text-neutral-400 opacity-0 transition-opacity hover:text-indigo-600 group-hover:opacity-100`,()=>`${location.origin}${u(t)}`);p.title=`Copy the board's link`,i.append(o,p,d),n.append(i);let m=a(`div`,`flex flex-wrap items-center gap-x-3 gap-y-1 text-[11.5px] text-neutral-500`);t.description&&m.append(a(`span`,`min-w-0 truncate`,t.description)),m.append(a(`span`,`flex-none text-neutral-400`,l(Date.parse(t.updatedAt))));for(let e of t.sessions){let t=s(e.slice(0,8),`flex-none cursor-pointer font-mono text-indigo-600 hover:underline`);t.title=`Open session ${e}`,t.onclick=()=>f(e),m.append(t)}if(t.public&&t.token){let e=a(`span`,`flex-none font-mono text-neutral-400`,u(t));e.title=`Public URL — anyone holding this link can read the board, no password`,m.append(e)}return n.append(m),n}let b=[{title:`Public`,hint:`Readable at /p/<slug>-<token>/ by anyone holding the link.`,wanted:!0},{title:`Private`,hint:`Reachable from the Console only.`,wanted:!1}];function x(){let e=a(`div`,`mx-auto flex max-w-3xl flex-col`);p.length===0&&e.append(a(`p`,`rounded-xl border border-dashed border-neutral-300 px-4 py-6 text-center text-[12.5px] text-neutral-500`,`No boards yet. Ask an agent to build one — it writes a folder under ~/.pier/boards.`));for(let{title:t,hint:n,wanted:r}of b){let i=p.filter(e=>e.public===r);if(i.length===0)continue;let o=a(`section`,`mb-6`);o.append(a(`h2`,`text-[13px] font-semibold text-neutral-700`,t)),o.append(a(`p`,`mb-1 text-[11.5px] leading-snug text-neutral-500`,n));let s=a(`div`,`rounded-xl border border-neutral-200 bg-white px-3`);s.append(...i.map(y)),o.append(s),e.append(o)}g.replaceChildren(...m?[a(`p`,`mb-3 text-[13px] text-red-600`,m)]:[],e)}async function S(){let e=await o(`/api/boards`,`Could not load boards`);if(!e.ok)return m=e.error,x();p=e.value,x(),m=``}let C=i(d,()=>void S());return window.addEventListener(`focus`,()=>{C.visible&&S()}),C}export{d as createBoardsView};
@@ -1,4 +0,0 @@
1
- import{I as e,N as t,P as n,R as r,W as i,a,d as o,f as s,i as c,n as l,s as u,u as d,z as f}from"./index-uFsZkKOQ.js";var p=e=>{let t=new Date(e),n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`},m=e=>[e.subject,e.body,[[e.author,e.email?`<${e.email}>`:``].filter(Boolean).join(` `),e.at?p(e.at):``].filter(Boolean).join(` · `)].filter(Boolean).join(`
2
-
3
- `),h=null;function g(){h&&(h.remove(),h=null,document.removeEventListener(`pointerdown`,g,!0),window.removeEventListener(`scroll`,g,!0))}function ee(e,t){e.onmouseenter=()=>{g();let n=t();if(!n)return;h=r(`div`,`pointer-events-none fixed z-50 max-w-96 whitespace-pre-wrap rounded-lg bg-neutral-800/95 px-3 py-2 font-sans text-[11.5px] leading-snug text-neutral-100 shadow-lg`),h.textContent=n,document.body.append(h),document.addEventListener(`pointerdown`,g,!0),window.addEventListener(`scroll`,g,!0);let i=e.getBoundingClientRect();h.style.left=`${Math.max(8,Math.min(i.left,window.innerWidth-h.offsetWidth-8))}px`,h.style.top=i.bottom+6+h.offsetHeight>window.innerHeight?`${i.top-h.offsetHeight-6}px`:`${i.bottom+6}px`},e.onmouseleave=g}function _(e,t,n){let i=r(`button`,`flex w-full cursor-pointer items-center gap-1.5 px-2 py-1 text-left hover:bg-neutral-100`,r(`span`,`w-3 flex-none text-indigo-600`,e.value===t?`✓`:``),r(`span`,`flex-none font-mono text-[11.5px] text-neutral-800`,e.label??e.value));return e.subject&&i.append(r(`span`,`min-w-0 truncate text-[11px] text-neutral-400`,e.subject)),e.author&&i.append(r(`span`,`ml-auto flex-none pl-1.5 text-[10.5px] text-neutral-400`,`${e.author} · ${e.at?f(e.at):``}`)),ee(i,()=>m(e)),i.onclick=()=>n(e.value),i}function te(e,t,n,i,o){let{base:s,head:l}=n,u=()=>l&&s===`${l}~1`?l:``,d=u()?`commit`:`compare`,f=t.commits[0],p=e=>[...e?[{value:``,label:`Working tree`,subject:`the files on disk, uncommitted changes included`}]:[],{...f,value:`HEAD`},...t.refs.map(e=>({value:e.name,subject:e.subject})),...t.commits.map(e=>({...e,value:e.hash}))],m=r(`div`,`flex w-[38rem] max-w-full flex-col`);function h(){let e=(e,t)=>{let n=r(`button`,`cursor-pointer rounded-full px-2.5 py-0.5 text-[11.5px] ${d===t?`bg-indigo-50 font-medium text-indigo-700`:`text-neutral-500 hover:bg-neutral-100`}`,e);return n.onclick=()=>{d=t,h()},n},n=(e,t,n,i)=>r(`div`,`flex min-w-0 flex-1 flex-col`,r(`div`,`flex-none px-2 pb-0.5 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e),r(`div`,`min-h-0 flex-1 overflow-y-auto`,...t.map(e=>_(e,n,i)))),a=d===`compare`?r(`div`,`flex h-72 min-h-0 divide-x divide-neutral-200 pb-1`,n(`base`,p(!1),s,e=>{s=e,h(),i(s,l)}),n(`to`,p(!0),l,e=>{l=e,h(),i(s,l)})):r(`div`,`flex h-72 min-h-0 flex-col overflow-y-auto pb-1`,...t.commits.map(e=>_({value:e.hash,...e},u(),e=>{s=`${e}~1`,l=e,c(),i(s,l)}))),f=r(`div`,`flex-none border-t border-neutral-200`,_({value:o,label:`↺ ${o} ↔ Working tree`,subject:`back to the default: the main line's tip vs the files on disk`},s===o&&l===``?o:``,()=>{s=o,l=``,h(),i(s,l)}));m.replaceChildren(r(`div`,`flex flex-none items-center gap-1 border-b border-neutral-200 px-2 py-1.5`,e(`Compare two points`,`compare`),e(`One commit`,`commit`)),a,...d===`compare`?[f]:[])}h(),a(e,m)}var ne=/\.(png|jpe?g|gif|webp|avif|bmp|svg)$/i,v={A:`text-emerald-600`,M:`text-amber-600`,D:`text-red-600`},re=30,y=`pier.filesPrefs`,b=50,x=()=>{try{let e=JSON.parse(localStorage.getItem(y)??`{}`);return e&&typeof e==`object`?e:{}}catch{return{}}},S=e=>{let t=e?x()[e]:void 0;return typeof t?.cwd==`string`&&typeof t.base==`string`&&typeof t.head==`string`?{cwd:t.cwd,base:t.base,head:t.head}:null},ie=(e,t)=>{let n=x();delete n[e],n[e]=t;let r=Object.keys(n);for(let e of r.slice(0,Math.max(0,r.length-b)))delete n[e];try{localStorage.setItem(y,JSON.stringify(n))}catch(e){console.warn(`Files: could not remember this folder`,e)}},ae=(e,t=`indigo`)=>{let n=r(`button`,`min-w-0 cursor-pointer truncate rounded-md px-2 py-0.5 text-left font-mono text-[11.5px] ${t===`indigo`?`bg-indigo-50 font-medium text-indigo-700 hover:bg-indigo-100`:`bg-neutral-100 text-neutral-600 hover:bg-neutral-200`}`,e);return n.type=`button`,n};function C(a,c,f,p){let h=``,g=``,_={branch:null,refs:[],commits:[],worktrees:[]},y=`HEAD`,b=``,x=new Map,C=!0,w=!1,T=[],E=new Set,D=null,O=null,k=r(`header`,`flex h-10 flex-none items-center gap-2 border-b border-neutral-200 bg-white px-3`),A=r(`div`,`flex-none border-b border-neutral-200`),j=r(`div`,`min-h-0 flex-1 overflow-y-auto py-1`),oe=r(`aside`,`flex w-64 flex-none flex-col border-r border-neutral-200 text-[12.5px] max-md:h-2/5 max-md:w-full max-md:border-b max-md:border-r-0`,A,j),M=r(`div`,`h-full min-w-0 overflow-auto`),N=r(`div`,`pointer-events-none absolute inset-y-0 right-0 z-20 hidden w-2`),se=r(`section`,`relative min-h-0 min-w-0 flex-1`,M,N);a.append(k,r(`div`,`flex min-h-0 flex-1 max-md:flex-col`,oe,se));let P=(e,t)=>`/api/explorer/${e}?${new URLSearchParams({root:h,...t})}`,F=(e,t)=>`/api/fs/${e}?${new URLSearchParams({root:h,...t})}`,I=(e,t=`text-neutral-400`)=>r(`p`,`px-4 py-3 text-[12.5px] ${t}`,e),L=e=>{let t=0;for(let n of x.keys())n.startsWith(`${e}/`)&&t++;return t};function R(e,t){let n=new Set(t.map(e=>e.name)),r=e?`${e}/`:``;for(let[e,i]of x){if(i.status!==`D`||!e.startsWith(r))continue;let a=e.slice(r.length).split(`/`)[0];n.has(a)||(n.add(a),t.push({name:a,dir:e.slice(r.length).includes(`/`)}))}let i=t;return C&&_.branch&&(i=t.filter(e=>e.dir?L(`${r}${e.name}`)>0:x.has(`${r}${e.name}`))),i.sort((e,t)=>Number(t.dir)-Number(e.dir)||e.name.localeCompare(t.name)),i.map(e=>e.dir?ce(`${r}${e.name}`,e.name):le(`${r}${e.name}`,e.name))}async function z(e,t){try{let{entries:n}=await i(F(`ls`,{path:t}),`could not list this folder`);e.replaceChildren(...R(t,n)),e.childElementCount||e.append(I(C?`No changes.`:`Empty.`))}catch(n){let r=R(t,[]);r.length?e.replaceChildren(...r):e.replaceChildren(I(String(n),`text-red-600`))}}function ce(t,n){let i=L(t),a=[r(`span`,`truncate`,n)];i&&a.push(r(`span`,`ml-auto flex-none rounded bg-amber-100/80 px-1 font-mono text-[10px] text-amber-700`,String(i)));let{el:o,summary:s}=e(``,a);s.className+=` px-2 py-0.5 hover:bg-neutral-100`;let c=r(`div`,`pl-3`);o.append(c);let l=!1,u=()=>{l||(l=!0,c.append(I(`…`)),z(c,t))};return o.ontoggle=()=>{E[o.open?`add`:`delete`](t),o.open&&u()},(C&&_.branch&&!w||E.has(t))&&(o.open=!0,u()),o}function B(e){O?.classList.remove(`bg-indigo-50`,`text-indigo-700`),O=e,e.classList.add(`bg-indigo-50`,`text-indigo-700`)}function le(e,t){let n=x.get(e)?.status,i=r(`button`,`flex w-full cursor-pointer items-center gap-1.5 px-2 py-0.5 pl-6 text-left hover:bg-neutral-100`,r(`span`,`truncate`,t));return n&&i.append(r(`span`,`ml-auto flex-none font-mono text-[10.5px] font-semibold ${v[n]??`text-neutral-500`}`,n)),i.title=e,e===D&&B(i),i.onclick=()=>{B(i),D=e,de(e)},i}let V=()=>void z(j,``),H=(e,t)=>[...e?[r(`span`,`flex-none font-mono text-[10.5px] font-semibold text-emerald-600`,`+${e}`)]:[],...t?[r(`span`,`flex-none font-mono text-[10.5px] font-semibold text-red-600`,`−${t}`)]:[]];function U(e,n,i){let a=x.get(e),o=r(`div`,`sticky top-0 z-10 flex items-center gap-2 border-b border-neutral-200 bg-white px-4 py-1.5 font-mono text-[11.5px] text-neutral-500`,r(`span`,`truncate`,e));a&&(o.append(r(`span`,`flex-none font-semibold ${v[a.status]??``}`,a.status)),o.append(...H(a.add,a.del)));let s=r(`div`,`ml-auto flex flex-none items-center gap-2`);if(i&&s.append(i),n){let n=document.createElement(`a`);n.className=`flex-none text-neutral-400 hover:text-indigo-700 hover:underline`,n.href=F(`file`,{path:e}),n.download=t(e),n.textContent=`Download`,s.append(n)}return o.append(s),o}function ue(e){let t=0;for(;t<e.length;){if(e[t].tone!==`del`){t++;continue}let n=t;for(;t<e.length&&e[t].tone===`del`;)t++;let r=t;for(;t<e.length&&e[t].tone===`add`;)t++;let i=Math.min(r-n,t-r);for(let t=0;t<i;t++){let i=e[n+t],a=e[r+t],o=Math.min(i.text.length,a.text.length),s=0;for(;s<o&&i.text[s]===a.text[s];)s++;let c=0;for(;c<o-s&&i.text[i.text.length-1-c]===a.text[a.text.length-1-c];)c++;s+c!==0&&(i.mark=[s,i.text.length-c],a.mark=[s,a.text.length-c])}}}let W=ve();function G(){N.classList.add(`hidden`),N.replaceChildren(),W.set([],[])}let K=0,q=e=>e===K;function de(e){let t=++K;return x.has(e)?ye(e,t):fe(e,t)}async function fe(e,t){if(!q(t))return;G();let n=F(`file`,{path:e}),i=r(`div`,`min-w-0`);if(M.classList.remove(`flex`,`flex-col`),M.replaceChildren(U(e,!0),i),ne.test(e)){let e=r(`img`,`max-w-full p-4`);e.src=n,e.onerror=()=>i.replaceChildren(I(`Could not load image.`,`text-red-600`)),i.append(e);return}if(e.toLowerCase().endsWith(`.pdf`)){let t=document.createElement(`iframe`);t.className=`h-full w-full`,t.src=n,M.replaceChildren(U(e,!0),t),M.classList.add(`flex`,`flex-col`);return}i.append(I(`…`));let a=await fetch(n);if(!q(t))return;if(!a.ok){let{error:e}=await a.json().catch(()=>({}));i.replaceChildren(I(e??`HTTP ${a.status}`,`text-red-600`));return}if(!(a.headers.get(`content-type`)??``).startsWith(`text/plain`)){i.replaceChildren(I(`Binary file — use Download.`));return}let c=o(await a.text());if(!q(t))return;let l=await s(e);q(t)&&i.replaceChildren(d(c,l))}function pe(e){let t=[],n=0,r=0,i=!1,a=e.split(`
4
- `);a.at(-1)===``&&a.pop();for(let e of a){let a=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(e);if(a){i&&t.push({nums:[``,``],text:`⋯`,tone:``}),[n,r]=[Number(a[1]),Number(a[2])],i=!0;continue}!i||e.startsWith(`\\`)||(e.startsWith(`+`)?t.push({nums:[``,r++],text:e.slice(1),tone:`add`}):e.startsWith(`-`)?t.push({nums:[n++,``],text:e.slice(1),tone:`del`}):t.push({nums:[n++,r++],text:e.slice(1),tone:``}))}return t}function me(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n].tone;if(!r)continue;let i=t.at(-1);i&&i.end===n-1?(i.end=n,(r===`add`&&i.tone===`del`||r===`del`&&i.tone===`add`)&&(i.tone=`mixed`)):t.push({start:n,end:n,tone:r})}return t}let he={add:`bg-emerald-400`,del:`bg-red-400`,mixed:`bg-amber-400`};function ge(e,t,n){N.replaceChildren(...e.map(e=>{let i=r(`button`,`pointer-events-auto absolute w-full cursor-pointer ${he[e.tone]}`);return i.style.top=`${e.start/t*100}%`,i.style.height=`${Math.max(.4,(e.end-e.start+1)/t*100)}%`,i.title=`line ${_e(n,e.start)}`,i.onclick=()=>n[e.start].scrollIntoView({block:`center`}),i})),N.classList.remove(`hidden`)}let _e=(e,t)=>e[t]?.querySelector(`span`)?.textContent?.trim()||String(t+1);function ve(){let e=[],t=[],n=-1,i=r(`span`,`flex-none text-[10.5px] text-neutral-400`),o=r=>{e.length&&(n=(n+r+e.length)%e.length,t[e[n].start].scrollIntoView({block:`center`}),i.textContent=`${n+1}/${e.length}`)},s=()=>e.length>0&&!a.classList.contains(`hidden`),c=(e,t,n,i)=>{let a=r(`button`,`icon-btn flex-none`,e);return a.onclick=()=>o(t),u(a,i,n,()=>o(t),s),a};return{el:r(`div`,`flex flex-none items-center gap-1`,i,c(`↑`,-1,`Previous change`,[`p`,`k`]),c(`↓`,1,`Next change`,[`n`,`j`])),set(r,a){e=r,t=a,n=-1,i.textContent=`${r.length} change${r.length===1?``:`s`}`}}}async function ye(e,t){G(),M.classList.remove(`flex`,`flex-col`);let n=x.get(e)?.status!==`D`;M.replaceChildren(U(e,n),I(`…`));try{let{diff:r}=await i(P(`diff`,{base:y,head:b,file:e,context:`99999`}),`could not read this diff`);if(!q(t))return;if(!r||/^Binary files /m.test(r))return fe(e,t);let a=pe(r);ue(a);let o=await s(e);if(!q(t))return;let c=d(a,o),l=[...c.children],u=me(a);W.set(u,l),M.replaceChildren(U(e,n,W.el),c),ge(u,a.length,l)}catch(n){q(t)&&M.replaceChildren(U(e,!1),I(String(n),`text-red-600`))}}let J=()=>b&&y===`${b}~1`?b:``,be=()=>_.commits.find(e=>e.hash===J())?.subject??``,xe=()=>J()?`${J()} — ${be()||`commit`}`:`${y} ↔ ${b||`working tree`}`,Se=(e,t,n,i)=>{let a=r(`button`,`flex h-6 w-6 flex-none cursor-pointer items-center justify-center rounded-md ${n?`bg-indigo-50 text-indigo-700`:`text-neutral-400 hover:bg-neutral-100 hover:text-neutral-700`}`);return a.innerHTML=e,a.title=t,a.onclick=i,a};function Y(){let e=Se(`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" class="h-3.5 w-3.5"><path d="M2.5 3h11l-4.25 5v4.5l-2.5 1.25V8L2.5 3z" stroke-linejoin="round"/></svg>`,`Show only files that differ`,C,()=>{C=!C,Y(),V()}),t=Se(`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" class="h-3.5 w-3.5"><path d="m4.5 2.5 3.5 3 3.5-3M4.5 13.5l3.5-3 3.5 3" stroke-linecap="round" stroke-linejoin="round"/></svg>`,w?`Restore folders`:`Collapse all folders`,w,()=>{if(w=!w,w)T=[...E],E.clear();else for(let e of T)E.add(e);Y(),V()});if(!_.branch){A.replaceChildren(r(`div`,`flex items-center justify-end gap-1 p-1.5`,t));return}let n=ae(xe());if(J()){let e=_.commits.find(e=>e.hash===J());ee(n,()=>e?m(e):``)}else n.title=`Choose what to diff`;n.onclick=async()=>{await Te(),te(n,_,{base:y,head:b},(e,t)=>{y=e,b=t,Z()},$())};let[i,a]=[0,0];for(let e of x.values())i+=e.add,a+=e.del;A.replaceChildren(r(`div`,`flex flex-col gap-1 p-2`,n,r(`div`,`flex items-center gap-1.5 pl-1`,r(`span`,`text-[11px] text-neutral-400`,`${x.size} changed file${x.size===1?``:`s`}`),...H(i,a),r(`span`,`ml-auto`),e,t)))}let Ce=()=>{g&&h&&ie(g,{cwd:h,base:y,head:b})},X=e=>{let t=e.replace(/~\d+$/,``);return!t||t===`HEAD`||_.refs.some(e=>e.name===t)||_.commits.some(e=>e.hash===t)};async function we(){if(x=new Map,!_.branch)return;let{files:e}=await i(P(`diff`,{base:y,head:b}),`could not read what changed`);for(let t of e)x.set(t.path,{status:t.status,add:t.add,del:t.del});if(x.size<=re)for(let e of x.keys()){let t=e.split(`/`);for(let e=1;e<t.length;e++)E.add(t.slice(0,e).join(`/`))}}async function Z(){Ce();try{await we()}catch(e){Y(),j.replaceChildren(I(String(e),`text-red-600`));return}Y(),V(),D&&de(D)}function Q(){let e=ae(h||`Choose a folder…`,`neutral`);e.className+=` max-w-72`,e.title=`Switch folder`,e.onclick=()=>l(e,_.worktrees.map(e=>({path:e.path,...e.branch?{hint:e.branch}:{}})),h||void 0,f);let t=r(`button`,`icon-btn`,`✕`);t.type=`button`,t.title=`Close Files`,t.setAttribute(`aria-label`,`Close Files`),t.onclick=p,t.classList.add(`ml-auto`),k.replaceChildren(e,r(`span`,`truncate font-mono text-[11.5px] text-neutral-400`,_.branch?`⎇ ${_.branch}`:`no git`),t)}async function Te(){if(h)try{_=await i(P(`git`,{}),`could not read this repository`),Q()}catch(e){M.replaceChildren(I(String(e),`text-red-600`))}}let $=()=>_.refs.some(e=>e.name===`main`)?`main`:_.refs.some(e=>e.name===`master`)?`master`:`HEAD`;async function Ee(){if(Q(),D=null,O=null,E.clear(),G(),M.classList.remove(`flex`,`flex-col`),M.replaceChildren(I(`Select a file.`)),!h){A.replaceChildren(),j.replaceChildren(),M.replaceChildren(I(`No folder yet — pick one from the chip above.`));return}try{_=await i(P(`git`,{}),`could not read this repository`)}catch(e){_={branch:null,refs:[],commits:[],worktrees:[]},M.replaceChildren(I(String(e),`text-red-600`))}let e=S(g),t=e&&e.cwd===h&&X(e.base)&&X(e.head)?e:null;y=t?.base??$(),b=t?.head??``,Q(),await Z()}return n(a,e=>{let t=c(),n=t?.id??``,r=e?.startsWith(`/`)?e:(n===g?h:``)||S(n)?.cwd||t?.cwd||``;if(r===h&&n===g&&j.childElementCount){Q(),Te().then(Z);return}g=n,h=r,Ee()},()=>{G(),M.classList.remove(`flex`,`flex-col`),M.replaceChildren(I(`Select a file.`))})}export{C as createExplorerView};