pi-session-cleanup 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/config/config.example.json +4 -0
- package/index.ts +3 -0
- package/package.json +66 -0
- package/src/config-store.ts +81 -0
- package/src/constants.ts +3 -0
- package/src/index.ts +27 -0
- package/src/session-agent.ts +78 -0
- package/src/session-cleanup-command.ts +268 -0
- package/src/session-delete.ts +50 -0
- package/src/session-format.ts +98 -0
- package/src/session-nix-command.ts +84 -0
- package/src/session-selection.ts +167 -0
- package/src/session-sort.ts +137 -0
- package/src/session-source.ts +32 -0
- package/src/tui/session-cleanup-picker.ts +592 -0
- package/src/types-shims.d.ts +192 -0
- package/src/types.ts +39 -0
- package/src/ui/icons.ts +476 -0
- package/src/ui/legend.ts +15 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0 - 2026-03-05
|
|
4
|
+
|
|
5
|
+
- Renamed extension from its previous package name to `pi-session-cleanup`
|
|
6
|
+
- Renamed primary command to `/session-cleanup`
|
|
7
|
+
- Added a deprecated legacy alias for backward compatibility
|
|
8
|
+
- Refactored command/picker module names for clarity
|
|
9
|
+
- Upgraded custom picker UI with bordered modal layout, title/status/help lines, and responsive overlay sizing
|
|
10
|
+
- Added production-ready package metadata and README
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MasuRii
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# pi-session-cleanup
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/pi-session-cleanup) [](LICENSE)
|
|
4
|
+
|
|
5
|
+
Interactive session cleanup extension for the [Pi coding agent](https://github.com/mariozechner/pi).
|
|
6
|
+
|
|
7
|
+
<img width="1389" height="768" alt="image" src="https://github.com/user-attachments/assets/42464ca1-4a6c-4496-b13f-5bcc2093bf59" />
|
|
8
|
+
|
|
9
|
+
**pi-session-cleanup** provides a focused TUI command for batch-selecting historical sessions and deleting them safely with trash-first fallback and active session protection.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Interactive Session Cleanup** — Browse, select, and delete sessions via an intuitive modal interface
|
|
14
|
+
- **Scope Filtering** — View only orphaned sessions or all historical sessions
|
|
15
|
+
- **Batch Selection Controls** — Multi-select with Space, select all with `a`, keyboard navigation
|
|
16
|
+
- **Safe Delete Flow** — Excludes the currently active session and uses trash-first deletion with unlink fallback
|
|
17
|
+
- **Improved Modal UX** — Centered overlay with bordered layout, concise single-line legend, status summary, and automatic icon fallback
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
### Local Extension Folder
|
|
22
|
+
|
|
23
|
+
Place this folder in one of Pi's auto-discovery paths:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
~/.pi/agent/extensions/pi-session-cleanup # Global default (when PI_CODING_AGENT_DIR is unset)
|
|
27
|
+
.pi/extensions/pi-session-cleanup # Project-specific
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Pi will auto-discover the extension on startup.
|
|
31
|
+
|
|
32
|
+
### As NPM Package
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pi install npm:pi-session-cleanup
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Git Repository
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pi install git:github.com/MasuRii/pi-session-cleanup
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
### Commands
|
|
47
|
+
|
|
48
|
+
| Command | Arguments | Description |
|
|
49
|
+
|---------|-----------|-------------|
|
|
50
|
+
| `/session-cleanup` | — | Opens the session cleanup modal showing orphaned sessions only |
|
|
51
|
+
| `/session-cleanup current` | — | Opens modal with sessions from the current directory |
|
|
52
|
+
| `/session-cleanup all` | — | Opens modal showing all sessions |
|
|
53
|
+
| `/session-cleanup help` | — | Displays usage help |
|
|
54
|
+
|
|
55
|
+
**Scopes:**
|
|
56
|
+
|
|
57
|
+
- **Default (no args)** — Shows orphaned sessions (sessions without a matching directory)
|
|
58
|
+
- **`current`** — Shows sessions from the current working directory
|
|
59
|
+
- **`all`** — Shows all historical sessions across all directories
|
|
60
|
+
|
|
61
|
+
### Modal Controls
|
|
62
|
+
|
|
63
|
+
When the session picker modal is open:
|
|
64
|
+
|
|
65
|
+
| Key | Action |
|
|
66
|
+
|-----|--------|
|
|
67
|
+
| `↑` / `↓` / `j` / `k` | Navigate up/down in the list |
|
|
68
|
+
| `PgUp` / `PgDn` | Page up/down through sessions |
|
|
69
|
+
| `Home` / `End` | Jump to first/last item |
|
|
70
|
+
| `Space` | Toggle selection of current item |
|
|
71
|
+
| `a` | Select all visible sessions |
|
|
72
|
+
| `r` | Refresh the session list |
|
|
73
|
+
| `Enter` | Confirm deletion of selected sessions |
|
|
74
|
+
| `Esc` / `q` / `Ctrl+C` | Cancel and close modal |
|
|
75
|
+
|
|
76
|
+
### Safety Guards
|
|
77
|
+
|
|
78
|
+
The extension includes multiple safety mechanisms:
|
|
79
|
+
|
|
80
|
+
1. **Active Session Protection** — The currently active session is never shown in the list and cannot be deleted
|
|
81
|
+
2. **Trash-First Deletion** — Sessions are moved to trash first; only falls back to permanent deletion if trash is unavailable
|
|
82
|
+
3. **Confirmation Required** — The modal requires explicit `Enter` keypress to proceed with deletion
|
|
83
|
+
4. **Escapable** — `Esc` or `q` immediately cancels without any changes
|
|
84
|
+
|
|
85
|
+
## Configuration
|
|
86
|
+
|
|
87
|
+
Configuration is stored at:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
Default global path: ~/.pi/agent/extensions/pi-session-cleanup/config.json
|
|
91
|
+
Actual global path: $PI_CODING_AGENT_DIR/extensions/pi-session-cleanup/config.json when PI_CODING_AGENT_DIR is set
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
A starter template is provided in `config/config.example.json`. On startup, the extension creates `config.json` with defaults if missing.
|
|
95
|
+
|
|
96
|
+
### Configuration Options
|
|
97
|
+
|
|
98
|
+
| Option | Type | Default | Description |
|
|
99
|
+
|--------|------|---------|-------------|
|
|
100
|
+
| `enabled` | `boolean` | `true` | Master on/off switch for the extension |
|
|
101
|
+
| `iconMode` | `"auto" \| "nerd" \| "fallback"` | `"auto"` | Icon rendering mode for the modal UI (`auto` detects Nerd Font usage in supported terminals and safely falls back otherwise) |
|
|
102
|
+
|
|
103
|
+
### Icon Mode Overrides
|
|
104
|
+
|
|
105
|
+
You can override icon mode without editing config:
|
|
106
|
+
|
|
107
|
+
- `PI_SESSION_CLEANUP_ICON_MODE=nerd|fallback|auto`
|
|
108
|
+
- `PI_SESSION_CLEANUP_NERD_FONT=true|false` (or `PI_NERD_FONT=true|false`)
|
|
109
|
+
|
|
110
|
+
`auto` now prefers Nerd icons when Nerd Font is actually configured (including Windows Terminal profile/default font checks) and falls back to safe icons when detection is unavailable or uncertain.
|
|
111
|
+
|
|
112
|
+
## Development
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npm run build # Type-check with TypeScript
|
|
116
|
+
npm run lint # Run linting (same as build)
|
|
117
|
+
npm run test # Run test suite
|
|
118
|
+
npm run check # Run full verification (build + test)
|
|
119
|
+
npm run package:dry-run
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Publishing
|
|
123
|
+
|
|
124
|
+
The package metadata follows the same publish-ready shape used by established Pi extensions:
|
|
125
|
+
|
|
126
|
+
- entrypoint: `index.ts`
|
|
127
|
+
- package exports: `.` → `./index.ts`
|
|
128
|
+
- Pi extension manifest: `pi.extensions`
|
|
129
|
+
- published files: source, README, changelog, license, and config template
|
|
130
|
+
- runtime `config.json`, tests, and build artifacts excluded from npm publication
|
|
131
|
+
|
|
132
|
+
## Related Pi Extensions
|
|
133
|
+
|
|
134
|
+
- [pi-hide-messages](https://github.com/MasuRii/pi-hide-messages) — Hide older TUI chat history while preserving full session context
|
|
135
|
+
- [pi-context-injector](https://github.com/MasuRii/pi-context-injector) — Inject compact project context into first-turn and compaction prompts
|
|
136
|
+
- [pi-tool-display](https://github.com/MasuRii/pi-tool-display) — Compact tool rendering and diff visualization
|
|
137
|
+
- [pi-rtk-optimizer](https://github.com/MasuRii/pi-rtk-optimizer) — RTK command rewriting and output compaction
|
|
138
|
+
|
|
139
|
+
## Changelog
|
|
140
|
+
|
|
141
|
+
See [CHANGELOG.md](CHANGELOG.md) for version history.
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
[MIT](LICENSE) © MasuRii
|
package/index.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-session-cleanup",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Pi extension for interactive batch session cleanup and safe deletion.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"index.ts",
|
|
12
|
+
"src",
|
|
13
|
+
"config/config.example.json",
|
|
14
|
+
"README.md",
|
|
15
|
+
"CHANGELOG.md",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "npx --yes -p typescript@5.7.3 tsc -p tsconfig.json --noCheck",
|
|
20
|
+
"lint": "npm run build",
|
|
21
|
+
"test:clean": "node -e \"require('node:fs').rmSync('.test-dist', { recursive: true, force: true })\"",
|
|
22
|
+
"pretest": "npm run test:clean",
|
|
23
|
+
"test": "npx --yes -p typescript@5.7.3 tsc -p tsconfig.test.json && node --test .test-dist/test/*.test.js",
|
|
24
|
+
"posttest": "npm run test:clean",
|
|
25
|
+
"check": "npm run lint && npm run test",
|
|
26
|
+
"package:dry-run": "npm pack --dry-run"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"pi-package",
|
|
30
|
+
"pi",
|
|
31
|
+
"pi-extension",
|
|
32
|
+
"session",
|
|
33
|
+
"cleanup",
|
|
34
|
+
"delete",
|
|
35
|
+
"pi-coding-agent",
|
|
36
|
+
"pi-tui",
|
|
37
|
+
"session-management",
|
|
38
|
+
"tui",
|
|
39
|
+
"safe-delete"
|
|
40
|
+
],
|
|
41
|
+
"author": "MasuRii",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=20"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"pi": {
|
|
50
|
+
"extensions": [
|
|
51
|
+
"./index.ts"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"@mariozechner/pi-coding-agent": "^0.70.5",
|
|
56
|
+
"@mariozechner/pi-tui": "^0.70.5"
|
|
57
|
+
},
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "git+https://github.com/MasuRii/pi-session-cleanup.git"
|
|
61
|
+
},
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/MasuRii/pi-session-cleanup/issues"
|
|
64
|
+
},
|
|
65
|
+
"homepage": "https://github.com/MasuRii/pi-session-cleanup#readme"
|
|
66
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
export type IconModePreference = "auto" | "nerd" | "fallback";
|
|
6
|
+
|
|
7
|
+
export interface SessionCleanupConfig {
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
iconMode: IconModePreference;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const DEFAULT_CONFIG: SessionCleanupConfig = {
|
|
13
|
+
enabled: true,
|
|
14
|
+
iconMode: "auto",
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function resolveExtensionRoot(): string {
|
|
18
|
+
return join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function parseIconMode(value: unknown): IconModePreference | null {
|
|
22
|
+
if (typeof value !== "string") {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const normalized = value.trim().toLowerCase();
|
|
27
|
+
if (normalized === "auto" || normalized === "nerd" || normalized === "fallback") {
|
|
28
|
+
return normalized;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function readConfigFile(configPath: string): Record<string, unknown> | null {
|
|
35
|
+
if (!existsSync(configPath)) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const raw = readFileSync(configPath, "utf8");
|
|
41
|
+
const parsed = JSON.parse(raw);
|
|
42
|
+
if (parsed && typeof parsed === "object") {
|
|
43
|
+
return parsed as Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
} catch {
|
|
46
|
+
// Fall back to defaults when config parsing fails.
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function ensureConfigFile(configPath: string): void {
|
|
53
|
+
if (existsSync(configPath)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
59
|
+
writeFileSync(configPath, `${JSON.stringify(DEFAULT_CONFIG, null, 2)}\n`, "utf8");
|
|
60
|
+
} catch {
|
|
61
|
+
// Ignore file system errors and continue with in-memory defaults.
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function loadSessionCleanupConfig(): SessionCleanupConfig {
|
|
66
|
+
const configPath = join(resolveExtensionRoot(), "config.json");
|
|
67
|
+
ensureConfigFile(configPath);
|
|
68
|
+
|
|
69
|
+
const raw = readConfigFile(configPath);
|
|
70
|
+
if (!raw) {
|
|
71
|
+
return { ...DEFAULT_CONFIG };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const enabled = typeof raw.enabled === "boolean" ? raw.enabled : DEFAULT_CONFIG.enabled;
|
|
75
|
+
const iconMode = parseIconMode(raw.iconMode) ?? DEFAULT_CONFIG.iconMode;
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
enabled,
|
|
79
|
+
iconMode,
|
|
80
|
+
};
|
|
81
|
+
}
|
package/src/constants.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
import { SESSION_CLEANUP_COMMAND, SESSION_NIX_COMMAND } from "./constants.js";
|
|
4
|
+
import {
|
|
5
|
+
getSessionCleanupArgumentCompletions,
|
|
6
|
+
handleSessionCleanupCommand,
|
|
7
|
+
} from "./session-cleanup-command.js";
|
|
8
|
+
import { handleSessionNixCommand } from "./session-nix-command.js";
|
|
9
|
+
|
|
10
|
+
export default function sessionCleanupExtension(pi: ExtensionAPI): void {
|
|
11
|
+
pi.registerCommand(SESSION_CLEANUP_COMMAND, {
|
|
12
|
+
description:
|
|
13
|
+
"Batch-select previous sessions and delete them with confirmation.",
|
|
14
|
+
getArgumentCompletions: getSessionCleanupArgumentCompletions,
|
|
15
|
+
handler: async (args, ctx) => {
|
|
16
|
+
await handleSessionCleanupCommand(args, ctx);
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
pi.registerCommand(SESSION_NIX_COMMAND, {
|
|
21
|
+
description:
|
|
22
|
+
"Start a new session and automatically delete the previous session.",
|
|
23
|
+
handler: async (args, ctx) => {
|
|
24
|
+
await handleSessionNixCommand(args, ctx);
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
|
|
3
|
+
import type { SessionInfo } from "@mariozechner/pi-coding-agent";
|
|
4
|
+
|
|
5
|
+
import type { SessionCleanupSession } from "./types.js";
|
|
6
|
+
|
|
7
|
+
function toRecord(value: unknown): Record<string, unknown> | null {
|
|
8
|
+
return typeof value === "object" && value !== null ? (value as Record<string, unknown>) : null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function normalizeAgentName(value: unknown): string | null {
|
|
12
|
+
if (typeof value !== "string") {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const trimmed = value.trim();
|
|
17
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function parseJsonLine(value: string): Record<string, unknown> | null {
|
|
21
|
+
try {
|
|
22
|
+
return toRecord(JSON.parse(value));
|
|
23
|
+
} catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function extractResponsibleAgentNameFromContent(content: string): string | null {
|
|
29
|
+
const lines = content.split(/\r?\n/);
|
|
30
|
+
|
|
31
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
32
|
+
const trimmed = lines[index]?.trim();
|
|
33
|
+
if (!trimmed) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const entry = parseJsonLine(trimmed);
|
|
38
|
+
if (!entry || entry.type !== "custom" || entry.customType !== "active_agent") {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const data = toRecord(entry.data);
|
|
43
|
+
const normalizedAgentName = normalizeAgentName(data?.name);
|
|
44
|
+
if (normalizedAgentName) {
|
|
45
|
+
return normalizedAgentName;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (data?.name === null) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function resolveResponsibleAgentName(sessionPath: string): Promise<string | null> {
|
|
57
|
+
if (typeof sessionPath !== "string" || sessionPath.trim().length === 0) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const content = await readFile(sessionPath, "utf8");
|
|
63
|
+
return extractResponsibleAgentNameFromContent(content);
|
|
64
|
+
} catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function enrichSessionWithResponsibleAgent(
|
|
70
|
+
session: SessionInfo,
|
|
71
|
+
): Promise<SessionCleanupSession> {
|
|
72
|
+
const responsibleAgentName = await resolveResponsibleAgentName(session.path);
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
...session,
|
|
76
|
+
responsibleAgentName,
|
|
77
|
+
};
|
|
78
|
+
}
|