apphx 1.0.0 → 2.0.0

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.
Files changed (126) hide show
  1. package/README.md +52 -138
  2. package/benchmarks/peer-context-worker.mjs +186 -0
  3. package/benchmarks/peer-context.mjs +150 -0
  4. package/dist/apple-types.js.map +1 -1
  5. package/dist/cli.js +373 -121
  6. package/dist/cli.js.map +1 -1
  7. package/dist/config.js +42 -4
  8. package/dist/config.js.map +1 -1
  9. package/dist/dependencies.js +455 -16
  10. package/dist/dependencies.js.map +1 -1
  11. package/dist/export-options.js +44 -2
  12. package/dist/export-options.js.map +1 -1
  13. package/dist/flutter.js +13 -25
  14. package/dist/flutter.js.map +1 -1
  15. package/dist/go-dependencies.js +389 -0
  16. package/dist/go-dependencies.js.map +1 -0
  17. package/dist/inbox.js +7 -8
  18. package/dist/inbox.js.map +1 -1
  19. package/dist/integrations.js +29 -29
  20. package/dist/integrations.js.map +1 -1
  21. package/dist/isolation.js +190 -0
  22. package/dist/isolation.js.map +1 -0
  23. package/dist/macos.js +57 -0
  24. package/dist/macos.js.map +1 -0
  25. package/dist/mygo-build.js +55 -0
  26. package/dist/mygo-build.js.map +1 -0
  27. package/dist/policy.js +35 -0
  28. package/dist/policy.js.map +1 -0
  29. package/dist/preflight.js +1 -1
  30. package/dist/process.js +3 -3
  31. package/dist/project-profiles.js +163 -0
  32. package/dist/project-profiles.js.map +1 -0
  33. package/dist/proof.js +33 -0
  34. package/dist/proof.js.map +1 -0
  35. package/dist/remote.js +1 -1
  36. package/dist/runner.js +269 -287
  37. package/dist/runner.js.map +1 -1
  38. package/dist/scheduler.js +0 -3
  39. package/dist/scheduler.js.map +1 -1
  40. package/dist/schemas.js +156 -44
  41. package/dist/schemas.js.map +1 -1
  42. package/dist/store.js +166 -44
  43. package/dist/store.js.map +1 -1
  44. package/dist/vendor/obfuscator/dist/cli.js +72 -0
  45. package/dist/vendor/obfuscator/dist/cli.js.map +1 -0
  46. package/dist/vendor/obfuscator/dist/code.js +585 -0
  47. package/dist/vendor/obfuscator/dist/code.js.map +1 -0
  48. package/dist/vendor/obfuscator/dist/common.js +262 -0
  49. package/dist/vendor/obfuscator/dist/common.js.map +1 -0
  50. package/dist/vendor/obfuscator/dist/config.js +123 -0
  51. package/dist/vendor/obfuscator/dist/config.js.map +1 -0
  52. package/dist/vendor/obfuscator/dist/content.js +89 -0
  53. package/dist/vendor/obfuscator/dist/content.js.map +1 -0
  54. package/dist/vendor/obfuscator/dist/obfuscate.js +93 -0
  55. package/dist/vendor/obfuscator/dist/obfuscate.js.map +1 -0
  56. package/dist/vendor/obfuscator/dist/png.js +283 -0
  57. package/dist/vendor/obfuscator/dist/png.js.map +1 -0
  58. package/dist/vendor/obfuscator/dist/project.js +159 -0
  59. package/dist/vendor/obfuscator/dist/project.js.map +1 -0
  60. package/dist/vendor/obfuscator/dist/resources.js +335 -0
  61. package/dist/vendor/obfuscator/dist/resources.js.map +1 -0
  62. package/dist/vendor/obfuscator/package.json +22 -0
  63. package/dist/workspace.js +113 -0
  64. package/dist/workspace.js.map +1 -0
  65. package/evals/control.mjs +73 -0
  66. package/evals/expectations.mjs +37 -0
  67. package/evals/host.mjs +51 -0
  68. package/evals/oracle.mjs +80 -0
  69. package/evals/policy.mjs +268 -0
  70. package/examples/android-java.factory.json +18 -0
  71. package/examples/android-java.json +16 -0
  72. package/examples/existing-project.factory.json +18 -0
  73. package/examples/existing-project.json +17 -0
  74. package/examples/expo.eas.json +17 -0
  75. package/examples/expo.factory.json +18 -0
  76. package/examples/expo.json +16 -0
  77. package/examples/factory.json +0 -2
  78. package/examples/flutter.factory.json +13 -0
  79. package/examples/flutter.json +16 -0
  80. package/examples/luggage.json +5 -3
  81. package/examples/mygo-web.factory.json +18 -0
  82. package/examples/mygo-web.json +16 -0
  83. package/examples/mygo.factory.json +18 -0
  84. package/examples/mygo.json +16 -0
  85. package/examples/react-native.factory.json +18 -0
  86. package/examples/react-native.json +16 -0
  87. package/examples/remote.json +1 -1
  88. package/examples/runtime/android-java/app/build.gradle +7 -0
  89. package/examples/runtime/android-java/app/src/main/AndroidManifest.xml +8 -0
  90. package/examples/runtime/android-java/app/src/main/java/dev/apphx/runtime/MainActivity.java +44 -0
  91. package/examples/runtime/android-java/sdk-build.mjs +29 -0
  92. package/examples/runtime/android-java/settings.gradle +2 -0
  93. package/examples/runtime/android-ui.mjs +70 -0
  94. package/examples/runtime/mygo-native/go.mod +13 -0
  95. package/examples/runtime/mygo-native/go.sum +10 -0
  96. package/examples/runtime/mygo-native/main.go +173 -0
  97. package/examples/runtime/mygo-native/main_test.go +14 -0
  98. package/examples/runtime/mygo-native/mygo.json +1 -0
  99. package/examples/runtime/mygo-web/bun.lock +15 -0
  100. package/examples/runtime/mygo-web/go.mod +9 -0
  101. package/examples/runtime/mygo-web/go.sum +8 -0
  102. package/examples/runtime/mygo-web/index.html +1 -0
  103. package/examples/runtime/mygo-web/main.go +60 -0
  104. package/examples/runtime/mygo-web/mygo.config.ts +10 -0
  105. package/examples/runtime/mygo-web/package.json +1 -0
  106. package/examples/runtime/mygo-web/src/main.ts +23 -0
  107. package/examples/runtime/mygo-web/src/mygo.ts +14 -0
  108. package/examples/swift.factory.json +18 -0
  109. package/examples/swift.json +16 -0
  110. package/examples/uni-app.factory.json +18 -0
  111. package/examples/uni-app.json +16 -0
  112. package/package.json +12 -5
  113. package/scripts/bundle-obfuscator.mjs +19 -0
  114. package/scripts/runtime-smoke.mjs +209 -0
  115. package/skills/apphx/SKILL.md +180 -0
  116. package/skills/apphx/resources/google-play-research-result.json +6 -0
  117. package/skills/apphx/resources/local-research-result.json +6 -0
  118. package/skills/{apple-app-factory → apphx}/resources/requirement.json +5 -8
  119. package/skills/apphx/resources/research-result.json +12 -0
  120. package/skills/apphx/resources/review-result.json +7 -0
  121. package/dist/apple.js +0 -900
  122. package/dist/apple.js.map +0 -1
  123. package/skills/apple-app-factory/SKILL.md +0 -103
  124. package/skills/apple-app-factory/resources/research-result.json +0 -21
  125. package/skills/apple-app-factory/resources/review-result.json +0 -7
  126. /package/skills/{apple-app-factory → apphx}/LICENSE +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"dependencies.js","names":[],"sources":["../src/dependencies.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { isAbsolute, join, relative, resolve, sep } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport { createHash } from 'node:crypto';\nimport { parseDocument } from 'yaml';\nimport { canonicalPath, inside } from './config.js';\n\nexport const GENERATED_PATHS = new Set([\n '.git', '.dart_tool', '.idea', '.factory-input', '.factory-cache', 'build',\n '.flutter-plugins-dependencies', 'ios/Pods', 'ios/.symlinks',\n 'ios/Flutter/Generated.xcconfig', 'ios/Flutter/flutter_export_environment.sh', 'ios/Flutter/ephemeral',\n]);\n\nexport function isGeneratedPath(path: string): boolean {\n let candidate = sep === '/' ? path : path.split(sep).join('/');\n while (candidate) {\n if (GENERATED_PATHS.has(candidate)) return true;\n const slash = candidate.lastIndexOf('/');\n if (slash < 0) return false;\n candidate = candidate.slice(0, slash);\n }\n return false;\n}\n\nfunction mapping(value: unknown, path: string): Record<string, unknown> {\n if (value === undefined || value === null) return {};\n if (typeof value !== 'object' || Array.isArray(value)) throw new Error(`Expected a YAML mapping in ${path}; run flutter pub get after repairing the dependency metadata`);\n return value as Record<string, unknown>;\n}\n\nfunction yaml(path: string): Record<string, unknown> {\n const document = parseDocument(readFileSync(path, 'utf8'));\n if (document.errors.length) throw new Error(`Cannot parse dependency metadata at ${path}: ${document.errors.map(error => error.message).join('; ')}`);\n return mapping(document.toJS(), path);\n}\n\nexport function validateLocalDependencies(root: string): void {\n const manifest = join(root, 'pubspec.yaml');\n if (!existsSync(manifest)) return;\n const workspace = canonicalPath(root);\n const rootSpec = yaml(manifest);\n const overridesFile = join(root, 'pubspec_overrides.yaml');\n const overrides = {\n ...mapping(rootSpec.dependency_overrides, manifest),\n ...mapping(existsSync(overridesFile) ? yaml(overridesFile).dependency_overrides : undefined, overridesFile),\n };\n const localPackages = new Map<string, string>();\n const immutablePackages = new Set<string>();\n const visited = new Set<string>();\n\n function owned(path: string): string {\n const absolute = resolve(path);\n const lexical = relative(resolve(root), absolute);\n const actual = relative(workspace, canonicalPath(absolute));\n if (isAbsolute(lexical) || lexical === '..' || lexical.startsWith(`..${sep}`) || isAbsolute(actual) || actual === '..' || actual.startsWith(`..${sep}`) || isGeneratedPath(lexical) || isGeneratedPath(actual)) {\n throw new Error(`Local dependency ${path} is outside fingerprinted workspace source; move the package into a non-generated workspace directory and run flutter pub get`);\n }\n if (lexical) inside(root, absolute);\n return absolute;\n }\n\n function pathDependency(name: string, value: unknown, directory: string): void {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return;\n const dependency = value as Record<string, unknown>;\n if (!Object.hasOwn(dependency, 'path')) return;\n if (typeof dependency.path !== 'string' || !dependency.path) throw new Error(`Local dependency ${name} in ${join(directory, 'pubspec.yaml')} requires a nonempty path`);\n if (isAbsolute(dependency.path)) throw new Error(`Local dependency ${name} in ${join(directory, 'pubspec.yaml')} requires a workspace-relative path so verified source can be copied to a successor`);\n const packageRoot = owned(resolve(directory, dependency.path));\n const previous = localPackages.get(name);\n if (previous && canonicalPath(previous) !== canonicalPath(packageRoot)) throw new Error(`Local dependency ${name} resolves to conflicting package directories; run flutter pub get before verification`);\n localPackages.set(name, packageRoot);\n visit(packageRoot, false);\n }\n\n function visit(directory: string, isRoot: boolean): void {\n directory = owned(directory);\n if (visited.has(directory)) return;\n visited.add(directory);\n const path = join(directory, 'pubspec.yaml');\n const spec = isRoot ? rootSpec : yaml(path);\n const dependencies = { ...mapping(spec.dependencies, path), ...(isRoot ? mapping(spec.dev_dependencies, path) : {}) };\n for (const [name, dependency] of Object.entries(dependencies)) {\n const overridden = Object.hasOwn(overrides, name);\n pathDependency(name, overridden ? overrides[name] : dependency, overridden ? root : directory);\n }\n }\n\n\n visit(root, true);\n const lockFile = join(root, 'pubspec.lock');\n if (existsSync(lockFile)) {\n const packages = mapping(yaml(lockFile).packages, lockFile);\n for (const [name, value] of Object.entries(packages)) {\n const entry = mapping(value, lockFile);\n if (entry.source === 'path') {\n const description = mapping(entry.description, lockFile);\n pathDependency(name, { path: description.path }, root);\n } else if (entry.source === 'hosted' || entry.source === 'sdk' || entry.source === 'git') immutablePackages.add(name);\n }\n }\n\n const packageConfig = join(root, '.dart_tool', 'package_config.json');\n if (!existsSync(packageConfig)) return;\n const config: unknown = JSON.parse(readFileSync(packageConfig, 'utf8'));\n const packages = mapping(config, packageConfig).packages;\n if (!Array.isArray(packages)) throw new Error(`Invalid package resolution at ${packageConfig}; run flutter pub get before verification`);\n for (const value of packages) {\n const entry = mapping(value, packageConfig);\n if (typeof entry.name !== 'string' || typeof entry.rootUri !== 'string') throw new Error(`Invalid package resolution at ${packageConfig}; run flutter pub get before verification`);\n if (immutablePackages.has(entry.name) && !localPackages.has(entry.name)) continue;\n const uri = new URL(entry.rootUri, pathToFileURL(packageConfig));\n if (uri.protocol !== 'file:') throw new Error(`Cannot establish local package source for ${entry.name} in ${packageConfig}; run flutter pub get before verification`);\n const packageRoot = owned(fileURLToPath(uri));\n const declared = localPackages.get(entry.name);\n if (declared && canonicalPath(declared) !== canonicalPath(packageRoot)) throw new Error(`Resolved local dependency ${entry.name} differs from its declared path; run flutter pub get before verification`);\n visit(packageRoot, canonicalPath(packageRoot) === workspace);\n }\n}\n\nexport function dependencyDigest(root: string): string {\n const path = join(root, '.dart_tool', 'package_config.json');\n const hash = createHash('sha256').update('factory-dependency-resolution-v1\\0');\n if (!existsSync(path)) return hash.update('missing').digest('hex');\n const config: unknown = JSON.parse(readFileSync(path, 'utf8'));\n const invalid = () => new Error(`Invalid package resolution at ${path}; run flutter pub get before verification`);\n if (!config || typeof config !== 'object' || Array.isArray(config)) throw invalid();\n const metadata = config as Record<string, unknown>;\n if (!Number.isInteger(metadata.configVersion) || !Array.isArray(metadata.packages)) throw invalid();\n const names = new Set<string>();\n\n function normalized(uri: URL): string {\n if (uri.protocol !== 'file:') return uri.href;\n const canonical = pathToFileURL(canonicalPath(fileURLToPath(uri)));\n if (uri.pathname.endsWith('/') && !canonical.pathname.endsWith('/')) canonical.pathname += '/';\n canonical.search = uri.search;\n canonical.hash = uri.hash;\n return canonical.href;\n }\n\n const packages = metadata.packages.map((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw invalid();\n const entry = value as Record<string, unknown>;\n if (typeof entry.name !== 'string' || !entry.name || names.has(entry.name) || typeof entry.rootUri !== 'string' || (entry.packageUri !== undefined && typeof entry.packageUri !== 'string') || (entry.languageVersion !== undefined && typeof entry.languageVersion !== 'string')) throw invalid();\n names.add(entry.name);\n const rootUri = new URL(entry.rootUri, pathToFileURL(path));\n // Dart treats both URI fields as directories even without a trailing slash.\n if (!rootUri.pathname.endsWith('/')) rootUri.pathname += '/';\n const packageUri = new URL(entry.packageUri ?? '', rootUri);\n if (!packageUri.pathname.endsWith('/')) packageUri.pathname += '/';\n return { name: entry.name, rootUri: normalized(rootUri), packageUri: normalized(packageUri), languageVersion: entry.languageVersion ?? null };\n }).sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);\n return hash.update(JSON.stringify({ configVersion: metadata.configVersion, packages })).digest('hex');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dependencies.js","names":[],"sources":["../src/dependencies.ts"],"sourcesContent":["import { existsSync, lstatSync, readFileSync, readdirSync } from 'node:fs';\nimport { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport { createHash } from 'node:crypto';\nimport { parseDocument } from 'yaml';\nimport { canonicalPath, inside } from './config.js';\nimport type { Framework } from './schemas.js';\nimport { goDependencyInputs } from './go-dependencies.js';\n\nexport const GENERATED_PATHS = new Set([\n '.git', '.dart_tool', '.idea', '.factory-input', '.factory-cache', 'build',\n '.flutter-plugins-dependencies', 'ios/Pods', 'ios/.symlinks',\n 'ios/Flutter/Generated.xcconfig', 'ios/Flutter/flutter_export_environment.sh', 'ios/Flutter/ephemeral',\n]);\n\nexport function isGeneratedPath(path: string, framework?: Framework): boolean {\n let candidate = sep === '/' ? path : path.split(sep).join('/');\n candidate = candidate.replace(/^\\.\\//, '').replace(/\\/$/, '');\n const parts = candidate.split('/');\n if (framework === 'mygo') {\n // MyGo owns only its actual caches and root/selected-project outputs. In\n // particular lib/build, Pods, .build and .gradle remain ordinary source.\n return ['.git', '.idea', '.factory-input', '.factory-cache', 'build', 'dist'].includes(parts[0]!)\n || parts.includes('.mygo') || parts.includes('node_modules')\n || parts.some((part, index) => part === '.yarn' && ['cache', 'unplugged', 'install-state.gz'].includes(parts[index + 1] ?? ''));\n }\n if (framework === 'flutter' && (parts.includes('.dart_tool') || parts.includes('.gradle'))) return true;\n // Exclusions are anchored: owned paths such as lib/build remain source.\n if (['.git', '.idea', '.factory-input', '.factory-cache', 'build'].includes(parts[0]!)) return true;\n if (framework && framework !== 'flutter') {\n const javascript = framework === 'react-native' || framework === 'expo' || framework === 'uni-app';\n if (javascript && parts.includes('node_modules')) return true;\n if (framework !== 'swift' && parts.includes('.gradle')) return true;\n if (framework !== 'android-java' && parts.includes('Pods')) return true;\n if (framework !== 'android-java' && (parts.includes('.build') || parts[0] === 'DerivedData')) return true;\n if (framework !== 'swift' && /^(?:android\\/)?(?:app\\/)?build(?:\\/|$)/.test(candidate)) return true;\n if (framework !== 'android-java' && /^ios\\/(?:build|DerivedData)(?:\\/|$)/.test(candidate)) return true;\n if (javascript && /^\\.yarn\\/(?:cache|unplugged|install-state\\.gz)(?:\\/|$)/.test(candidate)) return true;\n if (framework === 'expo' && /^\\.expo(?:\\/|$)/.test(candidate)) return true;\n if (framework === 'uni-app' && /^(?:unpackage|dist)(?:\\/|$)/.test(candidate)) return true;\n return false;\n }\n while (candidate) {\n if (GENERATED_PATHS.has(candidate)) return true;\n const slash = candidate.lastIndexOf('/');\n if (slash < 0) return false;\n candidate = candidate.slice(0, slash);\n }\n return false;\n}\n\nfunction manifestCode(path: string, ruby = false): string {\n return readFileSync(path, 'utf8').replace(/\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|\\/\\*[\\s\\S]*?\\*\\/|\\/\\/[^\\r\\n]*|#[^\\r\\n]*/g, token => {\n if (token.startsWith('\"') || token.startsWith(\"'\") || (token.startsWith('#') && !ruby)) return token;\n return ' ';\n });\n}\n\n// Consume complete literals before looking for declarations, including multiline\n// Gradle diagnostics. Their contents never establish source ownership.\nconst GRADLE_TOKENS = /\"\"\"[\\s\\S]*?\"\"\"|'''[\\s\\S]*?'''|\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|\\/\\*[\\s\\S]*?\\*\\/|\\/\\/[^\\r\\n]*/g;\nfunction gradleCode(path: string): string {\n return readFileSync(path, 'utf8').replace(GRADLE_TOKENS, token =>\n token.startsWith('/') ? token.replace(/[^\\r\\n]/g, ' ') : token);\n}\nfunction gradlePattern(expression: RegExp): RegExp {\n return new RegExp(`${GRADLE_TOKENS.source}|${expression.source}`, 'g');\n}\n\n/** Workspace-relative build outputs for statically declared, real Gradle modules. */\nexport function generatedModulePaths(root: string, framework: Framework, directory = '.'): ReadonlySet<string> {\n if (!['android-java', 'react-native', 'expo', 'uni-app'].includes(framework)) return new Set<string>();\n const outputs = new Set<string>();\n const visited = new Set<string>();\n function underOutput(path: string): boolean {\n const portable = path.split(sep).join('/');\n for (const output of outputs) if (portable === output || portable.startsWith(`${output}/`)) return true;\n return false;\n }\n function registerBuildOutput(absolute: string): void {\n for (const build of ['build.gradle', 'build.gradle.kts']) {\n const manifest = join(absolute, build);\n const stat = lstatSync(manifest, { throwIfNoEntry: false });\n if (stat?.isSymbolicLink()) throw new Error(`Gradle module manifest cannot be a symlink: ${manifest}`);\n if (stat?.isFile()) outputs.add(relative(root, join(absolute, 'build')).split(sep).join('/'));\n }\n }\n function visit(current: string): void {\n current = resolve(current);\n if (visited.has(current)) return;\n if (current !== resolve(root)) inside(root, current);\n const path = relative(root, current);\n if (generatedInProject(path, framework, directory) || underOutput(path)) return;\n if (path !== relative(canonicalPath(root), canonicalPath(current))) throw new Error(`Gradle build directory cannot be a source symlink: ${current}`);\n visited.add(current);\n registerBuildOutput(current);\n for (const name of ['settings.gradle', 'settings.gradle.kts']) {\n const settings = join(current, name);\n const stat = lstatSync(settings, { throwIfNoEntry: false });\n if (!stat) continue;\n if (!stat.isFile() || stat.isSymbolicLink()) throw new Error(`Gradle settings must be a regular source file: ${settings}`);\n const text = gradleCode(settings);\n const modules = new Map<string, string>();\n for (const include of text.matchAll(gradlePattern(/\\binclude\\s*(?:\\(([^)]*)\\)|([^\\r\\n;]+))/))) {\n const argumentsText = include[1] ?? include[2];\n if (argumentsText === undefined || !/^\\s*(?:(?:\"[:\\w.-]+\"|'[:\\w.-]+')\\s*,?\\s*)+$/.test(argumentsText)) continue;\n for (const match of argumentsText.matchAll(/[\"'](:?[\\w.-]+(?::[\\w.-]+)*)[\"']/g)) {\n const id = match[1]!.replace(/^:/, '');\n modules.set(id, id.split(':').join('/'));\n }\n }\n for (const match of text.matchAll(gradlePattern(/\\bproject\\s*\\(\\s*[\"'](:?[\\w.-]+(?::[\\w.-]+)*)[\"']\\s*\\)\\s*\\.projectDir\\s*=\\s*file\\s*\\(\\s*(?:\"([^\"\\\\$]+)\"|'([^'\\\\]+)')\\s*\\)/))) {\n if (match[1] === undefined) continue;\n const id = match[1].replace(/^:/, '');\n if (modules.has(id)) modules.set(id, (match[2] ?? match[3])!);\n }\n for (const module of modules.values()) {\n if (isAbsolute(module)) throw new Error(`Gradle module requires a workspace-relative path: ${module}`);\n const absolute = resolve(current, module);\n inside(root, absolute);\n if (relative(resolve(root), absolute) !== relative(canonicalPath(root), canonicalPath(absolute))) throw new Error(`Gradle module directory cannot be a source symlink: ${module}`);\n registerBuildOutput(absolute);\n }\n for (const match of text.matchAll(gradlePattern(/\\bincludeBuild\\s*\\(?\\s*(?:\"([^\"\\\\$]+)\"|'([^'\\\\]+)')/))) {\n const included = match[1] ?? match[2];\n if (included === undefined) continue;\n if (isAbsolute(included)) throw new Error(`Included Gradle build requires a workspace-relative path: ${included}`);\n visit(resolve(current, included));\n }\n }\n }\n visit(root);\n const project = projectRoot(root, directory);\n visit(project);\n visit(join(project, 'android'));\n return outputs;\n}\n\nfunction mapping(value: unknown, path: string): Record<string, unknown> {\n if (value === undefined || value === null) return {};\n if (typeof value !== 'object' || Array.isArray(value)) throw new Error(`Expected a YAML mapping in ${path}; run flutter pub get after repairing the dependency metadata`);\n return value as Record<string, unknown>;\n}\n\nfunction yaml(path: string): Record<string, unknown> {\n const document = parseDocument(readFileSync(path, 'utf8'));\n if (document.errors.length) throw new Error(`Cannot parse dependency metadata at ${path}: ${document.errors.map(error => error.message).join('; ')}`);\n return mapping(document.toJS(), path);\n}\n\nfunction validateFlutterDependencies(root: string, project = root): void {\n const manifest = join(project, 'pubspec.yaml');\n if (!existsSync(manifest)) return;\n const workspace = canonicalPath(root);\n const rootSpec = yaml(manifest);\n const overridesFile = join(project, 'pubspec_overrides.yaml');\n const overrides = {\n ...mapping(rootSpec.dependency_overrides, manifest),\n ...mapping(existsSync(overridesFile) ? yaml(overridesFile).dependency_overrides : undefined, overridesFile),\n };\n const localPackages = new Map<string, string>();\n const immutablePackages = new Set<string>();\n const visited = new Set<string>();\n\n function owned(path: string): string {\n const absolute = resolve(path);\n const lexical = relative(resolve(root), absolute);\n const actual = relative(workspace, canonicalPath(absolute));\n if (isAbsolute(lexical) || lexical === '..' || lexical.startsWith(`..${sep}`) || isAbsolute(actual) || actual === '..' || actual.startsWith(`..${sep}`) || lexical !== actual || generatedInProject(lexical, 'flutter', relative(root, project)) || generatedInProject(actual, 'flutter', relative(root, project))) {\n throw new Error(`Local dependency ${path} is outside fingerprinted workspace source; move the package into a non-generated workspace directory and run flutter pub get`);\n }\n if (lexical) inside(root, absolute);\n return absolute;\n }\n\n function pathDependency(name: string, value: unknown, directory: string): void {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return;\n const dependency = value as Record<string, unknown>;\n if (!Object.hasOwn(dependency, 'path')) return;\n if (typeof dependency.path !== 'string' || !dependency.path) throw new Error(`Local dependency ${name} in ${join(directory, 'pubspec.yaml')} requires a nonempty path`);\n if (isAbsolute(dependency.path)) throw new Error(`Local dependency ${name} in ${join(directory, 'pubspec.yaml')} requires a workspace-relative path so verified source can be copied to a successor`);\n const packageRoot = owned(resolve(directory, dependency.path));\n const previous = localPackages.get(name);\n if (previous && canonicalPath(previous) !== canonicalPath(packageRoot)) throw new Error(`Local dependency ${name} resolves to conflicting package directories; run flutter pub get before verification`);\n localPackages.set(name, packageRoot);\n visit(packageRoot, false);\n }\n\n function visit(directory: string, isRoot: boolean): void {\n directory = owned(directory);\n if (visited.has(directory)) return;\n visited.add(directory);\n const path = join(directory, 'pubspec.yaml');\n const spec = isRoot ? rootSpec : yaml(path);\n const dependencies = { ...mapping(spec.dependencies, path), ...(isRoot ? mapping(spec.dev_dependencies, path) : {}) };\n for (const [name, dependency] of Object.entries(dependencies)) {\n const overridden = Object.hasOwn(overrides, name);\n pathDependency(name, overridden ? overrides[name] : dependency, overridden ? project : directory);\n }\n }\n\n\n visit(project, true);\n const lockFile = join(project, 'pubspec.lock');\n if (existsSync(lockFile)) {\n const packages = mapping(yaml(lockFile).packages, lockFile);\n for (const [name, value] of Object.entries(packages)) {\n const entry = mapping(value, lockFile);\n if (entry.source === 'path') {\n const description = mapping(entry.description, lockFile);\n pathDependency(name, { path: description.path }, project);\n } else if (entry.source === 'hosted' || entry.source === 'sdk' || entry.source === 'git') immutablePackages.add(name);\n }\n }\n\n const packageConfig = join(project, '.dart_tool', 'package_config.json');\n if (!existsSync(packageConfig)) return;\n const config: unknown = JSON.parse(readFileSync(packageConfig, 'utf8'));\n const packages = mapping(config, packageConfig).packages;\n if (!Array.isArray(packages)) throw new Error(`Invalid package resolution at ${packageConfig}; run flutter pub get before verification`);\n for (const value of packages) {\n const entry = mapping(value, packageConfig);\n if (typeof entry.name !== 'string' || typeof entry.rootUri !== 'string') throw new Error(`Invalid package resolution at ${packageConfig}; run flutter pub get before verification`);\n if (immutablePackages.has(entry.name) && !localPackages.has(entry.name)) continue;\n const uri = new URL(entry.rootUri, pathToFileURL(packageConfig));\n if (uri.protocol !== 'file:') throw new Error(`Cannot establish local package source for ${entry.name} in ${packageConfig}; run flutter pub get before verification`);\n const packageRoot = owned(fileURLToPath(uri));\n const declared = localPackages.get(entry.name);\n if (declared && canonicalPath(declared) !== canonicalPath(packageRoot)) throw new Error(`Resolved local dependency ${entry.name} differs from its declared path; run flutter pub get before verification`);\n visit(packageRoot, canonicalPath(packageRoot) === canonicalPath(project));\n }\n}\n\nfunction flutterDependencyDigest(root: string): string {\n const path = join(root, '.dart_tool', 'package_config.json');\n const hash = createHash('sha256').update('factory-dependency-resolution-v1\\0');\n if (!existsSync(path)) return hash.update('missing').digest('hex');\n const config: unknown = JSON.parse(readFileSync(path, 'utf8'));\n const invalid = () => new Error(`Invalid package resolution at ${path}; run flutter pub get before verification`);\n if (!config || typeof config !== 'object' || Array.isArray(config)) throw invalid();\n const metadata = config as Record<string, unknown>;\n if (!Number.isInteger(metadata.configVersion) || !Array.isArray(metadata.packages)) throw invalid();\n const names = new Set<string>();\n\n function normalized(uri: URL): string {\n if (uri.protocol !== 'file:') return uri.href;\n const canonical = pathToFileURL(canonicalPath(fileURLToPath(uri)));\n if (uri.pathname.endsWith('/') && !canonical.pathname.endsWith('/')) canonical.pathname += '/';\n canonical.search = uri.search;\n canonical.hash = uri.hash;\n return canonical.href;\n }\n\n const packages = metadata.packages.map((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw invalid();\n const entry = value as Record<string, unknown>;\n if (typeof entry.name !== 'string' || !entry.name || names.has(entry.name) || typeof entry.rootUri !== 'string' || (entry.packageUri !== undefined && typeof entry.packageUri !== 'string') || (entry.languageVersion !== undefined && typeof entry.languageVersion !== 'string')) throw invalid();\n names.add(entry.name);\n const rootUri = new URL(entry.rootUri, pathToFileURL(path));\n // Dart treats both URI fields as directories even without a trailing slash.\n if (!rootUri.pathname.endsWith('/')) rootUri.pathname += '/';\n const packageUri = new URL(entry.packageUri ?? '', rootUri);\n if (!packageUri.pathname.endsWith('/')) packageUri.pathname += '/';\n return { name: entry.name, rootUri: normalized(rootUri), packageUri: normalized(packageUri), languageVersion: entry.languageVersion ?? null };\n }).sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);\n return hash.update(JSON.stringify({ configVersion: metadata.configVersion, packages })).digest('hex');\n}\n\nfunction projectRoot(root: string, directory = '.'): string {\n if (isAbsolute(directory)) throw new Error('Project directory must be workspace-relative');\n const project = resolve(root, directory);\n if (project !== resolve(root)) inside(root, project);\n return project;\n}\n\nfunction generatedInProject(path: string, framework: Framework, directory = '.'): boolean {\n if (isGeneratedPath(path, framework)) return true;\n const nested = relative(directory, path);\n return nested !== '..' && !nested.startsWith(`..${sep}`) && !isAbsolute(nested) && isGeneratedPath(nested, framework);\n}\n\nfunction sourceFiles(root: string, framework: Framework, activeDirectory: string, resolutions: string[], moduleOutputs: readonly string[]): string[] {\n const files: string[] = [];\n function visit(directory: string): void {\n for (const entry of readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {\n const absolute = join(directory, entry.name);\n const path = relative(root, absolute);\n const portable = path.split(sep).join('/');\n if (generatedInProject(path, framework, activeDirectory) || moduleOutputs.some(output => portable === output || portable.startsWith(`${output}/`))) {\n if (entry.isDirectory()) {\n const records = entry.name === 'node_modules' ? ['.package-lock.json', '.modules.yaml', '.pnpm/lock.yaml']\n : entry.name === 'Pods' ? ['Manifest.lock']\n : entry.name === '.build' ? ['workspace-state.json']\n : entry.name === 'build' ? ['SourcePackages/workspace-state.json', 'DerivedData/SourcePackages/workspace-state.json']\n : entry.name === 'DerivedData' ? ['SourcePackages/workspace-state.json'] : [];\n for (const record of records) {\n const metadata = join(absolute, record);\n const stat = lstatSync(metadata, { throwIfNoEntry: false });\n if (stat && relative(canonicalPath(root), canonicalPath(metadata)) !== relative(resolve(root), metadata)) throw new Error(`Dependency resolution metadata cannot traverse a source symlink: ${metadata}`);\n if (stat?.isSymbolicLink()) throw new Error(`Dependency resolution metadata cannot be a symlink: ${metadata}`);\n if (stat) resolutions.push(join(path, record));\n }\n }\n if (entry.isFile() && entry.name === 'install-state.gz') resolutions.push(path);\n continue;\n }\n const stat = lstatSync(absolute);\n if (stat.isSymbolicLink()) throw new Error(`Source symlinks are not trusted dependency inputs: ${path}`);\n if (stat.isDirectory()) visit(absolute);\n else if (stat.isFile()) files.push(path);\n else throw new Error(`Dependency input must be a regular source file: ${path}`);\n }\n }\n visit(root);\n return files;\n}\n\nfunction object(value: unknown, path: string): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`Invalid dependency metadata at ${path}`);\n return value as Record<string, unknown>;\n}\n\nfunction dependencyInputs(root: string, framework: Framework, activeDirectory = '.'): { files: string[]; local: Set<string>; resolutions: string[]; goFiles?: ReadonlySet<string> } {\n projectRoot(root, activeDirectory);\n const resolutions: string[] = [];\n const moduleOutputs = [...generatedModulePaths(root, framework, activeDirectory)];\n const files = sourceFiles(root, framework, activeDirectory, resolutions, moduleOutputs);\n const go = framework === 'mygo' ? goDependencyInputs(root, activeDirectory, path => generatedInProject(path, framework, activeDirectory)) : undefined;\n const javascriptActive = framework !== 'mygo' || ['package.json', 'frontend/package.json'].some(path => existsSync(join(root, activeDirectory, path)));\n const local = new Set<string>(go?.local);\n const packages = new Map<string, string>();\n for (const path of files.filter(path => javascriptActive && basename(path) === 'package.json')) {\n const pkg = object(JSON.parse(readFileSync(join(root, path), 'utf8')), path);\n if (typeof pkg.name === 'string') packages.set(pkg.name, dirname(path));\n }\n function owned(value: string, directory: string, native = false): void {\n if (!value || isAbsolute(value) || /^[a-z]:[\\\\/]/i.test(value)) throw new Error(`Local dependency requires a workspace-relative path: ${value}`);\n const absolute = resolve(root, directory, value);\n const path = relative(resolve(root), absolute);\n if (path === '..' || path.startsWith(`..${sep}`) || isAbsolute(path)) throw new Error(`Local dependency escapes fingerprinted workspace source: ${value}`);\n if (path) inside(root, absolute);\n const portable = path.split(sep).join('/');\n if (generatedInProject(path, framework, activeDirectory) || moduleOutputs.some(output => portable === output || portable.startsWith(`${output}/`))) {\n // Native autolinking may reference installed JS packages before installation.\n // Their resolution locks, rather than generated cache source, carry authority.\n if (native && path.split(sep).includes('node_modules')) return;\n throw new Error(`Local dependency is outside fingerprinted workspace source: ${value}`);\n }\n if (!existsSync(absolute)) {\n if (native) return; // Optional native file collections may legitimately be empty.\n throw new Error(`Local dependency does not exist: ${value}`);\n }\n const actual = relative(canonicalPath(root), canonicalPath(absolute));\n if (path !== actual || lstatSync(absolute).isSymbolicLink()) throw new Error(`Local dependency source symlinks are not trusted: ${value}`);\n local.add(path);\n }\n function reference(value: unknown, directory: string, name?: string): void {\n if (typeof value !== 'string') return;\n const match = /^(?:file|link|portal):(.*)$/.exec(value);\n if (match) owned(decodeURIComponent(match[1]!), directory);\n else if (value.startsWith('.') || isAbsolute(value) || /^[a-z]:[\\\\/]/i.test(value)) owned(value, directory);\n else if (value.startsWith('workspace:')) {\n const target = name ? packages.get(name) : undefined;\n if (target === undefined) throw new Error(`Workspace dependency ${name ?? value} has no owned package manifest`);\n owned(relative(resolve(root, directory), resolve(root, target)) || '.', directory);\n }\n }\n function declarations(value: unknown, directory: string): void {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return;\n for (const [name, child] of Object.entries(value)) {\n if (typeof child === 'object') declarations(child, directory);\n else reference(child, directory, name);\n }\n }\n function npmResolutions(value: unknown, directory: string): void {\n if (!value || typeof value !== 'object') return;\n const entry = value as Record<string, unknown>;\n if (entry.link === true && typeof entry.resolved === 'string') owned(entry.resolved.replace(/^(?:file|link):/, ''), directory);\n for (const [key, child] of Object.entries(entry)) {\n if (key === 'resolved' || key === 'version') reference(child, directory);\n else if (child && typeof child === 'object') npmResolutions(child, directory);\n }\n }\n function pnpmResolutions(lock: Record<string, unknown>, directory: string, path: string): void {\n for (const [importer, value] of Object.entries(mapping(lock.importers, path))) {\n const base = relative(root, resolve(root, directory, importer));\n const spec = mapping(value, path);\n for (const field of ['dependencies', 'devDependencies', 'optionalDependencies']) {\n for (const [dependency, value] of Object.entries(mapping(spec[field], path))) {\n if (typeof value === 'string') reference(value, base, dependency);\n else {\n const resolution = mapping(value, path);\n reference(resolution.specifier, base, dependency);\n reference(resolution.version, base, dependency);\n }\n }\n }\n }\n for (const field of ['packages', 'snapshots']) {\n for (const [key, value] of Object.entries(mapping(lock[field], path))) {\n const local = /(?:file|link|portal):([^(:]+)/.exec(key);\n if (local) owned(decodeURIComponent(local[1]!), directory);\n const record = mapping(value, path);\n reference(mapping(record.resolution, path).tarball, directory);\n }\n }\n }\n for (const path of files) {\n const name = basename(path);\n const directory = dirname(path);\n if (framework === 'mygo' && (!javascriptActive || !['package.json', 'package-lock.json', 'npm-shrinkwrap.json', 'pnpm-lock.yaml', 'yarn.lock', 'bun.lock'].includes(name))) continue;\n if (name === 'package.json') {\n const pkg = object(JSON.parse(readFileSync(join(root, path), 'utf8')), path);\n for (const field of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies', 'overrides', 'resolutions']) declarations(pkg[field], directory);\n } else if (name === 'package-lock.json' || name === 'npm-shrinkwrap.json') {\n const lock = object(JSON.parse(readFileSync(join(root, path), 'utf8')), path);\n npmResolutions(lock, directory);\n } else if (name === 'pnpm-lock.yaml') {\n pnpmResolutions(yaml(join(root, path)), directory, path);\n } else if (['yarn.lock', 'bun.lock'].includes(name)) {\n const text = readFileSync(join(root, path), 'utf8');\n for (const match of text.matchAll(/(?:file|link|portal):([^\\s\"'`,}\\]]+)/g)) owned(decodeURIComponent(match[1]!.split('::')[0]!), directory);\n } else if (name === 'Package.swift') {\n const text = manifestCode(join(root, path));\n for (const match of text.matchAll(/\\.package\\s*\\(\\s*(?:name\\s*:\\s*\"[^\"]*\"\\s*,\\s*)?path\\s*:\\s*\"([^\"]+)\"/g)) owned(match[1]!, directory);\n for (const match of text.matchAll(/\\burl\\s*:\\s*\"([^\"]+)\"/g)) reference(match[1]!, directory);\n } else if (name === 'Podfile' || name.endsWith('.podspec')) {\n const text = manifestCode(join(root, path), true);\n for (const match of text.matchAll(/(?::(?:path|podspec)\\s*=>\\s*|(?:path|podspec)\\s*:\\s*)[\"']([^\"']+)[\"']/g)) owned(match[1]!, directory, true);\n for (const match of text.matchAll(/(?::git\\s*=>\\s*|git\\s*:\\s*)[\"']([^\"']+)[\"']/g)) reference(match[1]!, directory);\n } else if (name === 'Podfile.lock') {\n const lock = yaml(join(root, path));\n for (const value of Object.values(mapping(lock['EXTERNAL SOURCES'], path))) {\n const external = mapping(value, path);\n for (const field of [':path', ':podspec']) if (typeof external[field] === 'string') owned(external[field], directory, true);\n reference(external[':git'], directory);\n }\n } else if (name === 'project.pbxproj') {\n const text = manifestCode(join(root, path));\n for (const match of text.matchAll(/\\brelativePath\\s*=\\s*\"?([^;\"\\r\\n]+)\"?\\s*;/g)) owned(match[1]!.trim(), dirname(directory));\n } else if (/^(?:settings|build)\\.gradle(?:\\.kts)?$/.test(name)) {\n const text = gradleCode(join(root, path));\n for (const match of text.matchAll(gradlePattern(/\\b(?:includeBuild\\s*\\(?\\s*|projectDir\\s*=\\s*file\\s*\\(\\s*|fileTree\\s*\\(\\s*(?:dir\\s*[:=]\\s*)?)(?:\"([^\"\\\\$]+)\"|'([^'\\\\]+)')/))) {\n const value = match[1] ?? match[2];\n if (value !== undefined) owned(value, directory, true);\n }\n // Only literal collections establish local ownership. Gradle is executable;\n // dynamic expressions cannot be proven by this static dependency check.\n const collections = gradlePattern(/\\b(files|dirs)\\b\\s*(?:(\\()|(?=[\"']))/);\n const literalPath = /\"([^\"\\\\$]*)\"|'([^'\\\\]*)'/y;\n for (let match; (match = collections.exec(text));) {\n if (!match[1]) continue;\n let offset = collections.lastIndex;\n const parenthesized = Boolean(match[2]);\n const whitespace = parenthesized ? /\\s/ : /[ \\t]/;\n while (true) {\n while (offset < text.length && whitespace.test(text[offset]!)) offset++;\n if (parenthesized && text[offset] === ')') { offset++; break; }\n if (!parenthesized && (offset === text.length || /[\\r\\n;}]/.test(text[offset]!))) break;\n literalPath.lastIndex = offset;\n const literal = literalPath.exec(text);\n if (!literal) throw new Error(`Cannot prove Gradle ${match[1]} collection in ${path}: expected literal paths`);\n owned((literal[1] ?? literal[2])!, directory, true);\n offset = literalPath.lastIndex;\n while (offset < text.length && whitespace.test(text[offset]!)) offset++;\n if (text[offset] === ',') {\n offset++;\n while (offset < text.length && /\\s/.test(text[offset]!)) offset++;\n continue;\n }\n if (parenthesized && text[offset] === ')') { offset++; break; }\n if (!parenthesized && (offset === text.length || /[\\r\\n;}]/.test(text[offset]!))) break;\n throw new Error(`Cannot prove Gradle ${match[1]} collection in ${path}: expected literal paths`);\n }\n collections.lastIndex = offset;\n }\n for (const match of text.matchAll(gradlePattern(/\\burl\\s*(?:=\\s*)?(?:uri\\s*\\(?\\s*)?(?:\"([^\"\\\\$]+)\"|'([^'\\\\]+)')/))) {\n const value = match[1] ?? match[2];\n if (value === undefined) continue;\n if (/^[a-z][a-z0-9+.-]*:/i.test(value)) reference(value, directory);\n else owned(value, directory, true);\n }\n }\n }\n for (const path of resolutions) {\n const absolute = join(root, path);\n if (!existsSync(absolute)) continue;\n inside(root, absolute);\n if (!lstatSync(absolute).isFile() || lstatSync(absolute).isSymbolicLink()) throw new Error(`Dependency resolution metadata must be a regular file: ${path}`);\n if (basename(path) === '.package-lock.json') npmResolutions(object(JSON.parse(readFileSync(absolute, 'utf8')), path), dirname(dirname(path)));\n else if (path.endsWith(`${sep}.pnpm${sep}lock.yaml`)) pnpmResolutions(yaml(absolute), dirname(dirname(dirname(path))), path);\n else if (basename(path) === 'workspace-state.json') {\n const metadata = object(JSON.parse(readFileSync(absolute, 'utf8')), path);\n const state = metadata.object === undefined ? metadata : object(metadata.object, path);\n if (Array.isArray(state.dependencies)) {\n for (const value of state.dependencies) {\n const dependency = object(value, path);\n const reference = object(dependency.packageRef, path);\n if ((reference.kind === 'fileSystem' || reference.kind === 'localSourceControl') && typeof reference.location === 'string') {\n const location = isAbsolute(reference.location) ? relative(resolve(root), reference.location) : join(activeDirectory, reference.location);\n owned(location || '.', '.');\n }\n }\n }\n }\n }\n return { files, local, resolutions, ...(go ? { goFiles: go.files } : {}) };\n}\n\n/** Validate declarations before any source is granted verification authority. */\nexport function validateLocalDependencies(root: string, framework?: Framework, directory = '.'): void {\n if (framework === undefined || framework === 'flutter') {\n validateFlutterDependencies(root, projectRoot(root, directory));\n return;\n }\n dependencyInputs(root, framework, directory);\n}\n\nfunction resolutionMetadata(path: string, framework: Framework): boolean {\n const name = basename(path);\n if (framework === 'mygo') return ['package.json', 'package-lock.json', 'npm-shrinkwrap.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock', 'bun.lockb', '.pnp.cjs'].includes(name);\n return ['package.json', 'package-lock.json', 'npm-shrinkwrap.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock', 'bun.lockb', 'Podfile', 'Podfile.lock', 'Package.swift', 'Package.resolved', 'Cartfile', 'Cartfile.resolved', 'project.pbxproj', 'gradle.properties', 'gradle.lockfile', 'gradle-wrapper.properties', 'verification-metadata.xml', 'libs.versions.toml', '.pnp.cjs'].includes(name)\n || /\\.(?:gradle(?:\\.kts)?|podspec)$/.test(name) || path.includes('dependency-locks/');\n}\n\nexport function dependencyDigest(root: string, framework?: Framework, directory = '.'): string {\n // Keep the established normalized Dart resolution contract for standalone callers.\n if (framework === undefined || framework === 'flutter') return flutterDependencyDigest(projectRoot(root, directory));\n const { files, local, resolutions, goFiles } = dependencyInputs(root, framework, directory);\n const hash = createHash('sha256').update(`factory-dependency-resolution-v2\\0${framework}\\0`);\n function add(path: string): void {\n const content = readFileSync(join(root, path));\n hash.update(`${path.split(sep).join('/')}\\0${content.length}\\0`).update(content).update('\\0');\n }\n const localDirectories = [...local];\n for (const path of files) {\n if (goFiles?.has(path) || resolutionMetadata(path, framework) || localDirectories.some(directory => !directory || path === directory || path.startsWith(`${directory}${sep}`))) add(path);\n }\n if (goFiles) {\n const sourcePaths = new Set(files);\n for (const path of [...goFiles].sort()) {\n if (sourcePaths.has(path)) continue;\n const absolute = inside(root, path);\n const stat = lstatSync(absolute);\n if (!stat.isFile() || stat.isSymbolicLink()) throw new Error(`Generated frontend dependency must be a regular owned file: ${path}`);\n add(path);\n }\n }\n // Generated installation records are excluded from source proof, but changes to\n // effective resolution must still invalidate evidence.\n const installationRecords = [join(directory, '.yarn/install-state.gz'), join(directory, '.pnp.data.json')];\n if (framework === 'mygo') installationRecords.push(join(directory, 'frontend/.yarn/install-state.gz'), join(directory, 'frontend/.pnp.data.json'));\n for (const path of [...new Set([...resolutions, ...installationRecords])].sort()) {\n const absolute = join(root, path);\n if (!existsSync(absolute)) { hash.update(`${path}\\0missing\\0`); continue; }\n inside(root, absolute);\n if (!lstatSync(absolute).isFile() || lstatSync(absolute).isSymbolicLink()) throw new Error(`Dependency resolution metadata must be a regular file: ${path}`);\n add(path);\n }\n return hash.digest('hex');\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
- import { join } from "node:path";
3
2
  import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
+ import { basename, join, resolve } from "node:path";
4
4
  // src/export-options.ts
5
5
  const ExportOptionsSchema = z.object({ destination: z.literal("export").default("export") }).passthrough();
6
6
  async function prepareExportOptions(source, stateDir, run) {
@@ -44,6 +44,48 @@ async function prepareExportOptions(source, stateDir, run) {
44
44
  throw error;
45
45
  }
46
46
  }
47
- export { prepareExportOptions };
47
+ async function prepareNativeExportCommands(commands, cwd, stateDir, run) {
48
+ const prepared = commands.map((argv) => [...argv]);
49
+ const directories = [];
50
+ const readableFiles = [];
51
+ const cleanup = () => {
52
+ for (const directory of directories) rmSync(directory, {
53
+ recursive: true,
54
+ force: true
55
+ });
56
+ };
57
+ const ambiguous = () => Object.assign(/* @__PURE__ */ new Error("Native IPA export requires exactly one unambiguous -exportOptionsPlist path; use direct xcodebuild or xcrun xcodebuild arguments."), { code: "SETUP_REQUIRED" });
58
+ try {
59
+ for (const argv of prepared) {
60
+ const executable = basename(argv[0] ?? "");
61
+ const direct = executable === "xcodebuild";
62
+ const wrapped = executable === "xcrun" && basename(argv[1] ?? "") === "xcodebuild";
63
+ if (!direct && !wrapped) {
64
+ if (executable === "xcrun" && argv.some((value) => basename(value) === "xcodebuild") && argv.includes("-exportArchive")) throw ambiguous();
65
+ continue;
66
+ }
67
+ const args = argv.slice(wrapped ? 2 : 1);
68
+ if (!args.some((value) => value.startsWith("-exportArchive"))) continue;
69
+ if (args.filter((value) => value === "-exportArchive").length !== 1 || args.some((value) => value.startsWith("-exportArchive") && value !== "-exportArchive")) throw ambiguous();
70
+ const flags = args.filter((value) => value.startsWith("-exportOptionsPlist"));
71
+ const index = argv.indexOf("-exportOptionsPlist");
72
+ const source = argv[index + 1];
73
+ if (flags.length !== 1 || flags[0] !== "-exportOptionsPlist" || index < 0 || !source || source.startsWith("-") || args.includes("--")) throw ambiguous();
74
+ const snapshot = await prepareExportOptions(resolve(cwd, source), stateDir, run);
75
+ directories.push(snapshot.directory);
76
+ readableFiles.push(snapshot.path);
77
+ argv[index + 1] = snapshot.path;
78
+ }
79
+ return {
80
+ commands: prepared,
81
+ readableFiles,
82
+ cleanup
83
+ };
84
+ } catch (error) {
85
+ cleanup();
86
+ throw error;
87
+ }
88
+ }
89
+ export { prepareExportOptions, prepareNativeExportCommands };
48
90
 
49
91
  //# sourceMappingURL=export-options.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"export-options.js","names":[],"sources":["../src/export-options.ts"],"sourcesContent":["import { mkdtempSync, writeFileSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { z } from 'zod';\nimport type { Run } from './process.js';\n\nconst ExportOptionsSchema = z.object({ destination: z.literal('export').default('export') }).passthrough();\n\nexport async function prepareExportOptions(source: string, stateDir: string, run: Run): Promise<{ directory: string; path: string }> {\n const decoded = await run(['/usr/bin/plutil', '-convert', 'json', '-o', '-', source]);\n if (decoded.code !== 0) throw Object.assign(new Error(`Cannot read IPA export options: ${decoded.stderr || decoded.stdout}`), { code: 'SETUP_REQUIRED' });\n let input: unknown;\n try { input = JSON.parse(decoded.stdout) as unknown; }\n catch { throw Object.assign(new Error('IPA export options did not decode to valid JSON'), { code: 'SETUP_REQUIRED' }); }\n const options = ExportOptionsSchema.safeParse(input);\n if (!options.success) throw Object.assign(new Error('IPA packaging only permits destination=export; destination=upload would bypass publication permission. Use local export options.'), { code: 'SETUP_REQUIRED' });\n const directory = mkdtempSync(join(stateDir, 'export-options-'));\n try {\n const path = join(directory, 'ExportOptions.plist');\n writeFileSync(path, JSON.stringify(options.data), { mode: 0o600 });\n const converted = await run(['/usr/bin/plutil', '-convert', 'xml1', path]);\n if (converted.code !== 0) throw Object.assign(new Error(`Cannot prepare local IPA export options: ${converted.stderr || converted.stdout}`), { code: 'SETUP_REQUIRED' });\n return { directory, path };\n } catch (error) {\n rmSync(directory, { recursive: true, force: true });\n throw error;\n }\n}\n"],"mappings":";;;;AAKA,MAAM,sBAAsB,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,QAAQ,CAAC,CAAC,QAAQ,QAAQ,EAAE,CAAC,CAAC,CAAC,YAAY;AAEzG,eAAsB,qBAAqB,QAAgB,UAAkB,KAAwD;CACnI,MAAM,UAAU,MAAM,IAAI;EAAC;EAAmB;EAAY;EAAQ;EAAM;EAAK;CAAM,CAAC;CACpF,IAAI,QAAQ,SAAS,GAAG,MAAM,OAAO,uBAAO,IAAI,MAAM,mCAAmC,QAAQ,UAAU,QAAQ,QAAQ,GAAG,EAAE,MAAM,iBAAiB,CAAC;CACxJ,IAAI;CACJ,IAAI;EAAE,QAAQ,KAAK,MAAM,QAAQ,MAAM;CAAc,QAC/C;EAAE,MAAM,OAAO,uBAAO,IAAI,MAAM,iDAAiD,GAAG,EAAE,MAAM,iBAAiB,CAAC;CAAG;CACvH,MAAM,UAAU,oBAAoB,UAAU,KAAK;CACnD,IAAI,CAAC,QAAQ,SAAS,MAAM,OAAO,uBAAO,IAAI,MAAM,kIAAkI,GAAG,EAAE,MAAM,iBAAiB,CAAC;CACnN,MAAM,YAAY,YAAY,KAAK,UAAU,iBAAiB,CAAC;CAC/D,IAAI;EACF,MAAM,OAAO,KAAK,WAAW,qBAAqB;EAClD,cAAc,MAAM,KAAK,UAAU,QAAQ,IAAI,GAAG,EAAE,MAAM,IAAM,CAAC;EACjE,MAAM,YAAY,MAAM,IAAI;GAAC;GAAmB;GAAY;GAAQ;EAAI,CAAC;EACzE,IAAI,UAAU,SAAS,GAAG,MAAM,OAAO,uBAAO,IAAI,MAAM,4CAA4C,UAAU,UAAU,UAAU,QAAQ,GAAG,EAAE,MAAM,iBAAiB,CAAC;EACvK,OAAO;GAAE;GAAW;EAAK;CAC3B,SAAS,OAAO;EACd,OAAO,WAAW;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EAClD,MAAM;CACR;AACF"}
1
+ {"version":3,"file":"export-options.js","names":[],"sources":["../src/export-options.ts"],"sourcesContent":["import { mkdtempSync, writeFileSync, rmSync } from 'node:fs';\nimport { basename, join, resolve } from 'node:path';\nimport { z } from 'zod';\nimport type { Run } from './process.js';\n\nconst ExportOptionsSchema = z.object({ destination: z.literal('export').default('export') }).passthrough();\n\nexport async function prepareExportOptions(source: string, stateDir: string, run: Run): Promise<{ directory: string; path: string }> {\n const decoded = await run(['/usr/bin/plutil', '-convert', 'json', '-o', '-', source]);\n if (decoded.code !== 0) throw Object.assign(new Error(`Cannot read IPA export options: ${decoded.stderr || decoded.stdout}`), { code: 'SETUP_REQUIRED' });\n let input: unknown;\n try { input = JSON.parse(decoded.stdout) as unknown; }\n catch { throw Object.assign(new Error('IPA export options did not decode to valid JSON'), { code: 'SETUP_REQUIRED' }); }\n const options = ExportOptionsSchema.safeParse(input);\n if (!options.success) throw Object.assign(new Error('IPA packaging only permits destination=export; destination=upload would bypass publication permission. Use local export options.'), { code: 'SETUP_REQUIRED' });\n const directory = mkdtempSync(join(stateDir, 'export-options-'));\n try {\n const path = join(directory, 'ExportOptions.plist');\n writeFileSync(path, JSON.stringify(options.data), { mode: 0o600 });\n const converted = await run(['/usr/bin/plutil', '-convert', 'xml1', path]);\n if (converted.code !== 0) throw Object.assign(new Error(`Cannot prepare local IPA export options: ${converted.stderr || converted.stdout}`), { code: 'SETUP_REQUIRED' });\n return { directory, path };\n } catch (error) {\n rmSync(directory, { recursive: true, force: true });\n throw error;\n }\n}\n\n// Prepare the entire sequence before executing any owner-configured packaging command.\n// This guards recognizable native exports, not arbitrary scripts or executable code.\nexport async function prepareNativeExportCommands(commands: string[][], cwd: string, stateDir: string, run: Run): Promise<{ commands: string[][]; readableFiles: string[]; cleanup: () => void }> {\n const prepared = commands.map(argv => [...argv]);\n const directories: string[] = [];\n const readableFiles: string[] = [];\n const cleanup = () => { for (const directory of directories) rmSync(directory, { recursive: true, force: true }); };\n const ambiguous = () => Object.assign(new Error('Native IPA export requires exactly one unambiguous -exportOptionsPlist path; use direct xcodebuild or xcrun xcodebuild arguments.'), { code: 'SETUP_REQUIRED' });\n try {\n for (const argv of prepared) {\n const executable = basename(argv[0] ?? '');\n const direct = executable === 'xcodebuild';\n const wrapped = executable === 'xcrun' && basename(argv[1] ?? '') === 'xcodebuild';\n if (!direct && !wrapped) {\n if (executable === 'xcrun' && argv.some(value => basename(value) === 'xcodebuild') && argv.includes('-exportArchive')) throw ambiguous();\n continue;\n }\n const args = argv.slice(wrapped ? 2 : 1);\n if (!args.some(value => value.startsWith('-exportArchive'))) continue;\n if (args.filter(value => value === '-exportArchive').length !== 1 || args.some(value => value.startsWith('-exportArchive') && value !== '-exportArchive')) throw ambiguous();\n const flags = args.filter(value => value.startsWith('-exportOptionsPlist'));\n const index = argv.indexOf('-exportOptionsPlist');\n const source = argv[index + 1];\n if (flags.length !== 1 || flags[0] !== '-exportOptionsPlist' || index < 0 || !source || source.startsWith('-') || args.includes('--')) throw ambiguous();\n const snapshot = await prepareExportOptions(resolve(cwd, source), stateDir, run);\n directories.push(snapshot.directory);\n readableFiles.push(snapshot.path);\n argv[index + 1] = snapshot.path;\n }\n return { commands: prepared, readableFiles, cleanup };\n } catch (error) {\n cleanup();\n throw error;\n }\n}\n"],"mappings":"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"}
package/dist/flutter.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { ToolchainSchema, toError } from "./schemas.js";
2
2
  import { inside } from "./config.js";
3
- import { delimiter, join, relative, sep } from "node:path";
3
+ import { removeConfinedPath } from "./isolation.js";
4
4
  import { existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
5
+ import { delimiter, join, relative, sep } from "node:path";
5
6
  // src/flutter.ts
6
7
  const FlutterIdentitySchema = ToolchainSchema.pick({
7
8
  frameworkRevision: true,
@@ -33,7 +34,7 @@ function flutterEnvironment(config, workspace, base, trusted = false) {
33
34
  async function prepareFlutter(job, { run, env, signal }) {
34
35
  if (!job.config.toolchain?.flutterSdk) return null;
35
36
  signal?.throwIfAborted();
36
- if (process.platform !== "darwin") throw unavailable("Isolated iOS Flutter SDK preparation requires macOS clone-capable storage.", "platform", job.workspace);
37
+ if (!["darwin", "linux"].includes(process.platform)) throw unavailable("Isolated Flutter SDK preparation requires macOS or Linux storage.", "platform", job.workspace);
37
38
  let source;
38
39
  try {
39
40
  source = realpathSync(job.config.toolchain.flutterSdk);
@@ -99,7 +100,7 @@ async function prepareFlutter(job, { run, env, signal }) {
99
100
  join(source, "bin", "flutter"),
100
101
  "--suppress-analytics",
101
102
  "precache",
102
- "--ios"
103
+ `--${job.spec.platform}`
103
104
  ], {
104
105
  env: {
105
106
  ...flutterEnvironment(job.config, job.workspace, env, true),
@@ -122,43 +123,30 @@ async function prepareFlutter(job, { run, env, signal }) {
122
123
  writeFileSync(marker, JSON.stringify(metadata), { mode: 384 });
123
124
  const temporary = mkdtempSync(join(cache, "flutter-clone-"));
124
125
  try {
125
- const cloned = await run([
126
+ const cloned = await run(process.platform === "darwin" ? [
126
127
  "/bin/cp",
127
128
  "-cRp",
128
129
  `${source}/.`,
129
130
  temporary
131
+ ] : [
132
+ "cp",
133
+ "--reflink=always",
134
+ "-Rp",
135
+ `${source}/.`,
136
+ temporary
130
137
  ], { signal });
131
138
  if (cloned.code !== 0) throw unavailable(`Cannot create the workspace-local copy-on-write SDK: ${cloned.stderr || cloned.stdout}`, "sdk-clone", source);
132
139
  signal?.throwIfAborted();
133
140
  renameSync(temporary, sdk);
134
141
  } finally {
135
- rmSync(temporary, {
142
+ if (job.config.isolation) removeConfinedPath(temporary, job.workspace);
143
+ else rmSync(temporary, {
136
144
  recursive: true,
137
145
  force: true
138
146
  });
139
147
  }
140
148
  }
141
149
  if (metadata?.ready) return metadata;
142
- if (job.stage === "build" && !existsSync(join(job.workspace, "pubspec.yaml"))) {
143
- const bundle = job.spec.apple?.bundleId;
144
- const organization = typeof bundle === "string" && bundle.includes(".") ? bundle.slice(0, bundle.lastIndexOf(".")) : "com.example";
145
- const created = await run([
146
- join(sdk, "bin", "flutter"),
147
- "--suppress-analytics",
148
- "create",
149
- "--no-pub",
150
- "--platforms=ios",
151
- "--project-name",
152
- job.spec.id.replaceAll("-", "_"),
153
- "--org",
154
- organization,
155
- "."
156
- ], {
157
- env,
158
- signal
159
- });
160
- if (created.code !== 0) throw unavailable(`Cannot bootstrap the Flutter project: ${created.stderr || created.stdout}`, "sdk-bootstrap", sdk);
161
- }
162
150
  metadata = ToolchainSchema.parse({
163
151
  ...metadata,
164
152
  ready: true
@@ -1 +1 @@
1
- {"version":3,"file":"flutter.js","names":[],"sources":["../src/flutter.ts"],"sourcesContent":["import { existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from 'node:fs';\nimport { join, delimiter, relative, sep } from 'node:path';\nimport { inside } from './config.js';\nimport { ToolchainSchema, toError, type Config, type Job, type Toolchain } from './schemas.js';\nimport type { Run } from './process.js';\n\nconst FlutterIdentitySchema = ToolchainSchema.pick({ frameworkRevision: true, engineRevision: true }).strip();\ntype FlutterIdentity = Pick<Toolchain, 'frameworkRevision' | 'engineRevision'>;\n\nexport interface PrepareFlutterOptions {\n run: Run;\n env: NodeJS.ProcessEnv;\n signal?: AbortSignal;\n}\n\nfunction unavailable(message: string, reason: string, path: string) {\n return Object.assign(new Error(message), { code: 'PREREQUISITE_FAILED', prerequisite: { reason, path } });\n}\n\nexport function flutterEnvironment(config: Config, workspace: string, base: NodeJS.ProcessEnv, trusted = false): NodeJS.ProcessEnv {\n if (!config.toolchain?.flutterSdk) return base;\n const cache = trusted ? join(config.stateDir, 'verification-cache') : join(workspace, '.factory-cache');\n const sdk = trusted ? config.toolchain.flutterSdk : join(cache, 'flutter');\n return {\n ...base,\n PATH: `${join(sdk, 'bin')}${delimiter}${base.PATH ?? ''}`,\n FLUTTER_ROOT: sdk,\n PUB_CACHE: join(cache, 'pub'),\n ANALYZER_STATE_LOCATION_OVERRIDE: join(cache, 'analyzer'),\n DART_SUPPRESS_ANALYTICS: 'true',\n FLUTTER_SUPPRESS_ANALYTICS: 'true',\n };\n}\n\nexport async function prepareFlutter(job: Pick<Job, 'config' | 'workspace' | 'spec' | 'stage' | 'toolchain'>, { run, env, signal }: PrepareFlutterOptions): Promise<Toolchain | null> {\n if (!job.config.toolchain?.flutterSdk) return null;\n signal?.throwIfAborted();\n if (process.platform !== 'darwin') throw unavailable('Isolated iOS Flutter SDK preparation requires macOS clone-capable storage.', 'platform', job.workspace);\n let source: string;\n try { source = realpathSync(job.config.toolchain.flutterSdk); }\n catch (error) { throw unavailable(`Flutter SDK is unavailable at the configured toolchain.flutterSdk: ${toError(error).message}`, 'missing-sdk', job.config.toolchain.flutterSdk); }\n if (!existsSync(join(source, 'bin', 'flutter'))) throw unavailable('Configured toolchain.flutterSdk does not contain bin/flutter.', 'missing-sdk', source);\n const cache = inside(job.workspace, '.factory-cache');\n const sdk = inside(job.workspace, '.factory-cache/flutter');\n const overlap = relative(source, cache);\n if (!overlap || !(overlap === '..' || overlap.startsWith(`..${sep}`))) throw unavailable('The Flutter SDK source cannot contain its workspace cache.', 'overlapping-sdk', source);\n if (job.toolchain && job.toolchain.source !== source) throw unavailable('This task is pinned to a different Flutter SDK. Restore its configured SDK or enqueue a new version; cached SDKs are not silently replaced.', 'sdk-mismatch', join(cache, 'flutter.json'));\n mkdirSync(cache, { recursive: true, mode: 0o700 });\n if (!existsSync(join(cache, '.gitignore'))) writeFileSync(join(cache, '.gitignore'), '*\\n', { mode: 0o600 });\n const marker = join(cache, 'flutter.json');\n let metadata: Toolchain | undefined;\n if (existsSync(marker)) {\n try { metadata = ToolchainSchema.parse(JSON.parse(readFileSync(marker, 'utf8'))); }\n catch (error) { throw unavailable(`Cannot read the owned Flutter cache metadata: ${toError(error).message}`, 'cache-metadata', marker); }\n if (metadata.source !== source) throw unavailable('This task is pinned to a different Flutter SDK. Restore its configured SDK or enqueue a new version; cached SDKs are not silently replaced.', 'sdk-mismatch', marker);\n } else if (existsSync(sdk)) {\n throw unavailable('An unmanaged Flutter cache already exists in this workspace; it will not be overwritten.', 'cache-conflict', sdk);\n }\n const pin = job.toolchain ?? metadata;\n const checkVersion = (identity: FlutterIdentity): void => {\n let current: FlutterIdentity;\n try { current = FlutterIdentitySchema.parse(JSON.parse(readFileSync(join(source, 'bin', 'cache', 'flutter.version.json'), 'utf8'))); }\n catch (error) { throw unavailable(`Cannot establish the verifier SDK identity: ${toError(error).message}`, 'sdk-version-unavailable', source); }\n if (current.frameworkRevision !== identity.frameworkRevision || current.engineRevision !== identity.engineRevision) throw unavailable('The configured verifier SDK changed during this task. Restore the pinned SDK or enqueue a new version; old verification cannot be reused.', 'sdk-version-changed', source);\n };\n if (pin) {\n checkVersion(pin);\n if (metadata && (metadata.frameworkRevision !== pin.frameworkRevision || metadata.engineRevision !== pin.engineRevision)) throw unavailable('The configured verifier SDK changed during this task. Restore the pinned SDK or enqueue a new version; old verification cannot be reused.', 'sdk-version-changed', source);\n }\n if (!existsSync(sdk)) {\n const initialized = await run([join(source, 'bin', 'flutter'), '--suppress-analytics', '--version', '--machine'], { env: { ...flutterEnvironment(job.config, job.workspace, env, true), FLUTTER_ROOT: source }, signal });\n if (initialized.code !== 0) throw unavailable(`Cannot initialize the configured Flutter SDK: ${initialized.stderr || initialized.stdout}`, 'sdk-initialization', source);\n let version: FlutterIdentity;\n try { version = FlutterIdentitySchema.parse(JSON.parse(initialized.stdout)); }\n catch { throw unavailable('Flutter --version --machine returned no valid version metadata.', 'sdk-version', source); }\n const prepared = await run([join(source, 'bin', 'flutter'), '--suppress-analytics', 'precache', '--ios'], { env: { ...flutterEnvironment(job.config, job.workspace, env, true), FLUTTER_ROOT: source }, signal });\n if (prepared.code !== 0) throw unavailable(`Cannot prepare Flutter artifacts before agent execution: ${prepared.stderr || prepared.stdout}`, 'sdk-artifacts', source);\n const identity = { source, frameworkRevision: version.frameworkRevision, engineRevision: version.engineRevision };\n checkVersion(pin ?? identity);\n if (pin && (identity.frameworkRevision !== pin.frameworkRevision || identity.engineRevision !== pin.engineRevision)) throw unavailable('The configured verifier SDK changed during this task. Restore the pinned SDK or enqueue a new version; old verification cannot be reused.', 'sdk-version-changed', source);\n metadata = { ...identity, ready: false };\n writeFileSync(marker, JSON.stringify(metadata), { mode: 0o600 });\n const temporary = mkdtempSync(join(cache, 'flutter-clone-'));\n try {\n const cloned = await run(['/bin/cp', '-cRp', `${source}/.`, temporary], { signal });\n if (cloned.code !== 0) throw unavailable(`Cannot create the workspace-local copy-on-write SDK: ${cloned.stderr || cloned.stdout}`, 'sdk-clone', source);\n signal?.throwIfAborted();\n renameSync(temporary, sdk);\n } finally { rmSync(temporary, { recursive: true, force: true }); }\n }\n if (metadata?.ready) return metadata;\n if (job.stage === 'build' && !existsSync(join(job.workspace, 'pubspec.yaml'))) {\n const bundle = job.spec.apple?.bundleId;\n const organization = typeof bundle === 'string' && bundle.includes('.') ? bundle.slice(0, bundle.lastIndexOf('.')) : 'com.example';\n const created = await run([join(sdk, 'bin', 'flutter'), '--suppress-analytics', 'create', '--no-pub', '--platforms=ios', '--project-name', job.spec.id.replaceAll('-', '_'), '--org', organization, '.'], { env, signal });\n if (created.code !== 0) throw unavailable(`Cannot bootstrap the Flutter project: ${created.stderr || created.stdout}`, 'sdk-bootstrap', sdk);\n }\n metadata = ToolchainSchema.parse({ ...metadata, ready: true });\n writeFileSync(marker, JSON.stringify(metadata), { mode: 0o600 });\n return metadata;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"flutter.js","names":[],"sources":["../src/flutter.ts"],"sourcesContent":["import { existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from 'node:fs';\nimport { join, delimiter, relative, sep } from 'node:path';\nimport { inside } from './config.js';\nimport { removeConfinedPath } from './isolation.js';\nimport { ToolchainSchema, toError, type Config, type Job, type Toolchain } from './schemas.js';\nimport type { Run } from './process.js';\n\nconst FlutterIdentitySchema = ToolchainSchema.pick({ frameworkRevision: true, engineRevision: true }).strip();\ntype FlutterIdentity = Pick<Toolchain, 'frameworkRevision' | 'engineRevision'>;\n\nexport interface PrepareFlutterOptions {\n run: Run;\n env: NodeJS.ProcessEnv;\n signal?: AbortSignal;\n}\n\nfunction unavailable(message: string, reason: string, path: string) {\n return Object.assign(new Error(message), { code: 'PREREQUISITE_FAILED', prerequisite: { reason, path } });\n}\n\nexport function flutterEnvironment(config: Config, workspace: string, base: NodeJS.ProcessEnv, trusted = false): NodeJS.ProcessEnv {\n if (!config.toolchain?.flutterSdk) return base;\n const cache = trusted ? join(config.stateDir, 'verification-cache') : join(workspace, '.factory-cache');\n const sdk = trusted ? config.toolchain.flutterSdk : join(cache, 'flutter');\n return {\n ...base,\n PATH: `${join(sdk, 'bin')}${delimiter}${base.PATH ?? ''}`,\n FLUTTER_ROOT: sdk,\n PUB_CACHE: join(cache, 'pub'),\n ANALYZER_STATE_LOCATION_OVERRIDE: join(cache, 'analyzer'),\n DART_SUPPRESS_ANALYTICS: 'true',\n FLUTTER_SUPPRESS_ANALYTICS: 'true',\n };\n}\n\nexport async function prepareFlutter(job: Pick<Job, 'config' | 'workspace' | 'spec' | 'stage' | 'toolchain'>, { run, env, signal }: PrepareFlutterOptions): Promise<Toolchain | null> {\n if (!job.config.toolchain?.flutterSdk) return null;\n signal?.throwIfAborted();\n if (!['darwin', 'linux'].includes(process.platform)) throw unavailable('Isolated Flutter SDK preparation requires macOS or Linux storage.', 'platform', job.workspace);\n let source: string;\n try { source = realpathSync(job.config.toolchain.flutterSdk); }\n catch (error) { throw unavailable(`Flutter SDK is unavailable at the configured toolchain.flutterSdk: ${toError(error).message}`, 'missing-sdk', job.config.toolchain.flutterSdk); }\n if (!existsSync(join(source, 'bin', 'flutter'))) throw unavailable('Configured toolchain.flutterSdk does not contain bin/flutter.', 'missing-sdk', source);\n const cache = inside(job.workspace, '.factory-cache');\n const sdk = inside(job.workspace, '.factory-cache/flutter');\n const overlap = relative(source, cache);\n if (!overlap || !(overlap === '..' || overlap.startsWith(`..${sep}`))) throw unavailable('The Flutter SDK source cannot contain its workspace cache.', 'overlapping-sdk', source);\n if (job.toolchain && job.toolchain.source !== source) throw unavailable('This task is pinned to a different Flutter SDK. Restore its configured SDK or enqueue a new version; cached SDKs are not silently replaced.', 'sdk-mismatch', join(cache, 'flutter.json'));\n mkdirSync(cache, { recursive: true, mode: 0o700 });\n if (!existsSync(join(cache, '.gitignore'))) writeFileSync(join(cache, '.gitignore'), '*\\n', { mode: 0o600 });\n const marker = join(cache, 'flutter.json');\n let metadata: Toolchain | undefined;\n if (existsSync(marker)) {\n try { metadata = ToolchainSchema.parse(JSON.parse(readFileSync(marker, 'utf8'))); }\n catch (error) { throw unavailable(`Cannot read the owned Flutter cache metadata: ${toError(error).message}`, 'cache-metadata', marker); }\n if (metadata.source !== source) throw unavailable('This task is pinned to a different Flutter SDK. Restore its configured SDK or enqueue a new version; cached SDKs are not silently replaced.', 'sdk-mismatch', marker);\n } else if (existsSync(sdk)) {\n throw unavailable('An unmanaged Flutter cache already exists in this workspace; it will not be overwritten.', 'cache-conflict', sdk);\n }\n const pin = job.toolchain ?? metadata;\n const checkVersion = (identity: FlutterIdentity): void => {\n let current: FlutterIdentity;\n try { current = FlutterIdentitySchema.parse(JSON.parse(readFileSync(join(source, 'bin', 'cache', 'flutter.version.json'), 'utf8'))); }\n catch (error) { throw unavailable(`Cannot establish the verifier SDK identity: ${toError(error).message}`, 'sdk-version-unavailable', source); }\n if (current.frameworkRevision !== identity.frameworkRevision || current.engineRevision !== identity.engineRevision) throw unavailable('The configured verifier SDK changed during this task. Restore the pinned SDK or enqueue a new version; old verification cannot be reused.', 'sdk-version-changed', source);\n };\n if (pin) {\n checkVersion(pin);\n if (metadata && (metadata.frameworkRevision !== pin.frameworkRevision || metadata.engineRevision !== pin.engineRevision)) throw unavailable('The configured verifier SDK changed during this task. Restore the pinned SDK or enqueue a new version; old verification cannot be reused.', 'sdk-version-changed', source);\n }\n if (!existsSync(sdk)) {\n const initialized = await run([join(source, 'bin', 'flutter'), '--suppress-analytics', '--version', '--machine'], { env: { ...flutterEnvironment(job.config, job.workspace, env, true), FLUTTER_ROOT: source }, signal });\n if (initialized.code !== 0) throw unavailable(`Cannot initialize the configured Flutter SDK: ${initialized.stderr || initialized.stdout}`, 'sdk-initialization', source);\n let version: FlutterIdentity;\n try { version = FlutterIdentitySchema.parse(JSON.parse(initialized.stdout)); }\n catch { throw unavailable('Flutter --version --machine returned no valid version metadata.', 'sdk-version', source); }\n const prepared = await run([join(source, 'bin', 'flutter'), '--suppress-analytics', 'precache', `--${job.spec.platform}`], { env: { ...flutterEnvironment(job.config, job.workspace, env, true), FLUTTER_ROOT: source }, signal });\n if (prepared.code !== 0) throw unavailable(`Cannot prepare Flutter artifacts before agent execution: ${prepared.stderr || prepared.stdout}`, 'sdk-artifacts', source);\n const identity = { source, frameworkRevision: version.frameworkRevision, engineRevision: version.engineRevision };\n checkVersion(pin ?? identity);\n if (pin && (identity.frameworkRevision !== pin.frameworkRevision || identity.engineRevision !== pin.engineRevision)) throw unavailable('The configured verifier SDK changed during this task. Restore the pinned SDK or enqueue a new version; old verification cannot be reused.', 'sdk-version-changed', source);\n metadata = { ...identity, ready: false };\n writeFileSync(marker, JSON.stringify(metadata), { mode: 0o600 });\n const temporary = mkdtempSync(join(cache, 'flutter-clone-'));\n try {\n const cloned = await run(process.platform === 'darwin' ? ['/bin/cp', '-cRp', `${source}/.`, temporary] : ['cp', '--reflink=always', '-Rp', `${source}/.`, temporary], { signal });\n if (cloned.code !== 0) throw unavailable(`Cannot create the workspace-local copy-on-write SDK: ${cloned.stderr || cloned.stdout}`, 'sdk-clone', source);\n signal?.throwIfAborted();\n renameSync(temporary, sdk);\n } finally {\n if (job.config.isolation) removeConfinedPath(temporary, job.workspace);\n else rmSync(temporary, { recursive: true, force: true });\n }\n }\n if (metadata?.ready) return metadata;\n metadata = ToolchainSchema.parse({ ...metadata, ready: true });\n writeFileSync(marker, JSON.stringify(metadata), { mode: 0o600 });\n return metadata;\n}\n"],"mappings":"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"}