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 +1 -1
- package/scripts/install.js +27 -29
- package/skills/capture/SKILL.md +11 -17
- package/skills/kickoff/SKILL.md +77 -20
package/package.json
CHANGED
package/scripts/install.js
CHANGED
|
@@ -462,17 +462,17 @@ function main() {
|
|
|
462
462
|
console.log('toga-ai — TOGA Technology Claude harness');
|
|
463
463
|
console.log('═════════════════════════════════════════════');
|
|
464
464
|
|
|
465
|
-
//
|
|
466
|
-
|
|
467
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 —
|
|
503
|
-
|
|
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('
|
|
512
|
-
if (
|
|
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 &&
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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,
|
|
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(
|
|
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 —
|
|
607
|
-
|
|
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,
|
|
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
|
package/skills/capture/SKILL.md
CHANGED
|
@@ -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
|
|
104
|
-
|
|
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
|
-
#
|
|
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
|
|
115
|
-
git -C "<TEAM_REPO>" push origin HEAD:
|
|
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
|
|
119
|
-
|
|
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
|
|
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
|
|
125
|
-
|
|
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
|
package/skills/kickoff/SKILL.md
CHANGED
|
@@ -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 —
|
|
153
|
+
## Step 5 — Propose a multi-agent workflow plan
|
|
154
154
|
|
|
155
|
-
After loading
|
|
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
|
-
|
|
158
|
-
|
|
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
|
-
|
|
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
|
-
|
|
166
|
-
|
|
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
|
-
**
|
|
169
|
-
-
|
|
170
|
-
-
|
|
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
|
-
|
|
173
|
-
|
|
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
|
-
|
|
183
|
+
Ready to proceed?
|
|
176
184
|
```
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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.
|