toga-ai 1.0.4 → 1.0.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.4",
3
+ "version": "1.0.7",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",
@@ -462,17 +462,17 @@ function main() {
462
462
  console.log('toga-ai — TOGA Technology Claude harness');
463
463
  console.log('═════════════════════════════════════════════');
464
464
 
465
- // Step 1: npm bundle is always the baseline source
466
- let sourceDir = PACKAGE_ROOT;
467
- let sourceLabel = 'npm bundle v' + bundleVersion;
465
+ // Harness components (skills/agents/rules/hooks) ALWAYS come from the npm bundle.
466
+ // The git repo is ONLY used to pull newer knowledge docs on top — it never
467
+ // replaces harness components, so a stale local clone can't break the install.
468
+ const harnessDir = PACKAGE_ROOT;
469
+ let knowledgeDir = PACKAGE_ROOT; // overridden below if git repo found
468
470
  let gitUpdateLine = null;
469
471
 
470
- // Step 2: find or try to clone git repo for updates
471
472
  if (repoFlag) {
472
473
  const resolved = path.resolve(repoFlag);
473
474
  if (isValidClone(resolved)) {
474
- sourceDir = resolved;
475
- sourceLabel = 'git repo (--repo flag)';
475
+ knowledgeDir = resolved;
476
476
  } else {
477
477
  console.error(' ERROR: --repo path is not a valid clone: ' + resolved);
478
478
  process.exit(1);
@@ -481,40 +481,37 @@ function main() {
481
481
  let repoDir = findExistingClone();
482
482
 
483
483
  if (!repoDir && !isPostInstall) {
484
- // Try to clone silently — no error if it fails
485
484
  repoDir = tryCloneRepo(path.join(os.homedir(), 'toga-tech'));
486
485
  }
487
486
 
488
487
  if (repoDir) {
489
- // Pull latest — silent on failure, just use bundle
490
488
  const pullResult = tryGitPull(repoDir);
491
489
  saveRepoPathCache(repoDir);
492
490
 
493
491
  if (pullResult.pulled) {
494
- sourceDir = repoDir;
495
- sourceLabel = 'npm bundle v' + bundleVersion;
492
+ knowledgeDir = repoDir;
496
493
  if (pullResult.newDocs > 0) {
497
494
  gitUpdateLine = 'git update: pulled ' + pullResult.newDocs + ' new knowledge doc' + (pullResult.newDocs !== 1 ? 's' : '') + ' from TOGATechnology/claude';
498
- } else {
495
+ } else if (pullResult.message !== 'already up to date') {
499
496
  gitUpdateLine = 'git update: ' + pullResult.message;
500
497
  }
501
498
  } else if (isValidClone(repoDir)) {
502
- // Pull failed but repo exists — still use it as source
503
- sourceDir = repoDir;
504
- sourceLabel = 'git repo (offline, using cached)';
499
+ // Pull failed but repo exists — use cached knowledge only
500
+ knowledgeDir = repoDir;
505
501
  }
506
- // else: pull failed and can't use repo — silently stick with bundle
507
502
  }
508
- // No git access at all — silently use bundle
509
503
  }
510
504
 
511
- console.log(' Source: ' + sourceLabel);
512
- if (gitUpdateLine) {
505
+ console.log(' Harness: npm bundle v' + bundleVersion);
506
+ if (knowledgeDir !== PACKAGE_ROOT) {
507
+ console.log(' Knowledge: git repo' + (gitUpdateLine ? ' (' + gitUpdateLine.replace('git update: ', '') + ')' : ' (cached)'));
508
+ }
509
+ if (gitUpdateLine && knowledgeDir === PACKAGE_ROOT) {
513
510
  console.log(' ↳ ' + gitUpdateLine);
514
511
  }
515
512
  console.log('');
516
513
 
517
- if (isPostInstall && sourceDir === PACKAGE_ROOT && !repoFlag) {
514
+ if (isPostInstall && !repoFlag) {
518
515
  console.log(' First-time setup: run `toga-ai` from your project to');
519
516
  console.log(' install the harness into your .claude/ directory.');
520
517
  console.log('');
@@ -535,7 +532,7 @@ function main() {
535
532
  const errors = [];
536
533
 
537
534
  // Skills
538
- const skillsSrc = path.join(sourceDir, 'skills');
535
+ const skillsSrc = path.join(harnessDir, 'skills');
539
536
  const skillsDest = path.join(claudeDir, 'skills');
540
537
  fs.mkdirSync(skillsDest, { recursive: true });
541
538
  const skillNames = fs.existsSync(skillsSrc)
@@ -552,7 +549,7 @@ function main() {
552
549
  console.log(' ✓ Skills (' + skillNames.length + '): ' + fmtStats(skillStats));
553
550
 
554
551
  // Rules — update if content changed (team standards should always be current)
555
- const rulesSrc = path.join(sourceDir, 'rules');
552
+ const rulesSrc = path.join(harnessDir, 'rules');
556
553
  const rulesDest = path.join(claudeDir, 'rules', 'toga');
557
554
  let rulesStats = { added: 0, updated: 0, unchanged: 0 };
558
555
  if (fs.existsSync(rulesSrc)) {
@@ -562,7 +559,7 @@ function main() {
562
559
  console.log(' ✓ Rules (' + countMd(rulesDest) + '): ' + fmtStats(rulesStats));
563
560
 
564
561
  // Agents — update if content changed
565
- const agentsSrc = path.join(sourceDir, 'agents');
562
+ const agentsSrc = path.join(harnessDir, 'agents');
566
563
  const agentsDest = path.join(claudeDir, 'agents', 'toga');
567
564
  let agentsStats = { added: 0, updated: 0, unchanged: 0 };
568
565
  if (fs.existsSync(agentsSrc)) {
@@ -573,7 +570,7 @@ function main() {
573
570
  console.log(' ✓ Agents (' + agentsCount + '): ' + fmtStats(agentsStats));
574
571
 
575
572
  // Hook scripts — always overwrite so paths stay up to date
576
- const hooksSrc = path.join(sourceDir, 'scripts', 'hooks');
573
+ const hooksSrc = path.join(harnessDir, 'scripts', 'hooks');
577
574
  const hooksDest = path.join(claudeDir, 'hooks', 'toga');
578
575
  let hooksCount = 0;
579
576
  if (fs.existsSync(hooksSrc)) {
@@ -584,18 +581,18 @@ function main() {
584
581
  }
585
582
 
586
583
  // knowledge.js CLI — always overwrite so it stays current
587
- const knowledgeJsSrc = path.join(sourceDir, 'knowledge.js');
584
+ const knowledgeJsSrc = path.join(harnessDir, 'knowledge.js');
588
585
  if (fs.existsSync(knowledgeJsSrc)) {
589
586
  try { fs.copyFileSync(knowledgeJsSrc, path.join(claudeDir, 'knowledge.js')); }
590
587
  catch (e) { errors.push('knowledge.js: ' + e.message); }
591
588
  }
592
589
 
593
590
  // Settings — merge (additive only, never removes existing hooks or permissions)
594
- const ok = mergeSettings(claudeDir, sourceDir);
591
+ const ok = mergeSettings(claudeDir, harnessDir);
595
592
  console.log(' ' + (ok ? '✓' : '✗') + ' Hooks (' + hooksCount + ' scripts in .claude/hooks/toga/, settings.json merged)');
596
593
 
597
594
  // MCP example — skip if already present
598
- const mcpSrc = path.join(sourceDir, 'mcp-configs', 'mcp-servers.json');
595
+ const mcpSrc = path.join(harnessDir, 'mcp-configs', 'mcp-servers.json');
599
596
  const mcpDest = path.join(claudeDir, 'mcp-servers.example.json');
600
597
  if (fs.existsSync(mcpSrc) && !fs.existsSync(mcpDest)) {
601
598
  try { fs.copyFileSync(mcpSrc, mcpDest); }
@@ -603,8 +600,9 @@ function main() {
603
600
  console.log(' ✓ MCP (.claude/mcp-servers.example.json — merge into .mcp.json to enable)');
604
601
  }
605
602
 
606
- // Knowledge — skipExisting: user-grown docs are never overwritten by the bundle
607
- const knowledgeSrc = path.join(sourceDir, 'knowledge');
603
+ // Knowledge — git repo if available (has team-captured docs), else npm bundle
604
+ // skipExisting: user-grown docs are never overwritten
605
+ const knowledgeSrc = path.join(knowledgeDir, 'knowledge');
608
606
  const knowledgeDest = path.join(claudeDir, 'knowledge');
609
607
  let knowledgeStats = { added: 0, updated: 0, unchanged: 0 };
610
608
  if (fs.existsSync(knowledgeSrc)) {
@@ -614,7 +612,7 @@ function main() {
614
612
  console.log(' ✓ Knowledge (' + countMd(knowledgeDest) + ' docs): ' + fmtStats(knowledgeStats));
615
613
 
616
614
  // CLAUDE.md
617
- const action = updateClaudeMd(projectRoot, skillNames, sourceDir, sourceLabel);
615
+ const action = updateClaudeMd(projectRoot, skillNames, harnessDir, 'npm bundle v' + bundleVersion);
618
616
  console.log(' ✓ CLAUDE.md ' + action);
619
617
 
620
618
  // ECC global integration — detect and report
@@ -100,39 +100,33 @@ report success on an inconsistent knowledge base.
100
100
 
101
101
  ## Step 7 — Auto-push to share with teammates
102
102
 
103
- After validate + index succeed, stage and push only `knowledge/` changes to a
104
- **personal branch** so a maintainer can review before merging to main.
103
+ After validate + index succeed, stage and push only `knowledge/` changes directly to
104
+ `feature/ai-harness-improvements`. CI picks up the push and publishes a new npm version
105
+ automatically — teammates get it on their next `npx toga-ai`.
105
106
 
106
107
  ```bash
107
- # Derive branch name from git user e.g. knowledge/john-smith
108
- BRANCH="knowledge/$(git -C "<TEAM_REPO>" config user.name | tr ' ' '-' | tr '[:upper:]' '[:lower:]')"
109
-
110
- # Stage only knowledge/ — never stages source code
108
+ # Stage only knowledge/ never stage source code
111
109
  git -C "<TEAM_REPO>" add knowledge/
112
110
  git -C "<TEAM_REPO>" diff --cached --quiet || git -C "<TEAM_REPO>" commit -m "knowledge: <brief description of what was captured>"
113
111
 
114
- # Push to personal branch does not touch main
115
- git -C "<TEAM_REPO>" push origin HEAD:"$BRANCH"
112
+ # Push directly to the active development branch
113
+ git -C "<TEAM_REPO>" push origin HEAD:feature/ai-harness-improvements
116
114
  ```
117
115
 
118
- Replace `<brief description of what was captured>` with a one-line summary of the docs
119
- written this capture (e.g. `"knowledge: add clickup-deploy feature doc for worker2"`).
116
+ Replace `<brief description of what was captured>` with a one-line summary
117
+ (e.g. `"knowledge: add clickup-deploy feature doc for worker2"`).
120
118
 
121
119
  **If push succeeds:** report
122
- > "✓ Knowledge pushed to branch `knowledge/<your-name>` — a maintainer will review and merge to main"
120
+ > "✓ Knowledge pushed to `feature/ai-harness-improvements`CI will publish a new npm version. Teammates get it on their next `npx toga-ai`."
123
121
 
124
- **If push fails** (offline, no credentials, diverged branch, or any other error): do
125
- **NOT** error out. Report:
126
- > "⚠ Could not push — run `git -C <TEAM_REPO> push origin HEAD:knowledge/<your-name>` when ready"
122
+ **If push fails** (offline, no credentials, diverged): do **NOT** error out. Report:
123
+ > "⚠ Could not push — run `git -C <TEAM_REPO> push origin HEAD:feature/ai-harness-improvements` when ready"
127
124
  and still consider the capture session successful.
128
125
 
129
126
  Never stage anything outside `knowledge/`. If `git diff --cached` would include files
130
127
  outside `knowledge/`, abort the commit and warn: "Unexpected staged files outside
131
128
  `knowledge/` — push skipped. Review and push manually."
132
129
 
133
- **Devs do not need write access to main.** They only need permission to push to
134
- `knowledge/*` branches. A maintainer reviews the branch and merges via PR.
135
-
136
130
  ## Step 8 — Report
137
131
 
138
132
  List exactly what changed (clickable relative paths), and note any ⚠ ELEVATED docs the
@@ -150,32 +150,89 @@ If they have already run `/session-resume` and are now running `/kickoff`, proce
150
150
  normally — the session context they loaded will complement the framework knowledge
151
151
  loaded here.
152
152
 
153
- ## Step 5 — Surface ECC power-ups for the work type
153
+ ## Step 5 — Propose a multi-agent workflow plan
154
154
 
155
- After loading TOGA context, tell the developer which ECC specialist capabilities are available for this session's work type:
155
+ After loading context, analyze what the developer said they're building and **propose a
156
+ concrete agent plan before writing a single line of code**. This gives them visibility
157
+ into how the work will be done and a chance to adjust scope.
156
158
 
157
- **For PHP development:**
158
- - `/code-review` ECC php-reviewer + TOGA pattern overlay (use after writing any PHP)
159
- - ECC security-reviewer fires automatically on security-sensitive code
159
+ The developer does not know what "sub-agents" or "loops" are — do not use that jargon.
160
+ Frame everything in plain terms: "Here's my plan."
160
161
 
161
- **For feature implementation:**
162
- - `/code-review` triggers ecc:planner with your loaded TOGA architecture context
163
- - The php-reviewer agent runs automatically after every PHP file edit
162
+ ### Plan template
164
163
 
165
- **For debugging / build errors:**
166
- - ecc:build-error-resolver + TOGA framework context = fast diagnosis
164
+ ```
165
+ Here's how I'll approach this:
166
+
167
+ 1. [First step — e.g. "Map the existing code and create a phased plan"]
168
+ 2. [Build step — e.g. "Write the worker class and controller method"]
169
+ 3. [Verify step — e.g. "Run specialist reviewers on the PHP and SQL before showing you the result"]
170
+
171
+ To do this well, I'll use specialist reviewers that run automatically as I write —
172
+ they catch framework violations and security issues without you needing to ask.
167
173
 
168
- **For SQL/DB work:**
169
- - sql-reviewer agent fires automatically on PHP files with DB patterns
170
- - ecc:database-reviewer provides deep query analysis
174
+ **I'll need access to:**
175
+ - Read: [list relevant repo paths]
176
+ - Write/edit: [list the specific files or folders I plan to create or modify]
177
+ - Shell: [any commands I'll run, e.g. "php -l to lint files"]
171
178
 
172
- **For documentation:**
173
- - `knowledge-writer` agent writes correct TOGA frontmatter automatically
179
+ Claude Code will ask you to approve each action as I go. If you'd rather I just
180
+ proceed without interrupting you, say "go ahead" and I'll work through it and
181
+ show you the finished result.
174
182
 
175
- End the kickoff with:
183
+ Ready to proceed?
176
184
  ```
177
- Context loaded for <repo> (Framework <fw>).
178
- ECC agents active: php-reviewer, database-reviewer, security-reviewer, planner, build-error-resolver.
179
- Run /kickoff again if you switch to a different repo or client.
180
- What are you building?
185
+
186
+ **Always wait for a yes before starting.** If the developer says "go ahead", "just do it",
187
+ or "you have full access" proceed without further permission prompts, but still flag any
188
+ write outside the expected scope.
189
+
190
+ ---
191
+
192
+ ### Agent selection (how to build the plan internally)
193
+
194
+ Spawn specialists via the `Agent` tool. Grant only the tools the agent needs.
195
+
196
+ | Work type | Agent to spawn | Tools to grant |
197
+ |-----------|---------------|----------------|
198
+ | New feature design | `ecc:planner` with TOGA context prefix | Read, Grep, Glob |
199
+ | Write/edit PHP | `ecc:php-reviewer` after each file written | Read, Grep, Glob |
200
+ | SQL / DB queries | `ecc:database-reviewer` with TOGA DB context | Read, Grep, Glob |
201
+ | PHP errors / build broken | `ecc:build-error-resolver` with TOGA error patterns | Read, Write, Edit, Bash, Grep, Glob |
202
+ | Security audit | `ecc:security-reviewer` | Read, Grep, Glob |
203
+ | Document a feature | `knowledge-writer` TOGA agent | Read, Write, Bash, Grep, Glob |
204
+ | Large refactor | `ecc:code-reviewer` then `ecc:planner` | Read, Grep, Glob |
205
+
206
+ Always inject the TOGA context prefix when spawning any ECC agent. The prompts in
207
+ `.claude/agents/toga/php-reviewer.md` and `planner.md` show the exact prefix format.
208
+
209
+ ---
210
+
211
+ ### When to use an iterative loop
212
+
213
+ Run an agent, review findings, fix, repeat — when:
214
+ - Build errors are present (keep looping until output is clean)
215
+ - The developer says "make sure this is right" or "check everything"
216
+ - You're creating more than 3 PHP files in one task
217
+
218
+ Tell the developer when you enter a loop:
181
219
  ```
220
+ I'll write the code, then run it through the PHP reviewer. If issues are found
221
+ I'll fix them automatically before showing you the final result. This may take
222
+ a few passes — I'll let you know when it's clean.
223
+ ```
224
+
225
+ ---
226
+
227
+ ### End-of-kickoff output
228
+
229
+ ```
230
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
231
+ Context: <repo> · Framework <fw> · Client: <client>
232
+ Specialists on standby: php-reviewer, database-reviewer, security-reviewer, planner
233
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
234
+ What are you building today?
235
+ ```
236
+
237
+ After the developer describes the task, present the plan (template above) and wait
238
+ for confirmation. Then begin immediately — do not ask "shall I start?" a second time.