@hyperdrive.bot/paseo-protocol 0.3.66 → 0.3.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-filter.d.ts +47 -1
- package/dist/agent-filter.js +41 -2
- package/package.json +1 -1
package/dist/agent-filter.d.ts
CHANGED
|
@@ -136,8 +136,21 @@ export declare function deriveAgentOrigin(labels: Record<string, string> | null
|
|
|
136
136
|
* This is a MODE, not a second dimension. AND-ing "created today" with "active
|
|
137
137
|
* today" produces a mostly-empty list; the reader means one question or the
|
|
138
138
|
* other.
|
|
139
|
+
*
|
|
140
|
+
* `archived` (2026-08-28) measures `archivedAt`, so the same spans answer "what
|
|
141
|
+
* did I archive in this period". That question cannot be asked with the
|
|
142
|
+
* `archivedMode` dimension alone: `only` isolates the archive but says nothing
|
|
143
|
+
* about WHEN. The two stay orthogonal - this picks the DATE, that picks the
|
|
144
|
+
* ROWS - and no coupling is needed to make the pair behave, because a session
|
|
145
|
+
* that was never archived has `archivedAt === null` and every caller's resolver
|
|
146
|
+
* yields null, which `isWithinAgentTimeWindow` already refuses to match.
|
|
147
|
+
*
|
|
148
|
+
* The one pairing that is empty by construction is `archived` with
|
|
149
|
+
* `archivedMode: "hide"`: rows that are NOT archived, dated by when they were
|
|
150
|
+
* archived. Surfaces should name that rather than render a bare zero, which
|
|
151
|
+
* reads as a broken filter.
|
|
139
152
|
*/
|
|
140
|
-
export type AgentTimeField = "created" | "active";
|
|
153
|
+
export type AgentTimeField = "created" | "active" | "archived";
|
|
141
154
|
/**
|
|
142
155
|
* The rolling presets. They NEST (`today` is inside `3d` is inside `7d` ...),
|
|
143
156
|
* which is why the span is single-select: OR-ing two always collapses to the
|
|
@@ -173,6 +186,39 @@ export type AgentTimeSelection = {
|
|
|
173
186
|
range: AgentDateRange;
|
|
174
187
|
};
|
|
175
188
|
export declare function isAgentTimeField(value: unknown): value is AgentTimeField;
|
|
189
|
+
/**
|
|
190
|
+
* The field a cycling control lands on from `current`. Wraps at the end.
|
|
191
|
+
*
|
|
192
|
+
* Exported from the protocol so the app's chip cannot drift from the declared
|
|
193
|
+
* list. The two-way flip this replaced (`f === "created" ? "active" : "created"`)
|
|
194
|
+
* made any third member unreachable: the label rendered, no tap could select
|
|
195
|
+
* it. Driving the cycle off AGENT_TIME_FIELDS means a fourth field is
|
|
196
|
+
* selectable the moment it joins the union.
|
|
197
|
+
*/
|
|
198
|
+
export declare function nextAgentTimeField(current: AgentTimeField): AgentTimeField;
|
|
199
|
+
/** The agent timestamps a time field can name. Shapes differ per caller, so this is the union of them. */
|
|
200
|
+
export interface AgentTimeSource {
|
|
201
|
+
createdAt?: Date | null;
|
|
202
|
+
lastActivityAt?: Date | null;
|
|
203
|
+
archivedAt?: Date | null;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Collapses an agent's timestamps to the ONE the reader selected.
|
|
207
|
+
*
|
|
208
|
+
* This is what makes the field a mode rather than a second dimension:
|
|
209
|
+
* everything downstream compares a single value and never learns which field
|
|
210
|
+
* produced it. Exported so the four surfaces that each carried their own copy
|
|
211
|
+
* of this mapping (the app's Sessions screen and workspace tab strip, the
|
|
212
|
+
* daemon's `list_agents`, the CLI's `agent ls`) share one definition.
|
|
213
|
+
*
|
|
214
|
+
* A `switch`, not a ternary. All four copies were written as
|
|
215
|
+
* `field === "created" ? created : active`, which treats every field that is
|
|
216
|
+
* not "created" as "active" - so a new union member compiled clean on all four
|
|
217
|
+
* and silently measured the wrong timestamp while the UI named the new one.
|
|
218
|
+
* Exhaustive here, so a fifth field is a type error instead of a filter that
|
|
219
|
+
* quietly lies.
|
|
220
|
+
*/
|
|
221
|
+
export declare function resolveAgentTimeValue(agent: AgentTimeSource, field: AgentTimeField): Date | null;
|
|
176
222
|
export declare function isAgentTimeWindow(value: unknown): value is AgentTimeWindow;
|
|
177
223
|
/** True for a real `YYYY-MM-DD` calendar day (rejects 2026-02-31). */
|
|
178
224
|
export declare function isAgentDay(value: unknown): value is string;
|
package/dist/agent-filter.js
CHANGED
|
@@ -190,12 +190,51 @@ export function isAgentOrigin(value) {
|
|
|
190
190
|
export function deriveAgentOrigin(labels) {
|
|
191
191
|
return isDelegatedAgent({ labels }) ? "delegated" : "root";
|
|
192
192
|
}
|
|
193
|
-
export const AGENT_TIME_FIELDS = ["created", "active"];
|
|
193
|
+
export const AGENT_TIME_FIELDS = ["created", "active", "archived"];
|
|
194
194
|
export const AGENT_TIME_WINDOWS = ["today", "3d", "7d", "30d", "stale"];
|
|
195
195
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
196
196
|
const DAY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
197
197
|
export function isAgentTimeField(value) {
|
|
198
|
-
return value === "created" || value === "active";
|
|
198
|
+
return value === "created" || value === "active" || value === "archived";
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* The field a cycling control lands on from `current`. Wraps at the end.
|
|
202
|
+
*
|
|
203
|
+
* Exported from the protocol so the app's chip cannot drift from the declared
|
|
204
|
+
* list. The two-way flip this replaced (`f === "created" ? "active" : "created"`)
|
|
205
|
+
* made any third member unreachable: the label rendered, no tap could select
|
|
206
|
+
* it. Driving the cycle off AGENT_TIME_FIELDS means a fourth field is
|
|
207
|
+
* selectable the moment it joins the union.
|
|
208
|
+
*/
|
|
209
|
+
export function nextAgentTimeField(current) {
|
|
210
|
+
const index = AGENT_TIME_FIELDS.indexOf(current);
|
|
211
|
+
return AGENT_TIME_FIELDS[(index + 1) % AGENT_TIME_FIELDS.length] ?? "active";
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Collapses an agent's timestamps to the ONE the reader selected.
|
|
215
|
+
*
|
|
216
|
+
* This is what makes the field a mode rather than a second dimension:
|
|
217
|
+
* everything downstream compares a single value and never learns which field
|
|
218
|
+
* produced it. Exported so the four surfaces that each carried their own copy
|
|
219
|
+
* of this mapping (the app's Sessions screen and workspace tab strip, the
|
|
220
|
+
* daemon's `list_agents`, the CLI's `agent ls`) share one definition.
|
|
221
|
+
*
|
|
222
|
+
* A `switch`, not a ternary. All four copies were written as
|
|
223
|
+
* `field === "created" ? created : active`, which treats every field that is
|
|
224
|
+
* not "created" as "active" - so a new union member compiled clean on all four
|
|
225
|
+
* and silently measured the wrong timestamp while the UI named the new one.
|
|
226
|
+
* Exhaustive here, so a fifth field is a type error instead of a filter that
|
|
227
|
+
* quietly lies.
|
|
228
|
+
*/
|
|
229
|
+
export function resolveAgentTimeValue(agent, field) {
|
|
230
|
+
switch (field) {
|
|
231
|
+
case "created":
|
|
232
|
+
return agent.createdAt ?? null;
|
|
233
|
+
case "active":
|
|
234
|
+
return agent.lastActivityAt ?? null;
|
|
235
|
+
case "archived":
|
|
236
|
+
return agent.archivedAt ?? null;
|
|
237
|
+
}
|
|
199
238
|
}
|
|
200
239
|
export function isAgentTimeWindow(value) {
|
|
201
240
|
return (value === "today" || value === "3d" || value === "7d" || value === "30d" || value === "stale");
|