@straion/cli 0.0.1 → 0.0.2
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 +7 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/default.d.ts +2 -1
- package/dist/commands/default.d.ts.map +1 -1
- package/dist/commands/default.js +15 -3
- 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.d.ts +5 -0
- package/dist/commands/find-requirements.integration.test.d.ts.map +1 -0
- package/dist/commands/find-requirements.integration.test.js +131 -0
- package/dist/commands/find-requirements.integration.test.js.map +1 -0
- package/dist/commands/find-requirements.js +36 -5
- package/dist/commands/find-requirements.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.integration.test.d.ts +13 -0
- package/dist/commands/login.integration.test.d.ts.map +1 -0
- package/dist/commands/login.integration.test.js +188 -0
- package/dist/commands/login.integration.test.js.map +1 -0
- package/dist/commands/login.js +13 -4
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +19 -9
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/session-start.d.ts.map +1 -1
- package/dist/commands/session-start.js +8 -2
- package/dist/commands/session-start.js.map +1 -1
- package/dist/components/button.d.ts +2 -2
- package/dist/components/button.d.ts.map +1 -1
- package/dist/components/button.js +3 -3
- package/dist/components/button.js.map +1 -1
- package/dist/components/hero.d.ts +2 -1
- package/dist/components/hero.d.ts.map +1 -1
- package/dist/components/hero.js +76 -10
- package/dist/components/hero.js.map +1 -1
- package/dist/components/link.d.ts +2 -2
- package/dist/components/link.d.ts.map +1 -1
- package/dist/components/link.js +3 -3
- package/dist/components/link.js.map +1 -1
- package/dist/components/login/login-error.d.ts +6 -0
- package/dist/components/login/login-error.d.ts.map +1 -0
- package/dist/components/login/login-error.js +16 -0
- package/dist/components/login/login-error.js.map +1 -0
- package/dist/components/login/login-flow.d.ts +8 -2
- package/dist/components/login/login-flow.d.ts.map +1 -1
- package/dist/components/login/login-flow.js +123 -82
- package/dist/components/login/login-flow.js.map +1 -1
- package/dist/components/login/login-flow.test.js +69 -7
- package/dist/components/login/login-flow.test.js.map +1 -1
- package/dist/components/login/types.d.ts +2 -0
- package/dist/components/login/types.d.ts.map +1 -0
- package/dist/components/login/types.js +2 -0
- package/dist/components/login/types.js.map +1 -0
- package/dist/components/org-selector.d.ts +2 -1
- package/dist/components/org-selector.d.ts.map +1 -1
- package/dist/components/org-selector.js +7 -2
- package/dist/components/org-selector.js.map +1 -1
- package/dist/components/pat-input.d.ts +2 -1
- package/dist/components/pat-input.d.ts.map +1 -1
- package/dist/components/pat-input.js +9 -3
- package/dist/components/pat-input.js.map +1 -1
- package/dist/components/pat-input.test.js +8 -8
- package/dist/components/pat-input.test.js.map +1 -1
- package/dist/components/spinner.d.ts +2 -1
- package/dist/components/spinner.d.ts.map +1 -1
- package/dist/components/spinner.js +2 -3
- package/dist/components/spinner.js.map +1 -1
- package/dist/components/tabs.d.ts +3 -3
- package/dist/components/tabs.d.ts.map +1 -1
- package/dist/components/tabs.js +26 -21
- package/dist/components/tabs.js.map +1 -1
- package/dist/lib/ink-render.d.ts +1 -1
- package/dist/lib/ink-render.js +1 -1
- package/dist/lib/middleware.d.ts +9 -4
- package/dist/lib/middleware.d.ts.map +1 -1
- package/dist/lib/middleware.js +23 -7
- package/dist/lib/middleware.js.map +1 -1
- package/dist/lib/output.d.ts +16 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +14 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/test/integration-helpers.d.ts +101 -0
- package/dist/test/integration-helpers.d.ts.map +1 -0
- package/dist/test/integration-helpers.js +187 -0
- package/dist/test/integration-helpers.js.map +1 -0
- package/package.json +3 -1
- package/dist/auth/cookie-jar.d.ts +0 -24
- package/dist/auth/cookie-jar.d.ts.map +0 -1
- package/dist/auth/cookie-jar.js +0 -45
- package/dist/auth/cookie-jar.js.map +0 -1
- package/dist/components/login/login.provider.d.ts +0 -2
- package/dist/components/login/login.provider.d.ts.map +0 -1
- package/dist/components/login/login.provider.js +0 -2
- package/dist/components/login/login.provider.js.map +0 -1
- package/dist/components/login/login.store.d.ts +0 -2
- package/dist/components/login/login.store.d.ts.map +0 -1
- package/dist/components/login/login.store.js +0 -2
- package/dist/components/login/login.store.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## 0.0.2 (January 30, 2026)
|
|
2
|
+
|
|
3
|
+
- Fixes issues when running in non interactive terminals
|
|
4
|
+
- Adds support to login with the STRAION_API_KEY environment variable
|
|
5
|
+
- Adds `--output-format` flag to all commands that accepts `json` and `text` values. It uses `text` by default which renders a rich terminal user interface.
|
|
6
|
+
|
|
7
|
+
|
|
1
8
|
## 0.0.1 (January 26, 2026)
|
|
2
9
|
|
|
3
10
|
- Initial release with login, logout, and session management
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
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
|
+
}
|
|
3
7
|
export declare function createProgram(): Command;
|
|
4
8
|
//# 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;AAKpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,wBAAgB,aAAa,IAAI,OAAO,CAqBvC"}
|
package/dist/cli.js
CHANGED
|
@@ -7,11 +7,13 @@ export function createProgram() {
|
|
|
7
7
|
program
|
|
8
8
|
.name('straion')
|
|
9
9
|
.description('Straion CLI - The Missing Piece for AI-Era Software Engineering at Scale')
|
|
10
|
-
.version(packageJson.version)
|
|
10
|
+
.version(packageJson.version)
|
|
11
|
+
.option('-o, --output-format <format>', 'Output format: "text" for human-readable TUI, "json" for machine-readable', 'text');
|
|
11
12
|
registerCommands(program);
|
|
12
|
-
program.action(async ()
|
|
13
|
+
program.action(async function () {
|
|
14
|
+
const opts = this.optsWithGlobals();
|
|
13
15
|
const { runDefaultCommand } = await import('./commands/default.js');
|
|
14
|
-
await runDefaultCommand();
|
|
16
|
+
await runDefaultCommand(opts.outputFormat);
|
|
15
17
|
});
|
|
16
18
|
return program;
|
|
17
19
|
}
|
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,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAOvD,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;SAC5B,MAAM,CACL,8BAA8B,EAC9B,2EAA2E,EAC3E,MAAM,CACP,CAAC;IAEJ,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE1B,OAAO,CAAC,MAAM,CAAC,KAAK;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,EAAiB,CAAC;QACnD,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QACpE,MAAM,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,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":"AAOA,wBAAsB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/commands/default.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,YAAY,EAAc,MAAM,kBAAkB,CAAC;AAGjE,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDjF"}
|
package/dist/commands/default.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { createCredentialManager } from '../auth/credentials.js';
|
|
3
3
|
import { Hero } from '../components/hero.js';
|
|
4
4
|
import { renderInk } from '../lib/ink-render.js';
|
|
5
5
|
import { createDefaultCommandLogger } from '../lib/logger.js';
|
|
6
6
|
import { loginUser } from '../lib/login.js';
|
|
7
|
+
import { outputJson } from '../lib/output.js';
|
|
7
8
|
import { resolveOrg } from '../state/directory-config.js';
|
|
8
|
-
export async function runDefaultCommand() {
|
|
9
|
+
export async function runDefaultCommand(outputFormat) {
|
|
9
10
|
const logger = createDefaultCommandLogger();
|
|
11
|
+
const isJsonOutput = outputFormat === 'json';
|
|
10
12
|
try {
|
|
11
13
|
// Check if user is logged in
|
|
12
14
|
const credentialManager = await createCredentialManager();
|
|
@@ -30,7 +32,17 @@ export async function runDefaultCommand() {
|
|
|
30
32
|
}, 'Error during login or organization resolution');
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
|
-
|
|
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
|
+
}
|
|
34
46
|
}
|
|
35
47
|
catch (error) {
|
|
36
48
|
logger.error({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/commands/default.tsx"],"names":[],"mappings":"
|
|
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,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAqB,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,YAA0B;IAChE,MAAM,MAAM,GAAG,0BAA0B,EAAE,CAAC;IAC5C,MAAM,YAAY,GAAG,YAAY,KAAK,MAAM,CAAC;IAE7C,IAAI,CAAC;QACH,6BAA6B;QAC7B,MAAM,iBAAiB,GAAG,MAAM,uBAAuB,EAAE,CAAC;QAC1D,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,cAAc,EAAE,CAAC;QAE7D,IAAI,QAAQ,GAAG,IAAI,CAAC;QACpB,IAAI,aAAa,GAAG,IAAI,CAAC;QAEzB,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;gBACxD,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC9C,mFAAmF;gBACnF,MAAM,mBAAmB,GACvB,WAAW,KAAK,IAAI;oBACpB,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,WAAW,CAAC,EAAE,CAAC,CAAC;gBACzE,+CAA+C;gBAC/C,QAAQ,GAAG,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;gBACpD,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC;YAChD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CACV;oBACE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,EACD,+CAA+C,CAChD,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,UAAU,CAAC;gBACT,aAAa,EAAE,CAAC,CAAC,WAAW;gBAC5B,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI;gBACrD,YAAY,EAAE,QAAQ;gBACtB,aAAa,EAAE,aAAa;aAC7B,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,CACb,oBAAC,IAAI,IAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,GAAI,CACrF,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CACV;YACE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,EACD,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;AAWpC,wBAAgB,6BAA6B,IAAI,OAAO,CAuEvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-requirements.integration.test.d.ts","sourceRoot":"","sources":["../../src/commands/find-requirements.integration.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for the find-requirements command.
|
|
3
|
+
*/
|
|
4
|
+
import { graphql, HttpResponse } from 'msw';
|
|
5
|
+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
|
6
|
+
import { RequirementScopeClassification } from '../lib/graphql.js';
|
|
7
|
+
import { createMeHandler, IntegrationTestContext, parseJSONOutput, } from '../test/integration-helpers.js';
|
|
8
|
+
// Mock requirements data
|
|
9
|
+
const mockRequirements = [
|
|
10
|
+
{
|
|
11
|
+
requirementId: 'req-1',
|
|
12
|
+
content: 'Users must be able to log in with email and password',
|
|
13
|
+
scope: RequirementScopeClassification.InScope,
|
|
14
|
+
scopeReasoning: 'Core auth functionality',
|
|
15
|
+
collectionName: 'Security Requirements',
|
|
16
|
+
collectionId: 'col-1',
|
|
17
|
+
finalScore: 0.95,
|
|
18
|
+
scopeConfidence: 0.9,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
requirementId: 'req-2',
|
|
22
|
+
content: 'All API endpoints must validate input',
|
|
23
|
+
scope: RequirementScopeClassification.InScope,
|
|
24
|
+
scopeReasoning: 'Security best practice',
|
|
25
|
+
collectionName: 'Security Requirements',
|
|
26
|
+
collectionId: 'col-1',
|
|
27
|
+
finalScore: 0.9,
|
|
28
|
+
scopeConfidence: 0.8,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
requirementId: 'req-3',
|
|
32
|
+
content: 'Dashboard must load within 2 seconds',
|
|
33
|
+
scope: RequirementScopeClassification.Uncertain,
|
|
34
|
+
scopeReasoning: 'User experience',
|
|
35
|
+
collectionName: 'Performance Requirements',
|
|
36
|
+
collectionId: 'col-2',
|
|
37
|
+
finalScore: 0.75,
|
|
38
|
+
scopeConfidence: 0.2,
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
// GraphQL handler for requirements
|
|
42
|
+
const requirementsHandler = graphql.query('getMatchingRequirementsForTask', ({ request, variables }) => {
|
|
43
|
+
const authHeader = request.headers.get('Authorization');
|
|
44
|
+
if (authHeader !== 'Bearer valid-test-token') {
|
|
45
|
+
return HttpResponse.json({ errors: [{ message: 'Unauthorized' }] }, { status: 401 });
|
|
46
|
+
}
|
|
47
|
+
// Return empty results if no search criteria provided
|
|
48
|
+
if (!variables.title && !variables.body && !variables.summary) {
|
|
49
|
+
return HttpResponse.json({
|
|
50
|
+
data: { getMatchingRequirementsForTask: [] },
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return HttpResponse.json({
|
|
54
|
+
data: { getMatchingRequirementsForTask: mockRequirements },
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
const ctx = new IntegrationTestContext();
|
|
58
|
+
beforeAll(async () => {
|
|
59
|
+
await ctx.setupServer([createMeHandler(), requirementsHandler]);
|
|
60
|
+
});
|
|
61
|
+
beforeEach(() => {
|
|
62
|
+
ctx.setupConfigDir();
|
|
63
|
+
ctx.writeOrgConfig(); // find-requirements requires authenticated context
|
|
64
|
+
});
|
|
65
|
+
afterEach(() => {
|
|
66
|
+
ctx.cleanupConfigDir();
|
|
67
|
+
});
|
|
68
|
+
afterAll(() => {
|
|
69
|
+
ctx.cleanup();
|
|
70
|
+
});
|
|
71
|
+
describe('find-requirements command', () => {
|
|
72
|
+
describe('JSON output (-o json)', () => {
|
|
73
|
+
it('returns requirements array for valid search', async () => {
|
|
74
|
+
const result = await ctx.runCLI([
|
|
75
|
+
'-o',
|
|
76
|
+
'json',
|
|
77
|
+
'find-requirements',
|
|
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
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe('text output (default)', () => {
|
|
110
|
+
it('shows formatted requirements list', async () => {
|
|
111
|
+
const result = await ctx.runCLI(['find-requirements', '--session', 'test-session', '--title', 'authentication'], { env: { STRAION_API_KEY: 'valid-test-token' } });
|
|
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');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
//# sourceMappingURL=find-requirements.integration.test.js.map
|
|
@@ -0,0 +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,EACL,eAAe,EACf,sBAAsB,EACtB,eAAe,GAChB,MAAM,gCAAgC,CAAC;AAExC,yBAAyB;AACzB,MAAM,gBAAgB,GAAuB;IAC3C;QACE,aAAa,EAAE,OAAO;QACtB,OAAO,EAAE,sDAAsD;QAC/D,KAAK,EAAE,8BAA8B,CAAC,OAAO;QAC7C,cAAc,EAAE,yBAAyB;QACzC,cAAc,EAAE,uBAAuB;QACvC,YAAY,EAAE,OAAO;QACrB,UAAU,EAAE,IAAI;QAChB,eAAe,EAAE,GAAG;KACrB;IACD;QACE,aAAa,EAAE,OAAO;QACtB,OAAO,EAAE,uCAAuC;QAChD,KAAK,EAAE,8BAA8B,CAAC,OAAO;QAC7C,cAAc,EAAE,wBAAwB;QACxC,cAAc,EAAE,uBAAuB;QACvC,YAAY,EAAE,OAAO;QACrB,UAAU,EAAE,GAAG;QACf,eAAe,EAAE,GAAG;KACrB;IACD;QACE,aAAa,EAAE,OAAO;QACtB,OAAO,EAAE,sCAAsC;QAC/C,KAAK,EAAE,8BAA8B,CAAC,SAAS;QAC/C,cAAc,EAAE,iBAAiB;QACjC,cAAc,EAAE,0BAA0B;QAC1C,YAAY,EAAE,OAAO;QACrB,UAAU,EAAE,IAAI;QAChB,eAAe,EAAE,GAAG;KACrB;CACF,CAAC;AAEF,mCAAmC;AACnC,MAAM,mBAAmB,GAAG,OAAO,CAAC,KAAK,CACvC,gCAAgC,EAChC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE;IACzB,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAExD,IAAI,UAAU,KAAK,yBAAyB,EAAE,CAAC;QAC7C,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACvF,CAAC;IAED,sDAAsD;IACtD,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAC9D,OAAO,YAAY,CAAC,IAAI,CAAC;YACvB,IAAI,EAAE,EAAE,8BAA8B,EAAE,EAAE,EAAE;SAC7C,CAAC,CAAC;IACL,CAAC;IAED,OAAO,YAAY,CAAC,IAAI,CAAC;QACvB,IAAI,EAAE,EAAE,8BAA8B,EAAE,gBAAgB,EAAE;KAC3D,CAAC,CAAC;AACL,CAAC,CACF,CAAC;AAEF,MAAM,GAAG,GAAG,IAAI,sBAAsB,EAAE,CAAC;AAEzC,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC,eAAe,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEH,UAAU,CAAC,GAAG,EAAE;IACd,GAAG,CAAC,cAAc,EAAE,CAAC;IACrB,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,mDAAmD;AAC3E,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,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAC7B;gBACE,IAAI;gBACJ,MAAM;gBACN,mBAAmB;gBACnB,WAAW;gBACX,cAAc;gBACd,SAAS;gBACT,gBAAgB;aACjB,EACD,EAAE,GAAG,EAAE,EAAE,eAAe,EAAE,kBAAkB,EAAE,EAAE,CACjD,CAAC;YAEF,MAAM,MAAM,GAAG,eAAe,CAA0B,MAAM,CAAC,MAAM,CAAC,CAAC;YAEvE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,SAAS,CACtC,sDAAsD,CACvD,CAAC;YACF,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAC7B,CAAC,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,WAAW,EAAE,cAAc,CAAC,EAChE,EAAE,GAAG,EAAE,EAAE,eAAe,EAAE,kBAAkB,EAAE,EAAE,CACjD,CAAC;YAEF,MAAM,MAAM,GAAG,eAAe,CAA0B,MAAM,CAAC,MAAM,CAAC,CAAC;YAEvE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAC7B,CAAC,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,CAAC,EACnF,EAAE,GAAG,EAAE,EAAE,eAAe,EAAE,kBAAkB,EAAE,EAAE,CACjD,CAAC;YAEF,MAAM,MAAM,GAAG,eAAe,CAA0B,MAAM,CAAC,MAAM,CAAC,CAAC;YAEvE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;YACjD,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YAC3C,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACzC,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;YAClD,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACjD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAC7B,CAAC,mBAAmB,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,CAAC,EAC/E,EAAE,GAAG,EAAE,EAAE,eAAe,EAAE,kBAAkB,EAAE,EAAE,CACjD,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;YACnE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;YACzD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;YAC5D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,sDAAsD,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,mBAAmB,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE;gBAClF,GAAG,EAAE,EAAE,eAAe,EAAE,kBAAkB,EAAE;aAC7C,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACjD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAC7B,CAAC,mBAAmB,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,CAAC,EACrE,EAAE,GAAG,EAAE,EAAE,eAAe,EAAE,kBAAkB,EAAE,EAAE,CACjD,CAAC;YAEF,iCAAiC;YACjC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;YACzD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -2,6 +2,7 @@ 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';
|
|
5
6
|
export function createFindRequirementsCommand() {
|
|
6
7
|
return new Command('find-requirements')
|
|
7
8
|
.requiredOption('--session <id>', 'Session ID from the calling agent')
|
|
@@ -9,7 +10,8 @@ export function createFindRequirementsCommand() {
|
|
|
9
10
|
.option('--body <body>', 'Body/content of the task', '')
|
|
10
11
|
.option('--summary <summary>', 'Summary of the entire plan', '')
|
|
11
12
|
.description('Find requirements matching a given task description')
|
|
12
|
-
.action(withAuthAndLogging(async (options, { organization, accessToken, logger }) => {
|
|
13
|
+
.action(withAuthAndLogging(async (options, { organization, accessToken, logger, outputFormat }) => {
|
|
14
|
+
const isJsonOutput = outputFormat === 'json';
|
|
13
15
|
try {
|
|
14
16
|
const client = getGraphqlClient(accessToken, organization.id);
|
|
15
17
|
const response = await client.request(GetMatchingRequirementsForTaskDocument, {
|
|
@@ -18,15 +20,44 @@ export function createFindRequirementsCommand() {
|
|
|
18
20
|
summary: options.summary,
|
|
19
21
|
});
|
|
20
22
|
const requirements = response.getMatchingRequirementsForTask;
|
|
21
|
-
|
|
23
|
+
if (isJsonOutput) {
|
|
24
|
+
outputJson(requirements);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// Text output: display requirements in readable format
|
|
28
|
+
if (requirements.length === 0) {
|
|
29
|
+
console.log('No matching requirements found.');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
console.log(`Found ${requirements.length} matching requirement(s):\n`);
|
|
33
|
+
// Group requirements by collection
|
|
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);
|
|
42
|
+
}
|
|
43
|
+
for (const [collectionName, reqs] of byCollection) {
|
|
44
|
+
console.log(`Collection name: ${collectionName}`);
|
|
45
|
+
console.log('Requirements:');
|
|
46
|
+
for (const req of reqs) {
|
|
47
|
+
console.log(`- ${req.content} [${req.scope}] Reason: ${req.scopeReasoning}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
22
52
|
logger.info({ requirements, title: options.title, body: options.body, summary: options.summary }, 'Fetched matching requirements');
|
|
23
53
|
}
|
|
24
54
|
catch (error) {
|
|
25
|
-
|
|
26
|
-
|
|
55
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
56
|
+
if (isJsonOutput) {
|
|
57
|
+
outputJson({ error: errorMessage });
|
|
27
58
|
}
|
|
28
59
|
else {
|
|
29
|
-
console.error(
|
|
60
|
+
console.error(`Error: ${errorMessage}`);
|
|
30
61
|
}
|
|
31
62
|
process.exit(1);
|
|
32
63
|
}
|
|
@@ -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":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
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,CAwD5C"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for the login command in non-interactive mode.
|
|
3
|
+
*
|
|
4
|
+
* These tests spawn the actual CLI as a child process to test real behavior
|
|
5
|
+
* in non-TTY environments (CI/CD, piped input, scripts).
|
|
6
|
+
*
|
|
7
|
+
* Uses MSW (Mock Service Worker) with @mswjs/http-middleware to spawn a real
|
|
8
|
+
* HTTP server that the CLI child process can connect to.
|
|
9
|
+
*
|
|
10
|
+
* Run with: pnpm nx test cli -- --run src/commands/login.integration.test.ts
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=login.integration.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.integration.test.d.ts","sourceRoot":"","sources":["../../src/commands/login.integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for the login command in non-interactive mode.
|
|
3
|
+
*
|
|
4
|
+
* These tests spawn the actual CLI as a child process to test real behavior
|
|
5
|
+
* in non-TTY environments (CI/CD, piped input, scripts).
|
|
6
|
+
*
|
|
7
|
+
* Uses MSW (Mock Service Worker) with @mswjs/http-middleware to spawn a real
|
|
8
|
+
* HTTP server that the CLI child process can connect to.
|
|
9
|
+
*
|
|
10
|
+
* Run with: pnpm nx test cli -- --run src/commands/login.integration.test.ts
|
|
11
|
+
*/
|
|
12
|
+
import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest';
|
|
13
|
+
import { createMeHandler, IntegrationTestContext, parseJSONOutput, } from '../test/integration-helpers.js';
|
|
14
|
+
const ctx = new IntegrationTestContext();
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
await ctx.setupServer([createMeHandler()]);
|
|
17
|
+
});
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
ctx.cleanupConfigDir();
|
|
20
|
+
});
|
|
21
|
+
afterAll(() => {
|
|
22
|
+
ctx.cleanup();
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* Run CLI for login tests.
|
|
26
|
+
* This is a wrapper that uses the context's mock server URL.
|
|
27
|
+
*/
|
|
28
|
+
function runLoginCLI(args, options = {}) {
|
|
29
|
+
// For login tests, we set up a minimal config dir just for the test run
|
|
30
|
+
// but don't write any credentials (since we're testing login itself)
|
|
31
|
+
ctx.setupConfigDir();
|
|
32
|
+
return ctx.runCLI(args, {
|
|
33
|
+
...options,
|
|
34
|
+
env: {
|
|
35
|
+
// Default to empty API key unless specified
|
|
36
|
+
STRAION_API_KEY: '',
|
|
37
|
+
...options.env,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
describe('login command (non-interactive/integration)', () => {
|
|
42
|
+
describe('text output (default)', () => {
|
|
43
|
+
it('exits with error when no token is provided in non-TTY mode', async () => {
|
|
44
|
+
const result = await runLoginCLI(['login'], {
|
|
45
|
+
env: {
|
|
46
|
+
STRAION_API_KEY: '',
|
|
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);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe('with --token flag', () => {
|
|
131
|
+
it('authenticates successfully with valid token', async () => {
|
|
132
|
+
const result = await runLoginCLI(['-o', 'json', 'login', '--token', 'valid-test-token']);
|
|
133
|
+
const parsed = parseJSONOutput(result.stdout);
|
|
134
|
+
expect(parsed).not.toBeNull();
|
|
135
|
+
expect(parsed?.success).toBe(true);
|
|
136
|
+
expect(parsed?.user?.id).toBe('user-123');
|
|
137
|
+
expect(parsed?.user?.name).toBe('Test User');
|
|
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
|
+
});
|
|
150
|
+
});
|
|
151
|
+
describe('JSON output format', () => {
|
|
152
|
+
it('outputs valid JSON that can be parsed by scripts', async () => {
|
|
153
|
+
const result = await runLoginCLI(['-o', 'json', 'login'], {
|
|
154
|
+
env: {
|
|
155
|
+
// Explicitly clear STRAION_API_KEY
|
|
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
|
+
});
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
//# sourceMappingURL=login.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.integration.test.js","sourceRoot":"","sources":["../../src/commands/login.integration.test.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/login.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
1
|
import { Command } from 'commander';
|
|
2
|
+
import React from 'react';
|
|
3
3
|
import { createCredentialManager } from '../auth/credentials.js';
|
|
4
4
|
import { LoginFlow } from '../components/login/login-flow.js';
|
|
5
5
|
import {} from '../lib/graphql.js';
|
|
@@ -10,10 +10,18 @@ export function createLoginCommand() {
|
|
|
10
10
|
return new Command('login')
|
|
11
11
|
.description('Authenticate with a Personal Access Token')
|
|
12
12
|
.option('--token <token>', 'Personal Access Token')
|
|
13
|
-
.action(withLogging(async (options, { logger }) => {
|
|
13
|
+
.action(withLogging(async (options, { logger, outputFormat }) => {
|
|
14
14
|
try {
|
|
15
|
+
// Token resolution: --token flag takes precedence over env var
|
|
16
|
+
const token = options.token || process.env.STRAION_API_KEY;
|
|
17
|
+
const tokenSource = options.token
|
|
18
|
+
? 'flag'
|
|
19
|
+
: process.env.STRAION_API_KEY
|
|
20
|
+
? 'env'
|
|
21
|
+
: 'input';
|
|
22
|
+
const skipOrgSelection = !!token;
|
|
15
23
|
const { promise, resolve, reject } = createInkPromise();
|
|
16
|
-
await renderInk(
|
|
24
|
+
await renderInk(React.createElement(LoginFlow, { defaultPat: token, tokenSource: tokenSource, skipOrgSelection: skipOrgSelection, outputFormat: outputFormat, onComplete: (user, org, pat) => resolve({ user, org, pat }), onError: (error) => reject(error) }));
|
|
17
25
|
const { user, org, pat } = await promise;
|
|
18
26
|
// Store credentials in secure storage
|
|
19
27
|
const credentialManager = await createCredentialManager();
|
|
@@ -29,7 +37,8 @@ export function createLoginCommand() {
|
|
|
29
37
|
logger.error({
|
|
30
38
|
error: error instanceof Error ? error.message : String(error),
|
|
31
39
|
}, 'Error during login');
|
|
32
|
-
|
|
40
|
+
// Use setImmediate to allow stdout to flush before exiting
|
|
41
|
+
setImmediate(() => process.exit(1));
|
|
33
42
|
}
|
|
34
43
|
}));
|
|
35
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAE9D,OAAO,EAAwD,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;SACxB,WAAW,CAAC,2CAA2C,CAAC;SACxD,MAAM,CAAC,iBAAiB,EAAE,uBAAuB,CAAC;SAClD,MAAM,CACL,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE;QACtD,IAAI,CAAC;YACH,+DAA+D;YAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;YAC3D,MAAM,WAAW,GAAgB,OAAO,CAAC,KAAK;gBAC5C,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe;oBAC3B,CAAC,CAAC,KAAK;oBACP,CAAC,CAAC,OAAO,CAAC;YACd,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC;YAEjC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,gBAAgB,EAIjD,CAAC;YAEL,MAAM,SAAS,CACb,oBAAC,SAAS,IACR,UAAU,EAAE,KAAK,EACjB,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAC3D,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GACjC,CACH,CAAC;YAEF,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,CAAC;YAEzC,sCAAsC;YACtC,MAAM,iBAAiB,GAAG,MAAM,uBAAuB,EAAE,CAAC;YAC1D,MAAM,iBAAiB,CAAC,cAAc,CAAC;gBACrC,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI;gBACjC,WAAW,EAAE,GAAG;aACjB,CAAC,CAAC;YACH,mBAAmB;YACnB,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CACV;gBACE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,EACD,oBAAoB,CACrB,CAAC;YACF,2DAA2D;YAC3D,YAAY,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC,CACH,CAAC;AACN,CAAC"}
|