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
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: apphx
|
|
3
|
+
description: Build, verify and locally package Flutter, Java Android, Swift, React Native, Expo, uni-app or MyGo macOS projects from explicit requirements using apphx. Supports new apps and safe existing-project snapshots. Use for init, enqueue, research, native implementation, independent review or resuming a persisted job. Not a coding-agent launcher or automatic store publisher.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# apphx
|
|
7
|
+
|
|
8
|
+
Use your current host's model, context, authentication, filesystem, browser and native delegation tools. The installed `apphx` CLI owns requirements, durable turns, verification, fingerprints and local packaging. Never start another coding-agent CLI, including Hermes, as a subprocess to perform a phase. There is no apphx chat UI, model credential setup, daemon, or background agent loop.
|
|
9
|
+
|
|
10
|
+
This skill is advisory to the host. apphx code gates apphx-owned transitions, not arbitrary host edits or shell commands. It does not sandbox your host, enforce reviewer identity or guarantee store approval. Store submission and review are manual human work outside this tool. Preserve host permissions and the user's scope.
|
|
11
|
+
|
|
12
|
+
## 1. Establish the control project
|
|
13
|
+
|
|
14
|
+
1. Use the project where the user installed/invoked this skill as the control project. Keep `factory.json`, its SQLite state, requirement files and result JSON outside generated app workspaces. Keep the absolute config path for every command below, including commands issued while your working directory is an app workspace.
|
|
15
|
+
2. The npm package, executable and skill are all `apphx`. Run `apphx --version` and `apphx --help`. If `apphx` is an already-installed local dependency of the control project rather than on PATH, use that project's package manager for **every** apphx command: `pnpm exec apphx`, `yarn exec apphx`, or `npm exec --offline --package=apphx -- apphx`. Select from the project's `packageManager`/lockfile and run from the control project, not the app workspace. Confirm `apphx` is already installed; do not fetch a similarly named package or silently change the user's environment. If neither route is available, stop and report the missing installation. Installing a skill does not install platform SDKs.
|
|
16
|
+
3. If there is no configuration, select the actual stack and platform: `apphx init --framework react-native --platform android --package-target aab --config /absolute/control/factory.json`, for example. Choices are `flutter`, `android-java`, `swift`, `react-native`, `expo`, `uni-app`, `mygo`; iOS targets `simulator`/`ipa`, Android targets `apk`/`aab`, MyGo macOS targets `app`/`dmg`. Defaults remain Flutter/iOS/simulator; android-java defaults Android/APK, Expo defaults iOS/IPA with EAS local, MyGo defaults macOS/app. `init` creates an owner-editable config, not source code. It refuses overwrite and defaults to **no local execution or cloud build authorization**. Do not add `--allow-local-execution` unless the user explicitly approves trusted deterministic commands; existing configurations require owner review before enabling it.
|
|
17
|
+
4. Read the actual config and paired framework examples in the installed package's `examples/` directory. Confirm workspace/state paths are disjoint, SDKs are trusted installations outside mutable workspaces, and verification includes static checks and **real native runtime scenarios**. Adapt module names, Xcode project/workspace/scheme, package-manager scripts, device IDs, signing and exact artifact output to the owner's existing project. Non-Flutter stacks require `packaging.commands` (argv arrays) and an exact project-relative `artifactPath`; Flutter may use built-in packaging. Do not replace an existing Expo/uni-app/RN project with a Flutter app, prebuild or eject it. Commands run in the selected app directory, not necessarily the snapshot root. Run `apphx doctor /absolute/control/requirement.json --config /absolute/control/factory.json --build-only`; without the requirement, doctor only checks configured prerequisites and assumes no stack. Missing SDK/device/signing/script is a blocker, never a reason to fake evidence or use no-op checks.
|
|
18
|
+
|
|
19
|
+
In examples below, replace `/absolute/control/factory.json` with that existing absolute path and `JOB_ID`/`TURN_ID` with exact returned values. Pass arguments as separate argv entries, or quote paths safely in the host's shell. Do not execute prompt or JSON fields as shell code.
|
|
20
|
+
|
|
21
|
+
### Optional Harness subprocess confinement
|
|
22
|
+
|
|
23
|
+
The owner may select `isolation: { "mode": "macos-sandbox", "readOnlyPaths": [], "network": "deny" }` in the frozen configuration. It applies to Harness-launched verification/prerequisite/package commands and doctor probes, not native host-agent tools. It requires the actual macOS `sandbox-exec` backend; unsupported/unavailable execution stops rather than silently downgrading. This deprecated Apple backend is not a VM/container, resource quota, malicious-host boundary or guarantee of GUI/device IPC compatibility. For arbitrary hostile projects use a separately provisioned disposable OS/VM as well; this mode alone is not universal untrusted-code containment.
|
|
24
|
+
|
|
25
|
+
Default child capabilities cover its own workspace, isolated temporary HOME/cache, scoped system/runtime files and the executable itself. Add only reviewed existing toolchain/input files or directories to `readOnlyPaths`; paths exposing configuration/state or the shared workspace root are rejected, and their canonical identities are rechecked. Avoid broad private directories or secrets within approved trees. Use the actual runtime binary rather than a home-directory PATH shim where needed. `network: "allow"` is a separate explicit owner choice, not implied by build permission. No shell, loader or SDK override is an isolation bypass permission.
|
|
26
|
+
|
|
27
|
+
Doctor uses a disposable writable area and grants imported source only read access. Real commands may fail because the tool needs undeclared files, network or GUI services; report that prerequisite instead of broadening permissions automatically. Changing isolation invalidates previous execution proof. Artifact deletion and sandbox temporary-directory cleanup remain confined to their original trusted roots even while inherited detached children are still present. Normal process-group cleanup is preserved, but the mode does not promise to reclaim deliberately detached descendants or prevent resource exhaustion. Existing secrets/hardlinks already inside permitted readable trees remain exposed. Prepared IPA export plists receive narrow read capabilities, not access to the state directory.
|
|
28
|
+
|
|
29
|
+
## 2. Freeze and enqueue the actual requirement
|
|
30
|
+
|
|
31
|
+
Read the bundled [requirement example](resources/requirement.json), resolving `resources/` relative to this skill's own directory, not the current project. Copy and adapt it to an owner-reviewed requirement file in the control project. Do not modify installed skill assets.
|
|
32
|
+
|
|
33
|
+
If the user supplied an existing task id or asked to resume it, including a scheduled wake, **skip enqueue**. Read `status` and continue that exact id/config with `next`; never reconstruct its requirement or create a second task for the same work.
|
|
34
|
+
|
|
35
|
+
The requirement must describe a real audience, purpose, differentiators, framework, explicit `platform` (`ios`, `android` or `macos`), neutral top-level `version`, `channel` (`local`, `app-store`, `google-play`) and concrete acceptance scenarios/constraints. `version` defaults to `1.0.0` and `channel` to `local`; neither belongs in `apple`. `screenshotsDir` is also top-level. Java Android is Android-only; Swift is iOS-only; MyGo is macOS/local-only; App Store requires iOS and Google Play requires Android/AAB. Preserve the user's product; do not substitute a simpler app. Require honest privacy behavior, no hidden features/review bypass and real screenshots. The optional top-level `apple` metadata block is owner documentation for a manual store submission, never a requirement or a claim of approval. Shared purpose/audience is not a duplicate-admission error; assess meaningful distinction in the selected channel's research. Do not invent ownership, account eligibility, signing credentials or legal attestations.
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
apphx enqueue /absolute/control/requirement.json --config /absolute/control/factory.json --build-only
|
|
39
|
+
apphx status JOB_ID --config /absolute/control/factory.json
|
|
40
|
+
apphx next JOB_ID --config /absolute/control/factory.json --build-only
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Keep the returned immutable job id and workspace. New projects have no `project` field; the native host build turn creates the selected stack. Existing projects use `project: { "sourceDir": "/absolute/owned/repository", "directory": "apps/mobile" }` (or directory `"."` for its root). apphx pins a source snapshot; work only in the returned workspace, never the original. `directory` must stay inside the snapshot. Do not follow escaping source/local dependency symlinks or import from mutable external dependencies. A changed source after enqueue must be resubmitted honestly rather than forced through stale proof. A later requirement change needs a new enqueue, not saved-task/database edits. `baseJobId` may reference a verified/finished same-product predecessor with the same framework/platform/channel; do not copy stale artifacts yourself.
|
|
44
|
+
|
|
45
|
+
For **iOS App Store releases only**, omitting both `baseJobId` and `project.sourceDir` automatically pins the most recently enqueued finished same-product/platform/channel predecessor (`built`, `ready`, `approved` or `released`), recording `baseJobId`, `baseDigest` and `automaticBase: true`. Explicit source/base selection keeps its existing precedence and validation. The latest matching predecessor must have the same framework and valid unchanged source/dependency proof; a stale or incompatible latest version stops rather than falling back to an older version or starting fresh. Prior same-product history without a finished predecessor also stops; only a first-ever release without history may start new. Do not ask the owner to classify each release as new/update or manually copy code. A previous release is a source reuse baseline when available, not a differentiation unit; prior versions are release context, not competing portfolio products requiring artificial differentiation. Preserve application identity and data compatibility. Reuse and minimal changes are preferences, not a ban on theme, display-name, content, function or architecture changes needed for the product and its actual quality gaps.
|
|
46
|
+
|
|
47
|
+
For a batch, enqueue the entire requested set before starting research so pending peers are visible to every review. With a configured inbox, submit its individual requirements and run `apphx scan --config /absolute/control/factory.json --build-only`; otherwise enqueue each requirement once and retain its returned job id. Drive each id through `next` and its returned action. A repair verdict is a continuation of that same job, not a request for manual classification, owner-written code or a replacement task. Continue eligible jobs while another is blocked or deferred, respect each due time and existing host scheduling/attempt limits, and never reuse one package's review for the batch.
|
|
48
|
+
|
|
49
|
+
Research and review compare the same-channel portfolio including pending batch peers, using their supplied versions and available read-only source. If `next` or `complete` rejects changed peer context, abandon that exact stale token and request a fresh turn within existing budgets; do not reuse its verdict or create a replacement task. Packaging rechecks the accepted comparison before and after commands. A peer-only change returns unchanged own source to review rather than discarding its runtime proof. Scheduling notes and unrelated-channel/same-product history are not peer-comparison changes.
|
|
50
|
+
|
|
51
|
+
## 3. Dispatch exactly the persisted action
|
|
52
|
+
|
|
53
|
+
Read the JSON from `next`; do not guess stages from memory. Use `--build-only` throughout this workflow; it is accepted for CLI compatibility. Local packaging never grants submission, upload or release authority.
|
|
54
|
+
|
|
55
|
+
- **`action: "host"`**: preserve `turn.id`; read the full `turn.prompt`, `turn.stage`, `turn.cwd` and `turn.environment`. Perform that one native host phase as below. Work inside the returned cwd and merge the returned task/toolchain overrides into your host's existing command environment; do not replace it. Configured environment values are intentionally not printed in the response. This is not a host-wide security boundary; never copy store credentials into task commands. Only the CLI completion call advances the task. Repeated `next` resumes the same active turn without spending a second turn, unless its task deadline has expired.
|
|
56
|
+
- **`action: "step"`**: run `apphx step JOB_ID --config /absolute/control/factory.json --build-only` once, inspect its exit status and returned job, then follow `next`. A returned build/research repair is actionable host work under the existing authorization, not a reason to ask the owner to fix code manually; respect its due time. Blocked/failed states remain stopped. Only deterministic verify/package stages should be needed here. `step` cannot perform research, build or review for you. Never label a host verdict as external verification.
|
|
57
|
+
- **`action: "wait"`**: inspect the job's status, reason, error and due time. Report the exact blocker or scheduled time; do not busy-loop, automatically grant permission, or retry a failed command until it happens to pass. Resume with `next` after the prerequisite/due time is satisfied and the user intends to continue.
|
|
58
|
+
- **`action: "done"`**: inspect the persisted outcome. `built` plus a recorded local artifact is successful local packaging. Blocked/failed/rejected outcomes are not success merely because no action remains. Report the artifact kind/path/digest and evidence, or the exact unmet requirement.
|
|
59
|
+
|
|
60
|
+
For a scheduled wake, the host scheduler owns timing and non-overlap; do not create an apphx daemon or a second schedule. Check `status` first: if it is `running` and the prior execution's completion is unconfirmed, stop and ask the owner rather than taking over its token. Respect the requested bound (for example one persisted action), then report state and exit. A `wait` or `done` result ends this wake; it does not authorize changing permissions, increasing budgets or polling indefinitely. A fresh scheduled session may review only if it did not implement the change and genuinely inspects the saved source/evidence. Missing independent review or human authorization pauses the work; never manufacture approval to keep a schedule moving.
|
|
61
|
+
|
|
62
|
+
To stop an active host phase without completing it:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
apphx abandon JOB_ID TURN_ID --config /absolute/control/factory.json --build-only
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This explicitly abandons the current token; it does not refund the consumed turn. Resume later with `next`. Never reuse an abandoned, stale or already completed token. If a completion's outcome is uncertain, inspect `status`/`next` rather than replaying it blindly. Do not edit SQLite or increase budgets to bypass a rejection. Use `apphx retry --help` and the stopped task's reported recovery instructions only after fixing the actual cause with owner approval.
|
|
69
|
+
|
|
70
|
+
## 4. Native research
|
|
71
|
+
|
|
72
|
+
Read the immutable requirement and the research prompt. Research produces a local package; store submission and review are manual human work outside this tool, so no channel-specific policy citation or approval claim is required:
|
|
73
|
+
|
|
74
|
+
- **local**: evaluate implementability, real device acceptance, privacy, accessibility and the supplied portfolio. Use [local-research-result.json](resources/local-research-result.json) for shape only.
|
|
75
|
+
- **app-store** (iOS): evaluate honest differentiation and quality for a package the owner may later submit manually. Use [research-result.json](resources/research-result.json) for shape only.
|
|
76
|
+
- **google-play** (Android): evaluate honest differentiation and quality for a local AAB the owner may later submit manually. Use [google-play-research-result.json](resources/google-play-research-result.json) for shape only.
|
|
77
|
+
|
|
78
|
+
For every channel, return `viable` boolean, nonempty `distinctness` and nonempty `plan`; `risks` is optional. Replace all unassessed example content with actual findings against the channel-scoped portfolio. If not viable, return false with reasons; do not invent ownership attestations or an approval promise.
|
|
79
|
+
|
|
80
|
+
Research and independent review apply an honest differentiation and quality checklist, comparing the same-channel portfolio including pending batch peers:
|
|
81
|
+
|
|
82
|
+
- **Real value**: each package has its own genuine purpose, audience and functional behavior; identical functionality with only renamed labels is not meaningful differentiation.
|
|
83
|
+
- **Visual identity**: themes, layouts, colors and interaction flows are real product choices for this app, not templated reskins produced to look different.
|
|
84
|
+
- **Developer and identity metadata**: app name, title, icon, bundle/package id, keywords and description truthfully describe this app and its actual developer. Never forge identities, accounts, locations or submission sources.
|
|
85
|
+
- **Functionality**: every advertised feature works and is exercised by the frozen runtime acceptance; no hidden functionality for any audience and no fabricated screenshots or evidence.
|
|
86
|
+
- **Code identity**: project, folder, class, function and resource names follow this project's real conventions. Do not mutate hashes, names or resource bytes solely to defeat similarity checks.
|
|
87
|
+
- **Quality gate**: source, dependency and runtime proofs must be current, and independent review must cover every frozen acceptance requirement with observed evidence.
|
|
88
|
+
|
|
89
|
+
Missing owner facts (account, ownership, legal) are a blocker for that job, not permission to fabricate content. Store submission remains manual human work; nothing here bypasses, influences or pre-approves a store reviewer, and no Apple or Google Play approval is promised.
|
|
90
|
+
|
|
91
|
+
Save result JSON **outside the app workspace**, for example `/absolute/control/results/JOB_ID-research.json`, then:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
apphx complete JOB_ID TURN_ID /absolute/control/results/JOB_ID-research.json --config /absolute/control/factory.json --build-only
|
|
95
|
+
apphx next JOB_ID --config /absolute/control/factory.json --build-only
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 5. Native implementation
|
|
99
|
+
|
|
100
|
+
Perform the returned build prompt with native edit, terminal and design tools in `turn.cwd`. Implement the full requirement in its selected stack: Flutter (`pubspec.yaml`), Java Android (Gradle/Android manifest), Swift (Xcode project/workspace), React Native/Expo (existing package scripts and native host/build profile), or uni-app (its manifests/scripts and owner-maintained native packaging). For new projects create the real matching host; for imports preserve native integrations, project structure and scripts, with no forced ejection or migration. Run resource generation that changes owned source during this turn, before external verification. For unfamiliar APIs use official references. Never fake features, runtime evidence or screenshots. Do not weaken verification or alter frozen requirements/state.
|
|
101
|
+
|
|
102
|
+
For each pending package, inspect its fresh research/review findings and any pinned source baseline. Implement the identified repairs and requested product changes. Prefer reuse and small effective changes, but allow theme, display-name, content, functional or architecture changes where appropriate; preserve application identity and data compatibility. Cosmetic changes alone do not establish meaningful differentiation. A review repair returns here automatically; do not ask the owner to write routine feedback or enqueue a replacement job. Complete the returned build turn, then let `next`/`step` obtain renewed runtime and source/dependency proof before independent review. Missing owner facts remain a blocker for this job, not permission to fabricate content or dodge review.
|
|
103
|
+
|
|
104
|
+
The bundled uni-app command pair specifically illustrates a CLI/npm project with an owner-maintained offline native host; it is not a requirement to convert other uni-app projects. Classic HBuilderX projects may have `App.vue`, `main.js`/`main.ts`, `manifest.json` and `pages.json` without `package.json`; do not require or add Node/npm, invent npm scripts or convert that project. Preserve its existing HBuilderX layout and owner-provided prerequisite, native build and real device acceptance commands. `doctor` must not infer npm requirements for this variant; only the configured owner prerequisites identify its actual build tooling.
|
|
105
|
+
|
|
106
|
+
Expo initialization uses **EAS local** for either platform, without assuming `ios/` or `android/` exists or requesting prebuild/eject. Preserve the owner's existing `eas.json`: the generated commands require a `production` profile for IPA/AAB, an `apk` profile with `android.buildType: "apk"`, or a `simulator` profile with `ios.simulator: true`. The explicit simulator profile emits `build/simulator.tar.gz`, then extracts the expected `build/App.app`; adapt the product name/archive layout to the actual project. The owner supplies EAS CLI/authentication, SDK/signing and real native acceptance scripts; local compilation does not imply the EAS CLI is network-free. Never silently switch to cloud compilation. uni-app iOS's `native/ios` path is likewise an owner-configured offline-host convention, not a promise that init generates a native project.
|
|
107
|
+
|
|
108
|
+
### MyGo macOS: native UI and web frontend
|
|
109
|
+
|
|
110
|
+
`apphx init --framework mygo` defaults to macOS/app; `--package-target dmg` selects DMG. MyGo is macOS/local-only; other frameworks do not gain macOS support. Unsupported platform/target combinations fail before writing configuration. Keep `allowCloudBuild` false and packaging provider local. Init creates configuration, not app source or an acceptance harness. Requirements explicitly use `framework: "mygo"`, `platform: "macos"`, `channel: "local"`.
|
|
111
|
+
|
|
112
|
+
Use paired `examples/mygo.json` / `mygo.factory.json` for Go-only native UI, or `mygo-web.json` / `mygo-web.factory.json` for web. MyGo requires `go.mod` and exactly one `mygo.json` (native UI) or `mygo.config.ts` (web); web also retains its actual frontend `package.json` and dependency lock. Native UI does **not** require Bun, npm or package.json. Preserve existing layout, `project.directory` and package manager; the web pair illustrates an existing Bun `build` script, not mandatory migration. Do not auto-install tools: pinned MyGo v0.3.0 requires Go 1.27.1, `require github.com/egoist/mygo v0.3.0` and `tool github.com/egoist/mygo/cmd/mygo` in the owner's go.mod. Probe with `go tool mygo version`; never use `@latest`. The optional npm CLI distribution is `mygo-cli`, not the unrelated `mygo` package.
|
|
113
|
+
|
|
114
|
+
With a MyGo requirement, doctor runs configured prerequisites in the existing imported `project.sourceDir` / `project.directory`, using its closest owned Go workspace (or `GOWORK=off`), `GOENV=off`, `GOTOOLCHAIN=local` and `GOFLAGS=-mod=readonly`. Missing/new source is reported as not yet checkable; doctor never substitutes the control module or creates source. Generic Go availability probes are not proof that the project-pinned MyGo tool is available.
|
|
115
|
+
|
|
116
|
+
The owner must implement `go run ./cmd/acceptance` as a **real app-specific desktop harness**: launch the actual macOS app, wait for its window, drive visible controls, assert frozen scenarios, save actual screenshots and fail on errors. `go vet`, `go test`, browser-only tests and headless view tests do not replace it. A safe app build may precede runtime checks to provide the executable. No iOS simulator is involved; unavailable macOS runtime is a blocker. Prepare frontend bindings, dependency locks and other source generation during the host build turn before proof. MyGo v0.3.0 generates its client even with `-skip-build-command`; repeated generation during verify/package must leave owned source byte-identical or require renewed verification/review.
|
|
117
|
+
|
|
118
|
+
Packaging contains one direct `go tool mygo build` invocation pinned by go.mod, not a shell/npm wrapper: `-platform darwin/arm64 -sign - -skip-notarize -o build`, plus `-skip-dmg` for app only (omit for dmg). No upload, notarization or Developer ID workflow is authorized. Match name/version/architecture to actual project config: examples assume **MyGo App**, **0.1.0**, **arm64**, producing exactly `build/darwin-arm64/MyGo App.app` or, for pinned v0.3.0, `build/darwin-arm64/MyGo App 0.1.0.dmg`. Both are supported local deliverables. A `.app` must be a real executable signed bundle and a DMG must pass integrity validation; filenames alone are not proof. MyGo TypeScript configuration and owner commands are trusted executable code, not a sandbox: inspect them, keep store credentials out, and do not claim the direct-command guard constrains arbitrary project code. Included profiles are not evidence of successful builds or runtime acceptance.
|
|
119
|
+
|
|
120
|
+
Keep runtime screenshots outside the platform directory MyGo replaces, for example `build/screenshots`, not `build/darwin-arm64/screenshots`. Static `mygo.json` file inputs must remain owned and fingerprinted; duplicate fields, external resources and cache references are rejected. Declared JSON `frontendDist` under the app's `dist` or a separate `build/frontend` directory carries its actual file bytes in dependency proof, even though snapshots omit generated output; rebuild it during the host turn before verification. Do not embed the platform output directory itself. TypeScript configuration remains trusted executable code whose computed inputs require owner review; no static sandbox guarantee is implied.
|
|
121
|
+
|
|
122
|
+
Native delegation may handle independent file boundaries. The implementation owner integrates before any external verification. Complete only after the source exists and the requested implementation is ready:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
apphx complete JOB_ID TURN_ID --config /absolute/control/factory.json --build-only
|
|
126
|
+
apphx next JOB_ID --config /absolute/control/factory.json --build-only
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
No result JSON is normally required for build. The optional `apple` metadata block in the requirement is owner documentation for a manual store submission; it is never required for local packaging and never a claim of approval. Build completion is not approval or a package.
|
|
130
|
+
|
|
131
|
+
## 6. External verification, then independent review
|
|
132
|
+
|
|
133
|
+
The deterministic `step` executes configured prerequisite/static/runtime checks and records real results and source/dependency fingerprints for the selected profile. Read logs/evidence from the returned job or `apphx events JOB_ID --config /absolute/control/factory.json`. Compilation-only success is not runtime acceptance; web-only tests are not native acceptance for Expo/uni-app. Never synthesize receipts or claim unavailable iOS/Android execution passed. Fix actual failures through stopped-task/retry, not direct stage edits. Changing commands, execution environment, toolchain, packaging provider/commands/output, package target or obfuscation config invalidates prior proof and requires renewed verification/review; retry preserves budgets. Uncertain cloud packaging runs require reconciliation, not replay.
|
|
134
|
+
|
|
135
|
+
### Optional deterministic obfuscation (runs between build and verify)
|
|
136
|
+
|
|
137
|
+
When the factory config sets `obfuscation`, completing the build turn advances to an `obfuscate` step before verification: the runner executes `obfuscation.command` (default `obfuscator`) with `--project <workspace project> --config <obfuscation.configPath> --framework <stack>` and the optional `--seed`, so the verified and packaged code is the obfuscated code. `configPath` is resolved against the factory config directory and must exist as a regular file. The obfuscated source is exactly what verify checks, review approves and package ships; obfuscation never runs after verification.
|
|
138
|
+
|
|
139
|
+
The bundled `obfuscator` package is deterministic: identical project + config + seed produce byte-identical output, in place, never writing outside the walked owned project. Installing `apphx` also installs the `obfuscator` executable (the package ships the private obfuscator), and `apphx obfuscator <project> --config <file> [--framework <stack>] [--seed <text>]` runs it directly; the harness default `obfuscation.command` resolves to that bundled executable. Point `obfuscation.command` at a different binary only to override it. Its JSON config supports:
|
|
140
|
+
- `project`: `name: { from, to }` (whole-word display-name scrub in framework config files), `directories: [...]` (seeded directory renames with reference rewrites), `uuids: true` (Xcode-UUID remapping that preserves the internal reference graph)
|
|
141
|
+
- `resources`: `rename: { mappings, generated }` (asset stem renames with reference rewrites; `generated` deterministically renames that many discovered stems to seed-derived tokens), `hashPerturb: { bytes }` (decode-safe hash perturbation for PNG/JPEG/GIF), `images: { recolor, recolorAll }` (PNG color remap / hue-shift / invert / channel order)
|
|
142
|
+
- `content`: `sensitiveWords`, `controlColors`, `fontColors` (whole-word scrub and hex-color remap across text and code, never binary payloads)
|
|
143
|
+
- `code`: `removeComments`, `encryptStrings`, `renameIdentifiers`, `junkCode`, `keywords`. `renameIdentifiers: { generated }` additionally renames that many discovered top-level declarations (classes, top-level functions) to seed-derived tokens, consistently across files; generated renames never touch entrypoints (`main`, `init`) or build-generated files (`*.g.dart`, `*.freezed.dart`, …).
|
|
144
|
+
|
|
145
|
+
Seed semantics: identical project + config + seed always produce byte-identical output, while directory tokens, UUID mappings, hash-perturb payloads, junk names and every `generated` rename differ per seed. Mappings, recolor rules, sensitive words and name scrubbing are config-driven: vary them per app when those surfaces must also differ.
|
|
146
|
+
|
|
147
|
+
Obfuscation must keep the app buildable: the ordinary verify/checks/review/package stages run unchanged afterward, and any breakage is a task failure repaired through the stopped-task/retry loop. Never weaken acceptance or verification to accommodate a failing obfuscation config.
|
|
148
|
+
|
|
149
|
+
When `next` returns a **review** turn, use a **fresh native reviewer context** that did not implement the change. Give it the exact review prompt, requirement, workspace and external evidence. Have it independently inspect every acceptance scenario, code and real evidence, with **no source/dependency/screenshot edits**. Evidence-producing commands that mutate the verified source invalidate approval. An implementation agent's second self-review is not independent.
|
|
150
|
+
|
|
151
|
+
Use the host's native subagent/reviewer facility if present. If unavailable (including stock Pi), pause and ask the user to open a separate fresh host session for review, supply the job id/config/active turn, and return its JSON verdict. Do not launch another coding-agent process or claim independence that did not occur. The separate reviewer may complete the current token itself, or return the result to the controlling session; exactly one session completes it.
|
|
152
|
+
|
|
153
|
+
Use [review-result.json](resources/review-result.json) for the strict shape: `approved` boolean, `findings` array, and `acceptanceEvidence` array. Every frozen acceptance string must appear **exactly** as `requirement`, with nonempty concrete `evidence` identifying files/symbols and observed commands/scenarios. Approve only if all acceptance criteria are supported and there are no blocking findings. The example is deliberately a rejection, not reusable evidence. Save the verdict outside the app workspace:
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
apphx complete JOB_ID TURN_ID /absolute/control/results/JOB_ID-review.json --config /absolute/control/factory.json --build-only
|
|
157
|
+
apphx next JOB_ID --config /absolute/control/factory.json --build-only
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
apphx rejects incomplete evidence, rejected verdicts and changed fingerprints. It cannot prove which model/person authored a verdict; accurately report the review method and limitations.
|
|
161
|
+
|
|
162
|
+
## 7. Package locally and hand off
|
|
163
|
+
|
|
164
|
+
Recognizable direct native IPA exports (`xcodebuild -exportArchive` or direct `xcrun xcodebuild`) are prevalidated across the complete packaging sequence before any packaging command. Export options must select local `export` (or omit `destination`); the runner substitutes an immutable checked plist snapshot and cleans it afterward. Shell/npm wrappers remain trusted owner code, not a sandbox. Missing or ambiguous export-options arguments are blockers.
|
|
165
|
+
|
|
166
|
+
Run the returned package `step` once with `--build-only`, then inspect `status`/`next`. Output is the selected local simulator `.app`, signed `.ipa`, `.apk` or `.aab`. The configured packager must produce a fresh nonempty artifact at its exact generated-output path without changing verified source/dependencies. No arbitrary artifact glob or stale file is evidence. Report only recorded paths/digests, exercised checks and remaining environment limitations. These bundled command profiles have not been built or runtime-tested merely by being included here; owner adaptation and actual task evidence are required.
|
|
167
|
+
|
|
168
|
+
`packaging.provider: "cloud"` additionally requires explicit owner-approved `allowCloudBuild: true`; defaults remain local. Cloud commands can create remote work, so never enable them implicitly or blindly replay an uncertain run. Preserve the owner's existing build service/profile.
|
|
169
|
+
|
|
170
|
+
For an explicitly permitted cloud packaging provider, doctor validates the requirement/config and imported project profile but relies on owner-configured prerequisites rather than adding local SDK probes. This does not waive the task's required real runtime acceptance commands.
|
|
171
|
+
|
|
172
|
+
Store submission, upload and review are manual human work outside this tool; this skill never authorizes or performs them. Local packaging is not store submission, approval, TestFlight availability or release. This workflow ends at the recorded artifact or an accurately reported blocker.
|
|
173
|
+
|
|
174
|
+
## 8. Maintainer behavior, runtime and performance checks
|
|
175
|
+
|
|
176
|
+
The distributed package contains `evals/`, `scripts/` and `examples/runtime/`; these tools launch neither models nor another coding agent. `node evals/policy.mjs prepare /absolute/fresh-run` prepares seven separate controlled workflows. Retain its manifest SHA-256 outside actor access, give each fresh native actor only the neutral case instructions, and hand review turns to another fresh context. After actors stop, run `node evals/policy.mjs score /absolute/fresh-run --manifest-sha256 HASH`. Scoring checks actual persisted CLI transitions, frozen inputs/checks, source and metadata changes, genuine local runtime/persistence oracles and rejected-command receipts. Unrun or incomplete cases remain unfinished; supplied grades are ignored. Do not let actors inspect controller expectations. This is a controlled JavaScript workflow—not iOS UI, legal-account evidence, store approval, authenticated reviewer identity or a sandbox against arbitrary hostile fixture code. Reprepare after any distribution/evaluator change; never update frozen baselines to conceal a failure.
|
|
177
|
+
|
|
178
|
+
`node scripts/runtime-smoke.mjs --help` describes installed-tool prerequisites and fresh-output arguments for actual Android Java APK/native UI and MyGo native/WKWebView `.app` workflows. Android owns a fresh AVD/private ADB server and ephemeral signing key; never target a user device. Its direct installed-SDK compilation path is explicit, not evidence of Gradle compatibility. MyGo uses existing pinned module/frontend caches without installing packages. Workflows retain original task ids across abandoned/reclaimed turns, assert UI/backend state and relaunch persistence, save screenshots, check signed native artifacts and clean only owned runtime processes. Do not treat a source fixture or help output as successful execution; iOS needs its own actual device/simulator surface.
|
|
179
|
+
|
|
180
|
+
`node benchmarks/peer-context.mjs prepare FRESH_ROOT` freezes the production ten-project workload, then `baseline ROOT` and `compare ROOT CANDIDATE_DIST` collect paired measurements, exact output/stale-input correctness and separate profiles. Worker errors, signals, malformed reports or incomplete work fail the run; old sample output is never reused. Request-scoped comparison reuse does not cache across requests or weaken fresh completion/package validation. Timings cover the named Harness workload, not mobile compilation or store submission.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"viable": false,
|
|
3
|
+
"distinctness": "Unassessed Google Play example: compare this package's actual utility and identity with the supplied channel-scoped portfolio.",
|
|
4
|
+
"risks": ["This example has not assessed the product, built an AAB or verified its behavior.", "The harness hands off a local AAB and does not automate store submission; store review remains manual human work outside this tool."],
|
|
5
|
+
"plan": ["Assess real user value, honest identity metadata, privacy behavior and meaningful differentiation against same-channel peers.", "Assess the real Android runtime acceptance and signed AAB packaging profile; return a product-specific plan or preserve viable=false with blockers."]
|
|
6
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"viable": false,
|
|
3
|
+
"distinctness": "Unassessed local example: inspect the actual requirement and supplied channel-scoped portfolio before returning a real verdict.",
|
|
4
|
+
"risks": ["No implementation or runtime acceptance has been assessed by this example."],
|
|
5
|
+
"plan": ["Assess the selected stack, imported project constraints, owner-approved commands, privacy, accessibility and real device scenarios.", "Return a concrete implementation and verification plan for the actual product, or preserve viable=false with exact blockers. No store approval claim is needed for local delivery."]
|
|
6
|
+
}
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
"id": "pack-balance",
|
|
3
3
|
"name": "行李配重与打包助手",
|
|
4
4
|
"framework": "flutter",
|
|
5
|
+
"platform": "ios",
|
|
6
|
+
"channel": "local",
|
|
7
|
+
"version": "1.0.0",
|
|
8
|
+
"screenshotsDir": "build/screenshots",
|
|
5
9
|
"purpose": "离线规划多个行李包的重量,完成出发打包与返程核对,减少遗漏和超重",
|
|
6
10
|
"audience": "需要管理随身包与托运行李的个人旅客",
|
|
7
11
|
"differentiators": [
|
|
@@ -28,12 +32,5 @@
|
|
|
28
32
|
"导入损坏、未知版本或字段非法的备份时给出可操作错误,原数据不被部分覆盖",
|
|
29
33
|
"在无网络、空清单、大字体与 VoiceOver 标签场景下完成创建、分配、勾选和恢复流程",
|
|
30
34
|
"截图来自真实运行页面,隐私说明和应用行为一致,不宣称保证航空公司接受或苹果过审"
|
|
31
|
-
]
|
|
32
|
-
"apple": {
|
|
33
|
-
"bundleId": "com.example.packbalance",
|
|
34
|
-
"version": "1.0.0",
|
|
35
|
-
"buildNumber": "1",
|
|
36
|
-
"locale": "zh-Hans",
|
|
37
|
-
"screenshotsDir": "build/screenshots"
|
|
38
|
-
}
|
|
35
|
+
]
|
|
39
36
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"viable": false,
|
|
3
|
+
"distinctness": "Unassessed example: evaluate this pending package's real purpose, audience, function, visual identity, developer/app metadata and code identity against the same-channel portfolio. Identical functionality with renamed labels is not meaningful differentiation.",
|
|
4
|
+
"risks": [
|
|
5
|
+
"No implementation or runtime acceptance has been assessed by this example.",
|
|
6
|
+
"Store submission, account setup and platform review are manual human work outside this tool; nothing here pre-approves a store reviewer."
|
|
7
|
+
],
|
|
8
|
+
"plan": [
|
|
9
|
+
"Assess real value, honest visual identity, truthful developer and app metadata, exercised functionality and genuine code identity for this package, comparing same-channel peers and treating earlier versions of this same app as its source baseline.",
|
|
10
|
+
"Plan concrete agent work followed by real runtime verification and a fresh independent review; preserve viable=false with exact blockers when owner facts are missing. Do not promise store approval or add unrequested features."
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"approved": false,
|
|
3
|
+
"findings": [
|
|
4
|
+
"This is an unassessed result-shape example, not a completed review. A fresh independent reviewer must inspect this package's actual source, effective metadata, runtime evidence and same-channel peers; another package's pass does not approve this job."
|
|
5
|
+
],
|
|
6
|
+
"acceptanceEvidence": []
|
|
7
|
+
}
|