thinkwork-cli 0.12.2 → 0.12.4

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.
Files changed (29) hide show
  1. package/dist/cli.js +1586 -32
  2. package/dist/commands/enterprise/templates/deploy-repo/.github/workflows/deploy.yml +236 -0
  3. package/dist/commands/enterprise/templates/deploy-repo/README.md +33 -0
  4. package/dist/commands/enterprise/templates/deploy-repo/customer/branding/README.md +7 -0
  5. package/dist/commands/enterprise/templates/deploy-repo/customer/deployment.json +6 -0
  6. package/dist/commands/enterprise/templates/deploy-repo/customer/evals/README.md +10 -0
  7. package/dist/commands/enterprise/templates/deploy-repo/customer/seeds/README.md +7 -0
  8. package/dist/commands/enterprise/templates/deploy-repo/customer/skills/README.md +7 -0
  9. package/dist/commands/enterprise/templates/deploy-repo/customer/workspace-defaults/README.md +7 -0
  10. package/dist/commands/enterprise/templates/deploy-repo/docs/runbook.md +79 -0
  11. package/dist/commands/enterprise/templates/deploy-repo/scripts/apply-release.mjs +606 -0
  12. package/dist/commands/enterprise/templates/deploy-repo/scripts/smoke.mjs +99 -0
  13. package/dist/commands/enterprise/templates/deploy-repo/terraform/backend-dev.hcl +6 -0
  14. package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +101 -0
  15. package/dist/commands/enterprise/templates/deploy-repo/terraform/stages/dev.tfvars +9 -0
  16. package/dist/commands/enterprise/templates/deploy-repo/terraform/stages/prod.tfvars +9 -0
  17. package/dist/commands/enterprise/templates/deploy-repo/thinkwork.lock +17 -0
  18. package/dist/terraform/examples/greenfield/main.tf +26 -0
  19. package/dist/terraform/examples/greenfield/terraform.tfvars.example +12 -0
  20. package/dist/terraform/modules/app/lambda-api/eval-fanout.tf +7 -7
  21. package/dist/terraform/modules/app/lambda-api/handlers.tf +78 -68
  22. package/dist/terraform/modules/app/lambda-api/outputs.tf +9 -4
  23. package/dist/terraform/modules/app/lambda-api/remote-artifacts.tf +36 -0
  24. package/dist/terraform/modules/app/lambda-api/variables.tf +7 -0
  25. package/dist/terraform/modules/app/lambda-api/workspace-events.tf +1 -1
  26. package/dist/terraform/modules/thinkwork/main.tf +3 -2
  27. package/dist/terraform/modules/thinkwork/outputs.tf +5 -0
  28. package/dist/terraform/modules/thinkwork/variables.tf +6 -0
  29. package/package.json +1 -1
