thinkwork-cli 0.1.0 → 0.2.0

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 (39) hide show
  1. package/README.md +3 -3
  2. package/dist/cli.js +251 -47
  3. package/dist/terraform/examples/greenfield/main.tf +190 -0
  4. package/dist/terraform/examples/greenfield/terraform.tfvars.example +28 -0
  5. package/dist/terraform/modules/_internal/workspace-guard/main.tf +29 -0
  6. package/dist/terraform/modules/app/agentcore-runtime/main.tf +217 -0
  7. package/dist/terraform/modules/app/appsync-subscriptions/main.tf +122 -0
  8. package/dist/terraform/modules/app/appsync-subscriptions/outputs.tf +20 -0
  9. package/dist/terraform/modules/app/appsync-subscriptions/variables.tf +31 -0
  10. package/dist/terraform/modules/app/crons/main.tf +55 -0
  11. package/dist/terraform/modules/app/hindsight-memory/README.md +66 -0
  12. package/dist/terraform/modules/app/hindsight-memory/main.tf +331 -0
  13. package/dist/terraform/modules/app/job-triggers/main.tf +70 -0
  14. package/dist/terraform/modules/app/lambda-api/.build/placeholder.zip +0 -0
  15. package/dist/terraform/modules/app/lambda-api/handlers.tf +311 -0
  16. package/dist/terraform/modules/app/lambda-api/main.tf +245 -0
  17. package/dist/terraform/modules/app/lambda-api/outputs.tf +24 -0
  18. package/dist/terraform/modules/app/lambda-api/variables.tf +153 -0
  19. package/dist/terraform/modules/app/ses-email/main.tf +51 -0
  20. package/dist/terraform/modules/app/static-site/main.tf +176 -0
  21. package/dist/terraform/modules/data/aurora-postgres/README.md +92 -0
  22. package/dist/terraform/modules/data/aurora-postgres/main.tf +185 -0
  23. package/dist/terraform/modules/data/aurora-postgres/outputs.tf +30 -0
  24. package/dist/terraform/modules/data/aurora-postgres/variables.tf +114 -0
  25. package/dist/terraform/modules/data/bedrock-knowledge-base/main.tf +102 -0
  26. package/dist/terraform/modules/data/s3-buckets/main.tf +91 -0
  27. package/dist/terraform/modules/foundation/cognito/main.tf +377 -0
  28. package/dist/terraform/modules/foundation/cognito/outputs.tf +29 -0
  29. package/dist/terraform/modules/foundation/cognito/variables.tf +124 -0
  30. package/dist/terraform/modules/foundation/dns/main.tf +49 -0
  31. package/dist/terraform/modules/foundation/kms/main.tf +49 -0
  32. package/dist/terraform/modules/foundation/vpc/main.tf +137 -0
  33. package/dist/terraform/modules/foundation/vpc/outputs.tf +14 -0
  34. package/dist/terraform/modules/foundation/vpc/variables.tf +40 -0
  35. package/dist/terraform/modules/thinkwork/main.tf +212 -0
  36. package/dist/terraform/modules/thinkwork/outputs.tf +87 -0
  37. package/dist/terraform/modules/thinkwork/variables.tf +241 -0
  38. package/dist/terraform/schema.graphql +199 -0
  39. package/package.json +2 -2
