@straion/cli 0.0.2 → 0.0.3
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/CHANGELOG.md +6 -0
- package/README.md +0 -4
- package/dist/cli.d.ts +0 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -7
- package/dist/cli.js.map +1 -1
- package/dist/commands/default.d.ts +1 -2
- package/dist/commands/default.d.ts.map +1 -1
- package/dist/commands/default.js +7 -42
- package/dist/commands/default.js.map +1 -1
- package/dist/commands/find-requirements.d.ts.map +1 -1
- package/dist/commands/find-requirements.integration.test.js +17 -56
- package/dist/commands/find-requirements.integration.test.js.map +1 -1
- package/dist/commands/find-requirements.js +20 -32
- package/dist/commands/find-requirements.js.map +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.integration.test.js +21 -142
- package/dist/commands/login.integration.test.js.map +1 -1
- package/dist/commands/login.js +10 -4
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +7 -22
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/session-start.d.ts.map +1 -1
- package/dist/commands/session-start.js +1 -8
- package/dist/commands/session-start.js.map +1 -1
- package/dist/commands/setup.d.ts +3 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +23 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/components/banner.d.ts +3 -0
- package/dist/components/banner.d.ts.map +1 -0
- package/dist/components/banner.js +13 -0
- package/dist/components/banner.js.map +1 -0
- package/dist/components/default-flow.d.ts +11 -0
- package/dist/components/default-flow.d.ts.map +1 -0
- package/dist/components/default-flow.js +64 -0
- package/dist/components/default-flow.js.map +1 -0
- package/dist/components/hero.d.ts.map +1 -1
- package/dist/components/hero.js +22 -28
- package/dist/components/hero.js.map +1 -1
- package/dist/components/login/login-error.d.ts.map +1 -1
- package/dist/components/login/login-error.js +2 -4
- package/dist/components/login/login-error.js.map +1 -1
- package/dist/components/login/login-flow.d.ts +3 -3
- package/dist/components/login/login-flow.d.ts.map +1 -1
- package/dist/components/login/login-flow.js +19 -49
- package/dist/components/login/login-flow.js.map +1 -1
- package/dist/components/login/login-flow.test.js +8 -8
- package/dist/components/login/login-flow.test.js.map +1 -1
- package/dist/components/login/user-settings-link.d.ts +3 -0
- package/dist/components/login/user-settings-link.d.ts.map +1 -0
- package/dist/components/login/user-settings-link.js +8 -0
- package/dist/components/login/user-settings-link.js.map +1 -0
- package/dist/components/multi-select.d.ts +16 -0
- package/dist/components/multi-select.d.ts.map +1 -0
- package/dist/components/multi-select.js +105 -0
- package/dist/components/multi-select.js.map +1 -0
- package/dist/components/org-selector.d.ts.map +1 -1
- package/dist/components/org-selector.js +3 -1
- package/dist/components/org-selector.js.map +1 -1
- package/dist/components/pat-input.js +1 -1
- package/dist/components/pat-input.js.map +1 -1
- package/dist/components/setup/agent-setup.d.ts +9 -0
- package/dist/components/setup/agent-setup.d.ts.map +1 -0
- package/dist/components/setup/agent-setup.js +65 -0
- package/dist/components/setup/agent-setup.js.map +1 -0
- package/dist/components/setup/agents/agent-registry.d.ts +44 -0
- package/dist/components/setup/agents/agent-registry.d.ts.map +1 -0
- package/dist/components/setup/agents/agent-registry.js +64 -0
- package/dist/components/setup/agents/agent-registry.js.map +1 -0
- package/dist/components/setup/agents/command-helpers.d.ts +5 -0
- package/dist/components/setup/agents/command-helpers.d.ts.map +1 -0
- package/dist/components/setup/agents/command-helpers.js +28 -0
- package/dist/components/setup/agents/command-helpers.js.map +1 -0
- package/dist/components/setup/checking-agents.d.ts +16 -0
- package/dist/components/setup/checking-agents.d.ts.map +1 -0
- package/dist/components/setup/checking-agents.js +30 -0
- package/dist/components/setup/checking-agents.js.map +1 -0
- package/dist/components/setup/download-skills-and-plugins.d.ts +9 -0
- package/dist/components/setup/download-skills-and-plugins.d.ts.map +1 -0
- package/dist/components/setup/download-skills-and-plugins.js +29 -0
- package/dist/components/setup/download-skills-and-plugins.js.map +1 -0
- package/dist/components/setup/perform-setup.d.ts +23 -0
- package/dist/components/setup/perform-setup.d.ts.map +1 -0
- package/dist/components/setup/perform-setup.js +45 -0
- package/dist/components/setup/perform-setup.js.map +1 -0
- package/dist/components/spinner.d.ts +6 -2
- package/dist/components/spinner.d.ts.map +1 -1
- package/dist/components/spinner.js +12 -3
- package/dist/components/spinner.js.map +1 -1
- package/dist/hooks/use-credentials.d.ts +13 -0
- package/dist/hooks/use-credentials.d.ts.map +1 -0
- package/dist/hooks/use-credentials.js +33 -0
- package/dist/hooks/use-credentials.js.map +1 -0
- package/dist/lib/graphql.d.ts +57 -41
- package/dist/lib/graphql.d.ts.map +1 -1
- package/dist/lib/graphql.js +7 -0
- package/dist/lib/graphql.js.map +1 -1
- package/dist/lib/logger.d.ts +13 -8
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +6 -29
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/login.d.ts.map +1 -1
- package/dist/lib/middleware.d.ts +4 -8
- package/dist/lib/middleware.d.ts.map +1 -1
- package/dist/lib/middleware.js +5 -9
- package/dist/lib/middleware.js.map +1 -1
- package/dist/lib/skills-manager.d.ts +33 -0
- package/dist/lib/skills-manager.d.ts.map +1 -0
- package/dist/lib/skills-manager.js +233 -0
- package/dist/lib/skills-manager.js.map +1 -0
- package/dist/lib/skills-manager.test.d.ts +7 -0
- package/dist/lib/skills-manager.test.d.ts.map +1 -0
- package/dist/lib/skills-manager.test.js +248 -0
- package/dist/lib/skills-manager.test.js.map +1 -0
- package/dist/state/global-config.d.ts +23 -9
- package/dist/state/global-config.d.ts.map +1 -1
- package/dist/state/global-config.js +42 -36
- package/dist/state/global-config.js.map +1 -1
- package/dist/state/session-manager.js +2 -2
- package/dist/state/session-manager.js.map +1 -1
- package/dist/test/integration-helpers.d.ts +0 -5
- package/dist/test/integration-helpers.d.ts.map +1 -1
- package/dist/test/integration-helpers.js +0 -16
- package/dist/test/integration-helpers.js.map +1 -1
- package/package.json +15 -4
- package/dist/lib/output.d.ts +0 -16
- package/dist/lib/output.d.ts.map +0 -1
- package/dist/lib/output.js +0 -14
- package/dist/lib/output.js.map +0 -1
- package/dist/state/directory-config.d.ts +0 -21
- package/dist/state/directory-config.d.ts.map +0 -1
- package/dist/state/directory-config.js +0 -59
- package/dist/state/directory-config.js.map +0 -1
- /package/{LICENSE.txt → LICENSE} +0 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
package/dist/cli.d.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import type { OutputFormat } from './lib/output.js';
|
|
4
|
-
export interface GlobalOptions {
|
|
5
|
-
outputFormat: OutputFormat;
|
|
6
|
-
}
|
|
7
3
|
export declare function createProgram(): Command;
|
|
8
4
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,aAAa,IAAI,OAAO,CAYvC"}
|
package/dist/cli.js
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import packageJson from '../package.json' with { type: 'json' };
|
|
4
|
+
import { runDefaultCommand } from './commands/default.js';
|
|
4
5
|
import { registerCommands } from './commands/index.js';
|
|
5
6
|
export function createProgram() {
|
|
6
7
|
const program = new Command();
|
|
7
8
|
program
|
|
8
9
|
.name('straion')
|
|
9
10
|
.description('Straion CLI - The Missing Piece for AI-Era Software Engineering at Scale')
|
|
10
|
-
.version(packageJson.version)
|
|
11
|
-
.option('-o, --output-format <format>', 'Output format: "text" for human-readable TUI, "json" for machine-readable', 'text');
|
|
11
|
+
.version(packageJson.version);
|
|
12
12
|
registerCommands(program);
|
|
13
|
-
program.action(
|
|
14
|
-
const opts = this.optsWithGlobals();
|
|
15
|
-
const { runDefaultCommand } = await import('./commands/default.js');
|
|
16
|
-
await runDefaultCommand(opts.outputFormat);
|
|
17
|
-
});
|
|
13
|
+
program.action(runDefaultCommand);
|
|
18
14
|
return program;
|
|
19
15
|
}
|
|
20
16
|
createProgram()
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,WAAW,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,WAAW,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,0EAA0E,CAAC;SACvF,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAEhC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE1B,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAElC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,aAAa,EAAE;KACZ,UAAU,EAAE;KACZ,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/commands/default.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/commands/default.tsx"],"names":[],"mappings":"AAQA,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAqBvD"}
|
package/dist/commands/default.js
CHANGED
|
@@ -1,53 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { createCredentialManager } from '../auth/credentials.js';
|
|
3
|
-
import {
|
|
3
|
+
import { DefaultFlow } from '../components/default-flow.js';
|
|
4
4
|
import { renderInk } from '../lib/ink-render.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export async function runDefaultCommand(outputFormat) {
|
|
10
|
-
const logger = createDefaultCommandLogger();
|
|
11
|
-
const isJsonOutput = outputFormat === 'json';
|
|
5
|
+
import { createLogger } from '../lib/logger.js';
|
|
6
|
+
import { config } from '../state/global-config.js';
|
|
7
|
+
export async function runDefaultCommand() {
|
|
8
|
+
const logger = createLogger();
|
|
12
9
|
try {
|
|
13
|
-
// Check if user is logged in
|
|
14
10
|
const credentialManager = await createCredentialManager();
|
|
15
11
|
const credentials = await credentialManager.getCredentials();
|
|
16
|
-
|
|
17
|
-
let organizations = null;
|
|
18
|
-
if (credentials) {
|
|
19
|
-
try {
|
|
20
|
-
const result = await loginUser(credentials.accessToken);
|
|
21
|
-
const resolvedOrg = resolveOrg(process.cwd());
|
|
22
|
-
// check with a successful login whether the user still has access to the local org
|
|
23
|
-
const stillHasAccessToOrg = resolvedOrg !== null &&
|
|
24
|
-
result.me.organizations.nodes.some((org) => org.id === resolvedOrg.id);
|
|
25
|
-
// set org to null if user no longer has access
|
|
26
|
-
localOrg = stillHasAccessToOrg ? resolvedOrg : null;
|
|
27
|
-
organizations = result.me.organizations.nodes;
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
logger.error({
|
|
31
|
-
error: error instanceof Error ? error.message : String(error),
|
|
32
|
-
}, 'Error during login or organization resolution');
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (isJsonOutput) {
|
|
36
|
-
outputJson({
|
|
37
|
-
authenticated: !!credentials,
|
|
38
|
-
user: credentials ? { name: credentials.name } : null,
|
|
39
|
-
organization: localOrg,
|
|
40
|
-
organizations: organizations,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
await renderInk(React.createElement(Hero, { localOrg: localOrg, credentials: credentials, organizations: organizations }));
|
|
45
|
-
}
|
|
12
|
+
await renderInk(React.createElement(DefaultFlow, { logger: logger, credentials: credentials, defaultSetupDismissed: config.setupDismissed }));
|
|
46
13
|
}
|
|
47
14
|
catch (error) {
|
|
48
|
-
logger.error({
|
|
49
|
-
error: error instanceof Error ? error.message : String(error),
|
|
50
|
-
}, 'Error during rendering');
|
|
15
|
+
logger.error({ error: error instanceof Error ? error.message : String(error) }, 'Error during rendering');
|
|
51
16
|
process.exit(1);
|
|
52
17
|
}
|
|
53
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/commands/default.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/commands/default.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,iBAAiB,GAAG,MAAM,uBAAuB,EAAE,CAAC;QAC1D,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,cAAc,EAAE,CAAC;QAE7D,MAAM,SAAS,CACb,oBAAC,WAAW,IACV,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,qBAAqB,EAAE,MAAM,CAAC,cAAc,GAC5C,CACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CACV,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACjE,wBAAwB,CACzB,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-requirements.d.ts","sourceRoot":"","sources":["../../src/commands/find-requirements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"find-requirements.d.ts","sourceRoot":"","sources":["../../src/commands/find-requirements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,6BAA6B,IAAI,OAAO,CA6DvD"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { graphql, HttpResponse } from 'msw';
|
|
5
5
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
|
6
6
|
import { RequirementScopeClassification } from '../lib/graphql.js';
|
|
7
|
-
import { createMeHandler, IntegrationTestContext
|
|
7
|
+
import { createMeHandler, IntegrationTestContext } from '../test/integration-helpers.js';
|
|
8
8
|
// Mock requirements data
|
|
9
9
|
const mockRequirements = [
|
|
10
10
|
{
|
|
@@ -69,63 +69,24 @@ afterAll(() => {
|
|
|
69
69
|
ctx.cleanup();
|
|
70
70
|
});
|
|
71
71
|
describe('find-requirements command', () => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
'--session',
|
|
79
|
-
'test-session',
|
|
80
|
-
'--title',
|
|
81
|
-
'authentication',
|
|
82
|
-
], { env: { STRAION_API_KEY: 'valid-test-token' } });
|
|
83
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
84
|
-
expect(parsed).not.toBeNull();
|
|
85
|
-
expect(Array.isArray(parsed)).toBe(true);
|
|
86
|
-
expect(parsed).toHaveLength(3);
|
|
87
|
-
expect(parsed?.at(0)?.content).toContain('Users must be able to log in with email and password');
|
|
88
|
-
expect(parsed?.at(0)?.collectionName).toBe('Security Requirements');
|
|
89
|
-
});
|
|
90
|
-
it('returns empty array when no requirements match', async () => {
|
|
91
|
-
const result = await ctx.runCLI(['-o', 'json', 'find-requirements', '--session', 'test-session'], { env: { STRAION_API_KEY: 'valid-test-token' } });
|
|
92
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
93
|
-
expect(parsed).not.toBeNull();
|
|
94
|
-
expect(Array.isArray(parsed)).toBe(true);
|
|
95
|
-
expect(parsed).toHaveLength(0);
|
|
96
|
-
});
|
|
97
|
-
it('includes all requirement fields in response', async () => {
|
|
98
|
-
const result = await ctx.runCLI(['-o', 'json', 'find-requirements', '--session', 'test-session', '--title', 'test'], { env: { STRAION_API_KEY: 'valid-test-token' } });
|
|
99
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
100
|
-
expect(parsed).not.toBeNull();
|
|
101
|
-
const firstReq = parsed?.at(0);
|
|
102
|
-
expect(firstReq).toHaveProperty('requirementId');
|
|
103
|
-
expect(firstReq).toHaveProperty('content');
|
|
104
|
-
expect(firstReq).toHaveProperty('scope');
|
|
105
|
-
expect(firstReq).toHaveProperty('scopeReasoning');
|
|
106
|
-
expect(firstReq).toHaveProperty('collectionName');
|
|
107
|
-
});
|
|
72
|
+
it('shows formatted requirements list', async () => {
|
|
73
|
+
const result = await ctx.runCLI(['find-requirements', '--session', 'test-session', '--title', 'authentication'], { env: { STRAION_API_KEY: 'valid-test-token' } });
|
|
74
|
+
expect(result.stdout).toContain('Found 3 matching requirement(s)');
|
|
75
|
+
expect(result.stdout).toContain('Security Requirements');
|
|
76
|
+
expect(result.stdout).toContain('Performance Requirements');
|
|
77
|
+
expect(result.stdout).toContain('Users must be able to log in with email and password');
|
|
108
78
|
});
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
expect(result.stdout).toContain('Found 3 matching requirement(s)');
|
|
113
|
-
expect(result.stdout).toContain('Security Requirements');
|
|
114
|
-
expect(result.stdout).toContain('Performance Requirements');
|
|
115
|
-
expect(result.stdout).toContain('Users must be able to log in with email and password');
|
|
116
|
-
});
|
|
117
|
-
it('shows message when no requirements found', async () => {
|
|
118
|
-
const result = await ctx.runCLI(['find-requirements', '--session', 'test-session'], {
|
|
119
|
-
env: { STRAION_API_KEY: 'valid-test-token' },
|
|
120
|
-
});
|
|
121
|
-
expect(result.stdout).toContain('No matching requirements found');
|
|
122
|
-
});
|
|
123
|
-
it('groups requirements by collection', async () => {
|
|
124
|
-
const result = await ctx.runCLI(['find-requirements', '--session', 'test-session', '--title', 'test'], { env: { STRAION_API_KEY: 'valid-test-token' } });
|
|
125
|
-
// Should show collection headers
|
|
126
|
-
expect(result.stdout).toContain('Security Requirements');
|
|
127
|
-
expect(result.stdout).toContain('Performance Requirements');
|
|
79
|
+
it('shows message when no requirements found', async () => {
|
|
80
|
+
const result = await ctx.runCLI(['find-requirements', '--session', 'test-session'], {
|
|
81
|
+
env: { STRAION_API_KEY: 'valid-test-token' },
|
|
128
82
|
});
|
|
83
|
+
expect(result.stdout).toContain('No matching requirements found');
|
|
84
|
+
});
|
|
85
|
+
it('groups requirements by collection', async () => {
|
|
86
|
+
const result = await ctx.runCLI(['find-requirements', '--session', 'test-session', '--title', 'test'], { env: { STRAION_API_KEY: 'valid-test-token' } });
|
|
87
|
+
// Should show collection headers
|
|
88
|
+
expect(result.stdout).toContain('Security Requirements');
|
|
89
|
+
expect(result.stdout).toContain('Performance Requirements');
|
|
129
90
|
});
|
|
130
91
|
});
|
|
131
92
|
//# sourceMappingURL=find-requirements.integration.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-requirements.integration.test.js","sourceRoot":"","sources":["../../src/commands/find-requirements.integration.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE1F,OAAO,EAAE,8BAA8B,EAAyB,MAAM,mBAAmB,CAAC;AAC1F,OAAO,
|
|
1
|
+
{"version":3,"file":"find-requirements.integration.test.js","sourceRoot":"","sources":["../../src/commands/find-requirements.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@ import { Command } from 'commander';
|
|
|
2
2
|
import { getGraphqlClient } from '../auth/graphql-client.js';
|
|
3
3
|
import { GetMatchingRequirementsForTaskDocument, } from '../lib/graphql.js';
|
|
4
4
|
import { withAuthAndLogging } from '../lib/middleware.js';
|
|
5
|
-
import { outputJson } from '../lib/output.js';
|
|
6
5
|
export function createFindRequirementsCommand() {
|
|
7
6
|
return new Command('find-requirements')
|
|
8
7
|
.requiredOption('--session <id>', 'Session ID from the calling agent')
|
|
@@ -10,8 +9,7 @@ export function createFindRequirementsCommand() {
|
|
|
10
9
|
.option('--body <body>', 'Body/content of the task', '')
|
|
11
10
|
.option('--summary <summary>', 'Summary of the entire plan', '')
|
|
12
11
|
.description('Find requirements matching a given task description')
|
|
13
|
-
.action(withAuthAndLogging(async (options, { organization, accessToken, logger
|
|
14
|
-
const isJsonOutput = outputFormat === 'json';
|
|
12
|
+
.action(withAuthAndLogging(async (options, { organization, accessToken, logger }) => {
|
|
15
13
|
try {
|
|
16
14
|
const client = getGraphqlClient(accessToken, organization.id);
|
|
17
15
|
const response = await client.request(GetMatchingRequirementsForTaskDocument, {
|
|
@@ -20,32 +18,27 @@ export function createFindRequirementsCommand() {
|
|
|
20
18
|
summary: options.summary,
|
|
21
19
|
});
|
|
22
20
|
const requirements = response.getMatchingRequirementsForTask;
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
// Text output: display requirements in readable format
|
|
22
|
+
if (requirements.length === 0) {
|
|
23
|
+
console.log('No matching requirements found.');
|
|
25
24
|
}
|
|
26
25
|
else {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const byCollection = new Map();
|
|
35
|
-
for (const req of requirements) {
|
|
36
|
-
const collectionName = req.collectionName;
|
|
37
|
-
if (!byCollection.has(collectionName)) {
|
|
38
|
-
byCollection.set(collectionName, []);
|
|
39
|
-
}
|
|
40
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
41
|
-
byCollection.get(collectionName).push(req);
|
|
26
|
+
console.log(`Found ${requirements.length} matching requirement(s):\n`);
|
|
27
|
+
// Group requirements by collection
|
|
28
|
+
const byCollection = new Map();
|
|
29
|
+
for (const req of requirements) {
|
|
30
|
+
const collectionName = req.collectionName;
|
|
31
|
+
if (!byCollection.has(collectionName)) {
|
|
32
|
+
byCollection.set(collectionName, []);
|
|
42
33
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
35
|
+
byCollection.get(collectionName).push(req);
|
|
36
|
+
}
|
|
37
|
+
for (const [collectionName, reqs] of byCollection) {
|
|
38
|
+
console.log(`Collection name: ${collectionName}`);
|
|
39
|
+
console.log('Requirements:');
|
|
40
|
+
for (const req of reqs) {
|
|
41
|
+
console.log(`- ${req.content} [${req.scope}] Reason: ${req.scopeReasoning}`);
|
|
49
42
|
}
|
|
50
43
|
}
|
|
51
44
|
}
|
|
@@ -53,12 +46,7 @@ export function createFindRequirementsCommand() {
|
|
|
53
46
|
}
|
|
54
47
|
catch (error) {
|
|
55
48
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
56
|
-
|
|
57
|
-
outputJson({ error: errorMessage });
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
console.error(`Error: ${errorMessage}`);
|
|
61
|
-
}
|
|
49
|
+
console.error(`Error: ${errorMessage}`);
|
|
62
50
|
process.exit(1);
|
|
63
51
|
}
|
|
64
52
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-requirements.js","sourceRoot":"","sources":["../../src/commands/find-requirements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACL,sCAAsC,GAGvC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"find-requirements.js","sourceRoot":"","sources":["../../src/commands/find-requirements.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAMvD"}
|
package/dist/commands/index.js
CHANGED
|
@@ -2,10 +2,12 @@ import { createFindRequirementsCommand } from './find-requirements.js';
|
|
|
2
2
|
import { createLoginCommand } from './login.js';
|
|
3
3
|
import { createLogoutCommand } from './logout.js';
|
|
4
4
|
import { createSessionStartCommand } from './session-start.js';
|
|
5
|
+
import { createSetupCommand } from './setup.js';
|
|
5
6
|
export function registerCommands(program) {
|
|
6
7
|
program.addCommand(createSessionStartCommand());
|
|
7
8
|
program.addCommand(createLoginCommand());
|
|
8
9
|
program.addCommand(createLogoutCommand());
|
|
9
10
|
program.addCommand(createFindRequirementsCommand());
|
|
11
|
+
program.addCommand(createSetupCommand());
|
|
10
12
|
}
|
|
11
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,CAAC,UAAU,CAAC,yBAAyB,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,UAAU,CAAC,6BAA6B,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,kBAAkB,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,kBAAkB,IAAI,OAAO,CA8D5C"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Run with: pnpm nx test cli -- --run src/commands/login.integration.test.ts
|
|
11
11
|
*/
|
|
12
12
|
import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest';
|
|
13
|
-
import { createMeHandler, IntegrationTestContext
|
|
13
|
+
import { createMeHandler, IntegrationTestContext } from '../test/integration-helpers.js';
|
|
14
14
|
const ctx = new IntegrationTestContext();
|
|
15
15
|
beforeAll(async () => {
|
|
16
16
|
await ctx.setupServer([createMeHandler()]);
|
|
@@ -39,150 +39,29 @@ function runLoginCLI(args, options = {}) {
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
describe('login command (non-interactive/integration)', () => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
// Should not output JSON (no -o json flag)
|
|
50
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
51
|
-
expect(parsed).toBeNull();
|
|
52
|
-
// Should exit with error
|
|
53
|
-
expect(result.exitCode).not.toBe(0);
|
|
54
|
-
});
|
|
55
|
-
it('shows text success message with valid token', async () => {
|
|
56
|
-
const result = await runLoginCLI(['login', '--token', 'valid-test-token']);
|
|
57
|
-
// Should not output JSON
|
|
58
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
59
|
-
expect(parsed).toBeNull();
|
|
60
|
-
// Should show TUI success message
|
|
61
|
-
expect(result.stdout).toContain('Hello');
|
|
62
|
-
expect(result.stdout).toContain('Test');
|
|
63
|
-
expect(result.stdout).toContain('logged in successfully');
|
|
64
|
-
expect(result.exitCode).toBe(0);
|
|
65
|
-
});
|
|
66
|
-
it('shows text error message with invalid token', async () => {
|
|
67
|
-
const result = await runLoginCLI(['login', '--token', 'invalid-token']);
|
|
68
|
-
// Should not output JSON
|
|
69
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
70
|
-
expect(parsed).toBeNull();
|
|
71
|
-
// Should show TUI error message
|
|
72
|
-
expect(result.stdout).toContain('Login failed');
|
|
73
|
-
expect(result.exitCode).not.toBe(0);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
describe('without token', () => {
|
|
77
|
-
it('outputs JSON error when no token is provided in non-TTY mode', async () => {
|
|
78
|
-
const result = await runLoginCLI(['-o', 'json', 'login'], {
|
|
79
|
-
env: {
|
|
80
|
-
// Explicitly clear STRAION_API_KEY to ensure no token is available
|
|
81
|
-
STRAION_API_KEY: '',
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
// In non-TTY mode without a token, should output JSON error
|
|
85
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
86
|
-
expect(parsed).not.toBeNull();
|
|
87
|
-
expect(parsed?.success).toBe(false);
|
|
88
|
-
expect(parsed?.error).toContain('Token required in non-interactive mode');
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
describe('with STRAION_API_KEY env var', () => {
|
|
92
|
-
it('authenticates successfully with valid token from env var', async () => {
|
|
93
|
-
const result = await runLoginCLI(['-o', 'json', 'login'], {
|
|
94
|
-
env: {
|
|
95
|
-
STRAION_API_KEY: 'valid-test-token',
|
|
96
|
-
},
|
|
97
|
-
});
|
|
98
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
99
|
-
expect(parsed).not.toBeNull();
|
|
100
|
-
expect(parsed?.success).toBe(true);
|
|
101
|
-
expect(parsed?.user?.id).toBe('user-123');
|
|
102
|
-
expect(parsed?.user?.name).toBe('Test User');
|
|
103
|
-
expect(parsed?.organization?.id).toBe('org-456');
|
|
104
|
-
expect(parsed?.organization?.name).toBe('Test Organization');
|
|
105
|
-
});
|
|
106
|
-
it('outputs error for invalid token from env var', async () => {
|
|
107
|
-
const result = await runLoginCLI(['-o', 'json', 'login'], {
|
|
108
|
-
env: {
|
|
109
|
-
STRAION_API_KEY: 'invalid-test-token',
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
113
|
-
expect(parsed).not.toBeNull();
|
|
114
|
-
expect(parsed?.success).toBe(false);
|
|
115
|
-
expect(parsed?.error).toContain('Authentication failed');
|
|
116
|
-
});
|
|
117
|
-
it('token flag takes precedence over STRAION_API_KEY', async () => {
|
|
118
|
-
// Pass invalid flag token but valid env token - should fail because flag takes precedence
|
|
119
|
-
const result = await runLoginCLI(['-o', 'json', 'login', '--token', 'invalid-flag-token'], {
|
|
120
|
-
env: {
|
|
121
|
-
STRAION_API_KEY: 'valid-test-token',
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
125
|
-
// Should fail because flag-token (invalid) takes precedence over env (valid)
|
|
126
|
-
expect(parsed).not.toBeNull();
|
|
127
|
-
expect(parsed?.success).toBe(false);
|
|
42
|
+
it('exits with error when no token is provided in non-TTY mode', async () => {
|
|
43
|
+
const result = await runLoginCLI(['login'], {
|
|
44
|
+
env: {
|
|
45
|
+
STRAION_API_KEY: '',
|
|
46
|
+
},
|
|
128
47
|
});
|
|
48
|
+
// Should exit with error
|
|
49
|
+
expect(result.exitCode).not.toBe(0);
|
|
129
50
|
});
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
expect(parsed?.user?.firstName).toBe('Test');
|
|
139
|
-
expect(parsed?.organization?.id).toBe('org-456');
|
|
140
|
-
expect(parsed?.organization?.name).toBe('Test Organization');
|
|
141
|
-
expect(parsed?.organization?.subdomain).toBe('test-org');
|
|
142
|
-
});
|
|
143
|
-
it('outputs JSON error for invalid token', async () => {
|
|
144
|
-
const result = await runLoginCLI(['-o', 'json', 'login', '--token', 'invalid-token']);
|
|
145
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
146
|
-
expect(parsed).not.toBeNull();
|
|
147
|
-
expect(parsed?.success).toBe(false);
|
|
148
|
-
expect(parsed?.error).toContain('Authentication failed');
|
|
149
|
-
});
|
|
51
|
+
it('shows text success message with valid token', async () => {
|
|
52
|
+
const result = await runLoginCLI(['login', '--token', 'valid-test-token']);
|
|
53
|
+
console.log(result);
|
|
54
|
+
// Should show TUI success message
|
|
55
|
+
expect(result.stdout).toContain('Hello');
|
|
56
|
+
expect(result.stdout).toContain('Test');
|
|
57
|
+
expect(result.stdout).toContain('logged in successfully');
|
|
58
|
+
expect(result.exitCode).toBe(0);
|
|
150
59
|
});
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
STRAION_API_KEY: '',
|
|
157
|
-
},
|
|
158
|
-
});
|
|
159
|
-
// Should be parseable as JSON
|
|
160
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
161
|
-
expect(parsed).not.toBeNull();
|
|
162
|
-
// Should have expected shape
|
|
163
|
-
expect(typeof parsed?.success).toBe('boolean');
|
|
164
|
-
if (!parsed?.success) {
|
|
165
|
-
expect(typeof parsed?.error).toBe('string');
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
it('success response includes all required fields', async () => {
|
|
169
|
-
const result = await runLoginCLI(['-o', 'json', 'login', '--token', 'valid-test-token']);
|
|
170
|
-
const parsed = parseJSONOutput(result.stdout);
|
|
171
|
-
expect(parsed).toEqual({
|
|
172
|
-
success: true,
|
|
173
|
-
user: {
|
|
174
|
-
id: 'user-123',
|
|
175
|
-
name: 'Test User',
|
|
176
|
-
firstName: 'Test',
|
|
177
|
-
},
|
|
178
|
-
organization: {
|
|
179
|
-
id: 'org-456',
|
|
180
|
-
name: 'Test Organization',
|
|
181
|
-
subdomain: 'test-org',
|
|
182
|
-
},
|
|
183
|
-
tokenSource: 'flag',
|
|
184
|
-
});
|
|
185
|
-
});
|
|
60
|
+
it('shows text error message with invalid token', async () => {
|
|
61
|
+
const result = await runLoginCLI(['login', '--token', 'invalid-token']);
|
|
62
|
+
// Should show TUI error message
|
|
63
|
+
expect(result.stdout).toContain('Login failed');
|
|
64
|
+
expect(result.exitCode).not.toBe(0);
|
|
186
65
|
});
|
|
187
66
|
});
|
|
188
67
|
//# sourceMappingURL=login.integration.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.integration.test.js","sourceRoot":"","sources":["../../src/commands/login.integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9E,OAAO,
|
|
1
|
+
{"version":3,"file":"login.integration.test.js","sourceRoot":"","sources":["../../src/commands/login.integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9E,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAEzF,MAAM,GAAG,GAAG,IAAI,sBAAsB,EAAE,CAAC;AAEzC,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,GAAG,CAAC,gBAAgB,EAAE,CAAC;AACzB,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,GAAG,EAAE;IACZ,GAAG,CAAC,OAAO,EAAE,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,SAAS,WAAW,CAClB,IAAc,EACd,UAA8D,EAAE;IAEhE,wEAAwE;IACxE,qEAAqE;IACrE,GAAG,CAAC,cAAc,EAAE,CAAC;IAErB,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;QACtB,GAAG,OAAO;QACV,GAAG,EAAE;YACH,4CAA4C;YAC5C,eAAe,EAAE,EAAE;YACnB,GAAG,OAAO,CAAC,GAAG;SACf;KACF,CAAC,CAAC;AACL,CAAC;AAED,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;IAC3D,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE;YAC1C,GAAG,EAAE;gBACH,eAAe,EAAE,EAAE;aACpB;SACF,CAAC,CAAC;QACH,yBAAyB;QACzB,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAE3E,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,kCAAkC;QAClC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;QAExE,gCAAgC;QAChC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|