@made-by-moonlight/athene-core 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +241 -0
- package/dist/activity-events.d.ts +42 -0
- package/dist/activity-events.d.ts.map +1 -0
- package/dist/activity-events.js +192 -0
- package/dist/activity-events.js.map +1 -0
- package/dist/activity-log.d.ts +71 -0
- package/dist/activity-log.d.ts.map +1 -0
- package/dist/activity-log.js +203 -0
- package/dist/activity-log.js.map +1 -0
- package/dist/activity-signal.d.ts +20 -0
- package/dist/activity-signal.d.ts.map +1 -0
- package/dist/activity-signal.js +91 -0
- package/dist/activity-signal.js.map +1 -0
- package/dist/agent-report.d.ts +148 -0
- package/dist/agent-report.d.ts.map +1 -0
- package/dist/agent-report.js +516 -0
- package/dist/agent-report.js.map +1 -0
- package/dist/agent-selection.d.ts +31 -0
- package/dist/agent-selection.d.ts.map +1 -0
- package/dist/agent-selection.js +69 -0
- package/dist/agent-selection.js.map +1 -0
- package/dist/agent-workspace-hooks.d.ts +74 -0
- package/dist/agent-workspace-hooks.d.ts.map +1 -0
- package/dist/agent-workspace-hooks.js +988 -0
- package/dist/agent-workspace-hooks.js.map +1 -0
- package/dist/atomic-write.d.ts +6 -0
- package/dist/atomic-write.d.ts.map +1 -0
- package/dist/atomic-write.js +49 -0
- package/dist/atomic-write.js.map +1 -0
- package/dist/cleanup-stack.d.ts +37 -0
- package/dist/cleanup-stack.d.ts.map +1 -0
- package/dist/cleanup-stack.js +45 -0
- package/dist/cleanup-stack.js.map +1 -0
- package/dist/code-review-manager.d.ts +118 -0
- package/dist/code-review-manager.d.ts.map +1 -0
- package/dist/code-review-manager.js +719 -0
- package/dist/code-review-manager.js.map +1 -0
- package/dist/code-review-store.d.ts +114 -0
- package/dist/code-review-store.d.ts.map +1 -0
- package/dist/code-review-store.js +346 -0
- package/dist/code-review-store.js.map +1 -0
- package/dist/config-generator.d.ts +84 -0
- package/dist/config-generator.d.ts.map +1 -0
- package/dist/config-generator.js +295 -0
- package/dist/config-generator.js.map +1 -0
- package/dist/config.d.ts +55 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +852 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon-children.d.ts +55 -0
- package/dist/daemon-children.d.ts.map +1 -0
- package/dist/daemon-children.js +435 -0
- package/dist/daemon-children.js.map +1 -0
- package/dist/dashboard-notifications.d.ts +42 -0
- package/dist/dashboard-notifications.d.ts.map +1 -0
- package/dist/dashboard-notifications.js +123 -0
- package/dist/dashboard-notifications.js.map +1 -0
- package/dist/events-db.d.ts +39 -0
- package/dist/events-db.d.ts.map +1 -0
- package/dist/events-db.js +185 -0
- package/dist/events-db.js.map +1 -0
- package/dist/feature-flags.d.ts +2 -0
- package/dist/feature-flags.d.ts.map +1 -0
- package/dist/feature-flags.js +9 -0
- package/dist/feature-flags.js.map +1 -0
- package/dist/feedback-tools.d.ts +97 -0
- package/dist/feedback-tools.d.ts.map +1 -0
- package/dist/feedback-tools.js +161 -0
- package/dist/feedback-tools.js.map +1 -0
- package/dist/file-lock.d.ts +5 -0
- package/dist/file-lock.d.ts.map +1 -0
- package/dist/file-lock.js +59 -0
- package/dist/file-lock.js.map +1 -0
- package/dist/format-automated-comments.d.ts +18 -0
- package/dist/format-automated-comments.d.ts.map +1 -0
- package/dist/gh-trace.d.ts +57 -0
- package/dist/gh-trace.d.ts.map +1 -0
- package/dist/gh-trace.js +320 -0
- package/dist/gh-trace.js.map +1 -0
- package/dist/git-activity.d.ts +10 -0
- package/dist/git-activity.d.ts.map +1 -0
- package/dist/git-activity.js +30 -0
- package/dist/git-activity.js.map +1 -0
- package/dist/global-config.d.ts +1085 -0
- package/dist/global-config.d.ts.map +1 -0
- package/dist/global-config.js +1067 -0
- package/dist/global-config.js.map +1 -0
- package/dist/index.d.ts +91 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/key-value.d.ts +7 -0
- package/dist/key-value.d.ts.map +1 -0
- package/dist/key-value.js +24 -0
- package/dist/key-value.js.map +1 -0
- package/dist/lifecycle-manager.d.ts +22 -0
- package/dist/lifecycle-manager.d.ts.map +1 -0
- package/dist/lifecycle-manager.js +2813 -0
- package/dist/lifecycle-manager.js.map +1 -0
- package/dist/lifecycle-state.d.ts +28 -0
- package/dist/lifecycle-state.d.ts.map +1 -0
- package/dist/lifecycle-state.js +446 -0
- package/dist/lifecycle-state.js.map +1 -0
- package/dist/lifecycle-status-decisions.d.ts +85 -0
- package/dist/lifecycle-status-decisions.d.ts.map +1 -0
- package/dist/lifecycle-status-decisions.js +262 -0
- package/dist/lifecycle-status-decisions.js.map +1 -0
- package/dist/lifecycle-transition.d.ts +81 -0
- package/dist/lifecycle-transition.d.ts.map +1 -0
- package/dist/lifecycle-transition.js +207 -0
- package/dist/lifecycle-transition.js.map +1 -0
- package/dist/metadata.d.ts +54 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +484 -0
- package/dist/metadata.js.map +1 -0
- package/dist/migration/storage-v2.d.ts +76 -0
- package/dist/migration/storage-v2.d.ts.map +1 -0
- package/dist/migration/storage-v2.js +1614 -0
- package/dist/migration/storage-v2.js.map +1 -0
- package/dist/notification-data.d.ts +135 -0
- package/dist/notification-data.d.ts.map +1 -0
- package/dist/notification-data.js +204 -0
- package/dist/notification-data.js.map +1 -0
- package/dist/notification-observability.d.ts +21 -0
- package/dist/notification-observability.d.ts.map +1 -0
- package/dist/notification-observability.js +154 -0
- package/dist/notification-observability.js.map +1 -0
- package/dist/notifier-resolution.d.ts +14 -0
- package/dist/notifier-resolution.d.ts.map +1 -0
- package/dist/notifier-resolution.js +23 -0
- package/dist/notifier-resolution.js.map +1 -0
- package/dist/observability.d.ts +100 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +535 -0
- package/dist/observability.js.map +1 -0
- package/dist/opencode-agents-md.d.ts +3 -0
- package/dist/opencode-agents-md.d.ts.map +1 -0
- package/dist/opencode-agents-md.js +40 -0
- package/dist/opencode-agents-md.js.map +1 -0
- package/dist/opencode-config.d.ts +2 -0
- package/dist/opencode-config.d.ts.map +1 -0
- package/dist/opencode-config.js +17 -0
- package/dist/opencode-config.js.map +1 -0
- package/dist/opencode-session-id.d.ts +2 -0
- package/dist/opencode-session-id.d.ts.map +1 -0
- package/dist/opencode-session-id.js +12 -0
- package/dist/opencode-session-id.js.map +1 -0
- package/dist/opencode-shared.d.ts +80 -0
- package/dist/opencode-shared.d.ts.map +1 -0
- package/dist/opencode-shared.js +202 -0
- package/dist/opencode-shared.js.map +1 -0
- package/dist/orchestrator-prompt.d.ts +19 -0
- package/dist/orchestrator-prompt.d.ts.map +1 -0
- package/dist/orchestrator-prompt.js +130 -0
- package/dist/orchestrator-prompt.js.map +1 -0
- package/dist/orchestrator-session-strategy.d.ts +5 -0
- package/dist/orchestrator-session-strategy.d.ts.map +1 -0
- package/dist/orchestrator-session-strategy.js +13 -0
- package/dist/orchestrator-session-strategy.js.map +1 -0
- package/dist/paths.d.ts +145 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +288 -0
- package/dist/paths.js.map +1 -0
- package/dist/platform.d.ts +32 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +211 -0
- package/dist/platform.js.map +1 -0
- package/dist/plugin-registry.d.ts +15 -0
- package/dist/plugin-registry.d.ts.map +1 -0
- package/dist/plugin-registry.js +499 -0
- package/dist/plugin-registry.js.map +1 -0
- package/dist/portfolio-projects.d.ts +7 -0
- package/dist/portfolio-projects.d.ts.map +1 -0
- package/dist/portfolio-projects.js +65 -0
- package/dist/portfolio-projects.js.map +1 -0
- package/dist/portfolio-registry.d.ts +42 -0
- package/dist/portfolio-registry.d.ts.map +1 -0
- package/dist/portfolio-registry.js +311 -0
- package/dist/portfolio-registry.js.map +1 -0
- package/dist/portfolio-routing.d.ts +5 -0
- package/dist/portfolio-routing.d.ts.map +1 -0
- package/dist/portfolio-routing.js +24 -0
- package/dist/portfolio-routing.js.map +1 -0
- package/dist/portfolio-session-service.d.ts +15 -0
- package/dist/portfolio-session-service.d.ts.map +1 -0
- package/dist/portfolio-session-service.js +206 -0
- package/dist/portfolio-session-service.js.map +1 -0
- package/dist/process-cache.d.ts +32 -0
- package/dist/process-cache.d.ts.map +1 -0
- package/dist/process-cache.js +44 -0
- package/dist/process-cache.js.map +1 -0
- package/dist/project-resolver.d.ts +5 -0
- package/dist/project-resolver.d.ts.map +1 -0
- package/dist/project-resolver.js +20 -0
- package/dist/project-resolver.js.map +1 -0
- package/dist/prompt-builder.d.ts +42 -0
- package/dist/prompt-builder.d.ts.map +1 -0
- package/dist/prompt-builder.js +182 -0
- package/dist/prompt-builder.js.map +1 -0
- package/dist/prompts/orchestrator.md.js +4 -0
- package/dist/prompts/orchestrator.md.js.map +1 -0
- package/dist/query-activity-events.d.ts +42 -0
- package/dist/query-activity-events.d.ts.map +1 -0
- package/dist/query-activity-events.js +170 -0
- package/dist/query-activity-events.js.map +1 -0
- package/dist/recovery/actions.d.ts +7 -0
- package/dist/recovery/actions.d.ts.map +1 -0
- package/dist/recovery/index.d.ts +8 -0
- package/dist/recovery/index.d.ts.map +1 -0
- package/dist/recovery/logger.d.ts +12 -0
- package/dist/recovery/logger.d.ts.map +1 -0
- package/dist/recovery/manager.d.ts +24 -0
- package/dist/recovery/manager.d.ts.map +1 -0
- package/dist/recovery/scanner.d.ts +11 -0
- package/dist/recovery/scanner.d.ts.map +1 -0
- package/dist/recovery/types.d.ts +170 -0
- package/dist/recovery/types.d.ts.map +1 -0
- package/dist/recovery/validator.d.ts +8 -0
- package/dist/recovery/validator.d.ts.map +1 -0
- package/dist/report-watcher.d.ts +93 -0
- package/dist/report-watcher.d.ts.map +1 -0
- package/dist/report-watcher.js +182 -0
- package/dist/report-watcher.js.map +1 -0
- package/dist/scm-webhook-utils.d.ts +6 -0
- package/dist/scm-webhook-utils.d.ts.map +1 -0
- package/dist/scm-webhook-utils.js +36 -0
- package/dist/scm-webhook-utils.js.map +1 -0
- package/dist/session-manager.d.ts +22 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +3077 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/spawn-target.d.ts +23 -0
- package/dist/spawn-target.d.ts.map +1 -0
- package/dist/spawn-target.js +39 -0
- package/dist/spawn-target.js.map +1 -0
- package/dist/storage-key.d.ts +9 -0
- package/dist/storage-key.d.ts.map +1 -0
- package/dist/storage-key.js +59 -0
- package/dist/storage-key.js.map +1 -0
- package/dist/tmux.d.ts +39 -0
- package/dist/tmux.d.ts.map +1 -0
- package/dist/tmux.js +141 -0
- package/dist/tmux.js.map +1 -0
- package/dist/types.d.ts +1496 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +215 -0
- package/dist/types.js.map +1 -0
- package/dist/update-cache.d.ts +59 -0
- package/dist/update-cache.d.ts.map +1 -0
- package/dist/update-cache.js +77 -0
- package/dist/update-cache.js.map +1 -0
- package/dist/utils/metadata-flatten.d.ts +3 -0
- package/dist/utils/metadata-flatten.d.ts.map +1 -0
- package/dist/utils/metadata-flatten.js +18 -0
- package/dist/utils/metadata-flatten.js.map +1 -0
- package/dist/utils/pr.d.ts +7 -0
- package/dist/utils/pr.d.ts.map +1 -0
- package/dist/utils/pr.js +97 -0
- package/dist/utils/pr.js.map +1 -0
- package/dist/utils/session-from-metadata.d.ts +16 -0
- package/dist/utils/session-from-metadata.d.ts.map +1 -0
- package/dist/utils/session-from-metadata.js +87 -0
- package/dist/utils/session-from-metadata.js.map +1 -0
- package/dist/utils/session-id.d.ts +4 -0
- package/dist/utils/session-id.d.ts.map +1 -0
- package/dist/utils/session-id.js +9 -0
- package/dist/utils/session-id.js.map +1 -0
- package/dist/utils/validation.d.ts +9 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +45 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils.d.ts +65 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +189 -0
- package/dist/utils.js.map +1 -0
- package/dist/version-compare.d.ts +27 -0
- package/dist/version-compare.d.ts.map +1 -0
- package/dist/version-compare.js +121 -0
- package/dist/version-compare.js.map +1 -0
- package/dist/windows-pty-registry.d.ts +27 -0
- package/dist/windows-pty-registry.d.ts.map +1 -0
- package/dist/windows-pty-registry.js +109 -0
- package/dist/windows-pty-registry.js.map +1 -0
- package/package.json +110 -0
package/dist/metadata.js
ADDED
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
import { existsSync, unlinkSync, readdirSync, statSync, readFileSync, mkdirSync, openSync, constants, closeSync, renameSync } from 'node:fs';
|
|
2
|
+
import { join, dirname, basename } from 'node:path';
|
|
3
|
+
import { atomicWriteFileSync } from './atomic-write.js';
|
|
4
|
+
import { recordActivityEvent } from './activity-events.js';
|
|
5
|
+
import { parseCanonicalLifecycle, deriveLegacyStatus, cloneLifecycle, buildLifecycleMetadataPatch } from './lifecycle-state.js';
|
|
6
|
+
import { SESSION_ID_COMPONENT_PATTERN, assertValidSessionIdComponent } from './utils/session-id.js';
|
|
7
|
+
import { flattenToStringRecord } from './utils/metadata-flatten.js';
|
|
8
|
+
import { validateStatus } from './utils/validation.js';
|
|
9
|
+
import { withFileLockSync } from './file-lock.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Session metadata read/write — JSON format.
|
|
13
|
+
*
|
|
14
|
+
* V2 storage layout:
|
|
15
|
+
* - Session metadata: ~/.agent-orchestrator/projects/{projectId}/sessions/{sessionId}.json
|
|
16
|
+
* - Orchestrator metadata: ~/.agent-orchestrator/projects/{projectId}/orchestrator.json
|
|
17
|
+
*
|
|
18
|
+
* Format: JSON (2-space indented), one object per file.
|
|
19
|
+
* Status: computed on read from lifecycle via deriveLegacyStatus().
|
|
20
|
+
* Pre-lifecycle sessions retain a stored status field; lifecycle sessions omit it on write.
|
|
21
|
+
*/
|
|
22
|
+
const JSON_EXTENSION = ".json";
|
|
23
|
+
/** Serialize metadata to formatted JSON. */
|
|
24
|
+
function serializeMetadata(data) {
|
|
25
|
+
return JSON.stringify(data, null, 2) + "\n";
|
|
26
|
+
}
|
|
27
|
+
/** Parse JSON metadata file content. Returns null on invalid JSON. */
|
|
28
|
+
function parseMetadataContent(content) {
|
|
29
|
+
try {
|
|
30
|
+
const parsed = JSON.parse(content);
|
|
31
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
32
|
+
return null;
|
|
33
|
+
return parsed;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Extract the lifecycle object from raw metadata.
|
|
41
|
+
* Supports both V2 format ("lifecycle" key) and legacy format ("statePayload" + "stateVersion").
|
|
42
|
+
*/
|
|
43
|
+
function parseLifecycleField(raw) {
|
|
44
|
+
// V2 format: lifecycle is stored directly as an object
|
|
45
|
+
if (raw["lifecycle"] && typeof raw["lifecycle"] === "object") {
|
|
46
|
+
return raw["lifecycle"];
|
|
47
|
+
}
|
|
48
|
+
// Legacy format: statePayload is a JSON string or pre-parsed object
|
|
49
|
+
if (raw["statePayload"] && raw["stateVersion"] === "2") {
|
|
50
|
+
if (typeof raw["statePayload"] === "object") {
|
|
51
|
+
return raw["statePayload"];
|
|
52
|
+
}
|
|
53
|
+
if (typeof raw["statePayload"] === "string") {
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(raw["statePayload"]);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
/** Parse a runtimeHandle from raw metadata (may be object or JSON string). */
|
|
65
|
+
function parseRuntimeHandleField(value) {
|
|
66
|
+
if (typeof value === "object" && value !== null) {
|
|
67
|
+
const obj = value;
|
|
68
|
+
if (typeof obj["id"] === "string" && typeof obj["runtimeName"] === "string") {
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
if (typeof value === "string" && value) {
|
|
74
|
+
try {
|
|
75
|
+
const parsed = JSON.parse(value);
|
|
76
|
+
if (typeof parsed["id"] === "string" && typeof parsed["runtimeName"] === "string") {
|
|
77
|
+
return parsed;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
/* not valid JSON */
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
function parseDashboardField(raw) {
|
|
87
|
+
// New format: nested dashboard object
|
|
88
|
+
if (typeof raw["dashboard"] === "object" && raw["dashboard"] !== null) {
|
|
89
|
+
const d = raw["dashboard"];
|
|
90
|
+
return {
|
|
91
|
+
port: typeof d["port"] === "number" ? d["port"] : undefined,
|
|
92
|
+
terminalWsPort: typeof d["terminalWsPort"] === "number" ? d["terminalWsPort"] : undefined,
|
|
93
|
+
directTerminalWsPort: typeof d["directTerminalWsPort"] === "number" ? d["directTerminalWsPort"] : undefined,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// Legacy format: flat fields
|
|
97
|
+
const port = typeof raw["dashboardPort"] === "number" ? raw["dashboardPort"] : undefined;
|
|
98
|
+
const terminalWsPort = typeof raw["terminalWsPort"] === "number" ? raw["terminalWsPort"] : undefined;
|
|
99
|
+
const directTerminalWsPort = typeof raw["directTerminalWsPort"] === "number" ? raw["directTerminalWsPort"] : undefined;
|
|
100
|
+
if (port !== undefined || terminalWsPort !== undefined || directTerminalWsPort !== undefined) {
|
|
101
|
+
return { port, terminalWsPort, directTerminalWsPort };
|
|
102
|
+
}
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
function validateSessionId(sessionId) {
|
|
106
|
+
assertValidSessionIdComponent(sessionId);
|
|
107
|
+
}
|
|
108
|
+
/** Get the metadata file path for a session (with .json extension). */
|
|
109
|
+
function metadataPath(dataDir, sessionId) {
|
|
110
|
+
validateSessionId(sessionId);
|
|
111
|
+
return join(dataDir, `${sessionId}${JSON_EXTENSION}`);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Read metadata for a session. Returns null if the file doesn't exist.
|
|
115
|
+
*/
|
|
116
|
+
function readMetadata(dataDir, sessionId) {
|
|
117
|
+
const path = metadataPath(dataDir, sessionId);
|
|
118
|
+
let content;
|
|
119
|
+
try {
|
|
120
|
+
content = readFileSync(path, "utf-8").trim();
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return null; // file doesn't exist or was concurrently deleted
|
|
124
|
+
}
|
|
125
|
+
if (!content)
|
|
126
|
+
return null; // empty file (e.g. from reserveSessionId)
|
|
127
|
+
const raw = parseMetadataContent(content);
|
|
128
|
+
if (!raw)
|
|
129
|
+
return null; // corrupt JSON — treat as missing
|
|
130
|
+
// Derive status: lifecycle-derived (single source of truth) → stored fallback
|
|
131
|
+
const lifecycle = parseLifecycleField(raw);
|
|
132
|
+
const storedStatus = raw["status"];
|
|
133
|
+
const status = lifecycle ? deriveLegacyStatus(lifecycle) : (storedStatus ?? "unknown");
|
|
134
|
+
return {
|
|
135
|
+
worktree: raw["worktree"] ?? "",
|
|
136
|
+
branch: raw["branch"] ?? "",
|
|
137
|
+
status,
|
|
138
|
+
tmuxName: raw["tmuxName"],
|
|
139
|
+
issue: raw["issue"],
|
|
140
|
+
issueTitle: raw["issueTitle"],
|
|
141
|
+
pr: raw["pr"],
|
|
142
|
+
prAutoDetect: raw["prAutoDetect"] === "off" ||
|
|
143
|
+
raw["prAutoDetect"] === "false" ||
|
|
144
|
+
raw["prAutoDetect"] === false
|
|
145
|
+
? false
|
|
146
|
+
: raw["prAutoDetect"] === "on" ||
|
|
147
|
+
raw["prAutoDetect"] === "true" ||
|
|
148
|
+
raw["prAutoDetect"] === true
|
|
149
|
+
? true
|
|
150
|
+
: undefined,
|
|
151
|
+
summary: raw["summary"],
|
|
152
|
+
project: raw["project"],
|
|
153
|
+
agent: raw["agent"],
|
|
154
|
+
createdAt: raw["createdAt"],
|
|
155
|
+
runtimeHandle: parseRuntimeHandleField(raw["runtimeHandle"]),
|
|
156
|
+
lifecycle,
|
|
157
|
+
restoredAt: raw["restoredAt"],
|
|
158
|
+
role: raw["role"],
|
|
159
|
+
dashboard: parseDashboardField(raw),
|
|
160
|
+
opencodeSessionId: raw["opencodeSessionId"],
|
|
161
|
+
pinnedSummary: raw["pinnedSummary"],
|
|
162
|
+
userPrompt: raw["userPrompt"],
|
|
163
|
+
displayName: raw["displayName"],
|
|
164
|
+
displayNameUserSet: raw["displayNameUserSet"] === "off" ||
|
|
165
|
+
raw["displayNameUserSet"] === "false" ||
|
|
166
|
+
raw["displayNameUserSet"] === false
|
|
167
|
+
? false
|
|
168
|
+
: raw["displayNameUserSet"] === "on" ||
|
|
169
|
+
raw["displayNameUserSet"] === "true" ||
|
|
170
|
+
raw["displayNameUserSet"] === true
|
|
171
|
+
? true
|
|
172
|
+
: undefined,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Read raw metadata as a plain object (for arbitrary key access).
|
|
177
|
+
*/
|
|
178
|
+
function readMetadataRaw(dataDir, sessionId) {
|
|
179
|
+
const path = metadataPath(dataDir, sessionId);
|
|
180
|
+
let content;
|
|
181
|
+
try {
|
|
182
|
+
content = readFileSync(path, "utf-8").trim();
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return null; // file doesn't exist or was concurrently deleted
|
|
186
|
+
}
|
|
187
|
+
if (!content)
|
|
188
|
+
return null; // empty file (e.g. from reserveSessionId)
|
|
189
|
+
const raw = parseMetadataContent(content);
|
|
190
|
+
if (!raw)
|
|
191
|
+
return null; // corrupt JSON — treat as missing
|
|
192
|
+
// Lifecycle is the single source of truth for status — always override stored status.
|
|
193
|
+
// Check both V2 "lifecycle" key and legacy "statePayload" + "stateVersion" format.
|
|
194
|
+
if (raw["lifecycle"] || (raw["statePayload"] && raw["stateVersion"] === "2")) {
|
|
195
|
+
const lifecycle = parseLifecycleField(raw);
|
|
196
|
+
if (lifecycle) {
|
|
197
|
+
raw["status"] = deriveLegacyStatus(lifecycle);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Flatten to Record<string, string> for backward compatibility.
|
|
201
|
+
// Objects (runtimeHandle, statePayload) are JSON-stringified.
|
|
202
|
+
return flattenToStringRecord(raw);
|
|
203
|
+
}
|
|
204
|
+
/** Fields that are stored as JSON objects and should be parsed when unflattening. */
|
|
205
|
+
const jsonFields = new Set([
|
|
206
|
+
"runtimeHandle",
|
|
207
|
+
"lifecycle",
|
|
208
|
+
"statePayload",
|
|
209
|
+
"dashboard",
|
|
210
|
+
"agentReport",
|
|
211
|
+
"reportWatcher",
|
|
212
|
+
]);
|
|
213
|
+
/** Unflatten a Record<string, string> to proper types for JSON storage. */
|
|
214
|
+
function unflattenFromStringRecord(data) {
|
|
215
|
+
const result = {};
|
|
216
|
+
const numberFields = new Set(["dashboardPort", "terminalWsPort", "directTerminalWsPort"]);
|
|
217
|
+
const booleanFields = new Set(["prAutoDetect", "displayNameUserSet"]);
|
|
218
|
+
for (const [key, value] of Object.entries(data)) {
|
|
219
|
+
if (value === undefined || value === "")
|
|
220
|
+
continue;
|
|
221
|
+
if (booleanFields.has(key)) {
|
|
222
|
+
result[key] =
|
|
223
|
+
value === "on" || value === "true"
|
|
224
|
+
? true
|
|
225
|
+
: value === "off" || value === "false"
|
|
226
|
+
? false
|
|
227
|
+
: value;
|
|
228
|
+
}
|
|
229
|
+
else if (numberFields.has(key)) {
|
|
230
|
+
const num = Number(value);
|
|
231
|
+
result[key] = Number.isFinite(num) ? num : value;
|
|
232
|
+
}
|
|
233
|
+
else if (jsonFields.has(key) && (value.startsWith("{") || value.startsWith("["))) {
|
|
234
|
+
try {
|
|
235
|
+
result[key] = JSON.parse(value);
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
result[key] = value;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
result[key] = value;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Write full metadata for a session (overwrites existing file).
|
|
249
|
+
*/
|
|
250
|
+
function writeMetadata(dataDir, sessionId, metadata) {
|
|
251
|
+
const path = metadataPath(dataDir, sessionId);
|
|
252
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
253
|
+
const data = {
|
|
254
|
+
worktree: metadata.worktree,
|
|
255
|
+
branch: metadata.branch,
|
|
256
|
+
// Only persist status for pre-lifecycle sessions; lifecycle sessions
|
|
257
|
+
// derive it on read via deriveLegacyStatus(lifecycle). Callers that
|
|
258
|
+
// build the metadata literal must pass `lifecycle` as the typed
|
|
259
|
+
// object (not a JSON string) — see the writeMetadata sites in
|
|
260
|
+
// session-manager that override the buildLifecycleMetadataPatch
|
|
261
|
+
// spread with the object form.
|
|
262
|
+
...(metadata.lifecycle ? {} : { status: metadata.status }),
|
|
263
|
+
};
|
|
264
|
+
if (metadata.tmuxName)
|
|
265
|
+
data["tmuxName"] = metadata.tmuxName;
|
|
266
|
+
if (metadata.issue)
|
|
267
|
+
data["issue"] = metadata.issue;
|
|
268
|
+
if (metadata.issueTitle)
|
|
269
|
+
data["issueTitle"] = metadata.issueTitle;
|
|
270
|
+
if (metadata.pr)
|
|
271
|
+
data["pr"] = metadata.pr;
|
|
272
|
+
if (metadata.prAutoDetect !== undefined)
|
|
273
|
+
data["prAutoDetect"] = metadata.prAutoDetect;
|
|
274
|
+
if (metadata.summary)
|
|
275
|
+
data["summary"] = metadata.summary;
|
|
276
|
+
if (metadata.project)
|
|
277
|
+
data["project"] = metadata.project;
|
|
278
|
+
if (metadata.agent)
|
|
279
|
+
data["agent"] = metadata.agent;
|
|
280
|
+
if (metadata.createdAt)
|
|
281
|
+
data["createdAt"] = metadata.createdAt;
|
|
282
|
+
if (metadata.runtimeHandle)
|
|
283
|
+
data["runtimeHandle"] = metadata.runtimeHandle;
|
|
284
|
+
if (metadata.lifecycle)
|
|
285
|
+
data["lifecycle"] = metadata.lifecycle;
|
|
286
|
+
if (metadata.restoredAt)
|
|
287
|
+
data["restoredAt"] = metadata.restoredAt;
|
|
288
|
+
if (metadata.role)
|
|
289
|
+
data["role"] = metadata.role;
|
|
290
|
+
if (metadata.dashboard)
|
|
291
|
+
data["dashboard"] = metadata.dashboard;
|
|
292
|
+
if (metadata.opencodeSessionId)
|
|
293
|
+
data["opencodeSessionId"] = metadata.opencodeSessionId;
|
|
294
|
+
if (metadata.pinnedSummary)
|
|
295
|
+
data["pinnedSummary"] = metadata.pinnedSummary;
|
|
296
|
+
if (metadata.userPrompt)
|
|
297
|
+
data["userPrompt"] = metadata.userPrompt;
|
|
298
|
+
if (metadata.displayName)
|
|
299
|
+
data["displayName"] = metadata.displayName;
|
|
300
|
+
if (metadata.displayNameUserSet !== undefined)
|
|
301
|
+
data["displayNameUserSet"] = metadata.displayNameUserSet;
|
|
302
|
+
atomicWriteFileSync(path, serializeMetadata(data));
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Update specific fields in a session's metadata.
|
|
306
|
+
* Reads existing file, merges updates, writes back.
|
|
307
|
+
*/
|
|
308
|
+
function updateMetadata(dataDir, sessionId, updates) {
|
|
309
|
+
mutateMetadata(dataDir, sessionId, (existing) => {
|
|
310
|
+
return applyMetadataUpdates(existing, updates);
|
|
311
|
+
}, { createIfMissing: true });
|
|
312
|
+
}
|
|
313
|
+
function applyMetadataUpdates(existing, updates) {
|
|
314
|
+
let next = { ...existing };
|
|
315
|
+
// Merge updates — remove keys set to empty string
|
|
316
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
317
|
+
if (value === undefined)
|
|
318
|
+
continue;
|
|
319
|
+
if (value === "") {
|
|
320
|
+
const { [key]: _removed, ...rest } = next;
|
|
321
|
+
next = rest;
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
next[key] = value;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return next;
|
|
328
|
+
}
|
|
329
|
+
function normalizeMetadataRecord(data) {
|
|
330
|
+
return Object.fromEntries(Object.entries(data).filter(([, value]) => value !== undefined && value !== ""));
|
|
331
|
+
}
|
|
332
|
+
function mutateMetadata(dataDir, sessionId, updater, options = {}) {
|
|
333
|
+
const path = metadataPath(dataDir, sessionId);
|
|
334
|
+
const lockPath = `${path}.lock`;
|
|
335
|
+
return withFileLockSync(lockPath, () => {
|
|
336
|
+
let existing = {};
|
|
337
|
+
let content;
|
|
338
|
+
try {
|
|
339
|
+
content = readFileSync(path, "utf-8").trim();
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
// File doesn't exist
|
|
343
|
+
}
|
|
344
|
+
if (content !== undefined) {
|
|
345
|
+
if (content) {
|
|
346
|
+
const raw = parseMetadataContent(content);
|
|
347
|
+
if (raw) {
|
|
348
|
+
existing = flattenToStringRecord(raw);
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
// Corrupt JSON. Preserve forensic evidence by side-renaming
|
|
352
|
+
// the file before we overwrite it with the merged update.
|
|
353
|
+
// Without this, the very next mutateMetadata call destroys
|
|
354
|
+
// the corrupt bytes permanently and the user has no signal
|
|
355
|
+
// that anything was wrong — the file just becomes "not
|
|
356
|
+
// corrupt anymore — and missing fields".
|
|
357
|
+
const corruptPath = `${path}.corrupt-${Date.now()}`;
|
|
358
|
+
let renamed = false;
|
|
359
|
+
try {
|
|
360
|
+
renameSync(path, corruptPath);
|
|
361
|
+
renamed = true;
|
|
362
|
+
// eslint-disable-next-line no-console
|
|
363
|
+
console.warn(`[metadata] corrupt JSON at ${path}; preserved as ${corruptPath} before rewriting`);
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
// best effort — proceed even if the rename fails (e.g. EACCES)
|
|
367
|
+
}
|
|
368
|
+
// Forensic activity event so RCA can find every silent overwrite.
|
|
369
|
+
// Truncate the bad-JSON sample to 200 chars (B11 invariant — full file
|
|
370
|
+
// could be 16KB+ and would be dropped by the sanitizer cap).
|
|
371
|
+
const contentSample = content.length > 200 ? content.slice(0, 200) : content;
|
|
372
|
+
// dataDir is `.../projects/{projectId}/sessions`; recover projectId for filtering.
|
|
373
|
+
const inferredProjectId = basename(dirname(dataDir));
|
|
374
|
+
const summary = renamed
|
|
375
|
+
? `Corrupt metadata for session ${sessionId} renamed to ${basename(corruptPath)}`
|
|
376
|
+
: `Corrupt metadata detected for session ${sessionId}; failed to rename forensic copy before rewrite`;
|
|
377
|
+
recordActivityEvent({
|
|
378
|
+
projectId: inferredProjectId || undefined,
|
|
379
|
+
sessionId,
|
|
380
|
+
source: options.activityEventSource ?? "session-manager",
|
|
381
|
+
kind: "metadata.corrupt_detected",
|
|
382
|
+
level: "error",
|
|
383
|
+
summary,
|
|
384
|
+
data: {
|
|
385
|
+
path,
|
|
386
|
+
renamedTo: renamed ? corruptPath : null,
|
|
387
|
+
renameSucceeded: renamed,
|
|
388
|
+
contentSample,
|
|
389
|
+
contentLength: content.length,
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
else if (!options.createIfMissing) {
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
const next = normalizeMetadataRecord(updater({ ...existing }));
|
|
399
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
400
|
+
atomicWriteFileSync(path, serializeMetadata(unflattenFromStringRecord(next)));
|
|
401
|
+
return next;
|
|
402
|
+
}, { timeoutMs: 5_000, staleMs: 30_000 });
|
|
403
|
+
}
|
|
404
|
+
function readCanonicalLifecycle(dataDir, sessionId) {
|
|
405
|
+
const raw = readMetadataRaw(dataDir, sessionId);
|
|
406
|
+
if (!raw)
|
|
407
|
+
return null;
|
|
408
|
+
return parseCanonicalLifecycle(raw, { sessionId, status: validateStatus(raw["status"]) });
|
|
409
|
+
}
|
|
410
|
+
function writeCanonicalLifecycle(dataDir, sessionId, lifecycle) {
|
|
411
|
+
updateMetadata(dataDir, sessionId, buildLifecycleMetadataPatch(cloneLifecycle(lifecycle)));
|
|
412
|
+
}
|
|
413
|
+
function updateCanonicalLifecycle(dataDir, sessionId, updater) {
|
|
414
|
+
const raw = readMetadataRaw(dataDir, sessionId);
|
|
415
|
+
if (!raw)
|
|
416
|
+
return null;
|
|
417
|
+
const current = parseCanonicalLifecycle(raw, {
|
|
418
|
+
sessionId,
|
|
419
|
+
status: validateStatus(raw["status"]),
|
|
420
|
+
});
|
|
421
|
+
const next = updater(cloneLifecycle(current));
|
|
422
|
+
writeCanonicalLifecycle(dataDir, sessionId, next);
|
|
423
|
+
return next;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Delete a session's metadata file permanently.
|
|
427
|
+
*/
|
|
428
|
+
function deleteMetadata(dataDir, sessionId) {
|
|
429
|
+
const path = metadataPath(dataDir, sessionId);
|
|
430
|
+
if (!existsSync(path))
|
|
431
|
+
return;
|
|
432
|
+
try {
|
|
433
|
+
unlinkSync(path);
|
|
434
|
+
}
|
|
435
|
+
catch {
|
|
436
|
+
// File may already be deleted by a concurrent process — not an error
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* List all session IDs that have metadata files.
|
|
441
|
+
* Reads .json files from the sessions directory.
|
|
442
|
+
*/
|
|
443
|
+
function listMetadata(dataDir) {
|
|
444
|
+
const dir = dataDir;
|
|
445
|
+
if (!existsSync(dir))
|
|
446
|
+
return [];
|
|
447
|
+
return readdirSync(dir)
|
|
448
|
+
.filter((name) => {
|
|
449
|
+
// Must be a .json file
|
|
450
|
+
if (!name.endsWith(JSON_EXTENSION))
|
|
451
|
+
return false;
|
|
452
|
+
const baseName = name.slice(0, -JSON_EXTENSION.length);
|
|
453
|
+
if (!baseName || baseName.startsWith("."))
|
|
454
|
+
return false;
|
|
455
|
+
if (!SESSION_ID_COMPONENT_PATTERN.test(baseName))
|
|
456
|
+
return false;
|
|
457
|
+
try {
|
|
458
|
+
return statSync(join(dir, name)).isFile();
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
})
|
|
464
|
+
.map((name) => name.slice(0, -JSON_EXTENSION.length));
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Atomically reserve a session ID by creating its metadata file with O_EXCL.
|
|
468
|
+
* Returns true if the ID was successfully reserved, false if it already exists.
|
|
469
|
+
*/
|
|
470
|
+
function reserveSessionId(dataDir, sessionId) {
|
|
471
|
+
const path = metadataPath(dataDir, sessionId);
|
|
472
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
473
|
+
try {
|
|
474
|
+
const fd = openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL);
|
|
475
|
+
closeSync(fd);
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
catch {
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export { applyMetadataUpdates, deleteMetadata, listMetadata, mutateMetadata, readCanonicalLifecycle, readMetadata, readMetadataRaw, reserveSessionId, updateCanonicalLifecycle, updateMetadata, writeCanonicalLifecycle, writeMetadata };
|
|
484
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sources":["../src/metadata.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;AAAA;;;;;;;;;;AAUG;AAkCH,MAAM,cAAc,GAAG,OAAO;AAE9B;AACA,SAAS,iBAAiB,CAAC,IAA6B,EAAA;AACtD,IAAA,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI;AAC7C;AAEA;AACA,SAAS,oBAAoB,CAAC,OAAe,EAAA;AAC3C,IAAA,IAAI;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AAClC,QAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AAAE,YAAA,OAAO,IAAI;AACvF,QAAA,OAAO,MAAiC;IAC1C;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,IAAI;IACb;AACF;AAEA;;;AAGG;AACH,SAAS,mBAAmB,CAAC,GAA4B,EAAA;;AAEvD,IAAA,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,QAAQ,EAAE;AAC5D,QAAA,OAAO,GAAG,CAAC,WAAW,CAA8B;IACtD;;AAEA,IAAA,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,KAAK,GAAG,EAAE;QACtD,IAAI,OAAO,GAAG,CAAC,cAAc,CAAC,KAAK,QAAQ,EAAE;AAC3C,YAAA,OAAO,GAAG,CAAC,cAAc,CAA8B;QACzD;QACA,IAAI,OAAO,GAAG,CAAC,cAAc,CAAC,KAAK,QAAQ,EAAE;AAC3C,YAAA,IAAI;gBACF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAA8B;YACrE;AAAE,YAAA,MAAM;AACN,gBAAA,OAAO,SAAS;YAClB;QACF;IACF;AACA,IAAA,OAAO,SAAS;AAClB;AAEA;AACA,SAAS,uBAAuB,CAAC,KAAc,EAAA;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE;QAC/C,MAAM,GAAG,GAAG,KAAgC;AAC5C,QAAA,IAAI,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,aAAa,CAAC,KAAK,QAAQ,EAAE;AAC3E,YAAA,OAAO,KAAsB;QAC/B;AACA,QAAA,OAAO,SAAS;IAClB;AACA,IAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,EAAE;AACtC,QAAA,IAAI;YACF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAA4B;AAC3D,YAAA,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,aAAa,CAAC,KAAK,QAAQ,EAAE;AACjF,gBAAA,OAAO,MAAkC;YAC3C;QACF;AAAE,QAAA,MAAM;;QAER;IACF;AACA,IAAA,OAAO,SAAS;AAClB;AAEA,SAAS,mBAAmB,CAAC,GAA4B,EAAA;;AAEvD,IAAA,IAAI,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;AACrE,QAAA,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,CAA4B;QACrD,OAAO;AACL,YAAA,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS;AAC3D,YAAA,cAAc,EAAE,OAAO,CAAC,CAAC,gBAAgB,CAAC,KAAK,QAAQ,GAAG,CAAC,CAAC,gBAAgB,CAAC,GAAG,SAAS;AACzF,YAAA,oBAAoB,EAClB,OAAO,CAAC,CAAC,sBAAsB,CAAC,KAAK,QAAQ,GAAG,CAAC,CAAC,sBAAsB,CAAC,GAAG,SAAS;SACxF;IACH;;IAEA,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,eAAe,CAAC,KAAK,QAAQ,GAAG,GAAG,CAAC,eAAe,CAAC,GAAG,SAAS;IACxF,MAAM,cAAc,GAClB,OAAO,GAAG,CAAC,gBAAgB,CAAC,KAAK,QAAQ,GAAG,GAAG,CAAC,gBAAgB,CAAC,GAAG,SAAS;IAC/E,MAAM,oBAAoB,GACxB,OAAO,GAAG,CAAC,sBAAsB,CAAC,KAAK,QAAQ,GAAG,GAAG,CAAC,sBAAsB,CAAC,GAAG,SAAS;AAC3F,IAAA,IAAI,IAAI,KAAK,SAAS,IAAI,cAAc,KAAK,SAAS,IAAI,oBAAoB,KAAK,SAAS,EAAE;AAC5F,QAAA,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,oBAAoB,EAAE;IACvD;AACA,IAAA,OAAO,SAAS;AAClB;AAEA,SAAS,iBAAiB,CAAC,SAAoB,EAAA;IAC7C,6BAA6B,CAAC,SAAS,CAAC;AAC1C;AAEA;AACA,SAAS,YAAY,CAAC,OAAe,EAAE,SAAoB,EAAA;IACzD,iBAAiB,CAAC,SAAS,CAAC;IAC5B,OAAO,IAAI,CAAC,OAAO,EAAE,CAAA,EAAG,SAAS,CAAA,EAAG,cAAc,CAAA,CAAE,CAAC;AACvD;AAEA;;AAEG;AACG,SAAU,YAAY,CAAC,OAAe,EAAE,SAAoB,EAAA;IAChE,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC;AAE7C,IAAA,IAAI,OAAe;AACnB,IAAA,IAAI;QACF,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE;IAC9C;AAAE,IAAA,MAAM;QACN,OAAO,IAAI,CAAC;IACd;AACA,IAAA,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;AAC1B,IAAA,MAAM,GAAG,GAAG,oBAAoB,CAAC,OAAO,CAAC;AACzC,IAAA,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;;AAGtB,IAAA,MAAM,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAC;AAC1C,IAAA,MAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAuB;AACxD,IAAA,MAAM,MAAM,GAAG,SAAS,GAAG,kBAAkB,CAAC,SAAS,CAAC,IAAI,YAAY,IAAI,SAAS,CAAC;IAEtF,OAAO;AACL,QAAA,QAAQ,EAAG,GAAG,CAAC,UAAU,CAAY,IAAI,EAAE;AAC3C,QAAA,MAAM,EAAG,GAAG,CAAC,QAAQ,CAAY,IAAI,EAAE;QACvC,MAAM;AACN,QAAA,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAuB;AAC/C,QAAA,KAAK,EAAE,GAAG,CAAC,OAAO,CAAuB;AACzC,QAAA,UAAU,EAAE,GAAG,CAAC,YAAY,CAAuB;AACnD,QAAA,EAAE,EAAE,GAAG,CAAC,IAAI,CAAuB;AACnC,QAAA,YAAY,EACV,GAAG,CAAC,cAAc,CAAC,KAAK,KAAK;AAC7B,YAAA,GAAG,CAAC,cAAc,CAAC,KAAK,OAAO;AAC/B,YAAA,GAAG,CAAC,cAAc,CAAC,KAAK;AACtB,cAAE;AACF,cAAE,GAAG,CAAC,cAAc,CAAC,KAAK,IAAI;AAC1B,gBAAA,GAAG,CAAC,cAAc,CAAC,KAAK,MAAM;AAC9B,gBAAA,GAAG,CAAC,cAAc,CAAC,KAAK;AAC1B,kBAAE;AACF,kBAAE,SAAS;AACjB,QAAA,OAAO,EAAE,GAAG,CAAC,SAAS,CAAuB;AAC7C,QAAA,OAAO,EAAE,GAAG,CAAC,SAAS,CAAuB;AAC7C,QAAA,KAAK,EAAE,GAAG,CAAC,OAAO,CAAuB;AACzC,QAAA,SAAS,EAAE,GAAG,CAAC,WAAW,CAAuB;AACjD,QAAA,aAAa,EAAE,uBAAuB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC5D,SAAS;AACT,QAAA,UAAU,EAAE,GAAG,CAAC,YAAY,CAAuB;AACnD,QAAA,IAAI,EAAE,GAAG,CAAC,MAAM,CAAuB;AACvC,QAAA,SAAS,EAAE,mBAAmB,CAAC,GAAG,CAAC;AACnC,QAAA,iBAAiB,EAAE,GAAG,CAAC,mBAAmB,CAAuB;AACjE,QAAA,aAAa,EAAE,GAAG,CAAC,eAAe,CAAuB;AACzD,QAAA,UAAU,EAAE,GAAG,CAAC,YAAY,CAAuB;AACnD,QAAA,WAAW,EAAE,GAAG,CAAC,aAAa,CAAuB;AACrD,QAAA,kBAAkB,EAChB,GAAG,CAAC,oBAAoB,CAAC,KAAK,KAAK;AACnC,YAAA,GAAG,CAAC,oBAAoB,CAAC,KAAK,OAAO;AACrC,YAAA,GAAG,CAAC,oBAAoB,CAAC,KAAK;AAC5B,cAAE;AACF,cAAE,GAAG,CAAC,oBAAoB,CAAC,KAAK,IAAI;AAChC,gBAAA,GAAG,CAAC,oBAAoB,CAAC,KAAK,MAAM;AACpC,gBAAA,GAAG,CAAC,oBAAoB,CAAC,KAAK;AAChC,kBAAE;AACF,kBAAE,SAAS;KAClB;AACH;AAEA;;AAEG;AACG,SAAU,eAAe,CAC7B,OAAe,EACf,SAAoB,EAAA;IAEpB,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC;AAE7C,IAAA,IAAI,OAAe;AACnB,IAAA,IAAI;QACF,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE;IAC9C;AAAE,IAAA,MAAM;QACN,OAAO,IAAI,CAAC;IACd;AACA,IAAA,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;AAC1B,IAAA,MAAM,GAAG,GAAG,oBAAoB,CAAC,OAAO,CAAC;AACzC,IAAA,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;;;AAGtB,IAAA,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,KAAK,GAAG,CAAC,EAAE;AAC5E,QAAA,MAAM,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAC;QAC1C,IAAI,SAAS,EAAE;YACb,GAAG,CAAC,QAAQ,CAAC,GAAG,kBAAkB,CAAC,SAAS,CAAC;QAC/C;IACF;;;AAGA,IAAA,OAAO,qBAAqB,CAAC,GAAG,CAAC;AACnC;AAEA;AACA,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,eAAe;IACf,WAAW;IACX,cAAc;IACd,WAAW;IACX,aAAa;IACb,eAAe;AAChB,CAAA,CAAC;AAEF;AACA,SAAS,yBAAyB,CAAC,IAA4B,EAAA;IAC7D,MAAM,MAAM,GAA4B,EAAE;AAC1C,IAAA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,gBAAgB,EAAE,sBAAsB,CAAC,CAAC;IACzF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,oBAAoB,CAAC,CAAC;AAErE,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAC/C,QAAA,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;YAAE;AACzC,QAAA,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAC1B,MAAM,CAAC,GAAG,CAAC;AACT,gBAAA,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK;AAC1B,sBAAE;AACF,sBAAE,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK;AAC7B,0BAAE;0BACA,KAAK;QACf;AAAO,aAAA,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AAChC,YAAA,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;AACzB,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,KAAK;QAClD;aAAO,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE;AAClF,YAAA,IAAI;gBACF,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YACjC;AAAE,YAAA,MAAM;AACN,gBAAA,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;YACrB;QACF;aAAO;AACL,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;QACrB;IACF;AACA,IAAA,OAAO,MAAM;AACf;AAEA;;AAEG;SACa,aAAa,CAC3B,OAAe,EACf,SAAoB,EACpB,QAAyB,EAAA;IAEzB,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC;AAC7C,IAAA,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAE7C,IAAA,MAAM,IAAI,GAA4B;QACpC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM;;;;;;;AAOvB,QAAA,IAAI,QAAQ,CAAC,SAAS,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;KAC3D;IAED,IAAI,QAAQ,CAAC,QAAQ;AAAE,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,QAAQ;IAC3D,IAAI,QAAQ,CAAC,KAAK;AAAE,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK;IAClD,IAAI,QAAQ,CAAC,UAAU;AAAE,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC,UAAU;IACjE,IAAI,QAAQ,CAAC,EAAE;AAAE,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,EAAE;AACzC,IAAA,IAAI,QAAQ,CAAC,YAAY,KAAK,SAAS;AAAE,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC,YAAY;IACrF,IAAI,QAAQ,CAAC,OAAO;AAAE,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,OAAO;IACxD,IAAI,QAAQ,CAAC,OAAO;AAAE,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,OAAO;IACxD,IAAI,QAAQ,CAAC,KAAK;AAAE,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK;IAClD,IAAI,QAAQ,CAAC,SAAS;AAAE,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,SAAS;IAC9D,IAAI,QAAQ,CAAC,aAAa;AAAE,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC,aAAa;IAC1E,IAAI,QAAQ,CAAC,SAAS;AAAE,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,SAAS;IAC9D,IAAI,QAAQ,CAAC,UAAU;AAAE,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC,UAAU;IACjE,IAAI,QAAQ,CAAC,IAAI;AAAE,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI;IAC/C,IAAI,QAAQ,CAAC,SAAS;AAAE,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,SAAS;IAC9D,IAAI,QAAQ,CAAC,iBAAiB;AAAE,QAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,QAAQ,CAAC,iBAAiB;IACtF,IAAI,QAAQ,CAAC,aAAa;AAAE,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC,aAAa;IAC1E,IAAI,QAAQ,CAAC,UAAU;AAAE,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC,UAAU;IACjE,IAAI,QAAQ,CAAC,WAAW;AAAE,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC,WAAW;AACpE,IAAA,IAAI,QAAQ,CAAC,kBAAkB,KAAK,SAAS;AAC3C,QAAA,IAAI,CAAC,oBAAoB,CAAC,GAAG,QAAQ,CAAC,kBAAkB;IAE1D,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;AACpD;AAEA;;;AAGG;SACa,cAAc,CAC5B,OAAe,EACf,SAAoB,EACpB,OAAwC,EAAA;IAExC,cAAc,CACZ,OAAO,EACP,SAAS,EACT,CAAC,QAAQ,KAAI;AACX,QAAA,OAAO,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC;AAChD,IAAA,CAAC,EACD,EAAE,eAAe,EAAE,IAAI,EAAE,CAC1B;AACH;AAEM,SAAU,oBAAoB,CAClC,QAAgC,EAChC,OAAwC,EAAA;AAExC,IAAA,IAAI,IAAI,GAAG,EAAE,GAAG,QAAQ,EAAE;;AAE1B,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAClD,IAAI,KAAK,KAAK,SAAS;YAAE;AACzB,QAAA,IAAI,KAAK,KAAK,EAAE,EAAE;AAChB,YAAA,MAAM,EAAE,CAAC,GAAG,GAAG,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI;YAEzC,IAAI,GAAG,IAAI;QACb;aAAO;AACL,YAAA,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK;QACnB;IACF;AACA,IAAA,OAAO,IAAI;AACb;AAEA,SAAS,uBAAuB,CAAC,IAA4B,EAAA;AAC3D,IAAA,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,CAAC,CAChF;AACH;AAOM,SAAU,cAAc,CAC5B,OAAe,EACf,SAAoB,EACpB,OAAqE,EACrE,OAAA,GAAiC,EAAE,EAAA;IAEnC,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC;AAC7C,IAAA,MAAM,QAAQ,GAAG,CAAA,EAAG,IAAI,OAAO;AAE/B,IAAA,OAAO,gBAAgB,CACrB,QAAQ,EACR,MAAK;QACH,IAAI,QAAQ,GAA2B,EAAE;AAEzC,QAAA,IAAI,OAA2B;AAC/B,QAAA,IAAI;YACF,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE;QAC9C;AAAE,QAAA,MAAM;;QAER;AAEA,QAAA,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB,IAAI,OAAO,EAAE;AACX,gBAAA,MAAM,GAAG,GAAG,oBAAoB,CAAC,OAAO,CAAC;gBACzC,IAAI,GAAG,EAAE;AACP,oBAAA,QAAQ,GAAG,qBAAqB,CAAC,GAAG,CAAC;gBACvC;qBAAO;;;;;;;oBAOL,MAAM,WAAW,GAAG,CAAA,EAAG,IAAI,CAAA,SAAA,EAAY,IAAI,CAAC,GAAG,EAAE,CAAA,CAAE;oBACnD,IAAI,OAAO,GAAG,KAAK;AACnB,oBAAA,IAAI;AACF,wBAAA,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC;wBAC7B,OAAO,GAAG,IAAI;;wBAEd,OAAO,CAAC,IAAI,CACV,CAAA,2BAAA,EAA8B,IAAI,CAAA,eAAA,EAAkB,WAAW,CAAA,iBAAA,CAAmB,CACnF;oBACH;AAAE,oBAAA,MAAM;;oBAER;;;;oBAIA,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,OAAO;;oBAE5E,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBACpD,MAAM,OAAO,GAAG;0BACZ,gCAAgC,SAAS,CAAA,YAAA,EAAe,QAAQ,CAAC,WAAW,CAAC,CAAA;AAC/E,0BAAE,CAAA,sCAAA,EAAyC,SAAS,CAAA,+CAAA,CAAiD;AACvG,oBAAA,mBAAmB,CAAC;wBAClB,SAAS,EAAE,iBAAiB,IAAI,SAAS;wBACzC,SAAS;AACT,wBAAA,MAAM,EAAE,OAAO,CAAC,mBAAmB,IAAI,iBAAiB;AACxD,wBAAA,IAAI,EAAE,2BAA2B;AACjC,wBAAA,KAAK,EAAE,OAAO;wBACd,OAAO;AACP,wBAAA,IAAI,EAAE;4BACJ,IAAI;4BACJ,SAAS,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI;AACvC,4BAAA,eAAe,EAAE,OAAO;4BACxB,aAAa;4BACb,aAAa,EAAE,OAAO,CAAC,MAAM;AAC9B,yBAAA;AACF,qBAAA,CAAC;gBACJ;YACF;QACF;AAAO,aAAA,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE;AACnC,YAAA,OAAO,IAAI;QACb;AAEA,QAAA,MAAM,IAAI,GAAG,uBAAuB,CAAC,OAAO,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;AAE9D,QAAA,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC7C,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7E,QAAA,OAAO,IAAI;IACb,CAAC,EACD,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CACtC;AACH;AAEM,SAAU,sBAAsB,CACpC,OAAe,EACf,SAAoB,EAAA;IAEpB,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC;AAC/C,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,IAAI;AACrB,IAAA,OAAO,uBAAuB,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;AAC3F;SAEgB,uBAAuB,CACrC,OAAe,EACf,SAAoB,EACpB,SAAoC,EAAA;AAEpC,IAAA,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,2BAA2B,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5F;SAEgB,wBAAwB,CACtC,OAAe,EACf,SAAoB,EACpB,OAA0E,EAAA;IAE1E,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC;AAC/C,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,IAAI;AACrB,IAAA,MAAM,OAAO,GAAG,uBAAuB,CAAC,GAAG,EAAE;QAC3C,SAAS;AACT,QAAA,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACtC,KAAA,CAAC;IACF,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;AAC7C,IAAA,uBAAuB,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC;AACjD,IAAA,OAAO,IAAI;AACb;AAEA;;AAEG;AACG,SAAU,cAAc,CAAC,OAAe,EAAE,SAAoB,EAAA;IAClE,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC;AAC7C,IAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE;AAEvB,IAAA,IAAI;QACF,UAAU,CAAC,IAAI,CAAC;IAClB;AAAE,IAAA,MAAM;;IAER;AACF;AAEA;;;AAGG;AACG,SAAU,YAAY,CAAC,OAAe,EAAA;IAC1C,MAAM,GAAG,GAAG,OAAO;AACnB,IAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;AAAE,QAAA,OAAO,EAAE;IAE/B,OAAO,WAAW,CAAC,GAAG;AACnB,SAAA,MAAM,CAAC,CAAC,IAAI,KAAI;;AAEf,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;AAAE,YAAA,OAAO,KAAK;AAChD,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC;QACtD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;AAAE,YAAA,OAAO,KAAK;AACvD,QAAA,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,QAAQ,CAAC;AAAE,YAAA,OAAO,KAAK;AAC9D,QAAA,IAAI;AACF,YAAA,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE;QAC3C;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,KAAK;QACd;AACF,IAAA,CAAC;AACA,SAAA,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AACzD;AAEA;;;AAGG;AACG,SAAU,gBAAgB,CAAC,OAAe,EAAE,SAAoB,EAAA;IACpE,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC;AAC7C,IAAA,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC7C,IAAA,IAAI;AACF,QAAA,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC;QACpF,SAAS,CAAC,EAAE,CAAC;AACb,QAAA,OAAO,IAAI;IACb;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,KAAK;IACd;AACF;;;;"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage V2 migration — converts old hash-based storage layout to
|
|
3
|
+
* the new `projects/{projectId}/` layout with JSON metadata.
|
|
4
|
+
*
|
|
5
|
+
* Old layout: ~/.agent-orchestrator/{12-hex}-{projectId}/sessions/{sessionId}
|
|
6
|
+
* New layout: ~/.agent-orchestrator/projects/{projectId}/sessions/{sessionId}.json
|
|
7
|
+
*
|
|
8
|
+
* This module is intentionally self-contained — it must NOT import
|
|
9
|
+
* deriveStorageKey, legacyProjectHash, or any old hash functions.
|
|
10
|
+
* Detection uses a single regex: /^([0-9a-f]{12})-(.+)$/
|
|
11
|
+
*/
|
|
12
|
+
export interface MigrationOptions {
|
|
13
|
+
/** Force migration even if active tmux sessions are detected. */
|
|
14
|
+
force?: boolean;
|
|
15
|
+
/** Dry run — report what would be done without making changes. */
|
|
16
|
+
dryRun?: boolean;
|
|
17
|
+
/** Override the base AO directory (for testing). */
|
|
18
|
+
aoBaseDir?: string;
|
|
19
|
+
/** Override the global config path (for testing). */
|
|
20
|
+
globalConfigPath?: string;
|
|
21
|
+
/** Log function (defaults to console.log). */
|
|
22
|
+
log?: (message: string) => void;
|
|
23
|
+
}
|
|
24
|
+
export interface RollbackOptions {
|
|
25
|
+
/** Dry run — report what would be done without making changes. */
|
|
26
|
+
dryRun?: boolean;
|
|
27
|
+
/** Override the base AO directory (for testing). */
|
|
28
|
+
aoBaseDir?: string;
|
|
29
|
+
/** Override the global config path (for testing). */
|
|
30
|
+
globalConfigPath?: string;
|
|
31
|
+
/** Log function (defaults to console.log). */
|
|
32
|
+
log?: (message: string) => void;
|
|
33
|
+
}
|
|
34
|
+
export interface MigrationResult {
|
|
35
|
+
projects: number;
|
|
36
|
+
sessions: number;
|
|
37
|
+
worktrees: number;
|
|
38
|
+
emptyDirsDeleted: number;
|
|
39
|
+
strayWorktreesMoved: number;
|
|
40
|
+
/** Number of Claude Code session-storage directories relinked to the new worktree path. */
|
|
41
|
+
claudeSessionsRelinked: number;
|
|
42
|
+
/** Number of Codex JSONL `session_meta.cwd` fields rewritten to the new worktree path. */
|
|
43
|
+
codexSessionsRewritten: number;
|
|
44
|
+
}
|
|
45
|
+
export interface HashDirEntry {
|
|
46
|
+
/** Full path to the hash-based directory. */
|
|
47
|
+
path: string;
|
|
48
|
+
/** The 12-char hex hash prefix. */
|
|
49
|
+
hash: string;
|
|
50
|
+
/** The project ID extracted from the directory name. */
|
|
51
|
+
projectId: string;
|
|
52
|
+
/** Whether the directory is empty (no sessions or worktrees). */
|
|
53
|
+
empty: boolean;
|
|
54
|
+
}
|
|
55
|
+
export declare function inventoryHashDirs(aoBaseDir: string, globalConfigPath?: string): HashDirEntry[];
|
|
56
|
+
/**
|
|
57
|
+
* Detect active AO tmux sessions. Returns session names that match
|
|
58
|
+
* either legacy ({hash}-{prefix}-{num}) or V2 ({prefix}-{num}) patterns.
|
|
59
|
+
*
|
|
60
|
+
* Legacy names: {12-hex}-{prefix}-{num} (e.g. abcdef012345-ao-1)
|
|
61
|
+
* V2 names: {prefix}-{num} (e.g. ao-17, app-orchestrator-1)
|
|
62
|
+
*
|
|
63
|
+
* To distinguish V2 names from unrelated tmux sessions, we match:
|
|
64
|
+
* - Any session ending in `-orchestrator-{num}` (always AO)
|
|
65
|
+
* - Sessions matching known AO prefixes: ao-{num}
|
|
66
|
+
* - If knownPrefixes are provided, also match {prefix}-{num}
|
|
67
|
+
*/
|
|
68
|
+
export declare function detectActiveSessions(knownPrefixes?: string[]): Promise<string[]>;
|
|
69
|
+
/**
|
|
70
|
+
* Convert old key=value metadata content to a JSON object.
|
|
71
|
+
* Handles all the grouping and type conversions.
|
|
72
|
+
*/
|
|
73
|
+
export declare function convertKeyValueToJson(kvContent: string): Record<string, unknown>;
|
|
74
|
+
export declare function migrateStorage(options?: MigrationOptions): Promise<MigrationResult>;
|
|
75
|
+
export declare function rollbackStorage(options?: RollbackOptions): Promise<void>;
|
|
76
|
+
//# sourceMappingURL=storage-v2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-v2.d.ts","sourceRoot":"","sources":["../../src/migration/storage-v2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAkDH,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8CAA8C;IAC9C,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8CAA8C;IAC9C,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,2FAA2F;IAC3F,sBAAsB,EAAE,MAAM,CAAC;IAC/B,0FAA0F;IAC1F,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAQD,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,KAAK,EAAE,OAAO,CAAC;CAChB;AAMD,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAsD9F;AA+FD;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAiCtF;AAUD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6GhF;AA6uBD,wBAAsB,cAAc,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAoT7F;AAiGD,wBAAsB,eAAe,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuNlF"}
|