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.
- package/README.md +52 -138
- package/benchmarks/peer-context-worker.mjs +186 -0
- package/benchmarks/peer-context.mjs +150 -0
- package/dist/apple-types.js.map +1 -1
- package/dist/cli.js +373 -121
- package/dist/cli.js.map +1 -1
- package/dist/config.js +42 -4
- package/dist/config.js.map +1 -1
- package/dist/dependencies.js +455 -16
- package/dist/dependencies.js.map +1 -1
- package/dist/export-options.js +44 -2
- package/dist/export-options.js.map +1 -1
- package/dist/flutter.js +13 -25
- package/dist/flutter.js.map +1 -1
- package/dist/go-dependencies.js +389 -0
- package/dist/go-dependencies.js.map +1 -0
- package/dist/inbox.js +7 -8
- package/dist/inbox.js.map +1 -1
- package/dist/integrations.js +29 -29
- package/dist/integrations.js.map +1 -1
- package/dist/isolation.js +190 -0
- package/dist/isolation.js.map +1 -0
- package/dist/macos.js +57 -0
- package/dist/macos.js.map +1 -0
- package/dist/mygo-build.js +55 -0
- package/dist/mygo-build.js.map +1 -0
- package/dist/policy.js +35 -0
- package/dist/policy.js.map +1 -0
- package/dist/preflight.js +1 -1
- package/dist/process.js +3 -3
- package/dist/project-profiles.js +163 -0
- package/dist/project-profiles.js.map +1 -0
- package/dist/proof.js +33 -0
- package/dist/proof.js.map +1 -0
- package/dist/remote.js +1 -1
- package/dist/runner.js +269 -287
- package/dist/runner.js.map +1 -1
- package/dist/scheduler.js +0 -3
- package/dist/scheduler.js.map +1 -1
- package/dist/schemas.js +156 -44
- package/dist/schemas.js.map +1 -1
- package/dist/store.js +166 -44
- package/dist/store.js.map +1 -1
- package/dist/vendor/obfuscator/dist/cli.js +72 -0
- package/dist/vendor/obfuscator/dist/cli.js.map +1 -0
- package/dist/vendor/obfuscator/dist/code.js +585 -0
- package/dist/vendor/obfuscator/dist/code.js.map +1 -0
- package/dist/vendor/obfuscator/dist/common.js +262 -0
- package/dist/vendor/obfuscator/dist/common.js.map +1 -0
- package/dist/vendor/obfuscator/dist/config.js +123 -0
- package/dist/vendor/obfuscator/dist/config.js.map +1 -0
- package/dist/vendor/obfuscator/dist/content.js +89 -0
- package/dist/vendor/obfuscator/dist/content.js.map +1 -0
- package/dist/vendor/obfuscator/dist/obfuscate.js +93 -0
- package/dist/vendor/obfuscator/dist/obfuscate.js.map +1 -0
- package/dist/vendor/obfuscator/dist/png.js +283 -0
- package/dist/vendor/obfuscator/dist/png.js.map +1 -0
- package/dist/vendor/obfuscator/dist/project.js +159 -0
- package/dist/vendor/obfuscator/dist/project.js.map +1 -0
- package/dist/vendor/obfuscator/dist/resources.js +335 -0
- package/dist/vendor/obfuscator/dist/resources.js.map +1 -0
- package/dist/vendor/obfuscator/package.json +22 -0
- package/dist/workspace.js +113 -0
- package/dist/workspace.js.map +1 -0
- package/evals/control.mjs +73 -0
- package/evals/expectations.mjs +37 -0
- package/evals/host.mjs +51 -0
- package/evals/oracle.mjs +80 -0
- package/evals/policy.mjs +268 -0
- package/examples/android-java.factory.json +18 -0
- package/examples/android-java.json +16 -0
- package/examples/existing-project.factory.json +18 -0
- package/examples/existing-project.json +17 -0
- package/examples/expo.eas.json +17 -0
- package/examples/expo.factory.json +18 -0
- package/examples/expo.json +16 -0
- package/examples/factory.json +0 -2
- package/examples/flutter.factory.json +13 -0
- package/examples/flutter.json +16 -0
- package/examples/luggage.json +5 -3
- package/examples/mygo-web.factory.json +18 -0
- package/examples/mygo-web.json +16 -0
- package/examples/mygo.factory.json +18 -0
- package/examples/mygo.json +16 -0
- package/examples/react-native.factory.json +18 -0
- package/examples/react-native.json +16 -0
- package/examples/remote.json +1 -1
- package/examples/runtime/android-java/app/build.gradle +7 -0
- package/examples/runtime/android-java/app/src/main/AndroidManifest.xml +8 -0
- package/examples/runtime/android-java/app/src/main/java/dev/apphx/runtime/MainActivity.java +44 -0
- package/examples/runtime/android-java/sdk-build.mjs +29 -0
- package/examples/runtime/android-java/settings.gradle +2 -0
- package/examples/runtime/android-ui.mjs +70 -0
- package/examples/runtime/mygo-native/go.mod +13 -0
- package/examples/runtime/mygo-native/go.sum +10 -0
- package/examples/runtime/mygo-native/main.go +173 -0
- package/examples/runtime/mygo-native/main_test.go +14 -0
- package/examples/runtime/mygo-native/mygo.json +1 -0
- package/examples/runtime/mygo-web/bun.lock +15 -0
- package/examples/runtime/mygo-web/go.mod +9 -0
- package/examples/runtime/mygo-web/go.sum +8 -0
- package/examples/runtime/mygo-web/index.html +1 -0
- package/examples/runtime/mygo-web/main.go +60 -0
- package/examples/runtime/mygo-web/mygo.config.ts +10 -0
- package/examples/runtime/mygo-web/package.json +1 -0
- package/examples/runtime/mygo-web/src/main.ts +23 -0
- package/examples/runtime/mygo-web/src/mygo.ts +14 -0
- package/examples/swift.factory.json +18 -0
- package/examples/swift.json +16 -0
- package/examples/uni-app.factory.json +18 -0
- package/examples/uni-app.json +16 -0
- package/package.json +12 -5
- package/scripts/bundle-obfuscator.mjs +19 -0
- package/scripts/runtime-smoke.mjs +209 -0
- package/skills/apphx/SKILL.md +180 -0
- package/skills/apphx/resources/google-play-research-result.json +6 -0
- package/skills/apphx/resources/local-research-result.json +6 -0
- package/skills/{apple-app-factory → apphx}/resources/requirement.json +5 -8
- package/skills/apphx/resources/research-result.json +12 -0
- package/skills/apphx/resources/review-result.json +7 -0
- package/dist/apple.js +0 -900
- package/dist/apple.js.map +0 -1
- package/skills/apple-app-factory/SKILL.md +0 -103
- package/skills/apple-app-factory/resources/research-result.json +0 -21
- package/skills/apple-app-factory/resources/review-result.json +0 -7
- /package/skills/{apple-app-factory → apphx}/LICENSE +0 -0
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { resolve, dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { parseArgs } from 'node:util';\nimport { loadConfig, loadJSON } from './config.js';\nimport { Store } from './store.js';\nimport { run, executionEnvironment } from './process.js';\nimport { appleDoctor, validateAppleSpec } from './apple.js';\nimport { runStep } from './scheduler.js';\nimport { nextTurn, completeTurn, abandonTurn } from './runner.js';\nimport { hosts, installIntegration, updateIntegration, inspectIntegration, uninstallIntegration } from './integrations.js';\nimport { submitRequirement, scanInbox } from './inbox.js';\nimport { MAX_INPUT_BYTES, parseRequirement, readInputFile } from './requirements.js';\nimport { dispatchRemote } from './remote.js';\nimport { toError } from './schemas.js';\nimport type { Config, Job } from './schemas.js';\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst print = (value: unknown): void => console.log(JSON.stringify(value, null, 2));\nconst view = (job: Job) => ({ id: job.id, product: job.spec.id, version: job.spec.apple?.version ?? '1.0.0', stage: job.stage, status: job.status, hostTurns: job.hostTurns, attempts: job.attempts, workspace: job.workspace, artifact: job.artifact ?? null, error: job.error ?? null });\n\nfunction inputJSON(path: string): unknown {\n const bytes = path === '-' ? readFileSync(0) : readInputFile(path);\n if (bytes.length > MAX_INPUT_BYTES) throw new Error(`Input exceeds ${MAX_INPUT_BYTES} bytes`);\n return JSON.parse(bytes.toString('utf8')) as unknown;\n}\n\nfunction arity(args: string[], minimum: number, maximum: number, usage: string): void {\n if (args.length < minimum || args.length > maximum) throw new Error(`Usage: app-factory ${usage}`);\n}\n\nfunction outcome(job: Job): void {\n print(view(job));\n if (job.status === 'blocked' || job.status === 'failed') process.exitCode = 2;\n}\n\nasync function probe(argv: string[], config: Config) {\n try {\n const result = await run(argv, { env: executionEnvironment(config), timeoutMs: 30000 });\n return { available: result.code === 0, detail: (result.code === 0 ? result.stdout : result.stderr || result.stdout).trim() };\n } catch (error) { return { available: false, detail: toError(error).message }; }\n}\n\nconst help = `app-factory <command> [--config factory.json] [--build-only]\n hosts List supported agent hosts and activation commands\n install <host> Install the workflow in the current project\n update <host> Update an existing, unmodified host workflow\n uninstall <host> Remove an unchanged installation owned by this package\n --project <directory> Select the project (default: current directory)\n --global Use the host's user-level skill directory instead\n doctor --host <host> Check installed workflow files; does not run the agent\n init [--allow-local-execution] Create factory.json without overwriting it\n doctor Check local build tools and execution permissions\n enqueue <spec.json|-> Persist requirements and return a task ID\n next <id> Resume a host turn or show the next deterministic action\n complete <id> <turn> [json|-] Record research/review, or finish the host's build turn\n abandon <id> <turn> Abandon a host turn without resetting its budget\n step <id> Execute one verification, packaging or Apple stage\n status [id] Read durable task state as JSON\n events <id> Read task transitions and evidence\n retry <id> Resume stopped work; preserve budgets and permissions\n submit <spec.json|-> Write requirements to the configured inbox\n scan [--observe] Validate or ingest inbox files; never start an agent\n inbox Read durable intake results\n reconcile-intake <id> <json|-> Restore a legacy request identity from original input\n authorize <id> --submit [--release] Explicitly grant publication permission\n feedback <id> <file> Resume using actual App Review rejection feedback\n remote <command> Call an installed Mac CLI over SSH (build-only)\n --version Print the installed package version\n\nYour agent supplies the model, session, tools and native delegation.\nNo coding-agent subprocess or autonomous daemon is started by this CLI.\nOnly verified local artifacts reach built; uploads require separate authorization.`;\n\nasync function main(): Promise<void> {\n const { values, positionals, tokens } = parseArgs({\n allowPositionals: true,\n tokens: true,\n options: {\n config: { type: 'string', default: 'factory.json' },\n 'build-only': { type: 'boolean', default: false },\n project: { type: 'string' },\n global: { type: 'boolean' },\n host: { type: 'string' },\n 'allow-local-execution': { type: 'boolean' },\n observe: { type: 'boolean' },\n submit: { type: 'boolean' },\n release: { type: 'boolean' },\n version: { type: 'boolean', short: 'v' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n const [command, ...args] = positionals;\n if (values.version) {\n const metadata = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8')) as { version: string };\n console.log(metadata.version);\n return;\n }\n if (!command || command === 'help' || values.help) { console.log(help); return; }\n const flags: Record<string, string[]> = {\n hosts: [], install: ['project', 'global'], update: ['project', 'global'], uninstall: ['project', 'global'],\n init: ['config', 'allow-local-execution'], doctor: ['config', 'build-only', 'host', 'project', 'global'],\n enqueue: ['config', 'build-only'], next: ['config', 'build-only'], complete: ['config', 'build-only'], abandon: ['config', 'build-only'],\n step: ['config', 'build-only'], status: ['config', 'build-only'], events: ['config', 'build-only'], retry: ['config', 'build-only'],\n submit: ['config', 'build-only'], scan: ['config', 'build-only', 'observe'], inbox: ['config', 'build-only'],\n 'reconcile-intake': ['config', 'build-only'], authorize: ['config', 'build-only', 'submit', 'release'], feedback: ['config', 'build-only'],\n remote: ['config', 'observe'],\n };\n if (!(command in flags)) throw new Error(`Unknown command ${command}; run app-factory --help`);\n for (const token of tokens) {\n if (token.kind === 'option' && !flags[command].includes(token.name)) throw new Error(`${command} does not accept --${token.name}`);\n }\n const configPath = values.config;\n const buildOnly = values['build-only'];\n if (values.global && values.project) throw new Error('Choose --project or --global, not both');\n const scope = { project: values.project, global: values.global };\n if (command === 'hosts') { arity(args, 0, 0, 'hosts'); print(hosts); return; }\n if (command === 'install' || command === 'update' || command === 'uninstall') {\n arity(args, 1, 1, `${command} <host> [--project <directory> | --global]`);\n const operation = command === 'install' ? installIntegration : command === 'update' ? updateIntegration : uninstallIntegration;\n print(operation(args[0], scope));\n return;\n }\n if (command === 'doctor' && values.host) {\n arity(args, 0, 0, 'doctor --host <host> [--project <directory> | --global]');\n const result = inspectIntegration(values.host, scope);\n print(result);\n if (!result.installed) process.exitCode = 2;\n return;\n }\n if (command === 'doctor' && (values.project || values.global)) throw new Error('--project and --global require doctor --host <host>');\n if (command === 'init') {\n arity(args, 0, 0, 'init [--config <file>] [--allow-local-execution]');\n const template = JSON.parse(readFileSync(join(packageRoot, 'examples', 'factory.json'), 'utf8')) as Record<string, unknown>;\n if (values['allow-local-execution']) template.allowLocalExecution = true;\n mkdirSync(dirname(resolve(configPath)), { recursive: true });\n writeFileSync(configPath, `${JSON.stringify(template, null, 2)}\\n`, { flag: 'wx', mode: 0o600 });\n print({ config: resolve(configPath), localExecution: template.allowLocalExecution, next: 'Configure Flutter/Xcode and IOS_DEVICE_ID, then run app-factory doctor --build-only' });\n return;\n }\n if (command === 'remote') {\n process.exitCode = await dispatchRemote(loadJSON(configPath), [...args, ...(values.observe ? ['--observe'] : [])]);\n return;\n }\n const config = loadConfig(configPath);\n if (buildOnly && (config.allowSubmit || config.allowRelease)) throw new Error('--build-only refuses configurations with upload or release enabled');\n if (buildOnly && ['authorize', 'feedback'].includes(command)) throw new Error('Publication commands are forbidden in --build-only mode');\n if (command === 'submit') {\n arity(args, 1, 1, 'submit <spec.json|->');\n print(submitRequirement(config, inputJSON(args[0])));\n return;\n }\n if (command === 'doctor') {\n arity(args, 0, 0, 'doctor [--build-only]');\n const flutter = config.toolchain ? join(config.toolchain.flutterSdk, 'bin', 'flutter') : 'flutter';\n const [flutterCheck, xcode] = await Promise.all([probe([flutter, '--version'], config), probe(['xcodebuild', '-version'], config)]);\n const environment = executionEnvironment(config);\n const neededEnv = [...new Set([...config.verification.prerequisites, ...config.verification.checks, ...config.verification.runtime].flat().flatMap(arg => [...arg.matchAll(/\\$\\{([A-Z][A-Z0-9_]*)\\}/g)].map(match => match[1])))];\n const checks = [\n { name: 'local-execution-permission', available: config.allowLocalExecution, detail: config.executionWarning ?? 'Trusted local commands permitted; host tools remain under the host permission policy' },\n { name: 'flutter', ...flutterCheck }, { name: 'xcode', ...xcode },\n ...neededEnv.map(name => ({ name, available: Boolean(environment[name]), detail: environment[name] ? 'Available in the configured execution environment; value not printed' : `Set ${name} and include its name in executionEnv` })),\n ];\n if (config.allowSubmit) checks.push(...await appleDoctor());\n print({ checks, submissionEnabled: config.allowSubmit, model: 'Provided by your agent host; no separate model authentication is configured here' });\n if (checks.some(check => !check.available)) process.exitCode = 2;\n return;\n }\n const store = new Store(config.stateDir);\n try {\n if (command === 'enqueue') {\n arity(args, 1, 1, 'enqueue <spec.json|->');\n const { spec, baseJobId } = parseRequirement(inputJSON(args[0]));\n if (config.allowSubmit) validateAppleSpec(spec);\n print(view(store.enqueue(spec, config, baseJobId)));\n } else if (command === 'scan') {\n arity(args, 0, 0, 'scan [--observe]');\n const result = await scanInbox(store, config, { observe: values.observe });\n print(result);\n if (result.error || result.entries.some(entry => entry.status === 'error')) process.exitCode = 2;\n } else if (command === 'inbox') {\n arity(args, 0, 0, 'inbox');\n print(store.inboxEntries());\n } else if (command === 'status') {\n arity(args, 0, 1, 'status [id]');\n print(args[0] ? store.get(args[0]) : store.list().map(view));\n } else if (command === 'events') {\n arity(args, 1, 1, 'events <id>');\n print(store.events(args[0]));\n } else if (command === 'next') {\n arity(args, 1, 1, 'next <id>');\n const result = await nextTurn(store, args[0], { buildOnly });\n print(result);\n if (result.job.status === 'blocked' || result.job.status === 'failed') process.exitCode = 2;\n } else if (command === 'complete') {\n arity(args, 2, 3, 'complete <id> <turn-id> [result.json|-]');\n outcome(await completeTurn(store, args[0], args[1], args[2] ? inputJSON(args[2]) : undefined, { buildOnly }));\n } else if (command === 'abandon') {\n arity(args, 2, 2, 'abandon <id> <turn-id>');\n outcome(abandonTurn(store, args[0], args[1], { buildOnly }));\n } else if (command === 'step') {\n arity(args, 1, 1, 'step <id>');\n const controller = new AbortController();\n const stop = (): void => controller.abort();\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n try { outcome(await runStep(store, config, args[0], { signal: controller.signal, buildOnly })); }\n finally { process.removeListener('SIGINT', stop); process.removeListener('SIGTERM', stop); }\n } else if (command === 'reconcile-intake') {\n arity(args, 2, 2, 'reconcile-intake <id> <original-spec.json|->');\n const { spec, baseJobId } = parseRequirement(inputJSON(args[1]));\n print(view(store.reconcileIntake(args[0], spec, baseJobId)));\n } else if (command === 'retry') {\n arity(args, 1, 1, 'retry <id>');\n print(view(store.transition(args[0], job => {\n if (buildOnly && (job.config.allowSubmit || job.config.allowRelease)) throw new Error('--build-only refuses a task with snapshotted publication permission');\n if (!['blocked', 'ready', 'built'].includes(job.status)) throw new Error(`Cannot retry ${job.status}; budgets and active work cannot be reset by retry`);\n if (job.turn) throw new Error('Abandon the active host turn before changing task configuration');\n const proofChanged = JSON.stringify(config.verification) !== JSON.stringify(job.config.verification) || JSON.stringify(config.executionEnv) !== JSON.stringify(job.config.executionEnv) || JSON.stringify(config.toolchain) !== JSON.stringify(job.config.toolchain) || (job.verifiedDigest != null && !job.verifiedDependencyDigest);\n if (proofChanged && Object.keys(job.receipt).length) throw new Error('Verification proof is no longer valid after publication began; reconcile the existing upload before creating a new version');\n const patch: Partial<Job> = proofChanged && job.verifiedDigest ? { stage: 'verify', verifiedDigest: null, verifiedDependencyDigest: null, review: null, artifact: null } : {};\n const resumedConfig = { ...config, packageTarget: job.config.allowSubmit ? 'ipa' as const : config.packageTarget, allowSubmit: job.config.allowSubmit, allowRelease: job.config.allowRelease };\n return { ...patch, config: resumedConfig, status: 'queued', manualRecovery: null, nextAt: Date.now(), error: null };\n })));\n } else if (command === 'authorize') {\n arity(args, 1, 1, 'authorize <id> --submit [--release]');\n if (!values.submit) throw new Error('authorize requires --submit');\n print(view(store.transition(args[0], job => {\n if (job.turn || !['ready', 'blocked', 'built'].includes(job.status) || Object.keys(job.receipt).length || job.stage === 'monitor') throw new Error('Publication permission can change only on stopped work before any remote intent');\n const publishing = validateAppleSpec(job.spec);\n if (values.release && !/^[A-Za-z]{2}$/.test(publishing.storefrontCountry ?? '')) throw new Error('--release requires apple.storefrontCountry in the immutable product specification');\n const granted = { ...job.config, packageTarget: 'ipa' as const, allowSubmit: true, allowRelease: Boolean(values.release) };\n return { config: granted, status: ['ready', 'built'].includes(job.status) ? 'queued' : 'blocked', nextAt: Date.now() };\n })));\n } else if (command === 'feedback') {\n arity(args, 2, 2, 'feedback <id> <file>');\n const feedback = readInputFile(args[1], 'App Review feedback').toString('utf8').trim();\n if (!feedback) throw new Error('App Review feedback file is empty');\n print(view(store.transition(args[0], job => {\n if (job.turn || job.stage !== 'monitor' || job.appleReview?.status !== 'rejected' || job.status !== 'blocked') throw new Error('feedback is only allowed for an observed App Review rejection');\n const spec = structuredClone(job.spec);\n if (!spec.apple?.buildNumber || !/^\\d+$/.test(spec.apple.buildNumber)) throw new Error('A numeric apple.buildNumber is required to prepare a replacement build');\n spec.apple.buildNumber = String(BigInt(spec.apple.buildNumber) + 1n);\n const resumedConfig = { ...config, packageTarget: job.config.allowSubmit ? 'ipa' as const : config.packageTarget, allowSubmit: job.config.allowSubmit, allowRelease: job.config.allowRelease };\n return { spec, config: resumedConfig, feedback, status: 'queued', stage: 'build', createdAt: Date.now(), attempts: {}, hostTurns: 0, nextAt: Date.now(), receipt: {}, ipaPath: null, archiveDigest: null, verifiedDigest: null, verifiedDependencyDigest: null, review: null, error: null };\n })));\n }\n } finally { store.close(); }\n}\n\nmain().catch(error => { console.error(JSON.stringify({ error: toError(error).message })); process.exitCode = 1; });\n"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,MAAM,cAAc,QAAQ,QAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,IAAI;AACzE,MAAM,SAAS,UAAyB,QAAQ,IAAI,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAClF,MAAM,QAAQ,SAAc;CAAE,IAAI,IAAI;CAAI,SAAS,IAAI,KAAK;CAAI,SAAS,IAAI,KAAK,OAAO,WAAW;CAAS,OAAO,IAAI;CAAO,QAAQ,IAAI;CAAQ,WAAW,IAAI;CAAW,UAAU,IAAI;CAAU,WAAW,IAAI;CAAW,UAAU,IAAI,YAAY;CAAM,OAAO,IAAI,SAAS;AAAK;AAExR,SAAS,UAAU,MAAuB;CACxC,MAAM,QAAQ,SAAS,MAAM,aAAa,CAAC,IAAI,cAAc,IAAI;CACjE,IAAI,MAAM,SAAA,SAA0B,MAAM,IAAI,MAAM,iBAAiB,gBAAgB,OAAO;CAC5F,OAAO,KAAK,MAAM,MAAM,SAAS,MAAM,CAAC;AAC1C;AAEA,SAAS,MAAM,MAAgB,SAAiB,SAAiB,OAAqB;CACpF,IAAI,KAAK,SAAS,WAAW,KAAK,SAAS,SAAS,MAAM,IAAI,MAAM,sBAAsB,OAAO;AACnG;AAEA,SAAS,QAAQ,KAAgB;CAC/B,MAAM,KAAK,GAAG,CAAC;CACf,IAAI,IAAI,WAAW,aAAa,IAAI,WAAW,UAAU,QAAQ,WAAW;AAC9E;AAEA,eAAe,MAAM,MAAgB,QAAgB;CACnD,IAAI;EACF,MAAM,SAAS,MAAM,IAAI,MAAM;GAAE,KAAK,qBAAqB,MAAM;GAAG,WAAW;EAAM,CAAC;EACtF,OAAO;GAAE,WAAW,OAAO,SAAS;GAAG,SAAS,OAAO,SAAS,IAAI,OAAO,SAAS,OAAO,UAAU,OAAO,OAAA,CAAQ,KAAK;EAAE;CAC7H,SAAS,OAAO;EAAE,OAAO;GAAE,WAAW;GAAO,QAAQ,QAAQ,KAAK,CAAC,CAAC;EAAQ;CAAG;AACjF;AAEA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+Bb,eAAe,OAAsB;CACnC,MAAM,EAAE,QAAQ,aAAa,WAAW,UAAU;EAChD,kBAAkB;EAClB,QAAQ;EACR,SAAS;GACP,QAAQ;IAAE,MAAM;IAAU,SAAS;GAAe;GAClD,cAAc;IAAE,MAAM;IAAW,SAAS;GAAM;GAChD,SAAS,EAAE,MAAM,SAAS;GAC1B,QAAQ,EAAE,MAAM,UAAU;GAC1B,MAAM,EAAE,MAAM,SAAS;GACvB,yBAAyB,EAAE,MAAM,UAAU;GAC3C,SAAS,EAAE,MAAM,UAAU;GAC3B,QAAQ,EAAE,MAAM,UAAU;GAC1B,SAAS,EAAE,MAAM,UAAU;GAC3B,SAAS;IAAE,MAAM;IAAW,OAAO;GAAI;GACvC,MAAM;IAAE,MAAM;IAAW,OAAO;GAAI;EACtC;CACF,CAAC;CACD,MAAM,CAAC,SAAS,GAAG,QAAQ;CAC3B,IAAI,OAAO,SAAS;EAClB,MAAM,WAAW,KAAK,MAAM,aAAa,KAAK,aAAa,cAAc,GAAG,MAAM,CAAC;EACnF,QAAQ,IAAI,SAAS,OAAO;EAC5B;CACF;CACA,IAAI,CAAC,WAAW,YAAY,UAAU,OAAO,MAAM;EAAE,QAAQ,IAAI,IAAI;EAAG;CAAQ;CAChF,MAAM,QAAkC;EACtC,OAAO,CAAC;EAAG,SAAS,CAAC,WAAW,QAAQ;EAAG,QAAQ,CAAC,WAAW,QAAQ;EAAG,WAAW,CAAC,WAAW,QAAQ;EACzG,MAAM,CAAC,UAAU,uBAAuB;EAAG,QAAQ;GAAC;GAAU;GAAc;GAAQ;GAAW;EAAQ;EACvG,SAAS,CAAC,UAAU,YAAY;EAAG,MAAM,CAAC,UAAU,YAAY;EAAG,UAAU,CAAC,UAAU,YAAY;EAAG,SAAS,CAAC,UAAU,YAAY;EACvI,MAAM,CAAC,UAAU,YAAY;EAAG,QAAQ,CAAC,UAAU,YAAY;EAAG,QAAQ,CAAC,UAAU,YAAY;EAAG,OAAO,CAAC,UAAU,YAAY;EAClI,QAAQ,CAAC,UAAU,YAAY;EAAG,MAAM;GAAC;GAAU;GAAc;EAAS;EAAG,OAAO,CAAC,UAAU,YAAY;EAC3G,oBAAoB,CAAC,UAAU,YAAY;EAAG,WAAW;GAAC;GAAU;GAAc;GAAU;EAAS;EAAG,UAAU,CAAC,UAAU,YAAY;EACzI,QAAQ,CAAC,UAAU,SAAS;CAC9B;CACA,IAAI,EAAE,WAAW,QAAQ,MAAM,IAAI,MAAM,mBAAmB,QAAQ,yBAAyB;CAC7F,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,SAAS,YAAY,CAAC,MAAM,QAAQ,CAAC,SAAS,MAAM,IAAI,GAAG,MAAM,IAAI,MAAM,GAAG,QAAQ,qBAAqB,MAAM,MAAM;CAEnI,MAAM,aAAa,OAAO;CAC1B,MAAM,YAAY,OAAO;CACzB,IAAI,OAAO,UAAU,OAAO,SAAS,MAAM,IAAI,MAAM,wCAAwC;CAC7F,MAAM,QAAQ;EAAE,SAAS,OAAO;EAAS,QAAQ,OAAO;CAAO;CAC/D,IAAI,YAAY,SAAS;EAAE,MAAM,MAAM,GAAG,GAAG,OAAO;EAAG,MAAM,KAAK;EAAG;CAAQ;CAC7E,IAAI,YAAY,aAAa,YAAY,YAAY,YAAY,aAAa;EAC5E,MAAM,MAAM,GAAG,GAAG,GAAG,QAAQ,2CAA2C;EAExE,OADkB,YAAY,YAAY,qBAAqB,YAAY,WAAW,oBAAoB,qBAAA,CAC1F,KAAK,IAAI,KAAK,CAAC;EAC/B;CACF;CACA,IAAI,YAAY,YAAY,OAAO,MAAM;EACvC,MAAM,MAAM,GAAG,GAAG,yDAAyD;EAC3E,MAAM,SAAS,mBAAmB,OAAO,MAAM,KAAK;EACpD,MAAM,MAAM;EACZ,IAAI,CAAC,OAAO,WAAW,QAAQ,WAAW;EAC1C;CACF;CACA,IAAI,YAAY,aAAa,OAAO,WAAW,OAAO,SAAS,MAAM,IAAI,MAAM,qDAAqD;CACpI,IAAI,YAAY,QAAQ;EACtB,MAAM,MAAM,GAAG,GAAG,kDAAkD;EACpE,MAAM,WAAW,KAAK,MAAM,aAAa,KAAK,aAAa,YAAY,cAAc,GAAG,MAAM,CAAC;EAC/F,IAAI,OAAO,0BAA0B,SAAS,sBAAsB;EACpE,UAAU,QAAQ,QAAQ,UAAU,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;EAC3D,cAAc,YAAY,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE,KAAK;GAAE,MAAM;GAAM,MAAM;EAAM,CAAC;EAC/F,MAAM;GAAE,QAAQ,QAAQ,UAAU;GAAG,gBAAgB,SAAS;GAAqB,MAAM;EAAsF,CAAC;EAChL;CACF;CACA,IAAI,YAAY,UAAU;EACxB,QAAQ,WAAW,MAAM,eAAe,SAAS,UAAU,GAAG,CAAC,GAAG,MAAM,GAAI,OAAO,UAAU,CAAC,WAAW,IAAI,CAAC,CAAE,CAAC;EACjH;CACF;CACA,MAAM,SAAS,WAAW,UAAU;CACpC,IAAI,cAAc,OAAO,eAAe,OAAO,eAAe,MAAM,IAAI,MAAM,oEAAoE;CAClJ,IAAI,aAAa,CAAC,aAAa,UAAU,CAAC,CAAC,SAAS,OAAO,GAAG,MAAM,IAAI,MAAM,yDAAyD;CACvI,IAAI,YAAY,UAAU;EACxB,MAAM,MAAM,GAAG,GAAG,sBAAsB;EACxC,MAAM,kBAAkB,QAAQ,UAAU,KAAK,EAAE,CAAC,CAAC;EACnD;CACF;CACA,IAAI,YAAY,UAAU;EACxB,MAAM,MAAM,GAAG,GAAG,uBAAuB;EACzC,MAAM,UAAU,OAAO,YAAY,KAAK,OAAO,UAAU,YAAY,OAAO,SAAS,IAAI;EACzF,MAAM,CAAC,cAAc,SAAS,MAAM,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC,cAAc,UAAU,GAAG,MAAM,CAAC,CAAC;EAClI,MAAM,cAAc,qBAAqB,MAAM;EAC/C,MAAM,YAAY,CAAC,GAAG,IAAI,IAAI;GAAC,GAAG,OAAO,aAAa;GAAe,GAAG,OAAO,aAAa;GAAQ,GAAG,OAAO,aAAa;EAAO,CAAC,CAAC,KAAK,CAAC,CAAC,SAAQ,QAAO,CAAC,GAAG,IAAI,SAAS,0BAA0B,CAAC,CAAC,CAAC,KAAI,UAAS,MAAM,EAAE,CAAC,CAAC,CAAC;EAChO,MAAM,SAAS;GACb;IAAE,MAAM;IAA8B,WAAW,OAAO;IAAqB,QAAQ,OAAO,oBAAoB;GAAuF;GACvM;IAAE,MAAM;IAAW,GAAG;GAAa;GAAG;IAAE,MAAM;IAAS,GAAG;GAAM;GAChE,GAAG,UAAU,KAAI,UAAS;IAAE;IAAM,WAAW,QAAQ,YAAY,KAAK;IAAG,QAAQ,YAAY,QAAQ,yEAAyE,OAAO,KAAK;GAAuC,EAAE;EACrO;EACA,IAAI,OAAO,aAAa,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;EAC1D,MAAM;GAAE;GAAQ,mBAAmB,OAAO;GAAa,OAAO;EAAmF,CAAC;EAClJ,IAAI,OAAO,MAAK,UAAS,CAAC,MAAM,SAAS,GAAG,QAAQ,WAAW;EAC/D;CACF;CACA,MAAM,QAAQ,IAAI,MAAM,OAAO,QAAQ;CACvC,IAAI;EACF,IAAI,YAAY,WAAW;GACzB,MAAM,MAAM,GAAG,GAAG,uBAAuB;GACzC,MAAM,EAAE,MAAM,cAAc,iBAAiB,UAAU,KAAK,EAAE,CAAC;GAC/D,IAAI,OAAO,aAAa,kBAAkB,IAAI;GAC9C,MAAM,KAAK,MAAM,QAAQ,MAAM,QAAQ,SAAS,CAAC,CAAC;EACpD,OAAO,IAAI,YAAY,QAAQ;GAC7B,MAAM,MAAM,GAAG,GAAG,kBAAkB;GACpC,MAAM,SAAS,MAAM,UAAU,OAAO,QAAQ,EAAE,SAAS,OAAO,QAAQ,CAAC;GACzE,MAAM,MAAM;GACZ,IAAI,OAAO,SAAS,OAAO,QAAQ,MAAK,UAAS,MAAM,WAAW,OAAO,GAAG,QAAQ,WAAW;EACjG,OAAO,IAAI,YAAY,SAAS;GAC9B,MAAM,MAAM,GAAG,GAAG,OAAO;GACzB,MAAM,MAAM,aAAa,CAAC;EAC5B,OAAO,IAAI,YAAY,UAAU;GAC/B,MAAM,MAAM,GAAG,GAAG,aAAa;GAC/B,MAAM,KAAK,KAAK,MAAM,IAAI,KAAK,EAAE,IAAI,MAAM,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC;EAC7D,OAAO,IAAI,YAAY,UAAU;GAC/B,MAAM,MAAM,GAAG,GAAG,aAAa;GAC/B,MAAM,MAAM,OAAO,KAAK,EAAE,CAAC;EAC7B,OAAO,IAAI,YAAY,QAAQ;GAC7B,MAAM,MAAM,GAAG,GAAG,WAAW;GAC7B,MAAM,SAAS,MAAM,SAAS,OAAO,KAAK,IAAI,EAAE,UAAU,CAAC;GAC3D,MAAM,MAAM;GACZ,IAAI,OAAO,IAAI,WAAW,aAAa,OAAO,IAAI,WAAW,UAAU,QAAQ,WAAW;EAC5F,OAAO,IAAI,YAAY,YAAY;GACjC,MAAM,MAAM,GAAG,GAAG,yCAAyC;GAC3D,QAAQ,MAAM,aAAa,OAAO,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK,UAAU,KAAK,EAAE,IAAI,KAAA,GAAW,EAAE,UAAU,CAAC,CAAC;EAC9G,OAAO,IAAI,YAAY,WAAW;GAChC,MAAM,MAAM,GAAG,GAAG,wBAAwB;GAC1C,QAAQ,YAAY,OAAO,KAAK,IAAI,KAAK,IAAI,EAAE,UAAU,CAAC,CAAC;EAC7D,OAAO,IAAI,YAAY,QAAQ;GAC7B,MAAM,MAAM,GAAG,GAAG,WAAW;GAC7B,MAAM,aAAa,IAAI,gBAAgB;GACvC,MAAM,aAAmB,WAAW,MAAM;GAC1C,QAAQ,GAAG,UAAU,IAAI;GACzB,QAAQ,GAAG,WAAW,IAAI;GAC1B,IAAI;IAAE,QAAQ,MAAM,QAAQ,OAAO,QAAQ,KAAK,IAAI;KAAE,QAAQ,WAAW;KAAQ;IAAU,CAAC,CAAC;GAAG,UACxF;IAAE,QAAQ,eAAe,UAAU,IAAI;IAAG,QAAQ,eAAe,WAAW,IAAI;GAAG;EAC7F,OAAO,IAAI,YAAY,oBAAoB;GACzC,MAAM,MAAM,GAAG,GAAG,8CAA8C;GAChE,MAAM,EAAE,MAAM,cAAc,iBAAiB,UAAU,KAAK,EAAE,CAAC;GAC/D,MAAM,KAAK,MAAM,gBAAgB,KAAK,IAAI,MAAM,SAAS,CAAC,CAAC;EAC7D,OAAO,IAAI,YAAY,SAAS;GAC9B,MAAM,MAAM,GAAG,GAAG,YAAY;GAC9B,MAAM,KAAK,MAAM,WAAW,KAAK,KAAI,QAAO;IAC1C,IAAI,cAAc,IAAI,OAAO,eAAe,IAAI,OAAO,eAAe,MAAM,IAAI,MAAM,qEAAqE;IAC3J,IAAI,CAAC;KAAC;KAAW;KAAS;IAAO,CAAC,CAAC,SAAS,IAAI,MAAM,GAAG,MAAM,IAAI,MAAM,gBAAgB,IAAI,OAAO,mDAAmD;IACvJ,IAAI,IAAI,MAAM,MAAM,IAAI,MAAM,iEAAiE;IAC/F,MAAM,eAAe,KAAK,UAAU,OAAO,YAAY,MAAM,KAAK,UAAU,IAAI,OAAO,YAAY,KAAK,KAAK,UAAU,OAAO,YAAY,MAAM,KAAK,UAAU,IAAI,OAAO,YAAY,KAAK,KAAK,UAAU,OAAO,SAAS,MAAM,KAAK,UAAU,IAAI,OAAO,SAAS,KAAM,IAAI,kBAAkB,QAAQ,CAAC,IAAI;IAC5S,IAAI,gBAAgB,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,QAAQ,MAAM,IAAI,MAAM,4HAA4H;IACjM,MAAM,QAAsB,gBAAgB,IAAI,iBAAiB;KAAE,OAAO;KAAU,gBAAgB;KAAM,0BAA0B;KAAM,QAAQ;KAAM,UAAU;IAAK,IAAI,CAAC;IAC5K,MAAM,gBAAgB;KAAE,GAAG;KAAQ,eAAe,IAAI,OAAO,cAAc,QAAiB,OAAO;KAAe,aAAa,IAAI,OAAO;KAAa,cAAc,IAAI,OAAO;IAAa;IAC7L,OAAO;KAAE,GAAG;KAAO,QAAQ;KAAe,QAAQ;KAAU,gBAAgB;KAAM,QAAQ,KAAK,IAAI;KAAG,OAAO;IAAK;GACpH,CAAC,CAAC,CAAC;EACL,OAAO,IAAI,YAAY,aAAa;GAClC,MAAM,MAAM,GAAG,GAAG,qCAAqC;GACvD,IAAI,CAAC,OAAO,QAAQ,MAAM,IAAI,MAAM,6BAA6B;GACjE,MAAM,KAAK,MAAM,WAAW,KAAK,KAAI,QAAO;IAC1C,IAAI,IAAI,QAAQ,CAAC;KAAC;KAAS;KAAW;IAAO,CAAC,CAAC,SAAS,IAAI,MAAM,KAAK,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,UAAU,IAAI,UAAU,WAAW,MAAM,IAAI,MAAM,iFAAiF;IACpO,MAAM,aAAa,kBAAkB,IAAI,IAAI;IAC7C,IAAI,OAAO,WAAW,CAAC,gBAAgB,KAAK,WAAW,qBAAqB,EAAE,GAAG,MAAM,IAAI,MAAM,mFAAmF;IAEpL,OAAO;KAAE,QAAQ;MADC,GAAG,IAAI;MAAQ,eAAe;MAAgB,aAAa;MAAM,cAAc,QAAQ,OAAO,OAAO;KAChG;KAAG,QAAQ,CAAC,SAAS,OAAO,CAAC,CAAC,SAAS,IAAI,MAAM,IAAI,WAAW;KAAW,QAAQ,KAAK,IAAI;IAAE;GACvH,CAAC,CAAC,CAAC;EACL,OAAO,IAAI,YAAY,YAAY;GACjC,MAAM,MAAM,GAAG,GAAG,sBAAsB;GACxC,MAAM,WAAW,cAAc,KAAK,IAAI,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,KAAK;GACrF,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,mCAAmC;GAClE,MAAM,KAAK,MAAM,WAAW,KAAK,KAAI,QAAO;IAC1C,IAAI,IAAI,QAAQ,IAAI,UAAU,aAAa,IAAI,aAAa,WAAW,cAAc,IAAI,WAAW,WAAW,MAAM,IAAI,MAAM,+DAA+D;IAC9L,MAAM,OAAO,gBAAgB,IAAI,IAAI;IACrC,IAAI,CAAC,KAAK,OAAO,eAAe,CAAC,QAAQ,KAAK,KAAK,MAAM,WAAW,GAAG,MAAM,IAAI,MAAM,wEAAwE;IAC/J,KAAK,MAAM,cAAc,OAAO,OAAO,KAAK,MAAM,WAAW,IAAI,EAAE;IAEnE,OAAO;KAAE;KAAM,QAAQ;MADC,GAAG;MAAQ,eAAe,IAAI,OAAO,cAAc,QAAiB,OAAO;MAAe,aAAa,IAAI,OAAO;MAAa,cAAc,IAAI,OAAO;KAC7I;KAAG;KAAU,QAAQ;KAAU,OAAO;KAAS,WAAW,KAAK,IAAI;KAAG,UAAU,CAAC;KAAG,WAAW;KAAG,QAAQ,KAAK,IAAI;KAAG,SAAS,CAAC;KAAG,SAAS;KAAM,eAAe;KAAM,gBAAgB;KAAM,0BAA0B;KAAM,QAAQ;KAAM,OAAO;IAAK;GAC5R,CAAC,CAAC,CAAC;EACL;CACF,UAAU;EAAE,MAAM,MAAM;CAAG;AAC7B;AAEA,KAAK,CAAC,CAAC,OAAM,UAAS;CAAE,QAAQ,MAAM,KAAK,UAAU,EAAE,OAAO,QAAQ,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;CAAG,QAAQ,WAAW;AAAG,CAAC"}
|
|
1
|
+
{"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, mkdtempSync, rmSync } from 'node:fs';\nimport { spawnSync } from 'node:child_process';\nimport { resolve, dirname, join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { fileURLToPath } from 'node:url';\nimport { parseArgs } from 'node:util';\nimport { canonicalPath, loadConfig, loadJSON, expandArgv, normalizeIsolationPaths, validateProjectSource } from './config.js';\nimport { Store } from './store.js';\nimport { run, executionEnvironment } from './process.js';\n\nimport { runStep } from './scheduler.js';\nimport { nextTurn, completeTurn, abandonTurn } from './runner.js';\nimport { hosts, installIntegration, updateIntegration, inspectIntegration, uninstallIntegration } from './integrations.js';\nimport { submitRequirement, scanInbox } from './inbox.js';\nimport { MAX_INPUT_BYTES, parseRequirement, readInputFile } from './requirements.js';\nimport { dispatchRemote } from './remote.js';\nimport { FrameworkSchema, PlatformSchema, PackageTargetSchema, toError, validateJobConfig } from './schemas.js';\nimport type { Config, Framework, Job, Platform } from './schemas.js';\nimport { assertProject, doctorCommands } from './project-profiles.js';\nimport { closestOwnedGoWorkspace } from './go-dependencies.js';\nimport { validateMyGoCommand } from './mygo-build.js';\nimport { invalidateVerification, verificationConfigChanged } from './proof.js';\nimport { prepareIsolatedCommand, removeConfinedPath, type IsolatedCommand } from './isolation.js';\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst print = (value: unknown): void => console.log(JSON.stringify(value, null, 2));\nconst view = (job: Job) => ({ id: job.id, product: job.spec.id, framework: job.spec.framework, platform: job.spec.platform, channel: job.spec.channel, version: job.spec.version, stage: job.stage, status: job.status, hostTurns: job.hostTurns, attempts: job.attempts, workspace: job.workspace, artifact: job.artifact ?? null, error: job.error ?? null });\n\nfunction inputJSON(path: string): unknown {\n const bytes = path === '-' ? readFileSync(0) : readInputFile(path);\n if (bytes.length > MAX_INPUT_BYTES) throw new Error(`Input exceeds ${MAX_INPUT_BYTES} bytes`);\n return JSON.parse(bytes.toString('utf8')) as unknown;\n}\n\nfunction arity(args: string[], minimum: number, maximum: number, usage: string): void {\n if (args.length < minimum || args.length > maximum) throw new Error(`Usage: apphx ${usage}`);\n}\n\nfunction outcome(job: Job): void {\n print(view(job));\n if (job.status === 'blocked' || job.status === 'failed') process.exitCode = 2;\n}\n\nasync function probe(argv: string[], config: Config, context?: { cwd: string; env: NodeJS.ProcessEnv; sourceRoot?: string }) {\n let temporary: string | undefined;\n let isolated: IsolatedCommand | undefined;\n try {\n const env = context?.env ?? executionEnvironment(config);\n const expanded = expandArgv(argv, env);\n validateMyGoCommand(config, expanded);\n if (config.isolation) {\n if (!config.allowLocalExecution) return { available: false, detail: 'Owner must enable local execution before isolated probes run' };\n temporary = mkdtempSync(join(tmpdir(), 'apphx-doctor-'));\n const scoped: Config = { ...config, isolation: { ...config.isolation, readOnlyPaths: [...config.isolation.readOnlyPaths, ...(context?.sourceRoot ? [canonicalPath(context.sourceRoot)] : [])] } };\n normalizeIsolationPaths(scoped);\n isolated = prepareIsolatedCommand(expanded, { config: scoped, workspace: temporary, cwd: context?.cwd ?? temporary, env, scratchParent: temporary });\n }\n const result = await run(isolated?.argv ?? expanded, { cwd: context?.cwd ?? temporary, env: isolated?.env ?? env, timeoutMs: 30000 });\n return { available: result.code === 0, detail: (result.code === 0 ? result.stdout : result.stderr || result.stdout).trim() };\n } catch (error) { return { available: false, detail: toError(error).message }; }\n finally {\n isolated?.cleanup();\n if (temporary) removeConfinedPath(temporary, temporary);\n }\n}\n\nconst frameworks = FrameworkSchema.options;\nconst packageTargets = PackageTargetSchema.options;\n\nfunction initialConfig(framework: Framework, platform: Platform, target: Config['packageTarget']): Record<string, unknown> {\n if ((framework === 'mygo') !== (platform === 'macos')) throw new Error(`${framework} does not support ${platform}`);\n if ((framework === 'android-java' && platform !== 'android') || (framework === 'swift' && platform !== 'ios')) throw new Error(`${framework} does not support ${platform}`);\n const allowedTargets = platform === 'macos' ? ['app', 'dmg'] : platform === 'ios' ? ['simulator', 'ipa'] : ['apk', 'aab'];\n if (!allowedTargets.includes(target)) throw new Error(`${target} does not match platform ${platform}`);\n const template = JSON.parse(readFileSync(join(packageRoot, 'examples', `${framework}.factory.json`), 'utf8')) as Record<string, unknown>;\n template.packageTarget = target;\n if (framework === 'mygo') {\n template.packaging = {\n provider: 'local',\n commands: [['go', 'tool', 'mygo', 'build', '-platform', 'darwin/arm64', '-sign', '-', '-skip-notarize', ...(target === 'app' ? ['-skip-dmg'] : []), '-o', 'build']],\n artifactPath: target === 'app' ? 'build/darwin-arm64/MyGo App.app' : 'build/darwin-arm64/MyGo App 0.1.0.dmg',\n };\n } else if (framework === 'flutter') {\n template.executionEnv = platform === 'ios' ? ['IOS_DEVICE_ID'] : ['ANDROID_DEVICE_ID'];\n template.verification = {\n prerequisites: platform === 'ios' ? [['xcodebuild', '-version']] : [['java', '-version'], ['adb', 'version']],\n checks: [['flutter', 'analyze', '--fatal-infos'], ['flutter', 'test']],\n runtime: [['flutter', 'drive', '--driver', 'test_driver/integration_test.dart', '--target', 'integration_test/app_test.dart', '-d', platform === 'ios' ? '${IOS_DEVICE_ID}' : '${ANDROID_DEVICE_ID}', '--no-pub']],\n };\n } else if (framework === 'expo') {\n const device = platform === 'ios' ? 'IOS_DEVICE_ID' : 'ANDROID_DEVICE_ID';\n const profile = target === 'simulator' ? 'simulator' : target === 'apk' ? 'apk' : 'production';\n const output = target === 'simulator' ? 'build/simulator.tar.gz' : `build/app.${target}`;\n template.executionEnv = [device, ...(platform === 'android' ? ['ANDROID_HOME'] : [])];\n template.verification = {\n prerequisites: [['node', '--version'], ['eas', '--version']],\n checks: [['npm', 'run', 'lint'], ['npm', 'test', '--', '--runInBand']],\n runtime: [['npm', 'run', 'test:e2e', '--', '--platform', platform, '--device', '${' + device + '}']],\n };\n template.packaging = {\n provider: 'local',\n commands: [['eas', 'build', '--platform', platform, '--profile', profile, '--local', '--non-interactive', '--output', output], ...(target === 'simulator' ? [['tar', '-xzf', output, '-C', 'build']] : [])],\n artifactPath: target === 'simulator' ? 'build/App.app' : output,\n };\n } else if (platform === 'ios') {\n const native = framework === 'swift' ? '.' : framework === 'uni-app' ? 'native/ios' : 'ios';\n const project = framework === 'swift' ? ['-project', 'App.xcodeproj'] : ['-workspace', `${native}/App.xcworkspace`];\n const base = ['xcodebuild', ...project, '-scheme', 'App'];\n template.executionEnv = ['IOS_DEVICE_ID'];\n template.verification = {\n prerequisites: [['xcodebuild', '-version'], ...(framework === 'swift' ? [] : [['node', '--version'], ['npm', '--version']])],\n checks: framework === 'swift' ? [[...base, 'build-for-testing', '-destination', 'generic/platform=iOS Simulator', '-derivedDataPath', 'build/DerivedData']] : [['npm', 'run', 'lint'], ['npm', 'test', '--', '--runInBand']],\n runtime: framework === 'swift' ? [[...base, 'test', '-destination', 'id=${IOS_DEVICE_ID}', '-derivedDataPath', 'build/DerivedData']] : [['npm', 'run', 'test:e2e', '--', '--platform', 'ios', '--device', '${IOS_DEVICE_ID}']],\n };\n template.packaging = target === 'simulator' ? {\n commands: [[...base, 'build', '-configuration', 'Debug', '-destination', 'generic/platform=iOS Simulator', '-derivedDataPath', 'build/DerivedData']],\n artifactPath: 'build/DerivedData/Build/Products/Debug-iphonesimulator/App.app', provider: 'local',\n } : {\n commands: [[...base, 'archive', '-configuration', 'Release', '-destination', 'generic/platform=iOS', '-archivePath', 'build/App.xcarchive'], ['xcodebuild', '-exportArchive', '-archivePath', 'build/App.xcarchive', '-exportPath', 'build/export', '-exportOptionsPlist', 'ExportOptions.plist']],\n artifactPath: 'build/export/App.ipa', provider: 'local',\n };\n } else if (target === 'apk') {\n const packaging = template.packaging as { commands: string[][]; artifactPath: string };\n packaging.commands = packaging.commands.map(argv => argv.map(arg => arg === ':app:bundleRelease' ? ':app:assembleRelease' : arg));\n packaging.artifactPath = packaging.artifactPath.replace('bundle/release/app-release.aab', 'apk/release/app-release.apk');\n }\n return template;\n}\n\nconst help = `apphx <command> [--config factory.json] [--build-only]\n hosts List supported agent hosts and activation commands\n install <host> Install the workflow in the current project\n update <host> Update an existing, unmodified host workflow\n uninstall <host> Remove an unchanged installation owned by this package\n --project <directory> Select the project (default: current directory)\n --global Use the host's user-level skill directory instead\n doctor --host <host> Check installed workflow files; does not run the agent\n init [--allow-local-execution] Create owner-editable factory.json; default Flutter/iOS\n --framework <stack> flutter|android-java|swift|react-native|expo|uni-app|mygo\n --platform <platform> ios|android|macos (mygo defaults macos; android-java android)\n --package-target <target> simulator|ipa|apk|aab|app|dmg (MyGo app; Expo iOS ipa)\n doctor [spec.json] Check configured prerequisites and optional stack tools\n enqueue <spec.json|-> Persist requirements and return a task ID\n next <id> Resume a host turn or show the next deterministic action\n complete <id> <turn> [json|-] Record research/review, or finish the host's build turn\n abandon <id> <turn> Abandon a host turn without resetting its budget\n step <id> Execute one obfuscation, verification or packaging stage\n status [id] Read durable task state as JSON\n events <id> Read task transitions and evidence\n retry <id> Resume stopped work; preserve budgets and proofs\n submit <spec.json|-> Write requirements to the configured inbox\n scan [--observe] Validate or ingest inbox files; never start an agent\n inbox Read durable intake results\n reconcile-intake <id> <json|-> Restore a legacy request identity from original input\n remote <command> Call an installed Mac CLI over SSH (build-only)\n obfuscator <project> Run the bundled deterministic obfuscator on a project copy\n --config <file> Obfuscator options as JSON (required)\n --framework <stack> flutter|android-java|swift|react-native|expo|uni-app|mygo\n --seed <text> Determinism seed\n --version Print the installed package version\n\nYour agent supplies the model, session, tools and native delegation.\nNo coding-agent subprocess or autonomous daemon is started by this CLI.\nOnly verified local artifacts reach built. Store submission and review are manual human work outside this tool.`;\n\nasync function main(): Promise<void> {\n const { values, positionals, tokens } = parseArgs({\n allowPositionals: true,\n tokens: true,\n options: {\n config: { type: 'string', default: 'factory.json' },\n 'build-only': { type: 'boolean', default: false },\n project: { type: 'string' },\n global: { type: 'boolean' },\n host: { type: 'string' },\n 'allow-local-execution': { type: 'boolean' },\n framework: { type: 'string' },\n seed: { type: 'string' },\n platform: { type: 'string' },\n 'package-target': { type: 'string' },\n observe: { type: 'boolean' },\n version: { type: 'boolean', short: 'v' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n const [command, ...args] = positionals;\n if (values.version) {\n const metadata = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8')) as { version: string };\n console.log(metadata.version);\n return;\n }\n if (!command || command === 'help' || values.help) { console.log(help); return; }\n const flags: Record<string, string[]> = {\n hosts: [], install: ['project', 'global'], update: ['project', 'global'], uninstall: ['project', 'global'],\n init: ['config', 'allow-local-execution', 'framework', 'platform', 'package-target'], doctor: ['config', 'build-only', 'host', 'project', 'global'],\n enqueue: ['config', 'build-only'], next: ['config', 'build-only'], complete: ['config', 'build-only'], abandon: ['config', 'build-only'],\n step: ['config', 'build-only'], status: ['config', 'build-only'], events: ['config', 'build-only'], retry: ['config', 'build-only'],\n submit: ['config', 'build-only'], scan: ['config', 'build-only', 'observe'], inbox: ['config', 'build-only'],\n 'reconcile-intake': ['config', 'build-only'],\n remote: ['config', 'observe'],\n obfuscator: ['config', 'framework', 'seed'],\n };\n if (!(command in flags)) throw new Error(`Unknown command ${command}; run apphx --help`);\n for (const token of tokens) {\n if (token.kind === 'option' && !flags[command].includes(token.name)) throw new Error(`${command} does not accept --${token.name}`);\n }\n const configPath = values.config;\n const buildOnly = values['build-only'];\n if (values.global && values.project) throw new Error('Choose --project or --global, not both');\n const scope = { project: values.project, global: values.global };\n if (command === 'obfuscator') {\n arity(args, 1, 1, 'obfuscator <project> --config <file> [--framework <stack>] [--seed <text>]');\n const bundled = join(packageRoot, 'dist', 'vendor', 'obfuscator', 'dist', 'cli.js');\n if (!existsSync(bundled)) throw new Error(`Bundled obfuscator is missing at ${bundled}; reinstall the apphx package`);\n const forward = [bundled, '--project', resolve(args[0]!)];\n // Forward only flags that were actually given, so the bundled binary sees exactly what the user\n // typed; an explicit empty value must reach the child and be rejected there, not dropped here.\n const configGiven = tokens.some(token => token.kind === 'option' && token.name === 'config');\n if (configGiven) forward.push('--config', resolve(values.config));\n if (values.framework !== undefined) forward.push('--framework', values.framework);\n if (values.seed !== undefined) forward.push('--seed', values.seed);\n const result = spawnSync(process.execPath, forward, { stdio: 'inherit' });\n if (result.error) throw result.error;\n process.exitCode = result.status ?? 1;\n return;\n }\n if (command === 'hosts') { arity(args, 0, 0, 'hosts'); print(hosts); return; }\n if (command === 'install' || command === 'update' || command === 'uninstall') {\n arity(args, 1, 1, `${command} <host> [--project <directory> | --global]`);\n const operation = command === 'install' ? installIntegration : command === 'update' ? updateIntegration : uninstallIntegration;\n print(operation(args[0], scope));\n return;\n }\n if (command === 'doctor' && values.host) {\n arity(args, 0, 0, 'doctor --host <host> [--project <directory> | --global]');\n const result = inspectIntegration(values.host, scope);\n print(result);\n if (!result.installed) process.exitCode = 2;\n return;\n }\n if (command === 'doctor' && (values.project || values.global)) throw new Error('--project and --global require doctor --host <host>');\n if (command === 'init') {\n arity(args, 0, 0, 'init [--framework <stack>] [--platform ios|android|macos] [--package-target simulator|ipa|apk|aab|app|dmg] [--config <file>] [--allow-local-execution]');\n const framework = values.framework ?? 'flutter';\n if (!frameworks.includes(framework as Framework)) throw new Error(`Unknown framework ${framework}; choose ${frameworks.join(', ')}`);\n const platform = PlatformSchema.parse(values.platform ?? (framework === 'mygo' ? 'macos' : framework === 'android-java' ? 'android' : 'ios'));\n const target = values['package-target'] ?? (platform === 'macos' ? 'app' : platform === 'ios' ? framework === 'expo' ? 'ipa' : 'simulator' : 'apk');\n if (!packageTargets.includes(target as Config['packageTarget'])) throw new Error(`Unknown package target ${target}; choose ${packageTargets.join(', ')}`);\n const template = initialConfig(framework as Framework, platform, target as Config['packageTarget']);\n if (values['allow-local-execution']) template.allowLocalExecution = true;\n mkdirSync(dirname(resolve(configPath)), { recursive: true });\n writeFileSync(configPath, `${JSON.stringify(template, null, 2)}\\n`, { flag: 'wx', mode: 0o600 });\n print({ config: resolve(configPath), framework, platform, packageTarget: target, localExecution: template.allowLocalExecution, next: framework === 'mygo' ? 'Pin MyGo v0.3.0 in go.mod (Go 1.27.1), match app name/version/arch and artifact path, and implement real desktop UI acceptance in cmd/acceptance. Native UI needs no Bun. Local ad-hoc builds only; init creates configuration, not source.' : framework === 'expo' ? 'Configure your existing eas.json production (store IPA/AAB), apk (Android buildType apk), or simulator (ios.simulator true) profile, real device acceptance, and exact app product/output path; no prebuild/eject is requested. Run apphx doctor <spec.json> --build-only.' : 'Adapt module/scheme, real device acceptance, signing and artifact path to your project; then run apphx doctor <spec.json> --build-only. init creates configuration, not app source.' });\n return;\n }\n if (command === 'remote') {\n process.exitCode = await dispatchRemote(loadJSON(configPath), [...args, ...(values.observe ? ['--observe'] : [])]);\n return;\n }\n const config = loadConfig(configPath);\n if (command === 'submit') {\n arity(args, 1, 1, 'submit <spec.json|->');\n print(submitRequirement(config, inputJSON(args[0])));\n return;\n }\n if (command === 'doctor') {\n arity(args, 0, 1, 'doctor [spec.json] [--build-only]');\n const spec = args[0] ? parseRequirement(inputJSON(args[0])).spec : undefined;\n let prerequisiteContext: { cwd: string; env: NodeJS.ProcessEnv; sourceRoot?: string } | undefined;\n if (spec) {\n validateJobConfig(spec, config);\n let source: string | undefined;\n try { source = validateProjectSource(spec, config); }\n catch (error) {\n if (spec.framework !== 'mygo' || (error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n const directory = spec.project?.directory ?? '.';\n const project = source ? resolve(source, directory) : undefined;\n if (source && project && (spec.framework !== 'mygo' || existsSync(project))) {\n assertProject(project, spec);\n if (spec.framework === 'mygo' || config.isolation) prerequisiteContext = {\n cwd: project, sourceRoot: source,\n env: { ...executionEnvironment(config), ...(spec.framework === 'mygo' ? { GOWORK: closestOwnedGoWorkspace(source, directory) ?? 'off', GOENV: 'off', GOTOOLCHAIN: 'local', GOFLAGS: '-mod=readonly' } : {}) },\n };\n }\n }\n const commands = spec && config.packaging?.provider !== 'cloud' ? doctorCommands(spec.framework, spec.platform) : [];\n const tools = await Promise.all(commands.map(async ({ name, argv }) => ({ name, ...await probe(argv[0] === 'flutter' && config.toolchain ? [join(config.toolchain.flutterSdk, 'bin', 'flutter'), ...argv.slice(1)] : argv, config) })));\n const prerequisites = await Promise.all(config.verification.prerequisites.map(async (argv, index) => ({\n name: `configured-prerequisite-${index + 1}`,\n ...(!config.allowLocalExecution\n ? { available: false, detail: 'Owner must enable allowLocalExecution before configured prerequisite commands run' }\n : spec?.framework === 'mygo' && !prerequisiteContext\n ? { available: false, detail: 'Project-scoped prerequisite cannot be checked yet: select an existing MyGo source app with project.sourceDir and project.directory; doctor does not create source or use the control module' }\n : await probe(argv, config, prerequisiteContext)),\n })));\n const environment = executionEnvironment(config);\n const configuredCommands = [...config.verification.prerequisites, ...config.verification.checks, ...config.verification.runtime, ...(config.packaging?.commands ?? [])];\n const neededEnv = [...new Set(configuredCommands.flat().flatMap(arg => [...arg.matchAll(/\\$\\{([A-Z][A-Z0-9_]*)\\}/g)].map(match => match[1])))];\n const checks = [\n { name: 'local-execution-permission', available: config.allowLocalExecution, detail: config.executionWarning ?? 'Trusted local commands permitted; host tools remain under the host permission policy' },\n ...(config.isolation ? [{ name: 'subprocess-isolation', ...await probe(['/usr/bin/true'], config), mode: config.isolation.mode, network: config.isolation.network }] : []),\n ...tools, ...prerequisites,\n ...neededEnv.map(name => ({ name, available: Boolean(environment[name]), detail: environment[name] ? 'Available in the configured execution environment; value not printed' : `Set ${name} and include its name in executionEnv` })),\n ];\n print({ framework: spec?.framework ?? null, platform: spec?.platform ?? null, checks, note: spec ? 'Tool availability is not runtime acceptance; configured checks run in the task workspace during verify' : 'No stack assumed; pass spec.json for profile-specific probes and compatibility checks', model: 'Provided by your agent host; no separate model authentication is configured here' });\n if (checks.some(check => !check.available)) process.exitCode = 2;\n return;\n }\n const queuedRequirement = command === 'enqueue' ? (() => {\n arity(args, 1, 1, 'enqueue <spec.json|->');\n const requirement = parseRequirement(inputJSON(args[0]));\n validateJobConfig(requirement.spec, config);\n validateProjectSource(requirement.spec, config);\n return requirement;\n })() : undefined;\n const store = new Store(config.stateDir);\n try {\n if (command === 'enqueue') {\n const { spec, baseJobId } = queuedRequirement!;\n print(view(store.enqueue(spec, config, baseJobId)));\n } else if (command === 'scan') {\n arity(args, 0, 0, 'scan [--observe]');\n const result = await scanInbox(store, config, { observe: values.observe });\n print(result);\n if (result.error || result.entries.some(entry => entry.status === 'error')) process.exitCode = 2;\n } else if (command === 'inbox') {\n arity(args, 0, 0, 'inbox');\n print(store.inboxEntries());\n } else if (command === 'status') {\n arity(args, 0, 1, 'status [id]');\n print(args[0] ? store.get(args[0]) : store.list().map(view));\n } else if (command === 'events') {\n arity(args, 1, 1, 'events <id>');\n print(store.events(args[0]));\n } else if (command === 'next') {\n arity(args, 1, 1, 'next <id>');\n const result = await nextTurn(store, args[0], { buildOnly });\n print(result);\n if (result.job.status === 'blocked' || result.job.status === 'failed') process.exitCode = 2;\n } else if (command === 'complete') {\n arity(args, 2, 3, 'complete <id> <turn-id> [result.json|-]');\n outcome(await completeTurn(store, args[0], args[1], args[2] ? inputJSON(args[2]) : undefined, { buildOnly }));\n } else if (command === 'abandon') {\n arity(args, 2, 2, 'abandon <id> <turn-id>');\n outcome(abandonTurn(store, args[0], args[1], { buildOnly }));\n } else if (command === 'step') {\n arity(args, 1, 1, 'step <id>');\n const controller = new AbortController();\n const stop = (): void => controller.abort();\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n try { outcome(await runStep(store, config, args[0], { signal: controller.signal, buildOnly })); }\n finally { process.removeListener('SIGINT', stop); process.removeListener('SIGTERM', stop); }\n } else if (command === 'reconcile-intake') {\n arity(args, 2, 2, 'reconcile-intake <id> <original-spec.json|->');\n const { spec, baseJobId } = parseRequirement(inputJSON(args[1]));\n print(view(store.reconcileIntake(args[0], spec, baseJobId)));\n } else if (command === 'retry') {\n arity(args, 1, 1, 'retry <id>');\n print(view(store.transition(args[0], job => {\n if (!['blocked', 'ready', 'built'].includes(job.status)) throw new Error(`Cannot retry ${job.status}; budgets and active work cannot be reset by retry`);\n if (job.turn) throw new Error('Abandon the active host turn before changing task configuration');\n if (job.cloudBuildPending) throw new Error('Cloud packaging outcome is uncertain; reconcile the existing provider run rather than replaying it with retry');\n const resumedConfig = { ...config, packageTarget: config.packageTarget };\n const proofChanged = verificationConfigChanged(job, resumedConfig);\n const patch: Partial<Job> = proofChanged ? { ...invalidateVerification(), stage: ['verify', 'review', 'package'].includes(job.stage) ? 'verify' : job.stage } : {};\n validateJobConfig(job.spec, resumedConfig);\n return { ...patch, config: resumedConfig, status: 'queued', manualRecovery: null, nextAt: Date.now(), error: null };\n })));\n } else throw new Error(`Unknown command ${command}; use --help`);\n } finally { store.close(); }\n}\n\nmain().catch(error => { console.error(JSON.stringify({ error: toError(error).message })); process.exitCode = 1; });\n"],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConfigSchema, SpecSchema, toError } from "./schemas.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { basename, dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
4
3
|
import { existsSync, lstatSync, readFileSync, realpathSync } from "node:fs";
|
|
4
|
+
import { basename, dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
5
5
|
// src/config.ts
|
|
6
6
|
function loadJSON(path) {
|
|
7
7
|
try {
|
|
@@ -19,6 +19,26 @@ function canonicalPath(path) {
|
|
|
19
19
|
if (lstatSync(absolute, { throwIfNoEntry: false })?.isSymbolicLink()) throw new Error(`Cannot resolve dangling symlink at ${absolute}; point it to an existing directory before continuing`);
|
|
20
20
|
return resolve(canonicalPath(dirname(absolute)), basename(absolute));
|
|
21
21
|
}
|
|
22
|
+
function normalizeIsolationPaths(config) {
|
|
23
|
+
if (!config.isolation) return;
|
|
24
|
+
const root = config.configPath ? dirname(resolve(config.configPath)) : process.cwd();
|
|
25
|
+
const protectedPaths = [
|
|
26
|
+
config.stateDir,
|
|
27
|
+
config.workspaceRoot,
|
|
28
|
+
...config.configPath ? [config.configPath] : []
|
|
29
|
+
].map((path) => canonicalPath(resolve(root, path)));
|
|
30
|
+
const contains = (parent, child) => {
|
|
31
|
+
const path = relative(parent, child);
|
|
32
|
+
return path === "" || path !== ".." && !path.startsWith(`..${sep}`) && !isAbsolute(path);
|
|
33
|
+
};
|
|
34
|
+
config.isolation.readOnlyPaths = [...new Set(config.isolation.readOnlyPaths.map((path) => {
|
|
35
|
+
const absolute = canonicalPath(resolve(root, path));
|
|
36
|
+
const info = lstatSync(absolute, { throwIfNoEntry: false });
|
|
37
|
+
if (!info || !info.isDirectory() && !info.isFile()) throw new Error(`Isolation read-only path must exist as a regular file or directory: ${path}`);
|
|
38
|
+
if (protectedPaths.some((protectedPath) => contains(absolute, protectedPath) || contains(protectedPath, absolute))) throw new Error("Isolation read-only paths must not expose control state, configuration or other task workspaces");
|
|
39
|
+
return absolute;
|
|
40
|
+
}))];
|
|
41
|
+
}
|
|
22
42
|
function loadConfig(path = "factory.json") {
|
|
23
43
|
const configPath = resolve(path);
|
|
24
44
|
const source = z.record(z.string(), z.unknown()).parse(loadJSON(configPath));
|
|
@@ -46,6 +66,10 @@ function loadConfig(path = "factory.json") {
|
|
|
46
66
|
if (!child || !(child === ".." || child.startsWith(`..${sep}`) || isAbsolute(child))) throw new Error("toolchain.flutterSdk must be outside workspaceRoot so verification does not trust an agent-writable SDK");
|
|
47
67
|
}
|
|
48
68
|
if (config.apple?.exportOptionsPlist) config.apple.exportOptionsPlist = resolve(root, config.apple.exportOptionsPlist);
|
|
69
|
+
if (config.obfuscation) {
|
|
70
|
+
config.obfuscation.configPath = resolve(root, config.obfuscation.configPath);
|
|
71
|
+
if (!existsSync(config.obfuscation.configPath) || !lstatSync(config.obfuscation.configPath).isFile()) throw new Error(`obfuscation.configPath must name an existing regular file: ${config.obfuscation.configPath}`);
|
|
72
|
+
}
|
|
49
73
|
if (config.inbox) {
|
|
50
74
|
config.inbox.directory = resolve(root, config.inbox.directory);
|
|
51
75
|
const workspace = canonicalPath(config.workspaceRoot);
|
|
@@ -54,13 +78,27 @@ function loadConfig(path = "factory.json") {
|
|
|
54
78
|
if (!child || !(child === ".." || child.startsWith(`..${sep}`) || isAbsolute(child))) throw new Error("inbox.directory must be outside workspaceRoot so agent output cannot become new requirements");
|
|
55
79
|
}
|
|
56
80
|
if (!config.allowLocalExecution) config.executionWarning = "Local execution is disabled. Use a dedicated OS account or VM, then set allowLocalExecution=true; a workspace is not a security sandbox.";
|
|
57
|
-
const
|
|
58
|
-
if (!
|
|
81
|
+
const state = canonicalPath(config.stateDir), workspace = canonicalPath(config.workspaceRoot);
|
|
82
|
+
if ([relative(workspace, state), relative(state, workspace)].some((child) => !child || !(child === ".." || child.startsWith(`..${sep}`) || isAbsolute(child)))) throw new Error("stateDir and workspaceRoot must not overlap in either direction so host tools do not own task state");
|
|
83
|
+
normalizeIsolationPaths(config);
|
|
59
84
|
return {
|
|
60
85
|
...config,
|
|
61
86
|
configPath
|
|
62
87
|
};
|
|
63
88
|
}
|
|
89
|
+
function validateProjectSource(spec, config) {
|
|
90
|
+
if (!spec.project?.sourceDir) return void 0;
|
|
91
|
+
const root = config.configPath ? dirname(resolve(config.configPath)) : process.cwd();
|
|
92
|
+
const source = resolve(root, spec.project.sourceDir);
|
|
93
|
+
const info = lstatSync(source);
|
|
94
|
+
if (info.isSymbolicLink() || !info.isDirectory()) throw new Error("project.sourceDir must identify a real directory, not a symlink");
|
|
95
|
+
const sourceDirectory = canonicalPath(source);
|
|
96
|
+
for (const path of [config.stateDir, config.workspaceRoot]) {
|
|
97
|
+
const reserved = canonicalPath(resolve(root, path));
|
|
98
|
+
if ([relative(reserved, sourceDirectory), relative(sourceDirectory, reserved)].some((child) => !child || !(child === ".." || child.startsWith(`..${sep}`) || isAbsolute(child)))) throw new Error("project.sourceDir must not overlap stateDir or workspaceRoot in either direction");
|
|
99
|
+
}
|
|
100
|
+
return sourceDirectory;
|
|
101
|
+
}
|
|
64
102
|
function inside(root, path) {
|
|
65
103
|
const resolved = resolve(root, path);
|
|
66
104
|
const child = relative(root, resolved);
|
|
@@ -75,6 +113,6 @@ function expandArgv(argv, env) {
|
|
|
75
113
|
return env[key];
|
|
76
114
|
}));
|
|
77
115
|
}
|
|
78
|
-
export { canonicalPath, expandArgv, inside, loadConfig, loadJSON, validateSpec };
|
|
116
|
+
export { canonicalPath, expandArgv, inside, loadConfig, loadJSON, normalizeIsolationPaths, validateProjectSource, validateSpec };
|
|
79
117
|
|
|
80
118
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["import { readFileSync, existsSync, realpathSync, lstatSync } from 'node:fs';\nimport { basename, dirname, resolve, isAbsolute, relative, sep } from 'node:path';\nimport { z } from 'zod';\nimport { ConfigSchema, SpecSchema, toError } from './schemas.js';\nimport type { Config, Spec } from './schemas.js';\n\nexport function loadJSON(path: string): unknown {\n try { return JSON.parse(readFileSync(path, 'utf8')) as unknown; }\n catch (cause) { throw new Error(`Cannot read JSON at ${path}: ${toError(cause).message}`); }\n}\n\nexport function validateSpec(spec: unknown): Spec {\n return SpecSchema.parse(spec);\n}\n\nexport function canonicalPath(path: string): string {\n const absolute = resolve(path);\n if (existsSync(absolute)) return realpathSync(absolute);\n if (lstatSync(absolute, { throwIfNoEntry: false })?.isSymbolicLink()) throw new Error(`Cannot resolve dangling symlink at ${absolute}; point it to an existing directory before continuing`);\n return resolve(canonicalPath(dirname(absolute)), basename(absolute));\n}\n\nexport function loadConfig(path = 'factory.json'): Config & { configPath: string } {\n const configPath = resolve(path);\n const source = z.record(z.string(), z.unknown()).parse(loadJSON(configPath));\n const legacyKeys = ['builder', 'reviewer', 'researcher', 'agentEnv', 'maxAgentCalls', 'maxConcurrentJobs'].filter(key => key in source);\n if (legacyKeys.length) throw new Error(`Legacy provider/daemon configuration is not supported (${legacyKeys.join(', ')}). Remove builder/reviewer/researcher/maxConcurrentJobs, rename agentEnv to executionEnv and maxAgentCalls to maxHostTurns. Models and authentication now belong to your host. Existing queue snapshots are migrated without deleting task history.`);\n const root = dirname(configPath);\n const config = ConfigSchema.parse({\n ...source, configPath,\n stateDir: resolve(root, z.string().min(1).default('.factory').parse(source.stateDir)),\n workspaceRoot: resolve(root, z.string().min(1).default('workspaces').parse(source.workspaceRoot)),\n });\n if (config.toolchain) {\n config.toolchain.flutterSdk = resolve(root, config.toolchain.flutterSdk);\n if (existsSync(config.toolchain.flutterSdk)) config.toolchain.flutterSdk = realpathSync(config.toolchain.flutterSdk);\n const workspace = existsSync(config.workspaceRoot) ? realpathSync(config.workspaceRoot) : config.workspaceRoot;\n const child = relative(workspace, config.toolchain.flutterSdk);\n if (!child || !(child === '..' || child.startsWith(`..${sep}`) || isAbsolute(child))) throw new Error('toolchain.flutterSdk must be outside workspaceRoot so verification does not trust an agent-writable SDK');\n }\n if (config.apple?.exportOptionsPlist) config.apple.exportOptionsPlist = resolve(root, config.apple.exportOptionsPlist);\n if (config.inbox) {\n config.inbox.directory = resolve(root, config.inbox.directory);\n const workspace = canonicalPath(config.workspaceRoot);\n const inbox = canonicalPath(config.inbox.directory);\n const child = relative(workspace, inbox);\n if (!child || !(child === '..' || child.startsWith(`..${sep}`) || isAbsolute(child))) throw new Error('inbox.directory must be outside workspaceRoot so agent output cannot become new requirements');\n }\n if (!config.allowLocalExecution) config.executionWarning = 'Local execution is disabled. Use a dedicated OS account or VM, then set allowLocalExecution=true; a workspace is not a security sandbox.';\n const stateChild = relative(canonicalPath(config.workspaceRoot), canonicalPath(config.stateDir));\n if (!stateChild || !(stateChild === '..' || stateChild.startsWith(`..${sep}`) || isAbsolute(stateChild))) throw new Error('stateDir must be outside workspaceRoot so host tools do not own task state');\n return { ...config, configPath };\n}\n\nexport function inside(root: string, path: string): string {\n const resolved = resolve(root, path);\n const child = relative(root, resolved);\n if (!child || child === '..' || child.startsWith(`..${sep}`) || isAbsolute(child)) throw new Error(`Expected a path inside the workspace: ${path}`);\n const actual = relative(canonicalPath(root), canonicalPath(resolved));\n if (!actual || actual === '..' || actual.startsWith(`..${sep}`) || isAbsolute(actual)) throw new Error(`Workspace path escapes through a symlink: ${path}`);\n return resolved;\n}\n\nexport function expandArgv(argv: string[], env: NodeJS.ProcessEnv): string[] {\n return argv.map(arg => arg.replace(/\\$\\{([A-Z][A-Z0-9_]*)\\}/g, (_, key: string) => {\n if (/^(ASC_|APPLE_|FASTLANE_|MATCH_)/.test(key) || !env[key]) throw Object.assign(new Error(`Verification requires ${key} in the allowed worker environment; publisher secrets cannot be command arguments`), { code: 'SETUP_REQUIRED' });\n return env[key];\n }));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["import { readFileSync, existsSync, realpathSync, lstatSync } from 'node:fs';\nimport { basename, dirname, resolve, isAbsolute, relative, sep } from 'node:path';\nimport { z } from 'zod';\nimport { ConfigSchema, SpecSchema, toError } from './schemas.js';\nimport type { Config, Spec } from './schemas.js';\n\nexport function loadJSON(path: string): unknown {\n try { return JSON.parse(readFileSync(path, 'utf8')) as unknown; }\n catch (cause) { throw new Error(`Cannot read JSON at ${path}: ${toError(cause).message}`); }\n}\n\nexport function validateSpec(spec: unknown): Spec {\n return SpecSchema.parse(spec);\n}\n\nexport function canonicalPath(path: string): string {\n const absolute = resolve(path);\n if (existsSync(absolute)) return realpathSync(absolute);\n if (lstatSync(absolute, { throwIfNoEntry: false })?.isSymbolicLink()) throw new Error(`Cannot resolve dangling symlink at ${absolute}; point it to an existing directory before continuing`);\n return resolve(canonicalPath(dirname(absolute)), basename(absolute));\n}\n\nexport function normalizeIsolationPaths(config: Config): void {\n if (!config.isolation) return;\n const root = config.configPath ? dirname(resolve(config.configPath)) : process.cwd();\n const protectedPaths = [config.stateDir, config.workspaceRoot, ...(config.configPath ? [config.configPath] : [])].map(path => canonicalPath(resolve(root, path)));\n const contains = (parent: string, child: string): boolean => {\n const path = relative(parent, child);\n return path === '' || path !== '..' && !path.startsWith(`..${sep}`) && !isAbsolute(path);\n };\n config.isolation.readOnlyPaths = [...new Set(config.isolation.readOnlyPaths.map(path => {\n const absolute = canonicalPath(resolve(root, path));\n const info = lstatSync(absolute, { throwIfNoEntry: false });\n if (!info || !info.isDirectory() && !info.isFile()) throw new Error(`Isolation read-only path must exist as a regular file or directory: ${path}`);\n if (protectedPaths.some(protectedPath => contains(absolute, protectedPath) || contains(protectedPath, absolute))) throw new Error('Isolation read-only paths must not expose control state, configuration or other task workspaces');\n return absolute;\n }))];\n}\n\nexport function loadConfig(path = 'factory.json'): Config & { configPath: string } {\n const configPath = resolve(path);\n const source = z.record(z.string(), z.unknown()).parse(loadJSON(configPath));\n const legacyKeys = ['builder', 'reviewer', 'researcher', 'agentEnv', 'maxAgentCalls', 'maxConcurrentJobs'].filter(key => key in source);\n if (legacyKeys.length) throw new Error(`Legacy provider/daemon configuration is not supported (${legacyKeys.join(', ')}). Remove builder/reviewer/researcher/maxConcurrentJobs, rename agentEnv to executionEnv and maxAgentCalls to maxHostTurns. Models and authentication now belong to your host. Existing queue snapshots are migrated without deleting task history.`);\n const root = dirname(configPath);\n const config = ConfigSchema.parse({\n ...source, configPath,\n stateDir: resolve(root, z.string().min(1).default('.factory').parse(source.stateDir)),\n workspaceRoot: resolve(root, z.string().min(1).default('workspaces').parse(source.workspaceRoot)),\n });\n if (config.toolchain) {\n config.toolchain.flutterSdk = resolve(root, config.toolchain.flutterSdk);\n if (existsSync(config.toolchain.flutterSdk)) config.toolchain.flutterSdk = realpathSync(config.toolchain.flutterSdk);\n const workspace = existsSync(config.workspaceRoot) ? realpathSync(config.workspaceRoot) : config.workspaceRoot;\n const child = relative(workspace, config.toolchain.flutterSdk);\n if (!child || !(child === '..' || child.startsWith(`..${sep}`) || isAbsolute(child))) throw new Error('toolchain.flutterSdk must be outside workspaceRoot so verification does not trust an agent-writable SDK');\n }\n if (config.apple?.exportOptionsPlist) config.apple.exportOptionsPlist = resolve(root, config.apple.exportOptionsPlist);\n if (config.obfuscation) {\n config.obfuscation.configPath = resolve(root, config.obfuscation.configPath);\n if (!existsSync(config.obfuscation.configPath) || !lstatSync(config.obfuscation.configPath).isFile()) throw new Error(`obfuscation.configPath must name an existing regular file: ${config.obfuscation.configPath}`);\n }\n if (config.inbox) {\n config.inbox.directory = resolve(root, config.inbox.directory);\n const workspace = canonicalPath(config.workspaceRoot);\n const inbox = canonicalPath(config.inbox.directory);\n const child = relative(workspace, inbox);\n if (!child || !(child === '..' || child.startsWith(`..${sep}`) || isAbsolute(child))) throw new Error('inbox.directory must be outside workspaceRoot so agent output cannot become new requirements');\n }\n if (!config.allowLocalExecution) config.executionWarning = 'Local execution is disabled. Use a dedicated OS account or VM, then set allowLocalExecution=true; a workspace is not a security sandbox.';\n const state = canonicalPath(config.stateDir), workspace = canonicalPath(config.workspaceRoot);\n if ([relative(workspace, state), relative(state, workspace)].some(child => !child || !(child === '..' || child.startsWith(`..${sep}`) || isAbsolute(child)))) throw new Error('stateDir and workspaceRoot must not overlap in either direction so host tools do not own task state');\n normalizeIsolationPaths(config);\n return { ...config, configPath };\n}\n\nexport function validateProjectSource(spec: Spec, config: Config): string | undefined {\n if (!spec.project?.sourceDir) return undefined;\n const root = config.configPath ? dirname(resolve(config.configPath)) : process.cwd();\n const source = resolve(root, spec.project.sourceDir);\n const info = lstatSync(source);\n if (info.isSymbolicLink() || !info.isDirectory()) throw new Error('project.sourceDir must identify a real directory, not a symlink');\n const sourceDirectory = canonicalPath(source);\n for (const path of [config.stateDir, config.workspaceRoot]) {\n const reserved = canonicalPath(resolve(root, path));\n if ([relative(reserved, sourceDirectory), relative(sourceDirectory, reserved)].some(child => !child || !(child === '..' || child.startsWith(`..${sep}`) || isAbsolute(child)))) throw new Error('project.sourceDir must not overlap stateDir or workspaceRoot in either direction');\n }\n return sourceDirectory;\n}\n\nexport function inside(root: string, path: string): string {\n const resolved = resolve(root, path);\n const child = relative(root, resolved);\n if (!child || child === '..' || child.startsWith(`..${sep}`) || isAbsolute(child)) throw new Error(`Expected a path inside the workspace: ${path}`);\n const actual = relative(canonicalPath(root), canonicalPath(resolved));\n if (!actual || actual === '..' || actual.startsWith(`..${sep}`) || isAbsolute(actual)) throw new Error(`Workspace path escapes through a symlink: ${path}`);\n return resolved;\n}\n\nexport function expandArgv(argv: string[], env: NodeJS.ProcessEnv): string[] {\n return argv.map(arg => arg.replace(/\\$\\{([A-Z][A-Z0-9_]*)\\}/g, (_, key: string) => {\n if (/^(ASC_|APPLE_|FASTLANE_|MATCH_)/.test(key) || !env[key]) throw Object.assign(new Error(`Verification requires ${key} in the allowed worker environment; publisher secrets cannot be command arguments`), { code: 'SETUP_REQUIRED' });\n return env[key];\n }));\n}\n"],"mappings":"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"}
|