@aifabrix/builder 2.54.1 → 2.55.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/README.md +8 -0
- package/lib/agent-kit/apply-ops.js +82 -0
- package/lib/agent-kit/checksums.js +28 -0
- package/lib/agent-kit/classify.js +113 -0
- package/lib/agent-kit/claude-shim.js +61 -0
- package/lib/agent-kit/constants.js +55 -0
- package/lib/agent-kit/file-list.js +103 -0
- package/lib/agent-kit/host-approve.js +172 -0
- package/lib/agent-kit/hosting/github.js +63 -0
- package/lib/agent-kit/hosts.js +71 -0
- package/lib/agent-kit/init.js +319 -0
- package/lib/agent-kit/kit-root.js +17 -0
- package/lib/agent-kit/managed-section.js +79 -0
- package/lib/agent-kit/package-load.js +45 -0
- package/lib/agent-kit/plan-ops.js +69 -0
- package/lib/agent-kit/remote-prompts.js +272 -0
- package/lib/agent-kit/render-host-markdown.js +40 -0
- package/lib/agent-kit/repo-guard.js +47 -0
- package/lib/agent-kit/report.js +107 -0
- package/lib/agent-kit/run.js +82 -0
- package/lib/agent-kit/scm/git.js +122 -0
- package/lib/agent-kit/start.js +310 -0
- package/lib/agent-kit/state-file.js +83 -0
- package/lib/agent-kit/status.js +50 -0
- package/lib/agent-kit/v1-detect.js +81 -0
- package/lib/agent-kit/validate-kit.js +87 -0
- package/lib/agent-kit/workspace-name.js +40 -0
- package/lib/agent-kit/workspace-skeleton.js +103 -0
- package/lib/api/role-assistant-test-pack.api.js +86 -0
- package/lib/api/work-search.api.js +31 -4
- package/lib/api/work.api.js +19 -12
- package/lib/app/deploy.js +7 -4
- package/lib/app/list-external-systems.js +2 -1
- package/lib/app/offer-create-from-template.js +184 -0
- package/lib/app/show-display.js +33 -6
- package/lib/app/show.js +25 -2
- package/lib/channels/add-channel.js +1 -0
- package/lib/channels/approval-guides/claude.js +2 -2
- package/lib/channels/channel-add-failure.js +1 -0
- package/lib/channels/channel-add-remaining.js +15 -9
- package/lib/channels/channel-definition-status.js +115 -0
- package/lib/channels/channel-description.js +2 -1
- package/lib/channels/channel-install-envelope.js +4 -2
- package/lib/channels/channel-integration-generator.js +2 -0
- package/lib/channels/channel-runtime-resolver.js +14 -0
- package/lib/channels/channel-targets.js +31 -5
- package/lib/channels/claude-setup-values.js +4 -1
- package/lib/channels/slack-channel-add.js +59 -6
- package/lib/channels/slack-mcp-callback.js +51 -0
- package/lib/channels/slack-mcp-runtime.js +156 -0
- package/lib/channels/slack-provisioning/install-cli.js +14 -2
- package/lib/channels/slack-provisioning/with-curl-on-path.js +6 -1
- package/lib/cli/index.js +4 -0
- package/lib/cli/setup-app.js +8 -1
- package/lib/cli/setup-auth.js +11 -2
- package/lib/cli/setup-certification-commands.js +2 -2
- package/lib/cli/setup-certification.help.js +3 -1
- package/lib/commands/agent-kit-help.js +149 -0
- package/lib/commands/agent-kit.js +417 -0
- package/lib/commands/auth-status-user.js +99 -0
- package/lib/commands/auth-status.js +14 -4
- package/lib/commands/channel-add-help.js +5 -5
- package/lib/commands/datasource-capability-relate-cli.js +5 -4
- package/lib/commands/datasource-load-export-cli.js +7 -2
- package/lib/commands/datasource-test-trust-cli.js +5 -1
- package/lib/commands/governance-command-action.js +5 -4
- package/lib/commands/identity-membership-role-cache.js +6 -1
- package/lib/commands/lifecycle-command-action.js +16 -15
- package/lib/commands/login-credentials.js +8 -3
- package/lib/commands/login-device.js +14 -5
- package/lib/commands/login.js +14 -1
- package/lib/commands/logout.js +50 -15
- package/lib/commands/repair-auth-apply.js +1 -1
- package/lib/commands/repair-datasource-key-skip.js +39 -0
- package/lib/commands/repair-datasource-keys.js +24 -12
- package/lib/commands/repair-rbac.js +16 -10
- package/lib/commands/role-assistant-copy-output.js +61 -0
- package/lib/commands/role-assistant-copy.js +155 -0
- package/lib/commands/role-assistant-test-output.js +8 -9
- package/lib/commands/role-assistant-test-result-rows.js +42 -0
- package/lib/commands/role-assistant.js +140 -59
- package/lib/commands/search.js +143 -0
- package/lib/commands/test-trust-external.js +7 -5
- package/lib/commands/upload-sidecar-followups.js +4 -1
- package/lib/commands/verify-governance-command-action.js +9 -7
- package/lib/commands/verify-operations-command-action.js +9 -8
- package/lib/commands/verify-operations-skip-e2e.js +131 -0
- package/lib/commands/verify-operations-step-plan.js +6 -33
- package/lib/commands/verify-operations-steps.js +3 -1
- package/lib/commands/verify-trust-command-action.js +6 -5
- package/lib/datasource/capability/relate-operations.js +28 -10
- package/lib/datasource/capability/run-capability-relate.js +48 -25
- package/lib/datasource/datasource-identifier.js +13 -5
- package/lib/deployment/deployer-poll-run.js +117 -35
- package/lib/external-system/deploy-dataplane-published.js +70 -0
- package/lib/external-system/deploy.js +12 -2
- package/lib/external-system/download-role-assistant.js +41 -15
- package/lib/external-system/download.js +8 -3
- package/lib/generator/helpers.js +12 -1
- package/lib/generator/wizard-datasource-key.js +54 -0
- package/lib/generator/wizard.js +55 -54
- package/lib/integration-definition/apply-datasource-keys.js +75 -0
- package/lib/integration-definition/apply-relationships.js +195 -0
- package/lib/integration-definition/apply-static-enterprise.js +232 -0
- package/lib/integration-definition/apply-system-file.js +71 -0
- package/lib/integration-definition/apply-test-endpoint.js +89 -0
- package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
- package/lib/integration-definition/apply.js +78 -59
- package/lib/integration-definition/enrich-openapi-operations.js +36 -10
- package/lib/integration-definition/enrich-openapi-pick.js +87 -0
- package/lib/lifecycle/role-assistant-governance.js +56 -21
- package/lib/programmatic/capability-registry.js +1 -0
- package/lib/programmatic/index.js +2 -0
- package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
- package/lib/programmatic/openapi-channel-install-schemas.js +4 -1
- package/lib/programmatic/openapi-component-schemas.js +1 -0
- package/lib/programmatic/openapi-descriptions.js +9 -3
- package/lib/programmatic/openapi-envelope-examples.js +7 -0
- package/lib/programmatic/openapi-operation-bindings.js +5 -0
- package/lib/programmatic/openapi-request-schemas.js +5 -0
- package/lib/programmatic/openapi-schema-descriptions-channel.js +8 -5
- package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
- package/lib/programmatic/openapi-spec.js +1 -0
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +7 -0
- package/lib/programmatic/run-channel-catalog.js +50 -8
- package/lib/programmatic/run-channel-install-options.js +5 -1
- package/lib/programmatic/run-download.js +41 -0
- package/lib/protection/auth-context.js +3 -1
- package/lib/protection/protection-display.js +3 -2
- package/lib/protection/report-exit.js +50 -0
- package/lib/protection/run-commands.js +2 -0
- package/lib/role-assistant/knowledge-sync-settings-push.js +172 -0
- package/lib/role-assistant/knowledge-sync.js +9 -126
- package/lib/role-assistant/package-validate.js +175 -0
- package/lib/role-assistant/test-case-assertion-row.js +36 -0
- package/lib/role-assistant/test-case-copy-bind.js +77 -0
- package/lib/role-assistant/test-case-copy-expected.js +127 -0
- package/lib/role-assistant/test-case-copy-from-work.js +90 -0
- package/lib/role-assistant/test-case-copy-interactions.js +67 -0
- package/lib/role-assistant/test-case-copy.js +119 -0
- package/lib/role-assistant/test-case-expected-catalog.js +135 -0
- package/lib/role-assistant/test-case-validate.js +88 -0
- package/lib/role-assistant/test-cases-bid.js +117 -4
- package/lib/role-assistant/test-cases-evaluate.js +149 -31
- package/lib/role-assistant/test-cases-evidence.js +44 -5
- package/lib/role-assistant/test-cases-honesty.js +155 -6
- package/lib/role-assistant/test-cases-lifecycle.js +297 -0
- package/lib/role-assistant/test-cases-search-graph.js +122 -0
- package/lib/role-assistant/test-cases-search.js +20 -2
- package/lib/role-assistant/test-cases.js +34 -168
- package/lib/role-assistant/test-pack-map.js +180 -0
- package/lib/role-assistant/test-pack-sync.js +187 -0
- package/lib/role-assistant/test-runner-debug.js +54 -0
- package/lib/role-assistant/test-runner-respond-body.js +36 -0
- package/lib/role-assistant/test-runner-search.js +20 -5
- package/lib/role-assistant/test-runner-start-payload.js +63 -10
- package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
- package/lib/role-assistant/test-runner-workhub.js +45 -21
- package/lib/role-assistant/test-runner.js +53 -10
- package/lib/schema/external-datasource.schema.json +36 -5
- package/lib/schema/external-system.schema.json +20 -2
- package/lib/schema/infra-parameter.schema.json +51 -3
- package/lib/schema/infra.parameter.yaml +476 -40
- package/lib/schema/role-assistant-test-case.schema.json +408 -0
- package/lib/schema/type/document-storage.json +1 -1
- package/lib/search/dataplane-context.js +23 -0
- package/lib/search/search-args.js +211 -0
- package/lib/search/search-display.js +238 -0
- package/lib/search/search-errors.js +50 -0
- package/lib/search/search-prompts.js +119 -0
- package/lib/search/search-roles.js +85 -0
- package/lib/search/search-run.js +241 -0
- package/lib/search/search-skills.js +198 -0
- package/lib/utils/api-required-permissions.js +271 -0
- package/lib/utils/api.js +16 -13
- package/lib/utils/authentication-slot-show.js +153 -0
- package/lib/utils/cli-json-exit.js +41 -0
- package/lib/utils/cli-utils.js +23 -5
- package/lib/utils/controller-url.js +78 -4
- package/lib/utils/credential-display.js +43 -1
- package/lib/utils/deployment-errors.js +15 -0
- package/lib/utils/deployment-validation-helpers.js +4 -1
- package/lib/utils/device-code.js +31 -10
- package/lib/utils/error-formatters/error-parser.js +16 -1
- package/lib/utils/error-formatters/permission-errors.js +19 -5
- package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
- package/lib/utils/external-system-readiness-compact-display.js +30 -1
- package/lib/utils/external-system-validators.js +2 -1
- package/lib/utils/help-builder.js +3 -1
- package/lib/utils/keycloak-realm-ready.js +5 -2
- package/lib/utils/logger.js +1 -0
- package/lib/utils/paths.js +26 -5
- package/lib/utils/schema-loader.js +37 -0
- package/lib/utils/secrets-helpers.js +2 -2
- package/lib/utils/write-stream-and-wait.js +63 -0
- package/lib/validation/validate-external-file.js +5 -1
- package/lib/validation/validate.js +3 -2
- package/package.json +20 -6
- package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
- package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
- package/templates/agent-kit/agent-kit.yaml +45 -0
- package/templates/agent-kit/instructions/AGENTKIT.md +104 -0
- package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
- package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
- package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
- package/templates/agent-kit/parity-inventory.yaml +188 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +59 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
- package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +52 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
- package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +51 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +43 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
- package/templates/agent-kit/skills/shared/hosts.md +65 -0
- package/templates/agent-kit/skills/shared/login.md +16 -0
- package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
- package/templates/agent-kit/workspace/LICENSE.mit +21 -0
- package/templates/agent-kit/workspace/README.md +89 -0
- package/templates/applications/builder-api/Dockerfile +3 -1
- package/templates/applications/dataplane/application.yaml +2 -3
- package/templates/applications/dataplane/env.template +5 -5
- package/templates/applications/dataplane/rbac.yaml +28 -0
- package/templates/applications/keycloak/env.template +3 -3
- package/templates/applications/miso-controller/application.yaml +21 -2
- package/templates/applications/miso-controller/env.template +96 -25
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/channels/claude/TROUBLESHOOTING.md +3 -0
- package/templates/channels/claude/channel.json +1 -1
- package/templates/channels/claude/install.template.md.hbs +1 -0
- package/templates/channels/claude/integration/claude-system.json +1 -1
- package/templates/channels/slack/channel.json +11 -0
- package/templates/channels/slack/install.template.md.hbs +9 -0
- package/templates/channels/slack/integration/slack-system.json +11 -0
- package/templates/channels/slack/manifest.template.json.hbs +6 -3
- package/templates/channels/teams-bot/channel.json +1 -0
- package/templates/python/docker-compose.hbs +14 -0
- package/templates/typescript/docker-compose.hbs +14 -0
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const logger = require('../utils/logger');
|
|
8
8
|
const { handleCommandError } = require('../utils/cli-utils');
|
|
9
|
+
const { writeJsonEnvelopeAndExit } = require('../utils/cli-json-exit');
|
|
9
10
|
const { runGovernanceGenerateForExternalSystem } = require('./governance-generate-external');
|
|
10
11
|
const { runGovernanceVerifyForExternalSystem } = require('./governance-verify-external');
|
|
11
12
|
const { runGovernanceUploadForExternalSystem } = require('./governance-upload-external');
|
|
@@ -75,12 +76,12 @@ async function governanceVerifyHandler(systemKey, options, cmd) {
|
|
|
75
76
|
try {
|
|
76
77
|
const opts = normalizeGovernanceOptions(options, cmd);
|
|
77
78
|
const result = await runGovernanceVerifyForExternalSystem(systemKey, opts);
|
|
79
|
+
const exitCode = exitCodeFromVerdict(result.verdict);
|
|
78
80
|
if (opts.json) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
displayVerifyGovernanceTTY(result.systemKey, result, { details: opts.verbose });
|
|
81
|
+
await writeJsonEnvelopeAndExit(buildJsonEnvelope(result, opts.verbose), exitCode);
|
|
82
|
+
return;
|
|
82
83
|
}
|
|
83
|
-
|
|
84
|
+
displayVerifyGovernanceTTY(result.systemKey, result, { details: opts.verbose });
|
|
84
85
|
if (exitCode !== 0) {
|
|
85
86
|
process.exit(exitCode);
|
|
86
87
|
}
|
|
@@ -35,7 +35,12 @@ const ROLE_LIST_COLUMNS = [
|
|
|
35
35
|
label: 'Groups',
|
|
36
36
|
width: 44,
|
|
37
37
|
value: (r) => {
|
|
38
|
-
const groups = Array.isArray(r.groups)
|
|
38
|
+
const groups = Array.isArray(r.groups)
|
|
39
|
+
? r.groups.filter(Boolean)
|
|
40
|
+
: (r.mappings || [])
|
|
41
|
+
.filter((mapping) => mapping?.isActive !== false)
|
|
42
|
+
.map((mapping) => mapping?.groupName)
|
|
43
|
+
.filter(Boolean);
|
|
39
44
|
return groups.length > 0 ? groups.join(', ') : '—';
|
|
40
45
|
}
|
|
41
46
|
}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
const logger = require('../utils/logger');
|
|
10
9
|
const { handleCommandError } = require('../utils/cli-utils');
|
|
10
|
+
const { writeJsonEnvelopeAndExit } = require('../utils/cli-json-exit');
|
|
11
11
|
const { cliOptsSkipPublish } = require('../utils/cli-sync-options');
|
|
12
12
|
const { runLifecycleForExternalSystem } = require('./lifecycle-external');
|
|
13
13
|
const { displayLifecycleReportTTY } = require('../lifecycle/report-display');
|
|
@@ -65,6 +65,12 @@ async function runLifecycleCommandAction(appName, options, cmd) {
|
|
|
65
65
|
const result = await runLifecycleForExternalSystem(appName, opts);
|
|
66
66
|
const report = result.report;
|
|
67
67
|
|
|
68
|
+
const pillarVerdict = lifecycleVerdictFromReport(report);
|
|
69
|
+
const exitCode =
|
|
70
|
+
pillarVerdict === VERDICT.VERIFIED
|
|
71
|
+
? 0
|
|
72
|
+
: exitCodeFromVerdict(pillarVerdict, { partial: pillarVerdict === VERDICT.NOT_VERIFIED });
|
|
73
|
+
|
|
68
74
|
if (opts.json) {
|
|
69
75
|
const envelope = {
|
|
70
76
|
systemKey: result.systemKey,
|
|
@@ -82,22 +88,17 @@ async function runLifecycleCommandAction(appName, options, cmd) {
|
|
|
82
88
|
if (opts.verbose) {
|
|
83
89
|
envelope.datasources = report.datasources;
|
|
84
90
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
displayLifecycleReportTTY(result.systemKey, report, {
|
|
88
|
-
details: opts.verbose,
|
|
89
|
-
openApiPublished: result.openApiPublished === true,
|
|
90
|
-
certificationProgress: result.certificationProgress ?? null,
|
|
91
|
-
dataplaneUrl: result.dataplaneUrl ?? null,
|
|
92
|
-
dataplaneUiBaseUrl: result.dataplaneUiBaseUrl ?? null
|
|
93
|
-
});
|
|
91
|
+
await writeJsonEnvelopeAndExit(envelope, exitCode);
|
|
92
|
+
return;
|
|
94
93
|
}
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
displayLifecycleReportTTY(result.systemKey, report, {
|
|
96
|
+
details: opts.verbose,
|
|
97
|
+
openApiPublished: result.openApiPublished === true,
|
|
98
|
+
certificationProgress: result.certificationProgress ?? null,
|
|
99
|
+
dataplaneUrl: result.dataplaneUrl ?? null,
|
|
100
|
+
dataplaneUiBaseUrl: result.dataplaneUiBaseUrl ?? null
|
|
101
|
+
});
|
|
101
102
|
if (exitCode !== 0) {
|
|
102
103
|
process.exit(exitCode);
|
|
103
104
|
}
|
|
@@ -15,6 +15,7 @@ const { getToken } = require('../api/auth.api');
|
|
|
15
15
|
const { formatApiError } = require('../utils/api-error-handler');
|
|
16
16
|
const { loadClientCredentials } = require('../utils/token-manager');
|
|
17
17
|
const logger = require('../utils/logger');
|
|
18
|
+
const { writeStreamAndWait } = require('../utils/write-stream-and-wait');
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Tries to load credentials from secrets file
|
|
@@ -136,7 +137,7 @@ function handleLoginError(response, appName) {
|
|
|
136
137
|
* @param {Object} response - API response
|
|
137
138
|
* @returns {Object} Token data object
|
|
138
139
|
*/
|
|
139
|
-
function extractTokenData(response) {
|
|
140
|
+
async function extractTokenData(response) {
|
|
140
141
|
// OpenAPI spec response: { success: boolean, token: string, expiresIn: number, expiresAt: string, ... }
|
|
141
142
|
// Handle both flat and nested response structures (some APIs wrap in data field)
|
|
142
143
|
// If response.data exists, use it; otherwise use response directly
|
|
@@ -146,7 +147,10 @@ function extractTokenData(response) {
|
|
|
146
147
|
if (!responseData || !responseData.token) {
|
|
147
148
|
logger.error(formatBlockingError('Invalid response: missing token'));
|
|
148
149
|
if (responseData) {
|
|
149
|
-
|
|
150
|
+
await writeStreamAndWait(
|
|
151
|
+
process.stderr,
|
|
152
|
+
`${chalk.gray(`Response structure: ${JSON.stringify(responseData, null, 2)}`)}\n`
|
|
153
|
+
);
|
|
150
154
|
}
|
|
151
155
|
process.exit(1);
|
|
152
156
|
}
|
|
@@ -190,9 +194,10 @@ async function handleCredentialsLogin(controllerUrl, appName, clientId, clientSe
|
|
|
190
194
|
|
|
191
195
|
if (!response.success) {
|
|
192
196
|
handleLoginError(response, appName);
|
|
197
|
+
return;
|
|
193
198
|
}
|
|
194
199
|
|
|
195
|
-
const responseData = extractTokenData(response);
|
|
200
|
+
const responseData = await extractTokenData(response);
|
|
196
201
|
const expiresAt = calculateTokenExpiration(responseData);
|
|
197
202
|
|
|
198
203
|
return {
|
|
@@ -15,6 +15,7 @@ const ora = require('ora');
|
|
|
15
15
|
const { setCurrentEnvironment, saveDeviceToken, setControllerUrl } = require('../core/config');
|
|
16
16
|
const { initiateDeviceCodeFlow } = require('../api/auth.api');
|
|
17
17
|
const { pollDeviceCodeToken, displayDeviceCodeInfo } = require('../utils/api');
|
|
18
|
+
const { resolveDeviceVisitUrl } = require('../utils/device-code');
|
|
18
19
|
const logger = require('../utils/logger');
|
|
19
20
|
const { formatSuccessLine } = require('../utils/cli-layout-chalk');
|
|
20
21
|
|
|
@@ -42,6 +43,10 @@ async function getEnvironmentKey(environment) {
|
|
|
42
43
|
return envKey;
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
if (!process.stdin || process.stdin.isTTY === false) {
|
|
47
|
+
return 'dev';
|
|
48
|
+
}
|
|
49
|
+
|
|
45
50
|
const envPrompt = await inquirer.prompt([{
|
|
46
51
|
type: 'input',
|
|
47
52
|
name: 'environment',
|
|
@@ -255,10 +260,8 @@ function logDeviceFlowError(deviceError, opts) {
|
|
|
255
260
|
}
|
|
256
261
|
|
|
257
262
|
function printCompactDeviceUrl(deviceCodeResponse) {
|
|
258
|
-
const visitUrl =
|
|
259
|
-
|
|
260
|
-
`${deviceCodeResponse.verification_uri}?user_code=${deviceCodeResponse.user_code}`;
|
|
261
|
-
logger.log('\nOpen browser to authenticate:');
|
|
263
|
+
const visitUrl = resolveDeviceVisitUrl(deviceCodeResponse);
|
|
264
|
+
logger.log('\nOpen this URL to authenticate:');
|
|
262
265
|
logger.log(chalk.yellow(`${visitUrl}\n`));
|
|
263
266
|
}
|
|
264
267
|
|
|
@@ -289,7 +292,13 @@ async function handleDeviceCodeLogin(controllerUrl, environment, online, scope,
|
|
|
289
292
|
const deviceCodeResponse = convertDeviceCodeResponse(apiResponse);
|
|
290
293
|
|
|
291
294
|
if (!opts.compact) {
|
|
292
|
-
displayDeviceCodeInfo(
|
|
295
|
+
displayDeviceCodeInfo(
|
|
296
|
+
deviceCodeResponse.user_code,
|
|
297
|
+
deviceCodeResponse.verification_uri,
|
|
298
|
+
logger,
|
|
299
|
+
chalk,
|
|
300
|
+
deviceCodeResponse.verification_uri_complete
|
|
301
|
+
);
|
|
293
302
|
} else {
|
|
294
303
|
printCompactDeviceUrl(deviceCodeResponse);
|
|
295
304
|
}
|
package/lib/commands/login.js
CHANGED
|
@@ -16,9 +16,13 @@ const { setCurrentEnvironment, saveClientToken, setControllerUrl } = require('..
|
|
|
16
16
|
const logger = require('../utils/logger');
|
|
17
17
|
const { handleCredentialsLogin } = require('./login-credentials');
|
|
18
18
|
const { handleDeviceCodeLogin } = require('./login-device');
|
|
19
|
-
const { resolveControllerUrl } = require('../utils/controller-url');
|
|
19
|
+
const { resolveControllerUrl, discoverControllerBaseUrl } = require('../utils/controller-url');
|
|
20
20
|
const { tryRefreshDataplaneVersionAfterLogin } = require('./auth-status-dataplane-version');
|
|
21
21
|
|
|
22
|
+
function isInteractiveStdin() {
|
|
23
|
+
return Boolean(process.stdin && process.stdin.isTTY);
|
|
24
|
+
}
|
|
25
|
+
|
|
22
26
|
/**
|
|
23
27
|
* Determine and validate authentication method
|
|
24
28
|
* @async
|
|
@@ -34,6 +38,10 @@ async function determineAuthMethod(method) {
|
|
|
34
38
|
return method;
|
|
35
39
|
}
|
|
36
40
|
|
|
41
|
+
if (!isInteractiveStdin()) {
|
|
42
|
+
return 'device';
|
|
43
|
+
}
|
|
44
|
+
|
|
37
45
|
const authMethod = await inquirer.prompt([{
|
|
38
46
|
type: 'list',
|
|
39
47
|
name: 'method',
|
|
@@ -86,6 +94,8 @@ async function normalizeControllerUrl(options) {
|
|
|
86
94
|
controllerUrl = await resolveControllerUrl();
|
|
87
95
|
}
|
|
88
96
|
controllerUrl = String(controllerUrl).trim().replace(/\/+$/, '');
|
|
97
|
+
const inputUrl = controllerUrl;
|
|
98
|
+
controllerUrl = await discoverControllerBaseUrl(controllerUrl);
|
|
89
99
|
if (!options.skipControllerUrlPersist) {
|
|
90
100
|
const persistUrl = options.tokenControllerUrl
|
|
91
101
|
? String(options.tokenControllerUrl).trim().replace(/\/+$/, '')
|
|
@@ -93,6 +103,9 @@ async function normalizeControllerUrl(options) {
|
|
|
93
103
|
await setControllerUrl(persistUrl);
|
|
94
104
|
}
|
|
95
105
|
if (!options.compact) {
|
|
106
|
+
if (controllerUrl !== inputUrl) {
|
|
107
|
+
logger.log(chalk.gray(`Using controller ${controllerUrl}`));
|
|
108
|
+
}
|
|
96
109
|
logger.log(chalk.gray(`Controller URL: ${controllerUrl}`));
|
|
97
110
|
}
|
|
98
111
|
return controllerUrl;
|
package/lib/commands/logout.js
CHANGED
|
@@ -132,11 +132,54 @@ async function clearClientTokens(options) {
|
|
|
132
132
|
return 0;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
function normalizeTokenType(value) {
|
|
136
|
+
const type = value && String(value).toLowerCase();
|
|
137
|
+
if (type && type !== 'device' && type !== 'client') {
|
|
138
|
+
throw new Error('--type must be either "device" or "client"');
|
|
139
|
+
}
|
|
140
|
+
return type;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function validateLogoutOptionCombination(options, type) {
|
|
144
|
+
if (options.app && !options.environment) {
|
|
145
|
+
throw new Error('--app requires --environment option');
|
|
146
|
+
}
|
|
147
|
+
if (type === 'client' && options.controller) {
|
|
148
|
+
throw new Error('--controller can only be used with --type device');
|
|
149
|
+
}
|
|
150
|
+
if (type === 'device' && (options.environment || options.app)) {
|
|
151
|
+
throw new Error('--environment and --app can only be used with --type client');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function validateLogoutSelectors(options) {
|
|
156
|
+
if ('controller' in options && options.controller !== undefined && options.controller !== null) {
|
|
157
|
+
validateControllerUrl(options.controller);
|
|
158
|
+
}
|
|
159
|
+
if ('environment' in options && options.environment !== undefined && options.environment !== null) {
|
|
160
|
+
validateEnvironmentKey(options.environment);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Validate logout option combinations and normalize the token type.
|
|
166
|
+
* @param {Object} options - Raw logout options
|
|
167
|
+
* @returns {Object} Validated options with a normalized type
|
|
168
|
+
* @throws {Error} If an option or option combination is invalid
|
|
169
|
+
*/
|
|
170
|
+
function normalizeLogoutOptions(options) {
|
|
171
|
+
const type = normalizeTokenType(options.type);
|
|
172
|
+
validateLogoutOptionCombination(options, type);
|
|
173
|
+
validateLogoutSelectors(options);
|
|
174
|
+
return { ...options, type };
|
|
175
|
+
}
|
|
176
|
+
|
|
135
177
|
/**
|
|
136
178
|
* Handle logout command action
|
|
137
179
|
* @async
|
|
138
180
|
* @function handleLogout
|
|
139
181
|
* @param {Object} options - Logout options
|
|
182
|
+
* @param {string} [options.type] - Token type to clear (device or client)
|
|
140
183
|
* @param {string} [options.controller] - Clear device tokens for specific controller
|
|
141
184
|
* @param {string} [options.environment] - Clear client tokens for specific environment
|
|
142
185
|
* @param {string} [options.app] - Clear client tokens for specific app (requires --environment)
|
|
@@ -147,24 +190,17 @@ async function handleLogout(options) {
|
|
|
147
190
|
const configPath = CONFIG_FILE;
|
|
148
191
|
logger.log(chalk.blue('\n🔓 Clearing authentication tokens...\n'));
|
|
149
192
|
|
|
150
|
-
|
|
151
|
-
if (options.app && !options.environment) {
|
|
152
|
-
throw new Error('--app requires --environment option');
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if ('controller' in options && options.controller !== undefined && options.controller !== null) {
|
|
156
|
-
validateControllerUrl(options.controller);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if ('environment' in options && options.environment !== undefined && options.environment !== null) {
|
|
160
|
-
validateEnvironmentKey(options.environment);
|
|
161
|
-
}
|
|
193
|
+
const normalizedOptions = normalizeLogoutOptions(options);
|
|
162
194
|
|
|
163
195
|
// Clear device tokens
|
|
164
|
-
const deviceTokensCleared =
|
|
196
|
+
const deviceTokensCleared = normalizedOptions.type === 'client'
|
|
197
|
+
? 0
|
|
198
|
+
: await clearDeviceTokens(normalizedOptions);
|
|
165
199
|
|
|
166
200
|
// Clear client tokens
|
|
167
|
-
const clientTokensCleared =
|
|
201
|
+
const clientTokensCleared = normalizedOptions.type === 'device'
|
|
202
|
+
? 0
|
|
203
|
+
: await clearClientTokens(normalizedOptions);
|
|
168
204
|
|
|
169
205
|
// Summary
|
|
170
206
|
const totalCleared = deviceTokensCleared + clientTokensCleared;
|
|
@@ -178,4 +214,3 @@ async function handleLogout(options) {
|
|
|
178
214
|
}
|
|
179
215
|
|
|
180
216
|
module.exports = { handleLogout };
|
|
181
|
-
|
|
@@ -117,7 +117,7 @@ function repairAuthChangeLabel(authOption) {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
const MISSING_TEST_ENDPOINT_WARNING =
|
|
120
|
-
'authentication.variables.testEndpoint is missing for apikey/bearerToken auth — add a GET URL for credential/E2E tests (
|
|
120
|
+
'authentication.variables.testEndpoint is missing for apikey/bearerToken auth — add a GET URL for credential/E2E tests (use the OpenAPI minimum for required page-size query params, or a path resolved against baseUrl).';
|
|
121
121
|
|
|
122
122
|
/**
|
|
123
123
|
* Warn when apikey auth (including bearerToken preset) has no testEndpoint.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skip repair key prefix when a datasource key is already unique scoped kebab-case.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Unique kebab datasource keys stay as-is during repair
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const SCOPED_KEBAB = /^[a-z0-9]+(-[a-z0-9]+)+$/;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} key
|
|
13
|
+
* @returns {boolean}
|
|
14
|
+
*/
|
|
15
|
+
function isScopedKebabKey(key) {
|
|
16
|
+
return SCOPED_KEBAB.test(String(key || '').trim());
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* True when key already contains a hyphen and appears once in the package.
|
|
21
|
+
* Single-token keys (persons) must still be prefixed with the system key.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} key
|
|
24
|
+
* @param {string[]} allKeys
|
|
25
|
+
* @returns {boolean}
|
|
26
|
+
*/
|
|
27
|
+
function shouldSkipSystemKeyPrefix(key, allKeys) {
|
|
28
|
+
const trimmed = String(key || '').trim();
|
|
29
|
+
if (!isScopedKebabKey(trimmed) || trimmed.endsWith('-datasource')) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const hits = (allKeys || []).filter((item) => String(item || '').trim() === trimmed);
|
|
33
|
+
return hits.length === 1;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = {
|
|
37
|
+
isScopedKebabKey,
|
|
38
|
+
shouldSkipSystemKeyPrefix
|
|
39
|
+
};
|
|
@@ -17,6 +17,7 @@ const fs = require('fs');
|
|
|
17
17
|
const { loadConfigFile, writeConfigFile } = require('../utils/config-format');
|
|
18
18
|
const { backupIntegrationFile } = require('../utils/integration-file-backup');
|
|
19
19
|
const { trackRepairWrite } = require('./repair-changed-files');
|
|
20
|
+
const { shouldSkipSystemKeyPrefix } = require('./repair-datasource-key-skip');
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Returns suffix from a canonical-format filename: <systemKey>-datasource-<suffix>.<ext>.
|
|
@@ -53,6 +54,9 @@ function isKeyAlreadyCanonical(key, systemKey, fileName) {
|
|
|
53
54
|
return true;
|
|
54
55
|
}
|
|
55
56
|
}
|
|
57
|
+
if (shouldSkipSystemKeyPrefix(key, [key])) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
56
60
|
if (!key.startsWith(systemKey + '-')) return false;
|
|
57
61
|
const suffix = key.slice(systemKey.length + 1);
|
|
58
62
|
if (!suffix) return false;
|
|
@@ -126,6 +130,7 @@ function normalizeDatasourceKeysAndFilenames(appPath, datasourceFiles, systemKey
|
|
|
126
130
|
|
|
127
131
|
const slugCounts = new Map();
|
|
128
132
|
const fileInfos = [];
|
|
133
|
+
const packageKeys = [];
|
|
129
134
|
|
|
130
135
|
for (const fileName of datasourceFiles) {
|
|
131
136
|
const filePath = path.join(appPath, fileName);
|
|
@@ -138,23 +143,30 @@ function normalizeDatasourceKeysAndFilenames(appPath, datasourceFiles, systemKey
|
|
|
138
143
|
continue;
|
|
139
144
|
}
|
|
140
145
|
const key = (parsed && typeof parsed.key === 'string' && parsed.key.trim()) ? parsed.key.trim() : null;
|
|
141
|
-
if (
|
|
142
|
-
|
|
146
|
+
if (key) packageKeys.push(key);
|
|
147
|
+
fileInfos.push({ fileName, parsed, key, skip: false, slug: null, canonicalKey: null });
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
for (const info of fileInfos) {
|
|
151
|
+
if (info.skip) continue;
|
|
152
|
+
const filenameCanonical = isFilenameAlreadyCanonical(info.fileName, systemKey);
|
|
153
|
+
const keyCanonical = isKeyAlreadyCanonical(info.key, systemKey, info.fileName);
|
|
154
|
+
const skipPrefix =
|
|
155
|
+
shouldSkipSystemKeyPrefix(info.key, packageKeys) &&
|
|
156
|
+
!String(info.key || '').endsWith('-datasource');
|
|
157
|
+
if ((keyCanonical || skipPrefix) && filenameCanonical) {
|
|
158
|
+
info.skip = true;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (skipPrefix) {
|
|
162
|
+
info.canonicalKey = info.key;
|
|
143
163
|
continue;
|
|
144
164
|
}
|
|
145
|
-
|
|
146
|
-
fileInfos.push({
|
|
147
|
-
fileName,
|
|
148
|
-
parsed,
|
|
149
|
-
key,
|
|
150
|
-
slug,
|
|
151
|
-
canonicalKey: null,
|
|
152
|
-
skip: false
|
|
153
|
-
});
|
|
165
|
+
info.slug = slugFromKey(info.key || info.fileName, systemKey);
|
|
154
166
|
}
|
|
155
167
|
|
|
156
168
|
for (const info of fileInfos) {
|
|
157
|
-
if (info.skip) continue;
|
|
169
|
+
if (info.skip || info.canonicalKey) continue;
|
|
158
170
|
const slug = info.slug;
|
|
159
171
|
const n = (slugCounts.get(slug) || 0) + 1;
|
|
160
172
|
slugCounts.set(slug, n);
|
|
@@ -29,6 +29,7 @@ const {
|
|
|
29
29
|
ensureOrchestrationResourceType
|
|
30
30
|
} = require('./repair-rbac-platform-preset');
|
|
31
31
|
const { trackRepairWrite } = require('./repair-changed-files');
|
|
32
|
+
const { listCapabilityKeys } = require('../datasource/capability/capability-manifest');
|
|
32
33
|
const { ensureDefaultRoles } = require('./repair-rbac-catalog-defaults');
|
|
33
34
|
|
|
34
35
|
const DEFAULT_CAPABILITIES = ['list', 'get', 'create', 'update', 'delete'];
|
|
@@ -47,24 +48,29 @@ function _normalizeOperationKey(opKey) {
|
|
|
47
48
|
return cleaned.replace(/-+/g, '-').replace(/^-+|-+$/g, '');
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
function defaultCapabilitiesForDatasource(parsed) {
|
|
52
|
+
if (String(parsed?.storageType || '') === 'view') {
|
|
53
|
+
return ['list', 'get'];
|
|
54
|
+
}
|
|
55
|
+
return [...DEFAULT_CAPABILITIES];
|
|
56
|
+
}
|
|
57
|
+
|
|
50
58
|
/**
|
|
51
|
-
* Resolves capabilities from datasource (array or legacy
|
|
59
|
+
* Resolves capabilities from datasource (array, COM objects, or legacy map).
|
|
52
60
|
* @param {Object} parsed - Parsed datasource
|
|
53
61
|
* @returns {string[]}
|
|
54
62
|
*/
|
|
55
63
|
function getCapabilitiesFromDatasource(parsed) {
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
if (arr.length > 0) return arr;
|
|
60
|
-
return [...DEFAULT_CAPABILITIES];
|
|
64
|
+
const fromList = listCapabilityKeys(parsed?.capabilities);
|
|
65
|
+
if (fromList.length > 0) {
|
|
66
|
+
return fromList;
|
|
61
67
|
}
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
const cap = parsed?.capabilities;
|
|
69
|
+
if (cap && typeof cap === 'object' && !Array.isArray(cap)) {
|
|
70
|
+
const keys = Object.keys(cap).filter((k) => cap[k] === true);
|
|
64
71
|
if (keys.length > 0) return keys;
|
|
65
|
-
return [...DEFAULT_CAPABILITIES];
|
|
66
72
|
}
|
|
67
|
-
return
|
|
73
|
+
return defaultCapabilitiesForDatasource(parsed);
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
/**
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TTY and --json output for role-assistant copy.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Success and blocking copy envelopes
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const logger = require('../utils/logger');
|
|
10
|
+
const { formatSuccessLine, formatBlockingError } = require('../utils/cli-layout-chalk');
|
|
11
|
+
|
|
12
|
+
function copyWarnings(result) {
|
|
13
|
+
return Array.isArray(result.warnings) ? result.warnings : [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function buildCopyEnvelope(result) {
|
|
17
|
+
const envelope = {
|
|
18
|
+
success: true,
|
|
19
|
+
path: result.path,
|
|
20
|
+
caseId: result.caseId,
|
|
21
|
+
suiteId: result.suiteId,
|
|
22
|
+
processExecutionId: result.processExecutionId
|
|
23
|
+
};
|
|
24
|
+
const warnings = copyWarnings(result);
|
|
25
|
+
if (warnings.length > 0) {
|
|
26
|
+
envelope.warnings = warnings;
|
|
27
|
+
}
|
|
28
|
+
if (result.dryRun === true) {
|
|
29
|
+
envelope.dryRun = true;
|
|
30
|
+
envelope.yaml = result.yaml;
|
|
31
|
+
}
|
|
32
|
+
return envelope;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function emitCopySuccess(options, result) {
|
|
36
|
+
if (options && options.json) {
|
|
37
|
+
logger.log(JSON.stringify(buildCopyEnvelope(result), null, 2));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (result.dryRun === true) {
|
|
41
|
+
logger.log(result.yaml);
|
|
42
|
+
logger.log(formatSuccessLine(`Would write ${result.path}`));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
logger.log(formatSuccessLine(`Wrote ${result.path}`));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function emitCopyFailure(options, error) {
|
|
49
|
+
const message = error && error.message ? error.message : String(error);
|
|
50
|
+
if (options && options.json) {
|
|
51
|
+
logger.log(JSON.stringify({ success: false, error: message }));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
logger.error(formatBlockingError(message));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = {
|
|
58
|
+
buildCopyEnvelope,
|
|
59
|
+
emitCopySuccess,
|
|
60
|
+
emitCopyFailure
|
|
61
|
+
};
|