@dtlabs/ai-toolkit 0.12.0 → 0.13.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 (36) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/bin/cli.js +480 -7
  3. package/lib/agent-registry.js +1018 -0
  4. package/lib/execution-ledger.js +97 -3
  5. package/package.json +1 -1
  6. package/src/claude/agents/{concurrency-safety-assessment.md → gaia-concurrency-safety-assessment.md} +1 -1
  7. package/src/claude/agents/{define-feature.md → gaia-define-feature.md} +1 -1
  8. package/src/claude/agents/{dependency-injection-refactoring.md → gaia-dependency-injection-refactoring.md} +1 -1
  9. package/src/claude/agents/{dependency-supply-chain-security.md → gaia-dependency-supply-chain-security.md} +1 -1
  10. package/src/claude/agents/{developer-backend.md → gaia-developer-backend.md} +1 -1
  11. package/src/claude/agents/{developer-frontend.md → gaia-developer-frontend.md} +1 -1
  12. package/src/claude/agents/{developer-testing.md → gaia-developer-testing.md} +1 -1
  13. package/src/claude/agents/{domain-model-refactoring.md → gaia-domain-model-refactoring.md} +1 -1
  14. package/src/claude/agents/{generate-requirements.md → gaia-generate-requirements.md} +1 -1
  15. package/src/claude/agents/{generate-tech-spec.md → gaia-generate-tech-spec.md} +1 -1
  16. package/src/claude/agents/{generate-work-breakdown.md → gaia-generate-work-breakdown.md} +5 -5
  17. package/src/claude/agents/{generic-software-assessment.md → gaia-generic-software-assessment.md} +1 -1
  18. package/src/claude/agents/{god-class-decomposition.md → gaia-god-class-decomposition.md} +1 -1
  19. package/src/claude/agents/{init-agents-md.md → gaia-init-agents-md.md} +1 -1
  20. package/src/claude/agents/{install-toolkit.md → gaia-install-toolkit.md} +1 -1
  21. package/src/claude/agents/{intervention-documentation-standard.md → gaia-intervention-documentation-standard.md} +1 -1
  22. package/src/claude/agents/{layered-architecture-assessment.md → gaia-layered-architecture-assessment.md} +1 -1
  23. package/src/claude/agents/{review-solution.md → gaia-review-solution.md} +1 -1
  24. package/src/claude/agents/{security-hardening.md → gaia-security-hardening.md} +1 -1
  25. package/src/claude/agents/{validate-feature-docs.md → gaia-validate-feature-docs.md} +2 -2
  26. package/src/claude/agents/{validate-work-breakdown-semantic.md → gaia-validate-work-breakdown-semantic.md} +1 -1
  27. package/src/claude/commands/next-task.md +4 -4
  28. package/src/claude/skills/assess-codebase/SKILL.md +1 -1
  29. package/src/claude/skills/define-feature/SKILL.md +2 -2
  30. package/src/claude/skills/hi-gaia/SKILL.md +1 -1
  31. package/src/claude/skills/implement-feature/SKILL.md +186 -8
  32. package/src/claude/skills/init-agents/SKILL.md +2 -2
  33. package/src/claude/skills/install-toolkit/SKILL.md +2 -2
  34. package/src/claude/workflows/pm-phase1.js +76 -5
  35. package/src/claude/workflows/pm-phase2.js +63 -2
  36. package/src/claude/workflows/pm-phase3.js +66 -9
@@ -244,6 +244,73 @@ function _isLockStale(content, stat) {
244
244
  return mtimeAge > LOCK_ORPHAN_THRESHOLD_MS ? 'reclaimable' : 'wait';
245
245
  }
246
246
 
