omniconductor 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 (118) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE +219 -0
  3. package/NOTICE +11 -0
  4. package/README.md +526 -0
  5. package/THIRD_PARTY_NOTICES.md +31 -0
  6. package/TRADEMARKS.md +26 -0
  7. package/VISION.md +106 -0
  8. package/adapters/README.md +121 -0
  9. package/adapters/claude/README.md +102 -0
  10. package/adapters/claude/SUPPORTED-FEATURES.md +66 -0
  11. package/adapters/claude/hookify-templates/.recipe-scoped +9 -0
  12. package/adapters/claude/hookify-templates/README.md +93 -0
  13. package/adapters/claude/hookify-templates/block-completion-claim-without-push.local.md.template +56 -0
  14. package/adapters/claude/hookify-templates/block-direct-push-protected-branch.local.md.template +18 -0
  15. package/adapters/claude/hookify-templates/block-force-push-protected-branch.local.md.template +42 -0
  16. package/adapters/claude/hookify-templates/block-server-secret-in-client.local.md.template +36 -0
  17. package/adapters/claude/hookify-templates/warn-any-type-added.local.md.template +44 -0
  18. package/adapters/claude/hookify-templates/warn-commit-without-pre-commit-review.local.md.template +52 -0
  19. package/adapters/claude/hookify-templates/warn-console-direct.local.md.template +55 -0
  20. package/adapters/claude/hookify-templates/warn-create-table-without-access-control.local.md.template +35 -0
  21. package/adapters/claude/hookify-templates/warn-current-work-without-remaining-tasks.local.md.template +36 -0
  22. package/adapters/claude/hookify-templates/warn-gh-pr-create-without-pre-merge-review.local.md.template +38 -0
  23. package/adapters/claude/hookify-templates/warn-hardcoded-text-without-i18n-key.local.md.template +21 -0
  24. package/adapters/claude/hookify-templates/warn-on-gh-pr-merge.local.md.template +33 -0
  25. package/adapters/claude/hookify-templates/warn-plan-spec-without-remaining-tasks.local.md.template +44 -0
  26. package/adapters/claude/hookify-templates/warn-raw-hex-instead-of-token.local.md.template +21 -0
  27. package/adapters/claude/hookify-templates/warn-security-definer-without-search-path.local.md.template +30 -0
  28. package/adapters/claude/hookify-templates/warn-stop-commit-without-current-work.local.md.template +47 -0
  29. package/adapters/claude/hookify-templates/warn-user-manual-completion.local.md.template +40 -0
  30. package/adapters/claude/transform-spec.md +140 -0
  31. package/adapters/claude/transform.sh +1169 -0
  32. package/adapters/codex/README.md +87 -0
  33. package/adapters/codex/SUPPORTED-FEATURES.md +66 -0
  34. package/adapters/codex/transform-spec.md +90 -0
  35. package/adapters/codex/transform.sh +748 -0
  36. package/adapters/copilot/README.md +88 -0
  37. package/adapters/copilot/SUPPORTED-FEATURES.md +73 -0
  38. package/adapters/copilot/transform-spec.md +111 -0
  39. package/adapters/copilot/transform.sh +757 -0
  40. package/adapters/cursor/README.md +87 -0
  41. package/adapters/cursor/SUPPORTED-FEATURES.md +90 -0
  42. package/adapters/cursor/transform-spec.md +124 -0
  43. package/adapters/cursor/transform.sh +731 -0
  44. package/adapters/gemini/README.md +93 -0
  45. package/adapters/gemini/SUPPORTED-FEATURES.md +80 -0
  46. package/adapters/gemini/transform-spec.md +102 -0
  47. package/adapters/gemini/transform.sh +844 -0
  48. package/adapters/windsurf/README.md +93 -0
  49. package/adapters/windsurf/SUPPORTED-FEATURES.md +67 -0
  50. package/adapters/windsurf/transform-spec.md +99 -0
  51. package/adapters/windsurf/transform.sh +727 -0
  52. package/bin/omniconductor.js +130 -0
  53. package/core/README.md +64 -0
  54. package/core/anti-patterns/README.md +142 -0
  55. package/core/anti-patterns/dynamic-system-prompt.md +113 -0
  56. package/core/anti-patterns/frequent-rule-file-edit.md +83 -0
  57. package/core/anti-patterns/large-file-read-no-range.md +90 -0
  58. package/core/anti-patterns/no-sub-agent-dispatch.md +89 -0
  59. package/core/anti-patterns/single-monolithic-rule-file.md +99 -0
  60. package/core/anti-patterns/skill-eager-load.md +83 -0
  61. package/core/anti-patterns/tool-call-spam.md +93 -0
  62. package/core/docs-templates/CURRENT_WORK.md +64 -0
  63. package/core/docs-templates/INDEX.md +57 -0
  64. package/core/docs-templates/PLANS.md +44 -0
  65. package/core/docs-templates/README.md +40 -0
  66. package/core/docs-templates/REMAINING_TASKS.md +43 -0
  67. package/core/docs-templates/TASKS.md +51 -0
  68. package/core/docs-templates/specs/_example.md +121 -0
  69. package/core/hooks/README.md +62 -0
  70. package/core/hooks/pretool-agent-routing.sh.template +97 -0
  71. package/core/hooks/pretool-commit-current-work-check.sh.template +103 -0
  72. package/core/hooks/pretool-commit-test-coverage-check.sh.template +116 -0
  73. package/core/hooks/pretool-large-file-read-guard.sh.template +117 -0
  74. package/core/hooks/stop-cache-hit-baseline-check.sh.template +133 -0
  75. package/core/hooks/stop-r6-review-check.sh.template +80 -0
  76. package/core/hooks/stop-session-log-check.sh.template +101 -0
  77. package/core/hooks/stop-trajectory-log.sh.template +96 -0
  78. package/core/memory-pattern/EXAMPLES.md +114 -0
  79. package/core/memory-pattern/README.md +133 -0
  80. package/core/recipes/README.md +46 -0
  81. package/core/recipes/auto-mock-data.md +82 -0
  82. package/core/recipes/branch-strategy.md +100 -0
  83. package/core/recipes/coding-conventions.md +123 -0
  84. package/core/recipes/database-discipline.md +65 -0
  85. package/core/recipes/debugging.md +143 -0
  86. package/core/recipes/design-system.md +30 -0
  87. package/core/recipes/i18n.md +118 -0
  88. package/core/recipes/monorepo.md +101 -0
  89. package/core/recipes/self-improvement.md +61 -0
  90. package/core/recipes/tdd.md +128 -0
  91. package/core/recipes/web-mobile-parity.md +87 -0
  92. package/core/reflector/SCHEDULING.md +83 -0
  93. package/core/reflector/prune-lessons.sh +105 -0
  94. package/core/reflector/reflect-brief.md +11 -0
  95. package/core/reflector/reflect.command.md +13 -0
  96. package/core/reflector/run-weekly.sh +54 -0
  97. package/core/reflector/trajectory-log.sh +55 -0
  98. package/core/roles/README.md +61 -0
  99. package/core/roles/builder.md +75 -0
  100. package/core/roles/designer.md +93 -0
  101. package/core/roles/helper.md +70 -0
  102. package/core/roles/planner.md +123 -0
  103. package/core/roles/reflector.md +72 -0
  104. package/core/roles/reviewer.md +104 -0
  105. package/core/roles/scribe.md +89 -0
  106. package/core/universal-rules/README.md +71 -0
  107. package/core/universal-rules/meta-discipline.md +292 -0
  108. package/core/universal-rules/operations.md +162 -0
  109. package/core/universal-rules/quality-gates.md +191 -0
  110. package/core/universal-rules/spec-as-you-go.md +123 -0
  111. package/core/universal-rules/workflow.md +153 -0
  112. package/core/workflow/PHASES.md +134 -0
  113. package/core/workflow/README.md +56 -0
  114. package/docs/MANUAL-INSTALL.md +456 -0
  115. package/package.json +52 -0
  116. package/tools/check-framework-purity.sh +91 -0
  117. package/tools/measure-tokens.sh +169 -0
  118. package/tools/validate-adapter-output.sh +611 -0
