@frankzhang2026/opencode-android-orchestrator 0.8.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +85 -14
  3. package/dist/cli.js +9 -1
  4. package/dist/cli.js.map +1 -1
  5. package/dist/config/commit-message-prefix.d.ts +31 -0
  6. package/dist/config/commit-message-prefix.d.ts.map +1 -0
  7. package/dist/config/commit-message-prefix.js +155 -0
  8. package/dist/config/commit-message-prefix.js.map +1 -0
  9. package/dist/config/verification-policy.d.ts +5 -3
  10. package/dist/config/verification-policy.d.ts.map +1 -1
  11. package/dist/config/verification-policy.js +32 -13
  12. package/dist/config/verification-policy.js.map +1 -1
  13. package/dist/doctor/index.d.ts +2 -0
  14. package/dist/doctor/index.d.ts.map +1 -1
  15. package/dist/doctor/index.js +2 -1
  16. package/dist/doctor/index.js.map +1 -1
  17. package/dist/doctor/installation.d.ts.map +1 -1
  18. package/dist/doctor/installation.js +78 -0
  19. package/dist/doctor/installation.js.map +1 -1
  20. package/dist/index.d.ts +2 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +2 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/installer/adaptive-templates.d.ts +8 -2
  25. package/dist/installer/adaptive-templates.d.ts.map +1 -1
  26. package/dist/installer/adaptive-templates.js +9 -1
  27. package/dist/installer/adaptive-templates.js.map +1 -1
  28. package/dist/installer/gradle-verification.d.ts +10 -1
  29. package/dist/installer/gradle-verification.d.ts.map +1 -1
  30. package/dist/installer/gradle-verification.js +192 -27
  31. package/dist/installer/gradle-verification.js.map +1 -1
  32. package/dist/installer/index.d.ts +1 -0
  33. package/dist/installer/index.d.ts.map +1 -1
  34. package/dist/installer/index.js +1 -0
  35. package/dist/installer/index.js.map +1 -1
  36. package/dist/installer/init.d.ts +4 -1
  37. package/dist/installer/init.d.ts.map +1 -1
  38. package/dist/installer/init.js +73 -14
  39. package/dist/installer/init.js.map +1 -1
  40. package/dist/installer/opencode-config.d.ts +3 -3
  41. package/dist/installer/opencode-config.d.ts.map +1 -1
  42. package/dist/installer/opencode-config.js +1 -1
  43. package/dist/installer/opencode-config.js.map +1 -1
  44. package/dist/installer/upgrade.d.ts +12 -1
  45. package/dist/installer/upgrade.d.ts.map +1 -1
  46. package/dist/installer/upgrade.js +127 -15
  47. package/dist/installer/upgrade.js.map +1 -1
  48. package/docs/MIGRATION.md +46 -12
  49. package/docs/SECURITY.md +14 -5
  50. package/docs/TROUBLESHOOTING.md +25 -11
  51. package/package.json +1 -1
  52. package/templates/README.md +9 -1
  53. package/templates/automation/config.json +2 -1
  54. package/templates/automation/config.schema.json +7 -2
  55. package/templates/scripts/automation/abort-task.sh +2 -1
  56. package/templates/scripts/automation/accept-and-integrate.sh +4 -2
  57. package/templates/scripts/automation/approve-and-run.sh +1 -0
  58. package/templates/scripts/automation/lib.sh +93 -2
  59. package/templates/scripts/automation/orchestrate-task.sh +1 -0
  60. package/templates/scripts/automation/preflight.sh +11 -0
  61. package/templates/scripts/automation/show-acceptance-review.sh +3 -0
  62. package/templates/scripts/automation/tests/run-tests.sh +59 -4
@@ -110,7 +110,7 @@ printf '%s\n' \
110
110
  chmod +x "$fixture/gradlew"
111
111
 
112
112
  jq -n '{
113
- schemaVersion: 4,
113
+ schemaVersion: 5,
114
114
  enabled: true,
115
115
  mode: "orchestrated",
116
116
  workspaceStrategy: "inPlaceExclusive",
