@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,223 @@
1
+ # `npm-ci` Adapter
2
+
3
+ The `npm-ci` adapter drives the `/publish deploy` flow for npm package targets.
4
+ It publishes to npmjs.com via **GitHub Actions OIDC Trusted Publishers** — no
5
+ `NPM_TOKEN` is stored anywhere. The adapter generates a GitHub Actions workflow
6
+ that runs `npm publish --provenance`, commits it to the repository, and triggers
7
+ it via `gh workflow run`. The local machine never publishes directly to npm.
8
+
9
+ ## Purpose
10
+
11
+ Publish an npm package from a GitHub repository to npmjs.com by:
12
+
13
+ 1. Generating a GitHub Actions workflow that authenticates to npm using a
14
+ short-lived OIDC token issued by GitHub's token service.
15
+ 2. Committing the workflow file to `<workflow_path>` (default:
16
+ `.github/workflows/npm-publish.yml`) in the repository.
17
+ 3. Triggering the workflow via `gh workflow run`.
18
+
19
+ No `NPM_TOKEN` is created, stored, or referenced. All authorisation is handled
20
+ through the npmjs.com Trusted Publisher link established between the package and
21
+ the repository.
22
+
23
+ ## Trust Boundary
24
+
25
+ `publish.json` holds **only** configuration values — no secrets of any kind.
26
+ The trust chain is OIDC-based:
27
+
28
+ ```
29
+ publish.json GitHub Actions npmjs.com
30
+ ────────────── ────────────────────────── ─────────────────────────────
31
+ github_repo: "owner/name" ← OIDC token issued per run ← Trusted Publisher link
32
+ npm.package_name: "pkg" scoped to this package (package ↔ repo + workflow)
33
+ npm.access: "public"
34
+ ```
35
+
36
+ GitHub's token service issues a short-lived OIDC token for each workflow run.
37
+ The npmjs.com Trusted Publisher configuration — a one-time link between the
38
+ package name and the repository + workflow file path — is the sole source of
39
+ authorisation. Once that link is in place, any workflow run originating from
40
+ the linked repository and workflow path may publish the package without a stored
41
+ token.
42
+
43
+ No secret values are committed to `publish.json` or the repository. Any
44
+ `secrets` block present in the target config is ignored by this adapter.
45
+
46
+ ## Invocation Contract
47
+
48
+ ### Inputs from `publish.json`
49
+
50
+ An `npm-ci` target must define:
51
+
52
+ - `name`
53
+ - `type: npm-ci`
54
+ - `npm.package_name` — name of the npm package to publish
55
+ - `npm.access` — `"public"` or `"restricted"`
56
+ - `npm.registry` — registry URL (default: `https://registry.npmjs.org`)
57
+ - `npm.dist_tag` — npm dist-tag (e.g. `latest`, `beta`)
58
+ - `github_repo` — **required**; `owner/name` identifying the GitHub repository
59
+ - `workflow_path` — **optional**; path to the workflow file to generate and
60
+ trigger; defaults to `.github/workflows/npm-publish.yml`
61
+ - `secrets` — **not required**; any `secrets` block present is ignored by this
62
+ adapter
63
+
64
+ The `npm.*` fields are read through the shared `npmSettings` schema, reused
65
+ across all npm-targeting adapters.
66
+
67
+ ### Required environment and tools
68
+
69
+ The adapter requires the following tools at invocation time:
70
+
71
+ - `jq` — to read `publish.json` target config
72
+ - `git` — to commit the generated workflow file
73
+ - `gh` — GitHub CLI, authenticated via `gh auth login`, to trigger the workflow
74
+ via `gh workflow run`
75
+
76
+ The `gh` CLI must be authenticated before running `/publish deploy` against an
77
+ `npm-ci` target.
78
+
79
+ ### Pipeline entrypoint
80
+
81
+ ```bash
82
+ bash skills/publish/scripts/npm_ci_pipeline.sh \
83
+ --target <name> \
84
+ --config <path-to-publish.json> \
85
+ [--dry-run]
86
+ ```
87
+
88
+ ## Execution Phases
89
+
90
+ Run the adapter phases in this exact order:
91
+
92
+ 1. **`validate`** — verify that `gh` CLI is authenticated (`gh auth status`),
93
+ that `github_repo` resolves to an accessible repository, and that all
94
+ required `npm.*` fields (`package_name`, `access`, `registry`, `dist_tag`)
95
+ are present and non-empty. Abort with exit 4 on any failure.
96
+
97
+ 2. **`generate-workflow`** — render the GitHub Actions workflow YAML in memory.
98
+ The generated workflow sets:
99
+ ```yaml
100
+ permissions:
101
+ id-token: write
102
+ contents: read
103
+ ```
104
+ and runs `npm publish --provenance` to attach a build provenance attestation
105
+ to the published package. In `--dry-run` mode, print the rendered YAML to
106
+ stdout and exit 0 without writing any file.
107
+
108
+ 3. **`commit-workflow`** — write the generated YAML to `<workflow_path>`
109
+ (creating the `.github/workflows/` directory if needed) and commit it with:
110
+ ```
111
+ git add <workflow_path>
112
+ git commit -m "chore(publish): update npm CI workflow for target <name>"
113
+ ```
114
+ If the file already exists and the content is unchanged (`git diff --quiet`),
115
+ skip the commit — the operation is idempotent.
116
+
117
+ 4. **`trigger`** — invoke:
118
+ ```bash
119
+ gh workflow run <workflow_filename> --ref <branch>
120
+ ```
121
+ where `<workflow_filename>` is the basename of `<workflow_path>`. After
122
+ dispatching, retrieve the run URL via
123
+ `gh run list --workflow <workflow_filename> --limit 1 --json url`.
124
+
125
+ 5. **`triggered`** — print the workflow run URL to stdout. The caller
126
+ (`publish_deploy.sh`) writes the ledger entry with
127
+ `platform_state: "triggered"`.
128
+
129
+ ## State Machine
130
+
131
+ ```
132
+ start
133
+ │
134
+ ▼
135
+ validate ──── exit 4 (config/env invalid)
136
+ │
137
+ ▼
138
+ generate-workflow ──── [--dry-run] → print YAML → exit 0
139
+ │
140
+ ▼
141
+ commit-workflow
142
+ │
143
+ ▼
144
+ trigger ──── exit 3 (gh workflow run failed)
145
+ │
146
+ ▼
147
+ triggered → exit 0 (success)
148
+ ```
149
+
150
+ Terminal states:
151
+
152
+ - **success** — all five phases complete; workflow run URL printed; exit 0.
153
+ - **dry-run exit** — adapter exits after `generate-workflow` without writing,
154
+ committing, or triggering; exit 0.
155
+ - **failure** — adapter exits with a non-zero code at the failing phase (see
156
+ Exit Codes).
157
+
158
+ ## Dry-Run Behaviour
159
+
160
+ When `--dry-run` is passed:
161
+
162
+ - The `validate` phase runs normally; config and environment errors still
163
+ surface.
164
+ - The `generate-workflow` phase runs normally; the rendered workflow YAML is
165
+ printed to stdout.
166
+ - The `commit-workflow` phase is **skipped** — no file is written, no git
167
+ commit is made.
168
+ - The `trigger` phase is **skipped** — `gh workflow run` is not called.
169
+ - The adapter exits 0 after printing the YAML.
170
+ - The ledger entry written by `publish_deploy.sh` will have
171
+ `platform_state: "dry-run"`.
172
+
173
+ ## Exit Codes
174
+
175
+ | Code | Meaning |
176
+ |------|-----------------------------------------------------------------------------|
177
+ | `0` | Pipeline completed successfully, or `--dry-run` finished cleanly |
178
+ | `3` | Workflow trigger failure (`gh workflow run` exited non-zero) |
179
+ | `4` | Config or environment invalid (missing required field, `gh` not authed, |
180
+ | | `github_repo` not found, or required `npm.*` field absent) |
181
+
182
+ ## Output Artefacts
183
+
184
+ A successful non-dry-run produces:
185
+
186
+ - The workflow file written to `<workflow_path>` in the working tree (default:
187
+ `.github/workflows/npm-publish.yml`) and committed to the repository
188
+ - A git commit: `chore(publish): update npm CI workflow for target <name>`
189
+ - A workflow run URL printed to stdout
190
+ - A history entry in `project/logs/publish-history.json` written by
191
+ `publish_deploy.sh` with `platform_state: "triggered"`
192
+
193
+ ## Post-Deploy Manual Steps
194
+
195
+ After a successful deploy trigger, the adapter prints the workflow run URL.
196
+ The operator should:
197
+
198
+ 1. Open the printed run URL to monitor the publish job in GitHub Actions.
199
+ 2. Verify the package appears on npmjs.com with the expected version and
200
+ provenance badge (the shield icon confirming `npm publish --provenance`).
201
+ 3. Confirm the dist-tag (`latest`, `beta`, or other) is correctly applied on
202
+ the npmjs.com package page.
203
+
204
+ The adapter does not wait for the CI run to complete — monitoring is the
205
+ operator's responsibility.
206
+
207
+ ## First-run prerequisite
208
+
209
+ The npmjs.com Trusted Publisher link between the package and the repository must
210
+ be established **before** the first `/publish deploy` invocation against an
211
+ `npm-ci` target. This one-time setup step is out of scope for the adapter itself
212
+ and is covered by the setup wizard (see S03).
213
+
214
+ Minimum pre-requisites:
215
+
216
+ - The package must already exist on npmjs.com (or be publishable under your
217
+ npm account).
218
+ - A Trusted Publisher must be configured on npmjs.com linking the package to
219
+ `github_repo` + `workflow_path`.
220
+ - The GitHub repository must have Actions enabled.
221
+
222
+ Once the Trusted Publisher link is in place, the adapter can publish on every
223
+ invocation without any stored token.
@@ -0,0 +1,121 @@
1
+ # `npm` Adapter
2
+
3
+ The `npm` adapter drives the `/publish deploy` flow for npm registry targets.
4
+ It is a prompt/template contract for the agent layer and delegates concrete execution to
5
+ `skills/publish/scripts/npm_pipeline.sh`.
6
+
7
+ ## Invocation Contract
8
+
9
+ ### Inputs from `publish.json`
10
+
11
+ An `npm` target must define:
12
+
13
+ - `name`
14
+ - `type: npm`
15
+ - `platform: npm-registry`
16
+ - `checks.pre[]` / `checks.post[]`
17
+ - `secrets.NPM_TOKEN` (env-var reference; `NODE_AUTH_TOKEN` is also accepted)
18
+ - `npm.package_name`
19
+ - `npm.access` (`public` or `restricted`)
20
+ - `npm.registry` (optional; defaults to `https://registry.npmjs.org`)
21
+ - `npm.dist_tag` (optional; defaults to `latest`)
22
+
23
+ ### Required environment variables
24
+
25
+ The adapter uses env-var references only and never stores secret values in repo files.
26
+ The required env vars are:
27
+
28
+ - `NPM_TOKEN` (or `NODE_AUTH_TOKEN` — either satisfies the auth requirement)
29
+
30
+ Validate them before execution with:
31
+
32
+ ```bash
33
+ bash skills/publish/scripts/validate_npm_env.sh <path-to-publish.json>
34
+ ```
35
+
36
+ ### Pipeline entrypoint
37
+
38
+ ```bash
39
+ bash skills/publish/scripts/npm_pipeline.sh <target> <path-to-publish.json> [--dry-run] [--non-interactive]
40
+ ```
41
+
42
+ ## Execution Phases
43
+
44
+ Run the adapter phases in this exact order:
45
+
46
+ 1. `validate`
47
+ 2. `gates`
48
+ 3. `pack`
49
+ 4. `publish`
50
+ 5. `tag`
51
+
52
+ Quality gates run inside the `gates` phase and must include `npm test`. If the consumer `package.json` declares a `build` script, `npm run build` also runs as a gate. Once control enters the adapter, external publish-side commands are restricted to direct `npm` and `git` invocations.
53
+
54
+ ## State Machine
55
+
56
+ The adapter records these transitions in `project/logs/publish-history.json`:
57
+
58
+ ```text
59
+ idle → validating → gating → packing → publishing → tagging → published
60
+ └───────────────→ failed
61
+ ```
62
+
63
+ ### State meanings
64
+
65
+ - `idle` — conceptual pre-start state before a history row is appended
66
+ - `validating` — token presence and `publish.json` npm block are being verified
67
+ - `gating` — `npm test` (and `npm run build` when present) are running
68
+ - `packing` — `npm pack` is generating the tarball for inspection
69
+ - `publishing` — `npm publish` is running against the configured `registry` with the resolved `access` and `dist_tag`
70
+ - `tagging` — `git tag v<version>` is being created and (optionally) pushed
71
+ - `published` — publish and tag both succeeded; package is visible on the registry
72
+ - `failed` — any validation/gate/publish/tag failure; `completed_at` must be set
73
+
74
+ ## Dry-run Mode
75
+
76
+ `--dry-run` is mandatory for safe CI validation without live npm credentials.
77
+
78
+ Behavior:
79
+
80
+ - The `publish` phase runs `npm publish --dry-run` instead of a live publish. No package is written to the registry; npm prints the tarball contents and would-be metadata.
81
+ - All `git tag` / `git push` commands are printed with a `[DRY RUN]` prefix and are **not** executed.
82
+ - State-machine writes still happen so reviewers can inspect the planned flow.
83
+ - Token presence is still validated so dry-runs surface auth misconfiguration early.
84
+ - The adapter exits `0` after simulating a successful publish.
85
+
86
+ ## Exit Codes
87
+
88
+ | Code | Meaning |
89
+ |---|---|
90
+ | `0` | Pipeline completed successfully or dry-run finished successfully |
91
+ | `2` | Missing `NPM_TOKEN` / `NODE_AUTH_TOKEN`, config validation failure, or quality-gate failure (`npm test` / `npm run build`) |
92
+ | `3` | `npm publish` failure, `git tag` failure, or history-update failure |
93
+
94
+ ### Success condition
95
+
96
+ `npm publish` exits `0` and the package is retrievable from the configured registry at the newly-published `version` and `dist_tag`.
97
+
98
+ ### Failure conditions
99
+
100
+ - **Missing token** — `NPM_TOKEN` (and `NODE_AUTH_TOKEN`) unset → exit `2`
101
+ - **Gate failure** — `npm test` or `npm run build` non-zero → exit `2`
102
+ - **Publish error** — `npm publish` non-zero (network, 403, version conflict, etc.) → exit `3`
103
+
104
+ ## Output Artefacts
105
+
106
+ A successful run produces:
107
+
108
+ - A published package on the configured npm registry (npmjs.com by default), reachable at `https://www.npmjs.com/package/<package_name>/v/<version>`
109
+ - A local (and optionally pushed) git tag `v<version>` matching the published `version`
110
+ - A history row appended to `project/logs/publish-history.json`
111
+
112
+ ## Post-deploy manual steps
113
+
114
+ After a successful publish, the deploy flow must print:
115
+
116
+ ✅ Publish complete. Next manual steps:
117
+ 1. Verify the package on the registry: https://www.npmjs.com/package/<package_name>/v/<version>
118
+ 2. Push the git tag if not already pushed: `git push origin v<version>`
119
+ 3. Draft release notes (GitHub Releases or your changelog of choice)
120
+
121
+ Print the same block in `--non-interactive` mode so CI logs capture it.
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>method</key>
6
+ <string>{{EXPORT_METHOD}}</string>
7
+ <key>teamID</key>
8
+ <string>{{TEAM_ID}}</string>
9
+ <key>signingStyle</key>
10
+ <string>manual</string>
11
+ <key>signingCertificate</key>
12
+ <string>{{SIGNING_IDENTITY}}</string>
13
+ <key>provisioningProfiles</key>
14
+ <dict>
15
+ <key>{{BUNDLE_ID}}</key>
16
+ <string>{{PROVISIONING_PROFILE_UUID}}</string>
17
+ </dict>
18
+ </dict>
19
+ </plist>
@@ -0,0 +1,111 @@
1
+ # `/publish` deploy contract
2
+
3
+ This document defines the CI-safe execution contract for the scaffolded `/publish` workflow. Interactive flows added later must wrap this contract and must not weaken it.
4
+
5
+ ## Validation order
6
+
7
+ Every `/publish` invocation must perform these steps before command-specific work:
8
+
9
+ 1. Resolve config path (`--config <path>` or default `project/configs/publish.json`)
10
+ 2. Run `bash skills/publish/scripts/validate_config.sh <resolved-path>`
11
+ 3. Abort immediately with exit code `4` if the file is missing, invalid JSON, or fails validation
12
+ 4. For the iOS adapter, run `bash skills/publish/scripts/validate_ios_env.sh <resolved-path>` before build/upload work begins
13
+
14
+ ## Inputs
15
+
16
+ | Purpose | Flag | Environment Variable | Required in non-interactive mode? | Notes |
17
+ |---|---|---|---|---|
18
+ | Select deploy target | `--target <name>` | `PUBLISH_TARGET` | Yes | Flag takes precedence over env var |
19
+ | Skip confirmation prompts | `--yes` | `PUBLISH_YES` | Yes | Env var truthy values: `1`, `true`, `yes`, `on` |
20
+ | Override config path | `--config <path>` | — | No | Defaults to `project/configs/publish.json` |
21
+ | Reuse prepared release notes | `--release-notes <path>` | — | No | Reserved for later release-note flow |
22
+ | Dry-run execution | `--dry-run` | `PUBLISH_DRY_RUN` | No | Prints allowlisted `xcodebuild` / `xcrun` commands without executing them |
23
+
24
+ ## Required contract
25
+
26
+ For a CI or agent-driven deploy, the caller must provide:
27
+
28
+ - a valid target via `--target` or `PUBLISH_TARGET`
29
+ - confirmation bypass via `--yes` or truthy `PUBLISH_YES`
30
+ - a valid config file at the provided path or the default path
31
+ - the required iOS credential environment variables when the `mobile-ios` adapter is used
32
+
33
+ If any of these are missing in a non-interactive execution context, the command must fail fast rather than prompting.
34
+
35
+ ## Mandatory global pre-deploy gates
36
+
37
+ `build` and `test` are mandatory global gates for `/publish deploy`.
38
+
39
+ - They run first on every `pre` gate pass.
40
+ - They cannot be disabled, removed, or overridden by target configuration.
41
+ - If `publish.json` also lists `build` or `test` under target-specific pre-gates, the runner ignores those duplicates and keeps the mandatory global versions.
42
+ - If either mandatory gate fails, the gate runner surfaces the full command output and exits with code `2` without continuing to later gates.
43
+
44
+ ## Configurable target gates
45
+
46
+ Per-target gates may add optional checks such as:
47
+
48
+ - `lint`
49
+ - `type-check`
50
+ - `custom-script`
51
+ - `smoke-test`
52
+ - `ping`
53
+
54
+ These run only after the mandatory global gates succeed.
55
+
56
+ ## Optional contract
57
+
58
+ These inputs remain optional in non-interactive mode:
59
+
60
+ - `--config <path>` when the default config exists
61
+ - `--release-notes <path>`
62
+ - `--from-tag` and `--to-ref` on `/publish release-notes`
63
+
64
+ ## Exit codes
65
+
66
+ | Code | Meaning | Current story coverage |
67
+ |---|---|---|
68
+ | `0` | Success | Config/env validation succeeds, dry-runs complete, and later deploy steps finish |
69
+ | `1` | User abort | Reserved for interactive confirmation flow |
70
+ | `2` | Quality gate failure | Implemented by the gate runner |
71
+ | `3` | Deploy failure | Used by the iOS adapter pipeline for build/export/upload failures |
72
+ | `4` | Config or environment invalid | Implemented by validation scripts |
73
+
74
+ ## Precedence rules
75
+
76
+ 1. Command-line flags win over environment variables.
77
+ 2. Environment variables are only fallbacks where explicitly supported.
78
+ 3. Missing/invalid config always stops execution before target resolution or deploy steps.
79
+ 4. Missing required iOS env vars stop execution before any `xcodebuild` or `xcrun` command runs.
80
+
81
+ ## Interactive vs non-interactive behavior
82
+
83
+ - Interactive mode offers: `[r] Retry after fixing / [a] Abort deploy`
84
+ - Retries are capped at 3 attempts per failed gate
85
+ - `--non-interactive` disables prompts and aborts immediately on any gate failure
86
+ - Every gate failure is appended to `project/logs/publish-history.json`
87
+ - `--dry-run` still records adapter state transitions so the planned pipeline can be reviewed safely
88
+
89
+ ## Example CI invocations
90
+
91
+ ### Flag-driven
92
+
93
+ ```bash
94
+ publish deploy --target staging-appstore --yes --dry-run
95
+ ```
96
+
97
+ ### Mixed flag + env var
98
+
99
+ ```bash
100
+ PUBLISH_YES=true publish deploy --target staging-appstore --dry-run
101
+ ```
102
+
103
+ ### Fully env-driven target selection
104
+
105
+ ```bash
106
+ PUBLISH_TARGET=staging-appstore PUBLISH_YES=1 publish deploy --dry-run
107
+ ```
108
+
109
+ ## Scope notes
110
+
111
+ This story set does not perform live Apple API calls during verification. The iOS adapter is structured around allowlisted `xcodebuild` and `xcrun` commands and relies on caller-provided credentials and a local Apple toolchain.
@@ -0,0 +1,17 @@
1
+ # Publish Agent Ownership Matrix
2
+
3
+ The `/publish` skill is initiated by the operator running the CLI, but each action has a defined workflow owner inside the multi-agent system.
4
+
5
+ | Action | Developer | Tester | Scrum Master |
6
+ |---|---|---|---|
7
+ | `/publish setup` | Initiates and owns | May run to configure test targets | Never |
8
+ | `/publish deploy --target staging` | Initiates | May run as part of test cycle | Never directly |
9
+ | `/publish deploy --target production` | Initiates with explicit confirmation | Reviews ledger entry post-deploy | Reviews `/status` only |
10
+ | `/publish history` | Reads for context | Reads for test baseline | Reads in `/status` review |
11
+ | `/publish release-notes` | Generates and reviews draft | May read draft for test context | Reviews content for sprint summary |
12
+ | Gate failure resolution | Owns rework | Validates rework | Escalates if blocked |
13
+ | Ledger entry disputes | Never modifies | Never modifies | Flags as rapport; human resolves |
14
+
15
+ ## Trust boundary
16
+
17
+ The `mobile-ios` adapter may only execute direct `xcodebuild` and `xcrun` commands. Arbitrary shell commands are not permitted inside the adapter pipeline.
@@ -0,0 +1,85 @@
1
+ {
2
+ "version": 1,
3
+ "defaults": {
4
+ "history_file": "project/logs/publish-history.json",
5
+ "mandatory_checks": [
6
+ "build",
7
+ "test"
8
+ ],
9
+ "optional_checks": [
10
+ "lint",
11
+ "type-check",
12
+ "custom-script",
13
+ "smoke-test",
14
+ "ping"
15
+ ]
16
+ },
17
+ "targets": [
18
+ {
19
+ "name": "staging-appstore",
20
+ "type": "mobile-ios",
21
+ "platform": "ios-app-store",
22
+ "checks": {
23
+ "pre": [
24
+ "lint",
25
+ "type-check"
26
+ ],
27
+ "post": [
28
+ "smoke-test"
29
+ ]
30
+ },
31
+ "secrets": {
32
+ "app_store_connect_api_key_id": "$APP_STORE_CONNECT_API_KEY_ID",
33
+ "app_store_connect_issuer_id": "$APP_STORE_CONNECT_ISSUER_ID",
34
+ "app_store_connect_private_key_path": "$APP_STORE_CONNECT_PRIVATE_KEY_PATH",
35
+ "code_sign_identity": "$CODE_SIGN_IDENTITY",
36
+ "provisioning_profile_uuid": "$PROVISIONING_PROFILE_UUID"
37
+ },
38
+ "ios": {
39
+ "project_path": "ios/ExampleApp.xcodeproj",
40
+ "scheme": "ExampleApp",
41
+ "configuration": "Release",
42
+ "archive_path": "build/ios/staging/ExampleApp.xcarchive",
43
+ "export_path": "build/ios/staging/export",
44
+ "export_method": "ad-hoc",
45
+ "bundle_id": "com.example.myapp.staging",
46
+ "team_id": "ABCDE12345",
47
+ "app_store_app_id": "1234567890",
48
+ "provider_short_name": "exampleco"
49
+ },
50
+ "notes": "Scaffold example only. Replace paths and identifiers with your real iOS project values."
51
+ },
52
+ {
53
+ "name": "production-appstore",
54
+ "type": "mobile-ios",
55
+ "platform": "ios-app-store",
56
+ "checks": {
57
+ "pre": [
58
+ "lint",
59
+ "type-check"
60
+ ],
61
+ "post": []
62
+ },
63
+ "secrets": {
64
+ "app_store_connect_api_key_id": "$APP_STORE_CONNECT_API_KEY_ID",
65
+ "app_store_connect_issuer_id": "$APP_STORE_CONNECT_ISSUER_ID",
66
+ "app_store_connect_private_key_path": "$APP_STORE_CONNECT_PRIVATE_KEY_PATH",
67
+ "code_sign_identity": "$CODE_SIGN_IDENTITY",
68
+ "provisioning_profile_uuid": "$PROVISIONING_PROFILE_UUID"
69
+ },
70
+ "ios": {
71
+ "workspace_path": "ios/ExampleApp.xcworkspace",
72
+ "scheme": "ExampleApp",
73
+ "configuration": "Release",
74
+ "archive_path": "build/ios/production/ExampleApp.xcarchive",
75
+ "export_path": "build/ios/production/export",
76
+ "export_method": "app-store",
77
+ "bundle_id": "com.example.myapp",
78
+ "team_id": "ABCDE12345",
79
+ "app_store_app_id": "1234567890",
80
+ "provider_short_name": "exampleco"
81
+ },
82
+ "notes": "Production upload example using App Store export mode."
83
+ }
84
+ ]
85
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "version": 1,
3
+ "defaults": {
4
+ "history_file": "project/logs/publish-history.json",
5
+ "mandatory_checks": [
6
+ "build",
7
+ "test"
8
+ ],
9
+ "optional_checks": [
10
+ "lint",
11
+ "type-check",
12
+ "smoke-test"
13
+ ]
14
+ },
15
+ "targets": [
16
+ {
17
+ "name": "npm-ci-jenga-agent",
18
+ "type": "npm-ci",
19
+ "platform": "npm-ci-oidc",
20
+ "github_repo": "samwelmunga/jenga-npm",
21
+ "workflow_path": ".github/workflows/npm-publish.yml",
22
+ "checks": {
23
+ "pre": [
24
+ "lint",
25
+ "type-check"
26
+ ],
27
+ "post": [
28
+ "smoke-test"
29
+ ]
30
+ },
31
+ "npm": {
32
+ "package_name": "jenga-agent",
33
+ "access": "public",
34
+ "registry": "https://registry.npmjs.org",
35
+ "dist_tag": "latest"
36
+ },
37
+ "notes": "Scaffold example for a CI-only npm publish via GitHub Actions OIDC (Trusted Publishers). No NPM_TOKEN is required — npmjs.com authenticates the publish using a short-lived OIDC token issued by GitHub's token service. The one-time setup step is: on npmjs.com, go to the package Settings → Publishing → Trusted Publishers → Add publisher → GitHub Actions → enter github_repo and workflow_path → Save. Once configured, only the linked workflow can publish this package — local npm publish with a token will be rejected."
38
+ }
39
+ ]
40
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "version": 1,
3
+ "defaults": {
4
+ "history_file": "project/logs/publish-history.json",
5
+ "mandatory_checks": [
6
+ "build",
7
+ "test"
8
+ ],
9
+ "optional_checks": [
10
+ "lint",
11
+ "type-check",
12
+ "smoke-test"
13
+ ]
14
+ },
15
+ "targets": [
16
+ {
17
+ "name": "npm-public",
18
+ "type": "npm",
19
+ "platform": "npm-registry",
20
+ "checks": {
21
+ "pre": [
22
+ "lint",
23
+ "type-check"
24
+ ],
25
+ "post": [
26
+ "smoke-test"
27
+ ]
28
+ },
29
+ "secrets": {
30
+ "NPM_TOKEN": "$NPM_TOKEN"
31
+ },
32
+ "npm": {
33
+ "package_name": "jenga-agent",
34
+ "access": "public",
35
+ "registry": "https://registry.npmjs.org",
36
+ "dist_tag": "latest"
37
+ },
38
+ "notes": "Scaffold example for a public npm registry publish. Field guide: `package_name` = the name that will appear in the registry (supports @scope/name); `access` = \"public\" for openly-installable packages or \"restricted\" for private packages; `registry` = target registry URL (default https://registry.npmjs.org, override for private registries or GitHub Packages); `dist_tag` = npm dist-tag applied to this publish (default \"latest\", use \"next\" or \"beta\" for pre-releases). The `secrets.NPM_TOKEN` entry maps to the `NPM_TOKEN` env var loaded at publish time — never hard-code the token value here."
39
+ }
40
+ ]
41
+ }