@jenga-ai/agent 1.2.1 → 1.2.3

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # JengaAgent
1
+ # Jenga AI
2
2
 
3
3
  **A structured multi-agent development workflow that works with any AI agent or AI-native IDE.** Three specialised AI agents — Scrum Master, Developer, and Tester — collaborate through a shared scrum board, an event-driven trigger queue, and 28 slash-command skills to take a project from idea to verified, committed code — across as many sessions as it takes.
4
4
 
@@ -34,7 +34,7 @@ npm install @jenga-ai/agent
34
34
 
35
35
  ## The Problem It Solves
36
36
 
37
- Without a framework like JengaAgent, AI-assisted development has serious structural weaknesses:
37
+ Without a framework like Jenga AI, AI-assisted development has serious structural weaknesses:
38
38
 
39
39
  | Problem | Reality |
40
40
  |---|---|
@@ -45,7 +45,7 @@ Without a framework like JengaAgent, AI-assisted development has serious structu
45
45
  | **No audit trail** | You can't replay *why* something was built, by which agent, based on which task |
46
46
  | **Sessions just end** | Work-in-progress, unresolved problems, and incomplete stories silently vanish |
47
47
 
48
- JengaAgent solves each of these with structure: persistent board state, strict agent roles, typed inter-agent contracts, and session-end hooks that preserve context between sessions.
48
+ Jenga AI solves each of these with structure: persistent board state, strict agent roles, typed inter-agent contracts, and session-end hooks that preserve context between sessions.
49
49
 
50
50
  ---
51
51
 
@@ -53,7 +53,7 @@ JengaAgent solves each of these with structure: persistent board state, strict a
53
53
 
54
54
  ### Before / After
55
55
 
56
- **Without JengaAgent:**
56
+ **Without Jenga AI:**
57
57
  ```
58
58
  You: "Add user authentication"
59
59
  AI agent: [writes auth code, declares it works, session ends]
@@ -63,7 +63,7 @@ You: "What's the status of auth?"
63
63
  AI agent: "I don't have context from the previous session."
64
64
  ```
65
65
 
66
- **With JengaAgent:**
66
+ **With Jenga AI:**
67
67
  ```
68
68
  /todo → "Add user authentication" → linked to E01_S02
69
69
  /do → Developer creates worktree E01_S02_T01-auth
@@ -81,7 +81,7 @@ Next session:
81
81
 
82
82
  ### Real-World Scenario: Building a Feature Across Sessions
83
83
 
84
- Imagine you're building a REST API with auth, rate limiting, and an admin dashboard. Each is a separate Epic. Here's how JengaAgent handles that across multiple days:
84
+ Imagine you're building a REST API with auth, rate limiting, and an admin dashboard. Each is a separate Epic. Here's how Jenga AI handles that across multiple days:
85
85
 
86
86
  **Planning**
87
87
  ```
@@ -187,7 +187,7 @@ Run `/status` at any time to see where the project stands.
187
187
 
188
188
  ## Supported Platforms
189
189
 
190
- JengaAgent has been tested with:
190
+ Jenga AI has been tested with:
191
191
 
192
192
  | Platform | Type |
193
193
  |---|---|
@@ -261,7 +261,7 @@ Skills live in `.agents/skills/<name>/SKILL.md`. Invoke with `/<name>` in your A
261
261
 
262
262
  ## Distributing the Workflow
263
263
 
264
- JengaAgent can propagate its workflow files to other projects on your machine via `/distribute`.
264
+ Jenga AI can propagate its workflow files to other projects on your machine via `/distribute`.
265
265
 
266
266
  1. **Register consumer projects** — add each consuming project to `distribute.config.json` at the repo root (or pass a path directly: `/distribute /path/to/project`).
267
267
  2. **Run `/distribute`** — choose `major`, `minor`, `patch`, or `amend` release type; the skill handles versioning, dry-run preview, file copy, and a version bump commit.
@@ -375,7 +375,7 @@ All agents log every incoming sender object to `project/logs/events.json` as the
375
375
 
