@frankzhang2026/opencode-android-orchestrator 0.1.0 → 0.3.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 (124) hide show
  1. package/CHANGELOG.md +92 -2
  2. package/LICENSE +21 -0
  3. package/README.md +402 -6
  4. package/THIRD_PARTY_NOTICES.md +119 -0
  5. package/dist/cli.js +360 -1
  6. package/dist/cli.js.map +1 -1
  7. package/dist/compatibility/hooks.d.ts +23 -0
  8. package/dist/compatibility/hooks.d.ts.map +1 -0
  9. package/dist/compatibility/hooks.js +44 -0
  10. package/dist/compatibility/hooks.js.map +1 -0
  11. package/dist/compatibility/versions.d.ts +19 -0
  12. package/dist/compatibility/versions.d.ts.map +1 -1
  13. package/dist/compatibility/versions.js +116 -0
  14. package/dist/compatibility/versions.js.map +1 -1
  15. package/dist/doctor/index.d.ts +36 -0
  16. package/dist/doctor/index.d.ts.map +1 -0
  17. package/dist/doctor/index.js +289 -0
  18. package/dist/doctor/index.js.map +1 -0
  19. package/dist/doctor/installation.d.ts +4 -0
  20. package/dist/doctor/installation.d.ts.map +1 -0
  21. package/dist/doctor/installation.js +497 -0
  22. package/dist/doctor/installation.js.map +1 -0
  23. package/dist/index.d.ts +13 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +13 -2
  26. package/dist/index.js.map +1 -1
  27. package/dist/installer/adaptive-templates.d.ts +78 -0
  28. package/dist/installer/adaptive-templates.d.ts.map +1 -0
  29. package/dist/installer/adaptive-templates.js +233 -0
  30. package/dist/installer/adaptive-templates.js.map +1 -0
  31. package/dist/installer/agents-config.d.ts +19 -0
  32. package/dist/installer/agents-config.d.ts.map +1 -0
  33. package/dist/installer/agents-config.js +147 -0
  34. package/dist/installer/agents-config.js.map +1 -0
  35. package/dist/installer/android-project.d.ts +36 -0
  36. package/dist/installer/android-project.d.ts.map +1 -0
  37. package/dist/installer/android-project.js +418 -0
  38. package/dist/installer/android-project.js.map +1 -0
  39. package/dist/installer/index.d.ts +8 -0
  40. package/dist/installer/index.d.ts.map +1 -1
  41. package/dist/installer/index.js +8 -1
  42. package/dist/installer/index.js.map +1 -1
  43. package/dist/installer/init.d.ts +68 -0
  44. package/dist/installer/init.d.ts.map +1 -0
  45. package/dist/installer/init.js +398 -0
  46. package/dist/installer/init.js.map +1 -0
  47. package/dist/installer/install-manifest.d.ts +132 -0
  48. package/dist/installer/install-manifest.d.ts.map +1 -0
  49. package/dist/installer/install-manifest.js +1047 -0
  50. package/dist/installer/install-manifest.js.map +1 -0
  51. package/dist/installer/opencode-config.d.ts +32 -0
  52. package/dist/installer/opencode-config.d.ts.map +1 -0
  53. package/dist/installer/opencode-config.js +302 -0
  54. package/dist/installer/opencode-config.js.map +1 -0
  55. package/dist/installer/uninstall.d.ts +70 -0
  56. package/dist/installer/uninstall.d.ts.map +1 -0
  57. package/dist/installer/uninstall.js +770 -0
  58. package/dist/installer/uninstall.js.map +1 -0
  59. package/dist/installer/upgrade.d.ts +101 -0
  60. package/dist/installer/upgrade.d.ts.map +1 -0
  61. package/dist/installer/upgrade.js +1140 -0
  62. package/dist/installer/upgrade.js.map +1 -0
  63. package/dist/opencode-plugin.d.ts +2 -0
  64. package/dist/opencode-plugin.d.ts.map +1 -0
  65. package/dist/opencode-plugin.js +4 -0
  66. package/dist/opencode-plugin.js.map +1 -0
  67. package/dist/plugin/index.d.ts +7 -2
  68. package/dist/plugin/index.d.ts.map +1 -1
  69. package/dist/plugin/index.js +23 -6
  70. package/dist/plugin/index.js.map +1 -1
  71. package/dist/tools/index.d.ts +35 -1
  72. package/dist/tools/index.d.ts.map +1 -1
  73. package/dist/tools/index.js +197 -1
  74. package/dist/tools/index.js.map +1 -1
  75. package/docs/MIGRATION.md +184 -0
  76. package/docs/SECURITY.md +219 -0
  77. package/docs/TROUBLESHOOTING.md +171 -0
  78. package/package.json +23 -5
  79. package/templates/.opencode/agents/scheduled-coder.md +115 -0
  80. package/templates/.opencode/agents/scheduled-planner.md +166 -0
  81. package/templates/.opencode/agents/scheduled-reviewer.md +88 -0
  82. package/templates/.opencode/commands/abort-task.md +20 -0
  83. package/templates/.opencode/commands/acceptance.md +20 -0
  84. package/templates/.opencode/commands/change.md +23 -0
  85. package/templates/.opencode/commands/resume-review.md +19 -0
  86. package/templates/.opencode/skills/scheduled-quality-coder/SKILL.md +93 -0
  87. package/templates/.opencode/skills/scheduled-quality-orchestrator/SKILL.md +216 -0
  88. package/templates/.opencode/skills/scheduled-quality-reviewer/SKILL.md +68 -0
  89. package/templates/AGENTS.md.fragment +19 -0
  90. package/templates/README.md +55 -9
  91. package/templates/automation/config.json +67 -0
  92. package/templates/automation/config.schema.json +194 -0
  93. package/templates/automation/task-contract.schema.json +92 -0
  94. package/templates/automation/tasks/TASK-TEMPLATE.json.example +56 -0
  95. package/templates/docs/plans/README.md +26 -0
  96. package/templates/installation-manifest.schema.json +201 -0
  97. package/templates/scripts/automation/abort-task.sh +171 -0
  98. package/templates/scripts/automation/accept-and-integrate.sh +263 -0
  99. package/templates/scripts/automation/acceptance-report.sh +132 -0
  100. package/templates/scripts/automation/approve-and-run.sh +175 -0
  101. package/templates/scripts/automation/begin-review.sh +18 -0
  102. package/templates/scripts/automation/block-task.sh +26 -0
  103. package/templates/scripts/automation/claim-task.sh +74 -0
  104. package/templates/scripts/automation/integration-scope-gate.sh +103 -0
  105. package/templates/scripts/automation/lib.sh +815 -0
  106. package/templates/scripts/automation/orchestrate-task.sh +119 -0
  107. package/templates/scripts/automation/preflight.sh +206 -0
  108. package/templates/scripts/automation/prepare-contract-review.sh +101 -0
  109. package/templates/scripts/automation/quality-gate.sh +72 -0
  110. package/templates/scripts/automation/queue-task.sh +35 -0
  111. package/templates/scripts/automation/record-red.sh +55 -0
  112. package/templates/scripts/automation/resume-review-fix.sh +32 -0
  113. package/templates/scripts/automation/resume-review.sh +120 -0
  114. package/templates/scripts/automation/scope-gate.sh +110 -0
  115. package/templates/scripts/automation/select-task.sh +34 -0
  116. package/templates/scripts/automation/shadow-run.sh +24 -0
  117. package/templates/scripts/automation/show-acceptance-review.sh +111 -0
  118. package/templates/scripts/automation/status.sh +125 -0
  119. package/templates/scripts/automation/submit-review.sh +73 -0
  120. package/templates/scripts/automation/tests/run-tests.sh +716 -0
  121. package/templates/scripts/automation/transition-state.sh +21 -0
  122. package/templates/scripts/automation/validate-contract.sh +98 -0
  123. package/templates/scripts/automation/verify-integration.sh +38 -0
  124. package/templates/scripts/automation/verify-task.sh +39 -0
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
5
+ # shellcheck source=lib.sh
6
+ source "$SCRIPT_DIR/lib.sh"
7
+
8
+ task_id="${1:-}"
9
+ expected="${2:-}"
10
+ next="${3:-}"
11
+ actor="${4:-}"
12
+ note="${5:-}"
13
+
14
+ if [[ -z "$task_id" || -z "$expected" || -z "$next" || -z "$actor" || -z "$note" ]]; then
15
+ printf 'Usage: %s TASK-ID EXPECTED NEXT ACTOR NOTE\n' "$0" >&2
16
+ exit 2
17
+ fi
18
+
19
+ automation_validate_task_id "$task_id"
20
+ automation_require_layout
21
+ automation_transition_state "$task_id" "$expected" "$next" "$actor" "$note"
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
5
+ # shellcheck source=lib.sh
6
+ source "$SCRIPT_DIR/lib.sh"
7
+
8
+ usage() {
9
+ printf 'Usage: %s TASK-ID|/path/to/contract.json\n' "$0" >&2
10
+ }
11
+
12
+ input="${1:-}"
13
+ [[ -n "$input" ]] || { usage; exit 2; }
14
+ automation_require_command jq
15
+ automation_require_layout
16
+ automation_validate_config
17
+
18
+ if [[ "$input" == */* || "$input" == *.json || "$input" == *.example ]]; then
19
+ contract="$input"
20
+ [[ "$contract" == /* ]] || contract="$AUTOMATION_ROOT/$contract"
21
+ else
22
+ automation_validate_task_id "$input"
23
+ contract="$(automation_contract_path "$input")"
24
+ fi
25
+
26
+ [[ -f "$contract" ]] || automation_die "contract not found: $contract"
27
+ jq -e . "$contract" >/dev/null || automation_die "contract is not valid JSON: $contract"
28
+
29
+ jq -e '
30
+ .schemaVersion == 1 and
31
+ (.id | type == "string" and test("^TASK-[A-Z0-9-]+$")) and
32
+ (.title | type == "string" and length > 0) and
33
+ .designApproved == true and
34
+ (.planPath | type == "string" and length > 0) and
35
+ .ambiguityPolicy == "BLOCKED" and
36
+ (.maxFixLoops | type == "number" and . >= 0 and . <= 1 and floor == .) and
37
+ (.maxChangedFiles | type == "number" and . >= 1 and . <= 12 and floor == .) and
38
+ (.allowedPaths | type == "array" and length > 0) and
39
+ (.forbiddenPaths | type == "array" and length > 0) and
40
+ (.allowedSuperpowers == ["test-driven-development", "systematic-debugging", "verification-before-completion"]) and
41
+ (.acceptanceCriteria | type == "array" and length > 0) and
42
+ (.nonGoals | type == "array" and length > 0) and
43
+ (.targetTests | type == "array" and length > 0 and all(.[];
44
+ type == "object" and
45
+ keys == ["filter", "gradleTask"] and
46
+ (.gradleTask | type == "string" and test("^(?:[A-Za-z][A-Za-z0-9_.-]*|(?::[A-Za-z0-9_.-]+)+)$")) and
47
+ (.filter | type == "string" and test("^[A-Za-z0-9_.#$*-]+$")))) and
48
+ ([.targetTests[].filter] | length == (unique | length)) and
49
+ (.deviceTestsRequired | type == "boolean") and
50
+ (.testPolicy == "required" or .testPolicy == "not-required") and
51
+ (if .testPolicy == "not-required" then (.testPolicyReason | type == "string" and length >= 20) else true end)
52
+ ' "$contract" >/dev/null || automation_die "contract is missing required fields or violates limits"
53
+
54
+ task_id="$(jq -r '.id' "$contract")"
55
+ automation_validate_task_id "$task_id"
56
+
57
+ if [[ "$contract" == "$AUTOMATION_TASKS_DIR/"* ]]; then
58
+ expected_contract="$(automation_contract_path "$task_id")"
59
+ [[ "$contract" == "$expected_contract" ]] || automation_die "contract filename must match id: $(basename "$expected_contract")"
60
+ fi
61
+
62
+ while IFS= read -r value; do
63
+ [[ "$value" != /* ]] || automation_die "paths must be repository-relative: $value"
64
+ [[ "$value" != *".."* ]] || automation_die "paths may not contain '..': $value"
65
+ [[ "$value" =~ ^[A-Za-z0-9._/?*-]+$ ]] || automation_die "unsupported path pattern: $value"
66
+ done < <(jq -r '.allowedPaths[], .forbiddenPaths[]' "$contract")
67
+
68
+ while IFS= read -r protected; do
69
+ if automation_array_matches_path "$contract" '.allowedPaths' "$protected"; then
70
+ automation_die "allowedPaths overlaps protected path: $protected"
71
+ fi
72
+ if ! automation_array_matches_path "$contract" '.forbiddenPaths' "$protected"; then
73
+ automation_die "forbiddenPaths must cover protected path: $protected"
74
+ fi
75
+ done < <(jq -r '.protectedPaths[]' "$AUTOMATION_CONFIG")
76
+
77
+ while IFS=$'\t' read -r gradle_task filter; do
78
+ automation_validate_gradle_task "$gradle_task"
79
+ automation_validate_test_filter "$filter"
80
+ jq -e \
81
+ --arg task "$gradle_task" \
82
+ '.gradleVerification.focusedTestTasks | index($task) != null' \
83
+ "$AUTOMATION_CONFIG" >/dev/null || \
84
+ automation_die "target test Gradle task is not allowed by automation/config.json: $gradle_task"
85
+ done < <(jq -r '.targetTests[] | [.gradleTask, .filter] | @tsv' "$contract")
86
+
87
+ if rg -n -i 'replace with|TASK-EXAMPLE|todo|tbd|placeholder' "$contract" >/dev/null; then
88
+ automation_die "contract still contains template placeholders"
89
+ fi
90
+
91
+ plan_path="$(jq -r '.planPath' "$contract")"
92
+ if [[ "$plan_path" == /* || "$plan_path" == *".."* ]]; then
93
+ automation_die "planPath must be a safe repository-relative path"
94
+ fi
95
+ [[ "$plan_path" == "docs/plans/$task_id.md" ]] || automation_die "planPath must be docs/plans/$task_id.md"
96
+ [[ -f "$AUTOMATION_ROOT/$plan_path" ]] || automation_die "approved plan does not exist: $plan_path"
97
+
98
+ automation_info "contract valid: $task_id"
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
5
+ # shellcheck source=lib.sh
6
+ source "$SCRIPT_DIR/lib.sh"
7
+
8
+ task_id="${1:-}"
9
+ base="${2:-}"
10
+ head="${3:-}"
11
+ [[ "$#" -eq 3 ]] || { printf 'Usage: %s TASK-ID BASE-COMMIT HEAD-COMMIT\n' "$0" >&2; exit 2; }
12
+ automation_validate_task_id "$task_id"
13
+ [[ "$(automation_read_state "$task_id")" == "INTEGRATING" ]] || automation_die "$task_id is not INTEGRATING"
14
+ contract="$(automation_contract_path "$task_id")"
15
+ "$SCRIPT_DIR/validate-contract.sh" "$task_id" >/dev/null
16
+
17
+ "$SCRIPT_DIR/integration-scope-gate.sh" "$task_id" "$base" "$head"
18
+
19
+ while IFS=$'\t' read -r gradle_task filter; do
20
+ automation_info "running integration focused test ($gradle_task): $filter"
21
+ automation_run_focused_test "$gradle_task" "$filter" "$AUTOMATION_ROOT"
22
+ done < <(jq -r '.targetTests[] | [.gradleTask, .filter] | @tsv' "$contract")
23
+
24
+ automation_info "running integration full unit tests"
25
+ automation_run_gradle_group "fullUnitTestTasks" "$AUTOMATION_ROOT"
26
+
27
+ automation_info "running configured integration assemble tasks"
28
+ automation_run_gradle_group "assembleTasks" "$AUTOMATION_ROOT"
29
+
30
+ automation_info "running configured integration Android lint tasks"
31
+ automation_run_gradle_group "lintTasks" "$AUTOMATION_ROOT"
32
+
33
+ if [[ "$(jq -r '.deviceTestsRequired' "$contract")" == "true" ]]; then
34
+ automation_info "running configured integration device tests"
35
+ automation_run_gradle_group "deviceTestTasks" "$AUTOMATION_ROOT"
36
+ fi
37
+
38
+ automation_info "integration candidate passed all deterministic verification"
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
5
+ # shellcheck source=lib.sh
6
+ source "$SCRIPT_DIR/lib.sh"
7
+
8
+ task_id="${1:-}"
9
+ [[ -n "$task_id" ]] || { printf 'Usage: %s TASK-ID\n' "$0" >&2; exit 2; }
10
+ automation_validate_task_id "$task_id"
11
+ "$SCRIPT_DIR/validate-contract.sh" "$task_id" >/dev/null
12
+
13
+ contract="$(automation_contract_path "$task_id")"
14
+ evidence_dir="$(automation_evidence_path "$task_id")"
15
+ [[ -f "$evidence_dir/baseline.json" ]] || { automation_die "baseline evidence is missing"; exit 41; }
16
+ [[ -f "$evidence_dir/red.json" ]] || { automation_die "RED evidence is missing"; exit 41; }
17
+
18
+ "$SCRIPT_DIR/scope-gate.sh" "$task_id"
19
+
20
+ while IFS=$'\t' read -r gradle_task filter; do
21
+ automation_info "running focused test ($gradle_task): $filter"
22
+ automation_run_focused_test "$gradle_task" "$filter" "$AUTOMATION_ROOT"
23
+ done < <(jq -r '.targetTests[] | [.gradleTask, .filter] | @tsv' "$contract")
24
+
25
+ automation_info "running full unit tests"
26
+ automation_run_gradle_group "fullUnitTestTasks" "$AUTOMATION_ROOT"
27
+
28
+ automation_info "running configured assemble tasks"
29
+ automation_run_gradle_group "assembleTasks" "$AUTOMATION_ROOT"
30
+
31
+ automation_info "running configured Android lint tasks"
32
+ automation_run_gradle_group "lintTasks" "$AUTOMATION_ROOT"
33
+
34
+ if [[ "$(jq -r '.deviceTestsRequired' "$contract")" == "true" ]]; then
35
+ automation_info "running configured device tests"
36
+ automation_run_gradle_group "deviceTestTasks" "$AUTOMATION_ROOT"
37
+ fi
38
+
39
+ automation_info "all deterministic verification commands passed"