@@ -0,0 +1,236 @@
1
+ # thinkwork-managed: enterprise-deploy-template
2
+ name: Deploy ThinkWork
3
+
4
+ on:
5
+ workflow_dispatch:
6
+ inputs:
7
+ stage:
8
+ description: "Deployment stage"
9
+ type: string
10
+ required: true
11
+ default: dev
12
+ component:
13
+ description: "Deployment component"
14
+ type: choice
15
+ required: true
16
+ default: all
17
+ options:
18
+ - all
19
+ - foundation
20
+ - artifacts
21
+ - overlays
22
+ - smokes
23
+ run_smokes:
24
+ description: "Run post-deploy smoke checks"
25
+ type: boolean
26
+ required: true
27
+ default: true
28
+
29
+ permissions:
30
+ contents: read
31
+ id-token: write
32
+
33
+ concurrency:
34
+ group: thinkwork-${{ github.event.inputs.stage }}
35
+ cancel-in-progress: false
36
+
37
+ jobs:
38
+ deploy:
39
+ name: Deploy ${{ github.event.inputs.stage }}
40
+ runs-on: ubuntu-latest
41
+ environment: ${{ github.event.inputs.stage }}
42
+ env:
43
+ STAGE: ${{ github.event.inputs.stage }}
44
+ COMPONENT: ${{ github.event.inputs.component }}
45
+ RUN_SMOKES: ${{ github.event.inputs.run_smokes }}
46
+ RELEASE_DIR: /tmp/thinkwork-release
47
+ RELEASE_MANIFEST: /tmp/thinkwork-release/thinkwork-release.json
48
+ DEPLOY_SUMMARY_JSON: /tmp/thinkwork-release/deploy-summary.json
49
+ TF_IN_AUTOMATION: "true"
50
+ TF_INPUT: "false"
51
+ steps:
52
+ - uses: actions/checkout@v4
53
+
54
+ - uses: actions/setup-node@v4
55
+ with:
56
+ node-version: "20"
57
+
58
+ - name: Read pinned ThinkWork release
59
+ id: lock
60
+ shell: bash
61
+ run: |
62
+ set -euo pipefail
63
+ test -f thinkwork.lock
64
+ test -f customer/deployment.json
65
+ test -f "terraform/backend-${STAGE}.hcl"
66
+ test -f "terraform/stages/${STAGE}.tfvars"
67
+ jq -e --arg stage "$STAGE" '.stages[$stage]' customer/deployment.json >/dev/null
68
+ mkdir -p "$RELEASE_DIR"
69
+ echo "release=$(jq -r '.thinkwork.release' thinkwork.lock)" >> "$GITHUB_OUTPUT"
70
+ echo "manifest_url=$(jq -r '.thinkwork.manifestUrl' thinkwork.lock)" >> "$GITHUB_OUTPUT"
71
+ echo "manifest_sha256=$(jq -r '.thinkwork.manifestSha256' thinkwork.lock)" >> "$GITHUB_OUTPUT"
72
+ echo "artifact_bucket=$(jq -r '.artifacts.bucket' thinkwork.lock)" >> "$GITHUB_OUTPUT"
73
+ echo "lambda_prefix=$(jq -r '.artifacts.lambdaPrefix' thinkwork.lock)" >> "$GITHUB_OUTPUT"
74
+
75
+ - name: Fetch and verify release manifest
76
+ shell: bash
77
+ run: |
78
+ set -euo pipefail
79
+ curl -fsSL "${{ steps.lock.outputs.manifest_url }}" -o "$RELEASE_MANIFEST"
80
+ if [ "${{ steps.lock.outputs.manifest_sha256 }}" != "CHANGE_ME" ]; then
81
+ echo "${{ steps.lock.outputs.manifest_sha256 }} $RELEASE_MANIFEST" | sha256sum -c -
82
+ fi
83
+ node scripts/apply-release.mjs validate-manifest \
84
+ --manifest "$RELEASE_MANIFEST" \
85
+ --expected-release "${{ steps.lock.outputs.release }}"
86
+
87
+ - name: Configure AWS credentials
88
+ uses: aws-actions/configure-aws-credentials@v4
89
+ with:
90
+ aws-region: ${{ vars.AWS_REGION }}
91
+ role-to-assume: ${{ vars.AWS_ROLE_ARN }}
92
+ role-session-name: thinkwork-${{ github.event.inputs.stage }}-${{ github.run_id }}
93
+
94
+ - uses: hashicorp/setup-terraform@v3
95
+ with:
96
+ terraform_wrapper: false
97
+
98
+ - name: Prepare release artifacts
99
+ if: ${{ github.event.inputs.component == 'all' || github.event.inputs.component == 'foundation' || github.event.inputs.component == 'artifacts' }}
100
+ shell: bash
101
+ run: |
102
+ set -euo pipefail
103
+ node scripts/apply-release.mjs prepare \
104
+ --manifest "$RELEASE_MANIFEST" \
105
+ --work-dir "$RELEASE_DIR" \
106
+ --artifact-bucket "${{ steps.lock.outputs.artifact_bucket }}" \
107
+ --lambda-prefix "${{ steps.lock.outputs.lambda_prefix }}"
108
+
109
+ - name: Terraform init
110
+ if: ${{ github.event.inputs.component == 'all' || github.event.inputs.component == 'foundation' || github.event.inputs.component == 'artifacts' || github.event.inputs.component == 'smokes' }}
111
+ working-directory: terraform
112
+ shell: bash
113
+ run: terraform init -backend-config="backend-${STAGE}.hcl"
114
+
115
+ - name: Select Terraform workspace
116
+ if: ${{ github.event.inputs.component == 'all' || github.event.inputs.component == 'foundation' || github.event.inputs.component == 'artifacts' || github.event.inputs.component == 'smokes' }}
117
+ working-directory: terraform
118
+ shell: bash
119
+ run: |
120
+ set -euo pipefail
121
+ if [ "$COMPONENT" = "all" ] || [ "$COMPONENT" = "foundation" ]; then
122
+ terraform workspace select "$STAGE" || terraform workspace new "$STAGE"
123
+ else
124
+ terraform workspace select "$STAGE"
125
+ fi
126
+
127
+ - name: Terraform apply
128
+ if: ${{ github.event.inputs.component == 'all' || github.event.inputs.component == 'foundation' }}
129
+ working-directory: terraform
130
+ shell: bash
131
+ env:
132
+ TF_VAR_db_password: ${{ secrets.TF_VAR_DB_PASSWORD }}
133
+ TF_VAR_api_auth_secret: ${{ secrets.TF_VAR_API_AUTH_SECRET }}
134
+ run: |
135
+ set -euo pipefail
136
+ terraform apply \
137
+ -var-file="stages/${STAGE}.tfvars" \
138
+ -var="lambda_artifact_bucket=${{ steps.lock.outputs.artifact_bucket }}" \
139
+ -var="lambda_artifact_prefix=${{ steps.lock.outputs.lambda_prefix }}" \
140
+ -auto-approve
141
+
142
+ - name: Copy runtime images into customer ECR
143
+ if: ${{ github.event.inputs.component == 'all' || github.event.inputs.component == 'foundation' || github.event.inputs.component == 'artifacts' }}
144
+ shell: bash
145
+ run: |
146
+ set -euo pipefail
147
+ ECR_REPOSITORY_URL="$(terraform -chdir=terraform output -raw ecr_repository_url)"
148
+ aws ecr get-login-password --region "${{ vars.AWS_REGION }}" | docker login --username AWS --password-stdin "${ECR_REPOSITORY_URL%/*}"
149
+ node scripts/apply-release.mjs copy-runtime-images \
150
+ --manifest "$RELEASE_MANIFEST" \
151
+ --work-dir "$RELEASE_DIR" \
152
+ --stage "$STAGE" \
153
+ --ecr-repository-url "$ECR_REPOSITORY_URL"
154
+
155
+ - name: Update AgentCore runtimes
156
+ if: ${{ github.event.inputs.component == 'all' || github.event.inputs.component == 'foundation' || github.event.inputs.component == 'artifacts' }}
157
+ shell: bash
158
+ run: |
159
+ set -euo pipefail
160
+ node scripts/apply-release.mjs update-agentcore-runtimes \
161
+ --work-dir "$RELEASE_DIR" \
162
+ --stage "$STAGE" \
163
+ --region "${{ vars.AWS_REGION }}"
164
+
165
+ - name: Sync static site bundles
166
+ if: ${{ github.event.inputs.component == 'all' || github.event.inputs.component == 'foundation' || github.event.inputs.component == 'artifacts' }}
167
+ shell: bash
168
+ run: |
169
+ set -euo pipefail
170
+ node scripts/apply-release.mjs sync-static \
171
+ --manifest "$RELEASE_MANIFEST" \
172
+ --work-dir "$RELEASE_DIR" \
173
+ --terraform-dir terraform
174
+
175
+ - name: Apply customer overlay contract
176
+ if: ${{ github.event.inputs.component == 'all' || github.event.inputs.component == 'overlays' }}
177
+ shell: bash
178
+ run: |
179
+ set -euo pipefail
180
+ CLI_VERSION="${{ steps.lock.outputs.release }}"
181
+ CLI_VERSION="${CLI_VERSION#v}"
182
+ TENANT_SLUG="$(jq -r --arg stage "$STAGE" '.stages[$stage].tenantSlug' customer/deployment.json)"
183
+ npx -y "thinkwork-cli@${CLI_VERSION}" --json enterprise overlay apply . \
184
+ --stage "$STAGE" \
185
+ --region "${{ vars.AWS_REGION }}" \
186
+ --tenant "$TENANT_SLUG" \
187
+ > "$RELEASE_DIR/overlay-report.json"
188
+
189
+ - name: Run smoke checks
190
+ if: ${{ github.event.inputs.run_smokes == 'true' && (github.event.inputs.component == 'all' || github.event.inputs.component == 'smokes') }}
191
+ shell: bash
192
+ run: |
193
+ set -euo pipefail
194
+ node scripts/smoke.mjs \
195
+ --stage "$STAGE" \
196
+ --terraform-dir terraform \
197
+ --summary "$RELEASE_DIR/smoke-summary.json"
198
+
199
+ - name: Write deploy summary
200
+ if: always()
201
+ shell: bash
202
+ run: |
203
+ set -euo pipefail
204
+ node scripts/apply-release.mjs write-summary \
205
+ --manifest "$RELEASE_MANIFEST" \
206
+ --work-dir "$RELEASE_DIR" \
207
+ --terraform-dir terraform \
208
+ --stage "$STAGE" \
209
+ --component "$COMPONENT" \
210
+ --output "$DEPLOY_SUMMARY_JSON"
211
+ cat "$DEPLOY_SUMMARY_JSON"
212
+ {
213
+ echo "## ThinkWork deploy summary"
214
+ echo
215
+ jq -r '
216
+ "- Stage: " + .stage,
217
+ "- Release: " + .release.version,
218
+ "- Component: " + .component,
219
+ "- API: " + (.outputs.api_endpoint // "n/a"),
220
+ "- Admin: " + (.outputs.admin_url // "n/a"),
221
+ "- Computer: " + (.outputs.computer_url // "n/a"),
222
+ "- Runtime images copied: " + ((.runtimeImages // []) | length | tostring),
223
+ "- Overlay status: " + (.overlay.status // "not-run"),
224
+ "- Smoke status: " + (.smokes.status // "not-run")
225
+ ' "$DEPLOY_SUMMARY_JSON"
226
+ } >> "$GITHUB_STEP_SUMMARY"
227
+
228
+ - uses: actions/upload-artifact@v4
229
+ if: always()
230
+ with:
231
+ name: thinkwork-deploy-${{ github.event.inputs.stage }}-${{ github.run_id }}
232
+ path: |
233
+ /tmp/thinkwork-release/*.json
234
+ /tmp/thinkwork-release/runtime-images.json
235
+ /tmp/thinkwork-release/overlay-report.json
236
+ /tmp/thinkwork-release/smoke-summary.json
@@ -0,0 +1,33 @@
1
+ <!-- thinkwork-managed: enterprise-deploy-template -->
2
+
3
+ # {{CUSTOMER_SLUG}} ThinkWork Deployment
4
+
5
+ This repository deploys a pinned ThinkWork foundation into the customer AWS
6
+ account. It is intentionally not a fork of the ThinkWork source monorepo:
7
+ `thinkwork.lock` pins a release manifest, Terraform consumes published release
8
+ artifacts, and customer-specific work lives under `customer/`.
9
+
10
+ ## Deployment Model
11
+
12
+ - GitHub Actions deploys through AWS OIDC and per-stage GitHub Environments.
13
+ - `terraform/stages/*.tfvars` contains non-secret stage configuration.
14
+ - Secrets stay in GitHub Environment secrets, AWS Secrets Manager, or SSM.
15
+ - `customer/deployment.json` declares which customer overlays apply to each
16
+ stage.
17
+
18
+ ## First-Time Setup
19
+
20
+ 1. Run `thinkwork enterprise bootstrap` from an admin machine with temporary
21
+ AWS bootstrap access.
22
+ 2. Review the generated GitHub Environments for `dev` and `prod`.
23
+ 3. Add required environment secrets, including `TF_VAR_db_password` and
24
+ `TF_VAR_api_auth_secret`.
25
+ 4. Dispatch `.github/workflows/deploy.yml` for the target stage.
26
+ 5. Use `docs/runbook.md` for release upgrades, overlay-only changes,
27
+ rollback, and break-glass guidance.
28
+
29
+ ## Customer Overlay
30
+
31
+ Place customer-specific eval packs, seeds, skills, workspace defaults, and
32
+ branding assets under `customer/`. Reusable platform behavior should be built
33
+ upstream in ThinkWork and adopted here by bumping `thinkwork.lock`.
@@ -0,0 +1,7 @@
1
+ <!-- thinkwork-managed: enterprise-deploy-template -->
2
+
3
+ # Branding
4
+
5
+ Add customer-approved branding assets here. Reference active assets from
6
+ `customer/deployment.json`; do not commit private signing keys, OAuth client
7
+ secrets, or other secret material.
@@ -0,0 +1,6 @@
1
+ {
2
+ "_comment": "thinkwork-managed: enterprise-deploy-template",
3
+ "schemaVersion": 1,
4
+ "customerSlug": "{{CUSTOMER_SLUG}}",
5
+ "stages": {}
6
+ }
@@ -0,0 +1,10 @@
1
+ <!-- thinkwork-managed: enterprise-deploy-template -->
2
+
3
+ # Eval Packs
4
+
5
+ Add customer-specific eval datasets and scorer configuration here. Reference
6
+ enabled packs from `customer/deployment.json` per stage.
7
+
8
+ Keep customer evals in this folder when they are specific to the enterprise
9
+ deployment. Move reusable evaluators upstream into ThinkWork and consume them by
10
+ bumping `thinkwork.lock`.
@@ -0,0 +1,7 @@
1
+ <!-- thinkwork-managed: enterprise-deploy-template -->
2
+
3
+ # Seed Packs
4
+
5
+ Add tenant bootstrap data that is safe to replay idempotently. Seed files must
6
+ not contain secrets; store secret material in GitHub Environment secrets, AWS
7
+ Secrets Manager, or SSM Parameter Store.
@@ -0,0 +1,7 @@
1
+ <!-- thinkwork-managed: enterprise-deploy-template -->
2
+
3
+ # Skill Packs
4
+
5
+ Add customer-owned script skills here. Each skill should include the same
6
+ metadata shape used by upstream ThinkWork skill catalog entries, then be listed
7
+ from `customer/deployment.json`.
@@ -0,0 +1,7 @@
1
+ <!-- thinkwork-managed: enterprise-deploy-template -->
2
+
3
+ # Workspace Defaults
4
+
5
+ Add customer-specific workspace defaults here, such as guardrails, memory guide
6
+ fragments, capability defaults, or template workspace files. Keep broad product
7
+ defaults upstream in ThinkWork.
@@ -0,0 +1,79 @@
1
+ <!-- thinkwork-managed: enterprise-deploy-template -->
2
+
3
+ # ThinkWork Enterprise Deployment Runbook
4
+
5
+ This repository deploys a pinned ThinkWork release into the customer AWS
6
+ account. It is a deployment repository, not a source fork.
7
+
8
+ ## Normal Sequence
9
+
10
+ 1. Bootstrap the repo once:
11
+
12
+ ```bash
13
+ thinkwork enterprise bootstrap . \
14
+ --customer {{CUSTOMER_SLUG}} \
15
+ --repo <github-owner>/<github-repo> \
16
+ --stage dev \
17
+ --stage prod
18
+ ```
19
+
20
+ 2. Review GitHub Environment settings for each stage.
21
+ 3. Add required secrets such as `TF_VAR_db_password` and
22
+ `TF_VAR_api_auth_secret`.
23
+ 4. Dispatch `.github/workflows/deploy.yml`.
24
+ 5. CI verifies `thinkwork.lock`, prepares release artifacts, runs Terraform,
25
+ updates AgentCore runtimes, applies customer overlays, runs smoke checks,
26
+ and writes a summary artifact.
27
+
28
+ The exact operational path is:
29
+
30
+ ```text
31
+ bootstrap -> workflow dispatch -> CI deploy -> overlay apply -> smoke summary
32
+ ```
33
+
34
+ ## Release Upgrades
35
+
36
+ 1. Update `thinkwork.lock` to the approved release manifest URL and checksum.
37
+ 2. Review ThinkWork release notes for schema or operator changes.
38
+ 3. Dispatch the workflow with `component=all`.
39
+ 4. Save the deploy summary artifact as evidence.
40
+
41
+ ## Overlay-Only Changes
42
+
43
+ 1. Edit files under `customer/`.
44
+ 2. Run a local dry-run:
45
+
46
+ ```bash
47
+ thinkwork enterprise overlay apply . --stage dev --dry-run --json
48
+ ```
49
+
50
+ 3. Dispatch the workflow with `component=overlays`.
51
+ 4. Confirm `overlay-report.json` in the workflow artifacts.
52
+
53
+ ## Secrets
54
+
55
+ Never commit secrets. Supported secret homes are:
56
+
57
+ - GitHub Environment secrets for CI inputs.
58
+ - AWS Secrets Manager for deployed application/runtime secrets.
59
+ - SSM Parameter Store for stage configuration consumed by Terraform or runtime
60
+ code.
61
+
62
+ Do not store plaintext secrets in `terraform/stages/*.tfvars`, `.env`,
63
+ `customer/`, or runbook files.
64
+
65
+ ## Rollback
66
+
67
+ To roll back application code, restore `thinkwork.lock` to the previously
68
+ working release and dispatch the workflow. To roll back customer overlays,
69
+ revert the customer repo commit and dispatch `component=overlays`.
70
+
71
+ If a deploy fails after Terraform apply but before smoke summary, inspect the
72
+ workflow artifacts first: `release-manifest.json`, `overlay-report.json`, and
73
+ the deploy summary identify which stage failed.
74
+
75
+ ## Break Glass
76
+
77
+ A full ThinkWork source fork is emergency debt. Use it only when the customer
78
+ requires source changes that cannot be shipped upstream quickly enough. Record
79
+ the fork reason, owner, and expected upstream PR before deploying it.