@jenga-ai/agent 1.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.
Files changed (177) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +340 -0
  3. package/agents/ai_engineer.md +113 -0
  4. package/agents/developer.md +236 -0
  5. package/agents/scrum-master.md +349 -0
  6. package/agents/scrutiny-agent.md +137 -0
  7. package/agents/solution-assessor.md +185 -0
  8. package/agents/tester.md +339 -0
  9. package/bin/jenga.js +70 -0
  10. package/hooks/copilot_session_end.sh +29 -0
  11. package/hooks/on_session_end.sh +238 -0
  12. package/hooks/prompt_router.sh +11 -0
  13. package/hooks/prompt_router_helper.js +52 -0
  14. package/hooks/session_end_helper.js +29 -0
  15. package/hooks/session_end_watcher.sh +24 -0
  16. package/lib/commands/attach.js +47 -0
  17. package/lib/commands/init.js +207 -0
  18. package/lib/commands/start.js +16 -0
  19. package/lib/commands/status.js +53 -0
  20. package/lib/config-schema.js +72 -0
  21. package/lib/inject-settings.js +61 -0
  22. package/lib/mirror.js +244 -0
  23. package/lib/resolve-project-dir.sh +47 -0
  24. package/mcp/execute-ticket/index.js +10 -0
  25. package/mcp/execute-ticket/package.json +5 -0
  26. package/mcp/help/index.js +79 -0
  27. package/mcp/help/package.json +14 -0
  28. package/mcp/router/README.md +19 -0
  29. package/mcp/router/embedder.js +23 -0
  30. package/mcp/router/index.js +204 -0
  31. package/mcp/router/matcher.js +87 -0
  32. package/mcp/router/package-lock.json +1048 -0
  33. package/mcp/router/package.json +11 -0
  34. package/mcp/router/skill-index.js +104 -0
  35. package/package.json +47 -0
  36. package/scripts/board_resolver.sh +46 -0
  37. package/scripts/e25_s01_extract_board_graph.py +292 -0
  38. package/scripts/e25_s01_generate_synthetic_board.py +90 -0
  39. package/scripts/measurement-10x.json +50 -0
  40. package/scripts/measurement-10x.txt +4 -0
  41. package/scripts/measurement-real.json +50 -0
  42. package/scripts/measurement-real.txt +4 -0
  43. package/scripts/postinstall.js +165 -0
  44. package/scripts/todo_cleanup.sh +22 -0
  45. package/scripts/todo_manager.sh +86 -0
  46. package/scripts/validate-board.sh +190 -0
  47. package/scripts/validate-story-format.sh +53 -0
  48. package/skills/brainstorm/SKILL.md +47 -0
  49. package/skills/btw/SKILL.md +42 -0
  50. package/skills/commit/SKILL.md +29 -0
  51. package/skills/commit/assets/user_instructions_template.md +22 -0
  52. package/skills/continue/SKILL.md +29 -0
  53. package/skills/convert/SKILL.md +124 -0
  54. package/skills/convert/convert_cli.py +235 -0
  55. package/skills/convert/tests/sample.csv +4 -0
  56. package/skills/convert/tests/sample.json +5 -0
  57. package/skills/convert/tests/sample.jsonl +3 -0
  58. package/skills/convert/tests/sample.yaml +18 -0
  59. package/skills/convert/tests/sample_obj.csv +2 -0
  60. package/skills/convert/tests/sample_obj.json +9 -0
  61. package/skills/deep-dive/SKILL.md +167 -0
  62. package/skills/do/SKILL.md +88 -0
  63. package/skills/do/assets/sender_template.json +12 -0
  64. package/skills/doc/SKILL.md +314 -0
  65. package/skills/doc/assets/path-objectives.yaml +38 -0
  66. package/skills/doc-sync/SKILL.md +167 -0
  67. package/skills/doc-sync/assets/default_excludes.txt +21 -0
  68. package/skills/doc-sync/assets/doc_targets.md +14 -0
  69. package/skills/dooo/SKILL.md +60 -0
  70. package/skills/error/SKILL.md +29 -0
  71. package/skills/evaluate/SKILL.md +45 -0
  72. package/skills/evaluate/assets/evaluation_invokation_template.yml +3 -0
  73. package/skills/evaluate/assets/evaluation_rapport_template.md +24 -0
  74. package/skills/examplify/SKILL.md +42 -0
  75. package/skills/help/SKILL.md +36 -0
  76. package/skills/improve/SKILL.md +55 -0
  77. package/skills/index/scripts/board-index +4 -0
  78. package/skills/index/scripts/board_index.py +615 -0
  79. package/skills/index/scripts/smoke_test.sh +86 -0
  80. package/skills/init/SKILL.md +44 -0
  81. package/skills/init/assets/.gitignore_template +15 -0
  82. package/skills/init/assets/PROJECT_SUMMARY_template.md +13 -0
  83. package/skills/init/assets/directory_structure.txt +13 -0
  84. package/skills/init/assets/test-config_template.json +4 -0
  85. package/skills/init/assets/workflow_template.json +30 -0
  86. package/skills/init/scripts/init.sh +48 -0
  87. package/skills/jbp/SKILL.md +25 -0
  88. package/skills/jenga/SKILL.md +68 -0
  89. package/skills/lgtm/SKILL.md +21 -0
  90. package/skills/mirror-public/SKILL.md +237 -0
  91. package/skills/mirror-public/assets/config.json +5 -0
  92. package/skills/mirror-public/scripts/mirror.sh +374 -0
  93. package/skills/pi-plan/SKILL.md +62 -0
  94. package/skills/pi-plan/assets/epic.json +7 -0
  95. package/skills/pi-plan/assets/story_template.md +18 -0
  96. package/skills/proceed/SKILL.md +29 -0
  97. package/skills/publish/SKILL.md +351 -0
  98. package/skills/publish/adapters/droplet.md +200 -0
  99. package/skills/publish/adapters/mobile-ios.md +114 -0
  100. package/skills/publish/adapters/npm-ci.md +223 -0
  101. package/skills/publish/adapters/npm.md +121 -0
  102. package/skills/publish/assets/ExportOptions.plist.template +19 -0
  103. package/skills/publish/assets/ci-contract.md +111 -0
  104. package/skills/publish/assets/ownership-matrix.md +17 -0
  105. package/skills/publish/assets/publish.example.json +85 -0
  106. package/skills/publish/assets/publish.example.npm-ci.json +40 -0
  107. package/skills/publish/assets/publish.example.npm.json +41 -0
  108. package/skills/publish/assets/secrets-guide.md +104 -0
  109. package/skills/publish/schemas/fixtures/npm-ci-minimal.json +17 -0
  110. package/skills/publish/schemas/fixtures/npm-ci-with-empty-secrets.json +18 -0
  111. package/skills/publish/schemas/fixtures/npm-ci-with-workflow-path.json +18 -0
  112. package/skills/publish/schemas/publish.schema.json +428 -0
  113. package/skills/publish/scripts/check_target_config.sh +96 -0
  114. package/skills/publish/scripts/droplet_pipeline.sh +208 -0
  115. package/skills/publish/scripts/generate_release_notes.sh +200 -0
  116. package/skills/publish/scripts/ios_pipeline.sh +486 -0
  117. package/skills/publish/scripts/npm_ci_pipeline.sh +225 -0
  118. package/skills/publish/scripts/npm_pipeline.sh +249 -0
  119. package/skills/publish/scripts/publish_common.sh +253 -0
  120. package/skills/publish/scripts/publish_deploy.sh +538 -0
  121. package/skills/publish/scripts/reconcile_tags.sh +135 -0
  122. package/skills/publish/scripts/run_gates.sh +616 -0
  123. package/skills/publish/scripts/setup_wizard.sh +394 -0
  124. package/skills/publish/scripts/show_history.sh +95 -0
  125. package/skills/publish/scripts/suggest_semver_bump.sh +105 -0
  126. package/skills/publish/scripts/validate_config.sh +163 -0
  127. package/skills/publish/scripts/validate_droplet_env.sh +45 -0
  128. package/skills/publish/scripts/validate_ios_env.sh +68 -0
  129. package/skills/publish/scripts/validate_npm_ci_env.sh +71 -0
  130. package/skills/publish/scripts/validate_npm_env.sh +22 -0
  131. package/skills/publish/scripts/write_ledger_entry.sh +126 -0
  132. package/skills/publish/wizards/droplet.md +275 -0
  133. package/skills/publish/wizards/mobile-ios.md +157 -0
  134. package/skills/publish/wizards/npm-ci.md +240 -0
  135. package/skills/publish/wizards/npm.md +224 -0
  136. package/skills/reconcile/SKILL.md +93 -0
  137. package/skills/reconcile/assets/report_format.md +44 -0
  138. package/skills/reconcile-origin/SKILL.md +75 -0
  139. package/skills/reconcile-origin/scripts/reconcile-origin.sh +372 -0
  140. package/skills/redo/SKILL.md +70 -0
  141. package/skills/route/SKILL.md +180 -0
  142. package/skills/self-sync/SKILL.md +73 -0
  143. package/skills/self-sync/scripts/run.js +136 -0
  144. package/skills/skillify/SKILL.md +68 -0
  145. package/skills/skillify/assets/init-new/SKILL.md +35 -0
  146. package/skills/skillify/assets/init-new/assets/.gitignore_template +15 -0
  147. package/skills/skillify/assets/init-new/assets/PROJECT_SUMMARY_template.md +13 -0
  148. package/skills/skillify/assets/init-new/assets/directory_structure.txt +10 -0
  149. package/skills/skillify/assets/init-new/assets/test-config_template.json +4 -0
  150. package/skills/skillify/assets/init-new/assets/workflow_template.json +17 -0
  151. package/skills/skillify/assets/init-new/scripts/init.sh +48 -0
  152. package/skills/skillify/assets/init-old/SKILL.md +124 -0
  153. package/skills/spinoff/SKILL.md +48 -0
  154. package/skills/status/SKILL.md +33 -0
  155. package/skills/status/assets/output_format.md +41 -0
  156. package/skills/todo/SKILL.md +46 -0
  157. package/skills/todo/assets/todo_handoff_template.md +22 -0
  158. package/skills/todo/assets/todo_template.md +3 -0
  159. package/skills/train/SKILL.md +116 -0
  160. package/skills/train/assets/dashboard-templates/classifiers.html +106 -0
  161. package/skills/train/assets/dashboard-templates/nlp.html +102 -0
  162. package/skills/train/assets/dashboard-templates/transformers.html +98 -0
  163. package/skills/train/assets/results-parsers/__init__.py +9 -0
  164. package/skills/train/assets/results-parsers/classifiers.py +84 -0
  165. package/skills/train/assets/results-parsers/nlp.py +88 -0
  166. package/skills/train/assets/results-parsers/reporter.py +154 -0
  167. package/skills/train/assets/results-parsers/transformers.py +120 -0
  168. package/skills/train/train_cli.py +786 -0
  169. package/templates/EXECUTION_PLAN_TEMPLATE.md +43 -0
  170. package/templates/EXECUTION_SUMMARY_TEMPLATE.md +50 -0
  171. package/templates/JENGA_CONFIG_TEMPLATE.json +23 -0
  172. package/templates/PROBLEM_RAPPORT_TEMPLATE.md +88 -0
  173. package/templates/SCRUM_BOARD_SCHEMA.md +311 -0
  174. package/templates/SKILL.md +16 -0
  175. package/templates/SKILL_TEMPLATE.md +28 -0
  176. package/templates/USER_INSTRUCTIONS_TEMPLATE.md +22 -0
  177. package/templates/copilot-instructions.md.tpl +55 -0
