mobile-debug-mcp 0.26.3 → 0.26.5
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/interact/index.js +496 -7
- package/dist/observe/ios.js +48 -4
- package/dist/server/tool-definitions.js +56 -0
- package/dist/server/tool-handlers.js +25 -0
- package/dist/server-core.js +1 -1
- package/dist/utils/android/utils.js +37 -5
- package/docs/CHANGELOG.md +6 -0
- package/docs/ROADMAP.md +69 -14
- package/docs/rfcs/008-adjustable-control-support-and-semantic-value-manipulation.md +273 -0
- package/docs/rfcs/009-semantic-control-modeling-for-custom-and-composite-controls.md +238 -0
- package/docs/specs/mcp-tooling-spec-v1.md +23 -1
- package/docs/tools/interact.md +21 -0
- package/package.json +1 -1
- package/src/interact/index.ts +625 -8
- package/src/observe/ios.ts +43 -4
- package/src/server/tool-definitions.ts +56 -0
- package/src/server/tool-handlers.ts +26 -0
- package/src/server-core.ts +1 -1
- package/src/types.ts +21 -0
- package/src/utils/android/utils.ts +32 -5
- package/test/unit/interact/adjust_control.test.ts +365 -0
- package/test/unit/observe/find_element.test.ts +46 -0
- package/test/unit/observe/state_extraction.test.ts +89 -2
- package/test/unit/server/contract.test.ts +8 -0
- package/test/unit/server/response_shapes.test.ts +39 -0
|
@@ -555,6 +555,62 @@ Failure Handling:
|
|
|
555
555
|
required: ['property', 'expected']
|
|
556
556
|
}
|
|
557
557
|
},
|
|
558
|
+
{
|
|
559
|
+
name: 'adjust_control',
|
|
560
|
+
description: `Purpose:
|
|
561
|
+
Adjust a numeric control value with verification.
|
|
562
|
+
|
|
563
|
+
This is the initial adjustable-control surface for slider-like controls and other controls that expose a numeric value or value_range.
|
|
564
|
+
|
|
565
|
+
Inputs:
|
|
566
|
+
- selector or element_id
|
|
567
|
+
- property (defaults to "value")
|
|
568
|
+
- targetValue
|
|
569
|
+
- tolerance (optional)
|
|
570
|
+
- maxAttempts (optional)
|
|
571
|
+
- platform/deviceId (optional)
|
|
572
|
+
|
|
573
|
+
Output Structure:
|
|
574
|
+
- action_id, timestamp (ISO 8601), action_type
|
|
575
|
+
- lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
|
|
576
|
+
- source_module: runtime source of the action envelope
|
|
577
|
+
- target_state / actual_state / within_tolerance / converged / attempts / adjustment_mode
|
|
578
|
+
- target.selector = original selector or element handle
|
|
579
|
+
- success = true when the control converges within tolerance
|
|
580
|
+
|
|
581
|
+
Verification Guidance:
|
|
582
|
+
- Prefer direct target placement when value_range is available; fall back to a drag only if the direct tap does not converge
|
|
583
|
+
- Use expect_state for the control value readback
|
|
584
|
+
- Treat coordinate fallback as degraded mode
|
|
585
|
+
|
|
586
|
+
Failure Handling:
|
|
587
|
+
- ELEMENT_NOT_FOUND → re-resolve the control
|
|
588
|
+
- ELEMENT_NOT_INTERACTABLE → the control cannot be adjusted through the current runtime
|
|
589
|
+
- TIMEOUT → the control did not converge within bounded retries
|
|
590
|
+
- UNKNOWN → capture a snapshot and stop`,
|
|
591
|
+
inputSchema: {
|
|
592
|
+
type: 'object',
|
|
593
|
+
properties: {
|
|
594
|
+
selector: {
|
|
595
|
+
type: 'object',
|
|
596
|
+
properties: {
|
|
597
|
+
text: { type: 'string' },
|
|
598
|
+
resource_id: { type: 'string' },
|
|
599
|
+
accessibility_id: { type: 'string' },
|
|
600
|
+
contains: { type: 'boolean', default: false }
|
|
601
|
+
}
|
|
602
|
+
},
|
|
603
|
+
element_id: { type: 'string', description: 'Optional previously resolved element identifier.' },
|
|
604
|
+
property: { type: 'string', description: 'Readable numeric state property to adjust.', default: 'value' },
|
|
605
|
+
targetValue: { type: 'number', description: 'Target numeric value.' },
|
|
606
|
+
tolerance: { type: 'number', description: 'Accepted numeric tolerance around the target value.', default: 0 },
|
|
607
|
+
maxAttempts: { type: 'number', description: 'Maximum adjustment attempts.', default: 3 },
|
|
608
|
+
platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override' },
|
|
609
|
+
deviceId: { type: 'string', description: 'Optional device serial/udid' }
|
|
610
|
+
},
|
|
611
|
+
required: ['targetValue']
|
|
612
|
+
}
|
|
613
|
+
},
|
|
558
614
|
{
|
|
559
615
|
name: 'wait_for_ui',
|
|
560
616
|
description: `Purpose:
|
|
@@ -226,6 +226,30 @@ async function handleExpectState(args) {
|
|
|
226
226
|
const res = await ToolsInteract.expectStateHandler({ selector: selector ?? undefined, element_id: element_id ?? undefined, property, expected, platform, deviceId });
|
|
227
227
|
return wrapResponse(res);
|
|
228
228
|
}
|
|
229
|
+
async function handleAdjustControl(args) {
|
|
230
|
+
const selector = getObjectArg(args, 'selector');
|
|
231
|
+
const element_id = getStringArg(args, 'element_id');
|
|
232
|
+
const property = getStringArg(args, 'property') ?? 'value';
|
|
233
|
+
const targetValue = requireNumberArg(args, 'targetValue');
|
|
234
|
+
const tolerance = getNumberArg(args, 'tolerance') ?? 0;
|
|
235
|
+
const maxAttempts = getNumberArg(args, 'maxAttempts') ?? 3;
|
|
236
|
+
const platform = getStringArg(args, 'platform');
|
|
237
|
+
const deviceId = getStringArg(args, 'deviceId');
|
|
238
|
+
if (!selector && !element_id) {
|
|
239
|
+
throw new Error('Missing selector or element_id argument');
|
|
240
|
+
}
|
|
241
|
+
const res = await ToolsInteract.adjustControlHandler({
|
|
242
|
+
selector: selector ?? undefined,
|
|
243
|
+
element_id: element_id ?? undefined,
|
|
244
|
+
property,
|
|
245
|
+
targetValue,
|
|
246
|
+
tolerance,
|
|
247
|
+
maxAttempts,
|
|
248
|
+
platform,
|
|
249
|
+
deviceId
|
|
250
|
+
});
|
|
251
|
+
return wrapResponse(res);
|
|
252
|
+
}
|
|
229
253
|
async function handleWaitForUI(args) {
|
|
230
254
|
const selector = getObjectArg(args, 'selector');
|
|
231
255
|
const condition = getStringArg(args, 'condition') ?? 'exists';
|
|
@@ -431,6 +455,7 @@ export const toolHandlers = {
|
|
|
431
455
|
expect_screen: handleExpectScreen,
|
|
432
456
|
expect_element_visible: handleExpectElementVisible,
|
|
433
457
|
expect_state: handleExpectState,
|
|
458
|
+
adjust_control: handleAdjustControl,
|
|
434
459
|
wait_for_ui: handleWaitForUI,
|
|
435
460
|
find_element: handleFindElement,
|
|
436
461
|
tap: handleTap,
|
package/dist/server-core.js
CHANGED
|
@@ -6,7 +6,7 @@ import { handleToolCall } from './server/tool-handlers.js';
|
|
|
6
6
|
export { wrapResponse, toolDefinitions, handleToolCall };
|
|
7
7
|
export const serverInfo = {
|
|
8
8
|
name: 'mobile-debug-mcp',
|
|
9
|
-
version: '0.26.
|
|
9
|
+
version: '0.26.5'
|
|
10
10
|
};
|
|
11
11
|
export function createServer() {
|
|
12
12
|
const server = new Server(serverInfo, {
|
|
@@ -360,8 +360,14 @@ function normalizeClassName(value) {
|
|
|
360
360
|
return typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
361
361
|
}
|
|
362
362
|
function inferAndroidRole(className) {
|
|
363
|
-
if (/seekbar|slider
|
|
363
|
+
if (/seekbar|slider/.test(className))
|
|
364
364
|
return 'slider';
|
|
365
|
+
if (/stepper|numberpicker/.test(className))
|
|
366
|
+
return 'stepper';
|
|
367
|
+
if (/spinner|dropdown/.test(className))
|
|
368
|
+
return 'dropdown';
|
|
369
|
+
if (/segment|tablayout/.test(className))
|
|
370
|
+
return 'segmented_control';
|
|
365
371
|
if (/switch|toggle/.test(className))
|
|
366
372
|
return 'switch';
|
|
367
373
|
if (/checkbox/.test(className))
|
|
@@ -403,15 +409,41 @@ function buildAndroidSelector(text, contentDescription, resourceId, className) {
|
|
|
403
409
|
return { value: className, confidence: buildAndroidSelectorConfidence('class') };
|
|
404
410
|
return null;
|
|
405
411
|
}
|
|
406
|
-
function buildAndroidSemantic(clickable, className) {
|
|
407
|
-
|
|
412
|
+
function buildAndroidSemantic(clickable, className, role) {
|
|
413
|
+
const semantic = {
|
|
408
414
|
is_clickable: clickable,
|
|
409
415
|
is_container: /recyclerview|scroll|layout|viewgroup|frame/.test(className)
|
|
410
416
|
};
|
|
417
|
+
if (role === 'slider') {
|
|
418
|
+
semantic.semantic_role = 'slider';
|
|
419
|
+
semantic.adjustable = true;
|
|
420
|
+
semantic.supported_actions = ['adjust'];
|
|
421
|
+
semantic.state_shape = 'continuous';
|
|
422
|
+
}
|
|
423
|
+
else if (role === 'stepper') {
|
|
424
|
+
semantic.semantic_role = 'stepper';
|
|
425
|
+
semantic.adjustable = true;
|
|
426
|
+
semantic.supported_actions = ['increment', 'decrement'];
|
|
427
|
+
semantic.state_shape = 'discrete';
|
|
428
|
+
}
|
|
429
|
+
else if (role === 'dropdown') {
|
|
430
|
+
semantic.semantic_role = 'dropdown';
|
|
431
|
+
semantic.supported_actions = ['tap', 'expand'];
|
|
432
|
+
semantic.state_shape = 'semantic';
|
|
433
|
+
}
|
|
434
|
+
else if (role === 'segmented_control') {
|
|
435
|
+
semantic.semantic_role = 'segmented_control';
|
|
436
|
+
semantic.supported_actions = ['tap'];
|
|
437
|
+
semantic.state_shape = 'discrete';
|
|
438
|
+
}
|
|
439
|
+
else if (clickable) {
|
|
440
|
+
semantic.supported_actions = ['tap'];
|
|
441
|
+
}
|
|
442
|
+
return semantic;
|
|
411
443
|
}
|
|
412
444
|
function isSliderLikeAndroid(node) {
|
|
413
445
|
const className = String(node['@_class'] || '').toLowerCase();
|
|
414
|
-
return /seekbar|slider|range
|
|
446
|
+
return /seekbar|slider|range/i.test(className);
|
|
415
447
|
}
|
|
416
448
|
function extractAndroidState(node) {
|
|
417
449
|
const checked = parseBooleanAttr(node['@_checked']);
|
|
@@ -487,7 +519,7 @@ export function traverseNode(node, elements, parentIndex = -1, depth = 0) {
|
|
|
487
519
|
const stableId = resourceId ?? (typeof contentDescription === 'string' && contentDescription.trim().length > 0 ? contentDescription : null);
|
|
488
520
|
const testTag = stableId;
|
|
489
521
|
const selector = buildAndroidSelector(text, contentDescription, resourceId, normalizeClassName(className));
|
|
490
|
-
const semantic = buildAndroidSemantic(clickable, normalizeClassName(className));
|
|
522
|
+
const semantic = buildAndroidSemantic(clickable, normalizeClassName(className), role);
|
|
491
523
|
const isUseful = clickable || (text && text.length > 0) || (contentDescription && contentDescription.length > 0);
|
|
492
524
|
if (isUseful) {
|
|
493
525
|
const element = {
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the **Mobile Debug MCP** project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.26.5]
|
|
6
|
+
- Introduces a semantic control model to improve the identification and interaction with custom and composite UI controls.
|
|
7
|
+
|
|
8
|
+
## [0.26.4]
|
|
9
|
+
- Improved slider accuracy
|
|
10
|
+
|
|
5
11
|
## [0.26.3]
|
|
6
12
|
- updates the `find_element` tool to return detailed resolution metadata, including confidence scores,
|
|
7
13
|
|
package/docs/ROADMAP.md
CHANGED
|
@@ -44,6 +44,7 @@ Higher task success with fewer retries.
|
|
|
44
44
|
|
|
45
45
|
- Stronger State Verification — Complete (Foundational verification layer shipped)
|
|
46
46
|
- Richer Element Identity — Complete (Identity and selector confidence foundations shipped)
|
|
47
|
+
- Better Compose / Custom Control Semantics — Complete (Semantic role enrichment and custom-adjustable inference shipped)
|
|
47
48
|
|
|
48
49
|
## Current Focus
|
|
49
50
|
|
|
@@ -52,10 +53,61 @@ Higher task success with fewer retries.
|
|
|
52
53
|
|
|
53
54
|
## Upcoming Work
|
|
54
55
|
|
|
56
|
+
- Environment Auto-Configuration and Toolchain Discovery
|
|
55
57
|
- Adjustable Control Support
|
|
56
|
-
- Better Compose / Custom Control Semantics
|
|
57
58
|
- Signal-Oriented Diagnostic Filtering
|
|
58
59
|
- Long Press Gesture
|
|
60
|
+
# Stronger State Verification
|
|
61
|
+
# Richer Element Identity
|
|
62
|
+
# Wait and Synchronization Reliability
|
|
63
|
+
# Environment Auto-Configuration and Toolchain Discovery
|
|
64
|
+
|
|
65
|
+
## Rationale
|
|
66
|
+
Reduce onboarding friction and improve developer experience by minimizing manual setup dependencies.
|
|
67
|
+
|
|
68
|
+
**Status:** Planned
|
|
69
|
+
|
|
70
|
+
Addresses friction around:
|
|
71
|
+
- manual idb installation
|
|
72
|
+
- manual adb path configuration
|
|
73
|
+
- manual xcrun path configuration
|
|
74
|
+
- environment drift across machines
|
|
75
|
+
- setup failures blocking first use
|
|
76
|
+
|
|
77
|
+
## Scope
|
|
78
|
+
- Automatic discovery of adb
|
|
79
|
+
- Automatic discovery of xcrun
|
|
80
|
+
- idb detection and guided bootstrap support
|
|
81
|
+
- Startup toolchain validation
|
|
82
|
+
- Environment health diagnostics / doctor-style checks
|
|
83
|
+
- Minimal-manual-configuration defaults
|
|
84
|
+
|
|
85
|
+
## Expected Impact
|
|
86
|
+
High.
|
|
87
|
+
|
|
88
|
+
## Exit Criteria
|
|
89
|
+
- adb and xcrun auto-discovery implemented
|
|
90
|
+
- Missing dependencies surfaced with guided remediation
|
|
91
|
+
- Startup environment validation available
|
|
92
|
+
- Manual path configuration eliminated or minimized for standard setups
|
|
93
|
+
- First-run setup validated on representative developer environments
|
|
94
|
+
|
|
95
|
+
## Success Metrics
|
|
96
|
+
- Reduced setup friction during onboarding
|
|
97
|
+
- Lower environment configuration failures
|
|
98
|
+
- Faster time-to-first-successful-session
|
|
99
|
+
- Reduced support/debugging caused by local setup issues
|
|
100
|
+
|
|
101
|
+
## Dependencies
|
|
102
|
+
Depends on:
|
|
103
|
+
- Stronger State Verification
|
|
104
|
+
- Richer Element Identity
|
|
105
|
+
|
|
106
|
+
Strengthens:
|
|
107
|
+
- Actionability Resolution
|
|
108
|
+
- Broader user adoption readiness
|
|
109
|
+
|
|
110
|
+
---
|
|
59
111
|
|
|
60
112
|
## Later Horizon
|
|
61
113
|
|
|
@@ -383,7 +435,7 @@ Strengthens:
|
|
|
383
435
|
## Rationale
|
|
384
436
|
Higher priority after agent feedback exposed custom control semantics as a core reliability gap, not a later optimization.
|
|
385
437
|
|
|
386
|
-
**Status:**
|
|
438
|
+
**Status:** Completed
|
|
387
439
|
|
|
388
440
|
Semantics become more useful once:
|
|
389
441
|
- identity is stronger
|
|
@@ -394,8 +446,8 @@ Semantics become more useful once:
|
|
|
394
446
|
|
|
395
447
|
## Scope
|
|
396
448
|
- Composite control traits
|
|
397
|
-
- Control role enrichment (
|
|
398
|
-
- Interaction
|
|
449
|
+
- Control role enrichment (`slider`, `stepper`, `dropdown`, `segmented_control`, `custom_adjustable`)
|
|
450
|
+
- Interaction contract metadata (`supported_actions`, `adjustable`, `state_shape`)
|
|
399
451
|
- Custom widget gesture affordance hints
|
|
400
452
|
- Semantic confidence annotations
|
|
401
453
|
- Compose-aware selectors for waits (merged semantics and element relationships)
|
|
@@ -405,7 +457,7 @@ High.
|
|
|
405
457
|
|
|
406
458
|
## Exit Criteria
|
|
407
459
|
- Semantic traits implemented for major custom control classes
|
|
408
|
-
- Interaction contracts surfaced in
|
|
460
|
+
- Interaction contracts surfaced in observation and resolution paths
|
|
409
461
|
- Confidence model defined for derived semantics
|
|
410
462
|
- Custom control manipulation success validated in benchmark flows
|
|
411
463
|
|
|
@@ -516,6 +568,7 @@ Foundation
|
|
|
516
568
|
- Richer Element Identity
|
|
517
569
|
|
|
518
570
|
Synchronization & Actionability
|
|
571
|
+
- Environment Auto-Configuration and Toolchain Discovery
|
|
519
572
|
- Wait and Synchronization Reliability
|
|
520
573
|
- Actionability Resolution
|
|
521
574
|
|
|
@@ -536,9 +589,10 @@ Deep Observability
|
|
|
536
589
|
- Richer Element Identity
|
|
537
590
|
- Wait and Synchronization Reliability
|
|
538
591
|
- Actionability Resolution
|
|
592
|
+
- Environment Auto-Configuration and Toolchain Discovery
|
|
539
593
|
|
|
540
594
|
Focus:
|
|
541
|
-
Make core loop
|
|
595
|
+
Make core loop reliable and reduce onboarding friction.
|
|
542
596
|
|
|
543
597
|
---
|
|
544
598
|
|
|
@@ -575,16 +629,17 @@ Roadmap Ordering:
|
|
|
575
629
|
1. Stronger State Verification
|
|
576
630
|
2. Richer Element Identity
|
|
577
631
|
3. Wait and Synchronization Reliability
|
|
578
|
-
4.
|
|
579
|
-
5.
|
|
580
|
-
6.
|
|
581
|
-
7.
|
|
582
|
-
8.
|
|
583
|
-
9.
|
|
584
|
-
10.
|
|
632
|
+
4. Environment Auto-Configuration and Toolchain Discovery
|
|
633
|
+
5. Actionability Resolution
|
|
634
|
+
6. Adjustable Control Support
|
|
635
|
+
7. Better Compose / Custom Control Semantics
|
|
636
|
+
8. Signal-Oriented Diagnostic Filtering
|
|
637
|
+
9. Long Press Gesture
|
|
638
|
+
10. Pinch to Zoom
|
|
639
|
+
11. Action Trace Correlation
|
|
585
640
|
|
|
586
641
|
Rationale:
|
|
587
|
-
- Early roadmap items harden state, targeting, synchronization, action execution.
|
|
642
|
+
- Early roadmap items harden state, targeting, synchronization, environment readiness, and action execution.
|
|
588
643
|
- Mid roadmap items improve control precision and signal observability.
|
|
589
644
|
- Later interaction-focused items expand interaction coverage.
|
|
590
645
|
- Final observability work deepens debugging observability.
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# RFC 008 — Adjustable Control Support and Semantic Value Manipulation
|
|
5
|
+
|
|
6
|
+
## 1. Summary
|
|
7
|
+
|
|
8
|
+
This RFC defines semantic interaction support for adjustable controls whose primary interaction changes a value rather than triggering a discrete action.
|
|
9
|
+
|
|
10
|
+
Examples include:
|
|
11
|
+
- sliders
|
|
12
|
+
- steppers
|
|
13
|
+
- seek bars
|
|
14
|
+
- drag-based range controls
|
|
15
|
+
- quantized parameter selectors
|
|
16
|
+
|
|
17
|
+
Goal:
|
|
18
|
+
Enable reliable value-setting interactions with verification, minimizing coordinate guessing and brittle gesture calibration.
|
|
19
|
+
|
|
20
|
+
Builds on:
|
|
21
|
+
- RFC 005 — correctness model
|
|
22
|
+
- RFC 006 — runtime execution binding
|
|
23
|
+
- RFC 007 — target resolution
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 2. Problem Statement
|
|
28
|
+
|
|
29
|
+
Current control adjustment often degrades into coordinate heuristics.
|
|
30
|
+
|
|
31
|
+
Observed failure modes:
|
|
32
|
+
- slider handles not semantically surfaced
|
|
33
|
+
- coordinate calibration guesswork
|
|
34
|
+
- snapping or quantized values behaving unexpectedly
|
|
35
|
+
- weak confirmation of resulting value
|
|
36
|
+
- retries caused by partial adjustment success
|
|
37
|
+
|
|
38
|
+
This is not primarily a gesture problem.
|
|
39
|
+
|
|
40
|
+
It is:
|
|
41
|
+
- a control semantics problem
|
|
42
|
+
- a value verification problem
|
|
43
|
+
- an adjustment convergence problem
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 3. Design Goals
|
|
48
|
+
|
|
49
|
+
Support MUST:
|
|
50
|
+
- Prefer semantic adjustment over coordinate manipulation
|
|
51
|
+
- Support deterministic value targeting
|
|
52
|
+
- Verify resulting value after adjustment
|
|
53
|
+
- Handle quantized or snapping controls
|
|
54
|
+
- Support bounded tolerance when exact values are impossible
|
|
55
|
+
- Use coordinate fallback only as degraded mode
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 4. Adjustable Control Model
|
|
60
|
+
|
|
61
|
+
Treat adjustable controls as a combination of:
|
|
62
|
+
- target control
|
|
63
|
+
- value model
|
|
64
|
+
- adjustment mechanism
|
|
65
|
+
- verification loop
|
|
66
|
+
|
|
67
|
+
Control should expose where possible:
|
|
68
|
+
- current value
|
|
69
|
+
- minimum and maximum range
|
|
70
|
+
- step granularity (if known)
|
|
71
|
+
- adjustable role metadata
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 5. Primary Primitive
|
|
76
|
+
|
|
77
|
+
Illustrative adjustment primitive (conceptual, not yet a committed tool surface):
|
|
78
|
+
|
|
79
|
+
set_slider_value(target, value, tolerance?)
|
|
80
|
+
|
|
81
|
+
This denotes an adjustment capability, not a required standalone tool API. Implementations may realize it as:
|
|
82
|
+
- an extension of existing gesture tools
|
|
83
|
+
- an internal adjustment helper
|
|
84
|
+
- a future dedicated control-adjustment tool surface
|
|
85
|
+
|
|
86
|
+
This RFC does not mandate which mechanism is used.
|
|
87
|
+
|
|
88
|
+
Semantics:
|
|
89
|
+
- resolve control target
|
|
90
|
+
- perform adjustment
|
|
91
|
+
- read back resulting value
|
|
92
|
+
- converge or fail explicitly
|
|
93
|
+
|
|
94
|
+
This is not:
|
|
95
|
+
blind drag gestures
|
|
96
|
+
|
|
97
|
+
It is:
|
|
98
|
+
set and verify
|
|
99
|
+
|
|
100
|
+
## 5.1 Tool Surface Boundary
|
|
101
|
+
|
|
102
|
+
This RFC specifies adjustment semantics, not a committed tool API.
|
|
103
|
+
|
|
104
|
+
It does not assume a new public tool is introduced in this RFC.
|
|
105
|
+
Implementation may extend existing gesture/runtime surfaces before introducing any dedicated adjustment command.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 6. Adjustment Modes
|
|
110
|
+
|
|
111
|
+
### Semantic mode (preferred)
|
|
112
|
+
Use control semantics to set value directly or intelligently drive adjustment.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### Gesture-assisted mode
|
|
117
|
+
Use controlled drag informed by:
|
|
118
|
+
- bounds
|
|
119
|
+
- target percentage
|
|
120
|
+
- snapping model
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### Coordinate fallback (last resort)
|
|
125
|
+
Allowed only when semantic control support is absent.
|
|
126
|
+
|
|
127
|
+
Must be explicit degraded mode.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 7. Verification Loop
|
|
132
|
+
|
|
133
|
+
Adjustment is incomplete until verified.
|
|
134
|
+
|
|
135
|
+
Loop:
|
|
136
|
+
- adjust
|
|
137
|
+
- read back
|
|
138
|
+
- compare to target or tolerance
|
|
139
|
+
- converge or fail after bounded retries
|
|
140
|
+
|
|
141
|
+
Possible outcomes:
|
|
142
|
+
- Verified
|
|
143
|
+
- Tolerance satisfied
|
|
144
|
+
- Failed to converge
|
|
145
|
+
|
|
146
|
+
Aligns with RFC 005.
|
|
147
|
+
Verification may initially be realized through explicit expect_state mappings for control value assertions. Dedicated value verifiers are a possible future extension, not a prerequisite of this RFC.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 8. Quantized / Snapping Controls
|
|
152
|
+
|
|
153
|
+
Support:
|
|
154
|
+
- discrete step controls
|
|
155
|
+
- snapping values
|
|
156
|
+
- non-linear scales (where detectable)
|
|
157
|
+
|
|
158
|
+
Tolerance model required.
|
|
159
|
+
|
|
160
|
+
Example:
|
|
161
|
+
Target 30
|
|
162
|
+
Actual 29.8
|
|
163
|
+
Within tolerance acceptable
|
|
164
|
+
Discrete or non-numeric controls may satisfy convergence through semantic state equivalence rather than numeric tolerance alone.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 9. Control Resolution Dependency
|
|
169
|
+
|
|
170
|
+
Uses RFC 007 target resolution for:
|
|
171
|
+
- locating actual adjustable control
|
|
172
|
+
- avoiding fake slider containers
|
|
173
|
+
- resolving executable adjustable target
|
|
174
|
+
|
|
175
|
+
RFC 007 resolves what to adjust.
|
|
176
|
+
RFC 008 defines how to adjust it.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 10. Compose / Custom Control Support
|
|
181
|
+
|
|
182
|
+
Support derived adjustable semantics for:
|
|
183
|
+
- Compose sliders
|
|
184
|
+
- custom parameter widgets
|
|
185
|
+
- composite adjustable controls
|
|
186
|
+
|
|
187
|
+
Strengthens Better Compose / Custom Control Semantics.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 11. Output / Result Model (Illustrative)
|
|
192
|
+
|
|
193
|
+
Illustrative result shape:
|
|
194
|
+
|
|
195
|
+
{
|
|
196
|
+
"target_state": 30,
|
|
197
|
+
"actual_state": 30,
|
|
198
|
+
"converged": true,
|
|
199
|
+
"adjustment_mode": "semantic"
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
State may be numeric, discrete, or semantic depending on control type. This model is illustrative and current implementations may expose only a subset through existing verification surfaces.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 12. Success Metrics
|
|
207
|
+
|
|
208
|
+
Track:
|
|
209
|
+
- reduction in coordinate fallback usage
|
|
210
|
+
- reduced retries adjusting controls
|
|
211
|
+
- improved first-pass value convergence
|
|
212
|
+
- improved custom control adjustment success
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 13. Dependencies
|
|
217
|
+
|
|
218
|
+
Depends on:
|
|
219
|
+
- Stronger State Verification
|
|
220
|
+
- Actionability Resolution (RFC 007)
|
|
221
|
+
|
|
222
|
+
Strengthens:
|
|
223
|
+
- Better Compose / Custom Control Semantics
|
|
224
|
+
- Pinch to Zoom (future)
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## 14. Relationship to Prior RFCs
|
|
229
|
+
|
|
230
|
+
RFC 005
|
|
231
|
+
Defines successful adjustment verification.
|
|
232
|
+
|
|
233
|
+
RFC 006
|
|
234
|
+
Defines runtime execution interpretation.
|
|
235
|
+
|
|
236
|
+
RFC 007
|
|
237
|
+
Defines which adjustable target gets selected.
|
|
238
|
+
|
|
239
|
+
RFC 008
|
|
240
|
+
Defines how value-changing controls are manipulated reliably.
|
|
241
|
+
|
|
242
|
+
Together:
|
|
243
|
+
- RFC 005 — correctness
|
|
244
|
+
- RFC 006 — runtime binding
|
|
245
|
+
- RFC 007 — target resolution
|
|
246
|
+
- RFC 008 — value manipulation
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 15. Summary
|
|
251
|
+
|
|
252
|
+
This RFC moves adjustable controls from:
|
|
253
|
+
- gesture guesswork
|
|
254
|
+
|
|
255
|
+
to:
|
|
256
|
+
- semantic value manipulation with verification
|
|
257
|
+
|
|
258
|
+
It reduces one of the largest remaining sources of interaction brittleness.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## 16. Non-Goals / Scope Boundary
|
|
263
|
+
|
|
264
|
+
This RFC defines adjustment semantics and convergence behavior.
|
|
265
|
+
|
|
266
|
+
It does not commit in this RFC to:
|
|
267
|
+
- a specific runtime tool API
|
|
268
|
+
- full adjustable control support across all control types
|
|
269
|
+
- generalized gesture framework support
|
|
270
|
+
- arbitrary drag or canvas manipulation
|
|
271
|
+
- pinch-to-zoom or broader gesture semantics
|
|
272
|
+
|
|
273
|
+
This RFC specifies the behavioral model adjustable-control support should satisfy as implementations mature.
|