@sandropadin/tend 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +160 -0
- package/LICENSE +21 -0
- package/README.md +206 -0
- package/dist/detect.js +123 -0
- package/dist/git.js +57 -0
- package/dist/index.js +303 -0
- package/dist/manifests.js +133 -0
- package/dist/nav.js +33 -0
- package/dist/pick.js +214 -0
- package/dist/regions.js +60 -0
- package/dist/render.js +118 -0
- package/dist/scan.js +41 -0
- package/dist/tmux.js +152 -0
- package/dist/types.js +4 -0
- package/package.json +31 -0
- package/src/detect.ts +152 -0
- package/src/git.ts +64 -0
- package/src/index.ts +341 -0
- package/src/manifests.ts +139 -0
- package/src/nav.ts +44 -0
- package/src/pick.ts +224 -0
- package/src/regions.ts +65 -0
- package/src/render.ts +139 -0
- package/src/scan.ts +58 -0
- package/src/tmux.ts +173 -0
- package/src/types.ts +73 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Core data model. The whole detection system is data, not code: manifests
|
|
2
|
+
// describe how to recognize an agent and how to read its state off the rendered
|
|
3
|
+
// terminal.
|
|
4
|
+
|
|
5
|
+
export type AgentState = "blocked" | "working" | "idle" | "unknown";
|
|
6
|
+
|
|
7
|
+
// Which slice of the captured pane text a rule looks at. See src/regions.ts for
|
|
8
|
+
// the region extractor implementations.
|
|
9
|
+
export type Region =
|
|
10
|
+
| "full" // the entire capture
|
|
11
|
+
| "after_last_horizontal_rule" // everything below the last ─── rule (the live area)
|
|
12
|
+
| "prompt_box_body" // the interior of the input box (between its top/bottom borders)
|
|
13
|
+
| { bottom_non_empty_lines: number }; // the last N non-blank lines
|
|
14
|
+
|
|
15
|
+
export interface Rule {
|
|
16
|
+
id: string;
|
|
17
|
+
state: AgentState;
|
|
18
|
+
priority: number; // highest matching rule wins
|
|
19
|
+
region: Region;
|
|
20
|
+
contains?: string[]; // ALL of these substrings must be present (case-insensitive)
|
|
21
|
+
anyContains?: string[]; // AT LEAST ONE of these must be present
|
|
22
|
+
regex?: string; // regex (multiline, case-insensitive) that must match
|
|
23
|
+
not?: string[]; // NONE of these substrings may be present
|
|
24
|
+
// When true and this rule matches, hold the previously-known state instead of
|
|
25
|
+
// overwriting it. Used for scrollback / transcript / menu screens that don't
|
|
26
|
+
// reflect live agent state.
|
|
27
|
+
skipStateUpdate?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface Manifest {
|
|
31
|
+
agent: string; // display name, e.g. "claude"
|
|
32
|
+
// pane_current_command values that identify this agent directly (fast path).
|
|
33
|
+
match: string[];
|
|
34
|
+
// Regex matched against pane_current_command. Claude Code renames its own
|
|
35
|
+
// process comm to its version string (e.g. "2.1.200"), so the literal name
|
|
36
|
+
// "claude" never appears — a semver pattern catches it. This is the most
|
|
37
|
+
// reliable signal because it's available regardless of what's scrolled into
|
|
38
|
+
// view, unlike screen signatures.
|
|
39
|
+
commandPattern?: string;
|
|
40
|
+
// Substrings that identify the agent from the *screen*, used when the process
|
|
41
|
+
// name is generic (e.g. Claude launched as `node`). These must be strings the
|
|
42
|
+
// agent keeps on screen in ANY state — persistent footer/chrome, not the
|
|
43
|
+
// welcome banner (which scrolls away mid-conversation).
|
|
44
|
+
signature: string[];
|
|
45
|
+
rules: Rule[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface PaneInfo {
|
|
49
|
+
id: string; // tmux pane id, e.g. "%3"
|
|
50
|
+
command: string; // #{pane_current_command}
|
|
51
|
+
pid: number; // #{pane_pid}
|
|
52
|
+
path: string; // #{pane_current_path}
|
|
53
|
+
title: string; // #{pane_title}
|
|
54
|
+
sessionName: string; // #{session_name}
|
|
55
|
+
windowName: string; // #{window_name}
|
|
56
|
+
windowIndex: string; // #{window_index}
|
|
57
|
+
active: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface GitStatus {
|
|
61
|
+
branch: string | null;
|
|
62
|
+
dirty: boolean;
|
|
63
|
+
ahead: number;
|
|
64
|
+
behind: number;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface AgentStatus {
|
|
68
|
+
pane: PaneInfo;
|
|
69
|
+
agent: string;
|
|
70
|
+
state: AgentState;
|
|
71
|
+
matchedRule: string | null;
|
|
72
|
+
git: GitStatus | null;
|
|
73
|
+
}
|