taphound 0.2.0-dev.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 +202 -0
- package/README.md +200 -0
- package/README.zh-CN.md +200 -0
- package/assets/brand/taphound-mark.svg +9 -0
- package/assets/skills/taphound-ai-journey/GUIDE.md +862 -0
- package/assets/skills/taphound-ai-journey/SKILL.md +377 -0
- package/assets/skills/taphound-ai-journey/prompts/analyze-project.md +526 -0
- package/assets/skills/taphound-ai-journey/prompts/check-completion.md +52 -0
- package/assets/skills/taphound-ai-journey/prompts/generate-step.md +109 -0
- package/assets/skills/taphound-ai-journey/schemas/observe-output.json +42 -0
- package/assets/skills/taphound-ai-journey/schemas/project-context.json +81 -0
- package/assets/skills/taphound-ai-journey/schemas/proposed-step-envelope.json +267 -0
- package/assets/skills/taphound-ai-journey/templates/project-context.example.json +49 -0
- package/dist/adapters/adb/adb-adapter.d.ts +23 -0
- package/dist/adapters/adb/adb-adapter.js +218 -0
- package/dist/adapters/android-cli/android-cli-adapter.d.ts +11 -0
- package/dist/adapters/android-cli/android-cli-adapter.js +64 -0
- package/dist/adapters/android-cli/layout-parser.d.ts +3 -0
- package/dist/adapters/android-cli/layout-parser.js +174 -0
- package/dist/adapters/clock/system-clock.d.ts +5 -0
- package/dist/adapters/clock/system-clock.js +13 -0
- package/dist/adapters/filesystem/artifact-store.d.ts +4 -0
- package/dist/adapters/filesystem/artifact-store.js +73 -0
- package/dist/adapters/filesystem/generation-meta-writer.d.ts +16 -0
- package/dist/adapters/filesystem/generation-meta-writer.js +34 -0
- package/dist/adapters/filesystem/generation-session-store.d.ts +68 -0
- package/dist/adapters/filesystem/generation-session-store.js +1603 -0
- package/dist/adapters/filesystem/journey-writer.d.ts +16 -0
- package/dist/adapters/filesystem/journey-writer.js +34 -0
- package/dist/adapters/filesystem/project-bound-file.d.ts +6 -0
- package/dist/adapters/filesystem/project-bound-file.js +240 -0
- package/dist/adapters/filesystem/project-file-inspector.d.ts +8 -0
- package/dist/adapters/filesystem/project-file-inspector.js +198 -0
- package/dist/adapters/filesystem/skill-installer.d.ts +10 -0
- package/dist/adapters/filesystem/skill-installer.js +39 -0
- package/dist/adapters/process/node-process-runner.d.ts +8 -0
- package/dist/adapters/process/node-process-runner.js +155 -0
- package/dist/adapters/prompt/inquirer-generation-prompt.d.ts +55 -0
- package/dist/adapters/prompt/inquirer-generation-prompt.js +213 -0
- package/dist/adapters/prompt/inquirer-init-prompt.d.ts +32 -0
- package/dist/adapters/prompt/inquirer-init-prompt.js +55 -0
- package/dist/adapters/prompt/inquirer-recorder-prompt.d.ts +47 -0
- package/dist/adapters/prompt/inquirer-recorder-prompt.js +157 -0
- package/dist/application/assertion/expectation-evaluator.d.ts +61 -0
- package/dist/application/assertion/expectation-evaluator.js +207 -0
- package/dist/application/collector/logcat-collector.d.ts +39 -0
- package/dist/application/collector/logcat-collector.js +107 -0
- package/dist/application/context/context-validator.d.ts +27 -0
- package/dist/application/context/context-validator.js +120 -0
- package/dist/application/doctor/doctor-service.d.ts +35 -0
- package/dist/application/doctor/doctor-service.js +178 -0
- package/dist/application/generation/focused-input.d.ts +2 -0
- package/dist/application/generation/focused-input.js +9 -0
- package/dist/application/generation/generation-confirmation-service.d.ts +76 -0
- package/dist/application/generation/generation-confirmation-service.js +383 -0
- package/dist/application/generation/generation-finalizer.d.ts +67 -0
- package/dist/application/generation/generation-finalizer.js +646 -0
- package/dist/application/generation/generation-publisher.d.ts +46 -0
- package/dist/application/generation/generation-publisher.js +178 -0
- package/dist/application/generation/generation-starter.d.ts +31 -0
- package/dist/application/generation/generation-starter.js +102 -0
- package/dist/application/generation/generation-step-executor.d.ts +52 -0
- package/dist/application/generation/generation-step-executor.js +668 -0
- package/dist/application/generation/proposed-step-validator.d.ts +11 -0
- package/dist/application/generation/proposed-step-validator.js +88 -0
- package/dist/application/generation/risk-evaluator.d.ts +9 -0
- package/dist/application/generation/risk-evaluator.js +14 -0
- package/dist/application/generation/runtime-observer.d.ts +39 -0
- package/dist/application/generation/runtime-observer.js +157 -0
- package/dist/application/init/init-service.d.ts +17 -0
- package/dist/application/init/init-service.js +44 -0
- package/dist/application/interaction/action-executor.d.ts +25 -0
- package/dist/application/interaction/action-executor.js +103 -0
- package/dist/application/interaction/fallback-resolver.d.ts +24 -0
- package/dist/application/interaction/fallback-resolver.js +48 -0
- package/dist/application/interaction/scroll-to-executor.d.ts +40 -0
- package/dist/application/interaction/scroll-to-executor.js +191 -0
- package/dist/application/locator/locator-resolver.d.ts +20 -0
- package/dist/application/locator/locator-resolver.js +89 -0
- package/dist/application/project/project-describer.d.ts +14 -0
- package/dist/application/project/project-describer.js +8 -0
- package/dist/application/recorder/locator-selector.d.ts +10 -0
- package/dist/application/recorder/locator-selector.js +80 -0
- package/dist/application/recorder/recorder-service.d.ts +41 -0
- package/dist/application/recorder/recorder-service.js +331 -0
- package/dist/application/report/report-writer.d.ts +10 -0
- package/dist/application/report/report-writer.js +39 -0
- package/dist/application/runtime/activity-waiter.d.ts +33 -0
- package/dist/application/runtime/activity-waiter.js +73 -0
- package/dist/application/runtime/launch-failure.d.ts +2 -0
- package/dist/application/runtime/launch-failure.js +20 -0
- package/dist/application/runtime/process-waiter.d.ts +27 -0
- package/dist/application/runtime/process-waiter.js +73 -0
- package/dist/application/runtime/step-runner.d.ts +50 -0
- package/dist/application/runtime/step-runner.js +429 -0
- package/dist/application/runtime/verify-runtime.d.ts +44 -0
- package/dist/application/runtime/verify-runtime.js +350 -0
- package/dist/application/wait/idle-waiter.d.ts +30 -0
- package/dist/application/wait/idle-waiter.js +90 -0
- package/dist/cli/commands/context.d.ts +3 -0
- package/dist/cli/commands/context.js +94 -0
- package/dist/cli/commands/doctor.d.ts +3 -0
- package/dist/cli/commands/doctor.js +51 -0
- package/dist/cli/commands/generation.d.ts +3 -0
- package/dist/cli/commands/generation.js +518 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.js +104 -0
- package/dist/cli/commands/project.d.ts +3 -0
- package/dist/cli/commands/project.js +58 -0
- package/dist/cli/commands/record.d.ts +3 -0
- package/dist/cli/commands/record.js +88 -0
- package/dist/cli/commands/verify.d.ts +3 -0
- package/dist/cli/commands/verify.js +106 -0
- package/dist/cli/dependencies.d.ts +66 -0
- package/dist/cli/dependencies.js +204 -0
- package/dist/cli/main.d.ts +8 -0
- package/dist/cli/main.js +73 -0
- package/dist/cli/output.d.ts +16 -0
- package/dist/cli/output.js +22 -0
- package/dist/cli/program.d.ts +3 -0
- package/dist/cli/program.js +43 -0
- package/dist/domain/activity.d.ts +7 -0
- package/dist/domain/activity.js +65 -0
- package/dist/domain/app-process.d.ts +7 -0
- package/dist/domain/app-process.js +10 -0
- package/dist/domain/config.d.ts +15 -0
- package/dist/domain/config.js +17 -0
- package/dist/domain/failure.d.ts +4 -0
- package/dist/domain/failure.js +43 -0
- package/dist/domain/generation.d.ts +912 -0
- package/dist/domain/generation.js +342 -0
- package/dist/domain/init.d.ts +42 -0
- package/dist/domain/init.js +114 -0
- package/dist/domain/journey.d.ts +673 -0
- package/dist/domain/journey.js +109 -0
- package/dist/domain/layout.d.ts +35 -0
- package/dist/domain/layout.js +33 -0
- package/dist/domain/locator.d.ts +8 -0
- package/dist/domain/locator.js +5 -0
- package/dist/domain/project-context.d.ts +101 -0
- package/dist/domain/project-context.js +64 -0
- package/dist/domain/proposed-step.d.ts +341 -0
- package/dist/domain/proposed-step.js +87 -0
- package/dist/domain/report.d.ts +349 -0
- package/dist/domain/report.js +135 -0
- package/dist/domain/runtime-snapshot.d.ts +16 -0
- package/dist/domain/runtime-snapshot.js +46 -0
- package/dist/ports/adb.d.ts +42 -0
- package/dist/ports/adb.js +1 -0
- package/dist/ports/android-cli.d.ts +21 -0
- package/dist/ports/android-cli.js +1 -0
- package/dist/ports/artifact-store.d.ts +12 -0
- package/dist/ports/artifact-store.js +1 -0
- package/dist/ports/clock.d.ts +4 -0
- package/dist/ports/clock.js +1 -0
- package/dist/ports/generation-meta-writer.d.ts +10 -0
- package/dist/ports/generation-meta-writer.js +1 -0
- package/dist/ports/generation-prompt.d.ts +19 -0
- package/dist/ports/generation-prompt.js +6 -0
- package/dist/ports/generation-session-store.d.ts +32 -0
- package/dist/ports/generation-session-store.js +26 -0
- package/dist/ports/init-prompt.d.ts +8 -0
- package/dist/ports/init-prompt.js +6 -0
- package/dist/ports/journey-writer.d.ts +10 -0
- package/dist/ports/journey-writer.js +1 -0
- package/dist/ports/process-runner.d.ts +32 -0
- package/dist/ports/process-runner.js +1 -0
- package/dist/ports/project-bound-file.d.ts +8 -0
- package/dist/ports/project-bound-file.js +1 -0
- package/dist/ports/project-file-inspector.d.ts +33 -0
- package/dist/ports/project-file-inspector.js +1 -0
- package/dist/ports/recorder-prompt.d.ts +29 -0
- package/dist/ports/recorder-prompt.js +1 -0
- package/dist/ports/skill-installer.d.ts +8 -0
- package/dist/ports/skill-installer.js +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { LocatorSchema } from "./layout.js";
|
|
3
|
+
const QualifiedActivitySchema = z.string().regex(/^(?:[A-Za-z_$][\w$]*\.)+[A-Za-z_$][\w$]*$/, "Activity checkpoint must be fully qualified");
|
|
4
|
+
export const ActivityCheckpointSchema = z.strictObject({
|
|
5
|
+
before: QualifiedActivitySchema,
|
|
6
|
+
after: QualifiedActivitySchema
|
|
7
|
+
});
|
|
8
|
+
const ActivityExpectSchema = z.strictObject({
|
|
9
|
+
type: z.literal("activity"),
|
|
10
|
+
value: QualifiedActivitySchema,
|
|
11
|
+
timeoutMs: z.number().int().positive()
|
|
12
|
+
});
|
|
13
|
+
const ElementExpectSchema = z.strictObject({
|
|
14
|
+
type: z.literal("element"),
|
|
15
|
+
locator: LocatorSchema,
|
|
16
|
+
timeoutMs: z.number().int().positive()
|
|
17
|
+
});
|
|
18
|
+
const LogcatExpectSchema = z.strictObject({
|
|
19
|
+
type: z.literal("logcat"),
|
|
20
|
+
tag: z.string().min(1),
|
|
21
|
+
level: z.enum(["V", "D", "I", "W", "E", "F", "A"]).optional(),
|
|
22
|
+
pattern: z.string().min(1),
|
|
23
|
+
match: z.enum(["literal", "regex"]).default("literal"),
|
|
24
|
+
timeoutMs: z.number().int().positive()
|
|
25
|
+
}).superRefine((expectation, context) => {
|
|
26
|
+
if (expectation.match === "regex") {
|
|
27
|
+
try {
|
|
28
|
+
new RegExp(expectation.pattern);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
context.addIssue({
|
|
32
|
+
code: "custom",
|
|
33
|
+
path: ["pattern"],
|
|
34
|
+
message: "pattern must be a valid regular expression"
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
export const ExpectSchema = z.discriminatedUnion("type", [
|
|
40
|
+
ActivityExpectSchema,
|
|
41
|
+
ElementExpectSchema,
|
|
42
|
+
LogcatExpectSchema
|
|
43
|
+
]);
|
|
44
|
+
const CommonStepShape = {
|
|
45
|
+
activity: ActivityCheckpointSchema,
|
|
46
|
+
expect: ExpectSchema.optional()
|
|
47
|
+
};
|
|
48
|
+
export const AnnotatedLabelFallbackSchema = z.strictObject({
|
|
49
|
+
type: z.literal("annotatedLabel"),
|
|
50
|
+
label: z.string().regex(/^#\d+$/, "Fallback label must use Android CLI #number format")
|
|
51
|
+
});
|
|
52
|
+
const ClickStepSchema = z.strictObject({
|
|
53
|
+
action: z.literal("click"),
|
|
54
|
+
locator: LocatorSchema,
|
|
55
|
+
fallback: AnnotatedLabelFallbackSchema.optional(),
|
|
56
|
+
...CommonStepShape
|
|
57
|
+
});
|
|
58
|
+
const LongClickStepSchema = z.strictObject({
|
|
59
|
+
action: z.literal("longClick"),
|
|
60
|
+
locator: LocatorSchema,
|
|
61
|
+
durationMs: z.number().int().positive().default(800),
|
|
62
|
+
fallback: AnnotatedLabelFallbackSchema.optional(),
|
|
63
|
+
...CommonStepShape
|
|
64
|
+
});
|
|
65
|
+
const InputTextStepSchema = z.strictObject({
|
|
66
|
+
action: z.literal("inputText"),
|
|
67
|
+
text: z.string().min(1),
|
|
68
|
+
...CommonStepShape
|
|
69
|
+
});
|
|
70
|
+
const SwipeStepSchema = z.strictObject({
|
|
71
|
+
action: z.literal("swipe"),
|
|
72
|
+
locator: LocatorSchema,
|
|
73
|
+
direction: z.enum(["up", "down", "left", "right"]),
|
|
74
|
+
distancePercent: z.number().positive().max(1).default(0.6),
|
|
75
|
+
durationMs: z.number().int().positive().default(300),
|
|
76
|
+
...CommonStepShape
|
|
77
|
+
});
|
|
78
|
+
const ScrollToStepSchema = z.strictObject({
|
|
79
|
+
action: z.literal("scrollTo"),
|
|
80
|
+
locator: LocatorSchema,
|
|
81
|
+
container: LocatorSchema,
|
|
82
|
+
direction: z.enum(["up", "down", "left", "right"]),
|
|
83
|
+
maxSwipes: z.number().int().positive().max(30).default(20),
|
|
84
|
+
distancePercent: z.number().positive().max(1).default(0.6),
|
|
85
|
+
durationMs: z.number().int().positive().default(300),
|
|
86
|
+
...CommonStepShape
|
|
87
|
+
});
|
|
88
|
+
const BackStepSchema = z.strictObject({
|
|
89
|
+
action: z.literal("back"),
|
|
90
|
+
...CommonStepShape
|
|
91
|
+
});
|
|
92
|
+
const WaitStepSchema = z.strictObject({
|
|
93
|
+
action: z.literal("wait"),
|
|
94
|
+
...CommonStepShape
|
|
95
|
+
});
|
|
96
|
+
export const JourneyStepSchema = z.discriminatedUnion("action", [
|
|
97
|
+
ClickStepSchema,
|
|
98
|
+
LongClickStepSchema,
|
|
99
|
+
InputTextStepSchema,
|
|
100
|
+
SwipeStepSchema,
|
|
101
|
+
ScrollToStepSchema,
|
|
102
|
+
BackStepSchema,
|
|
103
|
+
WaitStepSchema
|
|
104
|
+
]);
|
|
105
|
+
export const JourneySchema = z.strictObject({
|
|
106
|
+
version: z.literal(1),
|
|
107
|
+
name: z.string().trim().min(1),
|
|
108
|
+
steps: z.array(JourneyStepSchema).min(1)
|
|
109
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const BoundsSchema: z.ZodObject<{
|
|
3
|
+
left: z.ZodNumber;
|
|
4
|
+
top: z.ZodNumber;
|
|
5
|
+
right: z.ZodNumber;
|
|
6
|
+
bottom: z.ZodNumber;
|
|
7
|
+
}, z.core.$strict>;
|
|
8
|
+
export type Bounds = z.infer<typeof BoundsSchema>;
|
|
9
|
+
export declare const LayoutPointSchema: z.ZodObject<{
|
|
10
|
+
x: z.ZodNumber;
|
|
11
|
+
y: z.ZodNumber;
|
|
12
|
+
}, z.core.$strict>;
|
|
13
|
+
export type LayoutPoint = z.infer<typeof LayoutPointSchema>;
|
|
14
|
+
export declare const LocatorSchema: z.ZodObject<{
|
|
15
|
+
resourceId: z.ZodOptional<z.ZodString>;
|
|
16
|
+
text: z.ZodOptional<z.ZodString>;
|
|
17
|
+
contentDescription: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strict>;
|
|
19
|
+
export type Locator = z.infer<typeof LocatorSchema>;
|
|
20
|
+
export interface LayoutElement {
|
|
21
|
+
id: string;
|
|
22
|
+
resourceId?: string | undefined;
|
|
23
|
+
text?: string | undefined;
|
|
24
|
+
contentDescription?: string | undefined;
|
|
25
|
+
clickable?: boolean | undefined;
|
|
26
|
+
longClickable?: boolean | undefined;
|
|
27
|
+
scrollable?: boolean | undefined;
|
|
28
|
+
focusable?: boolean | undefined;
|
|
29
|
+
focused?: boolean | undefined;
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
center?: LayoutPoint | undefined;
|
|
32
|
+
bounds?: Bounds | undefined;
|
|
33
|
+
children: LayoutElement[];
|
|
34
|
+
}
|
|
35
|
+
export declare const LayoutElementSchema: z.ZodType<LayoutElement>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const BoundsSchema = z.strictObject({
|
|
3
|
+
left: z.number().int().nonnegative(),
|
|
4
|
+
top: z.number().int().nonnegative(),
|
|
5
|
+
right: z.number().int().positive(),
|
|
6
|
+
bottom: z.number().int().positive()
|
|
7
|
+
}).refine(({ left, right }) => right > left, { message: "right must be greater than left", path: ["right"] }).refine(({ bottom, top }) => bottom > top, { message: "bottom must be greater than top", path: ["bottom"] });
|
|
8
|
+
export const LayoutPointSchema = z.strictObject({
|
|
9
|
+
x: z.number().int().nonnegative(),
|
|
10
|
+
y: z.number().int().nonnegative()
|
|
11
|
+
});
|
|
12
|
+
export const LocatorSchema = z.strictObject({
|
|
13
|
+
resourceId: z.string().trim().min(1).optional(),
|
|
14
|
+
text: z.string().min(1).optional(),
|
|
15
|
+
contentDescription: z.string().min(1).optional()
|
|
16
|
+
}).refine(({ contentDescription, resourceId, text }) => (resourceId !== undefined
|
|
17
|
+
|| text !== undefined
|
|
18
|
+
|| contentDescription !== undefined), { message: "Locator must contain a supported identity field" });
|
|
19
|
+
export const LayoutElementSchema = z.lazy(() => z.strictObject({
|
|
20
|
+
id: z.string().min(1),
|
|
21
|
+
resourceId: z.string().min(1).optional(),
|
|
22
|
+
text: z.string().optional(),
|
|
23
|
+
contentDescription: z.string().optional(),
|
|
24
|
+
clickable: z.boolean().optional(),
|
|
25
|
+
longClickable: z.boolean().optional(),
|
|
26
|
+
scrollable: z.boolean().optional(),
|
|
27
|
+
focusable: z.boolean().optional(),
|
|
28
|
+
focused: z.boolean().optional(),
|
|
29
|
+
enabled: z.boolean(),
|
|
30
|
+
center: LayoutPointSchema.optional(),
|
|
31
|
+
bounds: BoundsSchema.optional(),
|
|
32
|
+
children: z.array(LayoutElementSchema).default([])
|
|
33
|
+
}).refine(({ bounds, center }) => bounds !== undefined || center !== undefined, { message: "Layout element requires center or bounds" }));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LayoutElement } from "./layout.js";
|
|
2
|
+
export declare const LOCATOR_FIELDS: readonly ["resourceId", "text", "contentDescription"];
|
|
3
|
+
export type LocatorField = (typeof LOCATOR_FIELDS)[number];
|
|
4
|
+
export interface LocatedElement {
|
|
5
|
+
element: LayoutElement;
|
|
6
|
+
field: LocatorField;
|
|
7
|
+
value: string;
|
|
8
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const ContextEvidenceConfidenceSchema: z.ZodEnum<{
|
|
3
|
+
unknown: "unknown";
|
|
4
|
+
sourceConfirmed: "sourceConfirmed";
|
|
5
|
+
runtimeConfirmed: "runtimeConfirmed";
|
|
6
|
+
inferred: "inferred";
|
|
7
|
+
}>;
|
|
8
|
+
export type ContextEvidenceConfidence = z.infer<typeof ContextEvidenceConfidenceSchema>;
|
|
9
|
+
export declare const ProjectRelativePathSchema: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
10
|
+
export declare const ContextManifestSchema: z.ZodObject<{
|
|
11
|
+
version: z.ZodLiteral<1>;
|
|
12
|
+
files: z.ZodArray<z.ZodObject<{
|
|
13
|
+
path: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
14
|
+
sha256: z.ZodString;
|
|
15
|
+
confidence: z.ZodEnum<{
|
|
16
|
+
unknown: "unknown";
|
|
17
|
+
sourceConfirmed: "sourceConfirmed";
|
|
18
|
+
runtimeConfirmed: "runtimeConfirmed";
|
|
19
|
+
inferred: "inferred";
|
|
20
|
+
}>;
|
|
21
|
+
}, z.core.$strict>>;
|
|
22
|
+
}, z.core.$strict>;
|
|
23
|
+
export declare const InteractionPolicySchema: z.ZodObject<{
|
|
24
|
+
allowedActions: z.ZodArray<z.ZodEnum<{
|
|
25
|
+
swipe: "swipe";
|
|
26
|
+
click: "click";
|
|
27
|
+
longClick: "longClick";
|
|
28
|
+
inputText: "inputText";
|
|
29
|
+
scrollTo: "scrollTo";
|
|
30
|
+
back: "back";
|
|
31
|
+
wait: "wait";
|
|
32
|
+
}>>;
|
|
33
|
+
confirmationRequiredActions: z.ZodArray<z.ZodEnum<{
|
|
34
|
+
swipe: "swipe";
|
|
35
|
+
click: "click";
|
|
36
|
+
longClick: "longClick";
|
|
37
|
+
inputText: "inputText";
|
|
38
|
+
scrollTo: "scrollTo";
|
|
39
|
+
back: "back";
|
|
40
|
+
wait: "wait";
|
|
41
|
+
}>>;
|
|
42
|
+
forbiddenActions: z.ZodArray<z.ZodEnum<{
|
|
43
|
+
swipe: "swipe";
|
|
44
|
+
click: "click";
|
|
45
|
+
longClick: "longClick";
|
|
46
|
+
inputText: "inputText";
|
|
47
|
+
scrollTo: "scrollTo";
|
|
48
|
+
back: "back";
|
|
49
|
+
wait: "wait";
|
|
50
|
+
}>>;
|
|
51
|
+
}, z.core.$strict>;
|
|
52
|
+
export declare const ProjectContextSchema: z.ZodObject<{
|
|
53
|
+
version: z.ZodLiteral<1>;
|
|
54
|
+
packageName: z.ZodString;
|
|
55
|
+
launchActivity: z.ZodString;
|
|
56
|
+
manifest: z.ZodObject<{
|
|
57
|
+
version: z.ZodLiteral<1>;
|
|
58
|
+
files: z.ZodArray<z.ZodObject<{
|
|
59
|
+
path: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
60
|
+
sha256: z.ZodString;
|
|
61
|
+
confidence: z.ZodEnum<{
|
|
62
|
+
unknown: "unknown";
|
|
63
|
+
sourceConfirmed: "sourceConfirmed";
|
|
64
|
+
runtimeConfirmed: "runtimeConfirmed";
|
|
65
|
+
inferred: "inferred";
|
|
66
|
+
}>;
|
|
67
|
+
}, z.core.$strict>>;
|
|
68
|
+
}, z.core.$strict>;
|
|
69
|
+
interactionPolicy: z.ZodObject<{
|
|
70
|
+
allowedActions: z.ZodArray<z.ZodEnum<{
|
|
71
|
+
swipe: "swipe";
|
|
72
|
+
click: "click";
|
|
73
|
+
longClick: "longClick";
|
|
74
|
+
inputText: "inputText";
|
|
75
|
+
scrollTo: "scrollTo";
|
|
76
|
+
back: "back";
|
|
77
|
+
wait: "wait";
|
|
78
|
+
}>>;
|
|
79
|
+
confirmationRequiredActions: z.ZodArray<z.ZodEnum<{
|
|
80
|
+
swipe: "swipe";
|
|
81
|
+
click: "click";
|
|
82
|
+
longClick: "longClick";
|
|
83
|
+
inputText: "inputText";
|
|
84
|
+
scrollTo: "scrollTo";
|
|
85
|
+
back: "back";
|
|
86
|
+
wait: "wait";
|
|
87
|
+
}>>;
|
|
88
|
+
forbiddenActions: z.ZodArray<z.ZodEnum<{
|
|
89
|
+
swipe: "swipe";
|
|
90
|
+
click: "click";
|
|
91
|
+
longClick: "longClick";
|
|
92
|
+
inputText: "inputText";
|
|
93
|
+
scrollTo: "scrollTo";
|
|
94
|
+
back: "back";
|
|
95
|
+
wait: "wait";
|
|
96
|
+
}>>;
|
|
97
|
+
}, z.core.$strict>;
|
|
98
|
+
}, z.core.$strict>;
|
|
99
|
+
export type ContextManifest = z.infer<typeof ContextManifestSchema>;
|
|
100
|
+
export type InteractionPolicy = z.infer<typeof InteractionPolicySchema>;
|
|
101
|
+
export type ProjectContext = z.infer<typeof ProjectContextSchema>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const QualifiedNameSchema = z.string().regex(/^(?:[A-Za-z_$][\w$]*\.)+[A-Za-z_$][\w$]*$/, "Value must be fully qualified");
|
|
3
|
+
const GenerationActionSchema = z.enum([
|
|
4
|
+
"click",
|
|
5
|
+
"longClick",
|
|
6
|
+
"inputText",
|
|
7
|
+
"swipe",
|
|
8
|
+
"scrollTo",
|
|
9
|
+
"back",
|
|
10
|
+
"wait"
|
|
11
|
+
]);
|
|
12
|
+
export const ContextEvidenceConfidenceSchema = z.enum([
|
|
13
|
+
"sourceConfirmed",
|
|
14
|
+
"runtimeConfirmed",
|
|
15
|
+
"inferred",
|
|
16
|
+
"unknown"
|
|
17
|
+
]);
|
|
18
|
+
export const ProjectRelativePathSchema = z.string()
|
|
19
|
+
.trim()
|
|
20
|
+
.min(1)
|
|
21
|
+
.transform((path) => path.replaceAll("\\", "/"))
|
|
22
|
+
.refine((path) => (!path.startsWith("/")
|
|
23
|
+
&& !/^[A-Za-z]:/.test(path)
|
|
24
|
+
&& !path.split("/").includes("..")), "Path must stay within the project");
|
|
25
|
+
const ContextFileSchema = z.strictObject({
|
|
26
|
+
path: ProjectRelativePathSchema,
|
|
27
|
+
sha256: z.string().regex(/^[a-f\d]{64}$/),
|
|
28
|
+
confidence: ContextEvidenceConfidenceSchema
|
|
29
|
+
});
|
|
30
|
+
export const ContextManifestSchema = z.strictObject({
|
|
31
|
+
version: z.literal(1),
|
|
32
|
+
files: z.array(ContextFileSchema).min(1)
|
|
33
|
+
});
|
|
34
|
+
export const InteractionPolicySchema = z.strictObject({
|
|
35
|
+
allowedActions: z.array(GenerationActionSchema),
|
|
36
|
+
confirmationRequiredActions: z.array(GenerationActionSchema),
|
|
37
|
+
forbiddenActions: z.array(GenerationActionSchema)
|
|
38
|
+
}).superRefine((policy, context) => {
|
|
39
|
+
const forbidden = new Set(policy.forbiddenActions);
|
|
40
|
+
const overlap = policy.allowedActions.find((action) => forbidden.has(action));
|
|
41
|
+
if (overlap !== undefined) {
|
|
42
|
+
context.addIssue({
|
|
43
|
+
code: "custom",
|
|
44
|
+
path: ["forbiddenActions"],
|
|
45
|
+
message: `${overlap} cannot be both allowed and forbidden`
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const allowed = new Set(policy.allowedActions);
|
|
49
|
+
const invalidConfirmation = policy.confirmationRequiredActions.find((action) => !allowed.has(action));
|
|
50
|
+
if (invalidConfirmation !== undefined) {
|
|
51
|
+
context.addIssue({
|
|
52
|
+
code: "custom",
|
|
53
|
+
path: ["confirmationRequiredActions"],
|
|
54
|
+
message: `${invalidConfirmation} must be allowed before requiring confirmation`
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
export const ProjectContextSchema = z.strictObject({
|
|
59
|
+
version: z.literal(1),
|
|
60
|
+
packageName: QualifiedNameSchema,
|
|
61
|
+
launchActivity: QualifiedNameSchema,
|
|
62
|
+
manifest: ContextManifestSchema,
|
|
63
|
+
interactionPolicy: InteractionPolicySchema
|
|
64
|
+
});
|