@@ -0,0 +1,275 @@
1
+ # Droplet setup wizard
2
+
3
+ Use this template to collect the values required for a `droplet` publish target.
4
+ Each section maps directly to a field in `publish.json`. The adapter is generic —
5
+ it works with any SSH-reachable Linux host, not just DigitalOcean droplets.
6
+
7
+ Before running the prompts, check whether `publish.json` already contains a target
8
+ whose `type` is `droplet`. If one exists, ask the user whether to **overwrite**
9
+ the existing target or **update** individual fields — do not silently replace it.
10
+
11
+ After collecting answers, write the target block to `publish.json` (create the
12
+ file from the base scaffold if it does not exist), validate the config, and write
13
+ `project/instructions/E22_S07_INSTRUCTIONS.md` listing the required GitHub secrets.
14
+ See the "Post-collection actions" section at the bottom for the full write sequence.
15
+
16
+ ---
17
+
18
+ ## Question: host
19
+
20
+ Maps to: `targets[].droplet.host`
21
+
22
+ Enter the IP address or fully qualified domain name (FQDN) of the target host.
23
+ This is the address GitHub Actions will SSH into when deploying.
24
+
25
+ ## Expected format:
26
+
27
+ A valid IPv4 address or hostname (e.g. `192.168.1.10`, `deploy.example.com`).
28
+
29
+ ---
30
+
31
+ ## Question: ssh_user
32
+
33
+ Maps to: `targets[].droplet.ssh_user`
34
+
35
+ Enter the SSH username used to connect to the target host. This user must have
36
+ read/write access to the `deploy_path` directory and permission to execute
37
+ `build_cmd` and `start_cmd`.
38
+
39
+ ## Expected format:
40
+
41
+ A valid Unix username (e.g. `deploy`, `ubuntu`, `root`).
42
+
43
+ ---
44
+
45
+ ## Question: ssh_port
46
+
47
+ Maps to: `targets[].droplet.ssh_port`
48
+
49
+ Enter the SSH port on the target host. Press Enter to accept the default (22).
50
+
51
+ ## Expected format:
52
+
53
+ An integer between 1 and 65535. Press Enter to accept the default (`22`).
54
+
55
+ ---
56
+
57
+ ## Question: deploy_path
58
+
59
+ Maps to: `targets[].droplet.deploy_path`
60
+
61
+ Enter the absolute path on the remote host where the repository is checked out.
62
+ This directory must already exist and contain a valid git working tree before the
63
+ first deploy (see First-run bootstrap in post-setup manual steps).
64
+
65
+ ## Expected format:
66
+
67
+ An absolute Unix path (e.g. `/var/www/myapp`, `/home/deploy/myapp`).
68
+
69
+ ---
70
+
71
+ ## Question: github_repo
72
+
73
+ Maps to: `targets[].droplet.github_repo`
74
+
75
+ Enter the GitHub repository that hosts this project, in `owner/name` format.
76
+ The adapter uses this value with `gh workflow run` to trigger the generated
77
+ workflow.
78
+
79
+ ## Expected format:
80
+
81
+ `owner/name` (e.g. `acme-corp/my-app`). Must match the pattern
82
+ `^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$`.
83
+
84
+ ---
85
+
86
+ ## Question: deploy_branch
87
+
88
+ Maps to: `targets[].droplet.deploy_branch`
89
+
90
+ Enter the git branch to pull on the remote host during deploy. The generated
91
+ GitHub Actions workflow will run `git pull origin <deploy_branch>` on the host.
92
+
93
+ ## Expected format:
94
+
95
+ A git branch name (e.g. `main`, `production`). Press Enter to accept the
96
+ default (`main`).
97
+
98
+ ---
99
+
100
+ ## Question: build_cmd
101
+
102
+ Maps to: `targets[].droplet.build_cmd`
103
+
104
+ Enter the build command to run on the remote host after pulling (e.g.
105
+ `npm run build`, `make build`, `pip install -r requirements.txt`). Leave blank
106
+ to skip the build step — the `build_cmd` field is optional.
107
+
108
+ ## Expected format:
109
+
110
+ Any valid shell command string, or press Enter to skip.
111
+
112
+ ---
113
+
114
+ ## Question: start_cmd
115
+
116
+ Maps to: `targets[].droplet.start_cmd`
117
+
118
+ Enter the command to (re)start the service on the remote host after deploy.
119
+ The adapter makes no assumptions about your runtime — supply whatever command
120
+ your deployment uses. This field is required.
121
+
122
+ ## Expected format:
123
+
124
+ A valid shell command (e.g. `pm2 reload ecosystem.config.js`,
125
+ `sudo systemctl restart myapp`, `./scripts/restart.sh`).
126
+
127
+ ---
128
+
129
+ ## Question: ssh_key_secret
130
+
131
+ Maps to: `targets[].secrets.ssh_key_secret`
132
+
133
+ Enter the **name** of the GitHub Actions secret that holds the SSH private key
134
+ used to authenticate with the target host. Do not enter the key value itself —
135
+ only the secret name. The adapter reads this name and injects
136
+ `${{ secrets.<ssh_key_secret> }}` into the generated workflow.
137
+
138
+ ## Expected format:
139
+
140
+ A GitHub Actions secret name (e.g. `DROPLET_SSH_KEY`). Uppercase, underscores
141
+ allowed.
142
+
143
+ ---
144
+
145
+ ## Question: known_hosts_secret
146
+
147
+ Maps to: `targets[].secrets.known_hosts_secret`
148
+
149
+ Enter the **name** of the GitHub Actions secret that holds the known_hosts
150
+ entry for the target host. This prevents MITM attacks during the SSH connection
151
+ from GitHub Actions. Generate the value with `ssh-keyscan <host>`.
152
+
153
+ ## Expected format:
154
+
155
+ A GitHub Actions secret name (e.g. `DROPLET_KNOWN_HOSTS`).
156
+
157
+ ---
158
+
159
+ ## Secrets Guide
160
+
161
+ The following secrets must be added to the GitHub repository before the first
162
+ deploy. Navigate to **Settings → Secrets and variables → Actions → New
163
+ repository secret** in the GitHub UI, or use the `gh` CLI as shown below.
164
+
165
+ | Secret name | What it holds |
166
+ |-----------------------|------------------------------------------------------------------|
167
+ | `DROPLET_SSH_KEY` | Contents of the SSH private key file (e.g. `~/.ssh/id_deploy`) |
168
+ | `DROPLET_SSH_HOST` | IP address or FQDN of the target host |
169
+ | `DROPLET_SSH_USER` | SSH username on the target host |
170
+ | `DROPLET_SSH_PORT` | SSH port (typically `22`) |
171
+ | `DROPLET_KNOWN_HOSTS` | Output of `ssh-keyscan <host>` for the target host |
172
+
173
+ ### How to add secrets via `gh` CLI
174
+
175
+ ```bash
176
+ # Private key — reads from file
177
+ gh secret set DROPLET_SSH_KEY < ~/.ssh/id_deploy
178
+
179
+ # Host and connection details
180
+ gh secret set DROPLET_SSH_HOST --body "your.host.ip.or.fqdn"
181
+ gh secret set DROPLET_SSH_USER --body "your-ssh-user"
182
+ gh secret set DROPLET_SSH_PORT --body "22"
183
+
184
+ # Known hosts — generate with ssh-keyscan
185
+ ssh-keyscan your.host.ip.or.fqdn | gh secret set DROPLET_KNOWN_HOSTS
186
+ ```
187
+
188
+ ### Via GitHub UI
189
+
190
+ 1. Go to your repository on GitHub.
191
+ 2. Navigate to **Settings** → **Secrets and variables** → **Actions**.
192
+ 3. Click **New repository secret** for each of the five secrets listed above.
193
+ 4. Paste the value and save.
194
+
195
+ ---
196
+
197
+ ## Post-setup manual steps
198
+
199
+ After the wizard completes, the following steps must be performed manually:
200
+
201
+ 1. **Add the listed secrets to the GitHub repo before the first deploy.**
202
+ The workflow will fail immediately if any of the five secrets above are
203
+ missing. Verify them at Settings → Secrets and variables → Actions.
204
+
205
+ 2. **Bootstrap the deploy path on the host before the first deploy.**
206
+ The adapter assumes the deploy path already contains a git working tree.
207
+ SSH into the host and run:
208
+ ```bash
209
+ git clone <your-repo-url> <deploy_path>
210
+ cd <deploy_path>
211
+ # Install any runtime dependencies (e.g. npm install, pip install)
212
+ ```
213
+
214
+ 3. **Push a commit to the deploy branch to trigger the first deploy.**
215
+ After running `/publish deploy --target <name>`, the generated workflow will
216
+ be committed and can be triggered via `gh workflow run` or by pushing to the
217
+ configured deploy branch.
218
+
219
+ ---
220
+
221
+ ## Post-collection actions
222
+
223
+ Once all answers have been collected, perform the following steps in order:
224
+
225
+ 1. **Load or scaffold `publish.json`.** If the file does not exist at the
226
+ project root, create it from the base scaffold with `version: 1`,
227
+ populated `defaults`, and an empty `targets` array. If it does exist,
228
+ parse and preserve every unrelated field.
229
+
230
+ 2. **Check for an existing droplet target.** Scan `targets[]` for any entry
231
+ with `"type": "droplet"`. If one exists, ask the user:
232
+ - **overwrite** — replace the entire target block with the wizard output
233
+ - **update** — merge the wizard answers into the existing target
234
+ field-by-field, keeping any user-added fields (e.g. custom `checks`)
235
+ If none exists, append a new target block.
236
+
237
+ 3. **Write the target block.** Emit it in the exact shape below (omit
238
+ `build_cmd` if the user left it blank):
239
+
240
+ ```json
241
+ {
242
+ "name": "my-droplet",
243
+ "type": "droplet",
244
+ "platform": "droplet-ssh",
245
+ "checks": { "pre": ["build", "test"], "post": [] },
246
+ "secrets": {
247
+ "ssh_key_secret": "DROPLET_SSH_KEY",
248
+ "known_hosts_secret": "DROPLET_KNOWN_HOSTS"
249
+ },
250
+ "droplet": {
251
+ "host": "<answer>",
252
+ "ssh_user": "<answer>",
253
+ "ssh_port": 22,
254
+ "deploy_path": "<answer>",
255
+ "github_repo": "<answer>",
256
+ "deploy_branch": "<answer>",
257
+ "build_cmd": "<answer or omit if blank>",
258
+ "start_cmd": "<answer>"
259
+ }
260
+ }
261
+ ```
262
+
263
+ 4. **Validate against the schema.** Run
264
+ `bash skills/publish/scripts/validate_config.sh <path-to-publish.json>`
265
+ before saving. If validation fails, report the error and abort — do not
266
+ write a broken `publish.json`.
267
+
268
+ 5. **Write the instructions file.** Create
269
+ `project/instructions/E22_S07_INSTRUCTIONS.md` listing the five required
270
+ GitHub secrets and how to add them. Create the `project/instructions/`
271
+ directory if it does not exist.
272
+
273
+ 6. **Report to the user.** Print a short summary listing (a) the target block
274
+ written, (b) the path to the instructions file, and (c) the five GitHub
275
+ secrets that must be configured before the first deploy.
@@ -0,0 +1,157 @@
1
+ # mobile-ios setup wizard
2
+
3
+ Use this template to collect the values required for a `mobile-ios` publish target.
4
+ Each section maps directly to a field in `publish.json`.
5
+
6
+ ## Question: bundle_id
7
+
8
+ Maps to: `targets[].ios.bundle_id`
9
+
10
+ Enter the iOS bundle identifier for the app you want to publish.
11
+ This should match the bundle identifier configured in Xcode and Apple Developer.
12
+
13
+ ## Expected format:
14
+
15
+ Reverse-DNS identifier such as `com.example.myapp`.
16
+
17
+ ## Question: team_id
18
+
19
+ Maps to: `targets[].ios.team_id`
20
+
21
+ Enter the Apple Developer Team ID that owns the signing assets for this app.
22
+
23
+ ## Expected format:
24
+
25
+ Uppercase alphanumeric team identifier such as `ABCDE12345`.
26
+
27
+ ## Question: scheme
28
+
29
+ Maps to: `targets[].ios.scheme`
30
+
31
+ Enter the Xcode scheme that should be built for publish flows.
32
+
33
+ ## Expected format:
34
+
35
+ A non-empty scheme name such as `MyApp` or `MyAppRelease`.
36
+
37
+ ## Question: configuration
38
+
39
+ Maps to: `targets[].ios.configuration`
40
+
41
+ Enter the Xcode build configuration for the publish flow.
42
+
43
+ ## Expected format:
44
+
45
+ Usually `Release`. Press Enter to accept the default.
46
+
47
+ ## Question: archive_path
48
+
49
+ Maps to: `targets[].ios.archive_path`
50
+
51
+ Enter the repo-relative path where the Xcode archive should be written.
52
+
53
+ ## Expected format:
54
+
55
+ A non-empty path such as `build/ios/staging/MyApp.xcarchive`.
56
+
57
+ ## Question: export_path
58
+
59
+ Maps to: `targets[].ios.export_path`
60
+
61
+ Enter the repo-relative path where exported build artifacts should be written.
62
+
63
+ ## Expected format:
64
+
65
+ A non-empty path such as `build/ios/staging/export`.
66
+
67
+ ## Question: export_method
68
+
69
+ Maps to: `targets[].ios.export_method`
70
+
71
+ Choose the export method used for packaging the archive.
72
+
73
+ ## Expected format:
74
+
75
+ One of: `ad-hoc`, `app-store`.
76
+
77
+ ## Question: app_store_app_id
78
+
79
+ Maps to: `targets[].ios.app_store_app_id`
80
+
81
+ Enter the numeric App Store Connect app identifier for this target.
82
+
83
+ ## Expected format:
84
+
85
+ Digits only such as `1234567890`.
86
+
87
+ ## Question: project_or_workspace_path
88
+
89
+ Maps to: `targets[].ios.project_path` or `targets[].ios.workspace_path`
90
+
91
+ Enter the repo-relative Xcode project or workspace path used for builds.
92
+
93
+ ## Expected format:
94
+
95
+ A path ending in `.xcodeproj` or `.xcworkspace`.
96
+
97
+ ## Question: provider_short_name
98
+
99
+ Maps to: `targets[].ios.provider_short_name`
100
+
101
+ Optionally enter the App Store Connect provider short name used by some upload flows.
102
+ Leave blank if not needed.
103
+
104
+ ## Expected format:
105
+
106
+ Optional short string such as `exampleco`.
107
+
108
+ ## Question: api_key_id_env_var
109
+
110
+ Maps to: `targets[].secrets.app_store_connect_api_key_id`
111
+
112
+ Enter the environment-variable name that will supply the App Store Connect API key identifier.
113
+ See `skills/publish/assets/secrets-guide.md` before answering.
114
+
115
+ ## Expected format:
116
+
117
+ Uppercase environment-variable name such as `APP_STORE_CONNECT_API_KEY_ID`.
118
+
119
+ ## Question: issuer_id_env_var
120
+
121
+ Maps to: `targets[].secrets.app_store_connect_issuer_id`
122
+
123
+ Enter the environment-variable name that will supply the App Store Connect issuer identifier.
124
+
125
+ ## Expected format:
126
+
127
+ Uppercase environment-variable name such as `APP_STORE_CONNECT_ISSUER_ID`.
128
+
129
+ ## Question: private_key_path_env_var
130
+
131
+ Maps to: `targets[].secrets.app_store_connect_private_key_path`
132
+
133
+ Enter the environment-variable name that will supply the filesystem path to the App Store Connect private key.
134
+
135
+ ## Expected format:
136
+
137
+ Uppercase environment-variable name such as `APP_STORE_CONNECT_PRIVATE_KEY_PATH`.
138
+
139
+ ## Question: code_sign_identity_env_var
140
+
141
+ Maps to: `targets[].secrets.code_sign_identity`
142
+
143
+ Enter the environment-variable name that will supply the iOS code-sign identity.
144
+
145
+ ## Expected format:
146
+
147
+ Uppercase environment-variable name such as `CODE_SIGN_IDENTITY`.
148
+
149
+ ## Question: provisioning_profile_uuid_env_var
150
+
151
+ Maps to: `targets[].secrets.provisioning_profile_uuid`
152
+
153
+ Enter the environment-variable name that will supply the provisioning profile UUID reference.
154
+
155
+ ## Expected format:
156
+
157
+ Uppercase environment-variable name such as `PROVISIONING_PROFILE_UUID`.
@@ -0,0 +1,240 @@
1
+ # npm-ci setup wizard
2
+
3
+ Use this template to collect the values required for an `npm-ci` publish target.
4
+ Each section maps directly to a field in `publish.json`. Unlike the `npm` target
5
+ type, `npm-ci` publishes via GitHub Actions OIDC (Trusted Publishers) — no
6
+ `NPM_TOKEN` is stored anywhere. All authorisation is handled through the
7
+ npmjs.com Trusted Publisher link between the package and the GitHub repository.
8
+
9
+ Before running the prompts, load the project's `package.json` (if present) so
10
+ `name` can be offered as the default for `package_name`. If `publish.json`
11
+ already contains a target whose `type` is `npm-ci`, ask the user whether to
12
+ **overwrite** the existing target or **update** individual fields — do not
13
+ silently replace it.
14
+
15
+ After collecting answers, write the target block to `publish.json` (create the
16
+ file from the base scaffold if it does not exist). No instructions file is
17
+ generated for this target type — there is no secret to configure. See the
18
+ "Post-collection actions" section at the bottom for the full write sequence.
19
+
20
+ ## Prerequisites
21
+
22
+ Before running this wizard, confirm that all of the following are in place:
23
+
24
+ - **`gh` CLI installed and authenticated**: run `gh auth status` to verify.
25
+ If not authenticated, run `gh auth login` first.
26
+ - **GitHub Actions enabled** on the target repository. Actions must be enabled
27
+ under the repository's Settings → Actions → General page.
28
+ - **The package must already exist on npmjs.com**, or be publishable under
29
+ your npm account. A brand-new package name is created on the first successful
30
+ publish if your account has permission to publish under that name or scope.
31
+
32
+ ## One-time npmjs.com Trusted Publisher setup
33
+
34
+ Complete these steps manually in a browser **before** running `/publish deploy`
35
+ against this target for the first time. The adapter cannot establish this link
36
+ automatically — it is a one-time browser-based setup on the npmjs.com website.
37
+
38
+ 1. Sign in to https://www.npmjs.com with the account that owns (or is a
39
+ maintainer of) the package.
40
+ 2. Navigate to your package page. If the package does not exist yet, create it
41
+ first (publish a placeholder version locally before configuring Trusted
42
+ Publishers, or ensure your account has permission to publish under the
43
+ chosen name or scope on first push).
44
+ 3. Go to **Settings** → **Publishing** → **Trusted Publishers**.
45
+ 4. Click **Add publisher**.
46
+ 5. Select **GitHub Actions** as the publisher type.
47
+ 6. Enter the following values:
48
+ - **Owner/repository**: your GitHub `owner/repo`
49
+ (e.g. `acme-org/my-package`)
50
+ - **Workflow file path**: the path to the workflow file that will publish
51
+ (e.g. `.github/workflows/npm-publish.yml`)
52
+ 7. Click **Save**.
53
+
54
+ **Important trade-off**: once Trusted Publishers is configured on a package,
55
+ npmjs.com will **only** accept publishes originating from the linked workflow.
56
+ Local `npm publish` commands authenticated with an `NPM_TOKEN` will be rejected
57
+ for that package. If you need to publish locally in an emergency, you must
58
+ remove or disable the Trusted Publisher link on npmjs.com before using a token.
59
+ Plan accordingly before enabling this feature on a production package.
60
+
61
+ ## Question: package_name
62
+
63
+ Maps to: `targets[].npm.package_name`
64
+
65
+ Enter the npm package name as it should appear in the registry.
66
+ If a `package.json` exists at the project root, offer its `name` field as the
67
+ default. Supports scoped names such as `@scope/name`.
68
+
69
+ ## Expected format:
70
+
71
+ Lowercase, url-safe name matching `^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$`
72
+ (e.g. `jenga-agent`, `@my-org/utils`). Max 214 characters.
73
+
74
+ ## Question: access
75
+
76
+ Maps to: `targets[].npm.access`
77
+
78
+ Choose the registry access level for this package.
79
+ `public` publishes an openly-installable package. `restricted` publishes a
80
+ private package (requires a paid npm plan or a private registry such as
81
+ GitHub Packages).
82
+
83
+ ## Expected format:
84
+
85
+ One of: `public`, `restricted`. Press Enter to accept the default (`public`).
86
+
87
+ ## Question: dist_tag
88
+
89
+ Maps to: `targets[].npm.dist_tag`
90
+
91
+ Enter the npm dist-tag applied to this publish. `latest` is the default
92
+ install tag; use tags like `next` or `beta` for pre-releases so that
93
+ `npm install <pkg>` continues to resolve to the current stable version.
94
+
95
+ ## Expected format:
96
+
97
+ Lowercase tag matching `^[a-z0-9][a-z0-9._-]*$` (e.g. `latest`, `next`,
98
+ `beta`). Press Enter to accept the default (`latest`).
99
+
100
+ ## Question: registry
101
+
102
+ Maps to: `targets[].npm.registry`
103
+
104
+ Enter the registry URL to publish to.
105
+ For the public npm registry, accept the default. For GitHub Packages, use
106
+ `https://npm.pkg.github.com`. For a private/internal registry, use the URL
107
+ provided by your registry operator.
108
+
109
+ ## Expected format:
110
+
111
+ An absolute `https://` URL (e.g. `https://registry.npmjs.org`,
112
+ `https://npm.pkg.github.com`). Press Enter to accept the default
113
+ (`https://registry.npmjs.org`).
114
+
115
+ ## Question: github_repo
116
+
117
+ Maps to: `targets[].github_repo`
118
+
119
+ Enter the GitHub repository that will run the publish workflow. This value is
120
+ used by the adapter to generate and trigger the GitHub Actions workflow via
121
+ `gh workflow run`. It must match the repository where the Trusted Publisher
122
+ link was established on npmjs.com.
123
+
124
+ ## Expected format:
125
+
126
+ `owner/name` format matching `^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$`
127
+ (e.g. `acme-org/my-package`). This field is required — there is no default.
128
+
129
+ ## Question: workflow_path
130
+
131
+ Maps to: `targets[].workflow_path`
132
+
133
+ Enter the path to the GitHub Actions workflow file the adapter will generate
134
+ and trigger. This must match the workflow file path entered in the npmjs.com
135
+ Trusted Publisher configuration above. If the file already exists in the
136
+ repository, the adapter will overwrite it only if its content has changed.
137
+
138
+ ## Expected format:
139
+
140
+ A relative path starting with `.github/workflows/` and ending in `.yml` or
141
+ `.yaml` (e.g. `.github/workflows/npm-publish.yml`). Press Enter to accept the
142
+ default (`.github/workflows/npm-publish.yml`).
143
+
144
+ ## publish.json snippet
145
+
146
+ A complete, valid example target block for the `npm-ci` type. Note that there
147
+ is no `secrets` block — this adapter uses OIDC and requires no stored tokens:
148
+
149
+ ```json
150
+ {
151
+ "name": "npm-ci-my-package",
152
+ "type": "npm-ci",
153
+ "platform": "npm-registry",
154
+ "github_repo": "acme-org/my-package",
155
+ "workflow_path": ".github/workflows/npm-publish.yml",
156
+ "checks": {
157
+ "pre": ["lint", "type-check"],
158
+ "post": ["smoke-test"]
159
+ },
160
+ "npm": {
161
+ "package_name": "my-package",
162
+ "access": "public",
163
+ "registry": "https://registry.npmjs.org",
164
+ "dist_tag": "latest"
165
+ }
166
+ }
167
+ ```
168
+
169
+ ## Post-collection actions
170
+
171
+ Once all six answers have been collected, perform the following steps in order:
172
+
173
+ 1. **Load or scaffold `publish.json`.** If the file does not exist at the
174
+ project root, create it from the base scaffold with `version: 1`,
175
+ populated `defaults`, and an empty `targets` array. If it does exist,
176
+ parse and preserve every unrelated field.
177
+ 2. **Check for an existing `npm-ci` target.** Scan `targets[]` for any entry
178
+ with `"type": "npm-ci"`. If one exists, ask the user:
179
+ - **overwrite** — replace the entire target block with the wizard output
180
+ - **update** — merge the wizard answers into the existing target
181
+ field-by-field, keeping any user-added fields (e.g. custom `checks`
182
+ or `notes`) intact.
183
+ If none exists, append a new target block.
184
+ 3. **Write the target block.** Emit it in the exact shape shown in the
185
+ "publish.json snippet" section above — no `secrets` block:
186
+
187
+ ```json
188
+ {
189
+ "name": "npm-ci-<package-slug>",
190
+ "type": "npm-ci",
191
+ "platform": "npm-registry",
192
+ "github_repo": "<answer>",
193
+ "workflow_path": "<answer>",
194
+ "checks": {
195
+ "pre": ["lint", "type-check"],
196
+ "post": ["smoke-test"]
197
+ },
198
+ "npm": {
199
+ "package_name": "<answer>",
200
+ "access": "<answer>",
201
+ "registry": "<answer>",
202
+ "dist_tag": "<answer>"
203
+ }
204
+ }
205
+ ```
206
+
207
+ Notes on shape:
208
+ - `name` is derived from the package name (slugified, lowercased, prefixed
209
+ with `npm-ci-`). If a collision exists, suffix with `-2`, `-3`, etc.
210
+ - `platform` is `npm-registry` for `https://registry.npmjs.org`. If the
211
+ user supplied `https://npm.pkg.github.com`, set `platform` to
212
+ `github-packages` instead.
213
+ - Do not include a `secrets` block — this adapter uses OIDC and no token
214
+ is required.
215
+ 4. **Validate against the schema.** Run
216
+ `skills/publish/scripts/validate_config.sh` before saving. If validation
217
+ fails, report the error and abort — do not write a broken `publish.json`.
218
+ 5. **Report to the user.** Print a short summary confirming (a) the target
219
+ block written, (b) the `github_repo` value, and (c) the `workflow_path`
220
+ value. Remind the user to complete the one-time npmjs.com Trusted Publisher
221
+ setup (described above) before running `/publish deploy` for the first time.
222
+ 6. **No instructions file is needed.** Unlike the `npm` target type, `npm-ci`
223
+ has no secret to configure. The OIDC trust is established entirely through
224
+ the npmjs.com Trusted Publisher link and the GitHub Actions workflow — both
225
+ of which are documented in this wizard.
226
+
227
+ ## Post-setup verification
228
+
229
+ After completing the wizard and the one-time Trusted Publisher setup:
230
+
231
+ 1. Run `/publish deploy --target <name> --dry-run` to confirm the workflow YAML
232
+ is generated correctly. The adapter will print the rendered workflow YAML to
233
+ stdout without writing any file or triggering a run.
234
+ 2. Review the printed YAML to ensure it matches the expected `npm-publish.yml`
235
+ structure: verify that `permissions.id-token: write` is present and that the
236
+ publish step runs `npm publish --provenance`.
237
+ 3. Run `/publish deploy --target <name>` (without `--dry-run`) to trigger the
238
+ first CI publish. The adapter will commit the workflow file to the repository
239
+ and trigger a GitHub Actions run. Open the printed run URL to monitor the
240
+ job in GitHub Actions.