@@ -0,0 +1,844 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # CONDUCTOR — Gemini CLI adapter transform.sh
4
+ #
5
+ # Reads core/ assets and writes them into a target project as native Gemini CLI
6
+ # files: a single always-loaded GEMINI.md bundle, an optional .gemini/styleguide.md,
7
+ # and docs/* templates.
8
+ #
9
+ # Usage:
10
+ # bash adapters/gemini/transform.sh <target-project> [--recipes=<comma-list>] [--dry-run]
11
+ # [--no-prompt]
12
+ # bash adapters/gemini/transform.sh <target-project> --uninstall [--dry-run] [--force]
13
+ #
14
+ # Examples:
15
+ # bash adapters/gemini/transform.sh ~/Projects/my-app
16
+ # bash adapters/gemini/transform.sh ~/Projects/my-app --recipes=coding-conventions,i18n
17
+ # bash adapters/gemini/transform.sh /tmp/test-project --dry-run
18
+ # bash adapters/gemini/transform.sh . --no-prompt
19
+ # bash adapters/gemini/transform.sh . --uninstall # revert install
20
+ # bash adapters/gemini/transform.sh . --uninstall --force # bypass safety checks
21
+ #
22
+ # Layer 2 transformation (per ADR-004 honesty + ADR-021):
23
+ # core/universal-rules/*.md → <target>/GEMINI.md (all 5 bundled, single always-loaded file)
24
+ # core/workflow/PHASES.md → <target>/GEMINI.md (compressed workflow section)
25
+ # core/recipes/*.md (selected) → <target>/GEMINI.md (## Recipe — <name> sections; Gemini is single-file)
26
+ # core/recipes/coding-conventions → <target>/.gemini/styleguide.md (Gemini style-guide convention; opt-in)
27
+ # core/docs-templates/*.md → <target>/docs/*.md (CURRENT_WORK, REMAINING_TASKS, etc.)
28
+ # core/hooks/*.sh.template → SKIPPED (Reflector hook emitted via --recipes=self-improvement, ADR-032; other guards Claude-only, ADR-034)
29
+ # core/roles/*.md → SKIPPED (Gemini has no sub-agent dispatch)
30
+ #
31
+ # Gemini reality (per adapters/gemini/SUPPORTED-FEATURES.md):
32
+ # - Single always-loaded rule file (GEMINI.md). No per-pattern rule scoping.
33
+ # - No sub-agents, no per-call model routing, no built-in memory dir. CONDUCTOR
34
+ # emits the Reflector hook when --recipes=self-improvement (ADR-032); other
35
+ # guards remain Claude-only (ADR-034).
36
+ # The bundle below carries the rule TEXT honestly; Claude-only enforcement mechanisms
37
+ # are noted as self-policed for Gemini, never faked.
38
+
39
+ set -eu
40
+
41
+ # ----- arg parsing --------------------------------------------------------
42
+
43
+ TARGET=""
44
+ RECIPES=""
45
+ DRY_RUN="false"
46
+ NO_PROMPT="false"
47
+ UNINSTALL="false"
48
+ FORCE="false"
49
+
50
+ # Onboarding wizard state
51
+ WIZARD_APPLY_RULES="true"
52
+
53
+ while [ $# -gt 0 ]; do
54
+ case "$1" in
55
+ --recipes=*) RECIPES="${1#--recipes=}" ;;
56
+ --dry-run) DRY_RUN="true" ;;
57
+ --no-prompt) NO_PROMPT="true" ;;
58
+ --uninstall|--rollback) UNINSTALL="true" ;;
59
+ --force) FORCE="true" ;;
60
+ --help|-h)
61
+ /bin/cat <<EOF
62
+ Usage: bash adapters/gemini/transform.sh <target-project> [options]
63
+
64
+ Options:
65
+ --recipes=A,B,C Comma-separated list of recipes to install (appended into GEMINI.md)
66
+ --dry-run Preview only — no files written
67
+ --no-prompt Skip all interactive prompts; apply sensible defaults (CI-safe)
68
+ --uninstall Revert a previous install using <target>/.conductor-manifest.json
69
+ (alias: --rollback). Restores backups when present, deletes
70
+ Conductor-emitted files when none. Customizations not in the
71
+ manifest are preserved.
72
+ --force Bypass uninstall safety checks (active worktrees, missing manifest)
73
+
74
+ Recipes available: web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement
75
+
76
+ Gemini single-file model:
77
+ - All 5 universal rules + selected recipes are bundled into one always-loaded GEMINI.md.
78
+ - There is NO per-pattern rule scoping (Gemini loads the whole file every session).
79
+ - The 'coding-conventions' recipe ALSO produces .gemini/styleguide.md (Gemini's
80
+ native style-guide convention).
81
+
82
+ What this adapter does NOT install (per ADR-004 honesty + ADR-021):
83
+ - Hook guards (CONDUCTOR emits the Reflector hook when --recipes=self-improvement, ADR-032; other guards remain Claude-only, ADR-034)
84
+ - Sub-agent personas (Gemini has no sub-agent dispatch — single chat session per task)
85
+ - Per-call model routing (single model per Gemini session)
86
+ - Built-in memory directory (DIY at .memory/ — see the note inside GEMINI.md)
87
+ EOF
88
+ exit 0
89
+ ;;
90
+ *)
91
+ if [ -z "$TARGET" ]; then
92
+ TARGET="$1"
93
+ else
94
+ echo "Unknown argument: $1" >&2
95
+ exit 1
96
+ fi
97
+ ;;
98
+ esac
99
+ shift
100
+ done
101
+
102
+ if [ -z "$TARGET" ]; then
103
+ echo "Error: target-project path is required." >&2
104
+ echo "Usage: bash adapters/gemini/transform.sh <target-project> [--recipes=...]" >&2
105
+ exit 1
106
+ fi
107
+
108
+ # Resolve CONDUCTOR root (where this script lives: adapters/gemini/).
109
+ CONDUCTOR_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
110
+ CORE_ROOT="$CONDUCTOR_ROOT/core"
111
+ [ -d "$CORE_ROOT" ] || { echo "Error: core/ not found at $CORE_ROOT" >&2; exit 1; }
112
+
113
+ if [ "$DRY_RUN" = "true" ]; then
114
+ mkdir -p "$TARGET"
115
+ fi
116
+ TARGET_ABS="$(cd "$TARGET" 2>/dev/null && pwd)" || { echo "Error: target directory does not exist or is not a directory: $TARGET" >&2; exit 1; }
117
+
118
+ # ----- helpers ------------------------------------------------------------
119
+
120
+ log() {
121
+ if [ "$DRY_RUN" = "true" ]; then
122
+ echo "[dry-run] $*"
123
+ else
124
+ echo "[conductor] $*"
125
+ fi
126
+ }
127
+
128
+ mkdir_if_real() {
129
+ if [ "$DRY_RUN" = "true" ]; then
130
+ log "would mkdir -p $1"
131
+ else
132
+ mkdir -p "$1"
133
+ fi
134
+ }
135
+
136
+ # Strip the CONDUCTOR universal frontmatter (first --- ... --- block) from src body.
137
+ # Print body to stdout.
138
+ strip_frontmatter() {
139
+ local src="$1"
140
+ /usr/bin/awk 'BEGIN{f=0} /^---$/{c++; if(c==2){f=1; next}} f==1' "$src"
141
+ }
142
+
143
+ # Derive a section title from a rule/recipe markdown file: the first H1 after the
144
+ # frontmatter, with the leading "# " stripped. Falls back to the basename.
145
+ derive_title() {
146
+ local src="$1"
147
+ local title
148
+ title="$(strip_frontmatter "$src" | /usr/bin/grep -m1 '^# ' | /usr/bin/sed -e 's/^# *//')"
149
+ if [ -z "$title" ]; then
150
+ title="$(basename "$src" .md)"
151
+ fi
152
+ printf '%s' "$title"
153
+ }
154
+
155
+ # Emit a rule/recipe body into GEMINI.md as a section.
156
+ # The body (sans frontmatter) is demoted: its H1 "# Title" line is dropped (the
157
+ # caller supplies the "## " heading) and the Claude-only callout is rewritten for
158
+ # Gemini reality per transform-spec.md:
159
+ # "> **Claude-only mechanism**: ..." -> "> **Note (Gemini)**: enforced by hook
160
+ # on Claude Code; on Gemini CLI, follow self-policed."
161
+ # Honors DRY_RUN at the caller level (caller guards writes); this fn only prints.
162
+ emit_rule_body() {
163
+ local src="$1"
164
+ strip_frontmatter "$src" \
165
+ | /usr/bin/awk '
166
+ BEGIN{dropped=0}
167
+ # Drop the first H1 (the section title is provided by the caller as "## ").
168
+ dropped==0 && /^# /{dropped=1; next}
169
+ # Rewrite Claude-only mechanism callouts for Gemini self-policing.
170
+ /^> \*\*Claude-only mechanism\*\*/{
171
+ print "> **Note (Gemini)**: enforced by hook on Claude Code; on Gemini CLI, follow self-policed."
172
+ next
173
+ }
174
+ {print}
175
+ '
176
+ }
177
+
178
+ # backup_if_exists <dest>
179
+ # If <dest> is a regular file, copy it to <dest>.conductor-backup-<timestamp> before any
180
+ # downstream step overwrites it. Honors DRY_RUN. Idempotent across re-installs.
181
+ # Origin: ADR-019 (Claude adapter pattern, mirrored here per ADR-021).
182
+ backup_if_exists() {
183
+ local dest="$1"
184
+ if [ -f "$dest" ]; then
185
+ local ts
186
+ ts="$(/bin/date +%Y%m%d-%H%M%S)"
187
+ local backup="${dest}.conductor-backup-${ts}"
188
+ if [ "$DRY_RUN" = "true" ]; then
189
+ log "would back up existing $dest -> $backup"
190
+ else
191
+ /bin/cp "$dest" "$backup"
192
+ log " backed up existing $dest -> $backup"
193
+ fi
194
+ fi
195
+ }
196
+
197
+ # ----- manifest tracking (ADR-020, mirrored per ADR-021) ------------------
198
+ #
199
+ # Format identical to Claude/Cursor adapter manifests. POSIX shell + sed only — no jq.
200
+
201
+ MANIFEST_PATH="$TARGET_ABS/.conductor-manifest.json"
202
+ MANIFEST_STAGE_PATH=""
203
+ MANIFEST_TS=""
204
+ MANIFEST_LAST_BACKUP=""
205
+
206
+ init_manifest() {
207
+ if [ "$DRY_RUN" = "true" ]; then
208
+ log "would init manifest staging at $MANIFEST_PATH.staging"
209
+ return
210
+ fi
211
+ MANIFEST_TS="$(/bin/date -u +%Y-%m-%dT%H:%M:%SZ)"
212
+ MANIFEST_STAGE_PATH="$TARGET_ABS/.conductor-manifest.json.staging"
213
+ /bin/rm -f "$MANIFEST_STAGE_PATH"
214
+ : > "$MANIFEST_STAGE_PATH"
215
+ }
216
+
217
+ record_emit() {
218
+ if [ "$DRY_RUN" = "true" ] || [ "$UNINSTALL" = "true" ]; then
219
+ return
220
+ fi
221
+ local relpath="$1" src="$2" backup="${3:-}"
222
+ local had_backup="false"
223
+ [ -n "$backup" ] && had_backup="true"
224
+ local esc_path esc_src esc_backup
225
+ esc_path="$(printf '%s' "$relpath" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
226
+ esc_src="$(printf '%s' "$src" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
227
+ esc_backup="$(printf '%s' "$backup" | /usr/bin/sed 's/\\/\\\\/g; s/"/\\"/g')"
228
+ printf ' {"path": "%s", "source": "%s", "had_backup": %s, "backup_path": "%s"},\n' \
229
+ "$esc_path" "$esc_src" "$had_backup" "$esc_backup" >> "$MANIFEST_STAGE_PATH"
230
+ }
231
+
232
+ finalize_manifest() {
233
+ if [ "$DRY_RUN" = "true" ]; then
234
+ log "would finalize manifest -> $MANIFEST_PATH"
235
+ return
236
+ fi
237
+ [ -z "$MANIFEST_STAGE_PATH" ] && return
238
+ [ -f "$MANIFEST_STAGE_PATH" ] || return
239
+
240
+ if [ -f "$MANIFEST_PATH" ]; then
241
+ backup_if_exists "$MANIFEST_PATH"
242
+ fi
243
+
244
+ local recipes_json="[]"
245
+ if [ -n "$RECIPES" ]; then
246
+ recipes_json="["
247
+ local IFS_BAK=$IFS
248
+ IFS=','
249
+ local first="true"
250
+ for r in $RECIPES; do
251
+ r="$(printf '%s' "$r" | /usr/bin/sed 's/^ *//; s/ *$//')"
252
+ [ -z "$r" ] && continue
253
+ if [ "$first" = "true" ]; then
254
+ recipes_json="${recipes_json}\"$r\""
255
+ first="false"
256
+ else
257
+ recipes_json="${recipes_json}, \"$r\""
258
+ fi
259
+ done
260
+ IFS=$IFS_BAK
261
+ recipes_json="${recipes_json}]"
262
+ fi
263
+
264
+ local entries
265
+ if [ -s "$MANIFEST_STAGE_PATH" ]; then
266
+ entries="$(/usr/bin/sed -e '$ s/,$//' "$MANIFEST_STAGE_PATH")"
267
+ else
268
+ entries=""
269
+ fi
270
+
271
+ /bin/cat > "$MANIFEST_PATH" <<EOF
272
+ {
273
+ "version": "v0.2.0",
274
+ "adapter": "gemini",
275
+ "install_timestamp": "$MANIFEST_TS",
276
+ "conductor_root": "$CONDUCTOR_ROOT",
277
+ "recipes_enabled": $recipes_json,
278
+ "emitted_files": [
279
+ $entries
280
+ ]
281
+ }
282
+ EOF
283
+ /bin/rm -f "$MANIFEST_STAGE_PATH"
284
+ log " wrote manifest $MANIFEST_PATH"
285
+ }
286
+
287
+ backup_and_remember() {
288
+ MANIFEST_LAST_BACKUP=""
289
+ if [ -f "$1" ]; then
290
+ if [ "$DRY_RUN" = "true" ]; then
291
+ log "would back up existing $1 -> $1.conductor-backup-<ts>"
292
+ MANIFEST_LAST_BACKUP=""
293
+ else
294
+ local ts
295
+ ts="$(/bin/date +%Y%m%d-%H%M%S)"
296
+ local backup="$1.conductor-backup-$ts"
297
+ /bin/cp "$1" "$backup"
298
+ log " backed up existing $1 -> $backup"
299
+ MANIFEST_LAST_BACKUP="${backup#$TARGET_ABS/}"
300
+ fi
301
+ fi
302
+ }
303
+
304
+ # ----- uninstall flow (mirrored from Cursor/Claude adapter) ---------------
305
+
306
+ do_uninstall() {
307
+ log "uninstall mode (target: $TARGET_ABS)"
308
+
309
+ if [ ! -f "$MANIFEST_PATH" ]; then
310
+ if [ "$FORCE" = "true" ]; then
311
+ log "WARNING: no manifest at $MANIFEST_PATH — proceeding under --force (legacy backup scan only)"
312
+ uninstall_legacy_scan
313
+ return 0
314
+ fi
315
+ echo "Error: no manifest at $MANIFEST_PATH." >&2
316
+ echo " This target was either installed by a pre-manifest version or has already been uninstalled." >&2
317
+ echo " Re-run with --force to scan for legacy .conductor-backup-* files and delete them anyway:" >&2
318
+ echo " bash $0 $TARGET_ABS --uninstall --force" >&2
319
+ exit 1
320
+ fi
321
+
322
+ if [ -d "$TARGET_ABS/.git" ]; then
323
+ if [ -f "$TARGET_ABS/.git/MERGE_HEAD" ] || [ -f "$TARGET_ABS/.git/REBASE_HEAD" ] || [ -d "$TARGET_ABS/.git/rebase-merge" ]; then
324
+ if [ "$FORCE" != "true" ]; then
325
+ echo "Error: target has an active git operation (merge/rebase in progress)." >&2
326
+ echo " Resolve the in-flight operation first, or pass --force to override." >&2
327
+ exit 1
328
+ fi
329
+ log "WARNING: active git operation detected — proceeding under --force"
330
+ fi
331
+ fi
332
+
333
+ log "loading manifest entries..."
334
+ local entries_count=0
335
+ local restored=0
336
+ local deleted=0
337
+ local missing=0
338
+
339
+ while IFS= read -r line; do
340
+ case "$line" in
341
+ *'"path":'*'"source":'*'"had_backup":'*)
342
+ ;;
343
+ *) continue ;;
344
+ esac
345
+ entries_count=$((entries_count + 1))
346
+ local rel_path src had_backup backup_path
347
+ rel_path="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"path": *"([^"]*)".*/\1/')"
348
+ src="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"source": *"([^"]*)".*/\1/')"
349
+ had_backup="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"had_backup": *(true|false).*/\1/')"
350
+ backup_path="$(printf '%s' "$line" | /usr/bin/sed -E 's/.*"backup_path": *"([^"]*)".*/\1/')"
351
+
352
+ local abs_dest="$TARGET_ABS/$rel_path"
353
+ local abs_backup=""
354
+ [ -n "$backup_path" ] && abs_backup="$TARGET_ABS/$backup_path"
355
+
356
+ if [ "$had_backup" = "true" ] && [ -n "$abs_backup" ]; then
357
+ if [ -f "$abs_backup" ]; then
358
+ if [ "$DRY_RUN" = "true" ]; then
359
+ log " would restore $abs_backup -> $abs_dest"
360
+ else
361
+ /bin/mv -f "$abs_backup" "$abs_dest"
362
+ log " restored $abs_backup -> $abs_dest"
363
+ fi
364
+ restored=$((restored + 1))
365
+ else
366
+ if [ "$DRY_RUN" = "true" ]; then
367
+ log " would delete $abs_dest (backup $abs_backup missing)"
368
+ else
369
+ /bin/rm -f "$abs_dest"
370
+ log " deleted $abs_dest (backup $abs_backup missing)"
371
+ fi
372
+ missing=$((missing + 1))
373
+ fi
374
+ else
375
+ if [ -f "$abs_dest" ]; then
376
+ if [ "$DRY_RUN" = "true" ]; then
377
+ log " would delete $abs_dest"
378
+ else
379
+ /bin/rm -f "$abs_dest"
380
+ log " deleted $abs_dest"
381
+ fi
382
+ deleted=$((deleted + 1))
383
+ else
384
+ log " skip $abs_dest (already absent)"
385
+ fi
386
+ fi
387
+ done < "$MANIFEST_PATH"
388
+
389
+ if [ "$DRY_RUN" = "true" ]; then
390
+ log " would delete $MANIFEST_PATH"
391
+ for mb in "$MANIFEST_PATH".conductor-backup-*; do
392
+ [ -e "$mb" ] && log " would delete $mb"
393
+ done
394
+ else
395
+ /bin/rm -f "$MANIFEST_PATH"
396
+ for mb in "$MANIFEST_PATH".conductor-backup-*; do
397
+ [ -e "$mb" ] && /bin/rm -f "$mb"
398
+ done
399
+ log " deleted $MANIFEST_PATH"
400
+ fi
401
+
402
+ # Try to clean up empty dirs left behind (children before parents).
403
+ for d in .gemini/commands .gemini/agents .conductor/reflect .conductor .gemini; do
404
+ local abs_d="$TARGET_ABS/$d"
405
+ if [ -d "$abs_d" ]; then
406
+ if [ "$DRY_RUN" = "true" ]; then
407
+ if [ -z "$(/bin/ls -A "$abs_d" 2>/dev/null)" ]; then
408
+ log " would rmdir empty $abs_d"
409
+ fi
410
+ else
411
+ /bin/rmdir "$abs_d" 2>/dev/null && log " rmdir empty $abs_d" || true
412
+ fi
413
+ fi
414
+ done
415
+
416
+ echo ""
417
+ echo "========================================================"
418
+ if [ "$DRY_RUN" = "true" ]; then
419
+ echo " Uninstall preview (dry-run)"
420
+ else
421
+ echo " Uninstall complete"
422
+ fi
423
+ echo " Target: $TARGET_ABS"
424
+ echo " Entries processed: $entries_count"
425
+ echo " Backups restored: $restored"
426
+ echo " Files deleted: $deleted"
427
+ echo " Backup-missing deletes: $missing"
428
+ echo "========================================================"
429
+ }
430
+
431
+ uninstall_legacy_scan() {
432
+ log "legacy scan mode — searching for .conductor-backup-* files under $TARGET_ABS"
433
+ local found=0
434
+ while IFS= read -r f; do
435
+ found=$((found + 1))
436
+ if [ "$DRY_RUN" = "true" ]; then
437
+ log " would delete legacy backup $f"
438
+ else
439
+ /bin/rm -f "$f"
440
+ log " deleted legacy backup $f"
441
+ fi
442
+ done < <(/usr/bin/find "$TARGET_ABS" -type f -name '*.conductor-backup-*' 2>/dev/null)
443
+ log "legacy scan: $found backup file(s)"
444
+ log "WARNING: legacy mode does not delete Conductor-emitted source files (no manifest)."
445
+ log " Delete GEMINI.md and .gemini/styleguide.md manually if desired."
446
+ }
447
+
448
+ if [ "$UNINSTALL" = "true" ]; then
449
+ do_uninstall
450
+ exit 0
451
+ fi
452
+
453
+ # ----- onboarding wizard --------------------------------------------------
454
+ # Wizard fires when adopter signal is detected: existing GEMINI.md OR existing .gemini/.
455
+ # Otherwise (truly fresh target) wizard is skipped.
456
+
457
+ IS_ADOPTER_CASE="false"
458
+ if [ -f "$TARGET_ABS/GEMINI.md" ] || [ -d "$TARGET_ABS/.gemini" ]; then
459
+ IS_ADOPTER_CASE="true"
460
+ fi
461
+
462
+ if [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "false" ] && [ "$DRY_RUN" = "false" ]; then
463
+ echo ""
464
+ echo "========================================================"
465
+ echo " Welcome to CONDUCTOR setup (Gemini CLI adapter)"
466
+ echo " Target: $TARGET_ABS"
467
+ echo "========================================================"
468
+ echo ""
469
+
470
+ printf "Detect existing config? (y/N): "
471
+ read -r _detect_answer
472
+ if [ "$_detect_answer" = "y" ] || [ "$_detect_answer" = "Y" ]; then
473
+ _has_gemini="no"
474
+ [ -f "$TARGET_ABS/GEMINI.md" ] && _has_gemini="yes"
475
+ _has_styleguide="no"
476
+ [ -f "$TARGET_ABS/.gemini/styleguide.md" ] && _has_styleguide="yes"
477
+ echo " GEMINI.md present: $_has_gemini, .gemini/styleguide.md present: $_has_styleguide"
478
+ fi
479
+
480
+ printf "Apply universal-rules bundle? (Y/n): "
481
+ read -r _apply_answer
482
+ if [ "$_apply_answer" = "n" ] || [ "$_apply_answer" = "N" ]; then
483
+ WIZARD_APPLY_RULES="false"
484
+ echo " Skipping universal-rules installation."
485
+ fi
486
+
487
+ echo ""
488
+ echo "Available recipes:"
489
+ echo " web-mobile-parity, i18n, monorepo, branch-strategy, auto-mock-data, coding-conventions, tdd, debugging, database-discipline, design-system, self-improvement"
490
+ printf "Select recipes (comma-separated, or leave blank for none): "
491
+ read -r _recipe_answer
492
+ if [ -n "$_recipe_answer" ]; then
493
+ RECIPES="$_recipe_answer"
494
+ echo " Recipes selected: $RECIPES"
495
+ else
496
+ echo " No recipes selected."
497
+ fi
498
+
499
+ echo ""
500
+ elif [ "$IS_ADOPTER_CASE" = "true" ] && [ "$NO_PROMPT" = "true" ]; then
501
+ log "Adopter case detected — applying defaults (--no-prompt): rules=yes, recipes=${RECIPES:-(none)}"
502
+ fi
503
+
504
+ # ----- step 1: GEMINI.md bundle (header + rules + workflow + pointers) ----
505
+
506
+ init_manifest
507
+
508
+ UNIVERSAL_RULES="workflow spec-as-you-go quality-gates operations meta-discipline"
509
+ GEMINI_DEST="$TARGET_ABS/GEMINI.md"
510
+ INSTALLED_RECIPES=""
511
+
512
+ # Detect whether the coding-conventions recipe is in the selection (drives styleguide emit).
513
+ WANT_STYLEGUIDE="false"
514
+ if [ -n "$RECIPES" ]; then
515
+ _old_ifs="$IFS"; IFS=','
516
+ for _r in $RECIPES; do
517
+ _r="$(printf '%s' "$_r" | /usr/bin/sed 's/^ *//; s/ *$//')"
518
+ [ "$_r" = "coding-conventions" ] && WANT_STYLEGUIDE="true"
519
+ done
520
+ IFS="$_old_ifs"
521
+ fi
522
+
523
+ log "Step 1/3: GEMINI.md bundle → $GEMINI_DEST"
524
+
525
+ if [ -f "$GEMINI_DEST" ] && [ "$DRY_RUN" = "false" ]; then
526
+ backup_and_remember "$GEMINI_DEST"
527
+ fi
528
+
529
+ if [ "$DRY_RUN" = "true" ]; then
530
+ log "would synthesize $GEMINI_DEST (bilingual header + ABSOLUTE rules summary + 5 universal rules + workflow + memory note)"
531
+ if [ "$WIZARD_APPLY_RULES" != "true" ]; then
532
+ log " (universal-rules opted out — header + workflow + docs pointer only)"
533
+ fi
534
+ if [ -n "$RECIPES" ]; then
535
+ log " would append recipe sections for: $RECIPES"
536
+ fi
537
+ else
538
+ # --- Header (synthesized inline; bilingual 한/영) ---
539
+ /bin/cat > "$GEMINI_DEST" <<'HEADER_EOF'
540
+ # CONDUCTOR — Orchestrator Manual (Gemini CLI)
541
+
542
+ > Installed by CONDUCTOR (Gemini adapter). Gemini CLI auto-loads this file every session.
543
+ > Replace `{{PROJECT_NAME}}` below with your project name.
544
+
545
+ ## You are the orchestrator / 당신은 오케스트레이터입니다
546
+
547
+ **EN** — You are the lead orchestrator for **{{PROJECT_NAME}}**. You translate the
548
+ user's intent into a disciplined Plan → Architecture → Tasks → Implementation →
549
+ Review → Spec workflow. The universal rules below are your operating floor; every
550
+ turn inherits them. Gemini CLI runs a single chat session per task — there are no
551
+ sub-agents and no enforcement hooks here, so these rules are **self-policed**: you
552
+ follow them by reading them, not because a hook blocks you.
553
+
554
+ **KO** — 당신은 **{{PROJECT_NAME}}** 의 리드 오케스트레이터입니다. 사용자의 의도를
555
+ Plan → Architecture → Tasks → Implementation → Review → Spec 워크플로로 옮깁니다.
556
+ 아래 universal rule 은 모든 턴이 상속하는 기본 규칙입니다. Gemini CLI 는 작업당 단일
557
+ 세션으로 동작하며 sub-agent 나 enforcement hook 이 없습니다 — 따라서 이 규칙들은
558
+ **자기 규율(self-policed)** 로 지켜야 합니다.
559
+
560
+ > **Note (Gemini)**: Claude Code enforces parts of these rules with PreToolUse / Stop
561
+ > hooks and sub-agent dispatch. Gemini CLI has none of those surfaces. Where a rule
562
+ > mentions a Claude-only mechanism, treat it as self-policed: read the rule, follow it.
563
+
564
+ ## ABSOLUTE rules (summary) / 절대 규칙 요약
565
+
566
+ These are ABSOLUTE — no user shortcut ("just do it", "skip", "fast") waives them.
567
+ The full text is in the universal-rule sections that follow.
568
+
569
+ 1. **Plan-first / docs-first** — Plan → Architecture → Tasks → Implementation, in order.
570
+ Ad-hoc work is logged in `docs/CURRENT_WORK.md` BEFORE implementation. (Workflow)
571
+ 2. **Spec-as-you-go** — a source edit and its spec/doc update happen in the SAME turn,
572
+ never batched for later. (Spec-as-you-go)
573
+ 3. **Quality gates** — pre-commit + pre-merge review, test-coverage sync, and
574
+ verify-after-changes (evidence before any "done" claim). (Quality Gates)
575
+ 4. **Operations hygiene** — read `docs/CURRENT_WORK.md` first every session; delete
576
+ completed tasks from active lists; keep dev/prod in parity. (Operations)
577
+ 5. **Meta-discipline** — framework originality, ambiguity handling (ASK on the AMB
578
+ triggers), token economy, model-tier classification, flat-with-leader topology.
579
+ (Meta-Discipline)
580
+
581
+ > **Process over speed**: if a rule marked ABSOLUTE was skipped mid-turn, STOP, surface
582
+ > the violation in your next message, repair it, then continue. Silent recovery is worse
583
+ > than the original skip.
584
+
585
+ ---
586
+
587
+ HEADER_EOF
588
+
589
+ # --- Universal rules (each as "## <title>" + body sans frontmatter) ---
590
+ if [ "$WIZARD_APPLY_RULES" = "true" ]; then
591
+ for rule in $UNIVERSAL_RULES; do
592
+ src="$CORE_ROOT/universal-rules/$rule.md"
593
+ if [ ! -f "$src" ]; then
594
+ echo "Warning: $src not found; skipping" >&2
595
+ continue
596
+ fi
597
+ title="$(derive_title "$src")"
598
+ {
599
+ echo "## $title"
600
+ echo ""
601
+ emit_rule_body "$src"
602
+ echo ""
603
+ echo "---"
604
+ echo ""
605
+ } >> "$GEMINI_DEST"
606
+ done
607
+ else
608
+ log " universal-rules — skipped (user opted out)"
609
+ fi
610
+
611
+ # --- Compressed workflow section from core/workflow/PHASES.md ---
612
+ PHASES_SRC="$CORE_ROOT/workflow/PHASES.md"
613
+ if [ -f "$PHASES_SRC" ]; then
614
+ {
615
+ echo "## Workflow phases (compressed)"
616
+ echo ""
617
+ echo "> Full reference: CONDUCTOR's core/workflow/PHASES.md. Compressed here for the"
618
+ echo "> single-file Gemini bundle. Phases scale with scope (see the table at the end)."
619
+ echo ""
620
+ # Compress: keep numbered phase headers + their Trigger/Owner/Inputs/Outputs
621
+ # lines and the scaling table; drop the "How to read this file" template
622
+ # preamble and the per-phase "P1 fill" scaffolding.
623
+ /usr/bin/awk '
624
+ /^## [0-9]+\. /{inphase=1; print "### " substr($0,4); next}
625
+ inphase==1 && /^\*\*Trigger\*\*/{print; next}
626
+ inphase==1 && /^\*\*Owner\*\*/{print; next}
627
+ inphase==1 && /^\*\*Inputs\*\*/{print; next}
628
+ inphase==1 && /^\*\*Outputs\*\*/{print; next}
629
+ /^## Phase scaling reminder/{inphase=0; intable=1; print "### Phase scaling"; next}
630
+ /^## Tool-agnostic enforcement reminder/{intable=0; next}
631
+ intable==1{print; next}
632
+ ' "$PHASES_SRC"
633
+ echo ""
634
+ echo "---"
635
+ echo ""
636
+ } >> "$GEMINI_DEST"
637
+ fi
638
+
639
+ # --- Recipe sections (Gemini is single-file: append into GEMINI.md) ---
640
+ if [ -n "$RECIPES" ]; then
641
+ IFS=',' read -ra RECIPE_LIST <<< "$RECIPES"
642
+ for r in "${RECIPE_LIST[@]}"; do
643
+ r="$(printf '%s' "$r" | /usr/bin/sed 's/^ *//; s/ *$//')"
644
+ [ -z "$r" ] && continue
645
+ src="$CORE_ROOT/recipes/$r.md"
646
+ if [ ! -f "$src" ]; then
647
+ echo "Warning: recipe '$r' not found at $src; skipping" >&2
648
+ continue
649
+ fi
650
+ {
651
+ echo "## Recipe — $r"
652
+ echo ""
653
+ echo "> Opt-in recipe (installed via --recipes=$r). Gemini has no per-file rule"
654
+ echo "> scoping, so this is always-loaded alongside the universal rules."
655
+ echo ""
656
+ emit_rule_body "$src"
657
+ echo ""
658
+ echo "---"
659
+ echo ""
660
+ } >> "$GEMINI_DEST"
661
+ INSTALLED_RECIPES="$INSTALLED_RECIPES $r"
662
+ done
663
+ fi
664
+
665
+ # --- Docs pointer + memory note (footer) ---
666
+ /bin/cat >> "$GEMINI_DEST" <<'FOOTER_EOF'
667
+ ## First read every session / 매 세션 첫 작업
668
+
669
+ **Read `docs/CURRENT_WORK.md` first every session.** It is the single source of
670
+ "what is happening right now" — current state, immediate next action, in-progress
671
+ items, blockers. Without it you risk duplicating finished work or pushing
672
+ conflicting changes. (See the Operations rule above.)
673
+
674
+ ## Memory (.memory/) — DIY on Gemini / 메모리 설정
675
+
676
+ Gemini CLI has no built-in memory directory. CONDUCTOR's 4-type memory pattern
677
+ (user / feedback / project / reference) still applies — just host it yourself:
678
+
679
+ 1. Create a `.memory/` directory at the project root.
680
+ 2. Add `.memory/` to `.gitignore` so personal entries don't leak into the repo.
681
+ 3. Keep a `.memory/MEMORY.md` index (≤ 200 lines) and `*.md` entries per type.
682
+ 4. Gemini won't auto-load it — paste the relevant `.memory/*.md` entry into your
683
+ prompt (or @-mention the file) when it's relevant to the task.
684
+
685
+ Save: a user's role/preferences, corrections + validated approaches, ongoing
686
+ project goals/deadlines (use absolute dates), and pointers to external systems.
687
+ Do NOT save code patterns, file paths, git history, or anything already in the
688
+ rules above — verify before recommending from memory ("memory says X" ≠ "X is true now").
689
+ FOOTER_EOF
690
+
691
+ log " wrote $GEMINI_DEST ($(/usr/bin/wc -l < "$GEMINI_DEST" | /usr/bin/tr -d ' ') lines)"
692
+
693
+ # Gemini context-limit advisory (per transform-spec.md edge case).
694
+ _gemini_lines="$(/usr/bin/wc -l < "$GEMINI_DEST" | /usr/bin/tr -d ' ')"
695
+ if [ "$_gemini_lines" -gt 2000 ]; then
696
+ log " NOTE: GEMINI.md is large ($_gemini_lines lines). Most Gemini Pro models have a"
697
+ log " large context window, but if you hit a limit, trim recipes or move detail to docs/."
698
+ fi
699
+ fi
700
+ record_emit "GEMINI.md" "<synthesized:5-universal-rules+workflow>" "$MANIFEST_LAST_BACKUP"
701
+
702
+ # ----- step 2: .gemini/styleguide.md (opt-in: coding-conventions) ---------
703
+
704
+ log "Step 2/3: .gemini/styleguide.md (opt-in via --recipes=coding-conventions)"
705
+ if [ "$WANT_STYLEGUIDE" = "true" ]; then
706
+ STYLE_SRC="$CORE_ROOT/recipes/coding-conventions.md"
707
+ STYLE_DEST="$TARGET_ABS/.gemini/styleguide.md"
708
+ if [ ! -f "$STYLE_SRC" ]; then
709
+ echo "Warning: $STYLE_SRC not found; skipping styleguide" >&2
710
+ else
711
+ mkdir_if_real "$TARGET_ABS/.gemini"
712
+ if [ "$DRY_RUN" = "true" ]; then
713
+ log "would write $STYLE_DEST (coding-conventions body, header '# Code style guide')"
714
+ else
715
+ backup_and_remember "$STYLE_DEST"
716
+ {
717
+ echo "# Code style guide for {{PROJECT_NAME}}"
718
+ echo ""
719
+ echo "> Installed by CONDUCTOR (Gemini adapter) from the coding-conventions recipe."
720
+ echo "> Gemini CLI treats .gemini/styleguide.md as the canonical code-style reference."
721
+ echo "> Replace {{PROJECT_NAME}} with your project name."
722
+ echo ""
723
+ emit_rule_body "$STYLE_SRC"
724
+ } > "$STYLE_DEST"
725
+ record_emit ".gemini/styleguide.md" "core/recipes/coding-conventions.md" "$MANIFEST_LAST_BACKUP"
726
+ log " wrote $STYLE_DEST"
727
+ fi
728
+ fi
729
+ else
730
+ log " (coding-conventions not selected — pass --recipes=coding-conventions to emit styleguide)"
731
+ fi
732
+
733
+ # ----- self-improvement (opt-in: self-improvement recipe) ------------------
734
+
735
+ case ",$RECIPES," in
736
+ *",self-improvement,"*)
737
+ log "Step: self-improvement (Reflector) → .gemini hooks/command/agent"
738
+ if [ "$DRY_RUN" != "true" ]; then
739
+ /bin/mkdir -p "$TARGET_ABS/.conductor/reflect" "$TARGET_ABS/.gemini/commands" "$TARGET_ABS/.gemini/agents"
740
+ gi="$TARGET_ABS/.gitignore"
741
+ grep -qxF '.conductor/' "$gi" 2>/dev/null || printf '\n# CONDUCTOR runtime (local trajectories/lessons)\n.conductor/\n' >> "$gi"
742
+ for s in trajectory-log prune-lessons run-weekly; do
743
+ d="$TARGET_ABS/.conductor/reflect/$s.sh"
744
+ backup_and_remember "$d"; /bin/cp "$CORE_ROOT/reflector/$s.sh" "$d"; /bin/chmod +x "$d"
745
+ record_emit ".conductor/reflect/$s.sh" "core/reflector/$s.sh" "$MANIFEST_LAST_BACKUP"
746
+ done
747
+ # scheduling assets: run-weekly.sh needs the brief; SCHEDULING.md documents registration
748
+ for m in reflect-brief SCHEDULING; do
749
+ d="$TARGET_ABS/.conductor/reflect/$m.md"
750
+ backup_and_remember "$d"; /bin/cp "$CORE_ROOT/reflector/$m.md" "$d"
751
+ record_emit ".conductor/reflect/$m.md" "core/reflector/$m.md" "$MANIFEST_LAST_BACKUP"
752
+ done
753
+ # settings.json hooks — only if absent (merging JSON is unsafe in bash)
754
+ hc="$TARGET_ABS/.gemini/settings.json"
755
+ if [ ! -f "$hc" ]; then
756
+ backup_and_remember "$hc"
757
+ /bin/cat > "$hc" <<'HOOK'
758
+ {
759
+ "hooks": {
760
+ "SessionEnd": [
761
+ { "matcher": "*", "hooks": [ { "type": "command", "command": "\"$GEMINI_PROJECT_DIR\"/.conductor/reflect/trajectory-log.sh", "timeout": 30000 } ] }
762
+ ]
763
+ }
764
+ }
765
+ HOOK
766
+ record_emit ".gemini/settings.json" "<synthesized>" "$MANIFEST_LAST_BACKUP"
767
+ else
768
+ log " .gemini/settings.json exists — add a SessionEnd hook calling .conductor/reflect/trajectory-log.sh manually"
769
+ fi
770
+ cmd="$TARGET_ABS/.gemini/commands/reflect.toml"
771
+ backup_and_remember "$cmd"
772
+ { printf 'description = "Run the CONDUCTOR Reflector — propose lessons from recent sessions (propose-only)."\nprompt = """\n'; /bin/cat "$CORE_ROOT/reflector/reflect-brief.md"; printf '\n"""\n'; } > "$cmd"
773
+ record_emit ".gemini/commands/reflect.toml" "core/reflector/reflect-brief.md" "$MANIFEST_LAST_BACKUP"
774
+ ag="$TARGET_ABS/.gemini/agents/reflector.md"
775
+ backup_and_remember "$ag"
776
+ { printf -- '---\nname: reflector\ndescription: Reads session trajectories and proposes atomic lesson deltas. Propose-only; never applies.\n---\n\n'; strip_frontmatter "$CORE_ROOT/roles/reflector.md"; } > "$ag"
777
+ record_emit ".gemini/agents/reflector.md" "core/roles/reflector.md" "$MANIFEST_LAST_BACKUP"
778
+ fi
779
+ ;;
780
+ esac
781
+
782
+ # ----- step 3: docs templates --------------------------------------------
783
+
784
+ log "Step 3/3: docs templates → docs/"
785
+ mkdir_if_real "$TARGET_ABS/docs"
786
+ mkdir_if_real "$TARGET_ABS/docs/specs"
787
+
788
+ for tpl in CURRENT_WORK REMAINING_TASKS PLANS TASKS INDEX; do
789
+ src="$CORE_ROOT/docs-templates/$tpl.md"
790
+ dest="$TARGET_ABS/docs/$tpl.md"
791
+ [ -f "$src" ] || continue
792
+ if [ -f "$dest" ]; then
793
+ log " $dest exists — leaving in place"
794
+ continue
795
+ fi
796
+ if [ "$DRY_RUN" = "true" ]; then
797
+ log "would copy $src -> $dest"
798
+ else
799
+ /bin/cp "$src" "$dest"
800
+ record_emit "docs/$tpl.md" "core/docs-templates/$tpl.md" ""
801
+ fi
802
+ done
803
+
804
+ if [ -f "$CORE_ROOT/docs-templates/specs/_example.md" ]; then
805
+ src="$CORE_ROOT/docs-templates/specs/_example.md"
806
+ dest="$TARGET_ABS/docs/specs/_example.md"
807
+ if [ ! -f "$dest" ]; then
808
+ if [ "$DRY_RUN" = "true" ]; then
809
+ log "would copy $src -> $dest"
810
+ else
811
+ /bin/cp "$src" "$dest"
812
+ record_emit "docs/specs/_example.md" "core/docs-templates/specs/_example.md" ""
813
+ fi
814
+ fi
815
+ fi
816
+
817
+ # Finalize manifest after all emits.
818
+ finalize_manifest
819
+
820
+ # ----- completion summary -------------------------------------------------
821
+
822
+ echo ""
823
+ echo "========================================================"
824
+ echo " Done."
825
+ echo " Target: $TARGET_ABS"
826
+ echo " Adapter: gemini"
827
+ echo " GEMINI.md: 1 bundled file (5 universal rules + workflow, always-loaded)"
828
+ echo " Style guide: $([ "$WANT_STYLEGUIDE" = "true" ] && echo ".gemini/styleguide.md emitted" || echo "(not emitted — select coding-conventions)")"
829
+ echo " Recipes installed:${INSTALLED_RECIPES:- (none)}"
830
+ echo ""
831
+ echo " Skipped (per ADR-004 honesty):"
832
+ echo " - Hooks: CONDUCTOR emits the Reflector hook when --recipes=self-improvement (ADR-032); other guards remain Claude-only (ADR-034)."
833
+ echo " - Sub-agent personas: Gemini has no sub-agent dispatch — single chat session per task."
834
+ echo " - Per-call model routing: single model per Gemini session."
835
+ echo " - Built-in memory: DIY at .memory/ (see the note inside GEMINI.md)."
836
+ echo ""
837
+ echo " Activation: open $TARGET_ABS with Gemini CLI — it loads GEMINI.md automatically."
838
+ echo "========================================================"
839
+ echo ""
840
+ echo "Next steps for the project:"
841
+ echo " 1. Replace {{PROJECT_NAME}} in GEMINI.md (and .gemini/styleguide.md if present)."
842
+ echo " 2. Edit docs/CURRENT_WORK.md with your project's current state."
843
+ echo " 3. Add .memory/ to .gitignore if you adopt the DIY memory pattern."
844
+ echo " 4. Rename docs/specs/_example.md → docs/specs/<your-area>.md."