@@ -121,6 +121,7 @@ jq -n '{
121
121
  maxReviewerRestarts: 2,
122
122
  unitTestsEnabled: true,
123
123
  lintEnabled: false,
124
+ commitMessagePrefixMode: "required",
124
125
  longCommandTimeoutMs: 1800000,
125
126
  autoCleanupWorktrees: true,
126
127
  pushAfterAcceptance: false,
@@ -249,6 +250,8 @@ jq -n '{
249
250
  git commit -qm 'Create automation fixture'
250
251
  )
251
252
 
253
+ printf '%s\n' '批次甲' > "$fixture/automation/automation-commit-prefix"
254
+
252
255
  printf '%s\n' \
253
256
  '# Exact repository-relative paths intentionally kept local' \
254
257
  'local/operator-note.txt' \
@@ -260,6 +263,37 @@ run_fixture ./scripts/automation/preflight.sh --source >/dev/null
260
263
  allowlisted_changes="$(run_fixture bash -c 'source ./scripts/automation/lib.sh; automation_changed_paths')"
261
264
  [[ -z "$allowlisted_changes" ]] || fail "allowlisted paths remained visible: $allowlisted_changes"
262
265
 
266
+ printf '%s\n' \
267
+ '# 必填:请在下一行填写当前 Git 提交文案前缀' \
268
+ '# 示例:XXX' \
269
+ > "$fixture/automation/automation-commit-prefix"
270
+ if run_fixture ./scripts/automation/preflight.sh --source >/dev/null 2>&1; then
271
+ fail 'normal preflight accepted an unconfigured required commit prefix'
272
+ fi
273
+ run_fixture ./scripts/automation/preflight.sh --shadow >/dev/null 2>&1 || \
274
+ fail 'shadow preflight rejected the intentionally unconfigured installation template'
275
+ rm "$fixture/automation/automation-commit-prefix"
276
+ if run_fixture ./scripts/automation/preflight.sh --source >/dev/null 2>&1; then
277
+ fail 'normal preflight accepted a missing required commit prefix'
278
+ fi
279
+ run_fixture ./scripts/automation/preflight.sh --shadow >/dev/null 2>&1 || \
280
+ fail 'shadow preflight rejected a missing required commit prefix'
281
+ printf '%s\n' '批次甲' > "$fixture/automation/automation-commit-prefix"
282
+ pass 'required missing or unconfigured commit prefix blocks task startup but not shadow verification'
283
+
284
+ printf '%s\n' '批次甲' '第二行无效' > "$fixture/automation/automation-commit-prefix"
285
+ if run_fixture ./scripts/automation/preflight.sh --source >/dev/null 2>&1; then
286
+ fail 'preflight accepted more than one active commit-prefix line'
287
+ fi
288
+ rm "$fixture/automation/automation-commit-prefix"
289
+ ln -s ../local/operator-note.txt "$fixture/automation/automation-commit-prefix"
290
+ if run_fixture ./scripts/automation/preflight.sh --source >/dev/null 2>&1; then
291
+ fail 'preflight accepted a symbolic-link commit-prefix file'
292
+ fi
293
+ rm "$fixture/automation/automation-commit-prefix"
294
+ printf '%s\n' '批次甲' > "$fixture/automation/automation-commit-prefix"
295
+ pass 'invalid and symbolic-link commit-prefix files fail closed'
296
+
263
297
  printf '%s\n' \
264
298
  'local/operator-note.txt' \
265
299
  'local/generated-note.txt' \
@@ -288,6 +322,10 @@ printf '%s\n' 'automation/config.json' > "$fixture/.automation-worktree-allowlis
288
322
  if run_fixture bash -c 'source ./scripts/automation/lib.sh; automation_changed_paths >/dev/null' 2>/dev/null; then
289
323
  fail 'worktree allowlist accepted a protected automation path'
290
324
  fi
