@agentdeck/shared 0.1.0 → 0.2.3
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/LICENSE +21 -0
- package/dist/adapter.d.ts +18 -3
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +62 -0
- package/dist/adapter.js.map +1 -1
- package/dist/command-builders.d.ts +35 -0
- package/dist/command-builders.d.ts.map +1 -0
- package/dist/command-builders.js +75 -0
- package/dist/command-builders.js.map +1 -0
- package/dist/connection-status.d.ts +42 -0
- package/dist/connection-status.d.ts.map +1 -0
- package/dist/connection-status.js +52 -0
- package/dist/connection-status.js.map +1 -0
- package/dist/d200h-layout.d.ts +131 -0
- package/dist/d200h-layout.d.ts.map +1 -0
- package/dist/d200h-layout.js +627 -0
- package/dist/d200h-layout.js.map +1 -0
- package/dist/design-tokens.d.ts +259 -0
- package/dist/design-tokens.d.ts.map +1 -0
- package/dist/design-tokens.js +156 -0
- package/dist/design-tokens.js.map +1 -0
- package/dist/eval-schema.d.ts +235 -0
- package/dist/eval-schema.d.ts.map +1 -0
- package/dist/eval-schema.js +23 -0
- package/dist/eval-schema.js.map +1 -0
- package/dist/format-utils.d.ts +52 -0
- package/dist/format-utils.d.ts.map +1 -0
- package/dist/format-utils.js +165 -0
- package/dist/format-utils.js.map +1 -0
- package/dist/gateway-protocol.d.ts +391 -0
- package/dist/gateway-protocol.d.ts.map +1 -0
- package/dist/gateway-protocol.js +19 -0
- package/dist/gateway-protocol.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -1
- package/dist/llm-settings.d.ts +52 -0
- package/dist/llm-settings.d.ts.map +1 -0
- package/dist/llm-settings.js +118 -0
- package/dist/llm-settings.js.map +1 -0
- package/dist/net-utils.d.ts +2 -1
- package/dist/net-utils.d.ts.map +1 -1
- package/dist/net-utils.js +100 -3
- package/dist/net-utils.js.map +1 -1
- package/dist/pricing.d.ts +45 -0
- package/dist/pricing.d.ts.map +1 -0
- package/dist/pricing.js +93 -0
- package/dist/pricing.js.map +1 -0
- package/dist/protocol.d.ts +496 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +30 -1
- package/dist/protocol.js.map +1 -1
- package/dist/sample.d.ts +152 -0
- package/dist/sample.d.ts.map +1 -0
- package/dist/sample.js +22 -0
- package/dist/sample.js.map +1 -0
- package/dist/session-utils.d.ts +142 -0
- package/dist/session-utils.d.ts.map +1 -0
- package/dist/session-utils.js +304 -0
- package/dist/session-utils.js.map +1 -0
- package/dist/state-colors.d.ts +16 -0
- package/dist/state-colors.d.ts.map +1 -0
- package/dist/state-colors.js +48 -0
- package/dist/state-colors.js.map +1 -0
- package/dist/states.d.ts +2 -0
- package/dist/states.d.ts.map +1 -1
- package/dist/states.js +6 -1
- package/dist/states.js.map +1 -1
- package/dist/svg-renderers/agent-logos.d.ts +45 -0
- package/dist/svg-renderers/agent-logos.d.ts.map +1 -0
- package/dist/svg-renderers/agent-logos.js +238 -0
- package/dist/svg-renderers/agent-logos.js.map +1 -0
- package/dist/svg-renderers/index.d.ts +4 -0
- package/dist/svg-renderers/index.d.ts.map +1 -0
- package/dist/svg-renderers/index.js +4 -0
- package/dist/svg-renderers/index.js.map +1 -0
- package/dist/svg-renderers/session-slot-renderer.d.ts +78 -0
- package/dist/svg-renderers/session-slot-renderer.d.ts.map +1 -0
- package/dist/svg-renderers/session-slot-renderer.js +506 -0
- package/dist/svg-renderers/session-slot-renderer.js.map +1 -0
- package/dist/svg-renderers/text-utils.d.ts +29 -0
- package/dist/svg-renderers/text-utils.d.ts.map +1 -0
- package/dist/svg-renderers/text-utils.js +122 -0
- package/dist/svg-renderers/text-utils.js.map +1 -0
- package/dist/telemetry-envelope.d.ts +108 -0
- package/dist/telemetry-envelope.d.ts.map +1 -0
- package/dist/telemetry-envelope.js +34 -0
- package/dist/telemetry-envelope.js.map +1 -0
- package/dist/timeline-icons.d.ts +70 -0
- package/dist/timeline-icons.d.ts.map +1 -0
- package/dist/timeline-icons.js +161 -0
- package/dist/timeline-icons.js.map +1 -0
- package/dist/timeline-label.d.ts +38 -0
- package/dist/timeline-label.d.ts.map +1 -0
- package/dist/timeline-label.js +95 -0
- package/dist/timeline-label.js.map +1 -0
- package/dist/timeline-markdown.d.ts +80 -0
- package/dist/timeline-markdown.d.ts.map +1 -0
- package/dist/timeline-markdown.js +221 -0
- package/dist/timeline-markdown.js.map +1 -0
- package/dist/timeline-summarizer.d.ts +37 -0
- package/dist/timeline-summarizer.d.ts.map +1 -0
- package/dist/timeline-summarizer.js +125 -0
- package/dist/timeline-summarizer.js.map +1 -0
- package/dist/timeline.d.ts +135 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +633 -0
- package/dist/timeline.js.map +1 -0
- package/dist/voice-paths.d.ts +4 -0
- package/dist/voice-paths.d.ts.map +1 -1
- package/dist/voice-paths.js +5 -0
- package/dist/voice-paths.js.map +1 -1
- package/package.json +9 -3
package/dist/sample.d.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentDeck SessionSample — the canonical, evaluable unit of agent work.
|
|
3
|
+
*
|
|
4
|
+
* Inspired by Inspect AI's `EvalLog → Sample → Event → Scorer` model. A
|
|
5
|
+
* `SessionSample` is a bounded slice of an agent session (one "task") carrying
|
|
6
|
+
* a typed trajectory of message/tool/model/state events. It is the SINGLE
|
|
7
|
+
* source of truth: both the device-facing TIMELINE and the APME evaluation are
|
|
8
|
+
* projections of this object, rather than two parallel event emitters.
|
|
9
|
+
*
|
|
10
|
+
* Storage: the `tasks` row IS the sample header (id/run_id/index/boundary/…);
|
|
11
|
+
* the typed trajectory lives in the `sample_events` table. See
|
|
12
|
+
* `bridge/src/apme/store.ts`. Logical field names here are camelCase; the DAO
|
|
13
|
+
* maps to snake_case columns.
|
|
14
|
+
*
|
|
15
|
+
* Satisfies the HuggingFace "universal agent eval" requirements:
|
|
16
|
+
* #2 agent identity → SampleModelConfig (model, subagents, mcpServers)
|
|
17
|
+
* #5 trajectory → TrajectoryEvent[] (typed, ordered)
|
|
18
|
+
* #6 tool-use → ToolEvent
|
|
19
|
+
* #7 cost tracking → SampleCost + per-ModelEvent cost/latency
|
|
20
|
+
*/
|
|
21
|
+
import type { AgentType } from './adapter.js';
|
|
22
|
+
import type { ResponseKind, TaskBoundarySignal } from './eval-schema.js';
|
|
23
|
+
export interface SampleModelConfig {
|
|
24
|
+
/** Real model id, e.g. "claude-opus-4-8", "gpt-5-codex", "mlx:qwen3-30b". */
|
|
25
|
+
modelId: string;
|
|
26
|
+
/** "anthropic" | "openai" | "mlx" | "openclaw" | "local" | … */
|
|
27
|
+
provider?: string | null;
|
|
28
|
+
/** Sub-agent names spawned during the sample (Task tool, delegations). */
|
|
29
|
+
subagents?: string[];
|
|
30
|
+
/** MCP server names the agent had access to. */
|
|
31
|
+
mcpServers?: string[];
|
|
32
|
+
}
|
|
33
|
+
export interface SampleCost {
|
|
34
|
+
inputTokens: number;
|
|
35
|
+
outputTokens: number;
|
|
36
|
+
/** Sum over the sample's ModelEvents (priced at ingestion). 0 for local. */
|
|
37
|
+
costUsd: number;
|
|
38
|
+
/** Sum of per-model-call latencies (ms). */
|
|
39
|
+
latencyMs: number;
|
|
40
|
+
}
|
|
41
|
+
export type TrajectoryEventKind = 'user_message' | 'assistant_message' | 'model' | 'tool' | 'state' | 'info';
|
|
42
|
+
export type ToolStatus = 'pending' | 'success' | 'error';
|
|
43
|
+
interface TrajectoryEventBase {
|
|
44
|
+
ts: number;
|
|
45
|
+
/** Index of the turn this event belongs to within the run. */
|
|
46
|
+
turnIndex: number;
|
|
47
|
+
}
|
|
48
|
+
/** A user prompt / message. */
|
|
49
|
+
export interface UserMessageEvent extends TrajectoryEventBase {
|
|
50
|
+
kind: 'user_message';
|
|
51
|
+
text: string;
|
|
52
|
+
}
|
|
53
|
+
/** An assistant response body. `responseKind` lets scorers skip silence. */
|
|
54
|
+
export interface AssistantMessageEvent extends TrajectoryEventBase {
|
|
55
|
+
kind: 'assistant_message';
|
|
56
|
+
text: string;
|
|
57
|
+
responseKind: ResponseKind;
|
|
58
|
+
}
|
|
59
|
+
/** A model invocation with usage + cost. The atom of cost tracking. */
|
|
60
|
+
export interface ModelEvent extends TrajectoryEventBase {
|
|
61
|
+
kind: 'model';
|
|
62
|
+
model: string;
|
|
63
|
+
inputTokens: number;
|
|
64
|
+
outputTokens: number;
|
|
65
|
+
/** Priced at ingestion via shared/src/pricing.ts. 0 for local models. */
|
|
66
|
+
costUsd: number;
|
|
67
|
+
latencyMs: number;
|
|
68
|
+
}
|
|
69
|
+
/** A single tool call. The PreToolUse/PostToolUse pair collapses into one row. */
|
|
70
|
+
export interface ToolEvent extends TrajectoryEventBase {
|
|
71
|
+
kind: 'tool';
|
|
72
|
+
name: string;
|
|
73
|
+
input?: unknown;
|
|
74
|
+
output?: unknown;
|
|
75
|
+
error?: string | null;
|
|
76
|
+
status?: ToolStatus;
|
|
77
|
+
}
|
|
78
|
+
/** An agent-state machine transition (idle → processing → awaiting …). */
|
|
79
|
+
export interface StateTransitionEvent extends TrajectoryEventBase {
|
|
80
|
+
kind: 'state';
|
|
81
|
+
from?: string | null;
|
|
82
|
+
to: string;
|
|
83
|
+
}
|
|
84
|
+
/** Free-form annotation: memory recall, errors, boundary markers. */
|
|
85
|
+
export interface InfoEvent extends TrajectoryEventBase {
|
|
86
|
+
kind: 'info';
|
|
87
|
+
label: string;
|
|
88
|
+
detail?: string | null;
|
|
89
|
+
}
|
|
90
|
+
export type TrajectoryEvent = UserMessageEvent | AssistantMessageEvent | ModelEvent | ToolEvent | StateTransitionEvent | InfoEvent;
|
|
91
|
+
export interface SampleScore {
|
|
92
|
+
/** Scorer name, e.g. "deterministic", "judge", "outcome", "trajectory". */
|
|
93
|
+
scorer: string;
|
|
94
|
+
/** Axis within the scorer, e.g. "tests_pass", "overall", "tool_efficiency". */
|
|
95
|
+
metric: string;
|
|
96
|
+
/** [0,1]. */
|
|
97
|
+
score: number;
|
|
98
|
+
reasoning?: string | null;
|
|
99
|
+
}
|
|
100
|
+
export interface SessionSample {
|
|
101
|
+
/** Equals tasks.id — the task row is the sample header. */
|
|
102
|
+
id: string;
|
|
103
|
+
runId: string;
|
|
104
|
+
sessionId: string;
|
|
105
|
+
agentType: AgentType;
|
|
106
|
+
/** task_index within the run. */
|
|
107
|
+
index: number;
|
|
108
|
+
boundarySignal: TaskBoundarySignal;
|
|
109
|
+
startedAt: number;
|
|
110
|
+
endedAt?: number | null;
|
|
111
|
+
/** req #2 — agent identity. */
|
|
112
|
+
model: SampleModelConfig;
|
|
113
|
+
projectName?: string | null;
|
|
114
|
+
projectPath?: string | null;
|
|
115
|
+
/** req #5 — the ordered typed trajectory. */
|
|
116
|
+
events: TrajectoryEvent[];
|
|
117
|
+
/** req #7 — aggregated cost, projected from ModelEvents. */
|
|
118
|
+
cost: SampleCost;
|
|
119
|
+
/** Scorer outputs (present once evaluated). */
|
|
120
|
+
scores?: SampleScore[];
|
|
121
|
+
summary?: string | null;
|
|
122
|
+
outcome?: string | null;
|
|
123
|
+
compositeScore?: number | null;
|
|
124
|
+
taskCategory?: string | null;
|
|
125
|
+
}
|
|
126
|
+
/** One typed trajectory event as stored. Logical (camelCase) mirror of the
|
|
127
|
+
* `sample_events` columns. `payload` is JSON: message text, tool input/output,
|
|
128
|
+
* state from/to, or info detail depending on `kind`. */
|
|
129
|
+
export interface ApmeSampleEventRow {
|
|
130
|
+
id?: number;
|
|
131
|
+
taskId: string;
|
|
132
|
+
runId: string;
|
|
133
|
+
turnIndex?: number | null;
|
|
134
|
+
/** Monotonic order within the task. */
|
|
135
|
+
seq: number;
|
|
136
|
+
ts: number;
|
|
137
|
+
kind: TrajectoryEventKind;
|
|
138
|
+
model?: string | null;
|
|
139
|
+
inputTokens?: number | null;
|
|
140
|
+
outputTokens?: number | null;
|
|
141
|
+
costUsd?: number | null;
|
|
142
|
+
latencyMs?: number | null;
|
|
143
|
+
toolName?: string | null;
|
|
144
|
+
toolStatus?: ToolStatus | string | null;
|
|
145
|
+
toolError?: string | null;
|
|
146
|
+
/** JSON payload (message text / tool input+output / info detail / state). */
|
|
147
|
+
payload?: string | null;
|
|
148
|
+
/** Storage-time dedup key: sha1(kind | turnIndex | semanticCore). UNIQUE per task. */
|
|
149
|
+
dedupKey?: string | null;
|
|
150
|
+
}
|
|
151
|
+
export {};
|
|
152
|
+
//# sourceMappingURL=sample.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sample.d.ts","sourceRoot":"","sources":["../src/sample.ts"],"names":[],"mappings":"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"}
|
package/dist/sample.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentDeck SessionSample — the canonical, evaluable unit of agent work.
|
|
3
|
+
*
|
|
4
|
+
* Inspired by Inspect AI's `EvalLog → Sample → Event → Scorer` model. A
|
|
5
|
+
* `SessionSample` is a bounded slice of an agent session (one "task") carrying
|
|
6
|
+
* a typed trajectory of message/tool/model/state events. It is the SINGLE
|
|
7
|
+
* source of truth: both the device-facing TIMELINE and the APME evaluation are
|
|
8
|
+
* projections of this object, rather than two parallel event emitters.
|
|
9
|
+
*
|
|
10
|
+
* Storage: the `tasks` row IS the sample header (id/run_id/index/boundary/…);
|
|
11
|
+
* the typed trajectory lives in the `sample_events` table. See
|
|
12
|
+
* `bridge/src/apme/store.ts`. Logical field names here are camelCase; the DAO
|
|
13
|
+
* maps to snake_case columns.
|
|
14
|
+
*
|
|
15
|
+
* Satisfies the HuggingFace "universal agent eval" requirements:
|
|
16
|
+
* #2 agent identity → SampleModelConfig (model, subagents, mcpServers)
|
|
17
|
+
* #5 trajectory → TrajectoryEvent[] (typed, ordered)
|
|
18
|
+
* #6 tool-use → ToolEvent
|
|
19
|
+
* #7 cost tracking → SampleCost + per-ModelEvent cost/latency
|
|
20
|
+
*/
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=sample.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sample.js","sourceRoot":"","sources":["../src/sample.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session-utils.ts — Shared session ordering, numbering, and tier grouping.
|
|
3
|
+
* Single source of truth used by: TUI renderer, Plugin, Android, Apple, MenuBarExtra.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Rank agent states by priority (lower = higher priority).
|
|
7
|
+
* processing=0, awaiting=1, idle=2, disconnected=3, unknown=4.
|
|
8
|
+
*/
|
|
9
|
+
export declare function stateRank(state: string | undefined): number;
|
|
10
|
+
export type SessionTier = 'attention' | 'active' | 'idle';
|
|
11
|
+
export declare function sessionTier(state: string | undefined): SessionTier;
|
|
12
|
+
/**
|
|
13
|
+
* Rank agent types for stable ordering.
|
|
14
|
+
* openclaw=0 (always first), claude-code=1, codex-cli=2, codex-app=3, opencode=4, antigravity=5, others=6.
|
|
15
|
+
*/
|
|
16
|
+
export declare function agentTypeRank(agentType: string | undefined): number;
|
|
17
|
+
export declare function naturalLabelCompare(a: string | undefined, b: string | undefined): number;
|
|
18
|
+
export interface GatewayVisibilityFlags {
|
|
19
|
+
/** TCP port 18789 reachable — a topology hint only, NOT proof commands route. */
|
|
20
|
+
gatewayAvailable?: boolean;
|
|
21
|
+
/** Gateway WS handshake + auth succeeded — proof commands can route. */
|
|
22
|
+
gatewayConnected?: boolean;
|
|
23
|
+
/** `openclaw doctor`/health reports an error. */
|
|
24
|
+
gatewayHasError?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* SSOT: the daemon injects the virtual `openclaw` session iff this holds.
|
|
28
|
+
*
|
|
29
|
+
* "Active" = authenticated / can-route = the Gateway WS handshake+auth
|
|
30
|
+
* succeeded (`gatewayConnected`). Reachability (`gatewayAvailable`) and health
|
|
31
|
+
* (`gatewayHasError`) are topology/status hints only and MUST NOT materialize a
|
|
32
|
+
* session — surfacing them as a session is what made OpenClaw "stick" on
|
|
33
|
+
* devices after it was effectively off.
|
|
34
|
+
*
|
|
35
|
+
* Hand-mirrored in Swift `DashboardDataRules.isOpenClawSessionActive`
|
|
36
|
+
* (apple/AgentDeck/Model/Protocol.swift) and Kotlin `isOpenClawSessionActive`
|
|
37
|
+
* (android/.../ui/eink/EinkFormatUtils.kt) — keep all three in lockstep.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isOpenClawSessionActive(flags: GatewayVisibilityFlags): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Consumer SSOT: render OpenClaw iff the daemon actually emitted the session.
|
|
42
|
+
* Consumers must NOT re-derive OpenClaw visibility from raw gateway flags;
|
|
43
|
+
* the daemon source is the single authority. Hand-mirrored in Swift/Kotlin.
|
|
44
|
+
*/
|
|
45
|
+
export declare function hasOpenClawSession<T extends {
|
|
46
|
+
agentType?: string;
|
|
47
|
+
}>(sessions: readonly T[]): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Sort sessions with stable ordering that does NOT jump on state changes.
|
|
50
|
+
*
|
|
51
|
+
* Order: agentType (openclaw first → claude-code → codex → opencode → antigravity)
|
|
52
|
+
* → projectName alphabetically
|
|
53
|
+
* → startedAt ascending (oldest first) for stability
|
|
54
|
+
* → id as final tiebreaker
|
|
55
|
+
*
|
|
56
|
+
* Returns a new array (never mutates input).
|
|
57
|
+
*/
|
|
58
|
+
export declare function sortSessions<T extends {
|
|
59
|
+
state?: string;
|
|
60
|
+
projectName?: string;
|
|
61
|
+
agentType?: string;
|
|
62
|
+
startedAt?: string;
|
|
63
|
+
id?: string;
|
|
64
|
+
}>(sessions: T[]): T[];
|
|
65
|
+
export interface FoldableSession {
|
|
66
|
+
id: string;
|
|
67
|
+
projectName?: string;
|
|
68
|
+
agentType?: string;
|
|
69
|
+
state?: string;
|
|
70
|
+
startedAt?: string;
|
|
71
|
+
currentTool?: string;
|
|
72
|
+
groupSize?: number;
|
|
73
|
+
foldedSessionIds?: string[];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Collapse Codex companion-task rows for the same project into one display
|
|
77
|
+
* session. Raw rows remain authoritative inside the daemon; every user-facing
|
|
78
|
+
* surface should count this folded shape so completed one-turn Codex threads do
|
|
79
|
+
* not look like simultaneously running sessions.
|
|
80
|
+
*/
|
|
81
|
+
export declare function foldCodexSessionsForDisplay<T extends FoldableSession>(sessions: T[]): T[];
|
|
82
|
+
export interface SessionDisplayInfo {
|
|
83
|
+
/** Original session (unmodified) */
|
|
84
|
+
session: {
|
|
85
|
+
id: string;
|
|
86
|
+
projectName: string;
|
|
87
|
+
agentType?: string;
|
|
88
|
+
state?: string;
|
|
89
|
+
[key: string]: unknown;
|
|
90
|
+
};
|
|
91
|
+
/** Display name with optional #N suffix */
|
|
92
|
+
displayName: string;
|
|
93
|
+
/** Session tier for UI grouping */
|
|
94
|
+
tier: SessionTier;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Assign display names with #N suffixes for duplicate (projectName, agentType) tuples.
|
|
98
|
+
* Input is NOT mutated. Returns new display info objects.
|
|
99
|
+
*
|
|
100
|
+
* @param sessions - Already-sorted sessions array
|
|
101
|
+
*/
|
|
102
|
+
export declare function assignDisplayNames<T extends {
|
|
103
|
+
id: string;
|
|
104
|
+
projectName: string;
|
|
105
|
+
agentType?: string;
|
|
106
|
+
state?: string;
|
|
107
|
+
}>(sessions: T[]): (SessionDisplayInfo & {
|
|
108
|
+
session: T;
|
|
109
|
+
})[];
|
|
110
|
+
/**
|
|
111
|
+
* Normalize a project name for grouping: strip any path to the basename and
|
|
112
|
+
* drop a trailing " #N" duplicate suffix so "Foo #1" / "Foo #2" compare equal.
|
|
113
|
+
* Mirrors office.cpp `normProject`.
|
|
114
|
+
*/
|
|
115
|
+
export declare function normalizeProjectForGrouping(project: string | undefined): string;
|
|
116
|
+
/**
|
|
117
|
+
* When two normalized project names belong to the same work group, return the
|
|
118
|
+
* shared group key (the common stem); otherwise null. Mirrors office.cpp
|
|
119
|
+
* `sameProjectGroup`:
|
|
120
|
+
* - exact (case-insensitive) match → group
|
|
121
|
+
* - one extends the other at a delimiter ("foo-bar" + "foo-bar-1") or they
|
|
122
|
+
* diverge after a shared delimiter-aligned stem ("…-broken-a" + "…-broken-b")
|
|
123
|
+
* - conservative: only long multi-token stems fuse (stem ≥ 14 chars with
|
|
124
|
+
* ≥ 2 delimiters on both sides), so short siblings like "agentdeck-ios" /
|
|
125
|
+
* "agentdeck-android" stay separate.
|
|
126
|
+
*/
|
|
127
|
+
export declare function projectGroupKey(a: string, b: string): string | null;
|
|
128
|
+
export interface ProjectGroup<T> {
|
|
129
|
+
/** Group label — the shared stem, or the (normalized) project name for singletons. */
|
|
130
|
+
key: string;
|
|
131
|
+
/** True when ≥2 members fused (render a group header); singletons render flat. */
|
|
132
|
+
grouped: boolean;
|
|
133
|
+
members: T[];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Cluster an ordered session list into project groups, preserving the input
|
|
137
|
+
* order (first member's position anchors the group; members keep relative
|
|
138
|
+
* order). Greedy pairwise fusion with a growing group key, exactly like the
|
|
139
|
+
* office.cpp huddle builder.
|
|
140
|
+
*/
|
|
141
|
+
export declare function groupSessionsByProject<T>(items: readonly T[], projectOf: (item: T) => string | undefined): ProjectGroup<T>[];
|
|
142
|
+
//# sourceMappingURL=session-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-utils.d.ts","sourceRoot":"","sources":["../src/session-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAU3D;AAID,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE1D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAWlE;AAID;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUnE;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAExF;AAID,MAAM,WAAW,sBAAsB;IACrC,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iDAAiD;IACjD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAE9E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,GAAG,OAAO,CAEpG;AAID;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAsBxJ;AAID,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS,eAAe,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAqBzF;AA6CD,MAAM,WAAW,kBAAkB;IACjC,oCAAoC;IACpC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACzG,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,IAAI,EAAE,WAAW,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAClH,QAAQ,EAAE,CAAC,EAAE,GACZ,CAAC,kBAAkB,GAAG;IAAE,OAAO,EAAE,CAAC,CAAA;CAAE,CAAC,EAAE,CAsBzC;AA4BD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAK/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBnE;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,sFAAsF;IACtF,GAAG,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,CAAC,EAAE,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,GACzC,YAAY,CAAC,CAAC,CAAC,EAAE,CAsBnB"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session-utils.ts — Shared session ordering, numbering, and tier grouping.
|
|
3
|
+
* Single source of truth used by: TUI renderer, Plugin, Android, Apple, MenuBarExtra.
|
|
4
|
+
*/
|
|
5
|
+
// ===== State Ranking =====
|
|
6
|
+
/**
|
|
7
|
+
* Rank agent states by priority (lower = higher priority).
|
|
8
|
+
* processing=0, awaiting=1, idle=2, disconnected=3, unknown=4.
|
|
9
|
+
*/
|
|
10
|
+
export function stateRank(state) {
|
|
11
|
+
switch (state) {
|
|
12
|
+
case 'processing': return 0;
|
|
13
|
+
case 'awaiting_permission':
|
|
14
|
+
case 'awaiting_option':
|
|
15
|
+
case 'awaiting_diff': return 1;
|
|
16
|
+
case 'idle': return 2;
|
|
17
|
+
case 'disconnected': return 3;
|
|
18
|
+
default: return 4;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function sessionTier(state) {
|
|
22
|
+
switch (state) {
|
|
23
|
+
case 'awaiting_permission':
|
|
24
|
+
case 'awaiting_option':
|
|
25
|
+
case 'awaiting_diff':
|
|
26
|
+
return 'attention';
|
|
27
|
+
case 'processing':
|
|
28
|
+
return 'active';
|
|
29
|
+
default:
|
|
30
|
+
return 'idle';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// ===== Agent Type Ranking (stable ordering by agent kind) =====
|
|
34
|
+
/**
|
|
35
|
+
* Rank agent types for stable ordering.
|
|
36
|
+
* openclaw=0 (always first), claude-code=1, codex-cli=2, codex-app=3, opencode=4, antigravity=5, others=6.
|
|
37
|
+
*/
|
|
38
|
+
export function agentTypeRank(agentType) {
|
|
39
|
+
switch (agentType) {
|
|
40
|
+
case 'openclaw': return 0;
|
|
41
|
+
case 'claude-code': return 1;
|
|
42
|
+
case 'codex-cli': return 2;
|
|
43
|
+
case 'codex-app': return 3;
|
|
44
|
+
case 'opencode': return 4;
|
|
45
|
+
case 'antigravity': return 5;
|
|
46
|
+
default: return 6;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function naturalLabelCompare(a, b) {
|
|
50
|
+
return (a || '').localeCompare(b || '', undefined, { numeric: true, sensitivity: 'base' });
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* SSOT: the daemon injects the virtual `openclaw` session iff this holds.
|
|
54
|
+
*
|
|
55
|
+
* "Active" = authenticated / can-route = the Gateway WS handshake+auth
|
|
56
|
+
* succeeded (`gatewayConnected`). Reachability (`gatewayAvailable`) and health
|
|
57
|
+
* (`gatewayHasError`) are topology/status hints only and MUST NOT materialize a
|
|
58
|
+
* session — surfacing them as a session is what made OpenClaw "stick" on
|
|
59
|
+
* devices after it was effectively off.
|
|
60
|
+
*
|
|
61
|
+
* Hand-mirrored in Swift `DashboardDataRules.isOpenClawSessionActive`
|
|
62
|
+
* (apple/AgentDeck/Model/Protocol.swift) and Kotlin `isOpenClawSessionActive`
|
|
63
|
+
* (android/.../ui/eink/EinkFormatUtils.kt) — keep all three in lockstep.
|
|
64
|
+
*/
|
|
65
|
+
export function isOpenClawSessionActive(flags) {
|
|
66
|
+
return flags.gatewayConnected === true;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Consumer SSOT: render OpenClaw iff the daemon actually emitted the session.
|
|
70
|
+
* Consumers must NOT re-derive OpenClaw visibility from raw gateway flags;
|
|
71
|
+
* the daemon source is the single authority. Hand-mirrored in Swift/Kotlin.
|
|
72
|
+
*/
|
|
73
|
+
export function hasOpenClawSession(sessions) {
|
|
74
|
+
return sessions.some(s => s.agentType === 'openclaw');
|
|
75
|
+
}
|
|
76
|
+
// ===== Sorting =====
|
|
77
|
+
/**
|
|
78
|
+
* Sort sessions with stable ordering that does NOT jump on state changes.
|
|
79
|
+
*
|
|
80
|
+
* Order: agentType (openclaw first → claude-code → codex → opencode → antigravity)
|
|
81
|
+
* → projectName alphabetically
|
|
82
|
+
* → startedAt ascending (oldest first) for stability
|
|
83
|
+
* → id as final tiebreaker
|
|
84
|
+
*
|
|
85
|
+
* Returns a new array (never mutates input).
|
|
86
|
+
*/
|
|
87
|
+
export function sortSessions(sessions) {
|
|
88
|
+
return [...sessions].sort((a, b) => {
|
|
89
|
+
// 1. Agent type group (openclaw first, then by agent kind)
|
|
90
|
+
const typeRank = agentTypeRank(a.agentType) - agentTypeRank(b.agentType);
|
|
91
|
+
if (typeRank !== 0)
|
|
92
|
+
return typeRank;
|
|
93
|
+
// 2. Project name alphabetically with numeric chunks (Agent 2 before
|
|
94
|
+
// Agent 10). Must match Swift DashboardDataRules.naturalLabelCompare
|
|
95
|
+
// and Android naturalLabelCompare, otherwise numbered sessions render
|
|
96
|
+
// in different order on Stream Deck vs. Apple/Android.
|
|
97
|
+
const nameCompare = naturalLabelCompare(a.projectName, b.projectName);
|
|
98
|
+
if (nameCompare !== 0)
|
|
99
|
+
return nameCompare;
|
|
100
|
+
// 3. Start time ascending (oldest first = stable position)
|
|
101
|
+
if (a.startedAt && b.startedAt) {
|
|
102
|
+
const diff = new Date(a.startedAt).getTime() - new Date(b.startedAt).getTime();
|
|
103
|
+
if (diff !== 0)
|
|
104
|
+
return diff;
|
|
105
|
+
}
|
|
106
|
+
// 4. Session ID as final tiebreaker
|
|
107
|
+
return naturalLabelCompare(a.id, b.id);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Collapse Codex companion-task rows for the same project into one display
|
|
112
|
+
* session. Raw rows remain authoritative inside the daemon; every user-facing
|
|
113
|
+
* surface should count this folded shape so completed one-turn Codex threads do
|
|
114
|
+
* not look like simultaneously running sessions.
|
|
115
|
+
*/
|
|
116
|
+
export function foldCodexSessionsForDisplay(sessions) {
|
|
117
|
+
const passthrough = [];
|
|
118
|
+
const codexByProject = new Map();
|
|
119
|
+
for (const session of sessions) {
|
|
120
|
+
const project = session.projectName?.trim();
|
|
121
|
+
if (!isCodexSession(session) || !project) {
|
|
122
|
+
passthrough.push(session);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const key = `${codexDisplayKind(session)}:${project.toLocaleLowerCase()}`;
|
|
126
|
+
const group = codexByProject.get(key);
|
|
127
|
+
if (group)
|
|
128
|
+
group.push(session);
|
|
129
|
+
else
|
|
130
|
+
codexByProject.set(key, [session]);
|
|
131
|
+
}
|
|
132
|
+
for (const group of codexByProject.values()) {
|
|
133
|
+
passthrough.push(foldCodexProjectGroup(group));
|
|
134
|
+
}
|
|
135
|
+
return passthrough;
|
|
136
|
+
}
|
|
137
|
+
function isCodexSession(session) {
|
|
138
|
+
return session.agentType === 'codex-cli' || session.agentType === 'codex-app' || session.id.startsWith('codex:');
|
|
139
|
+
}
|
|
140
|
+
function codexDisplayKind(session) {
|
|
141
|
+
return session.agentType === 'codex-app' ? 'codex-app' : 'codex-cli';
|
|
142
|
+
}
|
|
143
|
+
function foldCodexProjectGroup(group) {
|
|
144
|
+
if (group.length <= 1)
|
|
145
|
+
return group[0];
|
|
146
|
+
const ranked = [...group].sort((a, b) => {
|
|
147
|
+
const rankDiff = stateRank(a.state) - stateRank(b.state);
|
|
148
|
+
if (rankDiff !== 0)
|
|
149
|
+
return rankDiff;
|
|
150
|
+
const aStarted = a.startedAt ? new Date(a.startedAt).getTime() : Number.NEGATIVE_INFINITY;
|
|
151
|
+
const bStarted = b.startedAt ? new Date(b.startedAt).getTime() : Number.NEGATIVE_INFINITY;
|
|
152
|
+
if (aStarted !== bStarted)
|
|
153
|
+
return bStarted - aStarted;
|
|
154
|
+
return a.id.localeCompare(b.id);
|
|
155
|
+
});
|
|
156
|
+
const representative = ranked[0];
|
|
157
|
+
const foldedIds = group.flatMap(s => s.foldedSessionIds ?? [s.id]);
|
|
158
|
+
const groupSize = group.reduce((total, s) => total + (s.groupSize ?? 1), 0);
|
|
159
|
+
const currentTool = ranked.find(s => stateRank(s.state) === 0 && s.currentTool?.trim())?.currentTool;
|
|
160
|
+
const folded = {
|
|
161
|
+
...representative,
|
|
162
|
+
state: ranked[0].state,
|
|
163
|
+
groupSize,
|
|
164
|
+
foldedSessionIds: foldedIds,
|
|
165
|
+
};
|
|
166
|
+
if (currentTool) {
|
|
167
|
+
folded.currentTool = currentTool;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
delete folded.currentTool;
|
|
171
|
+
}
|
|
172
|
+
return folded;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Assign display names with #N suffixes for duplicate (projectName, agentType) tuples.
|
|
176
|
+
* Input is NOT mutated. Returns new display info objects.
|
|
177
|
+
*
|
|
178
|
+
* @param sessions - Already-sorted sessions array
|
|
179
|
+
*/
|
|
180
|
+
export function assignDisplayNames(sessions) {
|
|
181
|
+
// Count occurrences of each (projectName, agentType) pair
|
|
182
|
+
const counts = new Map();
|
|
183
|
+
for (const s of sessions) {
|
|
184
|
+
const key = `${s.projectName}:${s.agentType || ''}`;
|
|
185
|
+
counts.set(key, (counts.get(key) || 0) + 1);
|
|
186
|
+
}
|
|
187
|
+
// Assign sequential numbers
|
|
188
|
+
const seq = new Map();
|
|
189
|
+
return sessions.map(s => {
|
|
190
|
+
const key = `${s.projectName}:${s.agentType || ''}`;
|
|
191
|
+
const n = (seq.get(key) || 0) + 1;
|
|
192
|
+
seq.set(key, n);
|
|
193
|
+
const needsSuffix = (counts.get(key) || 1) > 1;
|
|
194
|
+
const displayName = needsSuffix ? `${s.projectName} #${n}` : s.projectName;
|
|
195
|
+
return {
|
|
196
|
+
session: s,
|
|
197
|
+
displayName,
|
|
198
|
+
tier: sessionTier(s.state),
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// ===== Project-Prefix Grouping (IPS10 office huddle port) =====
|
|
203
|
+
//
|
|
204
|
+
// The IPS10 terrarium (esp32/src/ui/terrarium/office.cpp — normProject /
|
|
205
|
+
// sameProjectGroup) clusters sessions whose project names share a long
|
|
206
|
+
// delimiter-aligned prefix into one "work huddle": worktree/task folders like
|
|
207
|
+
// `xteink-x3-x4-japanese-broken-claude-glm` / `…-broken-codex` read as one
|
|
208
|
+
// unit of work, not N unrelated sessions. This is the SSOT port so the other
|
|
209
|
+
// dashboards' session lists (Android tablet SessionListPanel.kt, Apple
|
|
210
|
+
// SessionListPanel.swift — hand-mirrored, keep in lockstep) group the same way.
|
|
211
|
+
function isProjectDelim(c) {
|
|
212
|
+
return c === '-' || c === '_' || c === ' ' || c === '.';
|
|
213
|
+
}
|
|
214
|
+
function trimProjectTail(s) {
|
|
215
|
+
let n = s.length;
|
|
216
|
+
while (n > 0 && (isProjectDelim(s[n - 1]) || s[n - 1] === '#'))
|
|
217
|
+
n--;
|
|
218
|
+
return s.slice(0, n);
|
|
219
|
+
}
|
|
220
|
+
function projectDelimCount(s, len) {
|
|
221
|
+
let count = 0;
|
|
222
|
+
for (let i = 0; i < len && i < s.length; i++)
|
|
223
|
+
if (isProjectDelim(s[i]))
|
|
224
|
+
count++;
|
|
225
|
+
return count;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Normalize a project name for grouping: strip any path to the basename and
|
|
229
|
+
* drop a trailing " #N" duplicate suffix so "Foo #1" / "Foo #2" compare equal.
|
|
230
|
+
* Mirrors office.cpp `normProject`.
|
|
231
|
+
*/
|
|
232
|
+
export function normalizeProjectForGrouping(project) {
|
|
233
|
+
const raw = (project || '').trim();
|
|
234
|
+
const base = raw.split('/').filter(Boolean).pop() || raw;
|
|
235
|
+
const m = base.match(/^(.*?)\s*#\d+$/);
|
|
236
|
+
return trimProjectTail(m ? m[1] : base);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* When two normalized project names belong to the same work group, return the
|
|
240
|
+
* shared group key (the common stem); otherwise null. Mirrors office.cpp
|
|
241
|
+
* `sameProjectGroup`:
|
|
242
|
+
* - exact (case-insensitive) match → group
|
|
243
|
+
* - one extends the other at a delimiter ("foo-bar" + "foo-bar-1") or they
|
|
244
|
+
* diverge after a shared delimiter-aligned stem ("…-broken-a" + "…-broken-b")
|
|
245
|
+
* - conservative: only long multi-token stems fuse (stem ≥ 14 chars with
|
|
246
|
+
* ≥ 2 delimiters on both sides), so short siblings like "agentdeck-ios" /
|
|
247
|
+
* "agentdeck-android" stay separate.
|
|
248
|
+
*/
|
|
249
|
+
export function projectGroupKey(a, b) {
|
|
250
|
+
let i = 0;
|
|
251
|
+
let lastDelim = -1;
|
|
252
|
+
const n = Math.min(a.length, b.length);
|
|
253
|
+
while (i < n && a[i].toLowerCase() === b[i].toLowerCase()) {
|
|
254
|
+
if (isProjectDelim(a[i]))
|
|
255
|
+
lastDelim = i;
|
|
256
|
+
i++;
|
|
257
|
+
}
|
|
258
|
+
if (i === a.length && i === b.length)
|
|
259
|
+
return a;
|
|
260
|
+
let stemLen = -1;
|
|
261
|
+
if (i === a.length && i < b.length && isProjectDelim(b[i]))
|
|
262
|
+
stemLen = i;
|
|
263
|
+
else if (i === b.length && i < a.length && isProjectDelim(a[i]))
|
|
264
|
+
stemLen = i;
|
|
265
|
+
else if (lastDelim > 0)
|
|
266
|
+
stemLen = lastDelim;
|
|
267
|
+
if (stemLen < 14 || projectDelimCount(a, stemLen) < 2 || projectDelimCount(b, stemLen) < 2) {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
const key = trimProjectTail(a.slice(0, stemLen));
|
|
271
|
+
return key.length > 0 ? key : null;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Cluster an ordered session list into project groups, preserving the input
|
|
275
|
+
* order (first member's position anchors the group; members keep relative
|
|
276
|
+
* order). Greedy pairwise fusion with a growing group key, exactly like the
|
|
277
|
+
* office.cpp huddle builder.
|
|
278
|
+
*/
|
|
279
|
+
export function groupSessionsByProject(items, projectOf) {
|
|
280
|
+
const groups = [];
|
|
281
|
+
const done = new Array(items.length).fill(false);
|
|
282
|
+
for (let a = 0; a < items.length; a++) {
|
|
283
|
+
if (done[a])
|
|
284
|
+
continue;
|
|
285
|
+
const na = normalizeProjectForGrouping(projectOf(items[a]));
|
|
286
|
+
let key = na;
|
|
287
|
+
const members = [items[a]];
|
|
288
|
+
done[a] = true;
|
|
289
|
+
for (let b = a + 1; b < items.length; b++) {
|
|
290
|
+
if (done[b])
|
|
291
|
+
continue;
|
|
292
|
+
const nb = normalizeProjectForGrouping(projectOf(items[b]));
|
|
293
|
+
const nextKey = projectGroupKey(key, nb) ?? projectGroupKey(na, nb);
|
|
294
|
+
if (nextKey) {
|
|
295
|
+
key = nextKey;
|
|
296
|
+
members.push(items[b]);
|
|
297
|
+
done[b] = true;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
groups.push({ key, grouped: members.length > 1, members });
|
|
301
|
+
}
|
|
302
|
+
return groups;
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=session-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-utils.js","sourceRoot":"","sources":["../src/session-utils.ts"],"names":[],"mappings":"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"}
|