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,288 @@
|
|
|
1
|
+
import{existsSync as h,mkdirSync as m,readFileSync as g}from"node:fs";import{join as y,relative as w}from"node:path";import{maskSensitiveOutput as j}from"@fjall/util";import{atomicWrite as f}from"@fjall/util/fsHelpers";import{DEFAULT_BASE_URL as k}from"../api/FjallApiClient.types.js";import{logger as d}from"../logger/index.js";const u=e=>{d.debug("AgentInit","tmp cleanup failed",{error:e instanceof Error?e.message:String(e)})},l="<!-- fjall:managed:start -->",p="<!-- fjall:managed:end -->",v=`---
|
|
2
|
+
name: fjall
|
|
3
|
+
description: Deploy applications to AWS via Fjall CLI. Use when the user asks to deploy, connect AWS, manage secrets, or provision infrastructure.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`;function E(e){const c=[],o=[],t=[],n=y(e,"SKILL.md"),a=w(process.cwd(),n)||"SKILL.md",i=S();try{if(m(e,{recursive:!0}),h(n)){const r=g(n,"utf-8");if(r.includes(l)){const s=A(r,i);s.kind==="corrupt"?(d.warn("AgentInit","MANAGED markers are corrupt \u2014 leaving file untouched",{relPath:a}),t.push(`${a} (corrupt managed markers \u2014 repair manually)`)):s.kind==="unchanged"?t.push(`${a} (no changes)`):(f(n,s.content,{onCleanupError:u}),o.push(a))}else t.push(`${a} (exists, no managed section \u2014 add manually)`)}else f(n,v+b(i),{onCleanupError:u}),c.push(a)}catch(r){const s=j(r instanceof Error?r.message:String(r));d.debug("AgentInit","Skill file write failed",{relPath:a,error:s}),t.push(`${a} (error: ${s})`)}return{created:c,updated:o,skipped:t}}function b(e){return`${l}
|
|
7
|
+
${e}
|
|
8
|
+
${p}
|
|
9
|
+
`}function A(e,c){const o=e.indexOf(l),t=e.indexOf(p);if(o===-1||t===-1||t<o)return{kind:"corrupt"};if(e.lastIndexOf(l)!==o||e.lastIndexOf(p)!==t)return{kind:"corrupt"};const n=e.slice(0,o),a=e.slice(t+p.length),i=`${n}${l}
|
|
10
|
+
${c}
|
|
11
|
+
${p}${a}`;return i===e?{kind:"unchanged"}:{kind:"replaced",content:i}}function S(){return`# Fjall \u2014 Skill for AI Agents
|
|
12
|
+
|
|
13
|
+
You have the Fjall CLI available. Fjall deploys applications to AWS via
|
|
14
|
+
infrastructure-as-code. Always pass \`--agent\` for structured TOON output.
|
|
15
|
+
|
|
16
|
+
## Before You Start
|
|
17
|
+
- Confirm \`FJALL_API_KEY\` is set. If not, tell the user to sign up at
|
|
18
|
+
${k} and run \`fjall login --api-key <key>\`.
|
|
19
|
+
Alternatively, run \`fjall login --device --agent\` to initiate a
|
|
20
|
+
browser-based device-code flow.
|
|
21
|
+
- All Fjall terminology is British English: "organisation", "authorise", "colour".
|
|
22
|
+
- Each \`--agent\` output is **authoritative** \u2014 its \`status\`, \`error\`, and
|
|
23
|
+
\`help[]\` fields tell you what happened and what to do next. You do not
|
|
24
|
+
need to poll a separate state command between steps.
|
|
25
|
+
- **Always run \`fjall\` from the project root.** Scaffolding commands
|
|
26
|
+
(e.g. \`create account\`, \`create org\`) create subdirectories like
|
|
27
|
+
\`fjall/account/\` \u2014 do not \`cd\` into them. All subsequent commands
|
|
28
|
+
(\`connect\`, \`deploy\`, \`target list\`, etc.) expect the project root.
|
|
29
|
+
- Do **not** hand-roll AWS CLI, CDK, or Terraform \u2014 Fjall owns the
|
|
30
|
+
infrastructure graph and will diverge from manual edits.
|
|
31
|
+
|
|
32
|
+
## What Fjall Owns
|
|
33
|
+
|
|
34
|
+
Fjall manages two layers per application:
|
|
35
|
+
1. **Infrastructure** \u2014 CDK-generated AWS resources (ECS, RDS, ALB, S3, Lambda).
|
|
36
|
+
2. **Code** \u2014 container images and Lambda bundles from the source tree.
|
|
37
|
+
|
|
38
|
+
Both deploy via \`fjall deploy\`. Use \`--infra-only\` or \`--deploy-only\` to split.
|
|
39
|
+
|
|
40
|
+
\`fjall deploy <org>\` cascades: organisation \u2192 platform \u2192 accounts \u2192 applications.
|
|
41
|
+
Use \`--no-cascade\` to deploy a single level.
|
|
42
|
+
|
|
43
|
+
## Recipe: Onboard a New User
|
|
44
|
+
|
|
45
|
+
**First, ask the user which path they want:**
|
|
46
|
+
- **Single account** \u2014 one AWS account, no shared governance.
|
|
47
|
+
- **Organisation** \u2014 multi-account with governance and shared infrastructure.
|
|
48
|
+
|
|
49
|
+
### Path A: Single Account
|
|
50
|
+
1. \`fjall login --device --agent\` (skip if authenticated)
|
|
51
|
+
2. Ask which region. Default to **us-east-2** if no preference.
|
|
52
|
+
Common regions: us-east-2, us-west-2, eu-west-1, ap-southeast-2.
|
|
53
|
+
3. \`fjall create account --primary-region <region> --agent\`
|
|
54
|
+
-> Scaffolds \`fjall/account/\` infrastructure-as-code.
|
|
55
|
+
-> Confirm the user is in the correct project directory first.
|
|
56
|
+
4. \`fjall connect --environment production --region <region> --agent\`
|
|
57
|
+
-> Opens the CloudFormation URL in the user's browser and polls for
|
|
58
|
+
completion. **This command blocks** until the stack finishes (~3 min).
|
|
59
|
+
If the browser doesn't open, the URL is printed \u2014 show it to the user.
|
|
60
|
+
-> Run with a **10-minute timeout** (the stack takes ~3 minutes).
|
|
61
|
+
-> On success, the connection is fully registered and targets are available.
|
|
62
|
+
5. \`fjall deploy account --agent\`
|
|
63
|
+
-> Deploys the scaffolded account infrastructure to AWS.
|
|
64
|
+
6. Now the base infrastructure is live. Ask if they want to create an app
|
|
65
|
+
(see **Recipe: Create and Deploy an Application** below).
|
|
66
|
+
|
|
67
|
+
### Path B: Organisation
|
|
68
|
+
1. \`fjall login --device --agent\` (skip if authenticated)
|
|
69
|
+
2. Ask for: organisation name, admin email, and primary region.
|
|
70
|
+
3. \`fjall create org --name "<name>" --email "<email>" --primary-region <region> --agent\`
|
|
71
|
+
-> Scaffolds \`fjall/organisation/\`, \`fjall/platform/\`, \`fjall/account/\`.
|
|
72
|
+
-> Confirm the user is in the correct project directory first.
|
|
73
|
+
4. \`fjall connect --environment production --region <region> --agent\`
|
|
74
|
+
-> Same blocking CloudFormation flow as Path A (see step 4 above).
|
|
75
|
+
5. \`fjall deploy organisation --agent\`
|
|
76
|
+
-> Cascades: organisation \u2192 platform \u2192 accounts. This is a single
|
|
77
|
+
command \u2014 do NOT deploy each level separately.
|
|
78
|
+
6. Now the base infrastructure is live. Ask if they want to create an app
|
|
79
|
+
(see **Recipe: Create and Deploy an Application** below).
|
|
80
|
+
|
|
81
|
+
### Recipe: Create and Deploy an Application
|
|
82
|
+
|
|
83
|
+
Walk the decision tree below. **Do not skip steps** \u2014 each resolves
|
|
84
|
+
information the next step needs. Skipping detect or dry-run is the #1
|
|
85
|
+
cause of scaffold failures.
|
|
86
|
+
|
|
87
|
+
**Common mistakes to avoid:**
|
|
88
|
+
|
|
89
|
+
- \`--pattern\` is the **framework** (\`nextjs\`, \`payload\`), NOT the compute
|
|
90
|
+
model. There is no \`--pattern ecs\`. ECS vs Lambda is determined by the
|
|
91
|
+
pattern + tier combination.
|
|
92
|
+
- \`--tier\` sets the **infrastructure tier** (\`tinkerer\`,
|
|
93
|
+
\`lightweight\`, \`standard\`, \`resilient\`, \`enterprise\`). Do NOT pass
|
|
94
|
+
these values via \`--type\` \u2014 that flag is for legacy template mode only.
|
|
95
|
+
- \`--into <path>\` sets the repo root the scaffold writes into. The output
|
|
96
|
+
lands at \`<into>/fjall/<app-name>/\`. **You must also \`cd\` to the
|
|
97
|
+
\`--into\` path** (or its parent) before running the command \u2014 the CLI
|
|
98
|
+
resolves the config root from cwd, and a cwd mismatch causes files to
|
|
99
|
+
land in the wrong project.
|
|
100
|
+
- \`--dockerfile <path>\` is resolved relative to the \`--into\` directory
|
|
101
|
+
(or cwd if no \`--into\`), NOT relative to the agent's working directory.
|
|
102
|
+
Use a path relative to the target repo root, e.g. \`apps/website/Dockerfile\`.
|
|
103
|
+
|
|
104
|
+
**Step 1 \u2014 Detect the repo (MANDATORY for existing repos).** Run:
|
|
105
|
+
\`fjall apps detect <path> --output json --agent\`
|
|
106
|
+
|
|
107
|
+
This returns the framework, monorepo tool, Dockerfile presence, inferred
|
|
108
|
+
port, and \`suggestedConfigPath\` for each app. Use these values to seed
|
|
109
|
+
\`--pattern\` and \`--name\` in the create command. Do NOT guess the pattern
|
|
110
|
+
from the user's description \u2014 always use what detect reports.
|
|
111
|
+
|
|
112
|
+
**Step 2 \u2014 Pick the tier.** Tier governs blast radius and cost.
|
|
113
|
+
- \`tinkerer\` \u2014 smallest viable; single-AZ, no LB.
|
|
114
|
+
- \`lightweight\` \u2014 LB-only validation env. **Default for "is this app
|
|
115
|
+
deployable?" smoke tests.**
|
|
116
|
+
- \`standard\` \u2014 typical production profile.
|
|
117
|
+
- \`resilient\` / \`enterprise\` \u2014 multi-AZ, multi-region.
|
|
118
|
+
|
|
119
|
+
Pass via \`--tier <tier>\`. Use \`--pattern-domain <domain>\` for a
|
|
120
|
+
custom domain or omit for none.
|
|
121
|
+
|
|
122
|
+
**Step 3 \u2014 Pick the target account.** If more than one provider account
|
|
123
|
+
is connected, the scaffold needs to know which one will deploy this app.
|
|
124
|
+
- \`fjall accounts list --output json --agent\` \u2014 see candidates.
|
|
125
|
+
- Pass \`--target <account-name>\` to \`apps create\`.
|
|
126
|
+
- If only one candidate exists, the CLI auto-resolves it.
|
|
127
|
+
|
|
128
|
+
**Step 4 \u2014 Optional: pick a network preset.**
|
|
129
|
+
\`--network <lightweight|standard|resilient|enterprise|none>\`. Most apps
|
|
130
|
+
inherit from the tier; only set this when an app needs different network
|
|
131
|
+
topology from its tier default.
|
|
132
|
+
|
|
133
|
+
**Step 5 \u2014 Preview the scaffold (MANDATORY).** Before writing anything,
|
|
134
|
+
run with \`--dry-run\` to get a TOON preview of the planned files, npm
|
|
135
|
+
packages, and registry actions. Nothing is written, no API call is made,
|
|
136
|
+
no dependencies are installed. **Never skip this step.**
|
|
137
|
+
|
|
138
|
+
When using \`--into\`, \`cd\` to the target repo root first:
|
|
139
|
+
|
|
140
|
+
\`\`\`bash
|
|
141
|
+
cd <repo-path>
|
|
142
|
+
fjall apps create \\
|
|
143
|
+
--name <app> \\
|
|
144
|
+
--pattern <nextjs|payload|...> \\
|
|
145
|
+
--tier <tier> \\
|
|
146
|
+
[--pattern-domain <domain>] \\
|
|
147
|
+
[--network <preset>] \\
|
|
148
|
+
[--database] \\
|
|
149
|
+
[--dockerfile <relative-path-from-repo-root>] \\
|
|
150
|
+
[--container-port <port>] \\
|
|
151
|
+
[--container <monorepo-subdir>] \\
|
|
152
|
+
--into <repo-path> \\
|
|
153
|
+
[--target <account>] \\
|
|
154
|
+
--dry-run --agent
|
|
155
|
+
\`\`\`
|
|
156
|
+
|
|
157
|
+
Scaffold paths follow the \`fjall/\` marker convention \u2014 \`fjall/<name>/infrastructure.ts\`
|
|
158
|
+
at the repo root by default, or \`<container>/fjall/<name>/infrastructure.ts\` when the
|
|
159
|
+
optional \`--container\` flag is supplied (useful in monorepos where infrastructure
|
|
160
|
+
lives under a workspace directory like \`services/\` or \`apps/\`).
|
|
161
|
+
|
|
162
|
+
The TOON output includes \`fileCount\`, a \`files[]\` list with paths and
|
|
163
|
+
sizes, \`npmPackages[]\`, and \`registryActions[]\`. **Verify that \`path\`
|
|
164
|
+
in the output points inside the target repo**, not somewhere else. If
|
|
165
|
+
it doesn't, the cwd is wrong. Review files against the user's intent.
|
|
166
|
+
If anything looks wrong (file would clobber an existing path, wrong
|
|
167
|
+
tier, missing service), refine the flags and re-run \`--dry-run\` until
|
|
168
|
+
the preview matches.
|
|
169
|
+
|
|
170
|
+
If the output contains \`patternUnsupportedForDryRun: true\`, the
|
|
171
|
+
scaffold relies on a registry clone whose file list is only available
|
|
172
|
+
after apply \u2014 confirm the high-level shape (\`mode\`, \`pattern\`,
|
|
173
|
+
\`registryActions\`) and proceed.
|
|
174
|
+
|
|
175
|
+
**Step 6 \u2014 Apply.** Drop \`--dry-run\` and run again with the same flags
|
|
176
|
+
(same cwd) to write the scaffold, register the application, and install
|
|
177
|
+
dependencies.
|
|
178
|
+
|
|
179
|
+
For a fresh-start single-template app the older form still works:
|
|
180
|
+
\`fjall apps create --name <app> --template <template> --agent\`.
|
|
181
|
+
|
|
182
|
+
**Step 7 \u2014 Deploy:** \`fjall deploy <app> --agent\`.
|
|
183
|
+
|
|
184
|
+
**Worked example \u2014 "point at ansa, scaffold a lightweight LB-only env":**
|
|
185
|
+
1. \`fjall apps detect /Users/paul/Code/fjall/ansa --output json --agent\`
|
|
186
|
+
\u2192 reports \`monorepo: npm-workspaces\`, \`apps/website\` is
|
|
187
|
+
\`nextjs+payload\` with Dockerfile at \`apps/website/Dockerfile\`,
|
|
188
|
+
port 3000.
|
|
189
|
+
2. \`fjall accounts list --output json --agent\` \u2192 one candidate,
|
|
190
|
+
auto-resolved.
|
|
191
|
+
3. \`cd /Users/paul/Code/fjall/ansa\` \u2190 **must cd to the --into target**
|
|
192
|
+
4. \`fjall apps create --name ansa-web --pattern payload --tier lightweight --database --dockerfile apps/website/Dockerfile --container-port 3000 --into /Users/paul/Code/fjall/ansa --dry-run --agent\`
|
|
193
|
+
\u2192 review TOON: verify \`path\` is inside ansa repo, check \`fileCount\`,
|
|
194
|
+
\`registryActions[]\`. Confirm with the user.
|
|
195
|
+
5. Same command without \`--dry-run\` \u2192 scaffold writes to
|
|
196
|
+
\`ansa/fjall/ansa-web/\` (or pass \`--container apps\` to land
|
|
197
|
+
under \`ansa/apps/fjall/ansa-web/\` to match the existing
|
|
198
|
+
monorepo layout).
|
|
199
|
+
6. \`fjall deploy ansa-web --agent\`
|
|
200
|
+
|
|
201
|
+
After each step, summarise the TOON \`status\` and any \`help[]\` hints for the
|
|
202
|
+
user. On a non-zero exit, quote the \`error\` field and offer the suggested fix.
|
|
203
|
+
|
|
204
|
+
If you lose context mid-recipe, run:
|
|
205
|
+
- \`fjall list --agent\` (what resources exist?)
|
|
206
|
+
- \`fjall target list --agent\` (what AWS accounts are connected?)
|
|
207
|
+
|
|
208
|
+
## Recipe: Deploy Changes
|
|
209
|
+
1. \`fjall status <app> --agent\`
|
|
210
|
+
2. \`fjall deploy <app> --agent\`
|
|
211
|
+
|
|
212
|
+
## Recipe: Manage Secrets
|
|
213
|
+
1. \`fjall secrets list --app <app> --agent\`
|
|
214
|
+
2. \`fjall secrets set KEY=value --app <app> --agent\`
|
|
215
|
+
3. \`fjall deploy <app> --agent\` (secrets injected on next deploy)
|
|
216
|
+
|
|
217
|
+
## Recipe: Add a Database
|
|
218
|
+
1. \`fjall add database --app <app> --agent\`
|
|
219
|
+
2. \`fjall deploy <app> --agent\`
|
|
220
|
+
|
|
221
|
+
## Recipe: Recover from a Failed Deploy
|
|
222
|
+
1. \`fjall status <app> --agent\` (which step failed?)
|
|
223
|
+
2. \`fjall deploy logs --deployment-id <id> --agent\` (recent events \u2014 id from \`fjall status\`)
|
|
224
|
+
3. Ask the user: retry, rollback (\`fjall destroy\` + redeploy), or investigate.
|
|
225
|
+
|
|
226
|
+
## Global Flags
|
|
227
|
+
- \`--agent\` \u2014 TOON output (always use for parsing).
|
|
228
|
+
- \`--budget compact|minimal|<tokens>\` \u2014 cap output size.
|
|
229
|
+
- \`--fields <csv>\` \u2014 select specific fields.
|
|
230
|
+
- \`--verbose\` \u2014 diagnostic output (masks credentials).
|
|
231
|
+
|
|
232
|
+
## Flags Appendix (for composition beyond recipes)
|
|
233
|
+
When the user asks for something outside these recipes, compose from these
|
|
234
|
+
primitives. Always pass \`--agent\`.
|
|
235
|
+
|
|
236
|
+
| Command | Key flags |
|
|
237
|
+
|---------|-----------|
|
|
238
|
+
| \`fjall create org\` | \`--name\`, \`--email\`, \`--primary-region\`, \`--secondary-regions\`, \`--disaster-recovery-region\`, \`--security <foundation\\|compliance\\|hardened>\` |
|
|
239
|
+
| \`fjall create account\` | \`--primary-region\` |
|
|
240
|
+
| \`fjall connect\` | \`--region\`, \`--environment <production\\|staging\\|development\\|platform\\|compliance>\`, \`--name\` |
|
|
241
|
+
| \`fjall apps create\` | \`--name\`, \`--type\`, \`--template <nextjs\\|payload\\|dockerfile\\|api>\`, \`--pattern\`, \`--tier <tinkerer\\|lightweight\\|standard\\|resilient\\|enterprise>\`, \`--pattern-domain\`, \`--network <lightweight\\|standard\\|resilient\\|enterprise\\|none>\`, \`--into <repo-path>\`, \`--target <account-name>\`, \`--file-override <path>=<base64>\`, \`--dry-run\`, \`--database\`, \`--git\`, \`--github\`, \`--repo-visibility\` |
|
|
242
|
+
| \`fjall apps detect\` | (positional path), \`--output json\` |
|
|
243
|
+
| \`fjall accounts list\` | \`--output json\` |
|
|
244
|
+
| \`fjall deploy\` | \`--infra-only\`, \`--deploy-only\`, \`--skip-build\`, \`--environment\`, \`--target\`, \`--region\`, \`--all-regions\`, \`--no-cascade\` |
|
|
245
|
+
| \`fjall secrets set\` | \`--app\`, \`--cluster\`, \`--service\`, \`--lambda\`, \`--from-file\` |
|
|
246
|
+
| \`fjall add <type>\` | \`--app\`, \`--name\`, variadic \`--<property> <value>\` |
|
|
247
|
+
| \`fjall target set\` | (positional name) |
|
|
248
|
+
|
|
249
|
+
## Environment Detection
|
|
250
|
+
Fjall auto-detects these agent environments:
|
|
251
|
+
|
|
252
|
+
| Agent | Env Var |
|
|
253
|
+
|-------|---------|
|
|
254
|
+
| Claude Code | \`CLAUDECODE\` |
|
|
255
|
+
| Codex | \`CODEX_SANDBOX\` |
|
|
256
|
+
| Cursor | \`CURSOR_AGENT\` |
|
|
257
|
+
| GitHub Copilot | \`COPILOT_MODEL\` |
|
|
258
|
+
| Generic | \`AI_AGENT\` |
|
|
259
|
+
|
|
260
|
+
The \`--agent\` flag is still recommended for explicitness and portability.
|
|
261
|
+
|
|
262
|
+
## Session Hooks
|
|
263
|
+
|
|
264
|
+
\`\`\`bash
|
|
265
|
+
fjall agent install-hooks # Install ambient-context hooks
|
|
266
|
+
fjall agent uninstall-hooks # Remove hooks
|
|
267
|
+
\`\`\`
|
|
268
|
+
|
|
269
|
+
## If your host doesn't load SKILL files
|
|
270
|
+
|
|
271
|
+
This SKILL is the primary, validated agent surface. If your host (Claude
|
|
272
|
+
Desktop, Cursor, Cline, Continue, Zed, etc.) cannot load skill files,
|
|
273
|
+
Fjall ships a beta MCP server (\`@fjall/mcp\`, \`fjall-mcp\` binary,
|
|
274
|
+
\`0.1.0-beta.1\`) that exposes 9 production tools that map to the same
|
|
275
|
+
CLI commands: \`create_organisation\`, \`add_resource\`, \`deploy\`,
|
|
276
|
+
\`destroy\`, \`list_resources\`, \`manage_profile\`, \`detect_app_framework\`,
|
|
277
|
+
\`plan_app_scaffold\`, \`apply_app_scaffold\`. The MCP shells out to the
|
|
278
|
+
same \`fjall\` CLI, so authentication, masking, and exit-code semantics
|
|
279
|
+
are identical.
|
|
280
|
+
|
|
281
|
+
The scaffold trio (\`detect_app_framework\` \u2192 \`plan_app_scaffold\` \u2192
|
|
282
|
+
\`apply_app_scaffold\`) supports the same plan\u2192review\u2192apply loop the
|
|
283
|
+
SKILL recipe teaches above, with \`fjall://plans/{planId}\` resources,
|
|
284
|
+
elicitation for ambiguous target accounts, and \`notifications/progress\`
|
|
285
|
+
streaming during apply. Use the SKILL+CLI path above when available;
|
|
286
|
+
fall back to the MCP only when the host lacks SKILL support.
|
|
287
|
+
See \`mcp/README.md\` for the beta surface and known gaps.
|
|
288
|
+
`}export{E as generateAgentFiles};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentOutputWriter — the sole stdout-facing adapter for AXI agent mode.
|
|
3
|
+
*
|
|
4
|
+
* This class owns ALL TOON writes to stdout. It is the SINGLE masking
|
|
5
|
+
* boundary (synthesis §1.11): every public method masks string data via
|
|
6
|
+
* `maskSensitiveOutput` before passing it to the formatter. Neither the
|
|
7
|
+
* formatter nor the callback layer performs masking.
|
|
8
|
+
*
|
|
9
|
+
* Diagnostics go to stderr via `logDiagnostic`, never stdout.
|
|
10
|
+
*/
|
|
11
|
+
import type { AgentError, AgentSchema, ActionRequired, StreamEvent, TabularSchema } from "./schemas/types.js";
|
|
12
|
+
import { type SuggestionContext } from "./suggestions.js";
|
|
13
|
+
export interface AgentOutputWriterOptions {
|
|
14
|
+
readonly command: string;
|
|
15
|
+
readonly flags: Readonly<Record<string, string>>;
|
|
16
|
+
readonly verbose?: boolean;
|
|
17
|
+
readonly full?: boolean;
|
|
18
|
+
readonly writeFn?: (chunk: string) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Severity levels understood by `logDiagnostic`. Mirrors the logger's
|
|
22
|
+
* leveled methods; unspecified level defaults to `debug` to preserve the
|
|
23
|
+
* existing noise floor.
|
|
24
|
+
*/
|
|
25
|
+
export type DiagnosticLevel = "debug" | "info" | "warn" | "error";
|
|
26
|
+
export declare class AgentOutputWriter {
|
|
27
|
+
private readonly write;
|
|
28
|
+
private readonly resolver;
|
|
29
|
+
private readonly verbose;
|
|
30
|
+
private readonly full;
|
|
31
|
+
constructor(options: AgentOutputWriterOptions);
|
|
32
|
+
/** Whether `--full` was set, disabling content truncation. */
|
|
33
|
+
get isFullOutput(): boolean;
|
|
34
|
+
renderResult<T>(data: T, options?: {
|
|
35
|
+
schema?: AgentSchema;
|
|
36
|
+
suggestionContext?: SuggestionContext;
|
|
37
|
+
}): void;
|
|
38
|
+
renderListResult<T>(items: readonly T[], tabular: TabularSchema<T>, meta: {
|
|
39
|
+
entity: string;
|
|
40
|
+
aggregates?: Record<string, number | string>;
|
|
41
|
+
suggestionContext?: SuggestionContext;
|
|
42
|
+
fields?: readonly string[];
|
|
43
|
+
}): void;
|
|
44
|
+
renderEvent(event: StreamEvent): void;
|
|
45
|
+
emitEventSeparator(): void;
|
|
46
|
+
renderError(error: AgentError, suggestionContext?: SuggestionContext): void;
|
|
47
|
+
renderActionRequired(action: ActionRequired, suggestionContext?: SuggestionContext): void;
|
|
48
|
+
/**
|
|
49
|
+
* Write a diagnostic message to stderr. Never writes to stdout.
|
|
50
|
+
*
|
|
51
|
+
* When verbose is true, output is unmasked (debug mode per
|
|
52
|
+
* security-standards). When verbose is false, strings are masked.
|
|
53
|
+
*
|
|
54
|
+
* Severity defaults to `debug` to match the Phase 0 noise floor. Callers
|
|
55
|
+
* with explicit severity (e.g. build errors, warn-level callbacks) pass
|
|
56
|
+
* `level` so the message routes to the correct logger method.
|
|
57
|
+
*/
|
|
58
|
+
logDiagnostic(component: string, message: string, data?: Record<string, unknown>, level?: DiagnosticLevel): void;
|
|
59
|
+
renderHelpLines(lines: readonly string[]): void;
|
|
60
|
+
private resolveHelp;
|
|
61
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{maskSensitiveOutput as f}from"@fjall/util";import{logger as l}from"../logger/index.js";import{BLOCK_SEPARATOR as w,renderActionRequired as b,renderError as v,renderEvent as k,renderHelp as h,renderList as E,renderObject as R}from"./toonFormatter.js";import{SuggestionResolver as A}from"./suggestions.js";function d(n){if(typeof n=="string")return f(n);if(n==null||typeof n!="object")return n;if(Array.isArray(n))return n.map(t=>d(t));if(n instanceof Date||n instanceof RegExp)return n;const e={};for(const[t,r]of Object.entries(n))e[t]=d(r);return e}class q{write;resolver;verbose;full;constructor(e){this.write=e.writeFn??(t=>{process.stdout.write(t)}),this.resolver=new A(e.command,e.flags),this.verbose=e.verbose??!1,this.full=e.full??!1}get isFullOutput(){return this.full}renderResult(e,t){const r=d(e),i=R(r),s=this.resolveHelp(t?.suggestionContext);this.write(i+s+`
|
|
2
|
+
`)}renderListResult(e,t,r){const i=e.map(c=>d(c)),s=r.fields,o=s!==void 0&&s.length>0?{fields:s,project:c=>{const a=t.project(c),g={};for(const u of s)u in a&&(g[u]=a[u]);return g}}:t,m=E(i,o,{entity:r.entity,aggregates:r.aggregates}),p=this.resolveHelp(r.suggestionContext);this.write(m+p+`
|
|
3
|
+
`)}renderEvent(e){const t=d(e),r=k(t);this.write(r)}emitEventSeparator(){this.write(w+`
|
|
4
|
+
`)}renderError(e,t){const r={...e,message:f(e.message),...e.details!==void 0?{details:d(e.details)}:{}},i=v(r),s=this.resolveHelp(t);this.write(i+s+`
|
|
5
|
+
`)}renderActionRequired(e,t){const r={...e,message:f(e.message),action:f(e.action),...e.details!==void 0?{details:d(e.details)}:{},...e.choices!==void 0?{choices:e.choices.map(o=>f(o))}:{}},i=b(r),s=this.resolveHelp(t);this.write(i+s+`
|
|
6
|
+
`)}logDiagnostic(e,t,r,i="debug"){const s=this.verbose?t:f(t),o=this.verbose||r===void 0?r:d(r);switch(i){case"error":l.error(e,s,o);return;case"warn":l.warn(e,s,o);return;case"info":l.info(e,s,o);return;default:l.debug(e,s,o);return}}renderHelpLines(e){if(e.length===0)return;const t=e.map(r=>f(r));this.write(h(t)+`
|
|
7
|
+
`)}resolveHelp(e){if(e===void 0)return"";const t=this.resolver.resolve(e);return t.length===0?"":`
|
|
8
|
+
`+h(t)}}export{q as AgentOutputWriter};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progressive budget reducer for AXI agent output.
|
|
3
|
+
*
|
|
4
|
+
* Works on the already-rendered TOON string, stripping content until
|
|
5
|
+
* the output fits within the requested budget.
|
|
6
|
+
*
|
|
7
|
+
* Budget modes:
|
|
8
|
+
* - `minimal` — entity count + status summary only (no list items)
|
|
9
|
+
* - `compact` — list items with first 2 fields per row + aggregates
|
|
10
|
+
* - `<number>` — approximate token target via progressive reduction
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Apply a budget constraint to a rendered TOON string.
|
|
14
|
+
*
|
|
15
|
+
* @param output - The fully rendered TOON string
|
|
16
|
+
* @param budget - One of `"minimal"`, `"compact"`, or a numeric string
|
|
17
|
+
* @returns The reduced output string
|
|
18
|
+
*/
|
|
19
|
+
export declare function applyBudget(output: string, budget: string | undefined): string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
function a(n){return Math.ceil(n.length/4)}const i=/^ {2,}\S.*$/gm,s=/^help\[\d+\]:.*(?:\n {2,}.*$)*/gm,o=/^[a-zA-Z][a-zA-Z0-9_]*: \S.*$/gm,m=/^[a-zA-Z][a-zA-Z0-9_]*\[\d+\]:.*$/gm;function E(n){let r=n.replace(s,"");return r=r.replace(i,""),c(r)}function d(n){let r=n.replace(s,"");return r=r.replace(i,e=>p(e,2)),c(r)}function p(n,r){const e=n.match(/^(\s*)/)?.[1]??"",t=n.trimStart().split(",").map(u=>u.trim());if(t.length<=r)return n;const f=t.slice(0,r).join(", ");return`${e}${f}`}function h(n,r){if(a(n)<=r)return n;let e=n.replace(s,"");if(e=c(e),a(e)<=r)return e;const l=new Set;for(const t of e.matchAll(m))l.add(t[0]);return e=e.replace(o,t=>l.has(t)?t:""),e=c(e),a(e)<=r||(e=e.replace(i,t=>p(t,2)),e=c(e),a(e)<=r)?e:(e=e.replace(i,""),c(e))}function c(n){return n.replace(/\n{3,}/g,`
|
|
2
|
+
|
|
3
|
+
`).replace(/^\n+/,"").replace(/\n+$/,`
|
|
4
|
+
`)}function _(n,r){if(r===void 0)return n;if(r==="minimal")return E(n);if(r==="compact")return d(n);const e=parseInt(r,10);return Number.isNaN(e)||e<=0?n:h(n,e)}export{_ as applyBudget};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent environment detection.
|
|
3
|
+
*
|
|
4
|
+
* Detects known AI agent environments (Claude Code, Cursor, Codex, Copilot,
|
|
5
|
+
* etc.) via environment variables and filesystem markers. Pure, side-effect
|
|
6
|
+
* free except for a cached filesystem check and a result cache.
|
|
7
|
+
*
|
|
8
|
+
* Priority ordering is load-bearing: `generic` (AI_AGENT env var) must be
|
|
9
|
+
* checked LAST so that specific agent signals take precedence. Tests assert
|
|
10
|
+
* the ordering with an explicit case for CLAUDECODE + AI_AGENT both set.
|
|
11
|
+
*
|
|
12
|
+
* TTY gate: when auto-detecting, requires `!process.stdout.isTTY`. This is
|
|
13
|
+
* deliberate and matches `isNonInteractiveMode` which gates on stdout too.
|
|
14
|
+
* Reviewer feedback flagged stdin-based gating as inconsistent. Explicit
|
|
15
|
+
* `--agent` / `--no-agent` flags bypass the TTY check.
|
|
16
|
+
*/
|
|
17
|
+
export interface DetectedAgent {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
readonly detected: true;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns the first matching agent signal, or `undefined` if none matches.
|
|
23
|
+
* Memoised — call `resetDetectAgentCache()` in test `beforeEach` to clear.
|
|
24
|
+
*/
|
|
25
|
+
export declare function detectAgent(): DetectedAgent | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Resets the memoisation cache. Call this in `beforeEach` in tests that
|
|
28
|
+
* manipulate `process.env` via `vi.stubEnv`. Production code should never
|
|
29
|
+
* call this.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resetDetectAgentCache(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Options that influence agent-mode activation. Explicit `options.agent`
|
|
34
|
+
* (true or false) is a hard override — detection is not consulted.
|
|
35
|
+
*/
|
|
36
|
+
export interface AgentModeOptions {
|
|
37
|
+
readonly agent?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns true when the CLI should activate agent output mode.
|
|
41
|
+
*
|
|
42
|
+
* Priority (reviewer-confirmed):
|
|
43
|
+
* 1. Explicit `options.agent === true` → always on, regardless of TTY
|
|
44
|
+
* 2. Explicit `options.agent === false` → always off, hard override
|
|
45
|
+
* 3. Auto-detection: an agent signal is present AND `stdout` is not a TTY
|
|
46
|
+
*
|
|
47
|
+
* Stdout-based (not stdin-based) TTY gate matches `isNonInteractiveMode`
|
|
48
|
+
* for consistency. A developer running with `CLAUDECODE=1` in a real
|
|
49
|
+
* terminal does NOT auto-enter agent mode — `stdout.isTTY` is true.
|
|
50
|
+
*/
|
|
51
|
+
export declare function isAgentMode(options?: AgentModeOptions): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as r}from"node:fs";import{logger as s}from"../logger/index.js";function c(e){try{return r(e)}catch(t){return s.debug("Agent","safeExistsSync swallowed error",{path:e,error:t instanceof Error?t.message:String(t)}),!1}}const o=[{name:"claude-code",detect:()=>!!process.env.CLAUDECODE||!!process.env.CLAUDE_CODE},{name:"cowork",detect:()=>!!process.env.CLAUDE_CODE_IS_COWORK},{name:"codex",detect:()=>!!process.env.CODEX_SANDBOX||!!process.env.CODEX_CI||!!process.env.CODEX_THREAD_ID},{name:"cursor",detect:()=>!!process.env.CURSOR_TRACE_ID||!!process.env.CURSOR_AGENT||process.env.CURSOR_EXTENSION_HOST_ROLE==="agent-exec"},{name:"gemini",detect:()=>!!process.env.GEMINI_CLI},{name:"copilot",detect:()=>!!process.env.COPILOT_MODEL||!!process.env.COPILOT_ALLOW_ALL||!!process.env.COPILOT_GITHUB_TOKEN},{name:"devin",detect:()=>c("/opt/.devin")},{name:"replit",detect:()=>!!process.env.REPL_ID},{name:"augment",detect:()=>!!process.env.AUGMENT_AGENT},{name:"opencode",detect:()=>!!process.env.OPENCODE_CLIENT},{name:"generic",detect:()=>!!process.env.AI_AGENT}];let n=null;function d(){if(n!==null)return n;for(const e of o)if(e.detect())return n={name:e.name,detected:!0},n;n=void 0}function i(){n=null}function u(e){return e?.agent===!0?!0:e?.agent===!1||d()===void 0?!1:!process.stdout.isTTY}export{d as detectAgent,u as isAgentMode,i as resetDetectAgentCache};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps known service error classes to agent error codes. This provides
|
|
3
|
+
* deterministic error classification for typed service errors, bypassing
|
|
4
|
+
* the regex fallback in `errorCodes.ts`.
|
|
5
|
+
*
|
|
6
|
+
* The regex fallback still runs for unrecognised error classes and for
|
|
7
|
+
* raw string errors. This map simply short-circuits the lookup for known
|
|
8
|
+
* types, improving accuracy and avoiding false matches.
|
|
9
|
+
*/
|
|
10
|
+
import type { AgentErrorCode } from "./errorCodes.js";
|
|
11
|
+
/**
|
|
12
|
+
* Attempt to map an error to an agent error code via its class name.
|
|
13
|
+
* Returns `undefined` if the error class is not in the map, signalling
|
|
14
|
+
* the caller should fall through to the regex path.
|
|
15
|
+
*/
|
|
16
|
+
export declare function mapErrorClassToCode(error: unknown): AgentErrorCode | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const E={AppQueryError:"NOT_FOUND",SecretsError:"VALIDATION_ERROR",UserError:"VALIDATION_ERROR",ApiError:"UNKNOWN",AuthenticationError:"AUTH_REQUIRED",CloudFormationError:"AWS_ERROR",CredentialError:"AUTH_REQUIRED",DeploymentError:"DEPLOY_FAILED",ValidationError:"VALIDATION_ERROR",ZodError:"VALIDATION_ERROR",DomainError:"NOT_FOUND",CreateError:"VALIDATION_ERROR",RestoreError:"AWS_ERROR",ImportError:"NOT_FOUND",MonitoringMetadataError:"UNKNOWN"},O={AppQueryError:{not_found:"NOT_FOUND",api_error:"NETWORK_ERROR",credential_error:"AUTH_REQUIRED",general:"UNKNOWN"},SecretsError:{not_found:"NOT_FOUND",invalid_namespace:"VALIDATION_ERROR",general:"UNKNOWN"},UserError:{not_found:"NOT_FOUND",already_exists:"CONFLICT",general:"UNKNOWN"},DomainError:{not_found:"NOT_FOUND",already_exists:"CONFLICT",parse_error:"VALIDATION_ERROR",deploy_error:"DEPLOY_FAILED",verification_error:"TIMEOUT",validation_error:"VALIDATION_ERROR",import_error:"AWS_ERROR",export_error:"AWS_ERROR"},CreateError:{already_exists:"CONFLICT",not_found:"NOT_FOUND",generation_error:"UNKNOWN",dependency_error:"UNKNOWN",validation_error:"VALIDATION_ERROR",authentication_error:"AUTH_REQUIRED"},RestoreError:{not_found:"NOT_FOUND",permission_denied:"FORBIDDEN",validation_error:"VALIDATION_ERROR",aws_error:"AWS_ERROR",no_recovery_points:"NOT_FOUND"},ImportError:{APP_NOT_FOUND:"NOT_FOUND",MISSING_INFRASTRUCTURE_FILE:"NOT_FOUND",NO_RESOURCES:"NOT_FOUND",NO_RESOURCES_SELECTED:"VALIDATION_ERROR",MULTIPLE_RESOURCES:"VALIDATION_ERROR",DISCOVERY_FAILED:"AWS_ERROR",GENERATION_FAILED:"AWS_ERROR",SYNTHESIS_FAILED:"AWS_ERROR",MAPPING_FAILED:"AWS_ERROR",CDK_IMPORT_FAILED:"AWS_ERROR",IMPORT_FAILED:"AWS_ERROR"},MonitoringMetadataError:{captureMonitoringMetadata:"AWS_ERROR",sendMonitoringMetadata:"NETWORK_ERROR"}};function _(r){if(r==null||typeof r!="object")return;const e=("name"in r&&typeof r.name=="string"?r.name:void 0)??r.constructor?.name;if(e===void 0||e==="Error")return;const o=E[e];if(o===void 0)return;const R=O[e];if(R!==void 0){const n="errorType"in r&&typeof r.errorType=="string"?r.errorType:"code"in r&&typeof r.code=="string"?r.code:"operation"in r&&typeof r.operation=="string"?r.operation:void 0;if(n!==void 0&&R[n]!==void 0)return R[n]}return o}export{_ as mapErrorClassToCode};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AXI agent error codes — stable machine-readable strings returned to agents
|
|
3
|
+
* in TOON error blocks. Never leaks internal error class names.
|
|
4
|
+
*
|
|
5
|
+
* Pattern ordering is load-bearing: most-specific patterns FIRST, so that
|
|
6
|
+
* messages like "CloudFormation update failed: Parameter validation failed"
|
|
7
|
+
* resolve to AWS_ERROR rather than VALIDATION_ERROR. Run
|
|
8
|
+
* `errorCodes.test.ts` after any change to confirm the golden fixtures still
|
|
9
|
+
* resolve to their expected codes.
|
|
10
|
+
*
|
|
11
|
+
* Rationale for single closed enum: agents branch on these codes, so they
|
|
12
|
+
* must be stable across releases. New codes are additive only. Removing or
|
|
13
|
+
* renaming a code is a breaking change.
|
|
14
|
+
*/
|
|
15
|
+
export declare const AGENT_ERROR_CODES: {
|
|
16
|
+
readonly AUTH_REQUIRED: "AUTH_REQUIRED";
|
|
17
|
+
readonly AUTH_EXPIRED: "AUTH_EXPIRED";
|
|
18
|
+
readonly NO_AWS_ACCOUNT: "NO_AWS_ACCOUNT";
|
|
19
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
20
|
+
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
21
|
+
readonly DEPLOY_FAILED: "DEPLOY_FAILED";
|
|
22
|
+
readonly NETWORK_ERROR: "NETWORK_ERROR";
|
|
23
|
+
readonly AWS_ERROR: "AWS_ERROR";
|
|
24
|
+
readonly TIMEOUT: "TIMEOUT";
|
|
25
|
+
readonly CONFLICT: "CONFLICT";
|
|
26
|
+
readonly RATE_LIMITED: "RATE_LIMITED";
|
|
27
|
+
readonly FORBIDDEN: "FORBIDDEN";
|
|
28
|
+
readonly BUILDX_UNAVAILABLE: "BUILDX_UNAVAILABLE";
|
|
29
|
+
readonly UNKNOWN: "UNKNOWN";
|
|
30
|
+
};
|
|
31
|
+
export type AgentErrorCode = (typeof AGENT_ERROR_CODES)[keyof typeof AGENT_ERROR_CODES];
|
|
32
|
+
/**
|
|
33
|
+
* Maps an arbitrary error-shaped value to a stable agent error code.
|
|
34
|
+
* Accepts `unknown` because callback-surfaced errors are sometimes strings
|
|
35
|
+
* or shaped objects, not `Error` instances.
|
|
36
|
+
*
|
|
37
|
+
* Pattern matching order: explicit class-name checks first (via
|
|
38
|
+
* `errorCodeMap.ts`), then message regex fallback. Never throws; returns
|
|
39
|
+
* `UNKNOWN` on non-matching input.
|
|
40
|
+
*/
|
|
41
|
+
export declare function mapErrorToCode(error: unknown): AgentErrorCode;
|
|
42
|
+
/**
|
|
43
|
+
* Indicates whether an agent error represents a state the agent cannot
|
|
44
|
+
* resolve without human intervention. Used by the TOON `action_required`
|
|
45
|
+
* block to set `userActionRequired`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function isUserActionRequired(code: AgentErrorCode): boolean;
|
|
48
|
+
export declare function extractMessage(error: unknown): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{mapErrorClassToCode as E}from"./errorCodeMap.js";const r={AUTH_REQUIRED:"AUTH_REQUIRED",AUTH_EXPIRED:"AUTH_EXPIRED",NO_AWS_ACCOUNT:"NO_AWS_ACCOUNT",NOT_FOUND:"NOT_FOUND",VALIDATION_ERROR:"VALIDATION_ERROR",DEPLOY_FAILED:"DEPLOY_FAILED",NETWORK_ERROR:"NETWORK_ERROR",AWS_ERROR:"AWS_ERROR",TIMEOUT:"TIMEOUT",CONFLICT:"CONFLICT",RATE_LIMITED:"RATE_LIMITED",FORBIDDEN:"FORBIDDEN",BUILDX_UNAVAILABLE:"BUILDX_UNAVAILABLE",UNKNOWN:"UNKNOWN"},R=[{pattern:/throttl|rate.?limit/i,code:"RATE_LIMITED"},{pattern:/buildx (?:unavailable|not (?:installed|found))|docker buildx version/i,code:"BUILDX_UNAVAILABLE"},{pattern:/token.+(expired|invalid)|session.+expired/i,code:"AUTH_EXPIRED"},{pattern:/already authenticated/i,code:"CONFLICT"},{pattern:/not.?logged.?in|no.+credentials|authenticat/i,code:"AUTH_REQUIRED"},{pattern:/access.?denied|not authorized to|forbidden/i,code:"FORBIDDEN"},{pattern:/no.+aws.+account/i,code:"NO_AWS_ACCOUNT"},{pattern:/network|econnrefused|etimedout|enotfound/i,code:"NETWORK_ERROR"},{pattern:/timed.?out|timeout/i,code:"TIMEOUT"},{pattern:/already exists/i,code:"CONFLICT"},{pattern:/not.?found|does not exist/i,code:"NOT_FOUND"},{pattern:/cloudformation|cfn|^aws\.|aws::|resourcenotready/i,code:"AWS_ERROR"},{pattern:/validation failed|invalid parameter|is required/i,code:"VALIDATION_ERROR"}],a=new Set(["AUTH_REQUIRED","AUTH_EXPIRED","FORBIDDEN","BUILDX_UNAVAILABLE"]);function s(e){const t=E(e);if(t!==void 0)return t;const n=d(e);if(n==="")return"UNKNOWN";for(const{pattern:o,code:i}of R)if(o.test(n))return i;return"UNKNOWN"}function N(e){return a.has(e)}function d(e){if(e==null)return"";if(typeof e=="string")return e;if(e instanceof Error)return e.message;if(typeof e=="object"&&"message"in e){const t=e.message;return typeof t=="string"?t:String(t)}return String(e)}export{r as AGENT_ERROR_CODES,d as extractMessage,N as isUserActionRequired,s as mapErrorToCode};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field selection parser for AXI `--fields` flag.
|
|
3
|
+
*
|
|
4
|
+
* Parses a comma-separated field list, validates each field against the
|
|
5
|
+
* command's AgentSchema, and merges with the schema's defaultFields.
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentSchema } from "./schemas/types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Parse and resolve a `--fields` argument against an AgentSchema.
|
|
10
|
+
*
|
|
11
|
+
* When `fieldsArg` is undefined, returns the schema's `defaultFields`.
|
|
12
|
+
* When provided, validates each requested field exists in either
|
|
13
|
+
* `defaultFields` or `extraFields`, then returns the union of
|
|
14
|
+
* `defaultFields` and the valid requested fields. Invalid fields are
|
|
15
|
+
* silently dropped — the agent can inspect the returned list to see
|
|
16
|
+
* what was resolved.
|
|
17
|
+
*
|
|
18
|
+
* @param fieldsArg - Comma-separated field list from `--fields`, or undefined
|
|
19
|
+
* @param schema - The command's AgentSchema describing available fields
|
|
20
|
+
* @returns Resolved field list (defaults + validated extras), deduplicated
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseFieldSelection(fieldsArg: string | undefined, schema: AgentSchema): string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function o(n,t){const l=[...t.defaultFields];if(n===void 0)return l;const i=n.split(",").map(e=>e.trim()).filter(e=>e.length>0),s=new Set([...t.defaultFields,...Object.keys(t.extraFields)]),d=new Set(l);for(const e of i)s.has(e)&&d.add(e);return[...d]}export{o as parseFieldSelection};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Surface classifier for prerequisite-gate routing.
|
|
3
|
+
*
|
|
4
|
+
* Different CLI surfaces consume the same prerequisite failure (e.g. buildx
|
|
5
|
+
* not installed) in different shapes:
|
|
6
|
+
* - interactive → render an Ink screen with [Retry] [Cancel]
|
|
7
|
+
* - non-interactive → write a human-readable error to stderr, exit 64
|
|
8
|
+
* - ci → same as non-interactive (no TTY → no Ink screen)
|
|
9
|
+
* - agent → emit a TOON error block via AgentOutputWriter
|
|
10
|
+
*
|
|
11
|
+
* Precedence (most-specific-first; deliberately does not match
|
|
12
|
+
* `isNonInteractiveMode` which collapses agent into non-interactive):
|
|
13
|
+
* 1. agent — `isAgentMode()` true
|
|
14
|
+
* 2. non-interactive — explicit `--non-interactive` flag
|
|
15
|
+
* 3. ci — `process.env.CI` non-empty OR `!process.stdout.isTTY`
|
|
16
|
+
* 4. interactive — default
|
|
17
|
+
*
|
|
18
|
+
* Empty-string `CI` env is rejected per `robustness-standards.md` § "Environment
|
|
19
|
+
* Variable Truthy Checks" — Kubernetes ConfigMaps and compose env-files can
|
|
20
|
+
* legitimately export `CI=""` for an inherited-and-cleared variable.
|
|
21
|
+
*/
|
|
22
|
+
export type Surface = "interactive" | "non-interactive" | "ci" | "agent";
|
|
23
|
+
export interface GetSurfaceOptions {
|
|
24
|
+
readonly nonInteractive?: boolean;
|
|
25
|
+
readonly agent?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function getSurface(opts?: GetSurfaceOptions): Surface;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isAgentMode as t}from"./detectAgent.js";function c(e){if(t({agent:e?.agent}))return"agent";if(e?.nonInteractive===!0)return"non-interactive";const n=process.env.CI;return n!==void 0&&n!==""||!process.stdout.isTTY?"ci":"interactive"}export{c as getSurface};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API barrel for the AXI agent output layer.
|
|
3
|
+
*
|
|
4
|
+
* This module is CLI-internal. It MUST NOT be imported by the webapp
|
|
5
|
+
* package — `detectAgent.ts` uses `node:fs` directly, and several future
|
|
6
|
+
* submodules will use other Node-only APIs. The webapp consumes agent
|
|
7
|
+
* output contracts via the operations layer and TOON-formatted API
|
|
8
|
+
* responses, not by importing this barrel.
|
|
9
|
+
*
|
|
10
|
+
* Phase 0: detection + error codes + schema types.
|
|
11
|
+
* Phase 1: TOON formatter, suggestion resolver, AgentOutputWriter.
|
|
12
|
+
* Phase 1 (remaining): agent callback factory, CLI wiring.
|
|
13
|
+
*/
|
|
14
|
+
export { AGENT_ERROR_CODES, type AgentErrorCode, extractMessage, isUserActionRequired, mapErrorToCode } from "./errorCodes.js";
|
|
15
|
+
export { type AgentModeOptions, type DetectedAgent, detectAgent, isAgentMode, resetDetectAgentCache } from "./detectAgent.js";
|
|
16
|
+
export { SuggestionResolver, type SuggestionContext } from "./suggestions.js";
|
|
17
|
+
export { AgentOutputWriter, type AgentOutputWriterOptions, type DiagnosticLevel } from "./agentOutput.js";
|
|
18
|
+
export { createAgentOutput, type AgentCallbacksOutput } from "./agentCallbacks.js";
|
|
19
|
+
export type { ActionRequired, Aggregate, AgentError, AgentSchema, FieldSource, StreamEvent, TabularSchema, TransformName } from "./schemas/index.js";
|
|
20
|
+
export { mapErrorClassToCode } from "./errorCodeMap.js";
|
|
21
|
+
export { getRequiredScopes, type TokenScope } from "./tokenScopes.js";
|
|
22
|
+
export { applyBudget } from "./budget.js";
|
|
23
|
+
export { parseFieldSelection } from "./fieldSelection.js";
|
|
24
|
+
export { StreamingToonWriter } from "./streaming.js";
|
|
25
|
+
export { destructiveGate, missingFlagGate, authRequiredGate, ssoGate, awsAccountGate, driftConflictGate, type DriftConflictDelta } from "./actionRequired.js";
|
|
26
|
+
export { installHooks, uninstallHooks, isHookInstallDisabled, hasOptOutSentinel } from "./sessionHooks.js";
|
|
27
|
+
export { generateAgentFiles } from "./agentInit.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AGENT_ERROR_CODES as o,extractMessage as r,isUserActionRequired as s,mapErrorToCode as a}from"./errorCodes.js";import{detectAgent as p,isAgentMode as n,resetDetectAgentCache as m}from"./detectAgent.js";import{SuggestionResolver as f}from"./suggestions.js";import{AgentOutputWriter as u}from"./agentOutput.js";import{createAgentOutput as c}from"./agentCallbacks.js";import{mapErrorClassToCode as A}from"./errorCodeMap.js";import{getRequiredScopes as R}from"./tokenScopes.js";import{applyBudget as O}from"./budget.js";import{parseFieldSelection as E}from"./fieldSelection.js";import{StreamingToonWriter as h}from"./streaming.js";import{destructiveGate as q,missingFlagGate as D,authRequiredGate as F,ssoGate as H,awsAccountGate as v,driftConflictGate as M}from"./actionRequired.js";import{installHooks as _,uninstallHooks as b,isHookInstallDisabled as w,hasOptOutSentinel as y}from"./sessionHooks.js";import{generateAgentFiles as I}from"./agentInit.js";export{o as AGENT_ERROR_CODES,u as AgentOutputWriter,h as StreamingToonWriter,f as SuggestionResolver,O as applyBudget,F as authRequiredGate,v as awsAccountGate,c as createAgentOutput,q as destructiveGate,p as detectAgent,M as driftConflictGate,r as extractMessage,I as generateAgentFiles,R as getRequiredScopes,y as hasOptOutSentinel,_ as installHooks,n as isAgentMode,w as isHookInstallDisabled,s as isUserActionRequired,A as mapErrorClassToCode,a as mapErrorToCode,D as missingFlagGate,E as parseFieldSelection,m as resetDetectAgentCache,H as ssoGate,b as uninstallHooks};
|