325
+ printf '%s\n' 'automation/automation-commit-prefix' > "$fixture/.automation-worktree-allowlist"
326
+ if run_fixture bash -c 'source ./scripts/automation/lib.sh; automation_changed_paths >/dev/null' 2>/dev/null; then
327
+ fail 'worktree allowlist accepted the reserved commit-prefix control file'
328
+ fi
291
329
  printf '%s\n' 'local/*.json' > "$fixture/.automation-worktree-allowlist"
292
330
  if run_fixture bash -c 'source ./scripts/automation/lib.sh; automation_changed_paths >/dev/null' 2>/dev/null; then
293
331
  fail 'worktree allowlist accepted a glob pattern'
@@ -595,6 +633,11 @@ approved_baseline="$(jq -er '.baselineHead' "$runtime_root/workspaces/TASK-TEST-
595
633
  [[ "$(git -C "$fixture" rev-list --count "$approved_baseline..automation/task-test-004")" -eq 0 ]] || fail 'contract approval created a planning-only commit'
596
634
  [[ "$(jq -r '.contractCommit' "$runtime_root/evidence/TASK-TEST-004/origin.json")" == "null" ]] || fail 'contract approval recorded a commit before product integration'
597
635
  [[ "$(git -C "$fixture" status --porcelain --untracked-files=all -- docs/plans/TASK-TEST-004.md automation/tasks/TASK-TEST-004.json | wc -l | tr -d ' ')" -eq 2 ]] || fail 'sealed planning artifacts were not left pending on the task branch'
636
+ printf '%s\n' '# 尚未填写提交前缀' > "$fixture/automation/automation-commit-prefix"
637
+ if run_task "$task_root" env AUTOMATION_SKIP_AGENT_RUN=1 ./scripts/automation/orchestrate-task.sh TASK-TEST-004 >/dev/null 2>&1; then
638
+ fail 'direct task launcher bypassed the required commit-prefix gate'
639
+ fi
640
+ printf '%s\n' '批次甲' > "$fixture/automation/automation-commit-prefix"
598
641
  [[ -f "$runtime_root/locks/repository.workspace.lease/lease.json" ]] || fail 'persistent repository lease was not created'
599
642
  leased_status="$(run_fixture ./scripts/automation/status.sh TASK-TEST-004)"
600
643
  [[ "$(jq -r '.runtime.repositoryLeaseMatches' <<< "$leased_status")" == "true" ]] || fail 'status did not verify the repository lease'
@@ -611,6 +654,7 @@ pass 'contract approval switches to a leased task branch while deferring the sea
611
654
 
612
655
  git -C "$fixture" add -- \
613
656
  .automation-worktree-allowlist \
657
+ automation/automation-commit-prefix \
614
658
  local/operator-note.txt \
615
659
  local/generated-note.txt
616
660
  run_task "$task_root" ./scripts/automation/claim-task.sh TASK-TEST-004 >/dev/null
@@ -628,7 +672,8 @@ if jq -e '.changedPaths | any(. == "local/operator-note.txt" or . == "local/gene
628
672
  fi
629
673
  if rg -F 'diff --git a/local/operator-note.txt b/local/operator-note.txt' "$runtime_root/evidence/TASK-TEST-004/sealed.diff" >/dev/null || \
630
674
  rg -F 'diff --git a/local/generated-note.txt b/local/generated-note.txt' "$runtime_root/evidence/TASK-TEST-004/sealed.diff" >/dev/null || \
631
- rg -F 'diff --git a/.automation-worktree-allowlist b/.automation-worktree-allowlist' "$runtime_root/evidence/TASK-TEST-004/sealed.diff" >/dev/null; then
675
+ rg -F 'diff --git a/.automation-worktree-allowlist b/.automation-worktree-allowlist' "$runtime_root/evidence/TASK-TEST-004/sealed.diff" >/dev/null || \
676
+ rg -F 'diff --git a/automation/automation-commit-prefix b/automation/automation-commit-prefix' "$runtime_root/evidence/TASK-TEST-004/sealed.diff" >/dev/null; then
632
677
  fail 'sealed diff included allowlisted local content'
633
678
  fi
634
679
  [[ "$(jq -r '.evidence.qualityGate' "$runtime_root/evidence/TASK-TEST-004/acceptance-report.json")" == "PASSED" ]] || fail 'acceptance package omitted quality-gate status'
