@renseiai/agentfactory 0.8.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/LICENSE +21 -0
- package/README.md +125 -0
- package/dist/src/config/index.d.ts +3 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js +1 -0
- package/dist/src/config/repository-config.d.ts +44 -0
- package/dist/src/config/repository-config.d.ts.map +1 -0
- package/dist/src/config/repository-config.js +88 -0
- package/dist/src/config/repository-config.test.d.ts +2 -0
- package/dist/src/config/repository-config.test.d.ts.map +1 -0
- package/dist/src/config/repository-config.test.js +249 -0
- package/dist/src/deployment/deployment-checker.d.ts +110 -0
- package/dist/src/deployment/deployment-checker.d.ts.map +1 -0
- package/dist/src/deployment/deployment-checker.js +242 -0
- package/dist/src/deployment/index.d.ts +3 -0
- package/dist/src/deployment/index.d.ts.map +1 -0
- package/dist/src/deployment/index.js +2 -0
- package/dist/src/frontend/index.d.ts +2 -0
- package/dist/src/frontend/index.d.ts.map +1 -0
- package/dist/src/frontend/index.js +1 -0
- package/dist/src/frontend/types.d.ts +106 -0
- package/dist/src/frontend/types.d.ts.map +1 -0
- package/dist/src/frontend/types.js +11 -0
- package/dist/src/governor/decision-engine.d.ts +52 -0
- package/dist/src/governor/decision-engine.d.ts.map +1 -0
- package/dist/src/governor/decision-engine.js +220 -0
- package/dist/src/governor/decision-engine.test.d.ts +2 -0
- package/dist/src/governor/decision-engine.test.d.ts.map +1 -0
- package/dist/src/governor/decision-engine.test.js +629 -0
- package/dist/src/governor/event-bus.d.ts +43 -0
- package/dist/src/governor/event-bus.d.ts.map +1 -0
- package/dist/src/governor/event-bus.js +8 -0
- package/dist/src/governor/event-deduplicator.d.ts +43 -0
- package/dist/src/governor/event-deduplicator.d.ts.map +1 -0
- package/dist/src/governor/event-deduplicator.js +53 -0
- package/dist/src/governor/event-driven-governor.d.ts +131 -0
- package/dist/src/governor/event-driven-governor.d.ts.map +1 -0
- package/dist/src/governor/event-driven-governor.js +379 -0
- package/dist/src/governor/event-driven-governor.test.d.ts +2 -0
- package/dist/src/governor/event-driven-governor.test.d.ts.map +1 -0
- package/dist/src/governor/event-driven-governor.test.js +673 -0
- package/dist/src/governor/event-types.d.ts +78 -0
- package/dist/src/governor/event-types.d.ts.map +1 -0
- package/dist/src/governor/event-types.js +32 -0
- package/dist/src/governor/governor-types.d.ts +82 -0
- package/dist/src/governor/governor-types.d.ts.map +1 -0
- package/dist/src/governor/governor-types.js +21 -0
- package/dist/src/governor/governor.d.ts +100 -0
- package/dist/src/governor/governor.d.ts.map +1 -0
- package/dist/src/governor/governor.js +262 -0
- package/dist/src/governor/governor.test.d.ts +2 -0
- package/dist/src/governor/governor.test.d.ts.map +1 -0
- package/dist/src/governor/governor.test.js +514 -0
- package/dist/src/governor/human-touchpoints.d.ts +131 -0
- package/dist/src/governor/human-touchpoints.d.ts.map +1 -0
- package/dist/src/governor/human-touchpoints.js +251 -0
- package/dist/src/governor/human-touchpoints.test.d.ts +2 -0
- package/dist/src/governor/human-touchpoints.test.d.ts.map +1 -0
- package/dist/src/governor/human-touchpoints.test.js +366 -0
- package/dist/src/governor/in-memory-event-bus.d.ts +29 -0
- package/dist/src/governor/in-memory-event-bus.d.ts.map +1 -0
- package/dist/src/governor/in-memory-event-bus.js +79 -0
- package/dist/src/governor/index.d.ts +14 -0
- package/dist/src/governor/index.d.ts.map +1 -0
- package/dist/src/governor/index.js +13 -0
- package/dist/src/governor/override-parser.d.ts +60 -0
- package/dist/src/governor/override-parser.d.ts.map +1 -0
- package/dist/src/governor/override-parser.js +98 -0
- package/dist/src/governor/override-parser.test.d.ts +2 -0
- package/dist/src/governor/override-parser.test.d.ts.map +1 -0
- package/dist/src/governor/override-parser.test.js +312 -0
- package/dist/src/governor/platform-adapter.d.ts +69 -0
- package/dist/src/governor/platform-adapter.d.ts.map +1 -0
- package/dist/src/governor/platform-adapter.js +11 -0
- package/dist/src/governor/processing-state.d.ts +66 -0
- package/dist/src/governor/processing-state.d.ts.map +1 -0
- package/dist/src/governor/processing-state.js +43 -0
- package/dist/src/governor/processing-state.test.d.ts +2 -0
- package/dist/src/governor/processing-state.test.d.ts.map +1 -0
- package/dist/src/governor/processing-state.test.js +96 -0
- package/dist/src/governor/top-of-funnel.d.ts +118 -0
- package/dist/src/governor/top-of-funnel.d.ts.map +1 -0
- package/dist/src/governor/top-of-funnel.js +168 -0
- package/dist/src/governor/top-of-funnel.test.d.ts +2 -0
- package/dist/src/governor/top-of-funnel.test.d.ts.map +1 -0
- package/dist/src/governor/top-of-funnel.test.js +331 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +10 -0
- package/dist/src/linear-cli.d.ts +38 -0
- package/dist/src/linear-cli.d.ts.map +1 -0
- package/dist/src/linear-cli.js +674 -0
- package/dist/src/logger.d.ts +117 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +430 -0
- package/dist/src/manifest/generate.d.ts +20 -0
- package/dist/src/manifest/generate.d.ts.map +1 -0
- package/dist/src/manifest/generate.js +65 -0
- package/dist/src/manifest/index.d.ts +4 -0
- package/dist/src/manifest/index.d.ts.map +1 -0
- package/dist/src/manifest/index.js +2 -0
- package/dist/src/manifest/route-manifest.d.ts +34 -0
- package/dist/src/manifest/route-manifest.d.ts.map +1 -0
- package/dist/src/manifest/route-manifest.js +148 -0
- package/dist/src/orchestrator/activity-emitter.d.ts +119 -0
- package/dist/src/orchestrator/activity-emitter.d.ts.map +1 -0
- package/dist/src/orchestrator/activity-emitter.js +306 -0
- package/dist/src/orchestrator/api-activity-emitter.d.ts +167 -0
- package/dist/src/orchestrator/api-activity-emitter.d.ts.map +1 -0
- package/dist/src/orchestrator/api-activity-emitter.js +417 -0
- package/dist/src/orchestrator/heartbeat-writer.d.ts +57 -0
- package/dist/src/orchestrator/heartbeat-writer.d.ts.map +1 -0
- package/dist/src/orchestrator/heartbeat-writer.js +137 -0
- package/dist/src/orchestrator/index.d.ts +20 -0
- package/dist/src/orchestrator/index.d.ts.map +1 -0
- package/dist/src/orchestrator/index.js +22 -0
- package/dist/src/orchestrator/log-analyzer.d.ts +160 -0
- package/dist/src/orchestrator/log-analyzer.d.ts.map +1 -0
- package/dist/src/orchestrator/log-analyzer.js +572 -0
- package/dist/src/orchestrator/log-config.d.ts +39 -0
- package/dist/src/orchestrator/log-config.d.ts.map +1 -0
- package/dist/src/orchestrator/log-config.js +45 -0
- package/dist/src/orchestrator/orchestrator.d.ts +316 -0
- package/dist/src/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/src/orchestrator/orchestrator.js +3290 -0
- package/dist/src/orchestrator/parse-work-result.d.ts +16 -0
- package/dist/src/orchestrator/parse-work-result.d.ts.map +1 -0
- package/dist/src/orchestrator/parse-work-result.js +135 -0
- package/dist/src/orchestrator/parse-work-result.test.d.ts +2 -0
- package/dist/src/orchestrator/parse-work-result.test.d.ts.map +1 -0
- package/dist/src/orchestrator/parse-work-result.test.js +234 -0
- package/dist/src/orchestrator/progress-logger.d.ts +72 -0
- package/dist/src/orchestrator/progress-logger.d.ts.map +1 -0
- package/dist/src/orchestrator/progress-logger.js +135 -0
- package/dist/src/orchestrator/session-logger.d.ts +159 -0
- package/dist/src/orchestrator/session-logger.d.ts.map +1 -0
- package/dist/src/orchestrator/session-logger.js +275 -0
- package/dist/src/orchestrator/state-recovery.d.ts +96 -0
- package/dist/src/orchestrator/state-recovery.d.ts.map +1 -0
- package/dist/src/orchestrator/state-recovery.js +302 -0
- package/dist/src/orchestrator/state-types.d.ts +165 -0
- package/dist/src/orchestrator/state-types.d.ts.map +1 -0
- package/dist/src/orchestrator/state-types.js +7 -0
- package/dist/src/orchestrator/stream-parser.d.ts +151 -0
- package/dist/src/orchestrator/stream-parser.d.ts.map +1 -0
- package/dist/src/orchestrator/stream-parser.js +137 -0
- package/dist/src/orchestrator/types.d.ts +232 -0
- package/dist/src/orchestrator/types.d.ts.map +1 -0
- package/dist/src/orchestrator/types.js +4 -0
- package/dist/src/orchestrator/validate-git-remote.test.d.ts +2 -0
- package/dist/src/orchestrator/validate-git-remote.test.d.ts.map +1 -0
- package/dist/src/orchestrator/validate-git-remote.test.js +61 -0
- package/dist/src/providers/a2a-auth.d.ts +81 -0
- package/dist/src/providers/a2a-auth.d.ts.map +1 -0
- package/dist/src/providers/a2a-auth.js +188 -0
- package/dist/src/providers/a2a-auth.test.d.ts +2 -0
- package/dist/src/providers/a2a-auth.test.d.ts.map +1 -0
- package/dist/src/providers/a2a-auth.test.js +232 -0
- package/dist/src/providers/a2a-provider.d.ts +254 -0
- package/dist/src/providers/a2a-provider.d.ts.map +1 -0
- package/dist/src/providers/a2a-provider.integration.test.d.ts +9 -0
- package/dist/src/providers/a2a-provider.integration.test.d.ts.map +1 -0
- package/dist/src/providers/a2a-provider.integration.test.js +665 -0
- package/dist/src/providers/a2a-provider.js +811 -0
- package/dist/src/providers/a2a-provider.test.d.ts +2 -0
- package/dist/src/providers/a2a-provider.test.d.ts.map +1 -0
- package/dist/src/providers/a2a-provider.test.js +681 -0
- package/dist/src/providers/amp-provider.d.ts +20 -0
- package/dist/src/providers/amp-provider.d.ts.map +1 -0
- package/dist/src/providers/amp-provider.js +24 -0
- package/dist/src/providers/claude-provider.d.ts +18 -0
- package/dist/src/providers/claude-provider.d.ts.map +1 -0
- package/dist/src/providers/claude-provider.js +437 -0
- package/dist/src/providers/codex-provider.d.ts +133 -0
- package/dist/src/providers/codex-provider.d.ts.map +1 -0
- package/dist/src/providers/codex-provider.js +381 -0
- package/dist/src/providers/codex-provider.test.d.ts +2 -0
- package/dist/src/providers/codex-provider.test.d.ts.map +1 -0
- package/dist/src/providers/codex-provider.test.js +387 -0
- package/dist/src/providers/index.d.ts +44 -0
- package/dist/src/providers/index.d.ts.map +1 -0
- package/dist/src/providers/index.js +85 -0
- package/dist/src/providers/spring-ai-provider.d.ts +90 -0
- package/dist/src/providers/spring-ai-provider.d.ts.map +1 -0
- package/dist/src/providers/spring-ai-provider.integration.test.d.ts +13 -0
- package/dist/src/providers/spring-ai-provider.integration.test.d.ts.map +1 -0
- package/dist/src/providers/spring-ai-provider.integration.test.js +351 -0
- package/dist/src/providers/spring-ai-provider.js +317 -0
- package/dist/src/providers/spring-ai-provider.test.d.ts +2 -0
- package/dist/src/providers/spring-ai-provider.test.d.ts.map +1 -0
- package/dist/src/providers/spring-ai-provider.test.js +200 -0
- package/dist/src/providers/types.d.ts +165 -0
- package/dist/src/providers/types.d.ts.map +1 -0
- package/dist/src/providers/types.js +13 -0
- package/dist/src/templates/adapters.d.ts +51 -0
- package/dist/src/templates/adapters.d.ts.map +1 -0
- package/dist/src/templates/adapters.js +104 -0
- package/dist/src/templates/adapters.test.d.ts +2 -0
- package/dist/src/templates/adapters.test.d.ts.map +1 -0
- package/dist/src/templates/adapters.test.js +165 -0
- package/dist/src/templates/agent-definition.d.ts +85 -0
- package/dist/src/templates/agent-definition.d.ts.map +1 -0
- package/dist/src/templates/agent-definition.js +97 -0
- package/dist/src/templates/agent-definition.test.d.ts +2 -0
- package/dist/src/templates/agent-definition.test.d.ts.map +1 -0
- package/dist/src/templates/agent-definition.test.js +209 -0
- package/dist/src/templates/index.d.ts +14 -0
- package/dist/src/templates/index.d.ts.map +1 -0
- package/dist/src/templates/index.js +11 -0
- package/dist/src/templates/loader.d.ts +41 -0
- package/dist/src/templates/loader.d.ts.map +1 -0
- package/dist/src/templates/loader.js +114 -0
- package/dist/src/templates/registry.d.ts +80 -0
- package/dist/src/templates/registry.d.ts.map +1 -0
- package/dist/src/templates/registry.js +177 -0
- package/dist/src/templates/registry.test.d.ts +2 -0
- package/dist/src/templates/registry.test.d.ts.map +1 -0
- package/dist/src/templates/registry.test.js +198 -0
- package/dist/src/templates/renderer.d.ts +29 -0
- package/dist/src/templates/renderer.d.ts.map +1 -0
- package/dist/src/templates/renderer.js +35 -0
- package/dist/src/templates/strategy-templates.test.d.ts +2 -0
- package/dist/src/templates/strategy-templates.test.d.ts.map +1 -0
- package/dist/src/templates/strategy-templates.test.js +619 -0
- package/dist/src/templates/types.d.ts +233 -0
- package/dist/src/templates/types.d.ts.map +1 -0
- package/dist/src/templates/types.js +127 -0
- package/dist/src/templates/types.test.d.ts +2 -0
- package/dist/src/templates/types.test.d.ts.map +1 -0
- package/dist/src/templates/types.test.js +232 -0
- package/dist/src/tools/index.d.ts +6 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +3 -0
- package/dist/src/tools/linear-runner.d.ts +34 -0
- package/dist/src/tools/linear-runner.d.ts.map +1 -0
- package/dist/src/tools/linear-runner.js +700 -0
- package/dist/src/tools/plugins/linear.d.ts +9 -0
- package/dist/src/tools/plugins/linear.d.ts.map +1 -0
- package/dist/src/tools/plugins/linear.js +138 -0
- package/dist/src/tools/registry.d.ts +9 -0
- package/dist/src/tools/registry.d.ts.map +1 -0
- package/dist/src/tools/registry.js +18 -0
- package/dist/src/tools/types.d.ts +18 -0
- package/dist/src/tools/types.d.ts.map +1 -0
- package/dist/src/tools/types.js +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Template Types
|
|
3
|
+
*
|
|
4
|
+
* TypeScript interfaces and Zod schemas for the YAML-based workflow template system.
|
|
5
|
+
* Templates use Handlebars for interpolation and partials for composability.
|
|
6
|
+
*
|
|
7
|
+
* Architecture decisions (from SUP-701):
|
|
8
|
+
* - YAML format with Handlebars interpolation (not custom parser)
|
|
9
|
+
* - Single flat `prompt` field (not sectioned)
|
|
10
|
+
* - State transitions stay in TypeScript (not in templates)
|
|
11
|
+
* - Schema versioning: apiVersion: v1
|
|
12
|
+
* - Provider-agnostic tool permissions
|
|
13
|
+
* - Frontend-specific content in partials only
|
|
14
|
+
*/
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
import type { AgentWorkType } from '@renseiai/agentfactory-linear';
|
|
17
|
+
export type { AgentWorkType } from '@renseiai/agentfactory-linear';
|
|
18
|
+
/**
|
|
19
|
+
* Provider-agnostic tool permission.
|
|
20
|
+
*
|
|
21
|
+
* Shell permissions specify command patterns (e.g., "pnpm *").
|
|
22
|
+
* Provider adapters translate these to native format:
|
|
23
|
+
* - Claude: { shell: "pnpm *" } → "Bash(pnpm:*)"
|
|
24
|
+
* - Other providers: their own format
|
|
25
|
+
*/
|
|
26
|
+
export type ToolPermission = {
|
|
27
|
+
shell: string;
|
|
28
|
+
} | 'user-input' | string;
|
|
29
|
+
/**
|
|
30
|
+
* A workflow template defines the prompt and tool permissions for a work type.
|
|
31
|
+
*/
|
|
32
|
+
export interface WorkflowTemplate {
|
|
33
|
+
apiVersion: 'v1';
|
|
34
|
+
kind: 'WorkflowTemplate';
|
|
35
|
+
metadata: {
|
|
36
|
+
name: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
workType: AgentWorkType;
|
|
39
|
+
};
|
|
40
|
+
tools?: {
|
|
41
|
+
allow?: ToolPermission[];
|
|
42
|
+
disallow?: ToolPermission[];
|
|
43
|
+
};
|
|
44
|
+
/** Handlebars template string rendered with TemplateContext variables */
|
|
45
|
+
prompt: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A reusable instruction block that can be composed into workflow templates
|
|
49
|
+
* via Handlebars partials: {{> partials/name}}
|
|
50
|
+
*/
|
|
51
|
+
export interface PartialTemplate {
|
|
52
|
+
apiVersion: 'v1';
|
|
53
|
+
kind: 'PartialTemplate';
|
|
54
|
+
metadata: {
|
|
55
|
+
name: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
/** If set, this partial is frontend-specific (e.g., "linear", "asana") */
|
|
58
|
+
frontend?: string;
|
|
59
|
+
};
|
|
60
|
+
/** Handlebars template string (may reference other partials) */
|
|
61
|
+
content: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Variables available for interpolation in workflow templates.
|
|
65
|
+
*/
|
|
66
|
+
export interface TemplateContext {
|
|
67
|
+
/** Issue identifier, e.g., "SUP-123" */
|
|
68
|
+
identifier: string;
|
|
69
|
+
/** Optional user mention text providing additional context */
|
|
70
|
+
mentionContext?: string;
|
|
71
|
+
/** Status to show when agent starts, e.g., "Started" (Linear) */
|
|
72
|
+
startStatus?: string;
|
|
73
|
+
/** Status to show when agent completes, e.g., "Finished" */
|
|
74
|
+
completeStatus?: string;
|
|
75
|
+
/** Pre-built enriched prompt for parent issues with sub-issues */
|
|
76
|
+
parentContext?: string;
|
|
77
|
+
/** Formatted list of sub-issues with statuses */
|
|
78
|
+
subIssueList?: string;
|
|
79
|
+
/** Current escalation cycle count (from WorkflowState) */
|
|
80
|
+
cycleCount?: number;
|
|
81
|
+
/** Current escalation strategy: 'normal' | 'context-enriched' | 'decompose' | 'escalate-human' */
|
|
82
|
+
strategy?: string;
|
|
83
|
+
/** Accumulated failure summary across cycles */
|
|
84
|
+
failureSummary?: string;
|
|
85
|
+
/** Attempt number within current phase */
|
|
86
|
+
attemptNumber?: number;
|
|
87
|
+
/** List of previous failure reasons */
|
|
88
|
+
previousFailureReasons?: string[];
|
|
89
|
+
/** Total cost in USD across all attempts */
|
|
90
|
+
totalCostUsd?: number;
|
|
91
|
+
/** Blocker issue identifier (for escalation alerts) */
|
|
92
|
+
blockerIdentifier?: string;
|
|
93
|
+
/** Team name (for decomposition sub-issue creation) */
|
|
94
|
+
team?: string;
|
|
95
|
+
/** Git repository URL pattern for pre-push validation (e.g. 'github.com/org/repo') */
|
|
96
|
+
repository?: string;
|
|
97
|
+
/** Root directory for this project within the repo (e.g. 'apps/family') */
|
|
98
|
+
projectPath?: string;
|
|
99
|
+
/** Shared directories that any project's agent may modify (e.g. ['packages/ui']) */
|
|
100
|
+
sharedPaths?: string[];
|
|
101
|
+
/** When true, agents use in-process af_linear_* tools instead of CLI */
|
|
102
|
+
useToolPlugins?: boolean;
|
|
103
|
+
/** Command to invoke the Linear CLI (default: "pnpm af-linear") */
|
|
104
|
+
linearCli?: string;
|
|
105
|
+
/** Package manager used by the project (default: "pnpm"). Set to "none" for non-Node projects. */
|
|
106
|
+
packageManager?: string;
|
|
107
|
+
/** Build command override (e.g. 'cargo build', 'cmake --build build', 'make') */
|
|
108
|
+
buildCommand?: string;
|
|
109
|
+
/** Test command override (e.g. 'cargo test', 'ctest --test-dir build', 'make test') */
|
|
110
|
+
testCommand?: string;
|
|
111
|
+
/** Validation command override — replaces typecheck for compiled projects (e.g. 'cargo clippy') */
|
|
112
|
+
validateCommand?: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Translates abstract tool permissions to provider-native format.
|
|
116
|
+
*
|
|
117
|
+
* Example: Claude adapter translates { shell: "pnpm *" } → "Bash(pnpm:*)"
|
|
118
|
+
*/
|
|
119
|
+
export interface ToolPermissionAdapter {
|
|
120
|
+
/** Translate abstract permissions to provider-native format */
|
|
121
|
+
translatePermissions(permissions: ToolPermission[]): string[];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Configuration for creating a template registry.
|
|
125
|
+
*/
|
|
126
|
+
export interface TemplateRegistryConfig {
|
|
127
|
+
/** Directories to scan for template YAML files (searched in order) */
|
|
128
|
+
templateDirs?: string[];
|
|
129
|
+
/**
|
|
130
|
+
* Inline template overrides (highest priority).
|
|
131
|
+
* Keys can be AgentWorkType values (e.g., "development") or strategy-specific
|
|
132
|
+
* compound keys (e.g., "refinement-context-enriched").
|
|
133
|
+
*/
|
|
134
|
+
templates?: Partial<Record<AgentWorkType, WorkflowTemplate>> & Record<string, WorkflowTemplate>;
|
|
135
|
+
/** Whether to load built-in defaults (default: true) */
|
|
136
|
+
useBuiltinDefaults?: boolean;
|
|
137
|
+
/** Frontend discriminator for partial resolution (e.g., "linear", "asana") */
|
|
138
|
+
frontend?: string;
|
|
139
|
+
/** Provider discriminator for tool permission translation */
|
|
140
|
+
provider?: string;
|
|
141
|
+
}
|
|
142
|
+
export declare const AgentWorkTypeSchema: z.ZodEnum<{
|
|
143
|
+
research: "research";
|
|
144
|
+
"backlog-creation": "backlog-creation";
|
|
145
|
+
development: "development";
|
|
146
|
+
inflight: "inflight";
|
|
147
|
+
qa: "qa";
|
|
148
|
+
acceptance: "acceptance";
|
|
149
|
+
refinement: "refinement";
|
|
150
|
+
"refinement-coordination": "refinement-coordination";
|
|
151
|
+
coordination: "coordination";
|
|
152
|
+
"qa-coordination": "qa-coordination";
|
|
153
|
+
"acceptance-coordination": "acceptance-coordination";
|
|
154
|
+
}>;
|
|
155
|
+
export declare const ToolPermissionSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
156
|
+
shell: z.ZodString;
|
|
157
|
+
}, z.core.$strip>, z.ZodLiteral<"user-input">, z.ZodString]>;
|
|
158
|
+
export declare const WorkflowTemplateSchema: z.ZodObject<{
|
|
159
|
+
apiVersion: z.ZodLiteral<"v1">;
|
|
160
|
+
kind: z.ZodLiteral<"WorkflowTemplate">;
|
|
161
|
+
metadata: z.ZodObject<{
|
|
162
|
+
name: z.ZodString;
|
|
163
|
+
description: z.ZodOptional<z.ZodString>;
|
|
164
|
+
workType: z.ZodEnum<{
|
|
165
|
+
research: "research";
|
|
166
|
+
"backlog-creation": "backlog-creation";
|
|
167
|
+
development: "development";
|
|
168
|
+
inflight: "inflight";
|
|
169
|
+
qa: "qa";
|
|
170
|
+
acceptance: "acceptance";
|
|
171
|
+
refinement: "refinement";
|
|
172
|
+
"refinement-coordination": "refinement-coordination";
|
|
173
|
+
coordination: "coordination";
|
|
174
|
+
"qa-coordination": "qa-coordination";
|
|
175
|
+
"acceptance-coordination": "acceptance-coordination";
|
|
176
|
+
}>;
|
|
177
|
+
}, z.core.$strip>;
|
|
178
|
+
tools: z.ZodOptional<z.ZodObject<{
|
|
179
|
+
allow: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
180
|
+
shell: z.ZodString;
|
|
181
|
+
}, z.core.$strip>, z.ZodLiteral<"user-input">, z.ZodString]>>>;
|
|
182
|
+
disallow: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
183
|
+
shell: z.ZodString;
|
|
184
|
+
}, z.core.$strip>, z.ZodLiteral<"user-input">, z.ZodString]>>>;
|
|
185
|
+
}, z.core.$strip>>;
|
|
186
|
+
prompt: z.ZodString;
|
|
187
|
+
}, z.core.$strip>;
|
|
188
|
+
export declare const PartialTemplateSchema: z.ZodObject<{
|
|
189
|
+
apiVersion: z.ZodLiteral<"v1">;
|
|
190
|
+
kind: z.ZodLiteral<"PartialTemplate">;
|
|
191
|
+
metadata: z.ZodObject<{
|
|
192
|
+
name: z.ZodString;
|
|
193
|
+
description: z.ZodOptional<z.ZodString>;
|
|
194
|
+
frontend: z.ZodOptional<z.ZodString>;
|
|
195
|
+
}, z.core.$strip>;
|
|
196
|
+
content: z.ZodString;
|
|
197
|
+
}, z.core.$strip>;
|
|
198
|
+
export declare const TemplateContextSchema: z.ZodObject<{
|
|
199
|
+
identifier: z.ZodString;
|
|
200
|
+
mentionContext: z.ZodOptional<z.ZodString>;
|
|
201
|
+
startStatus: z.ZodOptional<z.ZodString>;
|
|
202
|
+
completeStatus: z.ZodOptional<z.ZodString>;
|
|
203
|
+
parentContext: z.ZodOptional<z.ZodString>;
|
|
204
|
+
subIssueList: z.ZodOptional<z.ZodString>;
|
|
205
|
+
cycleCount: z.ZodOptional<z.ZodNumber>;
|
|
206
|
+
strategy: z.ZodOptional<z.ZodString>;
|
|
207
|
+
failureSummary: z.ZodOptional<z.ZodString>;
|
|
208
|
+
attemptNumber: z.ZodOptional<z.ZodNumber>;
|
|
209
|
+
previousFailureReasons: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
210
|
+
totalCostUsd: z.ZodOptional<z.ZodNumber>;
|
|
211
|
+
blockerIdentifier: z.ZodOptional<z.ZodString>;
|
|
212
|
+
team: z.ZodOptional<z.ZodString>;
|
|
213
|
+
repository: z.ZodOptional<z.ZodString>;
|
|
214
|
+
projectPath: z.ZodOptional<z.ZodString>;
|
|
215
|
+
sharedPaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
216
|
+
useToolPlugins: z.ZodOptional<z.ZodBoolean>;
|
|
217
|
+
linearCli: z.ZodOptional<z.ZodString>;
|
|
218
|
+
packageManager: z.ZodOptional<z.ZodString>;
|
|
219
|
+
buildCommand: z.ZodOptional<z.ZodString>;
|
|
220
|
+
testCommand: z.ZodOptional<z.ZodString>;
|
|
221
|
+
validateCommand: z.ZodOptional<z.ZodString>;
|
|
222
|
+
}, z.core.$strip>;
|
|
223
|
+
/**
|
|
224
|
+
* Validate a parsed YAML object as a WorkflowTemplate.
|
|
225
|
+
* Throws ZodError with detailed messages on failure.
|
|
226
|
+
*/
|
|
227
|
+
export declare function validateWorkflowTemplate(data: unknown, filePath?: string): WorkflowTemplate;
|
|
228
|
+
/**
|
|
229
|
+
* Validate a parsed YAML object as a PartialTemplate.
|
|
230
|
+
* Throws ZodError with detailed messages on failure.
|
|
231
|
+
*/
|
|
232
|
+
export declare function validatePartialTemplate(data: unknown, filePath?: string): PartialTemplate;
|
|
233
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/templates/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAGlE,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAMlE;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB,YAAY,GACZ,MAAM,CAAA;AAMV;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,IAAI,CAAA;IAChB,IAAI,EAAE,kBAAkB,CAAA;IACxB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,aAAa,CAAA;KACxB,CAAA;IACD,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,cAAc,EAAE,CAAA;QACxB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAA;KAC5B,CAAA;IACD,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAA;CACf;AAMD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,IAAI,CAAA;IAChB,IAAI,EAAE,iBAAiB,CAAA;IACvB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,0EAA0E;QAC1E,QAAQ,CAAC,EAAE,MAAM,CAAA;KAClB,CAAA;IACD,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAA;CAChB;AAMD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAA;IAGvB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAA;IAGvB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAA;IAGrB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kGAAkG;IAClG,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gDAAgD;IAChD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,0CAA0C;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uCAAuC;IACvC,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAA;IACjC,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAA;IAGrB,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAA;IAGb,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAA;IAGnB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IAGtB,wEAAwE;IACxE,cAAc,CAAC,EAAE,OAAO,CAAA;IAGxB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kGAAkG;IAClG,cAAc,CAAC,EAAE,MAAM,CAAA;IAGvB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,uFAAuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mGAAmG;IACnG,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAMD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,+DAA+D;IAC/D,oBAAoB,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAAA;CAC9D;AAMD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IAC/F,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAqBD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAAqB,CAAA;AAErD,eAAO,MAAM,oBAAoB;;4DAI/B,CAAA;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAajC,CAAA;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;iBAShC,CAAA;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;iBA+BhC,CAAA;AAMF;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAS3F;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CASzF"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Template Types
|
|
3
|
+
*
|
|
4
|
+
* TypeScript interfaces and Zod schemas for the YAML-based workflow template system.
|
|
5
|
+
* Templates use Handlebars for interpolation and partials for composability.
|
|
6
|
+
*
|
|
7
|
+
* Architecture decisions (from SUP-701):
|
|
8
|
+
* - YAML format with Handlebars interpolation (not custom parser)
|
|
9
|
+
* - Single flat `prompt` field (not sectioned)
|
|
10
|
+
* - State transitions stay in TypeScript (not in templates)
|
|
11
|
+
* - Schema versioning: apiVersion: v1
|
|
12
|
+
* - Provider-agnostic tool permissions
|
|
13
|
+
* - Frontend-specific content in partials only
|
|
14
|
+
*/
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Zod Schemas
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
/** All valid work type values */
|
|
20
|
+
const WORK_TYPES = [
|
|
21
|
+
'research',
|
|
22
|
+
'backlog-creation',
|
|
23
|
+
'development',
|
|
24
|
+
'inflight',
|
|
25
|
+
'qa',
|
|
26
|
+
'acceptance',
|
|
27
|
+
'refinement',
|
|
28
|
+
'refinement-coordination',
|
|
29
|
+
'coordination',
|
|
30
|
+
'qa-coordination',
|
|
31
|
+
'acceptance-coordination',
|
|
32
|
+
];
|
|
33
|
+
export const AgentWorkTypeSchema = z.enum(WORK_TYPES);
|
|
34
|
+
export const ToolPermissionSchema = z.union([
|
|
35
|
+
z.object({ shell: z.string().min(1) }),
|
|
36
|
+
z.literal('user-input'),
|
|
37
|
+
z.string().min(1),
|
|
38
|
+
]);
|
|
39
|
+
export const WorkflowTemplateSchema = z.object({
|
|
40
|
+
apiVersion: z.literal('v1'),
|
|
41
|
+
kind: z.literal('WorkflowTemplate'),
|
|
42
|
+
metadata: z.object({
|
|
43
|
+
name: z.string().min(1),
|
|
44
|
+
description: z.string().optional(),
|
|
45
|
+
workType: AgentWorkTypeSchema,
|
|
46
|
+
}),
|
|
47
|
+
tools: z.object({
|
|
48
|
+
allow: z.array(ToolPermissionSchema).optional(),
|
|
49
|
+
disallow: z.array(ToolPermissionSchema).optional(),
|
|
50
|
+
}).optional(),
|
|
51
|
+
prompt: z.string().min(1),
|
|
52
|
+
});
|
|
53
|
+
export const PartialTemplateSchema = z.object({
|
|
54
|
+
apiVersion: z.literal('v1'),
|
|
55
|
+
kind: z.literal('PartialTemplate'),
|
|
56
|
+
metadata: z.object({
|
|
57
|
+
name: z.string().min(1),
|
|
58
|
+
description: z.string().optional(),
|
|
59
|
+
frontend: z.string().optional(),
|
|
60
|
+
}),
|
|
61
|
+
content: z.string().min(1),
|
|
62
|
+
});
|
|
63
|
+
export const TemplateContextSchema = z.object({
|
|
64
|
+
identifier: z.string().min(1),
|
|
65
|
+
mentionContext: z.string().optional(),
|
|
66
|
+
startStatus: z.string().optional(),
|
|
67
|
+
completeStatus: z.string().optional(),
|
|
68
|
+
parentContext: z.string().optional(),
|
|
69
|
+
subIssueList: z.string().optional(),
|
|
70
|
+
// Strategy / WorkflowState variables
|
|
71
|
+
cycleCount: z.number().int().nonnegative().optional(),
|
|
72
|
+
strategy: z.string().optional(),
|
|
73
|
+
failureSummary: z.string().optional(),
|
|
74
|
+
attemptNumber: z.number().int().positive().optional(),
|
|
75
|
+
previousFailureReasons: z.array(z.string()).optional(),
|
|
76
|
+
totalCostUsd: z.number().nonnegative().optional(),
|
|
77
|
+
// Governor notification variables
|
|
78
|
+
blockerIdentifier: z.string().optional(),
|
|
79
|
+
team: z.string().optional(),
|
|
80
|
+
// Repository validation variables
|
|
81
|
+
repository: z.string().optional(),
|
|
82
|
+
// Project path scoping variables (monorepo support)
|
|
83
|
+
projectPath: z.string().optional(),
|
|
84
|
+
sharedPaths: z.array(z.string()).optional(),
|
|
85
|
+
// Tool plugin mode
|
|
86
|
+
useToolPlugins: z.boolean().optional(),
|
|
87
|
+
// Non-Node project support
|
|
88
|
+
linearCli: z.string().optional(),
|
|
89
|
+
packageManager: z.string().optional(),
|
|
90
|
+
// Configurable build/test commands (native/compiled project support)
|
|
91
|
+
buildCommand: z.string().optional(),
|
|
92
|
+
testCommand: z.string().optional(),
|
|
93
|
+
validateCommand: z.string().optional(),
|
|
94
|
+
});
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Validation Helpers
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
/**
|
|
99
|
+
* Validate a parsed YAML object as a WorkflowTemplate.
|
|
100
|
+
* Throws ZodError with detailed messages on failure.
|
|
101
|
+
*/
|
|
102
|
+
export function validateWorkflowTemplate(data, filePath) {
|
|
103
|
+
try {
|
|
104
|
+
return WorkflowTemplateSchema.parse(data);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (filePath && error instanceof z.ZodError) {
|
|
108
|
+
throw new Error(`Invalid workflow template at ${filePath}: ${error.message}`, { cause: error });
|
|
109
|
+
}
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Validate a parsed YAML object as a PartialTemplate.
|
|
115
|
+
* Throws ZodError with detailed messages on failure.
|
|
116
|
+
*/
|
|
117
|
+
export function validatePartialTemplate(data, filePath) {
|
|
118
|
+
try {
|
|
119
|
+
return PartialTemplateSchema.parse(data);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (filePath && error instanceof z.ZodError) {
|
|
123
|
+
throw new Error(`Invalid partial template at ${filePath}: ${error.message}`, { cause: error });
|
|
124
|
+
}
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../../src/templates/types.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { WorkflowTemplateSchema, PartialTemplateSchema, TemplateContextSchema, AgentWorkTypeSchema, ToolPermissionSchema, validateWorkflowTemplate, validatePartialTemplate, } from './types.js';
|
|
3
|
+
describe('WorkflowTemplateSchema', () => {
|
|
4
|
+
it('validates a complete workflow template', () => {
|
|
5
|
+
const template = {
|
|
6
|
+
apiVersion: 'v1',
|
|
7
|
+
kind: 'WorkflowTemplate',
|
|
8
|
+
metadata: {
|
|
9
|
+
name: 'development',
|
|
10
|
+
description: 'Standard development workflow',
|
|
11
|
+
workType: 'development',
|
|
12
|
+
},
|
|
13
|
+
tools: {
|
|
14
|
+
allow: [
|
|
15
|
+
{ shell: 'pnpm *' },
|
|
16
|
+
{ shell: 'git commit *' },
|
|
17
|
+
],
|
|
18
|
+
disallow: ['user-input'],
|
|
19
|
+
},
|
|
20
|
+
prompt: 'Start work on {{identifier}}.',
|
|
21
|
+
};
|
|
22
|
+
const result = WorkflowTemplateSchema.parse(template);
|
|
23
|
+
expect(result.apiVersion).toBe('v1');
|
|
24
|
+
expect(result.metadata.workType).toBe('development');
|
|
25
|
+
expect(result.tools?.allow).toHaveLength(2);
|
|
26
|
+
});
|
|
27
|
+
it('validates a minimal workflow template', () => {
|
|
28
|
+
const template = {
|
|
29
|
+
apiVersion: 'v1',
|
|
30
|
+
kind: 'WorkflowTemplate',
|
|
31
|
+
metadata: {
|
|
32
|
+
name: 'research',
|
|
33
|
+
workType: 'research',
|
|
34
|
+
},
|
|
35
|
+
prompt: 'Research {{identifier}}.',
|
|
36
|
+
};
|
|
37
|
+
const result = WorkflowTemplateSchema.parse(template);
|
|
38
|
+
expect(result.metadata.name).toBe('research');
|
|
39
|
+
expect(result.tools).toBeUndefined();
|
|
40
|
+
});
|
|
41
|
+
it('rejects invalid apiVersion', () => {
|
|
42
|
+
const template = {
|
|
43
|
+
apiVersion: 'v2',
|
|
44
|
+
kind: 'WorkflowTemplate',
|
|
45
|
+
metadata: { name: 'test', workType: 'development' },
|
|
46
|
+
prompt: 'test',
|
|
47
|
+
};
|
|
48
|
+
expect(() => WorkflowTemplateSchema.parse(template)).toThrow();
|
|
49
|
+
});
|
|
50
|
+
it('rejects invalid workType', () => {
|
|
51
|
+
const template = {
|
|
52
|
+
apiVersion: 'v1',
|
|
53
|
+
kind: 'WorkflowTemplate',
|
|
54
|
+
metadata: { name: 'test', workType: 'invalid' },
|
|
55
|
+
prompt: 'test',
|
|
56
|
+
};
|
|
57
|
+
expect(() => WorkflowTemplateSchema.parse(template)).toThrow();
|
|
58
|
+
});
|
|
59
|
+
it('rejects empty prompt', () => {
|
|
60
|
+
const template = {
|
|
61
|
+
apiVersion: 'v1',
|
|
62
|
+
kind: 'WorkflowTemplate',
|
|
63
|
+
metadata: { name: 'test', workType: 'development' },
|
|
64
|
+
prompt: '',
|
|
65
|
+
};
|
|
66
|
+
expect(() => WorkflowTemplateSchema.parse(template)).toThrow();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe('PartialTemplateSchema', () => {
|
|
70
|
+
it('validates a partial template', () => {
|
|
71
|
+
const partial = {
|
|
72
|
+
apiVersion: 'v1',
|
|
73
|
+
kind: 'PartialTemplate',
|
|
74
|
+
metadata: {
|
|
75
|
+
name: 'cli-instructions',
|
|
76
|
+
description: 'CLI instructions',
|
|
77
|
+
},
|
|
78
|
+
content: 'Use pnpm af-linear for all operations.',
|
|
79
|
+
};
|
|
80
|
+
const result = PartialTemplateSchema.parse(partial);
|
|
81
|
+
expect(result.metadata.name).toBe('cli-instructions');
|
|
82
|
+
expect(result.metadata.frontend).toBeUndefined();
|
|
83
|
+
});
|
|
84
|
+
it('validates a frontend-specific partial', () => {
|
|
85
|
+
const partial = {
|
|
86
|
+
apiVersion: 'v1',
|
|
87
|
+
kind: 'PartialTemplate',
|
|
88
|
+
metadata: {
|
|
89
|
+
name: 'linear-cli',
|
|
90
|
+
frontend: 'linear',
|
|
91
|
+
},
|
|
92
|
+
content: 'pnpm af-linear get-issue <id>',
|
|
93
|
+
};
|
|
94
|
+
const result = PartialTemplateSchema.parse(partial);
|
|
95
|
+
expect(result.metadata.frontend).toBe('linear');
|
|
96
|
+
});
|
|
97
|
+
it('rejects empty content', () => {
|
|
98
|
+
const partial = {
|
|
99
|
+
apiVersion: 'v1',
|
|
100
|
+
kind: 'PartialTemplate',
|
|
101
|
+
metadata: { name: 'test' },
|
|
102
|
+
content: '',
|
|
103
|
+
};
|
|
104
|
+
expect(() => PartialTemplateSchema.parse(partial)).toThrow();
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
describe('AgentWorkTypeSchema', () => {
|
|
108
|
+
it('accepts all 10 work types', () => {
|
|
109
|
+
const workTypes = [
|
|
110
|
+
'research', 'backlog-creation', 'development', 'inflight',
|
|
111
|
+
'qa', 'acceptance', 'refinement', 'coordination',
|
|
112
|
+
'qa-coordination', 'acceptance-coordination',
|
|
113
|
+
];
|
|
114
|
+
for (const wt of workTypes) {
|
|
115
|
+
expect(AgentWorkTypeSchema.parse(wt)).toBe(wt);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
it('rejects invalid work type', () => {
|
|
119
|
+
expect(() => AgentWorkTypeSchema.parse('invalid')).toThrow();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
describe('ToolPermissionSchema', () => {
|
|
123
|
+
it('accepts shell permission', () => {
|
|
124
|
+
expect(ToolPermissionSchema.parse({ shell: 'pnpm *' })).toEqual({ shell: 'pnpm *' });
|
|
125
|
+
});
|
|
126
|
+
it('accepts user-input literal', () => {
|
|
127
|
+
expect(ToolPermissionSchema.parse('user-input')).toBe('user-input');
|
|
128
|
+
});
|
|
129
|
+
it('accepts string permission', () => {
|
|
130
|
+
expect(ToolPermissionSchema.parse('Read')).toBe('Read');
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
describe('TemplateContextSchema', () => {
|
|
134
|
+
it('validates minimal context', () => {
|
|
135
|
+
const result = TemplateContextSchema.parse({ identifier: 'SUP-123' });
|
|
136
|
+
expect(result.identifier).toBe('SUP-123');
|
|
137
|
+
});
|
|
138
|
+
it('validates full context', () => {
|
|
139
|
+
const result = TemplateContextSchema.parse({
|
|
140
|
+
identifier: 'SUP-123',
|
|
141
|
+
mentionContext: 'user mention',
|
|
142
|
+
startStatus: 'Started',
|
|
143
|
+
completeStatus: 'Finished',
|
|
144
|
+
parentContext: 'parent context',
|
|
145
|
+
subIssueList: '- SUP-124: Sub 1',
|
|
146
|
+
});
|
|
147
|
+
expect(result.mentionContext).toBe('user mention');
|
|
148
|
+
});
|
|
149
|
+
it('validates context with strategy/WorkflowState fields', () => {
|
|
150
|
+
const result = TemplateContextSchema.parse({
|
|
151
|
+
identifier: 'SUP-123',
|
|
152
|
+
cycleCount: 3,
|
|
153
|
+
strategy: 'context-enriched',
|
|
154
|
+
failureSummary: 'Tests failing on auth module',
|
|
155
|
+
attemptNumber: 2,
|
|
156
|
+
previousFailureReasons: ['reason1', 'reason2'],
|
|
157
|
+
totalCostUsd: 1.50,
|
|
158
|
+
blockerIdentifier: 'SUP-999',
|
|
159
|
+
team: 'Engineering',
|
|
160
|
+
});
|
|
161
|
+
expect(result.cycleCount).toBe(3);
|
|
162
|
+
expect(result.strategy).toBe('context-enriched');
|
|
163
|
+
expect(result.failureSummary).toBe('Tests failing on auth module');
|
|
164
|
+
expect(result.attemptNumber).toBe(2);
|
|
165
|
+
expect(result.previousFailureReasons).toEqual(['reason1', 'reason2']);
|
|
166
|
+
expect(result.totalCostUsd).toBe(1.50);
|
|
167
|
+
expect(result.blockerIdentifier).toBe('SUP-999');
|
|
168
|
+
expect(result.team).toBe('Engineering');
|
|
169
|
+
});
|
|
170
|
+
it('rejects negative cycleCount', () => {
|
|
171
|
+
expect(() => TemplateContextSchema.parse({
|
|
172
|
+
identifier: 'SUP-123',
|
|
173
|
+
cycleCount: -1,
|
|
174
|
+
})).toThrow();
|
|
175
|
+
});
|
|
176
|
+
it('rejects non-positive attemptNumber', () => {
|
|
177
|
+
expect(() => TemplateContextSchema.parse({
|
|
178
|
+
identifier: 'SUP-123',
|
|
179
|
+
attemptNumber: 0,
|
|
180
|
+
})).toThrow();
|
|
181
|
+
});
|
|
182
|
+
it('rejects negative totalCostUsd', () => {
|
|
183
|
+
expect(() => TemplateContextSchema.parse({
|
|
184
|
+
identifier: 'SUP-123',
|
|
185
|
+
totalCostUsd: -5,
|
|
186
|
+
})).toThrow();
|
|
187
|
+
});
|
|
188
|
+
it('rejects empty identifier', () => {
|
|
189
|
+
expect(() => TemplateContextSchema.parse({ identifier: '' })).toThrow();
|
|
190
|
+
});
|
|
191
|
+
it('validates context with build/test command variables', () => {
|
|
192
|
+
const result = TemplateContextSchema.parse({
|
|
193
|
+
identifier: 'SUP-123',
|
|
194
|
+
buildCommand: 'cargo build --release',
|
|
195
|
+
testCommand: 'cargo test',
|
|
196
|
+
validateCommand: 'cargo clippy -- -D warnings',
|
|
197
|
+
});
|
|
198
|
+
expect(result.buildCommand).toBe('cargo build --release');
|
|
199
|
+
expect(result.testCommand).toBe('cargo test');
|
|
200
|
+
expect(result.validateCommand).toBe('cargo clippy -- -D warnings');
|
|
201
|
+
});
|
|
202
|
+
it('allows omitting build/test command variables', () => {
|
|
203
|
+
const result = TemplateContextSchema.parse({
|
|
204
|
+
identifier: 'SUP-123',
|
|
205
|
+
});
|
|
206
|
+
expect(result.buildCommand).toBeUndefined();
|
|
207
|
+
expect(result.testCommand).toBeUndefined();
|
|
208
|
+
expect(result.validateCommand).toBeUndefined();
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
describe('validateWorkflowTemplate', () => {
|
|
212
|
+
it('adds file path to error message', () => {
|
|
213
|
+
try {
|
|
214
|
+
validateWorkflowTemplate({ invalid: true }, '/path/to/file.yaml');
|
|
215
|
+
expect.fail('should throw');
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
expect(error.message).toContain('/path/to/file.yaml');
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
describe('validatePartialTemplate', () => {
|
|
223
|
+
it('adds file path to error message', () => {
|
|
224
|
+
try {
|
|
225
|
+
validatePartialTemplate({ invalid: true }, '/path/to/partial.yaml');
|
|
226
|
+
expect.fail('should throw');
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
expect(error.message).toContain('/path/to/partial.yaml');
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ToolRegistry } from './registry.js';
|
|
2
|
+
export type { ToolPlugin, ToolPluginContext } from './types.js';
|
|
3
|
+
export { linearPlugin } from './plugins/linear.js';
|
|
4
|
+
export { runLinear, parseLinearArgs } from './linear-runner.js';
|
|
5
|
+
export type { LinearRunnerConfig, LinearRunnerResult } from './linear-runner.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC/D,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear CLI Runner — process-agnostic Linear operations.
|
|
3
|
+
*
|
|
4
|
+
* All 16 command implementations. This module does NOT call process.exit,
|
|
5
|
+
* read process.argv, or load dotenv. Shared by both the CLI entry point
|
|
6
|
+
* and the in-process tool plugin.
|
|
7
|
+
*/
|
|
8
|
+
export interface LinearRunnerConfig {
|
|
9
|
+
command: string;
|
|
10
|
+
args: Record<string, string | string[] | boolean>;
|
|
11
|
+
positionalArgs: string[];
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface LinearRunnerResult {
|
|
15
|
+
output: unknown;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Parse CLI arguments into a structured object.
|
|
19
|
+
*
|
|
20
|
+
* Supports:
|
|
21
|
+
* - `--key value` pairs
|
|
22
|
+
* - JSON array values: `--labels '["Bug", "Feature"]'`
|
|
23
|
+
* - Comma-separated values for array fields: `--labels "Bug,Feature"`
|
|
24
|
+
* - Boolean flags: `--dry-run` (value = "true")
|
|
25
|
+
*
|
|
26
|
+
* Returns the command (first non-flag arg), named args, and positional args.
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseLinearArgs(argv: string[]): {
|
|
29
|
+
command: string | undefined;
|
|
30
|
+
args: Record<string, string | string[] | boolean>;
|
|
31
|
+
positionalArgs: string[];
|
|
32
|
+
};
|
|
33
|
+
export declare function runLinear(config: LinearRunnerConfig): Promise<LinearRunnerResult>;
|
|
34
|
+
//# sourceMappingURL=linear-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-runner.d.ts","sourceRoot":"","sources":["../../../src/tools/linear-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,CAAA;IACjD,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAA;CAChB;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAC/C,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,CAAA;IACjD,cAAc,EAAE,MAAM,EAAE,CAAA;CACzB,CA2CA;AA0nBD,wBAAsB,SAAS,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAyNvF"}
|