fjall 0.96.0 → 0.99.1
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/bin/.bundled +3 -3
- package/bin/.metafile.json +4742 -3402
- package/bin/assets/generators/application/generator.js +1 -1
- package/bin/assets/generators/compute/generator.js +1 -1
- package/bin/assets/generators/compute/service/generator.js +1 -1
- package/bin/assets/generators/database/generator.js +1 -1
- package/bin/assets/generators/domain/generator.js +2 -2
- package/bin/assets/generators/organisation/files/organisation/infrastructure.ts +8 -2
- package/bin/assets/generators/shared/files/cdk.json +1 -1
- package/bin/assets/generators/shared/files/package.json +8 -7
- package/bin/assets/generators/shared/files/tsconfig.json +5 -4
- package/bin/assets/generators/utils/integrationTestUtils.d.ts +9 -0
- package/bin/assets/generators/utils/integrationTestUtils.js +4 -2
- package/bin/assets/generators/utils/planning/generatorHelpers.js +2 -2
- package/bin/assets/src/util/__tests__/fjallApiClientTestHelpers.d.ts +9 -0
- package/bin/assets/src/util/__tests__/fjallApiClientTestHelpers.js +1 -0
- package/bin/assets/src/util/__tests__/outputTestHelpers.d.ts +9 -0
- package/bin/assets/src/util/__tests__/outputTestHelpers.js +1 -0
- package/bin/assets/src/util/agent/__tests__/toonTestHelpers.d.ts +91 -0
- package/bin/assets/src/util/agent/__tests__/toonTestHelpers.js +1 -0
- package/bin/assets/src/util/agent/actionRequired.d.ts +60 -0
- package/bin/assets/src/util/agent/actionRequired.js +1 -0
- package/bin/assets/src/util/agent/agentCallbacks.d.ts +21 -0
- package/bin/assets/src/util/agent/agentCallbacks.js +1 -0
- package/bin/assets/src/util/agent/agentInit.d.ts +17 -0
- package/bin/assets/src/util/agent/agentInit.js +288 -0
- package/bin/assets/src/util/agent/agentOutput.d.ts +61 -0
- package/bin/assets/src/util/agent/agentOutput.js +8 -0
- package/bin/assets/src/util/agent/budget.d.ts +19 -0
- package/bin/assets/src/util/agent/budget.js +4 -0
- package/bin/assets/src/util/agent/detectAgent.d.ts +51 -0
- package/bin/assets/src/util/agent/detectAgent.js +1 -0
- package/bin/assets/src/util/agent/errorCodeMap.d.ts +16 -0
- package/bin/assets/src/util/agent/errorCodeMap.js +1 -0
- package/bin/assets/src/util/agent/errorCodes.d.ts +48 -0
- package/bin/assets/src/util/agent/errorCodes.js +1 -0
- package/bin/assets/src/util/agent/fieldSelection.d.ts +22 -0
- package/bin/assets/src/util/agent/fieldSelection.js +1 -0
- package/bin/assets/src/util/agent/getSurface.d.ts +27 -0
- package/bin/assets/src/util/agent/getSurface.js +1 -0
- package/bin/assets/src/util/agent/index.d.ts +27 -0
- package/bin/assets/src/util/agent/index.js +1 -0
- package/bin/assets/src/util/agent/mcpProtocolEmit.d.ts +31 -0
- package/bin/assets/src/util/agent/mcpProtocolEmit.js +2 -0
- package/bin/assets/src/util/agent/schemas/appsSchemas.d.ts +18 -0
- package/bin/assets/src/util/agent/schemas/appsSchemas.js +1 -0
- package/bin/assets/src/util/agent/schemas/assetSchemas.d.ts +13 -0
- package/bin/assets/src/util/agent/schemas/assetSchemas.js +1 -0
- package/bin/assets/src/util/agent/schemas/awsSchemas.d.ts +5 -0
- package/bin/assets/src/util/agent/schemas/awsSchemas.js +1 -0
- package/bin/assets/src/util/agent/schemas/deploySchemas.d.ts +8 -0
- package/bin/assets/src/util/agent/schemas/deploySchemas.js +1 -0
- package/bin/assets/src/util/agent/schemas/index.d.ts +10 -0
- package/bin/assets/src/util/agent/schemas/index.js +1 -0
- package/bin/assets/src/util/agent/schemas/infraSchemas.d.ts +45 -0
- package/bin/assets/src/util/agent/schemas/infraSchemas.js +1 -0
- package/bin/assets/src/util/agent/schemas/secretsSchemas.d.ts +13 -0
- package/bin/assets/src/util/agent/schemas/secretsSchemas.js +1 -0
- package/bin/assets/src/util/agent/schemas/types.d.ts +98 -0
- package/bin/assets/src/util/agent/schemas/types.js +0 -0
- package/bin/assets/src/util/agent/schemas/userSchemas.d.ts +21 -0
- package/bin/assets/src/util/agent/schemas/userSchemas.js +1 -0
- package/bin/assets/src/util/agent/sessionHooks.d.ts +47 -0
- package/bin/assets/src/util/agent/sessionHooks.js +6 -0
- package/bin/assets/src/util/agent/streaming.d.ts +51 -0
- package/bin/assets/src/util/agent/streaming.js +1 -0
- package/bin/assets/src/util/agent/suggestionEntries/coreEntries.d.ts +2 -0
- package/bin/assets/src/util/agent/suggestionEntries/coreEntries.js +1 -0
- package/bin/assets/src/util/agent/suggestionEntries/identityEntries.d.ts +2 -0
- package/bin/assets/src/util/agent/suggestionEntries/identityEntries.js +1 -0
- package/bin/assets/src/util/agent/suggestionEntries/index.d.ts +3 -0
- package/bin/assets/src/util/agent/suggestionEntries/index.js +1 -0
- package/bin/assets/src/util/agent/suggestionEntries/infraEntries.d.ts +2 -0
- package/bin/assets/src/util/agent/suggestionEntries/infraEntries.js +1 -0
- package/bin/assets/src/util/agent/suggestionEntries/observabilityEntries.d.ts +2 -0
- package/bin/assets/src/util/agent/suggestionEntries/observabilityEntries.js +1 -0
- package/bin/assets/src/util/agent/suggestionEntries/secretsEntries.d.ts +2 -0
- package/bin/assets/src/util/agent/suggestionEntries/secretsEntries.js +1 -0
- package/bin/assets/src/util/agent/suggestionEntries/types.d.ts +17 -0
- package/bin/assets/src/util/agent/suggestionEntries/types.js +1 -0
- package/bin/assets/src/util/agent/suggestions.d.ts +30 -0
- package/bin/assets/src/util/agent/suggestions.js +1 -0
- package/bin/assets/src/util/agent/tokenScopes.d.ts +24 -0
- package/bin/assets/src/util/agent/tokenScopes.js +1 -0
- package/bin/assets/src/util/agent/toonFormatter.d.ts +55 -0
- package/bin/assets/src/util/agent/toonFormatter.js +14 -0
- package/bin/assets/src/util/api/Credentials.d.ts +13 -0
- package/bin/assets/src/util/api/Credentials.js +1 -0
- package/bin/assets/src/util/api/FjallApiClient.d.ts +33 -0
- package/bin/assets/src/util/api/FjallApiClient.js +1 -0
- package/bin/assets/src/util/api/FjallApiClient.types.d.ts +375 -0
- package/bin/assets/src/util/api/FjallApiClient.types.js +1 -0
- package/bin/assets/src/util/api/FjallApiClientBase.d.ts +13 -0
- package/bin/assets/src/util/api/FjallApiClientBase.js +1 -0
- package/bin/assets/src/util/api/FjallApiClientDeviceCode.d.ts +13 -0
- package/bin/assets/src/util/api/FjallApiClientDeviceCode.js +1 -0
- package/bin/assets/src/util/api/FjallApiClientErrors.d.ts +5 -0
- package/bin/assets/src/util/api/FjallApiClientErrors.js +1 -0
- package/bin/assets/src/util/api/FjallApiClientResources.d.ts +45 -0
- package/bin/assets/src/util/api/FjallApiClientResources.js +1 -0
- package/bin/assets/src/util/api/index.d.ts +7 -0
- package/bin/assets/src/util/api/index.js +1 -0
- package/bin/assets/src/util/api/resolveApiKey.d.ts +1 -0
- package/bin/assets/src/util/api/resolveApiKey.js +1 -0
- package/bin/assets/src/util/api/scaffoldNotification.d.ts +2 -0
- package/bin/assets/src/util/api/scaffoldNotification.js +1 -0
- package/bin/assets/src/util/awsCleanup.d.ts +9 -0
- package/bin/assets/src/util/awsCleanup.js +1 -0
- package/bin/assets/src/util/awsTags.d.ts +19 -0
- package/bin/assets/src/util/awsTags.js +1 -0
- package/bin/assets/src/util/buildxEventAdapter.d.ts +20 -0
- package/bin/assets/src/util/buildxEventAdapter.js +1 -0
- package/bin/assets/src/util/caseConversion.d.ts +1 -0
- package/bin/assets/src/util/caseConversion.js +1 -0
- package/bin/assets/src/util/codemod/emitCliTelemetry.d.ts +32 -0
- package/bin/assets/src/util/codemod/emitCliTelemetry.js +1 -0
- package/bin/assets/src/util/codemod/exitCodes.d.ts +11 -0
- package/bin/assets/src/util/codemod/exitCodes.js +1 -0
- package/bin/assets/src/util/codemod/index.d.ts +3 -0
- package/bin/assets/src/util/codemod/index.js +1 -0
- package/bin/assets/src/util/codemod/renderCodemod.d.ts +5 -0
- package/bin/assets/src/util/codemod/renderCodemod.js +1 -0
- package/bin/assets/src/util/codemod/stepLabels.d.ts +11 -0
- package/bin/assets/src/util/codemod/stepLabels.js +1 -0
- package/bin/assets/src/util/colourUtils.d.ts +21 -0
- package/bin/assets/src/util/colourUtils.js +1 -0
- package/bin/assets/src/util/commandErrorHandler.d.ts +16 -0
- package/bin/assets/src/util/commandErrorHandler.js +1 -0
- package/bin/assets/src/util/commandResult.d.ts +63 -0
- package/bin/assets/src/util/commandResult.js +1 -0
- package/bin/assets/src/util/concurrency.d.ts +35 -0
- package/bin/assets/src/util/concurrency.js +1 -0
- package/bin/assets/src/util/deploymentEvents.d.ts +155 -0
- package/bin/assets/src/util/deploymentEvents.js +1 -0
- package/bin/assets/src/util/errorDisplay.d.ts +4 -0
- package/bin/assets/src/util/errorDisplay.js +2 -0
- package/bin/assets/src/util/errorUtils.d.ts +1 -0
- package/bin/assets/src/util/errorUtils.js +1 -0
- package/bin/assets/src/util/executionMode.d.ts +18 -0
- package/bin/assets/src/util/executionMode.js +1 -0
- package/bin/assets/src/util/formatDeltaValue.d.ts +1 -0
- package/bin/assets/src/util/formatDeltaValue.js +1 -0
- package/bin/assets/src/util/formatDuration.d.ts +1 -0
- package/bin/assets/src/util/formatDuration.js +1 -0
- package/bin/assets/src/util/formatRelativeTime.d.ts +1 -0
- package/bin/assets/src/util/formatRelativeTime.js +1 -0
- package/bin/assets/src/util/fuzzyMatch.d.ts +38 -0
- package/bin/assets/src/util/fuzzyMatch.js +1 -0
- package/bin/assets/src/util/gitDetection.d.ts +8 -0
- package/bin/assets/src/util/gitDetection.js +1 -0
- package/bin/assets/src/util/index.d.ts +50 -0
- package/bin/assets/src/util/index.js +1 -0
- package/bin/assets/src/util/log.d.ts +29 -0
- package/bin/assets/src/util/log.js +4 -0
- package/bin/assets/src/util/logger/CorrelatedLogger.d.ts +15 -0
- package/bin/assets/src/util/logger/CorrelatedLogger.js +1 -0
- package/bin/assets/src/util/logger/DeploymentLogger.d.ts +33 -0
- package/bin/assets/src/util/logger/DeploymentLogger.js +2 -0
- package/bin/assets/src/util/logger/FileRotator.d.ts +17 -0
- package/bin/assets/src/util/logger/FileRotator.js +1 -0
- package/bin/assets/src/util/logger/LogFileWriter.d.ts +54 -0
- package/bin/assets/src/util/logger/LogFileWriter.js +4 -0
- package/bin/assets/src/util/logger/Logger.d.ts +43 -0
- package/bin/assets/src/util/logger/Logger.js +1 -0
- package/bin/assets/src/util/logger/index.d.ts +15 -0
- package/bin/assets/src/util/logger/index.js +2 -0
- package/bin/assets/src/util/logger/logDir.d.ts +5 -0
- package/bin/assets/src/util/logger/logDir.js +1 -0
- package/bin/assets/src/util/logger/types.d.ts +48 -0
- package/bin/assets/src/util/logger/types.js +1 -0
- package/bin/assets/src/util/nonInteractive/index.d.ts +3 -0
- package/bin/assets/src/util/nonInteractive/index.js +1 -0
- package/bin/assets/src/util/nonInteractive/nonInteractiveCallbacks.d.ts +18 -0
- package/bin/assets/src/util/nonInteractive/nonInteractiveCallbacks.js +1 -0
- package/bin/assets/src/util/nonInteractive/nonInteractiveCascadeOutput.d.ts +51 -0
- package/bin/assets/src/util/nonInteractive/nonInteractiveCascadeOutput.js +1 -0
- package/bin/assets/src/util/nonInteractive/nonInteractiveLabels.d.ts +23 -0
- package/bin/assets/src/util/nonInteractive/nonInteractiveLabels.js +1 -0
- package/bin/assets/src/util/nonInteractive/nonInteractiveOutput.d.ts +128 -0
- package/bin/assets/src/util/nonInteractive/nonInteractiveOutput.js +4 -0
- package/bin/assets/src/util/nonInteractive/nonInteractiveSummaryOutput.d.ts +29 -0
- package/bin/assets/src/util/nonInteractive/nonInteractiveSummaryOutput.js +3 -0
- package/bin/assets/src/util/organisationStructure.d.ts +9 -0
- package/bin/assets/src/util/organisationStructure.js +1 -0
- package/bin/assets/src/util/parseTakeOption.d.ts +1 -0
- package/bin/assets/src/util/parseTakeOption.js +1 -0
- package/bin/assets/src/util/passwordValidation.d.ts +22 -0
- package/bin/assets/src/util/passwordValidation.js +1 -0
- package/bin/assets/src/util/pathHelpers.d.ts +19 -0
- package/bin/assets/src/util/pathHelpers.js +1 -0
- package/bin/assets/src/util/patternDetection.d.ts +7 -0
- package/bin/assets/src/util/patternDetection.js +1 -0
- package/bin/assets/src/util/promptYesNo.d.ts +5 -0
- package/bin/assets/src/util/promptYesNo.js +1 -0
- package/bin/assets/src/util/readStdin.d.ts +9 -0
- package/bin/assets/src/util/readStdin.js +1 -0
- package/bin/assets/src/util/secretsUtils.d.ts +155 -0
- package/bin/assets/src/util/secretsUtils.js +3 -0
- package/bin/assets/src/util/signalCleanup.d.ts +13 -0
- package/bin/assets/src/util/signalCleanup.js +4 -0
- package/bin/assets/src/util/stripAnsi.d.ts +2 -0
- package/bin/assets/src/util/stripAnsi.js +1 -0
- package/bin/assets/src/util/synchronizedOutput.d.ts +26 -0
- package/bin/assets/src/util/synchronizedOutput.js +1 -0
- package/bin/assets/src/util/targetDetection.d.ts +27 -0
- package/bin/assets/src/util/targetDetection.js +1 -0
- package/bin/assets/src/util/targetHelpers.d.ts +20 -0
- package/bin/assets/src/util/targetHelpers.js +1 -0
- package/bin/assets/src/util/terminalCapabilities.d.ts +21 -0
- package/bin/assets/src/util/terminalCapabilities.js +1 -0
- package/bin/assets/src/util/terminalEscapes.d.ts +29 -0
- package/bin/assets/src/util/terminalEscapes.js +1 -0
- package/bin/assets/src/util/terminalFocus.d.ts +33 -0
- package/bin/assets/src/util/terminalFocus.js +1 -0
- package/bin/assets/src/util/theme.d.ts +80 -0
- package/bin/assets/src/util/theme.js +1 -0
- package/bin/assets/src/util/truncateMiddle.d.ts +9 -0
- package/bin/assets/src/util/truncateMiddle.js +1 -0
- package/bin/assets/src/util/typeGuards.d.ts +5 -0
- package/bin/assets/src/util/typeGuards.js +1 -0
- package/bin/assets/src/util/uiRouter.d.ts +13 -0
- package/bin/assets/src/util/uiRouter.js +1 -0
- package/bin/assets/src/util/urlHelpers.d.ts +4 -0
- package/bin/assets/src/util/urlHelpers.js +1 -0
- package/bin/assets/src/util/versionDisplay.d.ts +5 -0
- package/bin/assets/src/util/versionDisplay.js +1 -0
- package/bin/fjall.bundle.js +736 -564
- package/package.json +38 -35
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{maskSensitiveOutput as a}from"@fjall/util";import{getErrorMessage as e}from"../errorUtils.js";import{logger as i}from"../logger/index.js";async function l(){try{const{FjallApiClient:o}=await import("./FjallApiClient.js"),t=o.fromCredentials();if(!t){i.warn("ScaffoldNotification","Not logged in, skipping scaffold notification");return}i.info("ScaffoldNotification","Notifying scaffold complete",{baseUrl:t.getBaseUrl()});const f=await t.markScaffolded();f.success?i.info("ScaffoldNotification","Scaffold complete notification sent"):i.warn("ScaffoldNotification","Scaffold notification failed",{error:a(e(f.error))})}catch(o){i.warn("ScaffoldNotification","Failed to notify scaffold complete",{error:a(o instanceof Error?o.message:String(o))})}}export{l as notifyScaffoldComplete};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort `AwsContext.destroyInstance()` swallowing any rejection.
|
|
3
|
+
*
|
|
4
|
+
* Used in `finally` blocks and signal-cleanup callbacks where a cleanup throw
|
|
5
|
+
* would replace the in-flight return value or unhandled-rejection-stall the
|
|
6
|
+
* process. Per `.claude/rules/robustness-standards.md § "Awaits inside finally
|
|
7
|
+
* must be caught"`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function cleanupAwsContext(): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AwsContext as t}from"../aws/AwsContext.js";import{getErrorMessage as o}from"./errorUtils.js";import{logger as r}from"./logger/index.js";async function c(){await t.destroyInstance().catch(e=>{r.debug("aws-cleanup","AwsContext cleanup failed",{error:o(e)})})}export{c as cleanupAwsContext};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Fjall tag construction for AWS resources created outside CloudFormation.
|
|
3
|
+
*
|
|
4
|
+
* Both SecretsService (SSM) and SecretManagerService (Secrets Manager) apply
|
|
5
|
+
* the same core tag set. This helper prevents drift between the two.
|
|
6
|
+
*
|
|
7
|
+
* See: aiDocs/patterns/tagging-strategy.md
|
|
8
|
+
*/
|
|
9
|
+
export interface FjallTag {
|
|
10
|
+
Key: string;
|
|
11
|
+
Value: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Build the core Fjall tags applied to all CLI-managed secrets.
|
|
15
|
+
*
|
|
16
|
+
* Returns: fjall:managed, fjall:application, fjall:costAllocation:service,
|
|
17
|
+
* and fjall:costAllocation:environment (when environment is resolvable).
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildCoreFjallTags(appName: string, environment: string | undefined): FjallTag[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(l,a){return[{Key:"fjall:managed",Value:"true"},{Key:"fjall:application",Value:l},{Key:"fjall:costAllocation:service",Value:l},...a?[{Key:"fjall:costAllocation:environment",Value:a}]:[]]}export{e as buildCoreFjallTags};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BuildxProgressEvent } from "@fjall/util/docker";
|
|
2
|
+
import type { ResourceEvent } from "../aws/utils/cloudformationEvents.js";
|
|
3
|
+
/**
|
|
4
|
+
* Project a BuildxProgressEvent onto a ResourceEvent shape consumable by
|
|
5
|
+
* useParallelOperations.addEvent(stack, event).
|
|
6
|
+
*
|
|
7
|
+
* Pure given a fixed clock — no env reads, no logger calls, no closure state.
|
|
8
|
+
* The orchestrator owns the clock (production: () => new Date()); tests pass
|
|
9
|
+
* a deterministic stub.
|
|
10
|
+
*
|
|
11
|
+
* Per-event status projection:
|
|
12
|
+
* vertex / log / status / warning → "running"
|
|
13
|
+
* Terminal transitions ("complete" / "failed") are emitted by the orchestrator
|
|
14
|
+
* directly via useParallelOperations.updateStatus, NOT by this adapter — the
|
|
15
|
+
* adapter only emits per-event projections.
|
|
16
|
+
*
|
|
17
|
+
* The event message has already been masked at the DockerCli boundary (PR 0);
|
|
18
|
+
* this adapter does NOT re-mask.
|
|
19
|
+
*/
|
|
20
|
+
export declare function mapBuildxEventToResourceEvent(serviceName: string, event: BuildxProgressEvent, clock: () => Date): ResourceEvent;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function u(t,e,s){return{logicalId:t,resourceType:e.type,status:a(e),timestamp:s(),...e.message!==""?{statusReason:e.message}:{}}}function a(t){switch(t.type){case"vertex":case"log":case"status":case"warning":return"running";default:return t.type}}export{u as mapBuildxEventToResourceEvent};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { toPascalCase, toKebab, capitalise } from "@fjall/util";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{toPascalCase as o,toKebab as t,capitalise as s}from"@fjall/util";export{s as capitalise,t as toKebab,o as toPascalCase};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { CodemodErrorKind } from "@fjall/generator/codemod";
|
|
2
|
+
/**
|
|
3
|
+
* Write-path codemod operations that contribute to the telemetry
|
|
4
|
+
* denominator. Read-only operations (list/validate/history) do NOT emit.
|
|
5
|
+
*/
|
|
6
|
+
export type CodemodOp = "add" | "remove" | "modify";
|
|
7
|
+
/**
|
|
8
|
+
* PII-minimised telemetry envelope for codemod CLI events.
|
|
9
|
+
*
|
|
10
|
+
* The type deliberately omits `message`, `path`, `name`, `content`,
|
|
11
|
+
* `properties`, and `filePath` so the compiler rejects any attempt to
|
|
12
|
+
* leak user-value strings through this boundary.
|
|
13
|
+
*/
|
|
14
|
+
export interface CliTelemetryEvent {
|
|
15
|
+
event: `codemod.${CodemodOp}.${"started" | "completed" | "failed"}`;
|
|
16
|
+
organisationId: string | null;
|
|
17
|
+
operation: CodemodOp;
|
|
18
|
+
statementType: string | null;
|
|
19
|
+
durationMs: number | null;
|
|
20
|
+
errorKind: CodemodErrorKind | null;
|
|
21
|
+
interactive: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Fire-and-forget telemetry emitter for the codemod CLI surface.
|
|
25
|
+
*
|
|
26
|
+
* Posts a PostHog-compatible envelope to the webapp's cli-telemetry
|
|
27
|
+
* ingress route with a 2-second timeout. Every transport error is
|
|
28
|
+
* caught at `logger.debug` — the helper NEVER throws.
|
|
29
|
+
*
|
|
30
|
+
* Kill-switch: `FJALL_CLI_TELEMETRY=off` short-circuits at entry.
|
|
31
|
+
*/
|
|
32
|
+
export declare function emitCliTelemetry(event: CliTelemetryEvent): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import E from"axios";import{resolveApiKey as f}from"../api/resolveApiKey.js";import{DEFAULT_BASE_URL as y,USER_AGENT as g}from"../api/FjallApiClient.types.js";import{logger as n}from"../logger/index.js";const i="CliTelemetry",u="/api/cli-telemetry",d=2e3;async function v(s){if(process.env.FJALL_CLI_TELEMETRY==="off")return;const o=f();if(!o){n.debug(i,"Skipping telemetry \u2014 no API key resolved");return}const l=`${y}${u}`,{event:a,...c}=s,m={event:a,properties:c},p={"Content-Type":"application/json","User-Agent":g,Authorization:`Bearer ${o}`},r=new AbortController;let e;try{e=setTimeout(()=>r.abort(),d),await E.post(l,m,{headers:p,signal:r.signal})}catch(t){const T=t instanceof Error?t.message:String(t);n.debug(i,`Telemetry post failed: ${T}`)}finally{e!==void 0&&clearTimeout(e)}}export{v as emitCliTelemetry};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CodemodError } from "@fjall/generator/codemod";
|
|
2
|
+
import type { CodemodIoError } from "../../operations/codemodHistory.js";
|
|
3
|
+
export declare const CODEMOD_EXIT_CODES: {
|
|
4
|
+
readonly SUCCESS: 0;
|
|
5
|
+
readonly GENERIC_ERROR: 1;
|
|
6
|
+
readonly USER_ERROR: 2;
|
|
7
|
+
readonly STATE_CONFLICT: 3;
|
|
8
|
+
readonly IO_ERROR: 4;
|
|
9
|
+
};
|
|
10
|
+
export type CodemodExitCode = (typeof CODEMOD_EXIT_CODES)[keyof typeof CODEMOD_EXIT_CODES];
|
|
11
|
+
export declare function mapCodemodErrorToExitCode(error: CodemodError | CodemodIoError): CodemodExitCode;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const r={SUCCESS:0,GENERIC_ERROR:1,USER_ERROR:2,STATE_CONFLICT:3,IO_ERROR:4};function o(e){switch(e.kind){case"ParseError":case"TemplateLiteralNameError":case"ResourceNotFoundError":case"InvalidPropertyError":case"PermissionError":return r.USER_ERROR;case"DuplicateResourceError":case"ReferencesRemainError":case"DriftConflictError":case"DriftUnmergeableError":return r.STATE_CONFLICT;case"ControlFlowClassifierError":case"LlmFallbackRejectedError":case"LlmFallbackUnsafeInputError":return r.USER_ERROR;case"LlmFallbackTimeoutError":return r.STATE_CONFLICT;case"SemanticQueryError":return r.GENERIC_ERROR;case"IoError":case"NotFoundError":case"InvalidSnapshotError":return r.IO_ERROR;default:{const E=e;return r.GENERIC_ERROR}}}export{r as CODEMOD_EXIT_CODES,o as mapCodemodErrorToExitCode};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{CODEMOD_EXIT_CODES as e,mapCodemodErrorToExitCode as d}from"./exitCodes.js";import{renderCodemodError as m,renderCodemodSuccess as C}from"./renderCodemod.js";import{CODEMOD_STEP_LABELS as O}from"./stepLabels.js";export{e as CODEMOD_EXIT_CODES,O as CODEMOD_STEP_LABELS,d as mapCodemodErrorToExitCode,m as renderCodemodError,C as renderCodemodSuccess};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CodemodError, CodemodSuccess } from "@fjall/generator/codemod";
|
|
2
|
+
import type { CodemodIoError } from "../../operations/codemodHistory.js";
|
|
3
|
+
import type { OutputWriter } from "../nonInteractive/nonInteractiveOutput.js";
|
|
4
|
+
export declare function renderCodemodSuccess(writer: OutputWriter, op: "add" | "remove" | "modify", filePath: string, data: CodemodSuccess): void;
|
|
5
|
+
export declare function renderCodemodError(writer: OutputWriter, error: CodemodError | CodemodIoError): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{maskSensitiveOutput as d}from"@fjall/util";import{formatDuration as u}from"../formatDuration.js";const a=(n,e)=>{n.indent(d(e))};function l(n,e,t,c){const{linesChanged:s,references:o}=c,i=s.added===0&&s.removed===0?"no-op (already at target state)":`+${String(s.added)}/-${String(s.removed)}`;n.indent(`${e} succeeded: ${i} in ${t}`),e==="remove"&&o!==void 0&&n.indent(o.length===0?"No remaining references to the removed resource.":`${String(o.length)} remaining reference${o.length===1?"":"s"} (use --force to override).`)}function $(n,e){switch(e.kind){case"ParseError":a(n,`Parse error: ${e.message||"unrecoverable syntax in target file"}`);return;case"TemplateLiteralNameError":a(n,`Template-literal name not supported. ${e.suggestion}`);return;case"DuplicateResourceError":a(n,`Resource '${e.name}' (${e.type}) already exists \u2014 choose a different name.`);return;case"ResourceNotFoundError":a(n,`Resource not found: ${e.name} (${e.type}).`);return;case"ReferencesRemainError":a(n,`Cannot remove '${e.variable}' \u2014 ${String(e.references.length)} reference${e.references.length===1?"":"s"} remain. Use --force to override.`);return;case"InvalidPropertyError":a(n,`Invalid property ${e.property}: ${e.reason}`);return;case"SemanticQueryError":a(n,`Semantic analysis failed: ${e.reason}`);return;case"PermissionError":{const t=e.remediation!==void 0?` ${e.remediation}`:"";a(n,`Permission error (${e.reason}): ${e.details}.${t}`);return}case"IoError":a(n,`I/O error during ${e.operation} on ${e.path}: ${e.cause instanceof Error?e.cause.message:String(e.cause)}`);return;case"NotFoundError":a(n,`Not found: ${e.path}`);return;case"InvalidSnapshotError":a(n,`Invalid snapshot ${e.path}: ${e.reason}`);return;case"DriftConflictError":{const t=e.deltas.filter(s=>s.verdict==="conflict").map(s=>s.property),c=e.remediation!==void 0?` ${e.remediation}`:"";a(n,`Drift conflict on ${e.resource.type} '${e.resource.name}': conflicting properties [${t.join(", ")}].${c}`);return}case"DriftUnmergeableError":a(n,`Cannot merge drift on ${e.resource.type} '${e.resource.name}': ${e.reason}`);return;case"ControlFlowClassifierError":{const t=e.remediation!==void 0?` ${e.remediation}`:"";a(n,`Operation refused (${e.reason}): ${e.resource.type} '${e.resource.name}'.${t}`);return}case"LlmFallbackRejectedError":a(n,`LLM fallback (${e.tier}) rejected at gate "${e.failedGate}": ${e.diagnostics}`);return;case"LlmFallbackTimeoutError":a(n,`LLM fallback (${e.tier}) timed out after ${u(e.elapsedMs)}.`);return;case"LlmFallbackUnsafeInputError":a(n,`LLM fallback blocked: ${String(e.count)} ${e.reason} match(es) detected in input.`);return;default:{const t=e;a(n,"Unknown codemod error.")}}}export{$ as renderCodemodError,l as renderCodemodSuccess};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const CODEMOD_STEP_LABELS: {
|
|
2
|
+
readonly add: readonly ["Locating", "Inserting", "Validating", "Writing"];
|
|
3
|
+
readonly remove: readonly ["Locating", "Removing", "Validating", "Writing"];
|
|
4
|
+
readonly modify: readonly ["Locating", "Modifying", "Validating", "Writing"];
|
|
5
|
+
readonly validate: readonly ["Validating"];
|
|
6
|
+
readonly undo: readonly ["Restoring"];
|
|
7
|
+
readonly list: readonly ["Listing"];
|
|
8
|
+
readonly history: readonly ["Listing"];
|
|
9
|
+
readonly "history-restore": readonly ["Restoring"];
|
|
10
|
+
};
|
|
11
|
+
export type CodemodOp = keyof typeof CODEMOD_STEP_LABELS;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const i={add:["Locating","Inserting","Validating","Writing"],remove:["Locating","Removing","Validating","Writing"],modify:["Locating","Modifying","Validating","Writing"],validate:["Validating"],undo:["Restoring"],list:["Listing"],history:["Listing"],"history-restore":["Restoring"]};export{i as CODEMOD_STEP_LABELS};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colour manipulation utilities for terminal rendering.
|
|
3
|
+
* Supports hex (#RRGGBB) and rgb(r,g,b) formats.
|
|
4
|
+
*/
|
|
5
|
+
export interface RGB {
|
|
6
|
+
r: number;
|
|
7
|
+
g: number;
|
|
8
|
+
b: number;
|
|
9
|
+
}
|
|
10
|
+
/** Parse a hex colour (#RRGGBB) or rgb(r,g,b) string to RGB components */
|
|
11
|
+
export declare function parseColour(colour: string): RGB | undefined;
|
|
12
|
+
/** Convert RGB components to a hex colour string */
|
|
13
|
+
export declare function toHex(rgb: RGB): `#${string}`;
|
|
14
|
+
/**
|
|
15
|
+
* Linearly interpolate between two colours.
|
|
16
|
+
* @param from - Start colour
|
|
17
|
+
* @param to - End colour
|
|
18
|
+
* @param t - Interpolation factor (0 = from, 1 = to)
|
|
19
|
+
* @returns Interpolated colour as hex string
|
|
20
|
+
*/
|
|
21
|
+
export declare function interpolateColour(from: RGB, to: RGB, t: number): `#${string}`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function i(t){if(t.startsWith("#")&&t.length===7){const r=parseInt(t.slice(1,3),16),a=parseInt(t.slice(3,5),16),e=parseInt(t.slice(5,7),16);if(!Number.isNaN(r)&&!Number.isNaN(a)&&!Number.isNaN(e))return{r,g:a,b:e}}const n=t.match(/^rgb\((\d+),(\d+),(\d+)\)$/);if(n)return{r:parseInt(n[1]??"0",10),g:parseInt(n[2]??"0",10),b:parseInt(n[3]??"0",10)}}function s(t){const n=Math.max(0,Math.min(255,Math.round(t.r))),r=Math.max(0,Math.min(255,Math.round(t.g))),a=Math.max(0,Math.min(255,Math.round(t.b)));return`#${n.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}`}function h(t,n,r){const a=Math.max(0,Math.min(1,r));return s({r:t.r+(n.r-t.r)*a,g:t.g+(n.g-t.g)*a,b:t.b+(n.b-t.b)*a})}export{h as interpolateColour,i as parseColour,s as toHex};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type CommandInfo = {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Registers an error handler for unknown commands on a commander command object
|
|
7
|
+
*
|
|
8
|
+
* @param command The commander command object to register the handler on
|
|
9
|
+
* @param commandType 'command' for top-level commands, 'subcommand' for subcommands
|
|
10
|
+
* @param commands List of available commands with names and descriptions
|
|
11
|
+
* @param parentCommand Optional name of the parent command for subcommands
|
|
12
|
+
*/
|
|
13
|
+
export declare function registerUnknownCommandHandler(command: {
|
|
14
|
+
on: (event: string | symbol, handler: (...args: unknown[]) => void) => unknown;
|
|
15
|
+
outputHelp: () => void;
|
|
16
|
+
}, commandType: "command" | "subcommand", _commands: CommandInfo[], _parentCommand?: string): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{error as t}from"./log.js";function d(n,o,m,p){n.on("command:*",function(...r){const e=r[0];t(`Unknown ${o}: ${e[0]}`),n.outputHelp(),process.exitCode=1})}export{d as registerUnknownCommandHandler};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Result } from "../types/Result.js";
|
|
2
|
+
import type { ProgressEvent, ProgressCallbacks } from "../types/ProgressEvent.js";
|
|
3
|
+
import type { OutputWriter } from "./nonInteractive/nonInteractiveOutput.js";
|
|
4
|
+
/**
|
|
5
|
+
* Sentinel error for cases where the error has already been displayed.
|
|
6
|
+
* The top-level handler in cli.ts exits with code 1 without printing the message again.
|
|
7
|
+
*/
|
|
8
|
+
export declare class SilentExitError extends Error {
|
|
9
|
+
constructor();
|
|
10
|
+
}
|
|
11
|
+
export interface CommandResult {
|
|
12
|
+
success?: boolean;
|
|
13
|
+
message?: string;
|
|
14
|
+
cancelled?: boolean;
|
|
15
|
+
error?: Error | string;
|
|
16
|
+
finalState?: unknown;
|
|
17
|
+
}
|
|
18
|
+
export declare function handleUIResult(result: CommandResult | undefined): void;
|
|
19
|
+
export declare function handleServiceResult(result: CommandResult): void;
|
|
20
|
+
export declare function throwOnFailure<T>(result: Result<T, unknown>): asserts result is {
|
|
21
|
+
success: true;
|
|
22
|
+
data: T;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Context passed by command handlers to `handleCommandError` for agent-mode
|
|
26
|
+
* suggestion resolution. Optional — existing non-agent callers pass nothing
|
|
27
|
+
* and behaviour is unchanged.
|
|
28
|
+
*/
|
|
29
|
+
export interface CommandErrorContext {
|
|
30
|
+
readonly command?: string;
|
|
31
|
+
readonly flags?: Readonly<Record<string, string>>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Unified command-error handler. In standard CLI mode this simply re-throws
|
|
35
|
+
* so the top-level handler can format and print to stderr. In agent mode it
|
|
36
|
+
* emits a structured TOON error block to stdout and exits with the mapped
|
|
37
|
+
* code — bypassing the stderr path entirely.
|
|
38
|
+
*
|
|
39
|
+
* Masking happens inline here because the agent error path bypasses the
|
|
40
|
+
* `AgentOutputWriter` callback path. This is the other half of the
|
|
41
|
+
* "two separate single boundaries" masking policy (see synthesis §1.11).
|
|
42
|
+
*/
|
|
43
|
+
export declare function handleCommandError(error: unknown, context?: CommandErrorContext): never;
|
|
44
|
+
export declare function throwIfInvalidOptions(validation: {
|
|
45
|
+
success: true;
|
|
46
|
+
} | {
|
|
47
|
+
success: false;
|
|
48
|
+
error: {
|
|
49
|
+
message: string;
|
|
50
|
+
};
|
|
51
|
+
}): void;
|
|
52
|
+
export declare function requireOption<T>(value: T | undefined | null, name: string, flag: string): asserts value is T;
|
|
53
|
+
export declare function requireArg(value: string | undefined, name: string, usage: string): asserts value is string;
|
|
54
|
+
export declare function throwUnknownSubcommand(subcommand: string, available: string[]): never;
|
|
55
|
+
export declare function createCLIProgressCallback(writer: OutputWriter): (event: ProgressEvent) => void;
|
|
56
|
+
export declare function createProgressHandler(writer: OutputWriter, verbose: boolean): ProgressCallbacks;
|
|
57
|
+
export declare function validateRequiredArgs(args: Record<string, unknown>, required: string[]): void;
|
|
58
|
+
interface ValidationServiceLike {
|
|
59
|
+
getMissingRequiredFields(command: string, options: Record<string, unknown>): string[];
|
|
60
|
+
fieldNamesToFlags(fields: string[]): string[];
|
|
61
|
+
}
|
|
62
|
+
export declare function throwIfMissingFields(validationService: ValidationServiceLike, command: string, options: Record<string, unknown>, interactiveModeHint?: string): void;
|
|
63
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getErrorMessage as l}from"./errorUtils.js";import t from"chalk";import{theme as m}from"./theme.js";import{maskSensitiveOutput as c}from"@fjall/util";import{isAgentMode as p}from"./executionMode.js";import{extractMessage as h,mapErrorToCode as w,isUserActionRequired as E}from"./agent/errorCodes.js";import{renderError as k,renderHelp as x,joinBlocks as b}from"./agent/toonFormatter.js";import{SuggestionResolver as $}from"./agent/suggestions.js";class q extends Error{constructor(){super("Silent exit"),this.name="SilentExitError"}}function B(r){if(!r)throw new Error("UI operation returned no result");if(!r.cancelled&&!r.success)throw r.finalState?new q:new Error(r.message||"UI operation failed")}function P(r){if(!r.success){const e=r.message||(r.error?l(r.error):void 0)||"Operation failed";throw new Error(e)}}function L(r){if(!r.success)throw new Error(l(r.error))}function T(r,e){throw p()&&I(r,e),r}function I(r,e){const o=w(r),n=h(r),i={message:c(n),code:o,userActionRequired:E(o)},f=k(i);let a="";if(e?.command!==void 0&&e.command.length>0){const d=new $(e.command,e.flags??{}).resolve({command:e.command,outcome:"error"});d.length>0&&(a=x(d))}const u=b([f,a]);process.stdout.write(u);const g=M(o);throw process.exit(g),r}function M(r){return r==="VALIDATION_ERROR"?2:1}function y(r){if(!r.success)throw console.error("Error: Invalid options provided:"),console.error(` ${c(r.error.message)}`),new Error("Invalid options provided")}function D(r,e,o){if(r==null||r==="")throw console.error(`Error: ${e} is required. Use --${o} flag`),new Error(`${e} is required`)}function H(r,e,o){if(!r)throw console.error(`Error: ${e} is required`),console.error(`Usage: ${o}`),new Error(`${e} is required`)}function N(r,e){throw console.error(`Error: Unknown subcommand '${r}'`),console.error(`Available subcommands: ${e.join(", ")}`),new Error(`Unknown subcommand '${r}'`)}function W(r){const e=m.colours;return o=>{const n=c(o.message);switch(o.type){case"step":r.indent(t.hex(e.completed)("\u2713")+" "+n);break;case"warning":r.indent(t.hex(e.warning)("Warning: "+n));break;case"info":r.indent(n,2);break;case"error":r.indent(t.hex(e.error)("Error: "+n));break;case"debug":break}}}function G(r,e){const o=m.colours;return{onProgress:n=>{const s=c(n.message);switch(n.type){case"step":r.indent(s);break;case"info":r.indent(s,2);break;case"spinner":r.indent(`${s}...`,2);break;case"warning":r.indent(`Warning: ${s}`);break;case"error":r.indent(t.hex(o.error)(`Error: ${s}`));break;case"debug":e&&r.indent(`[DEBUG] ${s}`,2);break}}}}function V(r,e){const o=e.filter(n=>r[n]===void 0||r[n]===null);if(o.length>0)throw new Error(`Missing required arguments: ${o.join(", ")}`)}function _(r,e,o,n="omit --non-interactive for interactive mode"){const s=r.getMissingRequiredFields(e,o);if(s.length>0){const i=r.fieldNamesToFlags(s);throw console.error(`Error: Missing required fields: ${i.join(", ")}`),console.error(`Provide all required flags or ${n}`),new Error(`Missing required fields: ${i.join(", ")}`)}}export{q as SilentExitError,W as createCLIProgressCallback,G as createProgressHandler,T as handleCommandError,P as handleServiceResult,B as handleUIResult,H as requireArg,D as requireOption,y as throwIfInvalidOptions,_ as throwIfMissingFields,L as throwOnFailure,N as throwUnknownSubcommand,V as validateRequiredArgs};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Result } from "../types/Result.js";
|
|
2
|
+
export interface RunWithBoundedConcurrencyOptions {
|
|
3
|
+
/**
|
|
4
|
+
* When true, stop issuing new jobs after the first failure. The orchestrator
|
|
5
|
+
* is responsible for owning the AbortController and signalling in-flight jobs;
|
|
6
|
+
* this runner only propagates the signal to job factories.
|
|
7
|
+
*/
|
|
8
|
+
abortOnFirstFailure?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Optional abort signal propagated to every job. Jobs are responsible for
|
|
11
|
+
* honouring the signal themselves.
|
|
12
|
+
*/
|
|
13
|
+
abortSignal?: AbortSignal;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Run a list of async jobs with a bounded number in-flight at any tick.
|
|
17
|
+
*
|
|
18
|
+
* Returns results in INPUT order (job N's result lives at index N) regardless
|
|
19
|
+
* of completion order. When `abortOnFirstFailure` is true, the runner stops
|
|
20
|
+
* issuing new jobs after the first failure but does NOT cancel in-flight jobs
|
|
21
|
+
* — the orchestrator owns the AbortController and is responsible for
|
|
22
|
+
* propagating the signal source.
|
|
23
|
+
*/
|
|
24
|
+
export declare function runWithBoundedConcurrency<T>(jobs: ReadonlyArray<() => Promise<T>>, concurrency: number, opts?: RunWithBoundedConcurrencyOptions): Promise<Array<Result<T, Error>>>;
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the per-orchestrator-run build concurrency from the
|
|
27
|
+
* `FJALL_BUILD_CONCURRENCY` environment variable, clamped to `[1, serviceCount]`.
|
|
28
|
+
*
|
|
29
|
+
* - Empty-string env values are rejected (per robustness-standards.md
|
|
30
|
+
* § "Environment Variable Truthy Checks").
|
|
31
|
+
* - Non-integer / non-positive values fall back to the default.
|
|
32
|
+
* - When `serviceCount === 0`, returns `1` (no jobs would be issued anyway).
|
|
33
|
+
* - The default is CPU-aware (see `defaultBuildConcurrency`).
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveBuildConcurrency(serviceCount: number): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import p from"os";import{success as y,failure as x}from"../types/Result.js";async function F(r,e,a={}){const t=r.length,i=new Array(t);if(t===0)return i;const l=Math.max(1,Math.min(e,t)),c=a.abortOnFirstFailure===!0;let u=0,s=!1;async function h(){for(;;){if(c&&s)return;const n=u;if(n>=t)return;u=n+1;const d=r[n];try{const o=await d();i[n]=y(o)}catch(o){const m=o instanceof Error?o:new Error(String(o));i[n]=x(m),c&&(s=!0)}}}const f=[];for(let n=0;n<l;n++)f.push(h());return await Promise.all(f),i}function w(r){const e=p.cpus().length;return Math.min(r,Math.max(2,Math.floor(e/2)))}function g(r){if(r<=0)return 1;const e=process.env.FJALL_BUILD_CONCURRENCY;let a=w(r);if(e!==void 0&&e!==""){const t=parseInt(e,10);Number.isInteger(t)&&t>0&&(a=t)}return Math.max(1,Math.min(a,r))}export{g as resolveBuildConcurrency,F as runWithBoundedConcurrency};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ResourceEvent } from "@fjall/util/aws";
|
|
3
|
+
import { type ResourceMapEntry } from "@fjall/util/constructMap";
|
|
4
|
+
/**
|
|
5
|
+
* Deployment event schema for CLI-side event emission.
|
|
6
|
+
*
|
|
7
|
+
* The canonical schema lives in @fjall/deploy-core (deploymentEventSchema.ts)
|
|
8
|
+
* and is used by both the webapp and worker. The CLI maintains its own copy
|
|
9
|
+
* because deploy-core's schema adds `.max()` length constraints for server-side
|
|
10
|
+
* input validation — the CLI is the emitter, not the receiver, so those
|
|
11
|
+
* constraints would incorrectly reject valid CloudFormation resource names and
|
|
12
|
+
* log messages that exceed the inbound limits.
|
|
13
|
+
*/
|
|
14
|
+
declare const CASCADE_PHASES: readonly ["platform", "domains", "accounts"];
|
|
15
|
+
declare const CASCADE_ACCOUNT_STATUSES: readonly ["started", "deploying", "completed", "failed"];
|
|
16
|
+
export declare const DeploymentProgressEventSchema: z.ZodObject<{
|
|
17
|
+
type: z.ZodEnum<{
|
|
18
|
+
error: "error";
|
|
19
|
+
step: "step";
|
|
20
|
+
complete: "complete";
|
|
21
|
+
resource: "resource";
|
|
22
|
+
docker: "docker";
|
|
23
|
+
ecs: "ecs";
|
|
24
|
+
cascade_phase: "cascade_phase";
|
|
25
|
+
cascade_account: "cascade_account";
|
|
26
|
+
parallel_phase: "parallel_phase";
|
|
27
|
+
detection: "detection";
|
|
28
|
+
log: "log";
|
|
29
|
+
}>;
|
|
30
|
+
timestamp: z.ZodString;
|
|
31
|
+
sequence: z.ZodOptional<z.ZodNumber>;
|
|
32
|
+
step: z.ZodOptional<z.ZodObject<{
|
|
33
|
+
id: z.ZodString;
|
|
34
|
+
name: z.ZodString;
|
|
35
|
+
index: z.ZodNumber;
|
|
36
|
+
total: z.ZodNumber;
|
|
37
|
+
status: z.ZodString;
|
|
38
|
+
}, z.core.$strict>>;
|
|
39
|
+
resource: z.ZodOptional<z.ZodObject<{
|
|
40
|
+
logicalId: z.ZodString;
|
|
41
|
+
resourceType: z.ZodString;
|
|
42
|
+
category: z.ZodEnum<{
|
|
43
|
+
security: "security";
|
|
44
|
+
network: "network";
|
|
45
|
+
compute: "compute";
|
|
46
|
+
database: "database";
|
|
47
|
+
storage: "storage";
|
|
48
|
+
monitoring: "monitoring";
|
|
49
|
+
dns: "dns";
|
|
50
|
+
identity: "identity";
|
|
51
|
+
bootstrap: "bootstrap";
|
|
52
|
+
events: "events";
|
|
53
|
+
registry: "registry";
|
|
54
|
+
backup: "backup";
|
|
55
|
+
}>;
|
|
56
|
+
group: z.ZodOptional<z.ZodString>;
|
|
57
|
+
constructPath: z.ZodOptional<z.ZodString>;
|
|
58
|
+
displayName: z.ZodString;
|
|
59
|
+
status: z.ZodString;
|
|
60
|
+
statusReason: z.ZodOptional<z.ZodString>;
|
|
61
|
+
physicalId: z.ZodOptional<z.ZodString>;
|
|
62
|
+
expectedDurationSeconds: z.ZodOptional<z.ZodNumber>;
|
|
63
|
+
stack: z.ZodOptional<z.ZodString>;
|
|
64
|
+
}, z.core.$strict>>;
|
|
65
|
+
docker: z.ZodOptional<z.ZodObject<{
|
|
66
|
+
message: z.ZodString;
|
|
67
|
+
percentage: z.ZodOptional<z.ZodNumber>;
|
|
68
|
+
}, z.core.$strict>>;
|
|
69
|
+
ecs: z.ZodOptional<z.ZodObject<{
|
|
70
|
+
status: z.ZodString;
|
|
71
|
+
message: z.ZodOptional<z.ZodString>;
|
|
72
|
+
percentage: z.ZodOptional<z.ZodNumber>;
|
|
73
|
+
}, z.core.$strict>>;
|
|
74
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
75
|
+
message: z.ZodString;
|
|
76
|
+
category: z.ZodOptional<z.ZodString>;
|
|
77
|
+
remediation: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
78
|
+
}, z.core.$strict>>;
|
|
79
|
+
message: z.ZodOptional<z.ZodString>;
|
|
80
|
+
cascadePhase: z.ZodOptional<z.ZodObject<{
|
|
81
|
+
phase: z.ZodEnum<{
|
|
82
|
+
platform: "platform";
|
|
83
|
+
domains: "domains";
|
|
84
|
+
accounts: "accounts";
|
|
85
|
+
}>;
|
|
86
|
+
status: z.ZodEnum<{
|
|
87
|
+
started: "started";
|
|
88
|
+
completed: "completed";
|
|
89
|
+
}>;
|
|
90
|
+
}, z.core.$strict>>;
|
|
91
|
+
cascadeAccount: z.ZodOptional<z.ZodObject<{
|
|
92
|
+
accountId: z.ZodString;
|
|
93
|
+
region: z.ZodString;
|
|
94
|
+
operationKey: z.ZodString;
|
|
95
|
+
status: z.ZodEnum<{
|
|
96
|
+
started: "started";
|
|
97
|
+
deploying: "deploying";
|
|
98
|
+
completed: "completed";
|
|
99
|
+
failed: "failed";
|
|
100
|
+
}>;
|
|
101
|
+
error: z.ZodOptional<z.ZodString>;
|
|
102
|
+
phase: z.ZodOptional<z.ZodEnum<{
|
|
103
|
+
deploy: "deploy";
|
|
104
|
+
destroy: "destroy";
|
|
105
|
+
bootstrap: "bootstrap";
|
|
106
|
+
synth: "synth";
|
|
107
|
+
}>>;
|
|
108
|
+
cascadePhase: z.ZodOptional<z.ZodEnum<{
|
|
109
|
+
platform: "platform";
|
|
110
|
+
domains: "domains";
|
|
111
|
+
accounts: "accounts";
|
|
112
|
+
}>>;
|
|
113
|
+
}, z.core.$strict>>;
|
|
114
|
+
parallelPhase: z.ZodOptional<z.ZodObject<{
|
|
115
|
+
stacks: z.ZodArray<z.ZodString>;
|
|
116
|
+
status: z.ZodEnum<{
|
|
117
|
+
started: "started";
|
|
118
|
+
completed: "completed";
|
|
119
|
+
}>;
|
|
120
|
+
results: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
121
|
+
stack: z.ZodString;
|
|
122
|
+
success: z.ZodBoolean;
|
|
123
|
+
error: z.ZodOptional<z.ZodString>;
|
|
124
|
+
}, z.core.$strict>>>;
|
|
125
|
+
}, z.core.$strict>>;
|
|
126
|
+
detection: z.ZodOptional<z.ZodObject<{
|
|
127
|
+
pattern: z.ZodNullable<z.ZodString>;
|
|
128
|
+
hasDockerfile: z.ZodBoolean;
|
|
129
|
+
hasDifferences: z.ZodBoolean;
|
|
130
|
+
resources: z.ZodObject<{
|
|
131
|
+
hasNetwork: z.ZodBoolean;
|
|
132
|
+
hasCompute: z.ZodBoolean;
|
|
133
|
+
hasDatabase: z.ZodBoolean;
|
|
134
|
+
hasStorage: z.ZodBoolean;
|
|
135
|
+
hasMessaging: z.ZodBoolean;
|
|
136
|
+
hasCdn: z.ZodBoolean;
|
|
137
|
+
}, z.core.$strict>;
|
|
138
|
+
requiredSecrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
139
|
+
}, z.core.$strict>>;
|
|
140
|
+
log: z.ZodOptional<z.ZodObject<{
|
|
141
|
+
message: z.ZodString;
|
|
142
|
+
level: z.ZodEnum<{
|
|
143
|
+
debug: "debug";
|
|
144
|
+
info: "info";
|
|
145
|
+
warn: "warn";
|
|
146
|
+
}>;
|
|
147
|
+
}, z.core.$strict>>;
|
|
148
|
+
}, z.core.$strict>;
|
|
149
|
+
export type DeploymentProgressEvent = z.infer<typeof DeploymentProgressEventSchema>;
|
|
150
|
+
export type { ResourceCategory } from "@fjall/util";
|
|
151
|
+
export type CascadePhase = (typeof CASCADE_PHASES)[number];
|
|
152
|
+
export type CascadeAccountStatus = (typeof CASCADE_ACCOUNT_STATUSES)[number];
|
|
153
|
+
export { categoriseResource, getExpectedDuration } from "@fjall/util";
|
|
154
|
+
export declare function logEvent(message: string, level?: "info" | "debug" | "warn"): DeploymentProgressEvent;
|
|
155
|
+
export declare function toDeploymentEvent(event: ResourceEvent, constructMap?: Map<string, ResourceMapEntry>): DeploymentProgressEvent;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z as e}from"zod";import{RESOURCE_CATEGORIES as c,categoriseResource as i,getExpectedDuration as p}from"@fjall/util";import{enrichFromConstructMap as l}from"@fjall/util/constructMap";const n=["platform","domains","accounts"],u=["started","deploying","completed","failed"],g=["step","resource","docker","ecs","error","complete","cascade_phase","cascade_account","parallel_phase","detection","log"],d={step:"step",resource:"resource",docker:"docker",ecs:"ecs",error:"error",complete:null,cascade_phase:"cascadePhase",cascade_account:"cascadeAccount",parallel_phase:"parallelPhase",detection:"detection",log:"log"},b=e.object({type:e.enum(g),timestamp:e.string(),sequence:e.number().int().nonnegative().optional(),step:e.object({id:e.string(),name:e.string(),index:e.number(),total:e.number(),status:e.string()}).strict().optional(),resource:e.object({logicalId:e.string(),resourceType:e.string(),category:e.enum(c),group:e.string().min(1).max(128).optional(),constructPath:e.string().min(1).max(512).optional(),displayName:e.string(),status:e.string(),statusReason:e.string().optional(),physicalId:e.string().optional(),expectedDurationSeconds:e.number().optional(),stack:e.string().optional()}).strict().optional(),docker:e.object({message:e.string(),percentage:e.number().optional()}).strict().optional(),ecs:e.object({status:e.string(),message:e.string().optional(),percentage:e.number().optional()}).strict().optional(),error:e.object({message:e.string(),category:e.string().optional(),remediation:e.array(e.string()).optional()}).strict().optional(),message:e.string().optional(),cascadePhase:e.object({phase:e.enum(n),status:e.enum(["started","completed"])}).strict().optional(),cascadeAccount:e.object({accountId:e.string(),region:e.string(),operationKey:e.string(),status:e.enum(u),error:e.string().optional(),phase:e.enum(["bootstrap","synth","deploy","destroy"]).optional(),cascadePhase:e.enum(n).optional()}).strict().optional(),parallelPhase:e.object({stacks:e.array(e.string()),status:e.enum(["started","completed"]),results:e.array(e.object({stack:e.string(),success:e.boolean(),error:e.string().optional()}).strict()).optional()}).strict().optional(),detection:e.object({pattern:e.string().nullable(),hasDockerfile:e.boolean(),hasDifferences:e.boolean(),resources:e.object({hasNetwork:e.boolean(),hasCompute:e.boolean(),hasDatabase:e.boolean(),hasStorage:e.boolean(),hasMessaging:e.boolean(),hasCdn:e.boolean()}).strict(),requiredSecrets:e.array(e.string()).optional()}).strict().optional(),log:e.object({message:e.string(),level:e.enum(["info","debug","warn"])}).strict().optional()}).strict().superRefine((t,s)=>{const o=d[t.type],r=o?t[o]:void 0;o&&r==null&&s.addIssue({code:e.ZodIssueCode.custom,message:`"${o}" is required when type is "${t.type}"`,path:[o]}),t.type==="complete"&&!t.message&&s.addIssue({code:e.ZodIssueCode.custom,message:'"message" is required when type is "complete"',path:["message"]})});import{categoriseResource as D,getExpectedDuration as T}from"@fjall/util";function f(t,s="info"){return{type:"log",timestamp:new Date().toISOString(),log:{message:t,level:s}}}function E(t,s){const o=l(t.logicalId,t.resourceType,s),r=t.group??o.group,a=t.constructPath??o.constructPath;return{type:"resource",timestamp:t.timestamp.toISOString(),resource:{logicalId:t.logicalId,resourceType:t.resourceType,category:i(t.resourceType),...r!==void 0?{group:r}:{},...a!==void 0?{constructPath:a}:{},displayName:o.displayName,status:t.status,statusReason:t.statusReason,physicalId:t.physicalId,expectedDurationSeconds:p(t.resourceType)}}}export{b as DeploymentProgressEventSchema,D as categoriseResource,T as getExpectedDuration,f as logEvent,E as toDeploymentEvent};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import o from"chalk";import{INFRASTRUCTURE_FILENAME as i}from"./pathHelpers.js";function E(n,e){const r=n.split(`
|
|
2
|
+
`);r[0].includes("does not exist")?console.error(o.hex("#AE2012")("Error: Target folder ")+o.hex("#0A9396")(e)+o.hex("#AE2012")(" does not exist")):r[0].includes(`No ${i}`)?console.error(o.hex("#AE2012")(`Error: No ${i} found in `)+o.hex("#0A9396")(e)):console.error(o.hex("#AE2012")(`Error: ${r[0]}`)),r[1]&&console.error(o.hex("#FFECD1")(r[1]))}export{E as displayValidationError};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { normaliseError, getErrorMessage, hasErrorCode, getErrorCode, getErrorStack, formatErrorString } from "@fjall/util";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{normaliseError as e,getErrorMessage as t,hasErrorCode as E,getErrorCode as a,getErrorStack as g,formatErrorString as s}from"@fjall/util";export{s as formatErrorString,a as getErrorCode,t as getErrorMessage,g as getErrorStack,E as hasErrorCode,e as normaliseError};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface NonInteractiveOptions {
|
|
2
|
+
nonInteractive?: boolean;
|
|
3
|
+
agent?: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Re-export of agent-mode detection from `./agent/detectAgent.js`.
|
|
7
|
+
* Explicit `options.agent` (true/false) is a hard override; otherwise
|
|
8
|
+
* auto-detection runs (env signals + TTY gate).
|
|
9
|
+
*/
|
|
10
|
+
export declare function isAgentMode(options?: {
|
|
11
|
+
agent?: boolean;
|
|
12
|
+
}): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Determines if the CLI should run in non-interactive mode.
|
|
15
|
+
* Triggered when --non-interactive flag is set, stdout is not a TTY,
|
|
16
|
+
* or agent mode is active (agent mode implies non-interactive).
|
|
17
|
+
*/
|
|
18
|
+
export declare function isNonInteractiveMode(options?: NonInteractiveOptions): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isAgentMode as t}from"./agent/detectAgent.js";function n(e){return t(e)}function o(e){return n(e)?!0:e?.nonInteractive||!process.stdout.isTTY}export{n as isAgentMode,o as isNonInteractiveMode};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatDeltaValue(value: unknown): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{logger as n}from"./logger/index.js";function i(r){if(r===void 0)return"(not set)";if(r===null)return"null";if(typeof r=="string")return r;if(typeof r=="boolean"||typeof r=="number")return String(r);try{return JSON.stringify(r)}catch(t){return n.debug("formatDeltaValue","JSON.stringify failed",{error:t instanceof Error?t.message:String(t)}),String(r)}}export{i as formatDeltaValue};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatDuration(ms: number): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const S=1e3,_=60;function r(n){if(n<1e3)return"<1s";const E=Math.floor(n/1e3);if(E<60)return`${E}s`;const t=Math.floor(E/60),o=E%60;return o>0?`${t}m ${o}s`:`${t}m`}export{r as formatDuration};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatRelativeTime(input: string | Date | number, now?: number): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const E=1e3,c=6e4,M=36e5,i=864e5,D=6048e5,N=2592e6,l=31536e6;function u(o,a=Date.now()){const r=(typeof o=="number"?new Date(o):o instanceof Date?o:new Date(o)).getTime();if(Number.isNaN(r))return"\u2014";const e=a-r,f=e<0,t=Math.abs(e),n=t<6e4?`${Math.floor(t/1e3)}s`:t<36e5?`${Math.floor(t/6e4)}m`:t<864e5?`${Math.floor(t/36e5)}h`:t<6048e5?`${Math.floor(t/864e5)}d`:t<2592e6?`${Math.floor(t/6048e5)}w`:t<31536e6?`${Math.floor(t/2592e6)}mo`:`${Math.floor(t/31536e6)}y`;return f?`in ${n}`:`${n} ago`}export{u as formatRelativeTime};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fuzzy matching algorithm for type-to-search interfaces.
|
|
3
|
+
*
|
|
4
|
+
* Scoring tiers:
|
|
5
|
+
* - Exact match: 100
|
|
6
|
+
* - Prefix match: 80
|
|
7
|
+
* - Contains (in label): 60
|
|
8
|
+
* - Contains (in description): 50
|
|
9
|
+
* - Fuzzy (chars in order): 20 + bonuses for consecutive/early matches
|
|
10
|
+
*/
|
|
11
|
+
export interface FuzzyPickerOption {
|
|
12
|
+
label: string;
|
|
13
|
+
value: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
/** Optional category for grouped display */
|
|
16
|
+
category?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface FuzzyMatchResult {
|
|
19
|
+
/** The matched score (0-100+). Higher = better match */
|
|
20
|
+
score: number;
|
|
21
|
+
/** Indices of matched characters in the label (for highlight rendering) */
|
|
22
|
+
indices: number[];
|
|
23
|
+
}
|
|
24
|
+
export interface FuzzyFilterResult<T> {
|
|
25
|
+
item: T;
|
|
26
|
+
score: number;
|
|
27
|
+
indices: number[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Score a single query against a text string.
|
|
31
|
+
* Returns the match result or null if no match.
|
|
32
|
+
*/
|
|
33
|
+
export declare function fuzzyMatch(query: string, text: string): FuzzyMatchResult | null;
|
|
34
|
+
/**
|
|
35
|
+
* Filter and sort items by fuzzy match score.
|
|
36
|
+
* Items that don't match are excluded. Results sorted by score descending.
|
|
37
|
+
*/
|
|
38
|
+
export declare function fuzzyFilter<T>(query: string, items: readonly T[], getText: (item: T) => string, getDescription?: (item: T) => string | undefined): Array<FuzzyFilterResult<T>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const E=100,N=80,R=60,I=50,l=20,h=5,T=10,d=3;function S(o,e){if(!o)return{score:0,indices:[]};const n=o.toLowerCase(),c=e.toLowerCase();if(c===n)return{score:100,indices:Array.from({length:o.length},(i,s)=>s)};if(c.startsWith(n))return{score:80,indices:Array.from({length:o.length},(i,s)=>s)};const r=c.indexOf(n);if(r>=0)return{score:60,indices:Array.from({length:o.length},(i,s)=>r+s)};const t=u(n,c);if(t.length===n.length){const i=_(t)*5,s=t[0]===0?10:0,O=(t[0]??0)<5?3:0;return{score:20+i+s+O,indices:t}}return null}function a(o,e,n,c){if(!o)return e.map(t=>({item:t,score:0,indices:[]}));const r=[];for(const t of e){const i=n(t),s=S(o,i);if(s){r.push({item:t,score:s.score,indices:s.indices});continue}const O=c?.(t);if(O){const C=S(o,O);if(C){const f=C.score>=60?50:40;r.push({item:t,score:f,indices:[]})}}}return r.sort((t,i)=>i.score-t.score)}function u(o,e){const n=[];let c=0;for(const r of o){const t=e.indexOf(r,c);if(t<0)return n;n.push(t),c=t+1}return n}function _(o){let e=0;for(let n=1;n<o.length;n++)o[n]===(o[n-1]??0)+1&&e++;return e}export{a as fuzzyFilter,S as fuzzyMatch};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{execFileSync as e}from"child_process";import{parseGitRemoteUrl as s,filterDangerousEnvVars as m}from"@fjall/util";const u=5e3;function f(o){try{const r={timeout:u,encoding:"utf-8",env:{...m(process.env),GIT_TERMINAL_PROMPT:"0"},...o!==void 0&&{cwd:o}},t=e("git",["remote","get-url","origin"],r).trim();if(!t)return null;const n=e("git",["rev-parse","HEAD"],r).trim(),i=e("git",["branch","--show-current"],r).trim(),c=s(t)?.provider??"other";return{remoteUrl:t,branch:i,commitSha:n,provider:c}}catch{return null}}export{f as detectGitInfo};
|