Symptom: app hard-blocks at boot with "JarvisEntitlementsVerified missing/false" after every incremental build, even though the build log shows pre-codesign writing YES into the bundle Info.plist. Root cause: Xcode 26's new build system schedules the built-in ProcessInfoPlistFile task (which copies App/Info.plist into Contents/Info.plist) independently from postBuildScripts. On incremental builds with no Swift compile work, ProcessInfoPlistFile ran AFTER pre-codesign, codesign, post-codesign, AND verify-codesign-settings — silently clobbering the bundle Info.plist with the source one. Source App/Info.plist carries <key>JarvisEntitlementsVerified</key><false/> by design as the static-state default; pre-codesign is supposed to flip it to <true/> inside the bundle. With the new ordering, the bundle ended every build at <false/> (and the signature was also stale relative to that plist, though codesign --verify happened to still pass). Fix: declare $(TARGET_BUILD_DIR)/$(INFOPLIST_PATH) as an inputFile of the pre-codesign phase, plus a per-build stamp file as its outputFile. This forces Xcode to make ProcessInfoPlistFile a prerequisite of pre-codesign, and chains codesign (also gaining the stamp as inputFile) deterministically behind it. Xcode 26's "mutable output but no other virtual output node" check rejects naming the plist as both input and output of the same phase, so the separate stamp file is required. Verified: clean and incremental builds both produce a bundle with JarvisEntitlementsVerified=true and a valid signature. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
671 lines
29 KiB
YAML
671 lines
29 KiB
YAML
name: Jarvis
|
|
options:
|
|
createIntermediateGroups: true
|
|
generateEmptyDirectories: true
|
|
minimumXcodeGenVersion: "2.40.0"
|
|
deploymentTarget:
|
|
macOS: "14.0"
|
|
settings:
|
|
base:
|
|
SWIFT_VERSION: "6.0"
|
|
SWIFT_STRICT_CONCURRENCY: complete
|
|
ENABLE_HARDENED_RUNTIME: YES
|
|
CODE_SIGN_STYLE: Manual
|
|
CODE_SIGN_IDENTITY: "-"
|
|
OTHER_CODE_SIGN_FLAGS: "--options=runtime --timestamp"
|
|
LD_RUNPATH_SEARCH_PATHS: "@executable_path/../Frameworks"
|
|
MACOSX_DEPLOYMENT_TARGET: "14.0"
|
|
configs:
|
|
# DEVELOPMENT_TEAM intentionally unset for Debug.
|
|
# With ad-hoc signing (CODE_SIGN_IDENTITY="-") and DEVELOPMENT_TEAM set,
|
|
# Xcode generates incremental debug dylibs signed with the Team ID while
|
|
# the main executable remains adhoc — dyld refuses to load the mismatched
|
|
# dylib ("different Team IDs"), and xctest crashes during bootstrap.
|
|
Debug:
|
|
ONLY_ACTIVE_ARCH: YES
|
|
Release:
|
|
DEVELOPMENT_TEAM: 7UC2HETAN9
|
|
packages:
|
|
Keychain:
|
|
path: packages/Keychain
|
|
Config:
|
|
path: packages/Config
|
|
Logging:
|
|
path: packages/Logging
|
|
Shell:
|
|
path: packages/Shell
|
|
Bus:
|
|
path: packages/Bus
|
|
# Plan 05-05: App-level wiring consumes JarvisMCP (the confirmation
|
|
# broker / dispatcher / presenter chain), AgentCore (BoundedAsyncChannel
|
|
# for ME-04 closure + ToolUseRequest), and Replay (ReplayEvent type for
|
|
# the orch→replay channel + ReplayLog for the SEC-07 observer).
|
|
AgentCore:
|
|
path: packages/AgentCore
|
|
MCP:
|
|
path: packages/MCP
|
|
Replay:
|
|
path: packages/Replay
|
|
# Plan 06-05: App-level voice wiring (App/AppDelegate.installVoice + the
|
|
# Voice typealias in App/HUD/HudStateIntent.swift) consumes the Voice
|
|
# package's VoiceController, VoiceState, VoiceHudIntent, PushToTalk,
|
|
# MuteWakeWord, and AudioLevelEmitter surfaces.
|
|
Voice:
|
|
path: packages/Voice
|
|
# Plan 07-01: App-level memory wiring (future: AppDelegate.installMemory in
|
|
# Plan 07-06) consumes the Memory package's MemoryStore actor + schema.
|
|
# Plan 07-01 only stands up the package; the App→Memory edge is exercised
|
|
# via Bus events / DevOverlay rows in Plan 07-03 + 07-06.
|
|
Memory:
|
|
path: packages/Memory
|
|
# Plan 07-04: App-level vision wiring (future: AppDelegate.installVision in
|
|
# Plan 07-06) consumes the Vision package's CameraCapture, PresenceMonitor,
|
|
# PresenceSignalBus, and DisablePresence surfaces. Plan 07-04 only stands
|
|
# up the package and the VISION-03 grep gates; the App→Vision edge is
|
|
# wired in Plan 07-06.
|
|
Vision:
|
|
path: packages/Vision
|
|
# DevOverlay package — diagnostic floating panel showing live agent state,
|
|
# tool calls, token counts, and per-turn latency. Hidden by default; toggled
|
|
# from the menu bar (Show Dev Overlay item).
|
|
DevOverlay:
|
|
path: packages/DevOverlay
|
|
# Plan 08-01: Phase 8 evaluation harness — `Harness` library + `jarvis-eval`
|
|
# executable target. Consumed by tests / CI shipping-gate (`scripts/shipping-gate.sh`).
|
|
# The xcodegen entry exposes the local SPM package; the executable is
|
|
# invoked via `swift run --package-path packages/Harness jarvis-eval ...`.
|
|
Harness:
|
|
path: packages/Harness
|
|
# MCP Swift SDK — consumed by `mcp-time`, `mcp-clipboard` (Plan 05-02), and
|
|
# `mcp-applescript` (Plan 05-03) helper targets. Pinned at the same exact
|
|
# version as `packages/MCP/Package.swift` (Plan 05-01) to avoid
|
|
# dual-resolution drift.
|
|
swift-sdk:
|
|
url: https://github.com/modelcontextprotocol/swift-sdk
|
|
exactVersion: "0.12.0"
|
|
# Plan 05-05: swift-log is consumed transitively by `JarvisLogging`,
|
|
# `Replay`, `AgentOrchestrator`, and `JarvisMCP`. The Xcode framework
|
|
# linker needs an explicit App-target dependency once these are linked
|
|
# as separate frameworks (the App previously only saw Logging through
|
|
# JarvisLogging's exported symbols, which xcodegen surfaces as a
|
|
# "Logger.MetadataValue undefined" linker error).
|
|
swift-log:
|
|
url: https://github.com/apple/swift-log.git
|
|
from: "1.5.0"
|
|
targets:
|
|
Jarvis:
|
|
type: application
|
|
platform: macOS
|
|
sources:
|
|
- path: App
|
|
excludes:
|
|
- "Info.plist"
|
|
- "Jarvis.entitlements"
|
|
- "Jarvis.Debug.entitlements"
|
|
- "Jarvis.Release.entitlements"
|
|
- "Tests/**"
|
|
- "Resources/**"
|
|
# Blue-folder reference. The folder's NAME becomes the subdirectory
|
|
# inside Contents/Resources/ in the built bundle (xcodegen preserves
|
|
# the last path segment). Pointing this at `App/Resources/webview`
|
|
# makes the bundle path `Contents/Resources/webview/…`, matching
|
|
# `Bundle.main.url(forResource:withExtension:subdirectory:"webview")`.
|
|
- path: App/Resources/webview
|
|
type: folder
|
|
buildPhase: resources
|
|
settings:
|
|
base:
|
|
PRODUCT_BUNDLE_IDENTIFIER: com.koftwentytwo.jarvis
|
|
PRODUCT_NAME: Jarvis
|
|
INFOPLIST_FILE: App/Info.plist
|
|
GENERATE_INFOPLIST_FILE: NO
|
|
ENABLE_HARDENED_RUNTIME: YES
|
|
CODE_SIGN_STYLE: Manual
|
|
CODE_SIGN_IDENTITY: "-"
|
|
OTHER_CODE_SIGN_FLAGS: "--options=runtime --timestamp"
|
|
SWIFT_STRICT_CONCURRENCY: complete
|
|
SWIFT_VERSION: "6.0"
|
|
MACOSX_DEPLOYMENT_TARGET: "14.0"
|
|
LD_RUNPATH_SEARCH_PATHS: "@executable_path/../Frameworks"
|
|
configs:
|
|
Debug:
|
|
CODE_SIGNING_ALLOWED: NO
|
|
CODE_SIGNING_REQUIRED: NO
|
|
CODE_SIGN_ENTITLEMENTS: App/Jarvis.Debug.entitlements
|
|
# Hardened Runtime OFF for Debug — HR's strict "non-platform Team IDs
|
|
# must match" rule rejects Xcode 26's debug dylib incremental-link
|
|
# artifact (Jarvis.debug.dylib) against our ad-hoc signed main
|
|
# executable, producing the abrt-during-bootstrap crash on xctest
|
|
# launch. HR is only meaningful for Release/distribution anyway.
|
|
ENABLE_HARDENED_RUNTIME: NO
|
|
# OTHER_CODE_SIGN_FLAGS must not carry `--options=runtime` on Debug —
|
|
# that flag enables HR regardless of ENABLE_HARDENED_RUNTIME. Strip it.
|
|
OTHER_CODE_SIGN_FLAGS: ""
|
|
# Disable Swift 6 / Xcode 26 incremental-link `Jarvis.debug.dylib`
|
|
# artifact entirely on Debug. The dylib gets a Team-ID context
|
|
# (from how Xcode's compile cache signs it) that diverges from the
|
|
# ad-hoc outer bundle; dyld then aborts at __abort_with_payload
|
|
# when the app tries to load it. With NO, Swift links the binary
|
|
# statically and there's no separate dylib to load.
|
|
# Trade-off: ~5-15% slower incremental Debug compile, but the app
|
|
# actually launches from Xcode's Run scheme (⌘R).
|
|
SWIFT_ENABLE_DEBUG_DYLIB: NO
|
|
Release:
|
|
DEVELOPMENT_TEAM: 7UC2HETAN9
|
|
CODE_SIGNING_ALLOWED: NO
|
|
CODE_SIGNING_REQUIRED: NO
|
|
CODE_SIGN_ENTITLEMENTS: App/Jarvis.Release.entitlements
|
|
dependencies:
|
|
- package: Keychain
|
|
product: Keychain
|
|
- package: Config
|
|
product: Config
|
|
- package: Logging
|
|
product: JarvisLogging
|
|
- package: Shell
|
|
product: Shell
|
|
- package: Bus
|
|
product: Bus
|
|
# Plan 05-05: App-level MCP runtime wiring (App/MCP/MCPRuntimeWiring,
|
|
# App/MCP/ReplayingToolResultObserver) consumes these.
|
|
- package: AgentCore
|
|
product: AgentCore
|
|
- package: AgentCore
|
|
product: AgentOrchestrator
|
|
- package: MCP
|
|
product: JarvisMCP
|
|
- package: Replay
|
|
product: Replay
|
|
# Plan 05-05: AppDelegate and other App sources `import Logging`
|
|
# (swift-log's Logger). The App target previously got swift-log
|
|
# transitively through JarvisLogging; the Xcode framework linker is
|
|
# stricter once the App pulls in extra package frameworks (Replay,
|
|
# AgentCore, JarvisMCP) so the dep needs to be explicit.
|
|
- package: swift-log
|
|
product: Logging
|
|
# Plan 06-05: AppDelegate.installVoice + HudStateIntent.swift
|
|
# `import Voice` for the VoiceController + VoiceHudIntent typealias.
|
|
- package: Voice
|
|
product: Voice
|
|
# Plan 07-01: package wiring for downstream Phase 7 plans
|
|
# (AppDelegate.installMemory lands in 07-06). Declaring the dependency
|
|
# here so xcodegen picks it up at the same time as the Memory package
|
|
# path entry above.
|
|
- package: Memory
|
|
product: Memory
|
|
# Plan 07-04: package wiring for downstream Phase 7 plans
|
|
# (AppDelegate.installVision lands in 07-06). Declaring the dependency
|
|
# here so xcodegen picks it up at the same time as the Vision package
|
|
# path entry above. Product is `JarvisVision` (not `Vision`) to avoid
|
|
# colliding with Apple's Vision framework — see packages/Vision/Package.swift.
|
|
- package: Vision
|
|
product: JarvisVision
|
|
# DevOverlay diagnostic panel — toggled from the menu-bar 'Show Dev
|
|
# Overlay' item. AppDelegate.installDevOverlay() constructs the
|
|
# DevOverlayWindow on first toggle and routes the menu action to it.
|
|
- package: DevOverlay
|
|
product: DevOverlay
|
|
# Plan 05-02 / 05-03: build the helper apps before the Jarvis copyFiles
|
|
# phase consumes them. xcodegen orders target dependencies before copy
|
|
# phases.
|
|
- target: mcp-time
|
|
embed: false
|
|
link: false
|
|
- target: mcp-clipboard
|
|
embed: false
|
|
link: false
|
|
- target: mcp-applescript
|
|
embed: false
|
|
link: false
|
|
preBuildScripts:
|
|
# Three build-breaking pre-build phases — run BEFORE Compile Sources.
|
|
# Ordered fastest-failing first so common authoring errors surface
|
|
# before the slower lint walk of the Swift tree.
|
|
- name: Check bus-harness.html parity (canonical vs bundle)
|
|
script: |
|
|
"${SRCROOT}/scripts/check-bus-harness-parity.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
inputFiles:
|
|
- $(SRCROOT)/webview/bus-harness.html
|
|
- $(SRCROOT)/App/Resources/webview/bus-harness.html
|
|
- name: Check bus protocol version (Swift/TS parity)
|
|
script: |
|
|
"${SRCROOT}/scripts/check-bus-protocol-version.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
inputFiles:
|
|
- $(SRCROOT)/packages/Bus/Sources/Bus/Protocol.swift
|
|
- $(SRCROOT)/webview/packages/bus/src/protocol.ts
|
|
- name: Check no evaluateJavaScript calls (HUD-04)
|
|
script: |
|
|
"${SRCROOT}/scripts/check-no-evaluate-javascript.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
- name: Check single-writer HUD state (HUD-08)
|
|
script: |
|
|
"${SRCROOT}/scripts/check-single-writer-hudstate.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
# Plan 05-05 (MCP-04): reject runModal / beginModalSession / NSApp.run
|
|
# outside the two-file allowlist (TCCAlertService + ConfirmationPresenter).
|
|
# Module-wide lint — fails the build fast on regression.
|
|
- name: Check no modal presentation (MCP-04)
|
|
script: |
|
|
"${SRCROOT}/scripts/check-no-modal-presentation.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
# Plan 07-06 (MEM-06): single emission site for ReplayEvent.memoryMutation.
|
|
- name: Check single memory.mutated emission site (MEM-06)
|
|
script: |
|
|
"${SRCROOT}/scripts/check-single-memory-mutated-emit.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
# Plan 07-06 (D-05): single emission site for ReplayEvent.memoryRetrieval.
|
|
- name: Check single memory.used emission site (D-05)
|
|
script: |
|
|
"${SRCROOT}/scripts/check-single-memory-used-emit.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
# Plan 07-06 (VISION-03): no PresenceSignalBus subscriber forwards into
|
|
# JarvisTTS or AgentOrchestrator submit / cancelAndSubmit / runTurn.
|
|
- name: Check presence-vision isolation (VISION-03)
|
|
script: |
|
|
"${SRCROOT}/scripts/check-presence-vision-isolation.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
# Plan 07-06 (MEM-02): no literal 768 outside MemoryConstants.embeddingDim.
|
|
- name: Check embedding-dim literal (MEM-02)
|
|
script: |
|
|
"${SRCROOT}/scripts/check-embedding-dim-literal.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
# Plan 09-01 (D-05/D-08, WARNING-2): orchestrator.events has exactly one
|
|
# production consumer — OrchestratorEventBroadcaster's drain Task.
|
|
- name: Check orchestrator.events single-consumer (Phase 9)
|
|
script: |
|
|
"${SRCROOT}/scripts/check-orchestrator-events-single-consumer.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
- name: Build webview bundle
|
|
script: |
|
|
"${SRCROOT}/scripts/build-webview.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
# Plan 05-02 (DEVIATION from plan): xcodegen's `copyFiles` phase doesn't
|
|
# resolve target products from BUILT_PRODUCTS_DIR — it expects file paths
|
|
# relative to SRCROOT. The plan's `files: [mcp-time.app, mcp-clipboard.app]`
|
|
# produced an empty Contents/Helpers/ at build time. Switched to a
|
|
# postBuildScript (`Copy MCP helpers into Contents/Helpers/`) that shells
|
|
# out to `cp -R` from BUILT_PRODUCTS_DIR — this matches the plan's
|
|
# deviation_rules clause #1 ("If xcodegen doesn't directly support nested
|
|
# .app bundles via Contents/Helpers/<Name>.app/, generate the helper
|
|
# bundles via separate xcodebuild targets and copy them in via a Build
|
|
# Phase script").
|
|
#
|
|
# Code Sign On Copy is NOT enabled anywhere — codesign.sh's deepest-first
|
|
# walker is the authoritative signer, preserving per-helper entitlements.
|
|
postBuildScripts:
|
|
- name: Copy voice models into Contents/Resources/Models/
|
|
# Plan 06-05 (Track B-1, 2026-05-03 audit fix): the voice subsystem
|
|
# reads ONNX models from `Contents/Resources/Models/` (capital M)
|
|
# in `AppDelegate.installVoice` (line 653). On disk, the canonical
|
|
# path is the repo-root `Resources/models/` (lowercase). project.yml
|
|
# had no copy phase wiring the two together, so the built .app
|
|
# bundle's `Contents/Resources/` had ZERO .onnx files and every
|
|
# cold launch logged `OpenWakeWordSession init failed (models
|
|
# absent?)`. This phase runs `scripts/copy-voice-models.sh` which
|
|
# does the canonical-path-to-runtime-path mapping (also corrects
|
|
# `openwakeword` → `openWakeWord` capitalization). The script
|
|
# gates on MANIFEST.json sha256 not being a `PLACEHOLDER_…` value
|
|
# so a forgotten `scripts/fetch-silero-models.sh` is a hard build
|
|
# error, not a silent runtime failure.
|
|
script: |
|
|
"${SRCROOT}/scripts/copy-voice-models.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
- name: Create Contents/Helpers directory
|
|
script: |
|
|
mkdir -p "${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Contents/Helpers"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
- name: Copy MCP helpers into Contents/Helpers/
|
|
script: |
|
|
# Replace any prior copies wholesale so stale files don't linger after
|
|
# a helper rename or removal. -R preserves the .app bundle structure.
|
|
set -euo pipefail
|
|
DEST="${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Contents/Helpers"
|
|
for HELPER in mcp-time mcp-clipboard mcp-applescript; do
|
|
SRC="${BUILT_PRODUCTS_DIR}/${HELPER}.app"
|
|
if [ ! -d "$SRC" ]; then
|
|
echo "error: helper bundle missing at $SRC (was the ${HELPER} target built first?)" >&2
|
|
exit 1
|
|
fi
|
|
rm -rf "${DEST}/${HELPER}.app"
|
|
cp -R "$SRC" "${DEST}/${HELPER}.app"
|
|
done
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
# Pre-codesign declares the bundle's Info.plist as an inputFile.
|
|
# Why: Xcode's built-in `ProcessInfoPlistFile` task (which copies
|
|
# App/Info.plist into Contents/Info.plist) has no implicit ordering vs.
|
|
# postBuildScripts. With the new build system on Xcode 26, an
|
|
# incremental build with no Swift compile work would schedule
|
|
# `ProcessInfoPlistFile` AFTER every PhaseScriptExecution — including
|
|
# codesign — silently clobbering the bundle Info.plist with the source
|
|
# one (which carries `<key>JarvisEntitlementsVerified</key><false/>` by
|
|
# design as the static-state default). The app then hard-blocks at boot
|
|
# via the AppDelegate marker check. Declaring the bundle plist as an
|
|
# inputFile forces Xcode to schedule `ProcessInfoPlistFile` before this
|
|
# phase. We also emit a stamp file as the outputFile so the new build
|
|
# system can build a clean dependency edge — declaring Info.plist as
|
|
# both input and output trips Xcode 26's "mutable output but no other
|
|
# virtual output node" check. The stamp file is the virtual output that
|
|
# downstream phases (codesign, post-codesign) chain off via their own
|
|
# inputFile, locking the rest of the postBuildScript chain behind us.
|
|
- name: Verify entitlements (pre-codesign)
|
|
script: |
|
|
"${SRCROOT}/scripts/verify-entitlements.sh" --pre-codesign
|
|
# Stamp file for build-graph ordering (see comment above). The
|
|
# script's real side effect is on Info.plist, but we expose this
|
|
# stamp as the virtual output so Xcode 26 can sequence later
|
|
# phases (codesign, post-codesign) behind us deterministically.
|
|
mkdir -p "${DERIVED_FILE_DIR}"
|
|
/usr/bin/touch "${DERIVED_FILE_DIR}/pre-codesign.stamp"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
inputFiles:
|
|
- $(TARGET_BUILD_DIR)/$(INFOPLIST_PATH)
|
|
outputFiles:
|
|
- $(DERIVED_FILE_DIR)/pre-codesign.stamp
|
|
- name: Codesign bundle (deepest-first)
|
|
script: |
|
|
# Fall back to CODE_SIGN_IDENTITY (then ad-hoc "-") when CODE_SIGNING_ALLOWED=NO,
|
|
# since Xcode does not set EXPANDED_CODE_SIGN_IDENTITY in that case.
|
|
export EXPANDED_CODE_SIGN_IDENTITY="${EXPANDED_CODE_SIGN_IDENTITY:-${CODE_SIGN_IDENTITY:--}}"
|
|
"${SRCROOT}/scripts/codesign.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
inputFiles:
|
|
- $(DERIVED_FILE_DIR)/pre-codesign.stamp
|
|
- name: Verify entitlements (post-codesign)
|
|
script: |
|
|
"${SRCROOT}/scripts/verify-entitlements.sh" --post-codesign
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
- name: Verify codesign settings (pbxproj lint)
|
|
script: |
|
|
"${SRCROOT}/scripts/verify-codesign-settings.sh"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
JarvisAppTests:
|
|
type: bundle.unit-test
|
|
platform: macOS
|
|
sources:
|
|
- path: App/Tests/AppTests
|
|
settings:
|
|
base:
|
|
PRODUCT_NAME: JarvisAppTests
|
|
PRODUCT_BUNDLE_IDENTIFIER: com.koftwentytwo.jarvis.AppTests
|
|
GENERATE_INFOPLIST_FILE: YES
|
|
SWIFT_STRICT_CONCURRENCY: complete
|
|
SWIFT_VERSION: "6.0"
|
|
MACOSX_DEPLOYMENT_TARGET: "14.0"
|
|
BUNDLE_LOADER: "$(TEST_HOST)"
|
|
TEST_HOST: "$(BUILT_PRODUCTS_DIR)/Jarvis.app/Contents/MacOS/Jarvis"
|
|
CODE_SIGN_IDENTITY: "-"
|
|
CODE_SIGN_STYLE: Manual
|
|
configs:
|
|
Debug:
|
|
CODE_SIGNING_ALLOWED: NO
|
|
CODE_SIGNING_REQUIRED: NO
|
|
dependencies:
|
|
- target: Jarvis
|
|
# Plan 05-05: MCPRuntimeWiringTests imports JarvisMCP, AgentCore, Replay
|
|
# for the structural wiring-graph assertions. Adding these new
|
|
# package deps to the AppTests target unfortunately disturbs the
|
|
# transitive resolution of Config/Keychain/Bus/Shell/Logging that the
|
|
# bundle was getting through `target: Jarvis`; declare them
|
|
# explicitly so the test bundle links cleanly.
|
|
- package: AgentCore
|
|
product: AgentCore
|
|
- package: AgentCore
|
|
product: AgentOrchestrator
|
|
- package: MCP
|
|
product: JarvisMCP
|
|
- package: Replay
|
|
product: Replay
|
|
- package: swift-log
|
|
product: Logging
|
|
- package: Config
|
|
product: Config
|
|
- package: Keychain
|
|
product: Keychain
|
|
- package: Bus
|
|
product: Bus
|
|
- package: Shell
|
|
product: Shell
|
|
- package: Logging
|
|
product: JarvisLogging
|
|
# Plan 06-05: VoiceWiringTests (App/Tests/AppTests/VoiceWiringTests.swift)
|
|
# asserts AppDelegate's voice wiring graph; needs the Voice product to
|
|
# @testable import the App target's voice integration code.
|
|
- package: Voice
|
|
product: Voice
|
|
# Track-D D-1: MemoryInstallWiringTests asserts AppDelegate.installMemory's
|
|
# post-D-1 wiring graph (extractor + coordinator construct even on vec
|
|
# failure; in-process tool registry gating). Requires Memory for the
|
|
# @testable import that lets the test reach internal types.
|
|
- package: Memory
|
|
product: Memory
|
|
JarvisEntitlementProbeTests:
|
|
type: bundle.unit-test
|
|
platform: macOS
|
|
sources:
|
|
- path: App/Tests/JarvisEntitlementProbeTests
|
|
excludes:
|
|
- "Info.plist"
|
|
settings:
|
|
base:
|
|
PRODUCT_NAME: JarvisEntitlementProbeTests
|
|
PRODUCT_BUNDLE_IDENTIFIER: com.koftwentytwo.jarvis.EntitlementProbeTests
|
|
INFOPLIST_FILE: App/Tests/JarvisEntitlementProbeTests/Info.plist
|
|
GENERATE_INFOPLIST_FILE: NO
|
|
SWIFT_STRICT_CONCURRENCY: complete
|
|
SWIFT_VERSION: "6.0"
|
|
MACOSX_DEPLOYMENT_TARGET: "14.0"
|
|
BUNDLE_LOADER: "$(TEST_HOST)"
|
|
TEST_HOST: "$(BUILT_PRODUCTS_DIR)/Jarvis.app/Contents/MacOS/Jarvis"
|
|
CODE_SIGN_IDENTITY: "-"
|
|
CODE_SIGN_STYLE: Manual
|
|
OTHER_SWIFT_FLAGS: "-DJARVIS_ENTITLEMENT_PROBE"
|
|
configs:
|
|
Debug:
|
|
CODE_SIGNING_ALLOWED: NO
|
|
CODE_SIGNING_REQUIRED: NO
|
|
dependencies:
|
|
- target: Jarvis
|
|
|
|
# =====================================================================
|
|
# MCP helper bundles (Plan 05-02)
|
|
# =====================================================================
|
|
# Each helper ships as a SEPARATELY codesigned nested .app under
|
|
# Jarvis.app/Contents/Helpers/<helper>.app/. Per-helper Info.plist +
|
|
# entitlements live under mcp-servers/<helper>/Support/. Codesigning is
|
|
# done by scripts/codesign.sh's deepest-first walker (NOT by xcodegen's
|
|
# "Code Sign On Copy" — that would strip per-helper entitlements). A
|
|
# postBuildScript on each target copies the source .entitlements into
|
|
# the bundle's Contents/Resources/<helper>.entitlements where codesign.sh
|
|
# expects to find it.
|
|
mcp-time:
|
|
type: application
|
|
platform: macOS
|
|
sources:
|
|
- path: mcp-servers/mcp-time/Sources/mcp-time
|
|
settings:
|
|
base:
|
|
PRODUCT_BUNDLE_IDENTIFIER: com.koftwentytwo.jarvis.mcp-time
|
|
PRODUCT_NAME: mcp-time
|
|
INFOPLIST_FILE: mcp-servers/mcp-time/Support/Info.plist
|
|
GENERATE_INFOPLIST_FILE: NO
|
|
CODE_SIGN_ENTITLEMENTS: mcp-servers/mcp-time/Support/mcp-time.entitlements
|
|
ENABLE_HARDENED_RUNTIME: YES
|
|
CODE_SIGN_STYLE: Manual
|
|
CODE_SIGN_IDENTITY: "-"
|
|
OTHER_CODE_SIGN_FLAGS: "--options=runtime --timestamp"
|
|
SWIFT_STRICT_CONCURRENCY: complete
|
|
SWIFT_VERSION: "6.0"
|
|
MACOSX_DEPLOYMENT_TARGET: "14.0"
|
|
configs:
|
|
Debug:
|
|
CODE_SIGNING_ALLOWED: NO
|
|
CODE_SIGNING_REQUIRED: NO
|
|
ENABLE_HARDENED_RUNTIME: NO
|
|
OTHER_CODE_SIGN_FLAGS: ""
|
|
Release:
|
|
DEVELOPMENT_TEAM: 7UC2HETAN9
|
|
CODE_SIGNING_ALLOWED: NO
|
|
CODE_SIGNING_REQUIRED: NO
|
|
dependencies:
|
|
- package: swift-sdk
|
|
product: MCP
|
|
postBuildScripts:
|
|
- name: Copy mcp-time.entitlements into bundle Resources
|
|
script: |
|
|
mkdir -p "${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources"
|
|
cp "${SRCROOT}/mcp-servers/mcp-time/Support/mcp-time.entitlements" \
|
|
"${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/mcp-time.entitlements"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
|
|
mcp-clipboard:
|
|
type: application
|
|
platform: macOS
|
|
sources:
|
|
- path: mcp-servers/mcp-clipboard/Sources/mcp-clipboard
|
|
settings:
|
|
base:
|
|
PRODUCT_BUNDLE_IDENTIFIER: com.koftwentytwo.jarvis.mcp-clipboard
|
|
PRODUCT_NAME: mcp-clipboard
|
|
INFOPLIST_FILE: mcp-servers/mcp-clipboard/Support/Info.plist
|
|
GENERATE_INFOPLIST_FILE: NO
|
|
CODE_SIGN_ENTITLEMENTS: mcp-servers/mcp-clipboard/Support/mcp-clipboard.entitlements
|
|
ENABLE_HARDENED_RUNTIME: YES
|
|
CODE_SIGN_STYLE: Manual
|
|
CODE_SIGN_IDENTITY: "-"
|
|
OTHER_CODE_SIGN_FLAGS: "--options=runtime --timestamp"
|
|
SWIFT_STRICT_CONCURRENCY: complete
|
|
SWIFT_VERSION: "6.0"
|
|
MACOSX_DEPLOYMENT_TARGET: "14.0"
|
|
configs:
|
|
Debug:
|
|
CODE_SIGNING_ALLOWED: NO
|
|
CODE_SIGNING_REQUIRED: NO
|
|
ENABLE_HARDENED_RUNTIME: NO
|
|
OTHER_CODE_SIGN_FLAGS: ""
|
|
Release:
|
|
DEVELOPMENT_TEAM: 7UC2HETAN9
|
|
CODE_SIGNING_ALLOWED: NO
|
|
CODE_SIGNING_REQUIRED: NO
|
|
dependencies:
|
|
- package: swift-sdk
|
|
product: MCP
|
|
postBuildScripts:
|
|
- name: Copy mcp-clipboard.entitlements into bundle Resources
|
|
script: |
|
|
mkdir -p "${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources"
|
|
cp "${SRCROOT}/mcp-servers/mcp-clipboard/Support/mcp-clipboard.entitlements" \
|
|
"${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/mcp-clipboard.entitlements"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
|
|
# ---------------------------------------------------------------------
|
|
# mcp-applescript helper (Plan 05-03 / MCP-04)
|
|
# ---------------------------------------------------------------------
|
|
# Identical xcodegen shape to mcp-time / mcp-clipboard, with ONE difference:
|
|
# CODE_SIGN_ENTITLEMENTS points at the per-helper entitlements file that
|
|
# carries `com.apple.security.automation.apple-events`. scripts/verify-
|
|
# entitlements.sh --post-codesign enforces bidirectionally that this
|
|
# helper MUST carry the key and no other helper may.
|
|
#
|
|
# Bundle ID `com.koftwentytwo.jarvis.mcp-applescript` MUST have the Apple
|
|
# Events capability registered at developer.apple.com for Release archive
|
|
# notarization to succeed (see .planning/phases/05-mcp/05-03-HUMAN-UAT.md).
|
|
# Debug ad-hoc signing works without the capability registration.
|
|
mcp-applescript:
|
|
type: application
|
|
platform: macOS
|
|
sources:
|
|
- path: mcp-servers/mcp-applescript/Sources/mcp-applescript
|
|
settings:
|
|
base:
|
|
PRODUCT_BUNDLE_IDENTIFIER: com.koftwentytwo.jarvis.mcp-applescript
|
|
PRODUCT_NAME: mcp-applescript
|
|
INFOPLIST_FILE: mcp-servers/mcp-applescript/Support/Info.plist
|
|
GENERATE_INFOPLIST_FILE: NO
|
|
CODE_SIGN_ENTITLEMENTS: mcp-servers/mcp-applescript/Support/mcp-applescript.entitlements
|
|
ENABLE_HARDENED_RUNTIME: YES
|
|
CODE_SIGN_STYLE: Manual
|
|
CODE_SIGN_IDENTITY: "-"
|
|
OTHER_CODE_SIGN_FLAGS: "--options=runtime --timestamp"
|
|
SWIFT_STRICT_CONCURRENCY: complete
|
|
SWIFT_VERSION: "6.0"
|
|
MACOSX_DEPLOYMENT_TARGET: "14.0"
|
|
configs:
|
|
Debug:
|
|
CODE_SIGNING_ALLOWED: NO
|
|
CODE_SIGNING_REQUIRED: NO
|
|
ENABLE_HARDENED_RUNTIME: NO
|
|
OTHER_CODE_SIGN_FLAGS: ""
|
|
Release:
|
|
DEVELOPMENT_TEAM: 7UC2HETAN9
|
|
CODE_SIGNING_ALLOWED: NO
|
|
CODE_SIGNING_REQUIRED: NO
|
|
dependencies:
|
|
- package: swift-sdk
|
|
product: MCP
|
|
postBuildScripts:
|
|
- name: Copy mcp-applescript.entitlements into bundle Resources
|
|
script: |
|
|
mkdir -p "${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources"
|
|
cp "${SRCROOT}/mcp-servers/mcp-applescript/Support/mcp-applescript.entitlements" \
|
|
"${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Contents/Resources/mcp-applescript.entitlements"
|
|
runOnlyWhenInstalling: false
|
|
basedOnDependencyAnalysis: false
|
|
|
|
schemes:
|
|
Jarvis:
|
|
build:
|
|
targets:
|
|
Jarvis: all
|
|
JarvisAppTests: [test]
|
|
test:
|
|
targets:
|
|
- JarvisAppTests
|
|
gatherCoverageData: false
|
|
run:
|
|
config: Debug
|
|
profile:
|
|
config: Release
|
|
analyze:
|
|
config: Debug
|
|
archive:
|
|
config: Release
|
|
EntitlementProbe:
|
|
build:
|
|
targets:
|
|
Jarvis: all
|
|
JarvisEntitlementProbeTests: [test]
|
|
test:
|
|
targets:
|
|
- JarvisEntitlementProbeTests
|
|
gatherCoverageData: false
|
|
run:
|
|
config: Release
|
|
profile:
|
|
config: Release
|
|
analyze:
|
|
config: Release
|
|
archive:
|
|
config: Release
|