{
  "format": "scripttap-import-authoring-index-v1",
  "commandContractSourceSha256": "F89C8BF0C842D03561C450ABD271E392E1FAB68CF4FD14B4F82D8C8A6B41168F",
  "packageContractSourceSha256": "7882EA5C7606A428F77A77224474C4FF3D788CDD99DB7FD3964CD3880C3DB6C8",
  "canonicalContract": "/ai_json_contract_v1.json",
  "schemaVersion": "1.0.0",
  "semantics": {
    "authority": "For the SAME contract revision, canonical command rules are identical to Bridge /health.commandContract and website commandContract. Compare Bridge commandContractSha256 with website commandContractSourceSha256; never mix older app revisions with current website rules. Package-only Call identity is an explicit transport mapping, not a different command rule.",
    "customContractNotStandardJsonSchema": true,
    "baseOptionalDoesNotMeanAllowedInEveryMode": true,
    "variantSelection": "Exactly one matching when/absent/contains/notContains variant. Allowed = required common fields + selected when keys + selected fields. All other fields are forbidden, even blank, false or null.",
    "selectorTypes": "Canonical when values are matcher text, not payload JSON types. Use payloadDiscriminators and the exact field schema: a Boolean matcher written as the text true/false requires native JSON true/false in a Boolean payload field, not a quoted string. Nested condition matchers follow the same rule.",
    "nestedConditions": "Every matching nested conditional requires and constrains all fields it names. Ordinary toggle retention is not a true-mode switch.",
    "unionSemantics": "Custom oneOf accepts any matching branch, as the app does; it is not exclusive JSON Schema oneOf.",
    "drafts": "Required fields remain present. Empty strings are drafts only where explicitly admitted. Examples are schema-valid snippets, not complete packages, granted capabilities or runnable scripts. Rename example IDs uniquely when composing a script/package.",
    "bestPractices": "Suggestions only, not necessarily suitable for every request. Exact schema always wins.",
    "callPackageMapping": {
      "call": {
        "targetScope": "package",
        "targetClientId": "maps to canonical targetMacroId"
      },
      "stop_call": {
        "targetScope": "package",
        "targetClientIds": "maps to canonical targetMacroIds"
      }
    }
  },
  "tokenRuleSemantics": {
    "combination": "Base field schema AND every matching selected-mode/nested constraint apply together. allowBlank admits exactly an empty String before token checking. A token is not proof that a variable has been declared with the needed type/scope. Respect each field's source mode; never convert a literal to a variable by guessing.",
    "action_array": "One ASCII letter; case-insensitive family identity.",
    "variable_name": "One ASCII letter with optional decimal index 1..4096, at most five characters; exact type/scope/declaration completeness is separate.",
    "integer_literal": "Signed 32-bit whole decimal String, optional + or -; obey attached minimum/maximum.",
    "unsigned_integer_literal": "Digits-only Integer String, no sign; obey attached minimum/maximum.",
    "signed_integer_or_variable": "Signed 32-bit Integer String or admitted Integer-variable token; attached bounds still apply.",
    "integer_literal_or_variable": "Signed 32-bit Integer String or admitted Integer-variable token; attached bounds still apply.",
    "c12d_integer_literal_or_variable": "Integer String spelling -?[0-9]+ or Integer-variable token. No leading +. A negative spelling is forbidden when minimum is nonnegative, even -0. Attached bounds apply.",
    "positive_integer_or_variable": "Integer String strictly greater than zero or admitted Integer-variable token; attached bounds apply.",
    "non_negative_integer_or_variable": "Integer String at least zero or admitted Integer-variable token; attached bounds apply.",
    "decimal_literal_or_variable": "Decimal String with period radix and optional sign/exponent, or admitted Decimal variable. NaN and Infinity are not literal spellings. Canonicalization/runtime behavior is documented separately.",
    "boolean_literal": "Exact JSON String True or False (quoted), not native JSON Boolean.",
    "boolean_literal_or_variable": "Case-insensitive true/false String or admitted Boolean-variable token; not native JSON Boolean.",
    "hex_literal_or_variable": "Six Hex digits, optionally # and/or 0x prefixed, zero literal 0, or admitted Hex variable. An attached field pattern can be narrower and must also pass.",
    "string_literal_or_variable": "Exact String, including whitespace; the owning source mode determines interpretation. Do not trim literal text.",
    "time_literal_or_variable": "24-hour HH:mm or HH:mm:ss, optionally prefixed by YYYY-MM-DD and space/T, or Current Time, or admitted Time variable. No AM/PM suffix in the wire token; editor clock widgets are separate.",
    "manual_time_literal_or_variable": "Same 24-hour/date Time grammar or prior Time variable, but Current Time is forbidden. Do not append AM/PM to the wire token."
  },
  "validator": "/ai_validator_v1.py.txt",
  "validatorUsage": "Download as a file without pasting the validator source into the prompt. Save as scripttap_validate.py; run python3 scripttap_validate.py your-file.scripttap.json. Exit 0 means the listed canonical-contract checks passed, not Android import or runtime readiness.",
  "package": {
    "format": "scripttap-ai-json-contract",
    "version": 1,
    "scriptPackage": {
      "requiredLiteralFields": {
        "format": "scripttap-json-script",
        "version": 2,
        "kind": "script_package"
      },
      "topLevelFields": [
        "format",
        "version",
        "kind",
        "packageId",
        "createdAtMs",
        "source",
        "rootClientId",
        "requirements",
        "folders",
        "scripts",
        "assetRequirements",
        "notes"
      ],
      "allowedSourceValues": [
        "user_export",
        "ai_generated",
        "script_builder"
      ],
      "requirementsFields": [
        "commandCatalogVersion",
        "requiresUserCompletion",
        "requiresAssets"
      ],
      "folderFields": [
        "id",
        "name",
        "parentId"
      ],
      "scriptFields": [
        "clientId",
        "uploadMode",
        "name",
        "folderId",
        "disabled",
        "commands"
      ],
      "assetRequirementFields": [
        "scriptId",
        "commandId",
        "commandType",
        "assetName",
        "reason"
      ],
      "allowedAssetRequirementReasons": [
        "user_must_capture",
        "user_must_attach_existing",
        "source_export_requires_recapture",
        "ai_cannot_provide"
      ],
      "idPrefixes": {
        "packageId": "pkg_",
        "scriptId": "script_",
        "folderId": "folder_",
        "commandId": "cmd_"
      },
      "idAllowedCharacters": "A-Z a-z 0-9 _ -",
      "idSemantics": {
        "scriptPackageIdsArePackageLocal": true,
        "notLiveAppScriptIds": true,
        "importAssignsFreshRealAppIds": true,
        "inPackageScriptReferencesRemapThroughPackageIds": true
      },
      "importValidationSemantics": {
        "importedPackagesDoNotCarryTrustedValidationOutcomeFields": true,
        "importedScriptsStartDisabled": true,
        "readinessIsDerivedLocallyFromSavedCommandGraph": true,
        "manualImportFormsValidationImmediatelyAfterCanonicalAcceptance": true,
        "bridgeFullScriptMutationUsesOneTwentySecondValidationQuietDeadline": true,
        "syntaxAndCallTopologyCheckedBeforeCanonicalAcceptance": true,
        "dependencyCompletenessIsNotCheckedDuringImport": true,
        "validPackagesCommitAllOrNothing": true,
        "admissionIsNotValidationV2Completion": true,
        "admissionIsNotRunReadiness": true,
        "nonterminalStateRequiresMutationRetry": false,
        "onlyTerminalCompleteClearsValidationBlocking": true,
        "terminalIncompleteRequiresCorrection": true,
        "runtimePermissionsAndPreflightAreSeparate": true
      },
      "nameLimits": {
        "scriptNameMaxChars": 28,
        "folderNameMaxChars": 28,
        "nicknameMaxChars": 20
      },
      "valueRules": {
        "integerLiteralRange": "-2147483648..2147483647",
        "integerLiteralFormat": "signed whole decimal integer only; decimals, blanks, malformed numbers, and overflow values are invalid",
        "variableToken": "Any one ASCII letter plus optional index 1..4096 is a valid variable token. Letters are case-insensitive and canonicalize to lowercase, so D1 and d1 are the same variable. i/d/b/h/s/t are type conventions, not enforced letter types.",
        "booleanLiteralStorage": "Boolean SetVariable variableValue is a JSON String token, for example True or False inside quotes, or an admitted prior variable token. Native JSON Boolean values are not admitted for variableValue. Boolean control fields such as disabled remain native JSON Booleans.",
        "selectedModeFields": "The base command field catalog is a union, not an all-mode allowlist. Select exactly one declared variant. Emit only required common fields, its when keys, and its fields. Omit every inactive field entirely, even if its value would be empty, false, zero, or null. Ordinary non-Time Array SetVariable omits variableValue; Single String Clipboard also omits variableValue.",
        "incompleteDrafts": "Required fields remain present. A blank String is an incomplete draft only when its exact field rule admits blank. Missing, null, wrong-type or inactive fields are not a substitute. If a requested operation cannot be represented safely, return an admitted empty root package and explain the limitation in notes.",
        "recommendationAuthority": "Best practices and example strategies are suggestions, not universally optimal instructions. Exact canonical schema is the final authority over every example, narrative, recommendation and outside source.",
        "contractRevisionRule": "Bridge commandContractSha256 and website commandContractSourceSha256 must match before sources are combined. Equal revisions use identical canonical command data. Older installed builds can expose older revisions; target their actual schema when connected, otherwise declare the current published target in notes. Do not claim cross-version parity.",
        "validatorIdentity": "Declaration order, one lowercase ASCII letter, exact type, and LOCAL/THREAD scope. Every suffix and array slot using that letter shares the family type in its visible scope; Integer d[] means D1/d1 cannot be Decimal there.",
        "scopeWire": "variableShared false means LOCAL and true means THREAD; it is the sole scope wire encoding.",
        "packageMetadataBoundary": "Packages contain no validation status, issue, revision, index, phase, owner state, or other validation outcome metadata."
      }
    },
    "flowPairingRules": [
      "loop pairs with end_loop",
      "for_each_index pairs with end_for_each_index",
      "touch_down pairs with end_touch",
      "pause_concurrent pairs with unpause_concurrent",
      "or pairs with end_or",
      "and pairs with end_and",
      "xor pairs with end_xor",
      "rgb_confidence uses an IF end row and remains inside the IF segment",
      "else may appear only inside an IF segment and before that segment's end row"
    ],
    "assetPolicy": {
      "jsonContainsAssetBytes": false,
      "assetReferencesAreNamesOnly": true,
      "missingAssetsRequireAssetRequirements": true,
      "assetBackedCommandsWithMissingAssetsMustBeIncomplete": true
    },
    "minimalPackage": {
      "format": "scripttap-json-script",
      "version": 2,
      "kind": "script_package",
      "packageId": "pkg_example",
      "createdAtMs": 0,
      "source": "ai_generated",
      "rootClientId": "script_root",
      "requirements": {
        "commandCatalogVersion": 1,
        "requiresUserCompletion": false,
        "requiresAssets": false
      },
      "folders": [],
      "scripts": [
        {
          "clientId": "script_root",
          "uploadMode": "new",
          "name": "New Script",
          "folderId": "",
          "disabled": true,
          "commands": []
        }
      ],
      "assetRequirements": [],
      "notes": ""
    }
  },
  "commandCount": 63,
  "exampleCount": 401,
  "commands": {
    "click": "/ai/commands/click.json",
    "delay": "/ai/commands/delay.json",
    "delay_until": "/ai/commands/delay_until.json",
    "retap": "/ai/commands/retap.json",
    "multi_click": "/ai/commands/multi_click.json",
    "swipe": "/ai/commands/swipe.json",
    "gestures": "/ai/commands/gestures.json",
    "img_find": "/ai/commands/img_find.json",
    "smart_tap": "/ai/commands/smart_tap.json",
    "label": "/ai/commands/label.json",
    "goto": "/ai/commands/goto.json",
    "loop": "/ai/commands/loop.json",
    "end_loop": "/ai/commands/end_loop.json",
    "break_loop": "/ai/commands/break_loop.json",
    "call": "/ai/commands/call.json",
    "break_call": "/ai/commands/break_call.json",
    "stop_call": "/ai/commands/stop_call.json",
    "pause_concurrent": "/ai/commands/pause_concurrent.json",
    "unpause_concurrent": "/ai/commands/unpause_concurrent.json",
    "break_exclusive": "/ai/commands/break_exclusive.json",
    "set_variable": "/ai/commands/set_variable.json",
    "mod_variable": "/ai/commands/mod_variable.json",
    "text_type": "/ai/commands/text_type.json",
    "get_pixel_color": "/ai/commands/get_pixel_color.json",
    "pixel_sample_batch": "/ai/commands/pixel_sample_batch.json",
    "pixel_find": "/ai/commands/pixel_find.json",
    "visual_trigger": "/ai/commands/visual_trigger.json",
    "divider": "/ai/commands/divider.json",
    "else": "/ai/commands/else.json",
    "or": "/ai/commands/or.json",
    "end_or": "/ai/commands/end_or.json",
    "xor": "/ai/commands/xor.json",
    "end_xor": "/ai/commands/end_xor.json",
    "and": "/ai/commands/and.json",
    "end_and": "/ai/commands/end_and.json",
    "rgb_confidence": "/ai/commands/rgb_confidence.json",
    "screenshot": "/ai/commands/screenshot.json",
    "prompt_me": "/ai/commands/prompt_me.json",
    "color_classify": "/ai/commands/color_classify.json",
    "array_get": "/ai/commands/array_get.json",
    "array_set": "/ai/commands/array_set.json",
    "for_each_index": "/ai/commands/for_each_index.json",
    "end_for_each_index": "/ai/commands/end_for_each_index.json",
    "array_segment_scan": "/ai/commands/array_segment_scan.json",
    "append_points": "/ai/commands/append_points.json",
    "device_settings": "/ai/commands/device_settings.json",
    "pinch": "/ai/commands/pinch.json",
    "ui_find": "/ai/commands/ui_find.json",
    "http": "/ai/commands/http.json",
    "clipboard": "/ai/commands/clipboard.json",
    "file": "/ai/commands/file.json",
    "text_transform": "/ai/commands/text_transform.json",
    "ocr": "/ai/commands/ocr.json",
    "reader": "/ai/commands/reader.json",
    "json": "/ai/commands/json.json",
    "translate": "/ai/commands/translate.json",
    "display": "/ai/commands/display.json",
    "touch_down": "/ai/commands/touch_down.json",
    "touch_move": "/ai/commands/touch_move.json",
    "end_touch": "/ai/commands/end_touch.json",
    "set_coordinates": "/ai/commands/set_coordinates.json",
    "state_get": "/ai/commands/state_get.json",
    "use_action": "/ai/commands/use_action.json"
  }
}
