11import { afterEach , describe , expect , it , vi } from "vitest"
2- import type { EnvConfig , WorkflowState } from "../setup"
3- import { buildEnvContent , findWorkflowState , linearQuery , maskApiKey } from "../setup"
2+ import type { WorkflowState } from "../setup"
3+ import { buildGlobalYaml , buildProjectYaml , findWorkflowState , linearQuery , maskApiKey } from "../setup"
44
55// ── findWorkflowState ────────────────────────────────────────────────────────
66
@@ -40,7 +40,6 @@ describe("findWorkflowState", () => {
4040 } )
4141
4242 it ( "returns first match when multiple states share a type" , ( ) => {
43- // "In Progress" and "In Review" are both "started", but name match wins
4443 const result = findWorkflowState ( states , [ "In Review" ] , "started" )
4544 expect ( result ) . toEqual ( { id : "ddd" , name : "In Review" , type : "started" } )
4645 } )
@@ -56,17 +55,33 @@ describe("findWorkflowState", () => {
5655 } )
5756
5857 it ( "matches multiple name candidates" , ( ) => {
59- // "Cancelled" (double l) doesn't exist but "Canceled" (single l) does
6058 const result = findWorkflowState ( states , [ "Cancelled" , "Canceled" ] , "canceled" )
6159 expect ( result ) . toEqual ( { id : "fff" , name : "Canceled" , type : "canceled" } )
6260 } )
6361} )
6462
65- // ── buildEnvContent ──────────────────────────────────────────────────────────
63+ // ── buildGlobalYaml ──────────────────────────────────────────────────────────
6664
67- describe ( "buildEnvContent" , ( ) => {
68- const config : EnvConfig = {
69- apiKey : "lin_api_test123" ,
65+ describe ( "buildGlobalYaml" , ( ) => {
66+ it ( "generates valid YAML with API key and agent type" , ( ) => {
67+ const content = buildGlobalYaml ( { apiKey : "lin_api_test123" , agentType : "claude" , maxParallel : 3 } )
68+
69+ expect ( content ) . toContain ( "api_key: lin_api_test123" )
70+ expect ( content ) . toContain ( "type: claude" )
71+ expect ( content ) . toContain ( "level: info" )
72+ expect ( content ) . toContain ( "port: 9741" )
73+ } )
74+
75+ it ( "preserves different agent types" , ( ) => {
76+ expect ( buildGlobalYaml ( { apiKey : "key" , agentType : "codex" , maxParallel : 3 } ) ) . toContain ( "type: codex" )
77+ expect ( buildGlobalYaml ( { apiKey : "key" , agentType : "gemini" , maxParallel : 3 } ) ) . toContain ( "type: gemini" )
78+ } )
79+ } )
80+
81+ // ── buildProjectYaml ─────────────────────────────────────────────────────────
82+
83+ describe ( "buildProjectYaml" , ( ) => {
84+ const config = {
7085 teamKey : "FIR" ,
7186 teamUuid : "uuid-team-123" ,
7287 webhookSecret : "lin_wh_secret456" ,
@@ -75,51 +90,26 @@ describe("buildEnvContent", () => {
7590 doneStateId : "state-done" ,
7691 cancelledStateId : "state-cancel" ,
7792 workspaceRoot : "/home/user/workspaces" ,
78- agentType : "claude" ,
79- maxParallel : 3 ,
8093 }
8194
82- it ( "generates valid .env content with all fields" , ( ) => {
83- const content = buildEnvContent ( config )
95+ it ( "generates valid YAML with all project fields" , ( ) => {
96+ const content = buildProjectYaml ( config )
8497
85- expect ( content ) . toContain ( "LINEAR_API_KEY=lin_api_test123" )
86- expect ( content ) . toContain ( "LINEAR_TEAM_ID=FIR" )
87- expect ( content ) . toContain ( "LINEAR_TEAM_UUID=uuid-team-123" )
88- expect ( content ) . toContain ( "LINEAR_WEBHOOK_SECRET=lin_wh_secret456" )
89- expect ( content ) . toContain ( "LINEAR_WORKFLOW_STATE_TODO=state-todo" )
90- expect ( content ) . toContain ( "LINEAR_WORKFLOW_STATE_IN_PROGRESS=state-ip" )
91- expect ( content ) . toContain ( "LINEAR_WORKFLOW_STATE_DONE=state-done" )
92- expect ( content ) . toContain ( "LINEAR_WORKFLOW_STATE_CANCELLED=state-cancel" )
93- expect ( content ) . toContain ( "WORKSPACE_ROOT=/home/user/workspaces" )
94- expect ( content ) . toContain ( "AGENT_TYPE=claude" )
95- expect ( content ) . toContain ( "MAX_PARALLEL=3" )
96- expect ( content ) . toContain ( "SERVER_PORT=9741" )
97- expect ( content ) . toContain ( "LOG_LEVEL=info" )
98- expect ( content ) . toContain ( "LOG_FORMAT=json" )
99- } )
100-
101- it ( "includes section comment headers" , ( ) => {
102- const content = buildEnvContent ( config )
103-
104- expect ( content ) . toContain ( "# ── Linear Issue Tracker" )
105- expect ( content ) . toContain ( "# ── Symphony Orchestrator" )
106- expect ( content ) . toContain ( "# ── Agent Selection" )
107- expect ( content ) . toContain ( "# ── Observability" )
108- } )
109-
110- it ( "ends with newline" , ( ) => {
111- const content = buildEnvContent ( config )
112- expect ( content . endsWith ( "\n" ) ) . toBe ( true )
113- } )
114-
115- it ( "preserves different agent types" , ( ) => {
116- expect ( buildEnvContent ( { ...config , agentType : "codex" } ) ) . toContain ( "AGENT_TYPE=codex" )
117- expect ( buildEnvContent ( { ...config , agentType : "gemini" } ) ) . toContain ( "AGENT_TYPE=gemini" )
98+ expect ( content ) . toContain ( "team_id: FIR" )
99+ expect ( content ) . toContain ( "team_uuid: uuid-team-123" )
100+ expect ( content ) . toContain ( "webhook_secret: lin_wh_secret456" )
101+ expect ( content ) . toContain ( "todo: state-todo" )
102+ expect ( content ) . toContain ( "in_progress: state-ip" )
103+ expect ( content ) . toContain ( "done: state-done" )
104+ expect ( content ) . toContain ( "cancelled: state-cancel" )
105+ expect ( content ) . toContain ( "root: /home/user/workspaces" )
106+ expect ( content ) . toContain ( "mode: merge" )
118107 } )
119108
120- it ( "handles special characters in values" , ( ) => {
121- const content = buildEnvContent ( { ...config , apiKey : "lin_api_a+b=c/d" } )
122- expect ( content ) . toContain ( "LINEAR_API_KEY=lin_api_a+b=c/d" )
109+ it ( "includes default prompt template" , ( ) => {
110+ const content = buildProjectYaml ( config )
111+ expect ( content ) . toContain ( "{{issue.identifier}}" )
112+ expect ( content ) . toContain ( "{{issue.title}}" )
123113 } )
124114} )
125115
0 commit comments