tapline-host 1.3.1 → 1.5.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/dist/actionlog.d.ts +28 -1
- package/dist/actionlog.js +2 -2
- package/dist/actionlog.js.map +1 -1
- package/dist/audit.d.ts +2 -0
- package/dist/audit.js +1 -1
- package/dist/audit.js.map +1 -1
- package/dist/cli.js +14 -0
- package/dist/cli.js.map +1 -1
- package/dist/format.d.ts +6 -0
- package/dist/format.js +69 -20
- package/dist/format.js.map +1 -1
- package/dist/images.d.ts +27 -0
- package/dist/images.js +50 -0
- package/dist/images.js.map +1 -1
- package/dist/init.js +83 -1
- package/dist/init.js.map +1 -1
- package/dist/journey.d.ts +259 -0
- package/dist/journey.js +336 -0
- package/dist/journey.js.map +1 -0
- package/dist/journeyexport.d.ts +58 -0
- package/dist/journeyexport.js +318 -0
- package/dist/journeyexport.js.map +1 -0
- package/dist/journeygif.d.ts +62 -0
- package/dist/journeygif.js +192 -0
- package/dist/journeygif.js.map +1 -0
- package/dist/journeyreport.d.ts +202 -0
- package/dist/journeyreport.js +664 -0
- package/dist/journeyreport.js.map +1 -0
- package/dist/mcp.d.ts +1 -0
- package/dist/mcp.js +72 -32
- package/dist/mcp.js.map +1 -1
- package/dist/media.d.ts +86 -0
- package/dist/media.js +244 -0
- package/dist/media.js.map +1 -0
- package/dist/protocol.d.ts +6 -1
- package/dist/protocol.js +9 -1
- package/dist/protocol.js.map +1 -1
- package/dist/report.d.ts +55 -0
- package/dist/report.js +298 -0
- package/dist/report.js.map +1 -0
- package/dist/run.js +1 -1
- package/dist/run.js.map +1 -1
- package/dist/server.d.ts +2 -0
- package/dist/server.js +8 -0
- package/dist/server.js.map +1 -1
- package/dist/tool-text-data.d.ts +5 -1
- package/dist/tool-text-data.js +5 -1
- package/dist/tool-text-data.js.map +1 -1
- package/dist/tools.d.ts +262 -0
- package/dist/tools.js +1337 -35
- package/dist/tools.js.map +1 -1
- package/dist/uxcheck.d.ts +102 -0
- package/dist/uxcheck.js +128 -0
- package/dist/uxcheck.js.map +1 -0
- package/package.json +2 -1
- package/skills/tapline/SKILL.md +40 -1
- package/skills/tapline/references/personas.md +45 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import type { ShotImage } from "./annotate.js";
|
|
2
|
+
import { type ShareBox } from "./images.js";
|
|
3
|
+
import { type JourneyState } from "./journey.js";
|
|
4
|
+
import type { UxAction, UxFindingSummary } from "./uxcheck.js";
|
|
5
|
+
/**
|
|
6
|
+
* The journey's visual report (AGENT-TOOLS 1.12 §17.5): the frames kept after each counted step, the findings, and
|
|
7
|
+
* the folder written at `stop`: `report.md`, `report.html`, `frames/`, `findings/`, `journey.gif`, `key-1.jpg`,
|
|
8
|
+
* `key-2.jpg`. Pictures stay in files; only the two key pictures reach the agent.
|
|
9
|
+
*/
|
|
10
|
+
export declare const FRAME_WIDTH = 360;
|
|
11
|
+
/** The report lists this many findings at most (the worst first) and says how many more there were; it never blocks `stop`. */
|
|
12
|
+
export declare const MAX_FINDINGS = 100;
|
|
13
|
+
/** What the app showed at one moment, from a cheap read that touches nothing. */
|
|
14
|
+
export interface Peek {
|
|
15
|
+
/** Hash of what is on screen: same hash, same screen. */
|
|
16
|
+
signature: string;
|
|
17
|
+
screen?: {
|
|
18
|
+
w: number;
|
|
19
|
+
h: number;
|
|
20
|
+
};
|
|
21
|
+
route: string[];
|
|
22
|
+
}
|
|
23
|
+
/** Where the recorder gets its pictures: the host's requests to the app, or a fake in tests. */
|
|
24
|
+
export interface FrameSource {
|
|
25
|
+
/** Whether the journey's app is connected and in front: frames are only taken then. */
|
|
26
|
+
where(): "front" | "background" | "disconnected" | "other";
|
|
27
|
+
peek(): Promise<Peek | undefined>;
|
|
28
|
+
shot(width: number, quality: number): Promise<ShotImage | undefined>;
|
|
29
|
+
}
|
|
30
|
+
/** The screen's elements as one hash: texts, values, positions and the route, not refs. */
|
|
31
|
+
export declare function screenSignature(elements: ReadonlyArray<{
|
|
32
|
+
role?: string | null;
|
|
33
|
+
text?: string | null;
|
|
34
|
+
label?: string | null;
|
|
35
|
+
value?: unknown;
|
|
36
|
+
frame?: {
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
} | null;
|
|
42
|
+
}>, route: string[], alerts: number): string;
|
|
43
|
+
/** Where a step touched, in points, and the frame of the element it touched. */
|
|
44
|
+
export interface Touch {
|
|
45
|
+
point?: {
|
|
46
|
+
x: number;
|
|
47
|
+
y: number;
|
|
48
|
+
};
|
|
49
|
+
frame?: {
|
|
50
|
+
x: number;
|
|
51
|
+
y: number;
|
|
52
|
+
width: number;
|
|
53
|
+
height: number;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export interface FrameRecord {
|
|
57
|
+
/** 1-based, in the order kept. */
|
|
58
|
+
n: number;
|
|
59
|
+
/** The step this frame follows; 0 is the screen at the start. */
|
|
60
|
+
step: number;
|
|
61
|
+
/** Relative to the report folder. */
|
|
62
|
+
file: string;
|
|
63
|
+
at: number;
|
|
64
|
+
/** The journey's screen number. */
|
|
65
|
+
screen: number | undefined;
|
|
66
|
+
signature: string;
|
|
67
|
+
/** Where the step touched and the touched element's box, as shares of the screen. */
|
|
68
|
+
tap?: {
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
};
|
|
72
|
+
box?: ShareBox;
|
|
73
|
+
}
|
|
74
|
+
/** One finding of a `ux_check` the agent made during the journey, with its marked-up picture. */
|
|
75
|
+
export interface SeenFinding extends UxFindingSummary {
|
|
76
|
+
screen: number | undefined;
|
|
77
|
+
title: string;
|
|
78
|
+
/** Relative path of the picture with the red box. */
|
|
79
|
+
shot?: string;
|
|
80
|
+
}
|
|
81
|
+
export declare class JourneyRecorder {
|
|
82
|
+
readonly folder: string;
|
|
83
|
+
private readonly source;
|
|
84
|
+
private readonly clock;
|
|
85
|
+
readonly frames: FrameRecord[];
|
|
86
|
+
readonly seen: SeenFinding[];
|
|
87
|
+
/** Skipped frames: the list hadn't changed and nothing animated. */
|
|
88
|
+
skipped: number;
|
|
89
|
+
/** Frames not taken because the journey's app was not connected and in front, by where it was. */
|
|
90
|
+
readonly away: Map<string, number>;
|
|
91
|
+
private readonly actions;
|
|
92
|
+
private queue;
|
|
93
|
+
private lastSignature;
|
|
94
|
+
private uxCount;
|
|
95
|
+
/** Times the app's photo picker was skipped (`media` with `picker`) during the journey. */
|
|
96
|
+
pickerSkips: number;
|
|
97
|
+
pickerPictures: number;
|
|
98
|
+
constructor(folder: string, source: FrameSource, clock: () => number);
|
|
99
|
+
get name(): string;
|
|
100
|
+
/** Runs `work` after the ones before it: the pictures come in the order of the steps. */
|
|
101
|
+
private later;
|
|
102
|
+
/**
|
|
103
|
+
* Keeps a small picture of the screen after a step. Skipped when the element list is what it was and nothing
|
|
104
|
+
* animates (AGENTS.md: don't look twice). Never fails the step.
|
|
105
|
+
*/
|
|
106
|
+
frame(step: number, screen: number | undefined, touch: Touch | undefined, animating: boolean): Promise<void>;
|
|
107
|
+
/** The action labels of the screens seen before `current`, for `ux_check`'s naming check. */
|
|
108
|
+
earlier(current: number | undefined): UxAction[];
|
|
109
|
+
/** A `ux_check` was made: keep its actions, and a picture per finding with the element boxed in red. */
|
|
110
|
+
uxSeen(screen: number | undefined, title: string, actions: UxAction[], findings: UxFindingSummary[]): Promise<void>;
|
|
111
|
+
/** Everything asked for is on disk. */
|
|
112
|
+
done(): Promise<void>;
|
|
113
|
+
}
|
|
114
|
+
export type Severity = "high" | "medium" | "low";
|
|
115
|
+
export interface Finding {
|
|
116
|
+
severity: Severity;
|
|
117
|
+
kind: string;
|
|
118
|
+
/** One line: what is wrong. */
|
|
119
|
+
title: string;
|
|
120
|
+
screen: number | undefined;
|
|
121
|
+
basis: string;
|
|
122
|
+
/** Relative path of the marked-up picture. */
|
|
123
|
+
shot?: string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Simple rules, written in the report's footer. A `ux_check` kind not named here is low.
|
|
127
|
+
*/
|
|
128
|
+
export declare const SEVERITY_RULES: string[];
|
|
129
|
+
/** The findings of a finished journey, worst first. `steps` pictures are filled in by `markSteps`. */
|
|
130
|
+
export declare function buildFindings(state: JourneyState, seen: readonly SeenFinding[], maxTaps: number | undefined): Finding[];
|
|
131
|
+
export declare function countFindings(findings: readonly Finding[]): Record<Severity, number>;
|
|
132
|
+
/** `Findings: 2 high, 3 medium, 1 low.` or `Findings: none.` */
|
|
133
|
+
export declare function findingsLine(counts: Record<Severity, number>): string;
|
|
134
|
+
/** `2026-11-12-1530-log-breakfast-by-scanning-its-barcode`, in the computer's local time. */
|
|
135
|
+
export declare function reportFolderName(goal: string, at: number): string;
|
|
136
|
+
/** A folder name that doesn't exist yet in `root` (`-2`, `-3` when the same goal ran in the same minute). */
|
|
137
|
+
/** How many journey reports a host keeps in its journeys folder (1.5 review, finding 6). */
|
|
138
|
+
export declare const JOURNEYS_KEPT = 20;
|
|
139
|
+
/**
|
|
140
|
+
* Keeps the newest `keep` report folders in `root` (by when they were last changed) and removes the rest. Only folders
|
|
141
|
+
* that hold a report or frames (what a journey writes) are counted or removed; anything else in `root` is left alone.
|
|
142
|
+
*/
|
|
143
|
+
export declare function pruneJourneys(root: string, keep: number): number;
|
|
144
|
+
export declare function freshFolder(root: string, goal: string, at: number): string;
|
|
145
|
+
export interface ReportResult {
|
|
146
|
+
folder: string;
|
|
147
|
+
name: string;
|
|
148
|
+
findings: Finding[];
|
|
149
|
+
counts: Record<Severity, number>;
|
|
150
|
+
/** Files of the folder, relative, for the export. */
|
|
151
|
+
files: string[];
|
|
152
|
+
/** What an export uploads: the report, the GIF and the pictures the report uses; not every raw frame. */
|
|
153
|
+
exportFiles: string[];
|
|
154
|
+
/** The first picture of the path, for an export's comment when there is no GIF. */
|
|
155
|
+
firstPicture: string | undefined;
|
|
156
|
+
/** Findings beyond the 100 the report lists. */
|
|
157
|
+
omitted: number;
|
|
158
|
+
gif: {
|
|
159
|
+
frames: number;
|
|
160
|
+
bytes: number;
|
|
161
|
+
dropped: number;
|
|
162
|
+
} | null;
|
|
163
|
+
/** The key pictures, relative: where the journey ended, and the worst finding. */
|
|
164
|
+
keys: string[];
|
|
165
|
+
notes: string[];
|
|
166
|
+
}
|
|
167
|
+
/** At most this many pictures are decoded for the GIF (each is about 1 MB as pixels): 1.5 review, finding 6. */
|
|
168
|
+
export declare const GIF_MAX_SOURCE_FRAMES = 150;
|
|
169
|
+
/**
|
|
170
|
+
* The frames the GIF is made of, at most `max`: every tap and every first picture of a screen stays (they tell the
|
|
171
|
+
* story); the other, still pictures are thinned evenly. Chosen before anything is decoded.
|
|
172
|
+
*/
|
|
173
|
+
export declare function framesForGif(frames: readonly FrameRecord[], max?: number): FrameRecord[];
|
|
174
|
+
/**
|
|
175
|
+
* The report's own folder, in whatever slash style a step's text carries it, replaced by `<report>`: an export
|
|
176
|
+
* must not publish this computer's user name and folders.
|
|
177
|
+
*/
|
|
178
|
+
export declare function scrubFolder(text: string, folder: string): string;
|
|
179
|
+
export interface Ctx {
|
|
180
|
+
state: JourneyState;
|
|
181
|
+
rec: JourneyRecorder;
|
|
182
|
+
findings: Finding[];
|
|
183
|
+
counts: Record<Severity, number>;
|
|
184
|
+
/** Findings past the cap, not listed. */
|
|
185
|
+
omitted: number;
|
|
186
|
+
gif: ReportResult["gif"];
|
|
187
|
+
maxTaps: number | undefined;
|
|
188
|
+
textRules: readonly string[];
|
|
189
|
+
}
|
|
190
|
+
export declare function renderMarkdown(ctx: Ctx): string;
|
|
191
|
+
export declare function renderHtml(ctx: Ctx): string;
|
|
192
|
+
export interface WriteOptions {
|
|
193
|
+
state: JourneyState;
|
|
194
|
+
rec: JourneyRecorder;
|
|
195
|
+
maxTaps: number | undefined;
|
|
196
|
+
textRules?: readonly string[];
|
|
197
|
+
gifMaxBytes?: number;
|
|
198
|
+
}
|
|
199
|
+
/** Writes the report folder: waits for the pictures asked for, then the findings, GIF, key pictures, `report.md` and `report.html`. */
|
|
200
|
+
export declare function writeReport(options: WriteOptions): Promise<ReportResult>;
|
|
201
|
+
/** A picture inside the report folder: a relative path of plain names, no `..`, ending .png, .jpg or .gif. */
|
|
202
|
+
export declare function isReportPicture(path: string): boolean;
|