247
+ // ── Metadata whitelist and reserved-field protection (INFRA-TASK-BE-03) ─────
248
+
249
+ const METADATA_WHITELIST = new Set([
250
+ 'agentId',
251
+ 'nativeAgentName',
252
+ 'platform',
253
+ 'toolkitVersion',
254
+ 'resolutionScope',
255
+ 'definitionHash',
256
+ ]);
257
+
258
+ const RESERVED_FIELDS = new Set([
259
+ 'operation_id',
260
+ 'agent',
261
+ 'phase',
262
+ 'model',
263
+ 'status',
264
+ 'started_at',
265
+ 'completed_at',
266
+ 'phase_delta_tokens',
267
+ 'error',
268
+ ]);
269
+
270
+ function _validateMetadata(metadata) {
271
+ for (const key of Object.keys(metadata)) {
272
+ if (RESERVED_FIELDS.has(key)) {
273
+ const err = new Error(
274
+ 'open: metadata key "' + key + '" is a reserved field and cannot be set via metadata'
275
+ );
276
+ err.code = 'METADATA_RESERVED_FIELD';
277
+ err.key = key;
278
+ throw err;
279
+ }
280
+ if (!METADATA_WHITELIST.has(key)) {
281
+ const err = new Error(
282
+ 'open: metadata key "' + key + '" is not in the whitelist; ' +
283
+ 'allowed keys: ' + Array.from(METADATA_WHITELIST).join(', ')
284
+ );
285
+ err.code = 'METADATA_UNKNOWN_KEY';
286
+ err.key = key;
287
+ throw err;
288
+ }
289
+ }
290
+ }
291
+
292
+ function _extractStoredMetadata(entry) {
293
+ const result = {};
294
+ for (const key of METADATA_WHITELIST) {
295
+ if (Object.prototype.hasOwnProperty.call(entry, key)) {
296
+ result[key] = entry[key];
297
+ }
298
+ }
299
+ return result;
300
+ }
301
+
302
+ function _metadataEqual(storedEntry, newMetadata) {
303
+ const stored = _extractStoredMetadata(storedEntry);
304
+ const storedKeys = Object.keys(stored).sort();
305
+ const newKeys = Object.keys(newMetadata).sort();
306
+
307
+ if (storedKeys.length !== newKeys.length) return false;
308
+ for (var i = 0; i < newKeys.length; i++) {
309
+ if (stored[newKeys[i]] !== newMetadata[newKeys[i]]) return false;
310
+ }
311
+ return true;
312
+ }
313
+
247
314
  // ── Public API (stubs — implemented by INFRA-TASK-BE-02 and US-0x tasks) ────
248
315
 