@@ -637,6 +682,7 @@ acceptance_card="$(run_fixture ./scripts/automation/show-acceptance-review.sh TA
637
682
  [[ "$acceptance_card" == *"P0 · 真实行为是否满足合同"* ]] || fail 'acceptance review omitted behavioral focus'
638
683
  [[ "$acceptance_card" == *"P0 · 旧行为与范围是否被误伤"* ]] || fail 'acceptance review omitted regression and scope focus'
639
684
  [[ "$acceptance_card" == *"sealed diff SHA"* ]] || fail 'acceptance review omitted sealed binding'
685
+ [[ "$acceptance_card" == *"批次甲 Implement"* ]] || fail 'acceptance review omitted the current prefixed commit message'
640
686
  [[ "$acceptance_card" == *"成功集成后自动删除;失败或阻塞时保留"* ]] || fail 'acceptance review omitted task branch cleanup policy'
641
687
  pass 'automated evidence becomes one focused, SHA-verified human acceptance card'
642
688
 
@@ -654,8 +700,10 @@ if run_fixture env AUTOMATION_FAKE_GREEN=1 ./scripts/automation/accept-and-integ
654
700
  fi
655
701
  pass 'integrator requires final acceptance bound to the sealed diff'
656
702
 
703
+ printf '%s\n' '批次甲-提交时' > "$fixture/automation/automation-commit-prefix"
657
704
  run_fixture env AUTOMATION_FAKE_GREEN=1 ./scripts/automation/accept-and-integrate.sh TASK-TEST-004 '验收通过,提交到原分支。' >/dev/null
658
705
  combined_commit="$(jq -er '.productCommit' "$runtime_root/workspaces/TASK-TEST-004.json")"
706
+ [[ "$(git -C "$fixture" show -s --format=%s "$combined_commit")" == "批次甲-提交时 Implement "* ]] || fail 'combined task commit did not re-read the latest prefix at commit time'
659
707
  [[ "$(jq -r '.state' "$runtime_root/state/TASK-TEST-004.json")" == "COMPLETED" ]] || fail 'final integration did not reach COMPLETED'
660
708
  [[ "$(git -C "$fixture" symbolic-ref --short HEAD)" == "$original_branch" ]] || fail 'integrator changed the original branch identity'
661
709
  [[ -f "$fixture/mobile-client/src/main/java/dev/example/orchestratorfixture/OrchestratedFlow.kt" ]] || fail 'product change was not integrated into original branch'
@@ -670,7 +718,7 @@ for combined_path in \
670
718
  fail "combined task commit omitted $combined_path"
671
719
  done
672
720
  if git -C "$fixture" diff-tree --no-commit-id --name-only -r "$combined_commit" | \
673
- rg -x 'local/(operator-note|generated-note)\.txt|\.automation-worktree-allowlist' >/dev/null; then
721
+ rg -x 'local/(operator-note|generated-note)\.txt|\.automation-worktree-allowlist|automation/automation-commit-prefix' >/dev/null; then
674
722
  fail 'combined task commit included an allowlisted local path or its control file'
675
723
  fi
676
724
  [[ "$(cat "$fixture/local/operator-note.txt")" == "operator local edit" ]] || fail 'tracked allowlisted content changed during integration'
@@ -678,6 +726,7 @@ fi
678
726
  staged_allowlist_paths="$(git -C "$fixture" diff --cached --name-only HEAD -- | LC_ALL=C sort)"
679
727
  for staged_allowlist_path in \
680
728
  .automation-worktree-allowlist \
729
+ automation/automation-commit-prefix \
681
730
  local/generated-note.txt \
682
731
  local/operator-note.txt; do
683
732
  printf '%s\n' "$staged_allowlist_paths" | \
@@ -688,6 +737,7 @@ run_fixture bash -c 'source ./scripts/automation/lib.sh; automation_worktree_is_
688
737
  pass 'in-place integration preserves allowlisted local state without evidence or commit leakage'