376
376
  ---
377
377
 
378
- ## When to Use JengaAgent
378
+ ## When to Use Jenga AI
379
379
 
380
380
  **Use it when:**
381
381
  - You're building a non-trivial project across multiple sessions
@@ -26,7 +26,7 @@
26
26
  * ESM, Node built-ins only — mirrors lib/mirror.js and lib/inject-settings.js.
27
27
  */
28
28
 
29
- import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "fs";
29
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, realpathSync } from "fs";
30
30
  import { join, dirname } from "path";
31
31
  import { fileURLToPath } from "url";
32
32
 
@@ -220,7 +220,16 @@ export function generateAgentContext(projectRoot = process.cwd(), packageRoot =
220
220
  // used by skills/init/scripts/init.sh (this repo's own board-scaffolding
221
221
  // flow, where node is guaranteed available). The published npm CLI path
222
222
  // (lib/commands/init.js) imports generateAgentContext() directly instead.
223
- if (process.argv[1] === fileURLToPath(import.meta.url)) {
223
+ //
224
+ // process.argv[1] is compared via realpath, not as a raw string: Node
225
+ // resolves import.meta.url through symlinks when loading an ES module, but
226
+ // leaves process.argv[1] exactly as the shell passed it. On macOS, TMPDIR
227
+ // and /tmp are themselves symlinks into /private, so any invocation from a
228
+ // path under either (a very ordinary occurrence — every consumer install
229
+ // under a symlinked, mapped, or `npm link`-ed directory hits this) made the
230
+ // two sides disagree and silently skipped generation with no error.
231
+ const invokedPath = process.argv[1] ? realpathSync(process.argv[1]) : null;
232
+ if (invokedPath === fileURLToPath(import.meta.url)) {
224
233
  const projectRoot = process.argv[2] || process.cwd();
225
234
  const result = generateAgentContext(projectRoot);
226
235
  if (result.skipped) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jenga-ai/agent",
3
- "version": "1.2.1",
4
- "description": "JengaAgent — agentic project management CLI",
3
+ "version": "1.2.3",
4
+ "description": "Structured multi-agent development workflow for AI coding agents — scrum board, role-bounded scrum master / developer / tester agents, and 30+ slash-command skills. Works with Claude Code, GitHub Copilot, and Codex.",
5
5
  "type": "module",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -9,8 +9,13 @@
9
9
  "bin": {
10
10
  "jenga": "./bin/jenga.js"
11
11
  },
12
+ "engines": {
13
+ "node": ">=14.13.1"
14
+ },
12
15
  "scripts": {
13
16
  "postinstall": "node scripts/postinstall.js",
17
+ "test": "bats tests/*.bats",
18
+ "validate:npm-metadata": "bash scripts/validate_npm_metadata.sh",
14
19
  "ui:dev": "npm run ui:dev --prefix project/app",
15
20
  "ui:build": "npm run ui:build --prefix project/app",
16
21
  "api:start": "npm run api:start --prefix project/app",
@@ -32,10 +37,35 @@
32
37
  ],
33
38
  "repository": {
34
39
  "type": "git",
35
- "url": "https://github.com/samwelmunga/jenga-npm"
40
+ "url": "git+https://github.com/samwelmunga/jenga-npm.git"
41
+ },
42
+ "homepage": "https://github.com/samwelmunga/jenga-npm#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/samwelmunga/jenga-npm/issues"
45
+ },
46
+ "keywords": [
47
+ "ai-agents",
48
+ "agentic",
49
+ "agentic-workflow",
50
+ "multi-agent",
51
+ "agent-framework",
52
+ "ai-development",
53
+ "claude",
54
+ "claude-code",
55
+ "agents-md",
56
+ "copilot",
57
+ "github-copilot",
58
+ "codex",
59
+ "skills",
60
+ "project-management",
61
+ "developer-tools",
62
+ "cli"
63
+ ],
64
+ "author": {
65
+ "name": "Samwel Munga",
66
+ "email": "samwelmunga88@hotmail.se",
67
+ "url": "https://knappkod.se/jenga-ai"
36
68
  },
37
- "keywords": [],
38
- "author": "",
39
69
  "license": "MIT",
40
70
  "dependencies": {
41
71
  "@huggingface/transformers": "^4.2.0"
@@ -45,5 +75,8 @@
45
75
  },
46
76
  "comments": {
47
77
  "audit": "sharp <0.35.0 and adm-zip <0.6.0 are transitive deps of @huggingface/transformers with no upstream fix available. Not exploitable in this context: only text feature-extraction pipeline is used — no image processing or ZIP handling at application boundary. Review when @huggingface/transformers ships a patched release."
78
+ },
79
+ "devDependencies": {
80
+ "bats": "^1.13.0"
48
81
  }
49
82
  }
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * postinstall.js — JengaAgent consumer installation hook
3
+ * postinstall.js — Jenga AI consumer installation hook
4
4
  *
5
5
  * Runs automatically when a consumer project installs jenga-agent via npm.
6
6
  * Copies the discovery-bound dirs — `skills/` and `agents/` — into BOTH
@@ -65,7 +65,7 @@ function main() {
65
65
 
66
66
  // Avoid running during development (when INIT_CWD === packageRoot itself)
67
67
  if (path.resolve(consumerRoot) === path.resolve(packageRoot)) {
68
- console.log('\n ℹ JengaAgent postinstall: running inside the package itself — skipping copy.\n');
68
+ console.log('\n ℹ Jenga AI postinstall: running inside the package itself — skipping copy.\n');
69
69
  return;
70
70
  }
71
71
 
@@ -93,7 +93,7 @@ function main() {
93
93
  const shouldCopy = isFirstInstall || isUpgrade;
94
94
 
95
95
  console.log('\n╔══════════════════════════════════════════════════════╗');
96
- console.log('║ JengaAgent — postinstall hook ║');
96
+ console.log('║ Jenga AI — postinstall hook ║');
97
97
  console.log('╚══════════════════════════════════════════════════════╝\n');
98
98
  console.log(` Package version : ${packageVersion}`);
99
99
  console.log(` Installed version: ${installedVersion ?? '(none — first install)'}`);
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # validate_npm_metadata.sh — deterministic check that package.json carries
4
+ # the metadata npm/GitHub discovery depends on (E41_S01_T02).
5
+ #
6
+ # Rationale: per the repo's "Scripts Over Inline Logic" principle
7
+ # (CLAUDE.md), this is a script rather than an agent instruction so that
8
+ # future drift in package.json's publish-facing fields (e.g. keywords
9
+ # accidentally cleared, or repository.url silently re-pointed at the
10
+ # private samwelmunga/Jenga AI repo instead of the public jenga-npm
11
+ # mirror) is caught deterministically instead of relying on an agent
12
+ # noticing during review.
13
+ #
14
+ # IMPORTANT — no pinned version check:
15
+ # This script intentionally does NOT compare package.json's `version`
16
+ # field against any hardcoded literal. E41_S01_T01 established that the
17
+ # locally committed version and the version actually published to npm
18
+ # drift independently over time, so pinning a literal here would go
19
+ # stale on the very next release. If a version check is wanted at all,
20
+ # it is structural only (present + semver-shaped), never a pinned value.
21
+ #
22
+ # Usage:
23
+ # bash scripts/validate_npm_metadata.sh
24
+ # npm run validate:npm-metadata
25
+ #
26
+ # Exit codes:
27
+ # 0 All checks passed.
28
+ # 1 One or more checks failed (each failure is printed with a
29
+ # descriptive message; a summary count follows).
30
+ #
31
+ # Dependencies: node only (already a required runtime for this project —
32
+ # see package.json's "engines" field). No new dependency is introduced.
33
+
34
+ set -euo pipefail
35
+
36
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
37
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
38
+ PACKAGE_JSON="${1:-$REPO_ROOT/package.json}"
39
+
40
+ if [[ ! -f "$PACKAGE_JSON" ]]; then
41
+ echo "FAIL: package.json not found at $PACKAGE_JSON" >&2
42
+ exit 1
43
+ fi
44
+
45
+ # All validation logic lives in one embedded Node script to avoid the
46
+ # quoting/escaping pitfalls of parsing JSON arrays and nested objects from
47
+ # bash. Node prints one "PASS: ..." or "FAIL: ..." line per check to
48
+ # stdout, plus a final "SUMMARY: <n> failed" line. Bash only interprets
49
+ # the final summary line to decide the exit code and print the banner.
50
+ NODE_OUTPUT="$(node -e '
51
+ const fs = require("fs");
52
+
53
+ const pkgPath = process.argv[1];
54
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
55
+
56
+ const failures = [];
57
+ const pass = (msg) => console.log("PASS: " + msg);
58
+ const fail = (msg) => { failures.push(msg); console.log("FAIL: " + msg); };
59
+
60
+ // keywords: must exist, be a non-empty array
61
+ if (!Array.isArray(pkg.keywords) || pkg.keywords.length === 0) {
62
+ fail("keywords is empty or missing — package.json must declare a non-empty keywords array for npm/GitHub discoverability.");
63
+ } else {
64
+ pass("keywords is present with " + pkg.keywords.length + " entries.");
65
+ }
66
+
67
+ // author: must exist and be non-empty (string or object form)
68
+ const authorEmpty = (() => {
69
+ if (pkg.author == null) return true;
70
+ if (typeof pkg.author === "string") return pkg.author.trim().length === 0;
71
+ if (typeof pkg.author === "object") {
72
+ return !pkg.author.name || String(pkg.author.name).trim().length === 0;
73
+ }
74
+ return true;
75
+ })();
76
+ if (authorEmpty) {
77
+ fail("author is empty or missing — package.json must declare an author (string or {name, ...} object).");
78
+ } else {
79
+ pass("author is present.");
80
+ }
81
+
82
+ // repository / homepage / bugs: must all be present
83
+ if (pkg.repository == null || (typeof pkg.repository === "object" && Object.keys(pkg.repository).length === 0)) {
84
+ fail("repository is missing from package.json.");
85
+ } else {
86
+ pass("repository is present.");
87
+ }
88
+
89
+ if (!pkg.homepage || String(pkg.homepage).trim().length === 0) {
90
+ fail("homepage is missing from package.json.");
91
+ } else {
92
+ pass("homepage is present.");
93
+ }
94
+
95
+ if (pkg.bugs == null || (typeof pkg.bugs === "object" && Object.keys(pkg.bugs).length === 0)) {
96
+ fail("bugs is missing from package.json.");
97
+ } else {
98
+ pass("bugs is present.");
99
+ }
100
+
101
+ // repository.url (object form) or repository (string form) must point at
102
+ // the PUBLIC mirror (samwelmunga/jenga-npm), never the private repo.
103
+ const PUBLIC_REPO_MARKER = "samwelmunga/jenga-npm";
104
+ if (pkg.repository != null) {
105
+ const repoUrl = typeof pkg.repository === "string"
106
+ ? pkg.repository
107
+ : (pkg.repository.url || "");
108
+
109
+ if (!repoUrl || repoUrl.trim().length === 0) {
110
+ fail("repository is present but has no resolvable url.");
111
+ } else if (!repoUrl.includes(PUBLIC_REPO_MARKER)) {
112
+ fail("repository.url (\"" + repoUrl + "\") does not point at the public " + PUBLIC_REPO_MARKER + " repo — it must not reference a private repo (e.g. samwelmunga/Jenga AI) or any other location.");
113
+ } else {
114
+ pass("repository.url points at the public " + PUBLIC_REPO_MARKER + " repo.");
115
+ }
116
+ }
117
+
118
+ // version: structural semver check only — NEVER a pinned literal value.
119
+ // See header comment for why a pinned check would go stale immediately.
120
+ const SEMVER_RE = /^\d+\.\d+\.\d+/;
121
+ if (!pkg.version || !SEMVER_RE.test(String(pkg.version))) {
122
+ fail("version (\"" + pkg.version + "\") is missing or not a valid semver-shaped string.");
123
+ } else {
124
+ pass("version (\"" + pkg.version + "\") is a valid semver-shaped string (no pinned-value check performed, by design).");
125
+ }
126
+
127
+ console.log("SUMMARY: " + failures.length + " failed");
128
+ process.exit(failures.length > 0 ? 1 : 0);
129
+ ' "$PACKAGE_JSON")" && NODE_EXIT=0 || NODE_EXIT=$?
130
+
131
+ echo "$NODE_OUTPUT"
132
+ echo
133
+
134
+ FAILED_COUNT="$(echo "$NODE_OUTPUT" | grep -c '^FAIL:' || true)"
135
+
136
+ if [[ "$NODE_EXIT" -ne 0 || "$FAILED_COUNT" -gt 0 ]]; then
137
+ echo "npm publish metadata validation FAILED ($FAILED_COUNT check(s) failed). See FAIL lines above." >&2
138
+ exit 1
139
+ fi
140
+
141
+ echo "All npm publish metadata checks passed."
142
+ exit 0
@@ -6,7 +6,7 @@ This document is the canonical reference for the `jenga.config.json` file writte
6
6
 
7
7
  ## Purpose
8
8
 
9
- `jenga.config.json` lives at the root of a consuming project and tracks which version of the JengaAgent framework is currently installed there, where the framework files were placed, and when the last distribution occurred. It is read by the distribution script on subsequent runs to determine the target directory and detect whether an upgrade is needed.
9
+ `jenga.config.json` lives at the root of a consuming project and tracks which version of the Jenga AI framework is currently installed there, where the framework files were placed, and when the last distribution occurred. It is read by the distribution script on subsequent runs to determine the target directory and detect whether an upgrade is needed.
10
10
 
11
11
  ---
12
12
 
@@ -40,17 +40,17 @@ This document is the canonical reference for the `jenga.config.json` file writte
40
40
  |---|---|---|---|---|
41
41
  | `project_name` | string | yes | — | Human-readable identifier for the consuming project. Must match the `name` field of the corresponding entry in the monorepo's `distribute.config.json`. |
42
42
  | `target_dir` | string | yes | `.agents` | The directory under the project root where framework files are copied. `distribute-changes.sh` reads this field to resolve the destination path on every run. Change this only if the consuming project uses a non-standard layout. |
43
- | `version` | string | yes | — | The JengaAgent semantic version currently installed in this project (e.g. `"2.3.1"`). Compared against the `version` field in the monorepo's `package.json` to determine whether an upgrade is required. |
43
+ | `version` | string | yes | — | The Jenga AI semantic version currently installed in this project (e.g. `"2.3.1"`). Compared against the `version` field in the monorepo's `package.json` to determine whether an upgrade is required. |
44
44
  | `updated_at` | string (ISO 8601 date) | yes | — | Date of the last successful distribution, in `YYYY-MM-DD` format. Does **not** include a time component. |
45
45
  | `last_distributed` | string (ISO 8601 datetime) | yes | — | Full UTC timestamp of the last successful distribution, in `YYYY-MM-DDTHH:MM:SSZ` format. Provides more precision than `updated_at` and is useful for audit and ordering purposes. |
46
46
  | `source` | string | yes | `"private"` | Distribution channel. Always `"private"` for projects that receive updates via the filesystem distribution mechanism. Distinguishes these projects from any future npm-installed consumers. Do not change this value manually. |
47
- | `project_files_visibility` | string (enum) | no | `"visible"` | How JengaAgent's own working files appear in the consuming project. Exactly one of `visible` or `ignored` — no other value is accepted. Written by `/init`, not by distribution. See [Project files visibility](#project-files-visibility) below. |
47
+ | `project_files_visibility` | string (enum) | no | `"visible"` | How Jenga AI's own working files appear in the consuming project. Exactly one of `visible` or `ignored` — no other value is accepted. Written by `/init`, not by distribution. See [Project files visibility](#project-files-visibility) below. |
48
48
 
49
49
  ---
50
50
 
51
51
  ## Project files visibility
52
52
 
53
- `project_files_visibility` controls how JengaAgent's own working files — the `project/` tree containing the scrum board, `todo.md`, `queue/`, `rapports/`, and `logs/` — appear in a consuming project.
53
+ `project_files_visibility` controls how Jenga AI's own working files — the `project/` tree containing the scrum board, `todo.md`, `queue/`, `rapports/`, and `logs/` — appear in a consuming project.
54
54
 
55
55
  This is distinct from `target_dir`. `target_dir` governs where the **distributed framework files** (skill and agent definitions) land; `project_files_visibility` governs the **working tree** that accumulates as the framework is used.
56
56
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: distribute
3
- description: Distribute JengaAgent framework files from this private monorepo to one or more consuming projects via the local filesystem. Manages release type selection, version bumping, dry-run preview, per-target file copy, and a post-distribution git commit.
3
+ description: Distribute Jenga AI framework files from this private monorepo to one or more consuming projects via the local filesystem. Manages release type selection, version bumping, dry-run preview, per-target file copy, and a post-distribution git commit.
4
4
  keywords:
5
5
  - distribute
6
6
  - private distribution
@@ -16,7 +16,7 @@ examples:
16
16
 
17
17
  # Distribute
18
18
 
19
- Copies JengaAgent framework files from this monorepo to all active consuming projects registered in `distribute.config.json`. Manages the full version lifecycle: release type selection, `package.json` version bump, dry-run preview, per-target file copy, and a final git commit of the version bump.
19
+ Copies Jenga AI framework files from this monorepo to all active consuming projects registered in `distribute.config.json`. Manages the full version lifecycle: release type selection, `package.json` version bump, dry-run preview, per-target file copy, and a final git commit of the version bump.
20
20
 
21
21
  Distinct from `/self-sync` (which mirrors root → in-repo `.claude/.agents/`) and `/mirror-public` (which syncs to the public GitHub repo). Do not call either of those skills from within this flow.
22
22
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # distribute-changes.sh — Copy JengaAgent framework files into a consuming project
2
+ # distribute-changes.sh — Copy Jenga AI framework files into a consuming project
3
3
  #
4
4
  # Usage:
5
5
  # distribute-changes.sh <project_path> [--dry-run]
@@ -39,7 +39,7 @@ After target resolution, all generation must operate on a synthesis context obje
39
39
  ```yaml
40
40
  target_path: README.md
41
41
  objective: project overview
42
- project_name: JengaAgent
42
+ project_name: Jenga AI
43
43
  project_description: Structured multi-agent development workflow
44
44
  features: []
45
45
  getting_started: []
@@ -67,11 +67,11 @@ changes nothing on disk, so it is the only safe default.
67
67
  Never treat `existing-codebase` as if it were `empty`, and never skip straight to step 2
68
68
  on that verdict without the user (or the non-interactive default) choosing to.
69
69
 
70
- ### 2. Ask how JengaAgent's working files should appear
70
+ ### 2. Ask how Jenga AI's working files should appear
71
71
 
72
72
  Ask the user this question, verbatim, before running any script:
73
73
 
74
- How should JengaAgent's own working files (project/ — the scrum board, todo.md,
74
+ How should Jenga AI's own working files (project/ — the scrum board, todo.md,
75
75
  queue/, rapports/, and logs/) appear in this project?
76
76
  1. Visible — keep them at `project/`, tracked and visible in directory listings
77
77
  2. Ignored — keep them at `project/` but add them to `.gitignore` so they are never committed
@@ -96,10 +96,26 @@ of the mechanical work.
96
96
 
97
97
  ### 3. Run the scaffold script
98
98
 
99
- Execute the init script from the project root, passing the choice from step 2:
99
+ `init.sh` is not guaranteed to live at a single fixed path: in a project that
100
+ installed Jenga via npm, it was mirrored to `.claude/skills/init/scripts/`
101
+ (Claude Code) and `.agents/skills/init/scripts/` (Copilot/other agents) by
102
+ `postinstall.js`, and neither of those exists yet in this framework's own
103
+ source checkout, where it lives at the bare `skills/init/scripts/` path
104
+ instead. This step runs before `CLAUDE.md`/`AGENTS.md` exist, so it cannot
105
+ rely on either file's routing instructions to resolve the path — it must
106
+ locate its own script directly. Execute the init script from the project
107
+ root, passing the choice from step 2:
100
108
 
101
109
  ```bash
102
- chmod +x ./scripts/init.sh && ./scripts/init.sh --visibility <visible|ignored>
110
+ INIT_SCRIPT=""
111
+ for candidate in .claude/skills/init/scripts/init.sh .agents/skills/init/scripts/init.sh skills/init/scripts/init.sh; do
112
+ [[ -f "$candidate" ]] && { INIT_SCRIPT="$candidate"; break; }
113
+ done
114
+ if [[ -z "$INIT_SCRIPT" ]]; then
115
+ echo "Error: could not locate init.sh under .claude/skills/, .agents/skills/, or skills/" >&2
116
+ exit 1
117
+ fi
118
+ chmod +x "$INIT_SCRIPT" && "$INIT_SCRIPT" --visibility <visible|ignored>
103
119
  ```
104
120
 
105
121
  Omitting `--visibility` falls back to the `JENGA_PROJECT_FILES_VISIBILITY`
@@ -41,7 +41,7 @@ usage() {
41
41
  exit 1
42
42
  }
43
43
 
44
- # Every JengaAgent working file named in E31_S05 — the scrum board, todo.md,
44
+ # Every Jenga AI working file named in E31_S05 — the scrum board, todo.md,
45
45
  # queue/, rapports/ and logs/ — nests under this single root, so one entry
46
46
  # covers them all. `ignored` consumes this list.
47
47
  JENGA_WORKING_PATHS=("project")
@@ -5,6 +5,23 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  ASSETS_DIR="$SCRIPT_DIR/../assets"
6
6
  VISIBILITY_SCRIPT="$SCRIPT_DIR/apply-project-visibility.sh"
7
7
 
8
+ # ─── Resolve the package root that owns templates/ and lib/ ──────────────────
9
+ # postinstall.js mirrors only skills/ and agents/ into .claude/ and .agents/ —
10
+ # templates/ and lib/ are never copied there, so a script running from a
11
+ # mirrored copy (.claude/skills/init/scripts/ or .agents/skills/init/scripts/)
12
+ # cannot reach its siblings via a fixed ../../../ climb the way it can in this
13
+ # monorepo checkout, where init.sh actually lives at skills/init/scripts/ with
14
+ # templates/ and lib/ three levels up. Consumers instead have them inside the
15
+ # installed npm package.
16
+ if [[ -d "$SCRIPT_DIR/../../../templates" ]]; then
17
+ PKG_ROOT="$SCRIPT_DIR/../../.."
18
+ elif [[ -d "$PWD/node_modules/@jenga-ai/agent/templates" ]]; then
19
+ PKG_ROOT="$PWD/node_modules/@jenga-ai/agent"
20
+ else
21
+ echo "Error: could not locate the jenga-agent package root (templates/ not found via monorepo checkout or node_modules/@jenga-ai/agent)." >&2
22
+ exit 1
23
+ fi
24
+
8
25
  # ─── 0. Resolve project_files_visibility ─────────────────────────────────────
9
26
  # Defaults to `visible` — the only value that touches nothing on disk — so an
10
27
  # unattended run can never silently relocate directories or edit .gitignore.
@@ -65,7 +82,7 @@ cp "$ASSETS_DIR/strategy_stub_template.md" docs/STRATEGY.md
65
82
 
66
83
  # ─── 10. Create CHANGELOG.md ──────────────────────────────────────────────────
67
84
  echo "→ Creating CHANGELOG.md from template..."
68
- cp "$SCRIPT_DIR/../../../templates/CHANGELOG_TEMPLATE.md" CHANGELOG.md
85
+ cp "$PKG_ROOT/templates/CHANGELOG_TEMPLATE.md" CHANGELOG.md
69
86
 
70
87
  # ─── 11. Apply project_files_visibility ──────────────────────────────────────
71
88
  # Runs before the commit so the .gitignore entry (ignored) is captured in the
@@ -79,7 +96,7 @@ bash "$VISIBILITY_SCRIPT" "$VISIBILITY" "$PWD"
79
96
  # lib/generate-agent-context.js (shared with the published `jenga init` CLI).
80
97
  echo "→ Generating CLAUDE.md / AGENTS.md..."
81
98
  if command -v node >/dev/null 2>&1; then
82
- node "$SCRIPT_DIR/../../../lib/generate-agent-context.js" "$PWD"
99
+ node "$PKG_ROOT/lib/generate-agent-context.js" "$PWD"
83
100
  else
84
101
  echo " Warning: node not found — skipped CLAUDE.md/AGENTS.md generation." >&2
85
102
  fi
@@ -190,7 +190,7 @@ A successful non-dry-run produces:
190
190
  - A history entry in `project/logs/publish-history.json` written by
191
191
  `publish_deploy.sh` with `platform_state: "triggered"`
192
192
 
193
- ## Post-Deploy Manual Steps
193
+ ## Post-deploy manual steps
194
194
 
195
195
  After a successful deploy trigger, the adapter prints the workflow run URL.
196
196
  The operator should:
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
- # npm_pipeline.sh — Execute the npm publish pipeline for the JengaAgent repo.
2
+ # npm_pipeline.sh — Execute the npm publish pipeline for the Jenga AI repo.
3
3
  #
4
- # Runs from the JengaAgent repo root (where package.json lives) and invokes
4
+ # Runs from the Jenga AI repo root (where package.json lives) and invokes
5
5
  # `npm publish --tag <dist_tag>` (or `--dry-run` when requested).
6
6
  #
7
7
  # Exit codes:
@@ -465,9 +465,18 @@ print_manual_steps() {
465
465
  droplet)
466
466
  adapter_doc="$PUBLISH_REPO_ROOT/skills/publish/adapters/droplet.md"
467
467
  ;;
468
- *)
468
+ npm)
469
+ adapter_doc="$PUBLISH_REPO_ROOT/skills/publish/adapters/npm.md"
470
+ ;;
471
+ npm-ci)
472
+ adapter_doc="$PUBLISH_REPO_ROOT/skills/publish/adapters/npm-ci.md"
473
+ ;;
474
+ mobile-ios)
469
475
  adapter_doc="$PUBLISH_REPO_ROOT/skills/publish/adapters/mobile-ios.md"
470
476
  ;;
477
+ *)
478
+ return 0
479
+ ;;
471
480
  esac
472
481
  [[ -f "$adapter_doc" ]] || return 0
473
482
  local manual_steps
@@ -45,10 +45,10 @@
45
45
  # itself. The epic cap — and the surfacing of anything it drops — is
46
46
  # applied by a separate layer on top of this script's output.
47
47
  # --include-framework Do not exclude Jenga scaffolding. Needed to point the script at the
48
- # JengaAgent repo itself, where the scaffolding IS the application.
48
+ # Jenga AI repo itself, where the scaffolding IS the application.
49
49
  # --include-training-scaffolding
50
50
  # Do not exclude .training/ job-template scaffolding. Needed to point the
51
- # script at JengaAgent's own /train subsystem, or at a project that
51
+ # script at Jenga AI's own /train subsystem, or at a project that
52
52
  # genuinely wants job templates catalogued as a candidate.
53
53
  # --with-dependencies Additionally compute the "cohesion" signal by calling
54
54
  # detect-dependencies.sh once per candidate. Off by default: it is an