feat(keyboard): ship AI hint carousel, home library cards, and clipboard polish
Rotate AI idle suggestions with optional remote packs, move history/dictionary onto self-sizing Home preview cards, harden clipboard capture/prompting, and simplify keyboard chrome by dropping most liquid-glass shadows.
This commit is contained in:
@@ -0,0 +1,294 @@
|
||||
{
|
||||
"originHash" : "3f7f9c5c939e016eed7645a0f0350b81159851de16e991f2d664636fd06245e3",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "async-http-client",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/swift-server/async-http-client",
|
||||
"state" : {
|
||||
"revision" : "2fc4652fb4689eb24af10e55cabaa61d8ba774fd",
|
||||
"version" : "1.32.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "eventsource",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/mattt/EventSource.git",
|
||||
"state" : {
|
||||
"revision" : "a2965424a4babeb0c8e4b5ec9708c3939bc52449",
|
||||
"version" : "1.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "librime-xcframework",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/ghostflyby/librime-xcframework.git",
|
||||
"state" : {
|
||||
"revision" : "d5781922905ff1ae967c222e40aa51cc451a5221",
|
||||
"version" : "1.17.0-pack.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "mlx-swift",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/ml-explore/mlx-swift.git",
|
||||
"state" : {
|
||||
"revision" : "61b9e011e09a62b489f6bd647958f1555bdf2896",
|
||||
"version" : "0.31.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "mlx-swift-lm",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/ml-explore/mlx-swift-lm.git",
|
||||
"state" : {
|
||||
"revision" : "1c05248bb0899e2a7a4962b84d319cf12f4e12aa",
|
||||
"version" : "3.31.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-algorithms",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-algorithms.git",
|
||||
"state" : {
|
||||
"revision" : "87e50f483c54e6efd60e885f7f5aa946cee68023",
|
||||
"version" : "1.2.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-asn1",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-asn1.git",
|
||||
"state" : {
|
||||
"revision" : "810496cf121e525d660cd0ea89a758740476b85f",
|
||||
"version" : "1.5.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-async-algorithms",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-async-algorithms.git",
|
||||
"state" : {
|
||||
"revision" : "2971dd5d9f6e0515664b01044826bcea16e59fac",
|
||||
"version" : "1.1.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-atomics",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-atomics.git",
|
||||
"state" : {
|
||||
"revision" : "b601256eab081c0f92f059e12818ac1d4f178ff7",
|
||||
"version" : "1.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-certificates",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-certificates.git",
|
||||
"state" : {
|
||||
"revision" : "24ccdeeeed4dfaae7955fcac9dbf5489ed4f1a25",
|
||||
"version" : "1.18.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-collections",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-collections.git",
|
||||
"state" : {
|
||||
"revision" : "7b847a3b7008b2dc2f47ca3110d8c782fb2e5c7e",
|
||||
"version" : "1.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-configuration",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-configuration.git",
|
||||
"state" : {
|
||||
"revision" : "1bb939fe7bbb00b8f8bab664cc90020c035c08d9",
|
||||
"version" : "1.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-crypto",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-crypto.git",
|
||||
"state" : {
|
||||
"revision" : "6f70fa9eab24c1fd982af18c281c4525d05e3095",
|
||||
"version" : "4.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-distributed-tracing",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-distributed-tracing.git",
|
||||
"state" : {
|
||||
"revision" : "e109d8b5308d0e05201d9a1dd1c475446a946a11",
|
||||
"version" : "1.4.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-http-structured-headers",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-http-structured-headers.git",
|
||||
"state" : {
|
||||
"revision" : "76d7627bd88b47bf5a0f8497dd244885960dde0b",
|
||||
"version" : "1.6.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-http-types",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-http-types.git",
|
||||
"state" : {
|
||||
"revision" : "45eb0224913ea070ec4fba17291b9e7ecf4749ca",
|
||||
"version" : "1.5.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-huggingface",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/huggingface/swift-huggingface.git",
|
||||
"state" : {
|
||||
"revision" : "de01c0ab8fd537bbd8216cea7f774275178501a2",
|
||||
"version" : "0.8.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-jinja",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/huggingface/swift-jinja.git",
|
||||
"state" : {
|
||||
"revision" : "f731f03bf746481d4fda07f817c3774390c4d5b9",
|
||||
"version" : "2.3.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-log",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-log.git",
|
||||
"state" : {
|
||||
"revision" : "bbd81b6725ae874c69e9b8c8804d462356b55523",
|
||||
"version" : "1.10.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio.git",
|
||||
"state" : {
|
||||
"revision" : "e932d3c4d8f77433c8f7093b5ebcbf91463948a0",
|
||||
"version" : "2.95.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio-extras",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio-extras.git",
|
||||
"state" : {
|
||||
"revision" : "3df009d563dc9f21a5c85b33d8c2e34d2e4f8c3b",
|
||||
"version" : "1.32.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio-http2",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio-http2.git",
|
||||
"state" : {
|
||||
"revision" : "b6571f3db40799df5a7fc0e92c399aa71c883edd",
|
||||
"version" : "1.40.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio-ssl",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio-ssl.git",
|
||||
"state" : {
|
||||
"revision" : "173cc69a058623525a58ae6710e2f5727c663793",
|
||||
"version" : "2.36.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio-transport-services",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio-transport-services.git",
|
||||
"state" : {
|
||||
"revision" : "60c3e187154421171721c1a38e800b390680fb5d",
|
||||
"version" : "1.26.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-numerics",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-numerics",
|
||||
"state" : {
|
||||
"revision" : "0c0290ff6b24942dadb83a929ffaaa1481df04a2",
|
||||
"version" : "1.1.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-service-context",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-service-context.git",
|
||||
"state" : {
|
||||
"revision" : "d0997351b0c7779017f88e7a93bc30a1878d7f29",
|
||||
"version" : "1.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-service-lifecycle",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/swift-server/swift-service-lifecycle",
|
||||
"state" : {
|
||||
"revision" : "89888196dd79c61c50bca9a103d8114f32e1e598",
|
||||
"version" : "2.10.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-syntax",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/swiftlang/swift-syntax.git",
|
||||
"state" : {
|
||||
"revision" : "0687f71944021d616d34d922343dcef086855920",
|
||||
"version" : "600.0.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-system",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-system.git",
|
||||
"state" : {
|
||||
"revision" : "7c6ad0fc39d0763e0b699210e4124afd5041c5df",
|
||||
"version" : "1.6.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-transformers",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/huggingface/swift-transformers.git",
|
||||
"state" : {
|
||||
"revision" : "150169bfba0889c229a2ce7494cf8949f18e6906",
|
||||
"version" : "1.1.9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-xet",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/mattt/swift-xet.git",
|
||||
"state" : {
|
||||
"revision" : "341bfd4172f6a57119bfd49bafa11cf5d21fab75",
|
||||
"version" : "0.2.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "yyjson",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/ibireme/yyjson.git",
|
||||
"state" : {
|
||||
"revision" : "8b4a38dc994a110abaec8a400615567bd996105f",
|
||||
"version" : "0.12.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 3
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Reject obvious credential and user-text interpolation in Swift logs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
EXCLUDED_PARTS = {
|
||||
".build",
|
||||
".git",
|
||||
"Carthage",
|
||||
"DerivedData",
|
||||
"OSGKeyboardExtTests",
|
||||
"OSGKeyboardMacTests",
|
||||
"OSGKeyboardTests",
|
||||
"Pods",
|
||||
"Scripts",
|
||||
"Tests",
|
||||
"ThirdParty",
|
||||
"Vendor",
|
||||
"build",
|
||||
}
|
||||
LOG_START = re.compile(
|
||||
r"""
|
||||
(?:
|
||||
\bprint\s*\(
|
||||
|\bOSGLog(?:\.\w+)+\s*\(
|
||||
|\bOSGDiag\.log\s*\(
|
||||
|\bFlowDiagnostics\.log\s*\(
|
||||
|\bFlowTrace\.(?:capture|pipeline|asr|polish|keyboard|warn)\s*\(
|
||||
|\bdebug\s*\(
|
||||
|\b(?:log|logger)\.(?:debug|info|notice|warning|error|fault)\s*\(
|
||||
)
|
||||
""",
|
||||
re.VERBOSE,
|
||||
)
|
||||
SENSITIVE_IDENTIFIER = re.compile(
|
||||
r"""
|
||||
\b(?:
|
||||
apiKey
|
||||
|asrApiKey
|
||||
|Authorization
|
||||
|httpBody
|
||||
|bodyText
|
||||
|responseBody
|
||||
|result\.text
|
||||
|error\.message
|
||||
|(?:raw|final|full|partial)?Transcript
|
||||
|(?:system|user|raw)?Prompt
|
||||
|clipboard(?:Text|Content)?
|
||||
)\b
|
||||
""",
|
||||
re.IGNORECASE | re.VERBOSE,
|
||||
)
|
||||
INTERPOLATION = re.compile(r"\\\((.*?)\)", re.DOTALL)
|
||||
SENSITIVE_LABEL = re.compile(
|
||||
r"\b(?:apiKey|Authorization|httpBody|bodyText|responseBody|transcript|prompt|clipboard)\s*[:=]",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Violation:
|
||||
path: Path
|
||||
line: int
|
||||
message: str
|
||||
|
||||
|
||||
def swift_files(root: Path) -> list[Path]:
|
||||
files: list[Path] = []
|
||||
for current, directories, names in os.walk(root):
|
||||
directories[:] = [
|
||||
directory
|
||||
for directory in directories
|
||||
if directory not in EXCLUDED_PARTS
|
||||
and not directory.endswith("Tests")
|
||||
and not directory.startswith(".")
|
||||
]
|
||||
current_path = Path(current)
|
||||
files.extend(current_path / name for name in names if name.endswith(".swift"))
|
||||
return sorted(files)
|
||||
|
||||
|
||||
def line_number(source: str, offset: int) -> int:
|
||||
return source.count("\n", 0, offset) + 1
|
||||
|
||||
|
||||
def extract_call(source: str, start: int) -> str:
|
||||
depth = 0
|
||||
saw_open = False
|
||||
for index in range(start, min(len(source), start + 16_384)):
|
||||
character = source[index]
|
||||
if character == "(":
|
||||
depth += 1
|
||||
saw_open = True
|
||||
elif character == ")" and saw_open:
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
return source[start : index + 1]
|
||||
return source[start : min(len(source), start + 16_384)]
|
||||
|
||||
|
||||
def extract_transcript_function(source: str) -> tuple[int, str] | None:
|
||||
match = re.search(r"\bfunc\s+transcript\s*\(", source)
|
||||
if match is None:
|
||||
return None
|
||||
brace = source.find("{", match.end())
|
||||
if brace < 0:
|
||||
return None
|
||||
depth = 0
|
||||
for index in range(brace, len(source)):
|
||||
if source[index] == "{":
|
||||
depth += 1
|
||||
elif source[index] == "}":
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
return match.start(), source[brace : index + 1]
|
||||
return match.start(), source[brace:]
|
||||
|
||||
|
||||
def scan_file(path: Path) -> list[Violation]:
|
||||
source = path.read_text(encoding="utf-8")
|
||||
violations: list[Violation] = []
|
||||
|
||||
for match in LOG_START.finditer(source):
|
||||
line_start = source.rfind("\n", 0, match.start()) + 1
|
||||
if source[line_start : match.start()].lstrip().startswith("//"):
|
||||
continue
|
||||
call = extract_call(source, match.start())
|
||||
expressions = INTERPOLATION.findall(call)
|
||||
exposed_expressions = [
|
||||
re.sub(r"\b(?:result\.text\?|error\.message)\.count\b", "", expression)
|
||||
for expression in expressions
|
||||
]
|
||||
if any(SENSITIVE_IDENTIFIER.search(expression) for expression in exposed_expressions):
|
||||
violations.append(
|
||||
Violation(
|
||||
path,
|
||||
line_number(source, match.start()),
|
||||
"sensitive identifier interpolated into a log",
|
||||
)
|
||||
)
|
||||
continue
|
||||
if SENSITIVE_LABEL.search(call) and (expressions or "+" in call):
|
||||
violations.append(
|
||||
Violation(
|
||||
path,
|
||||
line_number(source, match.start()),
|
||||
"sensitive log label may expose user or credential text",
|
||||
)
|
||||
)
|
||||
continue
|
||||
opening = call.find("(")
|
||||
direct_argument = call[opening + 1 :] if opening >= 0 else call
|
||||
if SENSITIVE_IDENTIFIER.match(direct_argument.lstrip()):
|
||||
violations.append(
|
||||
Violation(
|
||||
path,
|
||||
line_number(source, match.start()),
|
||||
"sensitive value passed directly to a log",
|
||||
)
|
||||
)
|
||||
continue
|
||||
if "CloudASR" in path.parts and re.search(
|
||||
r"\\\([^)]*\.localizedDescription\b", call
|
||||
):
|
||||
violations.append(
|
||||
Violation(
|
||||
path,
|
||||
line_number(source, match.start()),
|
||||
"cloud ASR log exposes localized error detail",
|
||||
)
|
||||
)
|
||||
|
||||
if path.name == "FlowTrace.swift" or "enum FlowTrace" in source:
|
||||
transcript_function = extract_transcript_function(source)
|
||||
if transcript_function is not None:
|
||||
offset, body = transcript_function
|
||||
if re.search(r"\\\(\s*text\b", body):
|
||||
violations.append(
|
||||
Violation(
|
||||
path,
|
||||
line_number(source, offset),
|
||||
"FlowTrace.transcript must not interpolate text",
|
||||
)
|
||||
)
|
||||
|
||||
return violations
|
||||
|
||||
|
||||
def scan(paths: list[Path]) -> list[Violation]:
|
||||
violations: list[Violation] = []
|
||||
for path in paths:
|
||||
violations.extend(scan_file(path))
|
||||
return violations
|
||||
|
||||
|
||||
def run_self_test() -> bool:
|
||||
fixture_root = ROOT / "Scripts"
|
||||
safe = fixture_root / "sensitive_logs_safe.fixture.swift"
|
||||
unsafe = fixture_root / "sensitive_logs_unsafe.fixture.swift"
|
||||
safe_violations = scan([safe])
|
||||
unsafe_violations = scan([unsafe])
|
||||
if safe_violations:
|
||||
print("self-test failed: safe fixture was rejected", file=sys.stderr)
|
||||
return False
|
||||
if len(unsafe_violations) < 4:
|
||||
print("self-test failed: unsafe fixture was not fully rejected", file=sys.stderr)
|
||||
return False
|
||||
print("Sensitive-log gate self-test passed.")
|
||||
return True
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--self-test",
|
||||
action="store_true",
|
||||
help="verify the scanner against safe and unsafe fixtures",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.self_test:
|
||||
return 0 if run_self_test() else 1
|
||||
|
||||
violations = scan(swift_files(ROOT))
|
||||
if violations:
|
||||
for violation in violations:
|
||||
relative = violation.path.relative_to(ROOT)
|
||||
print(f"{relative}:{violation.line}: {violation.message}", file=sys.stderr)
|
||||
print(f"Sensitive-log gate failed with {len(violations)} violation(s).", file=sys.stderr)
|
||||
return 1
|
||||
print("Sensitive-log gate passed.")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -4,11 +4,21 @@ set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
VENDOR="$ROOT/ThirdParty/mlx-audio-swift"
|
||||
PATCH_MARKER="$VENDOR/.osg-context-patch-applied"
|
||||
PATCH_MARKER="$VENDOR/.osg-context-patch-v2-applied"
|
||||
PINNED_COMMIT="d302a5c6080d2bb97bae38c7418f82abb76013b6"
|
||||
|
||||
if [[ ! -f "$VENDOR/Package.swift" ]]; then
|
||||
echo "Cloning mlx-audio-swift into ThirdParty/..."
|
||||
git clone --depth 1 https://github.com/Blaizzy/mlx-audio-swift "$VENDOR"
|
||||
echo "Cloning pinned mlx-audio-swift into ThirdParty/..."
|
||||
git clone --filter=blob:none --no-checkout https://github.com/Blaizzy/mlx-audio-swift "$VENDOR"
|
||||
git -C "$VENDOR" fetch --depth 1 origin "$PINNED_COMMIT"
|
||||
git -C "$VENDOR" checkout --detach FETCH_HEAD
|
||||
fi
|
||||
|
||||
ACTUAL_COMMIT="$(git -C "$VENDOR" rev-parse HEAD)"
|
||||
if [[ "$ACTUAL_COMMIT" != "$PINNED_COMMIT" ]]; then
|
||||
echo "error: mlx-audio-swift is at $ACTUAL_COMMIT; expected $PINNED_COMMIT" >&2
|
||||
echo "Remove ThirdParty/mlx-audio-swift and rerun this script." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -f "$PATCH_MARKER" ]]; then
|
||||
@@ -32,7 +42,19 @@ if "mlx-swift.git\", exact:" not in mtext:
|
||||
'.package(url: "https://github.com/ml-explore/mlx-swift.git", .upToNextMajor(from: "0.30.6")),',
|
||||
'.package(url: "https://github.com/ml-explore/mlx-swift.git", exact: "0.31.3"),',
|
||||
)
|
||||
manifest.write_text(mtext)
|
||||
mtext = mtext.replace(
|
||||
'.package(url: "https://github.com/ml-explore/mlx-swift-lm.git", .upToNextMajor(from: "3.31.3")),',
|
||||
'.package(url: "https://github.com/ml-explore/mlx-swift-lm.git", exact: "3.31.3"),',
|
||||
)
|
||||
mtext = mtext.replace(
|
||||
'.package(url: "https://github.com/huggingface/swift-transformers.git", .upToNextMajor(from: "1.1.6")),',
|
||||
'.package(url: "https://github.com/huggingface/swift-transformers.git", exact: "1.1.9"),',
|
||||
)
|
||||
mtext = mtext.replace(
|
||||
'.package(url: "https://github.com/huggingface/swift-huggingface.git", .upToNextMajor(from: "0.8.1"))',
|
||||
'.package(url: "https://github.com/huggingface/swift-huggingface.git", exact: "0.8.1")',
|
||||
)
|
||||
manifest.write_text(mtext)
|
||||
|
||||
text = types.read_text()
|
||||
if "public var context: String?" not in text:
|
||||
@@ -53,14 +75,16 @@ if "public var context: String?" not in text:
|
||||
types.write_text(text)
|
||||
|
||||
text = session.read_text()
|
||||
text = text.replace(
|
||||
" language: params.config.language\n )",
|
||||
" context: params.config.context ?? \"\",\n language: params.config.language\n )",
|
||||
)
|
||||
text = text.replace(
|
||||
" language: config.language\n )",
|
||||
" context: config.context ?? \"\",\n language: config.language\n )",
|
||||
)
|
||||
if "context: params.config.context" not in text:
|
||||
text = text.replace(
|
||||
" language: params.config.language\n )",
|
||||
" context: params.config.context ?? \"\",\n language: params.config.language\n )",
|
||||
)
|
||||
if "context: config.context" not in text:
|
||||
text = text.replace(
|
||||
" language: config.language\n )",
|
||||
" context: config.context ?? \"\",\n language: config.language\n )",
|
||||
)
|
||||
session.write_text(text)
|
||||
PY
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
PBXPROJ="$ROOT/OSGKeyboard.xcodeproj/project.pbxproj"
|
||||
PACKAGE_LOCK="$ROOT/Scripts/Package.resolved.lock"
|
||||
GENERATED_PACKAGE_LOCK="$ROOT/OSGKeyboard.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved"
|
||||
|
||||
# XcodeGen requires configFiles listed in project.yml to exist on disk.
|
||||
# Signing.local.xcconfig is gitignored so each machine keeps its own team ID.
|
||||
@@ -25,6 +27,13 @@ fi
|
||||
|
||||
xcodegen generate
|
||||
|
||||
if [[ ! -f "$PACKAGE_LOCK" ]]; then
|
||||
echo "error: missing reviewed SwiftPM lock at $PACKAGE_LOCK" >&2
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p "$(dirname "$GENERATED_PACKAGE_LOCK")"
|
||||
cp "$PACKAGE_LOCK" "$GENERATED_PACKAGE_LOCK"
|
||||
|
||||
"$ROOT/Scripts/patch-spm-local-package.sh"
|
||||
|
||||
if python3 - "$PBXPROJ" <<'PY'
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# Installs the reviewed XcodeGen release into RUNNER_TEMP for GitHub Actions.
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="2.43.0"
|
||||
SHA256="a4847ed77d3341a4d24049bc4424a3babca4c94ff1dcaaee923eaca2b32c678f"
|
||||
DESTINATION="${RUNNER_TEMP:?RUNNER_TEMP is required}/xcodegen-$VERSION"
|
||||
ARCHIVE="$RUNNER_TEMP/xcodegen-$VERSION.zip"
|
||||
|
||||
curl -fsSL --retry 3 --retry-all-errors --retry-delay 2 \
|
||||
--connect-timeout 15 --max-time 120 \
|
||||
"https://github.com/yonaskolb/XcodeGen/releases/download/$VERSION/xcodegen.zip" \
|
||||
-o "$ARCHIVE"
|
||||
echo "$SHA256 $ARCHIVE" | shasum -a 256 -c -
|
||||
rm -rf "$DESTINATION"
|
||||
mkdir -p "$DESTINATION"
|
||||
unzip -q "$ARCHIVE" -d "$DESTINATION"
|
||||
|
||||
test -x "$DESTINATION/bin/xcodegen"
|
||||
echo "$DESTINATION/bin" >> "$GITHUB_PATH"
|
||||
"$DESTINATION/bin/xcodegen" --version
|
||||
@@ -23,6 +23,8 @@ TEST_ROOTS = [
|
||||
ROOT / "OSGKeyboardExtTests",
|
||||
ROOT / "OSGKeyboardMacTests",
|
||||
]
|
||||
SHARED_TEST_ROOT = ROOT / "Tests"
|
||||
SHARED_TEST_TARGETS = ["OSGKeyboardTests", "OSGKeyboardMacTests"]
|
||||
|
||||
|
||||
def load_manifest() -> dict:
|
||||
@@ -87,6 +89,11 @@ def discover_on_disk_test_classes() -> dict[str, Path]:
|
||||
class_name = path.stem
|
||||
test_id = f"{target}/{class_name}"
|
||||
found[test_id] = path
|
||||
if SHARED_TEST_ROOT.is_dir():
|
||||
for path in sorted(SHARED_TEST_ROOT.glob("*Tests.swift")):
|
||||
for target in SHARED_TEST_TARGETS:
|
||||
test_id = f"{target}/{path.stem}"
|
||||
found[test_id] = path
|
||||
return found
|
||||
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ run_xcodebuild() {
|
||||
-scheme "$scheme"
|
||||
-destination "$destination"
|
||||
-configuration "$CONFIGURATION"
|
||||
-onlyUsePackageVersionsFromResolvedFile
|
||||
CODE_SIGNING_ALLOWED=NO
|
||||
)
|
||||
local test_id
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import Foundation
|
||||
|
||||
func buildRequest(apiKey: String, payload: Data, provider: String, status: Int) {
|
||||
var request = URLRequest(url: URL(string: "https://example.com/v1")!)
|
||||
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
|
||||
request.httpBody = payload
|
||||
print("provider=\(provider) status=\(status) responseBytes=\(payload.count)")
|
||||
}
|
||||
|
||||
func traceSafely(transcript: String) {
|
||||
FlowTrace.transcript("asr.final", transcript, "source=fixture")
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
func leakCredential(apiKey: String) {
|
||||
print("credential=\(apiKey)")
|
||||
}
|
||||
|
||||
func leakResponse(bodyText: String) {
|
||||
OSGLog.flow.error("response=\(bodyText, privacy: .public)")
|
||||
}
|
||||
|
||||
func leakPrompt(text: String) {
|
||||
debug("prompt=\(text)")
|
||||
}
|
||||
|
||||
func leakResult(result: FlowResult) {
|
||||
FlowTrace.warn("failed", "message=\(result.text ?? "nil")")
|
||||
}
|
||||
|
||||
func leakError(error: FlowTranscriptionError) {
|
||||
debug("failure=\(error.message)")
|
||||
}
|
||||
|
||||
enum FlowTrace {
|
||||
static func transcript(_ step: String, _ text: String) {
|
||||
print("stage=\(step) text=\(text)")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user