249
316
  function computeOperationId(prefix, agent, attempt) {
@@ -251,9 +318,14 @@ function computeOperationId(prefix, agent, attempt) {
251
318
  return crypto.createHash('sha256').update(input, 'utf8').digest('hex').slice(0, 32);
252
319
  }
253
320
 
254
- function open(dir, prefix, agent, phase, model, attempt) {
321
+ function open(dir, prefix, agent, phase, model, attempt, metadata) {
255
322
  if (attempt == null) attempt = 1;
256
323
 
324
+ // Validate metadata keys BEFORE any lock or I/O (fail-closed).
325
+ if (metadata != null) {
326
+ _validateMetadata(metadata);
327
+ }
328
+
257
329
  const ledgerPath = path.join(dir, prefix + '-token-ledger.json');
258
330
  const lockPath = ledgerPath + '.lock';
259
331
 
@@ -268,11 +340,24 @@ function open(dir, prefix, agent, phase, model, attempt) {
268
340
  });
269
341
 
270
342
  if (existingIndex !== -1) {
343
+ // Idempotent re-open: check metadata conflict BEFORE writing anything.
344
+ if (metadata != null) {
345
+ if (!_metadataEqual(entries[existingIndex], metadata)) {
346
+ const err = new Error(
347
+ 'open: metadata conflict for operation_id ' + operation_id +
348
+ ' — supplied metadata differs from stored metadata; re-open rejected (fail-closed)'
349
+ );
350
+ err.code = 'METADATA_CONFLICT';
351
+ err.operation_id = operation_id;
352
+ throw err;
353
+ }
354
+ }
271
355
  // Resume: idempotently preserve original started_at and any positive
272
356
  // phase_delta_tokens — only reset status to running.
273
357
  entries[existingIndex] = Object.assign({}, entries[existingIndex], { status: 'running' });
274
358
  } else {
275
- entries.push({
359
+ // First open: store standard fields, then spread validated metadata fields.
360
+ const newEntry = {
276
361
  operation_id: operation_id,
277
362
  agent: agent,
278
363
  phase: phase,
@@ -281,7 +366,11 @@ function open(dir, prefix, agent, phase, model, attempt) {
281
366
  started_at: started_at,
282
367
  completed_at: null,
283
368
  phase_delta_tokens: null,
284
- });
369
+ };
370
+ if (metadata != null) {
371
+ Object.assign(newEntry, metadata);
372
+ }
373
+ entries.push(newEntry);
285
374
  }
286
375
 
287
376
  _writeLedger(ledgerPath, entries);
@@ -512,4 +601,9 @@ module.exports = {
512
601
  _acquireLock,
513
602
  _releaseLock,
514
603
  _isLockStale,
604
+ _validateMetadata,
605
+ _extractStoredMetadata,
606
+ _metadataEqual,
607
+ METADATA_WHITELIST,
608
+ RESERVED_FIELDS,
515
609
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dtlabs/ai-toolkit",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "AI Toolkit — reusable agents and procedures for developers to build AI-powered applications.",
5
5
  "files": [
6
6
  "docs/",
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: concurrency-safety-assessment
2
+ name: gaia-concurrency-safety-assessment
3
3
  description: "Concurrency Safety Assessment — identifies race conditions, shared mutable state corruption, and non-deterministic behaviour in concurrent or event-driven systems. Language-agnostic; produces structured findings with severity, evidence, and mitigation patterns. Output: {ASSESS_PREFIX}-Concurrency-Assessment.md"
4
4
  tools: Read, Grep, Glob, Bash, Write
5
5
  model: haiku
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: define-feature
2
+ name: gaia-define-feature
3
3
  description: "Define Feature — grills the user with targeted questions to define a new feature, then writes feature.md in docs/features/FTR-XXX-slug/. Output: feature.md ready for /implement-feature"
4
4
  model: sonnet
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: dependency-injection-refactoring
2
+ name: gaia-dependency-injection-refactoring
3
3
  description: "Dependency Injection Refactoring — guides the incremental conversion of tightly coupled or statically accessed dependencies to constructor-injected services, preserving build integrity at every step. Language-agnostic; reads AGENTS.md for framework-specific DI patterns. Input: target classes from intervention document"
4
4
  model: sonnet
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: dependency-supply-chain-security
2
+ name: gaia-dependency-supply-chain-security
3
3
  description: "Dependency Supply Chain Security — guides the implementation of dependency integrity controls: trusted package sources, deterministic restore via lock files, unused dependency audit, and SCA integration in CI/CD pipelines. Works with npm, pip, NuGet, Maven, and other package managers; reads AGENTS.md for project stack. Output: remediated configuration files + CI/CD pipeline changes"
4
4
  model: sonnet
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: developer-backend
2
+ name: gaia-developer-backend
3
3
  description: "Senior Backend Developer — implements backend tasks (DB, BE, INFRA domains) from the Work Breakdown following project conventions. Input: path to feature.md + task IDs"
4
4
  model: sonnet
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: developer-frontend
2
+ name: gaia-developer-frontend
3
3
  description: "Senior Frontend Developer — implements frontend tasks (FE domain) from the Work Breakdown following project conventions. Input: path to feature.md + task IDs"
4
4
  model: sonnet
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: developer-testing
2
+ name: gaia-developer-testing
3
3
  description: "Senior Test Engineer — creates unit/integration tests for implemented features (TEST domain). Input: path to feature.md + task IDs"
4
4
  model: sonnet
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: domain-model-refactoring
2
+ name: gaia-domain-model-refactoring
3
3
  description: "Domain Model Refactoring — guides the decomposition of monolithic domain model files, introduction of type hierarchies for structurally similar types, and alignment of model names with domain ubiquitous language. Language-agnostic; reads AGENTS.md for project conventions. Input: target model directory from intervention document"
4
4
  model: sonnet
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: generate-requirements
2
+ name: gaia-generate-requirements
3
3
  description: "Generates a functional requirements document from a feature description. Input: path to feature.md"
4
4
  model: haiku
5
5
  tools: Read, Glob, Grep, Write
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: generate-tech-spec
2
+ name: gaia-generate-tech-spec
3
3
  description: "Generates a technical specification document from a feature description and requirements. Input: path to feature.md"
4
4
  model: haiku
5
5
  tools: Read, Glob, Grep, Write
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: generate-work-breakdown
2
+ name: gaia-generate-work-breakdown
3
3
  description: "Generates a structured work breakdown (User Stories + Tasks) from validated and approved Requirements and Tech-Spec. Input: path to feature.md"
4
4
  model: haiku
5
5
  tools: Read, Glob, Grep, Write
@@ -24,7 +24,7 @@ The user provides the path to a `feature.md` file. From the same directory, read
24
24
  ```
25
25
  Cannot generate work breakdown: `{file}` not found.
26
26
  The work breakdown requires validated and approved Requirements + Tech-Spec.
27
- Run /agent-project-manager to orchestrate the full pipeline (including validation and approval gates).
27
+ Run /implement-feature to orchestrate the full pipeline (including validation and approval gates).
28
28
  ```
29
29
 
30
30
  ---
@@ -63,7 +63,7 @@ Every task must be the **smallest independently implementable, verifiable, and c
63
63
 
64
64
  - **One observable outcome** — the task produces exactly one concrete artifact or behavioral change (one file, one endpoint, one migration, one test suite for one check). State it in the `outcome` field as a factual sentence describing what exists after the task is done.
65
65
  - **One domain** — choose exactly one: `BE`, `FE`, `DB`, `DevOps`, `INFRA`, or `TEST`.
66
- - **One agent type** — choose exactly one: `developer-backend`, `developer-frontend`, `developer-testing`, `developer-database`, or `review-solution`.
66
+ - **One agent type** — choose exactly one: `developer-backend`, `developer-frontend`, `developer-testing`, or `review-solution`. (`developer-database` is deprecated — use `developer-backend` for DB domain tasks.)
67
67
  - **One commit** — supply a single `commit.subject` describing the change.
68
68
  - **Estimated ≤ 15 minutes of agent time** — this is the target. If a task cannot be scoped to ≤ 15 minutes, split it further. Tasks up to 20 minutes are acceptable but above target. Tasks over 30 minutes are invalid and will be rejected by the validator.
69
69
 
@@ -126,7 +126,7 @@ Decomposition strategy by domain:
126
126
  | `title` | string | Short descriptive title; must not contain `\|`, CR, or LF |
127
127
  | `outcome` | string | Single observable outcome — what exists after this task is done |
128
128
  | `domain` | string | One of: `BE`, `FE`, `DB`, `DevOps`, `INFRA`, `TEST` |
129
- | `agentType` | string | One of: `developer-backend`, `developer-frontend`, `developer-testing`, `developer-database`, `review-solution` |
129
+ | `agentType` | string | One of: `developer-backend`, `developer-frontend`, `developer-testing`, `review-solution` (deprecated: `developer-database` — maps to `developer-backend`) |
130
130
  | `dependsOn` | array of strings | Task IDs this task depends on; may be empty `[]`; all IDs must be defined within this same JSON |
131
131
  | `acceptanceCriteria` | array of strings | AC IDs from Requirements that this task covers; may be empty `[]` |
132
132
  | `verification` | object | `{ "commands": ["..."] }` — one or more shell commands that verify the task output; array must be non-empty |
@@ -136,7 +136,7 @@ Decomposition strategy by domain:
136
136
  | `commit` | object | `{ "type": "feat", "subject": "..." }` — subject must not contain `\|`, CR, or LF |
137
137
 
138
138
  **Domain → agentType mapping (default):**
139
- - `DB` → `developer-database`
139
+ - `DB` → `developer-backend` (note: `developer-database` is a deprecated alias that still resolves — do NOT use it in new Work Breakdowns)
140
140
  - `BE`, `INFRA`, `DevOps` → `developer-backend`
141
141
  - `FE` → `developer-frontend`
142
142
  - `TEST` → `developer-testing`
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: generic-software-assessment
2
+ name: gaia-generic-software-assessment
3
3
  description: "Generic Software Assessment — performs a broad quality analysis across architecture, code quality, security, testability, observability, and DevOps. Reads AGENTS.md for project conventions. Output: {ASSESS_PREFIX}-Generic-Assessment.md"
4
4
  tools: Read, Grep, Glob, Bash, Write
5
5
  model: haiku
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: god-class-decomposition
2
+ name: gaia-god-class-decomposition
3
3
  description: "God Class Decomposition — guides the safe, incremental decomposition of oversized classes and methods using responsibility cluster analysis, extract-method, extract-class, and parameter object refactoring. Language-agnostic; reads AGENTS.md for project conventions. Input: target class(es) from intervention document"
4
4
  model: sonnet
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: init-agents-md
2
+ name: gaia-init-agents-md
3
3
  description: "Analyzes a project codebase and generates a complete AGENTS.md file with tech stack, conventions, real code patterns, build/test commands, and hard constraints. Input: (optional) path to project root — defaults to current working directory."
4
4
  model: sonnet
5
5
  tools: Read, Glob, Grep, Bash, Write
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: install-toolkit
2
+ name: gaia-install-toolkit
3
3
  description: "Installs the ai-toolkit into a destination project by copying agents, skills, commands, and procedures. Input: [path-to-destination] [--force] — defaults to current working directory"
4
4
  model: sonnet
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: intervention-documentation-standard
2
+ name: gaia-intervention-documentation-standard
3
3
  description: "Intervention Documentation Standard — generates structured, self-contained intervention documents from assessment findings. Each document is independently actionable by an architect or developer agent. Input: assessment findings; Output: {ASSESS_PREFIX}-INT-NNN-{slug}.md per finding + Interventions-Index.md"
4
4
  model: sonnet
5
5
  tools: Read, Grep, Glob, Bash, Write
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: layered-architecture-assessment
2
+ name: gaia-layered-architecture-assessment
3
3
  description: "Layered Architecture Assessment — audits a codebase for layer boundary violations, missing separation of concerns, and namespace/package misalignment. Produces a violation inventory and a recommended layer model. Language-agnostic; reads AGENTS.md for project conventions. Output: {ASSESS_PREFIX}-Layer-Assessment.md"
4
4
  tools: Read, Grep, Glob, Bash, Write
5
5
  model: haiku
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: review-solution
2
+ name: gaia-review-solution
3
3
  description: "Senior Architect — full solution review across quality, reuse, architecture, and security dimensions. Reports findings without auto-fixing. Input: scope (files, US-XX, or git diff)"
4
4
  model: opus
5
5
  tools: Read, Grep, Glob, Bash
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: security-hardening
2
+ name: gaia-security-hardening
3
3
  description: "Security Hardening — guides the implementation of targeted security fixes: input validation at system boundaries, parameterised queries, secret management, log sanitisation, and TLS/transport configuration. Language-agnostic; reads AGENTS.md for project-specific patterns. Input: security findings from assessment"
4
4
  model: sonnet
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: validate-feature-docs
2
+ name: gaia-validate-feature-docs
3
3
  description: "Validates Requirements and Tech-Spec documents against feature.md. Triggers targeted revision of failing documents if gaps are found. Input: path to feature.md"
4
4
  model: haiku
5
5
  tools: Read, Glob, Grep, Write
@@ -18,7 +18,7 @@ A QA agent that cross-references `feature.md` against `{PREFIX}-Requirements.md`
18
18
  - `feature.md` — source of truth
19
19
  - `{PREFIX}-Requirements.md`
20
20
  - `{PREFIX}-Tech-Spec.md`
21
- 3. If either output document is missing, abort and report: "Cannot validate: `{file}` not found. Run /agent-project-manager first."
21
+ 3. If either output document is missing, abort and report: "Cannot validate: `{file}` not found. Run /implement-feature first."
22
22
 
23
23
  ---
24
24
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: validate-work-breakdown-semantic
2
+ name: gaia-validate-work-breakdown-semantic
3
3
  description: "Semantic validator for Work Breakdown JSON — analyzes task coherence, scope alignment, and estimate realism. Runs after wb-validate.js exits 0. Input: path to {PREFIX}-Work-Breakdown.json"
4
4
  model: sonnet
5
5
  tools: Read, Glob, Grep
@@ -23,14 +23,14 @@ Steps:
23
23
 
24
24
  Suggested agent: <subagent_type>
25
25
  Suggested invocation:
26
- subagent_type: <developer-backend | developer-frontend | developer-testing>
26
+ subagent_type: <gaia-developer-backend | gaia-developer-frontend | gaia-developer-testing>
27
27
  prompt: <feature-md-path> <task-id>
28
28
  ```
29
29
 
30
30
  Domain → agent mapping:
31
- - `DB`, `BE`, `INFRA` → `developer-backend`
32
- - `FE` → `developer-frontend`
33
- - `TEST` → `developer-testing`
31
+ - `DB`, `BE`, `INFRA` → `gaia-developer-backend`
32
+ - `FE` → `gaia-developer-frontend`
33
+ - `TEST` → `gaia-developer-testing`
34
34
 
35
35
  5. If no unblocked task remains, output: `✅ All tasks are either done, in progress, or blocked. Check blockers.`
36
36
 
@@ -157,7 +157,7 @@ Append a horizontal rule (`---`) followed by:
157
157
  |-------|------------|-------|-------------|---------------|-------|---------------|-----------------|----------|
158
158
  | {agent} | {scope} | {model} | {est} | {actual} | {±delta} | {est_cost} | {actual_cost} | {Xmin Ys} |
159
159
  ...
160
- | assessment-manager/am-phase1 (orchestrator) | — | sonnet | 80,000 | {actual} | ±{delta} | $0.4320 | ${actual_cost} | {duration} |
160
+ | am-phase1 (orchestrator) | — | sonnet | 80,000 | {actual} | ±{delta} | $0.4320 | ${actual_cost} | {duration} |
161
161
  ```
162
162
 
163
163
  Column rules:
@@ -3,10 +3,10 @@ description: "Define Feature — reads existing repo context, then grills only o
3
3
  disable-model-invocation: true
4
4
  ---
5
5
 
6
- Spawn the `define-feature` agent, passing through whatever the user provided as a source reference (a backlog entry, ticket path, spec path, or free-text description). If the user gave nothing, pass an empty source.
6
+ Spawn the `gaia-define-feature` agent, passing through whatever the user provided as a source reference (a backlog entry, ticket path, spec path, or free-text description). If the user gave nothing, pass an empty source.
7
7
 
8
8
  ```
9
- subagent_type: define-feature
9
+ subagent_type: gaia-define-feature
10
10
  prompt: |
11
11
  Start the feature definition session.
12
12
  Source reference (may be empty): {{user arguments verbatim}}
@@ -37,7 +37,7 @@ Here's what I know and what's available for you:
37
37
  - `/feature-status`, `/check-docs`, `/next-task`, `/pr-description`
38
38
  - `/assessment-status`
39
39
 
40
- **Specialized agents** (spawnable): project-manager, developer-backend, developer-frontend, developer-testing, review-solution, assessment-manager, and more.
40
+ **Specialized agents** (spawnable): developer-backend, developer-frontend, developer-testing, review-solution, and more.
41
41
 
42
42
  Let me take a look at your workspace to understand the context…
43
43