689
738
  git -C "$fixture" restore --staged -- \
690
739
  .automation-worktree-allowlist \
740
+ automation/automation-commit-prefix \
691
741
  local/operator-note.txt \
692
742
  local/generated-note.txt
693
743
  [[ "$(jq -r '.contractCommit' "$runtime_root/evidence/TASK-TEST-004/origin.json")" == "$combined_commit" ]] || fail 'origin evidence did not bind the contract to the combined task commit'
@@ -714,8 +764,10 @@ jq \
714
764
  > "$fixture/automation/tasks/TASK-TEST-008.json"
715
765
  run_fixture ./scripts/automation/prepare-contract-review.sh TASK-TEST-008 '批准方案,生成计划和任务合同。' >/dev/null
716
766
  run_fixture env AUTOMATION_SKIP_AGENT_RUN=1 ./scripts/automation/approve-and-run.sh TASK-TEST-008 '合同已复核,批准自动执行到人工验收阶段。' >/dev/null
767
+ printf '%s\n' '批次乙' > "$fixture/automation/automation-commit-prefix"
717
768
  git -C "$fixture" add -- \
718
769
  .automation-worktree-allowlist \
770
+ automation/automation-commit-prefix \
719
771
  local/operator-note.txt \
720
772
  local/generated-note.txt
721
773
  printf '%s\n' 'class AbortArchive { fun value() = "preserved" }' > "$fixture/mobile-client/src/main/java/dev/example/orchestratorfixture/AbortArchive.kt"
@@ -728,16 +780,18 @@ fi
728
780
  rm "$fixture/out-of-contract.txt"
729
781
  run_fixture ./scripts/automation/abort-task.sh TASK-TEST-008 '中止任务,封存修改并恢复原分支。' >/dev/null
730
782
  abort_recovery_commit="$(jq -er '.recoveryCommit' "$runtime_root/evidence/TASK-TEST-008/abort.json")"
783
+ [[ "$(git -C "$fixture" show -s --format=%s "$abort_recovery_commit")" == "批次乙 Archive aborted work for TASK-TEST-008" ]] || fail 'abort recovery commit did not read the updated prefix'
731
784
  git -C "$fixture" cat-file -e "$abort_recovery_commit:mobile-client/src/main/java/dev/example/orchestratorfixture/AbortArchive.kt" || fail 'abort recovery commit omitted the allowed change'
732
785
  git -C "$fixture" cat-file -e "$abort_recovery_commit:docs/plans/TASK-TEST-008.md" || fail 'abort recovery commit omitted the sealed plan'
733
786
  git -C "$fixture" cat-file -e "$abort_recovery_commit:automation/tasks/TASK-TEST-008.json" || fail 'abort recovery commit omitted the sealed contract'
734
787
  if git -C "$fixture" diff-tree --no-commit-id --name-only -r "$abort_recovery_commit" | \
735
- rg -x 'local/(operator-note|generated-note)\.txt|\.automation-worktree-allowlist' >/dev/null; then
788
+ rg -x 'local/(operator-note|generated-note)\.txt|\.automation-worktree-allowlist|automation/automation-commit-prefix' >/dev/null; then
736
789
  fail 'abort recovery commit included an allowlisted local path or its control file'
737
790
  fi
738
791
  staged_abort_allowlist_paths="$(git -C "$fixture" diff --cached --name-only HEAD -- | LC_ALL=C sort)"
739
792
  for staged_allowlist_path in \
740
793
  .automation-worktree-allowlist \
794
+ automation/automation-commit-prefix \
741
795
  local/generated-note.txt \
742
796
  local/operator-note.txt; do
743
797
  printf '%s\n' "$staged_abort_allowlist_paths" | \
@@ -750,6 +804,7 @@ done
750
804
  pass 'abort refuses unrelated files and archives allowed uncommitted changes in a recovery commit'
751
805
  git -C "$fixture" restore --staged -- \
752
806
  .automation-worktree-allowlist \
807
+ automation/automation-commit-prefix \
753
808
  local/operator-note.txt \
754
809
  local/generated-note.txt
755
810