@@ -0,0 +1,87 @@
1
+ ################################################################################
2
+ # Thinkwork Composite Root — Outputs
3
+ ################################################################################
4
+
5
+ # Foundation
6
+ output "vpc_id" {
7
+ value = module.vpc.vpc_id
8
+ }
9
+
10
+ output "user_pool_id" {
11
+ value = module.cognito.user_pool_id
12
+ }
13
+
14
+ output "admin_client_id" {
15
+ value = module.cognito.admin_client_id
16
+ }
17
+
18
+ output "mobile_client_id" {
19
+ value = module.cognito.mobile_client_id
20
+ }
21
+
22
+ output "identity_pool_id" {
23
+ value = module.cognito.identity_pool_id
24
+ }
25
+
26
+ output "kms_key_arn" {
27
+ value = module.kms.key_arn
28
+ }
29
+
30
+ # Data
31
+ output "db_cluster_arn" {
32
+ value = module.database.db_cluster_arn
33
+ }
34
+
35
+ output "db_cluster_endpoint" {
36
+ value = module.database.cluster_endpoint
37
+ }
38
+
39
+ output "db_secret_arn" {
40
+ description = "Secrets Manager ARN for database credentials"
41
+ value = module.database.graphql_db_secret_arn
42
+ }
43
+
44
+ output "database_name" {
45
+ description = "Database name"
46
+ value = var.database_name
47
+ }
48
+
49
+ output "bucket_name" {
50
+ value = module.s3.bucket_name
51
+ }
52
+
53
+ output "kb_service_role_arn" {
54
+ value = module.bedrock_kb.kb_service_role_arn
55
+ }
56
+
57
+ # App
58
+ output "api_endpoint" {
59
+ value = module.api.api_endpoint
60
+ }
61
+
62
+ output "appsync_api_url" {
63
+ value = module.appsync.graphql_api_url
64
+ }
65
+
66
+ output "appsync_realtime_url" {
67
+ value = module.appsync.graphql_realtime_url
68
+ }
69
+
70
+ output "appsync_api_key" {
71
+ value = module.appsync.graphql_api_key
72
+ sensitive = true
73
+ }
74
+
75
+ output "ecr_repository_url" {
76
+ value = module.agentcore.ecr_repository_url
77
+ }
78
+
79
+ output "memory_engine" {
80
+ description = "Which memory engine is active (managed or hindsight)"
81
+ value = var.memory_engine
82
+ }
83
+
84
+ output "hindsight_endpoint" {
85
+ description = "Hindsight API endpoint (only when memory_engine = hindsight)"
86
+ value = var.memory_engine == "hindsight" ? module.hindsight[0].hindsight_endpoint : null
87
+ }
@@ -0,0 +1,241 @@
1
+ ################################################################################
2
+ # Thinkwork Composite Root — Variables
3
+ #
4
+ # This is the friendly front door: `thinkwork-ai/thinkwork/aws` on the
5
+ # Terraform Registry. It wires the three tiers (foundation, data, app)
6
+ # together with sensible defaults. Advanced users can compose sub-modules
7
+ # directly instead.
8
+ ################################################################################
9
+
10
+ # ---------------------------------------------------------------------------
11
+ # Required
12
+ # ---------------------------------------------------------------------------
13
+
14
+ variable "stage" {
15
+ description = "Deployment stage (e.g. dev, prod). Must match the Terraform workspace name."
16
+ type = string
17
+ }
18
+
19
+ variable "region" {
20
+ description = "AWS region"
21
+ type = string
22
+ default = "us-east-1"
23
+ }
24
+
25
+ variable "account_id" {
26
+ description = "AWS account ID"
27
+ type = string
28
+ }
29
+
30
+ # ---------------------------------------------------------------------------
31
+ # Secrets (populate via SSM data sources or tfvars)
32
+ # ---------------------------------------------------------------------------
33
+
34
+ variable "db_password" {
35
+ description = "Master password for the Aurora cluster"
36
+ type = string
37
+ sensitive = true
38
+ }
39
+
40
+ variable "google_oauth_client_id" {
41
+ description = "Google OAuth client ID for Cognito social login (optional)"
42
+ type = string
43
+ default = ""
44
+ }
45
+
46
+ variable "google_oauth_client_secret" {
47
+ description = "Google OAuth client secret"
48
+ type = string
49
+ sensitive = true
50
+ default = ""
51
+ }
52
+
53
+ # ---------------------------------------------------------------------------
54
+ # BYO Foundation (all optional — defaults to creating everything)
55
+ # ---------------------------------------------------------------------------
56
+
57
+ variable "create_vpc" {
58
+ description = "Create a new VPC (false = BYO)"
59
+ type = bool
60
+ default = true
61
+ }
62
+
63
+ variable "existing_vpc_id" {
64
+ type = string
65
+ default = null
66
+ }
67
+
68
+ variable "existing_public_subnet_ids" {
69
+ type = list(string)
70
+ default = []
71
+ }
72
+
73
+ variable "existing_private_subnet_ids" {
74
+ type = list(string)
75
+ default = []
76
+ }
77
+
78
+ variable "create_cognito" {
79
+ description = "Create a new Cognito user pool (false = BYO)"
80
+ type = bool
81
+ default = true
82
+ }
83
+
84
+ variable "existing_user_pool_id" {
85
+ type = string
86
+ default = null
87
+ }
88
+
89
+ variable "existing_user_pool_arn" {
90
+ type = string
91
+ default = null
92
+ }
93
+
94
+ variable "existing_admin_client_id" {
95
+ type = string
96
+ default = null
97
+ }
98
+
99
+ variable "existing_mobile_client_id" {
100
+ type = string
101
+ default = null
102
+ }
103
+
104
+ variable "existing_identity_pool_id" {
105
+ type = string
106
+ default = null
107
+ }
108
+
109
+ variable "create_database" {
110
+ description = "Create a new Aurora cluster (false = BYO)"
111
+ type = bool
112
+ default = true
113
+ }
114
+
115
+ variable "existing_db_cluster_arn" {
116
+ type = string
117
+ default = null
118
+ }
119
+
120
+ variable "existing_db_secret_arn" {
121
+ type = string
122
+ default = null
123
+ }
124
+
125
+ variable "existing_db_endpoint" {
126
+ type = string
127
+ default = null
128
+ }
129
+
130
+ variable "existing_db_security_group_id" {
131
+ type = string
132
+ default = null
133
+ }
134
+
135
+ variable "database_engine" {
136
+ description = "Database engine: 'aurora-serverless' (production) or 'rds-postgres' (dev/test, cheaper)"
137
+ type = string
138
+ default = "aurora-serverless"
139
+ }
140
+
141
+ variable "memory_engine" {
142
+ description = "Memory engine: 'managed' (AgentCore built-in, default) or 'hindsight' (ECS+ALB service, opt-in)"
143
+ type = string
144
+ default = "managed"
145
+
146
+ validation {
147
+ condition = contains(["managed", "hindsight"], var.memory_engine)
148
+ error_message = "memory_engine must be 'managed' or 'hindsight'"
149
+ }
150
+ }
151
+
152
+ variable "hindsight_image_tag" {
153
+ description = "Hindsight Docker image tag (only used when memory_engine = 'hindsight')"
154
+ type = string
155
+ default = "0.4.22"
156
+ }
157
+
158
+ variable "agentcore_memory_id" {
159
+ description = "AgentCore Memory resource ID (only used when memory_engine = 'managed')"
160
+ type = string
161
+ default = ""
162
+ }
163
+
164
+ # ---------------------------------------------------------------------------
165
+ # Naming / Buckets
166
+ # ---------------------------------------------------------------------------
167
+
168
+ variable "bucket_name" {
169
+ description = "Primary S3 bucket name"
170
+ type = string
171
+ default = ""
172
+ }
173
+
174
+ variable "database_name" {
175
+ description = "Aurora database name"
176
+ type = string
177
+ default = "thinkwork"
178
+ }
179
+
180
+ # ---------------------------------------------------------------------------
181
+ # Lambda Artifacts
182
+ # ---------------------------------------------------------------------------
183
+
184
+ variable "lambda_artifact_bucket" {
185
+ description = "S3 bucket containing Lambda deployment artifacts"
186
+ type = string
187
+ default = ""
188
+ }
189
+
190
+ variable "lambda_artifact_prefix" {
191
+ description = "S3 key prefix for Lambda artifacts"
192
+ type = string
193
+ default = "latest/lambdas"
194
+ }
195
+
196
+ variable "lambda_zips_dir" {
197
+ description = "Local directory containing Lambda zip artifacts (from scripts/build-lambdas.sh). Enables real handlers when set."
198
+ type = string
199
+ default = ""
200
+ }
201
+
202
+ variable "api_auth_secret" {
203
+ description = "Shared secret for inter-service API authentication"
204
+ type = string
205
+ sensitive = true
206
+ default = ""
207
+ }
208
+
209
+ # ---------------------------------------------------------------------------
210
+ # Cognito Callback URLs (configurable per deployment)
211
+ # ---------------------------------------------------------------------------
212
+
213
+ variable "admin_callback_urls" {
214
+ type = list(string)
215
+ default = ["http://localhost:5174", "http://localhost:5174/auth/callback"]
216
+ }
217
+
218
+ variable "admin_logout_urls" {
219
+ type = list(string)
220
+ default = ["http://localhost:5174"]
221
+ }
222
+
223
+ variable "mobile_callback_urls" {
224
+ type = list(string)
225
+ default = ["exp://localhost:8081", "thinkwork://", "thinkwork://auth/callback"]
226
+ }
227
+
228
+ variable "mobile_logout_urls" {
229
+ type = list(string)
230
+ default = ["exp://localhost:8081", "thinkwork://"]
231
+ }
232
+
233
+ # ---------------------------------------------------------------------------
234
+ # Pre-signup Lambda
235
+ # ---------------------------------------------------------------------------
236
+
237
+ variable "pre_signup_lambda_zip" {
238
+ description = "Path to the Cognito pre-signup Lambda zip"
239
+ type = string
240
+ default = ""
241
+ }
@@ -0,0 +1,199 @@
1
+ # Auto-generated AppSync subscription-only schema.
2
+ # DO NOT EDIT — regenerate with: pnpm schema:build
3
+ #
4
+ # Source: packages/database-pg/graphql/types/subscriptions.graphql
5
+
6
+ scalar AWSDateTime
7
+
8
+ schema {
9
+ query: Query
10
+ mutation: Mutation
11
+ subscription: Subscription
12
+ }
13
+
14
+ type Query {
15
+ _empty: String
16
+ }
17
+
18
+ # AppSync Subscriptions — real-time event streams
19
+ #
20
+ # Each subscription filters by tenantId (or threadId) and is triggered
21
+ # by its corresponding notification mutation via @aws_subscribe.
22
+
23
+ # ────────────────────────────────────────────────────────────────────
24
+ # Event payload types
25
+ # ────────────────────────────────────────────────────────────────────
26
+
27
+ type AgentStatusEvent {
28
+ agentId: ID!
29
+ tenantId: ID!
30
+ status: String!
31
+ name: String!
32
+ updatedAt: AWSDateTime!
33
+ }
34
+
35
+ type NewMessageEvent {
36
+ messageId: ID!
37
+ threadId: ID!
38
+ tenantId: ID!
39
+ role: String!
40
+ content: String
41
+ senderType: String
42
+ senderId: ID
43
+ createdAt: AWSDateTime!
44
+ }
45
+
46
+ type HeartbeatActivityEvent {
47
+ heartbeatId: ID!
48
+ tenantId: ID!
49
+ status: String!
50
+ message: String
51
+ createdAt: AWSDateTime!
52
+ }
53
+
54
+ type ThreadUpdateEvent {
55
+ threadId: ID!
56
+ tenantId: ID!
57
+ status: String!
58
+ title: String!
59
+ updatedAt: AWSDateTime!
60
+ }
61
+
62
+ type InboxItemStatusEvent {
63
+ inboxItemId: ID!
64
+ tenantId: ID!
65
+ status: String!
66
+ title: String
67
+ updatedAt: AWSDateTime!
68
+ }
69
+
70
+ type ThreadTurnUpdateEvent {
71
+ runId: ID!
72
+ triggerId: ID
73
+ tenantId: ID!
74
+ threadId: ID
75
+ agentId: ID
76
+ status: String!
77
+ triggerName: String
78
+ updatedAt: AWSDateTime!
79
+ }
80
+
81
+ type OrgUpdateEvent {
82
+ tenantId: ID!
83
+ changeType: String!
84
+ entityType: String
85
+ entityId: ID
86
+ updatedAt: AWSDateTime!
87
+ }
88
+
89
+ type CostRecordedEvent {
90
+ tenantId: ID!
91
+ agentId: ID
92
+ agentName: String
93
+ eventType: String!
94
+ amountUsd: Float!
95
+ model: String
96
+ updatedAt: AWSDateTime!
97
+ }
98
+
99
+ # ────────────────────────────────────────────────────────────────────
100
+ # Notification mutations
101
+ #
102
+ # These are called by Lambda resolvers (not clients) to trigger the
103
+ # corresponding subscriptions. @aws_subscribe binds each subscription
104
+ # to the mutation(s) whose return type matches the event payload.
105
+ # ────────────────────────────────────────────────────────────────────
106
+
107
+ type Mutation {
108
+ _empty: String
109
+ notifyAgentStatus(
110
+ agentId: ID!
111
+ tenantId: ID!
112
+ status: String!
113
+ name: String!
114
+ ): AgentStatusEvent @aws_api_key @aws_cognito_user_pools @aws_iam
115
+
116
+ notifyNewMessage(
117
+ messageId: ID!
118
+ threadId: ID!
119
+ tenantId: ID!
120
+ role: String!
121
+ content: String
122
+ senderType: String
123
+ senderId: ID
124
+ ): NewMessageEvent @aws_api_key @aws_cognito_user_pools @aws_iam
125
+
126
+ notifyHeartbeatActivity(
127
+ heartbeatId: ID!
128
+ tenantId: ID!
129
+ status: String!
130
+ message: String
131
+ ): HeartbeatActivityEvent @aws_api_key @aws_cognito_user_pools @aws_iam
132
+
133
+ notifyThreadUpdate(
134
+ threadId: ID!
135
+ tenantId: ID!
136
+ status: String!
137
+ title: String!
138
+ ): ThreadUpdateEvent @aws_api_key @aws_cognito_user_pools @aws_iam
139
+
140
+ notifyInboxItemUpdate(
141
+ inboxItemId: ID!
142
+ tenantId: ID!
143
+ status: String!
144
+ title: String
145
+ ): InboxItemStatusEvent @aws_api_key @aws_cognito_user_pools @aws_iam
146
+
147
+ notifyThreadTurnUpdate(
148
+ runId: ID!
149
+ triggerId: ID
150
+ tenantId: ID!
151
+ threadId: ID
152
+ agentId: ID
153
+ status: String!
154
+ triggerName: String
155
+ ): ThreadTurnUpdateEvent @aws_api_key @aws_cognito_user_pools @aws_iam
156
+
157
+ notifyOrgUpdate(
158
+ tenantId: ID!
159
+ changeType: String!
160
+ entityType: String
161
+ entityId: ID
162
+ ): OrgUpdateEvent @aws_api_key @aws_cognito_user_pools @aws_iam
163
+
164
+ notifyCostRecorded(
165
+ tenantId: ID!
166
+ agentId: ID
167
+ agentName: String
168
+ eventType: String!
169
+ amountUsd: Float!
170
+ model: String
171
+ ): CostRecordedEvent @aws_api_key @aws_cognito_user_pools @aws_iam
172
+ }
173
+
174
+ type Subscription {
175
+ _empty: String
176
+ onAgentStatusChanged(tenantId: ID!): AgentStatusEvent @aws_api_key @aws_cognito_user_pools @aws_iam
177
+ @aws_subscribe(mutations: ["notifyAgentStatus"])
178
+
179
+ onNewMessage(threadId: ID!): NewMessageEvent @aws_api_key @aws_cognito_user_pools @aws_iam
180
+ @aws_subscribe(mutations: ["notifyNewMessage"])
181
+
182
+ onHeartbeatActivity(tenantId: ID!): HeartbeatActivityEvent @aws_api_key @aws_cognito_user_pools @aws_iam
183
+ @aws_subscribe(mutations: ["notifyHeartbeatActivity"])
184
+
185
+ onThreadUpdated(tenantId: ID!): ThreadUpdateEvent @aws_api_key @aws_cognito_user_pools @aws_iam
186
+ @aws_subscribe(mutations: ["notifyThreadUpdate"])
187
+
188
+ onInboxItemStatusChanged(tenantId: ID!): InboxItemStatusEvent @aws_api_key @aws_cognito_user_pools @aws_iam
189
+ @aws_subscribe(mutations: ["notifyInboxItemUpdate"])
190
+
191
+ onThreadTurnUpdated(tenantId: ID!): ThreadTurnUpdateEvent @aws_api_key @aws_cognito_user_pools @aws_iam
192
+ @aws_subscribe(mutations: ["notifyThreadTurnUpdate"])
193
+
194
+ onOrgUpdated(tenantId: ID!): OrgUpdateEvent @aws_api_key @aws_cognito_user_pools @aws_iam
195
+ @aws_subscribe(mutations: ["notifyOrgUpdate"])
196
+
197
+ onCostRecorded(tenantId: ID!): CostRecordedEvent @aws_api_key @aws_cognito_user_pools @aws_iam
198
+ @aws_subscribe(mutations: ["notifyCostRecorded"])
199
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thinkwork-cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Thinkwork CLI — deploy, manage, and interact with your Thinkwork stack",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -11,7 +11,7 @@
11
11
  "dist"
12
12
  ],
13
13
  "scripts": {
14
- "build": "tsup src/cli.ts --format esm --dts --clean",
14
+ "build": "tsup src/cli.ts --format esm --dts --clean && node scripts/bundle-terraform.js",
15
15
  "dev": "tsx src/cli.ts",
16
16
  "typecheck": "tsc --noEmit",
17
17
  "test": "vitest run",