@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.
- package/LICENSE +201 -0
- package/README.md +340 -0
- package/agents/ai_engineer.md +113 -0
- package/agents/developer.md +236 -0
- package/agents/scrum-master.md +349 -0
- package/agents/scrutiny-agent.md +137 -0
- package/agents/solution-assessor.md +185 -0
- package/agents/tester.md +339 -0
- package/bin/jenga.js +70 -0
- package/hooks/copilot_session_end.sh +29 -0
- package/hooks/on_session_end.sh +238 -0
- package/hooks/prompt_router.sh +11 -0
- package/hooks/prompt_router_helper.js +52 -0
- package/hooks/session_end_helper.js +29 -0
- package/hooks/session_end_watcher.sh +24 -0
- package/lib/commands/attach.js +47 -0
- package/lib/commands/init.js +207 -0
- package/lib/commands/start.js +16 -0
- package/lib/commands/status.js +53 -0
- package/lib/config-schema.js +72 -0
- package/lib/inject-settings.js +61 -0
- package/lib/mirror.js +244 -0
- package/lib/resolve-project-dir.sh +47 -0
- package/mcp/execute-ticket/index.js +10 -0
- package/mcp/execute-ticket/package.json +5 -0
- package/mcp/help/index.js +79 -0
- package/mcp/help/package.json +14 -0
- package/mcp/router/README.md +19 -0
- package/mcp/router/embedder.js +23 -0
- package/mcp/router/index.js +204 -0
- package/mcp/router/matcher.js +87 -0
- package/mcp/router/package-lock.json +1048 -0
- package/mcp/router/package.json +11 -0
- package/mcp/router/skill-index.js +104 -0
- package/package.json +47 -0
- package/scripts/board_resolver.sh +46 -0
- package/scripts/e25_s01_extract_board_graph.py +292 -0
- package/scripts/e25_s01_generate_synthetic_board.py +90 -0
- package/scripts/measurement-10x.json +50 -0
- package/scripts/measurement-10x.txt +4 -0
- package/scripts/measurement-real.json +50 -0
- package/scripts/measurement-real.txt +4 -0
- package/scripts/postinstall.js +165 -0
- package/scripts/todo_cleanup.sh +22 -0
- package/scripts/todo_manager.sh +86 -0
- package/scripts/validate-board.sh +190 -0
- package/scripts/validate-story-format.sh +53 -0
- package/skills/brainstorm/SKILL.md +47 -0
- package/skills/btw/SKILL.md +42 -0
- package/skills/commit/SKILL.md +29 -0
- package/skills/commit/assets/user_instructions_template.md +22 -0
- package/skills/continue/SKILL.md +29 -0
- package/skills/convert/SKILL.md +124 -0
- package/skills/convert/convert_cli.py +235 -0
- package/skills/convert/tests/sample.csv +4 -0
- package/skills/convert/tests/sample.json +5 -0
- package/skills/convert/tests/sample.jsonl +3 -0
- package/skills/convert/tests/sample.yaml +18 -0
- package/skills/convert/tests/sample_obj.csv +2 -0
- package/skills/convert/tests/sample_obj.json +9 -0
- package/skills/deep-dive/SKILL.md +167 -0
- package/skills/do/SKILL.md +88 -0
- package/skills/do/assets/sender_template.json +12 -0
- package/skills/doc/SKILL.md +314 -0
- package/skills/doc/assets/path-objectives.yaml +38 -0
- package/skills/doc-sync/SKILL.md +167 -0
- package/skills/doc-sync/assets/default_excludes.txt +21 -0
- package/skills/doc-sync/assets/doc_targets.md +14 -0
- package/skills/dooo/SKILL.md +60 -0
- package/skills/error/SKILL.md +29 -0
- package/skills/evaluate/SKILL.md +45 -0
- package/skills/evaluate/assets/evaluation_invokation_template.yml +3 -0
- package/skills/evaluate/assets/evaluation_rapport_template.md +24 -0
- package/skills/examplify/SKILL.md +42 -0
- package/skills/help/SKILL.md +36 -0
- package/skills/improve/SKILL.md +55 -0
- package/skills/index/scripts/board-index +4 -0
- package/skills/index/scripts/board_index.py +615 -0
- package/skills/index/scripts/smoke_test.sh +86 -0
- package/skills/init/SKILL.md +44 -0
- package/skills/init/assets/.gitignore_template +15 -0
- package/skills/init/assets/PROJECT_SUMMARY_template.md +13 -0
- package/skills/init/assets/directory_structure.txt +13 -0
- package/skills/init/assets/test-config_template.json +4 -0
- package/skills/init/assets/workflow_template.json +30 -0
- package/skills/init/scripts/init.sh +48 -0
- package/skills/jbp/SKILL.md +25 -0
- package/skills/jenga/SKILL.md +68 -0
- package/skills/lgtm/SKILL.md +21 -0
- package/skills/mirror-public/SKILL.md +237 -0
- package/skills/mirror-public/assets/config.json +5 -0
- package/skills/mirror-public/scripts/mirror.sh +374 -0
- package/skills/pi-plan/SKILL.md +62 -0
- package/skills/pi-plan/assets/epic.json +7 -0
- package/skills/pi-plan/assets/story_template.md +18 -0
- package/skills/proceed/SKILL.md +29 -0
- package/skills/publish/SKILL.md +351 -0
- package/skills/publish/adapters/droplet.md +200 -0
- package/skills/publish/adapters/mobile-ios.md +114 -0
- package/skills/publish/adapters/npm-ci.md +223 -0
- package/skills/publish/adapters/npm.md +121 -0
- package/skills/publish/assets/ExportOptions.plist.template +19 -0
- package/skills/publish/assets/ci-contract.md +111 -0
- package/skills/publish/assets/ownership-matrix.md +17 -0
- package/skills/publish/assets/publish.example.json +85 -0
- package/skills/publish/assets/publish.example.npm-ci.json +40 -0
- package/skills/publish/assets/publish.example.npm.json +41 -0
- package/skills/publish/assets/secrets-guide.md +104 -0
- package/skills/publish/schemas/fixtures/npm-ci-minimal.json +17 -0
- package/skills/publish/schemas/fixtures/npm-ci-with-empty-secrets.json +18 -0
- package/skills/publish/schemas/fixtures/npm-ci-with-workflow-path.json +18 -0
- package/skills/publish/schemas/publish.schema.json +428 -0
- package/skills/publish/scripts/check_target_config.sh +96 -0
- package/skills/publish/scripts/droplet_pipeline.sh +208 -0
- package/skills/publish/scripts/generate_release_notes.sh +200 -0
- package/skills/publish/scripts/ios_pipeline.sh +486 -0
- package/skills/publish/scripts/npm_ci_pipeline.sh +225 -0
- package/skills/publish/scripts/npm_pipeline.sh +249 -0
- package/skills/publish/scripts/publish_common.sh +253 -0
- package/skills/publish/scripts/publish_deploy.sh +538 -0
- package/skills/publish/scripts/reconcile_tags.sh +135 -0
- package/skills/publish/scripts/run_gates.sh +616 -0
- package/skills/publish/scripts/setup_wizard.sh +394 -0
- package/skills/publish/scripts/show_history.sh +95 -0
- package/skills/publish/scripts/suggest_semver_bump.sh +105 -0
- package/skills/publish/scripts/validate_config.sh +163 -0
- package/skills/publish/scripts/validate_droplet_env.sh +45 -0
- package/skills/publish/scripts/validate_ios_env.sh +68 -0
- package/skills/publish/scripts/validate_npm_ci_env.sh +71 -0
- package/skills/publish/scripts/validate_npm_env.sh +22 -0
- package/skills/publish/scripts/write_ledger_entry.sh +126 -0
- package/skills/publish/wizards/droplet.md +275 -0
- package/skills/publish/wizards/mobile-ios.md +157 -0
- package/skills/publish/wizards/npm-ci.md +240 -0
- package/skills/publish/wizards/npm.md +224 -0
- package/skills/reconcile/SKILL.md +93 -0
- package/skills/reconcile/assets/report_format.md +44 -0
- package/skills/reconcile-origin/SKILL.md +75 -0
- package/skills/reconcile-origin/scripts/reconcile-origin.sh +372 -0
- package/skills/redo/SKILL.md +70 -0
- package/skills/route/SKILL.md +180 -0
- package/skills/self-sync/SKILL.md +73 -0
- package/skills/self-sync/scripts/run.js +136 -0
- package/skills/skillify/SKILL.md +68 -0
- package/skills/skillify/assets/init-new/SKILL.md +35 -0
- package/skills/skillify/assets/init-new/assets/.gitignore_template +15 -0
- package/skills/skillify/assets/init-new/assets/PROJECT_SUMMARY_template.md +13 -0
- package/skills/skillify/assets/init-new/assets/directory_structure.txt +10 -0
- package/skills/skillify/assets/init-new/assets/test-config_template.json +4 -0
- package/skills/skillify/assets/init-new/assets/workflow_template.json +17 -0
- package/skills/skillify/assets/init-new/scripts/init.sh +48 -0
- package/skills/skillify/assets/init-old/SKILL.md +124 -0
- package/skills/spinoff/SKILL.md +48 -0
- package/skills/status/SKILL.md +33 -0
- package/skills/status/assets/output_format.md +41 -0
- package/skills/todo/SKILL.md +46 -0
- package/skills/todo/assets/todo_handoff_template.md +22 -0
- package/skills/todo/assets/todo_template.md +3 -0
- package/skills/train/SKILL.md +116 -0
- package/skills/train/assets/dashboard-templates/classifiers.html +106 -0
- package/skills/train/assets/dashboard-templates/nlp.html +102 -0
- package/skills/train/assets/dashboard-templates/transformers.html +98 -0
- package/skills/train/assets/results-parsers/__init__.py +9 -0
- package/skills/train/assets/results-parsers/classifiers.py +84 -0
- package/skills/train/assets/results-parsers/nlp.py +88 -0
- package/skills/train/assets/results-parsers/reporter.py +154 -0
- package/skills/train/assets/results-parsers/transformers.py +120 -0
- package/skills/train/train_cli.py +786 -0
- package/templates/EXECUTION_PLAN_TEMPLATE.md +43 -0
- package/templates/EXECUTION_SUMMARY_TEMPLATE.md +50 -0
- package/templates/JENGA_CONFIG_TEMPLATE.json +23 -0
- package/templates/PROBLEM_RAPPORT_TEMPLATE.md +88 -0
- package/templates/SCRUM_BOARD_SCHEMA.md +311 -0
- package/templates/SKILL.md +16 -0
- package/templates/SKILL_TEMPLATE.md +28 -0
- package/templates/USER_INSTRUCTIONS_TEMPLATE.md +22 -0
- 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.
|