all-hands-cli 0.1.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.
- package/.allhands/README.md +75 -0
- package/.allhands/agents/compounder.yaml +15 -0
- package/.allhands/agents/coordinator.yaml +17 -0
- package/.allhands/agents/documentor.yaml +15 -0
- package/.allhands/agents/e2e-test-planner.yaml +17 -0
- package/.allhands/agents/emergent.yaml +22 -0
- package/.allhands/agents/executor.yaml +14 -0
- package/.allhands/agents/ideation.yaml +11 -0
- package/.allhands/agents/initiative-steering.yaml +19 -0
- package/.allhands/agents/judge.yaml +13 -0
- package/.allhands/agents/planner.yaml +19 -0
- package/.allhands/agents/pr-reviewer.yaml +15 -0
- package/.allhands/docs.json +5 -0
- package/.allhands/docs.local.json +26 -0
- package/.allhands/flows/COMPOUNDING.md +203 -0
- package/.allhands/flows/COORDINATION.md +89 -0
- package/.allhands/flows/CORE.md +87 -0
- package/.allhands/flows/DOCUMENTATION.md +218 -0
- package/.allhands/flows/E2E_TEST_PLAN_BUILDING.md +140 -0
- package/.allhands/flows/EMERGENT_PLANNING.md +57 -0
- package/.allhands/flows/IDEATION_SCOPING.md +154 -0
- package/.allhands/flows/INITIATIVE_STEERING.md +110 -0
- package/.allhands/flows/JUDGE_REVIEWING.md +79 -0
- package/.allhands/flows/PROMPT_TASK_EXECUTION.md +68 -0
- package/.allhands/flows/PR_REVIEWING.md +43 -0
- package/.allhands/flows/SPEC_PLANNING.md +216 -0
- package/.allhands/flows/harness/WRITING_HARNESS_FLOWS.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_KNOWLEDGE.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_ORCHESTRATION.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_SKILLS.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_TOOLS.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_VALIDATION_TOOLING.md +27 -0
- package/.allhands/flows/shared/CODEBASE_UNDERSTANDING.md +72 -0
- package/.allhands/flows/shared/CREATE_HARNESS_SPEC.md +48 -0
- package/.allhands/flows/shared/CREATE_SPEC.md +41 -0
- package/.allhands/flows/shared/CREATE_VALIDATION_TOOLING_SPEC.md +70 -0
- package/.allhands/flows/shared/DOCUMENTATION_DISCOVERY.md +123 -0
- package/.allhands/flows/shared/DOCUMENTATION_WRITER.md +101 -0
- package/.allhands/flows/shared/EMERGENT_REFINEMENT_ANALYSIS.md +76 -0
- package/.allhands/flows/shared/EXTERNAL_TECH_GUIDANCE.md +97 -0
- package/.allhands/flows/shared/IDEATION_CODEBASE_GROUNDING.md +49 -0
- package/.allhands/flows/shared/PLAN_DEEPENING.md +152 -0
- package/.allhands/flows/shared/PROMPT_TASKS_CURATION.md +113 -0
- package/.allhands/flows/shared/PROMPT_VALIDATION_REVIEW.MD +99 -0
- package/.allhands/flows/shared/QUICK_PREMORTEM.md +70 -0
- package/.allhands/flows/shared/RESEARCH_GUIDANCE.md +38 -0
- package/.allhands/flows/shared/REVIEW_OPTIONS_BREAKDOWN.md +68 -0
- package/.allhands/flows/shared/SKILL_EXTRACTION.md +84 -0
- package/.allhands/flows/shared/SPEC_FLOW_ANALYSIS.md +119 -0
- package/.allhands/flows/shared/TDD_WORKFLOW.md +109 -0
- package/.allhands/flows/shared/UTILIZE_VALIDATION_TOOLING.md +84 -0
- package/.allhands/flows/shared/WRITING_HARNESS_FLOWS.md +11 -0
- package/.allhands/flows/shared/WRITING_HARNESS_MCP_TOOLS.md +84 -0
- package/.allhands/flows/shared/jury/ARCHITECTURE_REVIEW.md +91 -0
- package/.allhands/flows/shared/jury/BEST_PRACTICES_REVIEW.md +80 -0
- package/.allhands/flows/shared/jury/CLAIM_VERIFICATION_REVIEW.md +101 -0
- package/.allhands/flows/shared/jury/EXPECTATIONS_FIT_REVIEW.md +78 -0
- package/.allhands/flows/shared/jury/MAINTAINABILITY_REVIEW.md +110 -0
- package/.allhands/flows/shared/jury/PROMPTS_EXPECTATIONS_FIT.md +74 -0
- package/.allhands/flows/shared/jury/PROMPTS_FLOW_ANALYSIS.md +92 -0
- package/.allhands/flows/shared/jury/PROMPTS_YAGNI.md +78 -0
- package/.allhands/flows/shared/jury/PROMPT_PREMORTEM.md +125 -0
- package/.allhands/flows/shared/jury/SECURITY_REVIEW.md +86 -0
- package/.allhands/flows/shared/jury/YAGNI_REVIEW.md +82 -0
- package/.allhands/flows/wip/DEBUG_INVESTIGATION.md +162 -0
- package/.allhands/flows/wip/MEMORY_RECALL.md +62 -0
- package/.allhands/harness/ah +131 -0
- package/.allhands/harness/package-lock.json +5292 -0
- package/.allhands/harness/package.json +52 -0
- package/.allhands/harness/src/__tests__/e2e/commands.test.ts +307 -0
- package/.allhands/harness/src/__tests__/e2e/event-loop.test.ts +539 -0
- package/.allhands/harness/src/__tests__/e2e/hooks.test.ts +427 -0
- package/.allhands/harness/src/__tests__/e2e/new-initiative-routing.test.ts +137 -0
- package/.allhands/harness/src/__tests__/e2e/run-e2e.ts +109 -0
- package/.allhands/harness/src/__tests__/e2e/specs-type.test.ts +210 -0
- package/.allhands/harness/src/__tests__/e2e/validation-hooks.test.ts +669 -0
- package/.allhands/harness/src/__tests__/e2e/validation-path-consistency.test.ts +354 -0
- package/.allhands/harness/src/__tests__/e2e/validation.test.ts +528 -0
- package/.allhands/harness/src/__tests__/harness/assertions.ts +318 -0
- package/.allhands/harness/src/__tests__/harness/cli-runner.ts +359 -0
- package/.allhands/harness/src/__tests__/harness/fixture.ts +384 -0
- package/.allhands/harness/src/__tests__/harness/hook-runner.ts +411 -0
- package/.allhands/harness/src/__tests__/harness/index.ts +122 -0
- package/.allhands/harness/src/cli.ts +36 -0
- package/.allhands/harness/src/commands/complexity.ts +177 -0
- package/.allhands/harness/src/commands/context7.ts +202 -0
- package/.allhands/harness/src/commands/docs.ts +557 -0
- package/.allhands/harness/src/commands/hooks.ts +24 -0
- package/.allhands/harness/src/commands/index.ts +51 -0
- package/.allhands/harness/src/commands/knowledge.ts +382 -0
- package/.allhands/harness/src/commands/memories.ts +302 -0
- package/.allhands/harness/src/commands/notify.ts +61 -0
- package/.allhands/harness/src/commands/oracle.ts +158 -0
- package/.allhands/harness/src/commands/perplexity.ts +220 -0
- package/.allhands/harness/src/commands/planning.ts +245 -0
- package/.allhands/harness/src/commands/schema.ts +73 -0
- package/.allhands/harness/src/commands/skills.ts +128 -0
- package/.allhands/harness/src/commands/solutions.ts +353 -0
- package/.allhands/harness/src/commands/spawn.ts +158 -0
- package/.allhands/harness/src/commands/specs.ts +532 -0
- package/.allhands/harness/src/commands/tavily.ts +226 -0
- package/.allhands/harness/src/commands/tools.ts +579 -0
- package/.allhands/harness/src/commands/trace.ts +327 -0
- package/.allhands/harness/src/commands/tui.ts +960 -0
- package/.allhands/harness/src/commands/validate.ts +143 -0
- package/.allhands/harness/src/commands/validation-tools.ts +108 -0
- package/.allhands/harness/src/hooks/context.ts +1442 -0
- package/.allhands/harness/src/hooks/enforcement.ts +170 -0
- package/.allhands/harness/src/hooks/index.ts +54 -0
- package/.allhands/harness/src/hooks/lifecycle.ts +229 -0
- package/.allhands/harness/src/hooks/notification.ts +104 -0
- package/.allhands/harness/src/hooks/observability.ts +551 -0
- package/.allhands/harness/src/hooks/session.ts +88 -0
- package/.allhands/harness/src/hooks/shared.ts +815 -0
- package/.allhands/harness/src/hooks/transcript-parser.ts +208 -0
- package/.allhands/harness/src/hooks/validation.ts +617 -0
- package/.allhands/harness/src/lib/__tests__/ctags.test.ts +244 -0
- package/.allhands/harness/src/lib/__tests__/docs-validation.test.ts +344 -0
- package/.allhands/harness/src/lib/__tests__/mcp-runtime.test.ts +190 -0
- package/.allhands/harness/src/lib/__tests__/schema.test.ts +861 -0
- package/.allhands/harness/src/lib/base-command.ts +198 -0
- package/.allhands/harness/src/lib/cli-daemon.ts +343 -0
- package/.allhands/harness/src/lib/compaction.ts +313 -0
- package/.allhands/harness/src/lib/ctags.ts +497 -0
- package/.allhands/harness/src/lib/docs-validation.ts +907 -0
- package/.allhands/harness/src/lib/event-loop.ts +662 -0
- package/.allhands/harness/src/lib/flows.ts +155 -0
- package/.allhands/harness/src/lib/git.ts +276 -0
- package/.allhands/harness/src/lib/knowledge-worker.ts +72 -0
- package/.allhands/harness/src/lib/knowledge.ts +810 -0
- package/.allhands/harness/src/lib/llm.ts +255 -0
- package/.allhands/harness/src/lib/mcp-client.ts +432 -0
- package/.allhands/harness/src/lib/mcp-daemon.ts +486 -0
- package/.allhands/harness/src/lib/mcp-runtime.ts +418 -0
- package/.allhands/harness/src/lib/notification.ts +115 -0
- package/.allhands/harness/src/lib/opencode/index.ts +70 -0
- package/.allhands/harness/src/lib/opencode/profiles.ts +300 -0
- package/.allhands/harness/src/lib/opencode/prompts/codesearch.md +98 -0
- package/.allhands/harness/src/lib/opencode/prompts/knowledge-aggregator.md +67 -0
- package/.allhands/harness/src/lib/opencode/runner.ts +281 -0
- package/.allhands/harness/src/lib/oracle.ts +926 -0
- package/.allhands/harness/src/lib/planning-utils.ts +150 -0
- package/.allhands/harness/src/lib/planning.ts +605 -0
- package/.allhands/harness/src/lib/pr-review.ts +225 -0
- package/.allhands/harness/src/lib/prompts.ts +522 -0
- package/.allhands/harness/src/lib/schema.ts +418 -0
- package/.allhands/harness/src/lib/schemas/agent-profile.ts +141 -0
- package/.allhands/harness/src/lib/schemas/template-vars.ts +138 -0
- package/.allhands/harness/src/lib/session.ts +164 -0
- package/.allhands/harness/src/lib/specs.ts +348 -0
- package/.allhands/harness/src/lib/tldr.ts +829 -0
- package/.allhands/harness/src/lib/tmux.ts +1051 -0
- package/.allhands/harness/src/lib/trace-store.ts +714 -0
- package/.allhands/harness/src/mcp/__tests__/index.test.ts +46 -0
- package/.allhands/harness/src/mcp/_template.ts +47 -0
- package/.allhands/harness/src/mcp/filesystem.ts +33 -0
- package/.allhands/harness/src/mcp/index.ts +69 -0
- package/.allhands/harness/src/mcp/playwright.ts +34 -0
- package/.allhands/harness/src/mcp/xcodebuild.ts +29 -0
- package/.allhands/harness/src/schemas/docs.schema.json +44 -0
- package/.allhands/harness/src/schemas/settings.schema.json +214 -0
- package/.allhands/harness/src/tui/actions.ts +227 -0
- package/.allhands/harness/src/tui/file-viewer-modal.ts +270 -0
- package/.allhands/harness/src/tui/index.ts +1574 -0
- package/.allhands/harness/src/tui/modal.ts +232 -0
- package/.allhands/harness/src/tui/prompts-pane.ts +186 -0
- package/.allhands/harness/src/tui/status-pane.ts +434 -0
- package/.allhands/harness/tsconfig.json +22 -0
- package/.allhands/harness/vitest.config.ts +13 -0
- package/.allhands/pillars.md +33 -0
- package/.allhands/principles.md +88 -0
- package/.allhands/schemas/alignment.yaml +51 -0
- package/.allhands/schemas/documentation.yaml +10 -0
- package/.allhands/schemas/prompt.yaml +92 -0
- package/.allhands/schemas/skill.yaml +34 -0
- package/.allhands/schemas/solution.yaml +131 -0
- package/.allhands/schemas/spec.yaml +67 -0
- package/.allhands/schemas/validation-suite.yaml +49 -0
- package/.allhands/schemas/workflow.yaml +51 -0
- package/.allhands/settings.json +57 -0
- package/.allhands/skills/claude-code-patterns/SKILL.md +60 -0
- package/.allhands/skills/claude-code-patterns/docs/context-hygiene.md +19 -0
- package/.allhands/skills/harness-maintenance/SKILL.md +449 -0
- package/.allhands/skills/harness-maintenance/references/core-architecture.md +187 -0
- package/.allhands/skills/harness-maintenance/references/harness-skills.md +87 -0
- package/.allhands/skills/harness-maintenance/references/knowledge-compounding.md +78 -0
- package/.allhands/skills/harness-maintenance/references/tools-commands-mcp-hooks.md +115 -0
- package/.allhands/skills/harness-maintenance/references/validation-tooling.md +77 -0
- package/.allhands/skills/harness-maintenance/references/writing-flows.md +84 -0
- package/.allhands/validation/browser-automation.md +109 -0
- package/.allhands/validation/xcode-automation.md +195 -0
- package/.allhands/workflows/documentation.md +86 -0
- package/.allhands/workflows/investigation.md +81 -0
- package/.allhands/workflows/milestone.md +91 -0
- package/.allhands/workflows/optimization.md +85 -0
- package/.allhands/workflows/refactor.md +99 -0
- package/.allhands/workflows/triage.md +81 -0
- package/.claude/README.md +1 -0
- package/.claude/agents/explorer.md +10 -0
- package/.claude/agents/researcher.md +11 -0
- package/.claude/agents/task-runner.md +8 -0
- package/.claude/settings.json +231 -0
- package/.env.ai.example +7 -0
- package/.github/workflows/npm-publish.yml +69 -0
- package/.internal.json +45 -0
- package/.tldr/config.json +11 -0
- package/.tldrignore +90 -0
- package/CLAUDE.md +6 -0
- package/README.md +98 -0
- package/bin/sync-cli.js +7552 -0
- package/concerns.md +7 -0
- package/docs/README.md +41 -0
- package/docs/agents/README.md +24 -0
- package/docs/agents/agent-configuration-system.md +86 -0
- package/docs/agents/execution-agents.md +50 -0
- package/docs/agents/knowledge-agents.md +61 -0
- package/docs/agents/orchestration-agent.md +57 -0
- package/docs/agents/planning-agents.md +84 -0
- package/docs/agents/quality-review-agents.md +67 -0
- package/docs/agents/workflow-agent-orchestration.md +69 -0
- package/docs/flows/README.md +44 -0
- package/docs/flows/compounding.md +126 -0
- package/docs/flows/coordination.md +72 -0
- package/docs/flows/core-harness-integration.md +63 -0
- package/docs/flows/documentation-orchestration.md +98 -0
- package/docs/flows/e2e-test-plan-building.md +83 -0
- package/docs/flows/emergent-refinement.md +104 -0
- package/docs/flows/flow-authoring-and-mcp-tools.md +89 -0
- package/docs/flows/judge-reviewing.md +112 -0
- package/docs/flows/plan-deepening-and-research.md +107 -0
- package/docs/flows/plan-review-jury.md +114 -0
- package/docs/flows/pr-reviewing.md +54 -0
- package/docs/flows/prompt-task-execution.md +119 -0
- package/docs/flows/spec-planning.md +162 -0
- package/docs/flows/type-specific-scoping-flows.md +49 -0
- package/docs/flows/validation-and-skills-integration.md +145 -0
- package/docs/flows/wip/wip-flows.md +102 -0
- package/docs/harness/README.md +23 -0
- package/docs/harness/agent-profiles.md +84 -0
- package/docs/harness/cli/README.md +24 -0
- package/docs/harness/cli/cli-entry-and-command-discovery.md +91 -0
- package/docs/harness/cli/docs-command.md +87 -0
- package/docs/harness/cli/knowledge-command.md +91 -0
- package/docs/harness/cli/minor-cli-commands.md +65 -0
- package/docs/harness/cli/oracle-command.md +113 -0
- package/docs/harness/cli/planning-command.md +95 -0
- package/docs/harness/cli/schema-and-validation-commands.md +154 -0
- package/docs/harness/cli/search-commands.md +97 -0
- package/docs/harness/cli/spawn-command.md +136 -0
- package/docs/harness/cli/specs-command.md +102 -0
- package/docs/harness/cli/tools-command.md +122 -0
- package/docs/harness/cli/trace-command.md +122 -0
- package/docs/harness/cli-daemon.md +92 -0
- package/docs/harness/event-loop.md +184 -0
- package/docs/harness/hooks/README.md +15 -0
- package/docs/harness/hooks/context-hooks.md +96 -0
- package/docs/harness/hooks/lifecycle-and-observability-hooks.md +135 -0
- package/docs/harness/hooks/validation-hooks.md +97 -0
- package/docs/harness/test-harness.md +149 -0
- package/docs/harness/tui.md +176 -0
- package/docs/memories.md +20 -0
- package/docs/solutions/agentic-issues/premature-agent-deletion-tui-action-dependency-20260130.md +49 -0
- package/docs/solutions/agentic-issues/ref-anchor-scope-mismatch-skill-references-20260131.md +55 -0
- package/docs/solutions/agentic-issues/tautological-tests-routing-20260131.md +52 -0
- package/docs/solutions/integration_issue/blocktool-output-format-mismatch-hook-runner-20260130.md +52 -0
- package/docs/solutions/integration_issue/dual-validation-path-divergence-schema-20260130.md +66 -0
- package/docs/solutions/security-issues/unsanitized-domain-path-join-20260131.md +52 -0
- package/docs/solutions/test-failures/event-loop-mock-ordering-checkAgentWindows-20260130.md +63 -0
- package/docs/sync-cli/README.md +19 -0
- package/docs/sync-cli/cli-entrypoint-and-commands.md +39 -0
- package/docs/sync-cli/commands/README.md +11 -0
- package/docs/sync-cli/commands/pull-manifest-command.md +36 -0
- package/docs/sync-cli/commands/push-command.md +84 -0
- package/docs/sync-cli/commands/sync-command.md +71 -0
- package/docs/sync-cli/systems/README.md +14 -0
- package/docs/sync-cli/systems/git-and-github-integration.md +49 -0
- package/docs/sync-cli/systems/interactive-ui.md +43 -0
- package/docs/sync-cli/systems/manifest-and-distribution.md +51 -0
- package/docs/sync-cli/systems/path-resolution.md +42 -0
- package/package.json +46 -0
- package/scripts/install-shim.sh +40 -0
- package/scripts/pre-pack.sh +25 -0
- package/specs/harness-maintenance-skill.spec.md +138 -0
- package/specs/roadmap/git-spec-lifecycle-management.spec.md +113 -0
- package/specs/sync-init-flag.spec.md +117 -0
- package/specs/unified-workflow-orchestration.spec.md +250 -0
- package/specs/validation-tooling-practice.spec.md +98 -0
- package/specs/workflow-domain-configuration.spec.md +265 -0
- package/src/commands/pull-manifest.ts +31 -0
- package/src/commands/push.ts +344 -0
- package/src/commands/sync.ts +289 -0
- package/src/lib/constants.ts +10 -0
- package/src/lib/dotfiles.ts +36 -0
- package/src/lib/fs-utils.ts +18 -0
- package/src/lib/gh.ts +40 -0
- package/src/lib/git.ts +63 -0
- package/src/lib/gitignore.ts +167 -0
- package/src/lib/manifest.ts +121 -0
- package/src/lib/marker-sync.ts +39 -0
- package/src/lib/paths.ts +38 -0
- package/src/lib/target-lines.ts +66 -0
- package/src/lib/ui.ts +78 -0
- package/src/sync-cli.ts +120 -0
- package/target-lines.json +23 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Profile Management
|
|
3
|
+
*
|
|
4
|
+
* Loads agent profiles and builds invocation contexts for TUI-delegated agents.
|
|
5
|
+
* Profiles define: flow, template vars, and message templates for each agent type.
|
|
6
|
+
*
|
|
7
|
+
* This module provides:
|
|
8
|
+
* - Profile loading with Zod validation
|
|
9
|
+
* - Template variable resolution
|
|
10
|
+
* - Context building for agent spawning
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { existsSync, readFileSync, readdirSync } from 'fs';
|
|
14
|
+
import { join, dirname } from 'path';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
import { parse as parseYaml } from 'yaml';
|
|
17
|
+
import {
|
|
18
|
+
RawAgentProfileSchema,
|
|
19
|
+
normalizeProfile,
|
|
20
|
+
validateProfileSemantics,
|
|
21
|
+
type AgentProfile,
|
|
22
|
+
} from '../schemas/agent-profile.js';
|
|
23
|
+
import {
|
|
24
|
+
validateContext,
|
|
25
|
+
type TemplateContext,
|
|
26
|
+
type TemplateVarName,
|
|
27
|
+
} from '../schemas/template-vars.js';
|
|
28
|
+
|
|
29
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
30
|
+
const __dirname = dirname(__filename);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Result of building an agent invocation
|
|
34
|
+
*/
|
|
35
|
+
export interface AgentInvocation {
|
|
36
|
+
/** Environment variables to set for the agent */
|
|
37
|
+
env: Record<string, string>;
|
|
38
|
+
/** Absolute path to the flow file */
|
|
39
|
+
flowPath: string;
|
|
40
|
+
/** Resolved message template (preamble) */
|
|
41
|
+
preamble: string;
|
|
42
|
+
/** The profile used */
|
|
43
|
+
profile: AgentProfile;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Stock environment variables injected for ALL agents.
|
|
48
|
+
* These are derived from context, not defined in profiles.
|
|
49
|
+
*/
|
|
50
|
+
export const STOCK_ENV_VARS = [
|
|
51
|
+
'AGENT_ID',
|
|
52
|
+
'AGENT_NAME',
|
|
53
|
+
'AGENT_TYPE',
|
|
54
|
+
'SPEC_NAME',
|
|
55
|
+
'BRANCH',
|
|
56
|
+
'PROMPT_NUMBER',
|
|
57
|
+
] as const;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get the agents directory path
|
|
61
|
+
* Path: harness/src/lib/opencode/ -> harness/src/lib/ -> harness/src/ -> harness/ -> .allhands/ -> agents/
|
|
62
|
+
*/
|
|
63
|
+
function getAgentsDir(): string {
|
|
64
|
+
return join(__dirname, '..', '..', '..', '..', 'agents');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get the flows directory path
|
|
69
|
+
* Path: harness/src/lib/opencode/ -> harness/src/lib/ -> harness/src/ -> harness/ -> .allhands/ -> flows/
|
|
70
|
+
*/
|
|
71
|
+
function getFlowsDir(): string {
|
|
72
|
+
return join(__dirname, '..', '..', '..', '..', 'flows');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Load an agent profile by name
|
|
77
|
+
*/
|
|
78
|
+
export function loadAgentProfile(name: string): AgentProfile | null {
|
|
79
|
+
const agentsDir = getAgentsDir();
|
|
80
|
+
const profilePath = join(agentsDir, `${name}.yaml`);
|
|
81
|
+
|
|
82
|
+
if (!existsSync(profilePath)) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
const content = readFileSync(profilePath, 'utf-8');
|
|
88
|
+
const rawData = parseYaml(content);
|
|
89
|
+
|
|
90
|
+
// Validate with Zod
|
|
91
|
+
const parseResult = RawAgentProfileSchema.safeParse(rawData);
|
|
92
|
+
|
|
93
|
+
if (!parseResult.success) {
|
|
94
|
+
console.error(`Invalid profile ${name}:`, parseResult.error.format());
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return normalizeProfile(parseResult.data);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
console.error(`Failed to load profile ${name}:`, err);
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* List all available agent profiles
|
|
107
|
+
*/
|
|
108
|
+
export function listAgentProfiles(): string[] {
|
|
109
|
+
const agentsDir = getAgentsDir();
|
|
110
|
+
|
|
111
|
+
if (!existsSync(agentsDir)) {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return readdirSync(agentsDir)
|
|
116
|
+
.filter((f) => f.endsWith('.yaml'))
|
|
117
|
+
.map((f) => f.replace('.yaml', ''));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get all profiles indexed by their TUI action
|
|
122
|
+
*/
|
|
123
|
+
export function getProfilesByTuiAction(): Map<string, AgentProfile[]> {
|
|
124
|
+
const map = new Map<string, AgentProfile[]>();
|
|
125
|
+
const names = listAgentProfiles();
|
|
126
|
+
|
|
127
|
+
for (const name of names) {
|
|
128
|
+
const profile = loadAgentProfile(name);
|
|
129
|
+
if (profile?.tuiAction) {
|
|
130
|
+
const existing = map.get(profile.tuiAction) ?? [];
|
|
131
|
+
existing.push(profile);
|
|
132
|
+
map.set(profile.tuiAction, existing);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return map;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Resolve template variables in a string
|
|
141
|
+
*
|
|
142
|
+
* Replaces ${VAR_NAME} with values from context.
|
|
143
|
+
* Null values are rendered as "null" string.
|
|
144
|
+
* Unresolved variables are left as-is (for debugging visibility).
|
|
145
|
+
*/
|
|
146
|
+
export function resolveTemplate(template: string, context: TemplateContext): string {
|
|
147
|
+
return template.replace(/\$\{([^}]+)\}/g, (match, varName) => {
|
|
148
|
+
const value = context[varName as TemplateVarName];
|
|
149
|
+
if (value === undefined) return match;
|
|
150
|
+
if (value === null) return 'null';
|
|
151
|
+
return value;
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Validate that a profile's flow file exists
|
|
157
|
+
*/
|
|
158
|
+
export function validateProfileFlowExists(profile: AgentProfile): {
|
|
159
|
+
valid: boolean;
|
|
160
|
+
error?: string;
|
|
161
|
+
} {
|
|
162
|
+
const flowsDir = getFlowsDir();
|
|
163
|
+
const flowPath = join(flowsDir, profile.flow);
|
|
164
|
+
|
|
165
|
+
if (!existsSync(flowPath)) {
|
|
166
|
+
return {
|
|
167
|
+
valid: false,
|
|
168
|
+
error: `Flow file not found: ${profile.flow}`,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return { valid: true };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Build a complete agent invocation from profile and context
|
|
177
|
+
*
|
|
178
|
+
* This is the main entry point for spawning agents. It:
|
|
179
|
+
* 1. Validates required template variables are provided
|
|
180
|
+
* 2. Resolves the message template
|
|
181
|
+
* 3. Returns everything needed to spawn the agent
|
|
182
|
+
*
|
|
183
|
+
* @param profile - The agent profile (from loadAgentProfile)
|
|
184
|
+
* @param context - Template variable values
|
|
185
|
+
* @returns AgentInvocation or throws on validation failure
|
|
186
|
+
*/
|
|
187
|
+
export function buildAgentInvocation(
|
|
188
|
+
profile: AgentProfile,
|
|
189
|
+
context: TemplateContext
|
|
190
|
+
): AgentInvocation {
|
|
191
|
+
// Validate required template variables
|
|
192
|
+
const validation = validateContext(context, profile.templateVars);
|
|
193
|
+
|
|
194
|
+
if (!validation.valid) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
`Missing required template variables for agent "${profile.name}": ${validation.errors.join(', ')}`
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Validate flow file exists
|
|
201
|
+
const flowCheck = validateProfileFlowExists(profile);
|
|
202
|
+
if (!flowCheck.valid) {
|
|
203
|
+
throw new Error(`Agent "${profile.name}": ${flowCheck.error}`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Build environment variables
|
|
207
|
+
const env: Record<string, string> = {
|
|
208
|
+
AGENT_NAME: profile.name,
|
|
209
|
+
AGENT_TYPE: profile.name,
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
// Add context values that map to env vars
|
|
213
|
+
if (context.SPEC_NAME) env.SPEC_NAME = context.SPEC_NAME;
|
|
214
|
+
if (context.BRANCH) env.BRANCH = context.BRANCH;
|
|
215
|
+
if (context.PROMPT_NUMBER) env.PROMPT_NUMBER = context.PROMPT_NUMBER;
|
|
216
|
+
|
|
217
|
+
// Resolve flow path
|
|
218
|
+
const flowsDir = getFlowsDir();
|
|
219
|
+
const flowPath = join(flowsDir, profile.flow);
|
|
220
|
+
|
|
221
|
+
// Resolve preamble from message template
|
|
222
|
+
const preamble = profile.messageTemplate
|
|
223
|
+
? resolveTemplate(profile.messageTemplate, context)
|
|
224
|
+
: '';
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
env,
|
|
228
|
+
flowPath,
|
|
229
|
+
preamble,
|
|
230
|
+
profile,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Build invocation for an agent by name
|
|
236
|
+
*
|
|
237
|
+
* Convenience wrapper that loads the profile first.
|
|
238
|
+
*/
|
|
239
|
+
export function buildAgentInvocationByName(
|
|
240
|
+
agentName: string,
|
|
241
|
+
context: TemplateContext
|
|
242
|
+
): AgentInvocation {
|
|
243
|
+
const profile = loadAgentProfile(agentName);
|
|
244
|
+
|
|
245
|
+
if (!profile) {
|
|
246
|
+
throw new Error(`Agent profile not found: ${agentName}`);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return buildAgentInvocation(profile, context);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Load and validate all agent profiles
|
|
254
|
+
*
|
|
255
|
+
* Returns all valid profiles and any validation errors.
|
|
256
|
+
*/
|
|
257
|
+
export function loadAllProfiles(): {
|
|
258
|
+
profiles: AgentProfile[];
|
|
259
|
+
errors: Array<{ name: string; errors: string[]; warnings: string[] }>;
|
|
260
|
+
} {
|
|
261
|
+
const names = listAgentProfiles();
|
|
262
|
+
const profiles: AgentProfile[] = [];
|
|
263
|
+
const errors: Array<{ name: string; errors: string[]; warnings: string[] }> = [];
|
|
264
|
+
|
|
265
|
+
for (const name of names) {
|
|
266
|
+
const profile = loadAgentProfile(name);
|
|
267
|
+
|
|
268
|
+
if (!profile) {
|
|
269
|
+
errors.push({ name, errors: ['Failed to parse profile'], warnings: [] });
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Validate flow exists
|
|
274
|
+
const flowCheck = validateProfileFlowExists(profile);
|
|
275
|
+
|
|
276
|
+
// Validate semantic consistency
|
|
277
|
+
const semanticCheck = validateProfileSemantics(profile);
|
|
278
|
+
|
|
279
|
+
const allErrors: string[] = [];
|
|
280
|
+
const allWarnings: string[] = [...semanticCheck.warnings];
|
|
281
|
+
|
|
282
|
+
if (!flowCheck.valid && flowCheck.error) {
|
|
283
|
+
allErrors.push(flowCheck.error);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
allErrors.push(...semanticCheck.errors);
|
|
287
|
+
|
|
288
|
+
if (allErrors.length > 0 || allWarnings.length > 0) {
|
|
289
|
+
errors.push({ name, errors: allErrors, warnings: allWarnings });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
profiles.push(profile);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return { profiles, errors };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Re-export types
|
|
299
|
+
export type { AgentProfile } from '../schemas/agent-profile.js';
|
|
300
|
+
export type { TemplateContext, TemplateVarName } from '../schemas/template-vars.js';
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Code Search Agent
|
|
2
|
+
|
|
3
|
+
You find relevant code by combining structural (ast-grep), text (ripgrep), and semantic (LSP) search. Return concise, actionable results.
|
|
4
|
+
|
|
5
|
+
## Available Tools
|
|
6
|
+
|
|
7
|
+
**ast-grep MCP tools** - Structural search via AST patterns
|
|
8
|
+
- `sg_search` / `ast-grep_find_code` - find code matching AST patterns
|
|
9
|
+
- Best for: function calls, imports, class definitions, specific constructs
|
|
10
|
+
- Pattern syntax:
|
|
11
|
+
- `$NAME` - named metavariable (single node)
|
|
12
|
+
- `$_` - anonymous metavariable (single node)
|
|
13
|
+
- `$$$` - matches zero or more nodes
|
|
14
|
+
- Examples: `useEffect($$$)`, `import { $_ } from "react"`, `async function $NAME($$$)`
|
|
15
|
+
|
|
16
|
+
**grep** - Text search via ripgrep
|
|
17
|
+
- Best for: string literals, comments, identifiers, regex patterns
|
|
18
|
+
- Fastest for broad text searches
|
|
19
|
+
|
|
20
|
+
**read** - File content retrieval
|
|
21
|
+
- Use after finding files to get surrounding context
|
|
22
|
+
- Specify line ranges when possible to minimize output
|
|
23
|
+
|
|
24
|
+
**lsp** (if available) - Language Server Protocol
|
|
25
|
+
- goToDefinition, findReferences, hover
|
|
26
|
+
- Best for: tracing symbol relationships after finding entry points
|
|
27
|
+
|
|
28
|
+
**glob** - File pattern matching
|
|
29
|
+
- Scope searches to specific directories/extensions
|
|
30
|
+
|
|
31
|
+
## Search Strategy
|
|
32
|
+
|
|
33
|
+
1. **Structural first** (ast-grep MCP): If query implies code patterns (functions, hooks, imports)
|
|
34
|
+
2. **Text fallback** (grep): For string matching, comments, identifiers
|
|
35
|
+
3. **Semantic exploration** (lsp): Trace definitions/references from found matches
|
|
36
|
+
4. **Read for context** (read): Get surrounding code for final results
|
|
37
|
+
|
|
38
|
+
## Budget Awareness
|
|
39
|
+
|
|
40
|
+
You have a soft tool budget. Stay efficient:
|
|
41
|
+
- High-signal tools first
|
|
42
|
+
- Avoid redundant searches (don't grep what you already found structurally)
|
|
43
|
+
- Read only when you need full context
|
|
44
|
+
- Track usage in dev_notes
|
|
45
|
+
|
|
46
|
+
## Output Format
|
|
47
|
+
|
|
48
|
+
Return ONLY valid JSON:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"results": [
|
|
53
|
+
{
|
|
54
|
+
"file": "src/components/Button.tsx",
|
|
55
|
+
"line_start": 45,
|
|
56
|
+
"line_end": 52,
|
|
57
|
+
"code": "export function Button({ onClick }) {\n return <button onClick={onClick} />;\n}",
|
|
58
|
+
"relevance": "high",
|
|
59
|
+
"match_type": "structural",
|
|
60
|
+
"context": "Button component with onClick handler"
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"warnings": [],
|
|
64
|
+
"dev_notes": {
|
|
65
|
+
"tool_budget_used": 4,
|
|
66
|
+
"tools_invoked": ["ast-grep_find_code", "grep"],
|
|
67
|
+
"tools_failed": []
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Field Guidelines
|
|
73
|
+
|
|
74
|
+
**results** (ranked by relevance, max 10):
|
|
75
|
+
- `file`: Relative path from project root
|
|
76
|
+
- `line_start` / `line_end`: 1-indexed line range
|
|
77
|
+
- `code`: Actual code snippet (keep concise, 1-20 lines)
|
|
78
|
+
- `relevance`: high (exact match), medium (related), low (tangential)
|
|
79
|
+
- `match_type`: structural | text | semantic
|
|
80
|
+
- `context`: Why this matches (1 sentence)
|
|
81
|
+
|
|
82
|
+
**warnings** (array):
|
|
83
|
+
- Tool unavailability: "ast-grep MCP not responding, using grep fallback"
|
|
84
|
+
- Search limitations: "exceeded budget, results may be incomplete"
|
|
85
|
+
- Fallback actions: "used grep instead of ast-grep for pattern search"
|
|
86
|
+
|
|
87
|
+
**dev_notes** (diagnostics):
|
|
88
|
+
- `tool_budget_used`: Actual tool calls made
|
|
89
|
+
- `tools_invoked`: Which tools were used
|
|
90
|
+
- `tools_failed`: Tools that returned errors (include error message)
|
|
91
|
+
|
|
92
|
+
## Anti-patterns
|
|
93
|
+
|
|
94
|
+
- Returning entire files instead of relevant sections
|
|
95
|
+
- Not using structural search when query implies patterns
|
|
96
|
+
- Making excessive tool calls beyond budget
|
|
97
|
+
- Generic results not grounded in actual code matches
|
|
98
|
+
- Missing context explanation for relevance
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Knowledge Aggregator
|
|
2
|
+
|
|
3
|
+
You synthesize documentation into codebase-grounded answers. The caller is exploring a codebase - they need to understand **what exists**, **why it was built that way**, and **where to look**.
|
|
4
|
+
|
|
5
|
+
## Core Principle
|
|
6
|
+
|
|
7
|
+
Never answer generically. Every insight must reference concrete codebase implementations:
|
|
8
|
+
- BAD: "An agent is a specialized execution context..."
|
|
9
|
+
- GOOD: "Agents in this codebase are defined in `.allhands/agents/` with configs that scope their tools - see `executor.yaml` for the pattern of defining agent profiles with flows and env vars"
|
|
10
|
+
|
|
11
|
+
## Input Format
|
|
12
|
+
|
|
13
|
+
You receive:
|
|
14
|
+
1. A user query about the codebase
|
|
15
|
+
2. Full results: Docs with complete content (high similarity)
|
|
16
|
+
3. Minimized results: Docs with metadata only (may need expansion)
|
|
17
|
+
|
|
18
|
+
## Expansion Protocol
|
|
19
|
+
|
|
20
|
+
Need content from a minimized result? Output:
|
|
21
|
+
```
|
|
22
|
+
EXPAND: <resource_path>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
You'll receive the content. Max 3 expansions. Only expand if description suggests direct relevance.
|
|
26
|
+
|
|
27
|
+
## Output Format
|
|
28
|
+
|
|
29
|
+
Return ONLY valid JSON:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"insight": "Codebase-grounded answer: what pattern exists, why it was chosen, how it's used. Include best practices if query implies implementation intent. 2-4 sentences max.",
|
|
34
|
+
"lsp_entry_points": [
|
|
35
|
+
{
|
|
36
|
+
"file": "path/to/implementation.ts",
|
|
37
|
+
"symbol": "functionOrClassName",
|
|
38
|
+
"why": "Brief reason main agent should check this"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"design_notes": ["Relevant architectural decisions or tradeoffs from docs"]
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Field Guidelines
|
|
46
|
+
|
|
47
|
+
**insight**:
|
|
48
|
+
- Ground every statement in the codebase
|
|
49
|
+
- If query implies they want to implement something, include the recommended approach
|
|
50
|
+
- Mention specific files/patterns by name
|
|
51
|
+
- Include "best practice: X" when docs encode conventions
|
|
52
|
+
|
|
53
|
+
**lsp_entry_points** (max 5, ranked by relevance):
|
|
54
|
+
- `file`: Path to code file (from doc's `relevant_files` or inline references like `[ref:path:symbol:hash]`)
|
|
55
|
+
- `symbol`: Function/class/variable name if known from doc references, null otherwise
|
|
56
|
+
- `why`: One sentence - why should they look here? What will they find?
|
|
57
|
+
|
|
58
|
+
**design_notes** (optional, max 2):
|
|
59
|
+
- Only include if docs explicitly discuss design rationale
|
|
60
|
+
- Format: "[Decision]: [Rationale]" e.g. "Least-privilege tooling: agents receive only tools for their function to prevent cross-domain actions"
|
|
61
|
+
|
|
62
|
+
## Anti-patterns
|
|
63
|
+
|
|
64
|
+
- Generic definitions not tied to this codebase
|
|
65
|
+
- Listing every file mentioned (keep only most relevant)
|
|
66
|
+
- Excerpts without actionability
|
|
67
|
+
- Restating the query as the answer
|