thinkwork-cli 0.12.11 → 0.12.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -38
- package/dist/{api-client-ASJWIG3Z.js → api-client-4VT3FWOH.js} +1 -1
- package/dist/{chunk-JEHV35EU.js → chunk-H7AB42ES.js} +340 -30
- package/dist/cli.js +22157 -9229
- package/dist/commands/enterprise/templates/deploy-repo/.github/workflows/deploy.yml +17 -6
- package/dist/commands/enterprise/templates/deploy-repo/docs/runbook.md +81 -9
- package/dist/commands/enterprise/templates/deploy-repo/scripts/apply-release.mjs +183 -21
- package/dist/commands/enterprise/templates/deploy-repo/scripts/smoke.mjs +1 -2
- package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +286 -0
- package/dist/drizzle/0000_petite_marvel_apes.sql +1188 -0
- package/dist/drizzle/0001_milky_surge.sql +103 -0
- package/dist/drizzle/0002_aberrant_mattie_franklin.sql +41 -0
- package/dist/drizzle/0003_exotic_ogun.sql +3 -0
- package/dist/drizzle/0004_glamorous_magneto.sql +2 -0
- package/dist/drizzle/0005_ancient_nocturne.sql +2 -0
- package/dist/drizzle/0006_new_colonel_america.sql +2 -0
- package/dist/drizzle/0007_unique_external_task_id.sql +31 -0
- package/dist/drizzle/0008_external_task_id_column.sql +43 -0
- package/dist/drizzle/0009_evaluations.sql +64 -0
- package/dist/drizzle/0010_eval_agent_template.sql +2 -0
- package/dist/drizzle/0011_eval_run_template.sql +2 -0
- package/dist/drizzle/0012_eval_seed_unique.sql +16 -0
- package/dist/drizzle/0013_motionless_white_queen.sql +140 -0
- package/dist/drizzle/0014_wiki_aggregation.sql +11 -0
- package/dist/drizzle/0015_pg_trgm_alias_title_indexes.sql +9 -0
- package/dist/drizzle/0016_wiki_schema_drops.sql +24 -0
- package/dist/drizzle/0017_wiki_places.sql +46 -0
- package/dist/drizzle/0018_agent_workspace_overlay.sql +26 -0
- package/dist/drizzle/0018_cool_firebird.sql +24 -0
- package/dist/drizzle/0018_skill_runs.sql +84 -0
- package/dist/drizzle/0019_condemned_dragon_man.sql +95 -0
- package/dist/drizzle/0019_webhook_skill_runs.sql +58 -0
- package/dist/drizzle/0020_crazy_the_anarchist.sql +9 -0
- package/dist/drizzle/0020_mutation_idempotency.sql +64 -0
- package/dist/drizzle/0021_crm_work_links.sql +76 -0
- package/dist/drizzle/0021_skill_runs_completion_hmac.sql +33 -0
- package/dist/drizzle/0022_add_billing_tables.sql +70 -0
- package/dist/drizzle/0022_seed_thinkwork_admin_permissions.sql +160 -0
- package/dist/drizzle/0022_stripe_billing_indexes.sql +48 -0
- package/dist/drizzle/0023_tenants_deactivation.sql +27 -0
- package/dist/drizzle/0024_tenant_mcp_admin_keys.sql +63 -0
- package/dist/drizzle/0025_v1_agent_architecture.sql +182 -0
- package/dist/drizzle/0026_thread_turns_add_kind.sql +28 -0
- package/dist/drizzle/0027_capability_catalog_and_manifests.sql +219 -0
- package/dist/drizzle/0028_aws_s3_extension.sql +26 -0
- package/dist/drizzle/0029_collapse_execution_types.sql +42 -0
- package/dist/drizzle/0030_retire_composition_primitives.sql +48 -0
- package/dist/drizzle/0031_thread_cleanup_drops.sql +131 -0
- package/dist/drizzle/0032_add_browser_automation_template_config.sql +24 -0
- package/dist/drizzle/0033_agent_operation_leases.sql +32 -0
- package/dist/drizzle/0034_agent_workspace_events.sql +116 -0
- package/dist/drizzle/0035_workspace_review_decisions.sql +19 -0
- package/dist/drizzle/0036_user_scoped_memory_wiki.sql +152 -0
- package/dist/drizzle/0037_user_profile_operating_model.sql +34 -0
- package/dist/drizzle/0042_agent_runtime_selector.sql +41 -0
- package/dist/drizzle/0043_wiki_search_tsv_tokenization.sql +48 -0
- package/dist/drizzle/0044_add_web_search_template_config.sql +7 -0
- package/dist/drizzle/0045_add_send_email_template_config.sql +7 -0
- package/dist/drizzle/0046_tenant_mcp_context_tools.sql +26 -0
- package/dist/drizzle/0047_add_context_engine_template_config.sql +7 -0
- package/dist/drizzle/0048_tenant_context_provider_settings.sql +22 -0
- package/dist/drizzle/0050_brain_v0_entity_subtype.sql +29 -0
- package/dist/drizzle/0051_brain_v0_tenant_entity_pages.sql +170 -0
- package/dist/drizzle/0052_brain_v0_external_refs.sql +41 -0
- package/dist/drizzle/0053_brain_v0_unresolved_mentions_subtype.sql +48 -0
- package/dist/drizzle/0054_wiki_compile_jobs_input.sql +28 -0
- package/dist/drizzle/0055_routines_stepfunctions_substrate.sql +202 -0
- package/dist/drizzle/0056_routine_step_events_dedup_idx.sql +25 -0
- package/dist/drizzle/0057_archive_legacy_python_routines.sql +36 -0
- package/dist/drizzle/0058_routines_visibility_and_owning_agent.sql +61 -0
- package/dist/drizzle/0061_routine_execution_asl_version_id.sql +29 -0
- package/dist/drizzle/0062_migrate_pi_to_flue.sql +110 -0
- package/dist/drizzle/0063_threads_session_data.sql +23 -0
- package/dist/drizzle/0064_tenant_credentials.sql +65 -0
- package/dist/drizzle/0067_thinkwork_computers_phase_one.sql +174 -0
- package/dist/drizzle/0068_drop_system_workflows_and_activation.sql +115 -0
- package/dist/drizzle/0069_compliance_schema.sql +364 -0
- package/dist/drizzle/0070_compliance_aurora_roles.sql +171 -0
- package/dist/drizzle/0072_threads_computer_ownership.sql +24 -0
- package/dist/drizzle/0073_compliance_tenant_anchor_state.sql +105 -0
- package/dist/drizzle/0074_compliance_event_hash_index.sql +49 -0
- package/dist/drizzle/0075_scheduled_jobs_computer_ownership.sql +27 -0
- package/dist/drizzle/0076_scheduled_jobs_marco_backfill.sql +69 -0
- package/dist/drizzle/0077_computers_primary_agent_id.sql +38 -0
- package/dist/drizzle/0078_tenant_customize_catalog.sql +46 -0
- package/dist/drizzle/0079_seed_tenant_customize_catalog.sql +53 -0
- package/dist/drizzle/0081_routines_catalog_slug.sql +42 -0
- package/dist/drizzle/0082_messages_parts_jsonb.sql +52 -0
- package/dist/drizzle/0083_computer_runbooks.sql +103 -0
- package/dist/drizzle/0084_artifacts_favorited_at.sql +32 -0
- package/dist/drizzle/0085_seed_thinkwork_computer_default_template.sql +46 -0
- package/dist/drizzle/0086_update_default_template_models.sql +19 -0
- package/dist/drizzle/0087_retire_oss_connectors.sql +77 -0
- package/dist/drizzle/0088_compliance_event_types_finance_pilot.sql +37 -0
- package/dist/drizzle/0089_remove_maniflow_eval_seeds.sql +81 -0
- package/dist/drizzle/0089_wiki_schema_extraction.sql +315 -0
- package/dist/drizzle/0090_brain_schema_extraction.sql +274 -0
- package/dist/drizzle/0091_drop_wiki_brain_compat_views.sql +118 -0
- package/dist/drizzle/0092_finish_oss_connector_retirement.sql +97 -0
- package/dist/drizzle/0093_eval_runs_scheduled_job_id.sql +23 -0
- package/dist/drizzle/0094_slack_workspace_app.sql +140 -0
- package/dist/drizzle/0095_eval_runs_computer_id.sql +22 -0
- package/dist/drizzle/0096_true_redteam_eval_seed_cleanup.sql +67 -0
- package/dist/drizzle/0097_shared_computers.sql +191 -0
- package/dist/drizzle/0098_business_ontology.sql +587 -0
- package/dist/drizzle/0099_thread_idle_learning.sql +145 -0
- package/dist/drizzle/0100_ontology_gated_brain_dynamic_subtypes.sql +7 -0
- package/dist/drizzle/0101_ontology_gated_unresolved_mentions_dynamic_subtypes.sql +7 -0
- package/dist/drizzle/0102_wiki_brain_owner_repair.sql +87 -0
- package/dist/drizzle/0103_brain_section_source_trigger_repair.sql +75 -0
- package/dist/drizzle/0104_expand_seed_ontology_for_user_memory.sql +166 -0
- package/dist/drizzle/0105_spaces_domain.sql +349 -0
- package/dist/drizzle/0106_expand_seed_ontology_for_triples.sql +173 -0
- package/dist/drizzle/0106_space_threads_participants.sql +197 -0
- package/dist/drizzle/0107_linked_task_mirror.sql +245 -0
- package/dist/drizzle/0108_message_mentions.sql +95 -0
- package/dist/drizzle/0109_space_owned_threads.sql +217 -0
- package/dist/drizzle/0110_thread_participant_read_state.sql +21 -0
- package/dist/drizzle/0111_agents_tenant_name_unique.sql +38 -0
- package/dist/drizzle/0112_recast_spaces_as_contextual_workrooms.sql +138 -0
- package/dist/drizzle/0113_agents_own_runtime_fields.sql +48 -0
- package/dist/drizzle/0114_migrate_templates_to_agents_and_spaces.sql +361 -0
- package/dist/drizzle/0115_remove_computer_eval_template_dependencies.sql +69 -0
- package/dist/drizzle/0116_backfill_thread_participants_access.sql +126 -0
- package/dist/drizzle/0117_space_access_mode.sql +40 -0
- package/dist/drizzle/0118_normalize_tenant_member_principal_type.sql +41 -0
- package/dist/drizzle/0119_space_knowledge_bases.sql +126 -0
- package/dist/drizzle/0120_space_automations.sql +58 -0
- package/dist/drizzle/0121_drop_computer_runbooks.sql +26 -0
- package/dist/drizzle/0122_space_email_triggers.sql +24 -0
- package/dist/drizzle/0123_single_platform_agent_and_overrides.sql +58 -0
- package/dist/drizzle/0124_thread_turns_finalized_at.sql +17 -0
- package/dist/drizzle/0125_drop_space_agent_assignments.sql +42 -0
- package/dist/drizzle/0126_migrate_flue_to_pi.sql +42 -0
- package/dist/drizzle/0127_runtime_type_observability.sql +28 -0
- package/dist/drizzle/0128_drop_eval_test_cases_agent_id.sql +37 -0
- package/dist/drizzle/0129_drop_code_factory_tables.sql +43 -0
- package/dist/drizzle/0129_eval_results_system_prompt.sql +30 -0
- package/dist/drizzle/0130_drop_teams_and_team_id_columns.sql +54 -0
- package/dist/drizzle/0131_drop_skill_catalog_and_tenant_skills.sql +33 -0
- package/dist/drizzle/0132_drop_computer_tables.sql +31 -0
- package/dist/drizzle/0133_drop_seed_view_tombstones.sql +79 -0
- package/dist/drizzle/0133_thread_turns_system_prompt.sql +22 -0
- package/dist/drizzle/0134_drop_dead_agent_runtime_tables.sql +53 -0
- package/dist/drizzle/0135_native_checklist_linked_tasks.sql +48 -0
- package/dist/drizzle/0136_goal_ledger.sql +55 -0
- package/dist/drizzle/0136_space_email_trigger_status.sql +66 -0
- package/dist/drizzle/0137_thread_participant_pins.sql +25 -0
- package/dist/drizzle/0138_users_cognito_sub.sql +30 -0
- package/dist/drizzle/0139_mobile_turn_client_id.sql +23 -0
- package/dist/drizzle/0140_workspace_folder_names.sql +36 -0
- package/dist/drizzle/0141_eval_runs_desktop_pi_provenance.sql +31 -0
- package/dist/drizzle/0142_pi_only_agent_runtime.sql +61 -0
- package/dist/drizzle/0143_add_web_extract_builtin_config.sql +28 -0
- package/dist/drizzle/0144_skill_catalog_index.sql +40 -0
- package/dist/drizzle/0145_knowledge_graph_thread_ingest.sql +512 -0
- package/dist/drizzle/0146_knowledge_graph_source_scope.sql +413 -0
- package/dist/drizzle/0147_knowledge_graph_scope_trigger_qualification.sql +211 -0
- package/dist/drizzle/0148_user_cost_attribution.sql +171 -0
- package/dist/drizzle/0149_managed_mcp_servers.sql +64 -0
- package/dist/drizzle/0149_user_model_approvals.sql +89 -0
- package/dist/drizzle/0150_bootstrap_first_admin_claim.sql +11 -0
- package/dist/drizzle/0151_managed_deployments.sql +91 -0
- package/dist/drizzle/0152_agent_profiles.sql +81 -0
- package/dist/drizzle/0153_message_mentions_agent_profile.sql +9 -0
- package/dist/drizzle/0154_customer_deployment_sessions.sql +61 -0
- package/dist/drizzle/0155_tenant_model_catalog.sql +152 -0
- package/dist/drizzle/0156_bootstrap_credential_leases.sql +52 -0
- package/dist/drizzle/0157_knowledge_graph_observations_source.sql +79 -0
- package/dist/drizzle/0158_pending_user_questions.sql +80 -0
- package/dist/drizzle/0158_wiki_tenant_scope.sql +38 -0
- package/dist/drizzle/0159_agent_profiles_space_local.sql +49 -0
- package/dist/drizzle/0159_application_plugins.sql +193 -0
- package/dist/drizzle/0159_eval_scoring_version.sql +46 -0
- package/dist/drizzle/0160_compliance_event_types_plugins.sql +37 -0
- package/dist/drizzle/0160_eval_datasets.sql +75 -0
- package/dist/drizzle/0160_eval_results_thread_turn.sql +35 -0
- package/dist/drizzle/0161_eval_run_pinning.sql +54 -0
- package/dist/drizzle/0161_tenant_mcp_servers_plugin_source.sql +62 -0
- package/dist/drizzle/0162_eval_result_override.sql +49 -0
- package/dist/drizzle/0163_eval_replay_tool_allowlist.sql +50 -0
- package/dist/drizzle/0164_eval_replay_tool_override_mode.sql +52 -0
- package/dist/drizzle/0165_plugin_premium_entitlements.sql +153 -0
- package/dist/drizzle/0166_company_brain_substrate_contract.sql +386 -0
- package/dist/drizzle/0167_company_brain_artifact_manifest_runtime.sql +85 -0
- package/dist/drizzle/0168_eval_skill_gate.sql +44 -0
- package/dist/drizzle/0169_release_update_jobs.sql +67 -0
- package/dist/drizzle/0170_email_channel_plugin.sql +291 -0
- package/dist/drizzle/0171_linked_task_external_providers.sql +30 -0
- package/dist/drizzle/0172_email_channel_sendgrid_provider.sql +8 -0
- package/dist/drizzle/0173_auth_provider_resources.sql +83 -0
- package/dist/drizzle/0174_workos_auth_bridges.sql +37 -0
- package/dist/drizzle/0175_workos_auth_sessions.sql +38 -0
- package/dist/drizzle/0176_n8n_agent_step_runs.sql +107 -0
- package/dist/drizzle/0177_workflow_control_plane.sql +281 -0
- package/dist/drizzle/0178_workflow_backfill_existing_routines.sql +525 -0
- package/dist/drizzle/0179_tenant_goal_budget_settings.sql +21 -0
- package/dist/drizzle/0180_skill_drafts.sql +89 -0
- package/dist/drizzle/0181_skill_draft_publish_status.sql +21 -0
- package/dist/drizzle/0182_agent_loops.sql +260 -0
- package/dist/drizzle/0183_okf_artifact_manifests.sql +52 -0
- package/dist/drizzle/0184_skill_catalog_trust_cache.sql +35 -0
- package/dist/drizzle/0185_agent_loop_space.sql +16 -0
- package/dist/drizzle/0186_tenant_mcp_runtime_metadata.sql +10 -0
- package/dist/drizzle/0187_native_work_items.sql +220 -0
- package/dist/drizzle/0188_company_etl_plugin_rename.sql +99 -0
- package/dist/drizzle/0189_trace_cost_substrate.sql +247 -0
- package/dist/drizzle/0190_billing_export_reconciliation.sql +101 -0
- package/dist/drizzle/0191_open_engine_work_item_queue.sql +66 -0
- package/dist/drizzle/0192_work_item_labels.sql +44 -0
- package/dist/drizzle/0193_work_item_documents.sql +31 -0
- package/dist/drizzle/0194_memory_retain_attempts.sql +103 -0
- package/dist/drizzle/0194_work_item_comments.sql +35 -0
- package/dist/drizzle/0195_plugin_app_overlays.sql +45 -0
- package/dist/drizzle/0196_pi_extensions.sql +118 -0
- package/dist/drizzle/0197_eval_profiles.sql +150 -0
- package/dist/drizzle/0198_eval_runs_unstable.sql +27 -0
- package/dist/drizzle/0199_eval_runs_cost_partial.sql +27 -0
- package/dist/drizzle/meta/_journal.json +160 -0
- package/dist/plugins/README.md +162 -0
- package/dist/plugins/catalog/package.json +40 -0
- package/dist/plugins/catalog/scripts/build-catalog.ts +120 -0
- package/dist/plugins/catalog/scripts/generate-plugin-registry.ts +144 -0
- package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +86 -0
- package/dist/plugins/catalog/src/__tests__/catalog.test.ts +308 -0
- package/dist/plugins/catalog/src/__tests__/contracts.test.ts +861 -0
- package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +124 -0
- package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +120 -0
- package/dist/plugins/catalog/src/catalog.ts +434 -0
- package/dist/plugins/catalog/src/contracts.ts +1498 -0
- package/dist/plugins/catalog/src/index.ts +4 -0
- package/dist/plugins/catalog/src/plugin-package.ts +171 -0
- package/dist/plugins/catalog/src/registry/generated-first-party.ts +76 -0
- package/dist/plugins/catalog/src/registry/index.ts +1 -0
- package/dist/plugins/catalog/tsconfig.json +8 -0
- package/dist/plugins/company-brain/README.md +37 -0
- package/dist/plugins/company-brain/package.json +33 -0
- package/dist/plugins/company-brain/runtime/cognee/Dockerfile +11 -0
- package/dist/plugins/company-brain/smoke/cognee-managed-app-smoke.mjs +458 -0
- package/dist/plugins/company-brain/smoke/cognee-memory-cutover-smoke.mjs +539 -0
- package/dist/plugins/company-brain/smoke/company-brain-context-engine-smoke.mjs +312 -0
- package/dist/plugins/company-brain/smoke/company-brain-operations-smoke.mjs +449 -0
- package/dist/plugins/company-brain/smoke/company-brain-plugin-smoke.mjs +655 -0
- package/dist/plugins/company-brain/smoke/hindsight-memory-isolation-smoke.mjs +474 -0
- package/dist/plugins/company-brain/src/api/cognee-client.ts +896 -0
- package/dist/plugins/company-brain/src/api/cognee-cluster-identity.ts +49 -0
- package/dist/plugins/company-brain/src/api/cognee-memory-scope.ts +84 -0
- package/dist/plugins/company-brain/src/api/context-engine-provider.ts +888 -0
- package/dist/plugins/company-brain/src/api/migration.ts +665 -0
- package/dist/plugins/company-brain/src/deployment/cognee-managed-app.ts +396 -0
- package/dist/plugins/company-brain/src/index.ts +62 -0
- package/dist/plugins/company-brain/src/manifest.ts +112 -0
- package/dist/plugins/company-brain/terraform/cognee/README.md +263 -0
- package/dist/plugins/company-brain/terraform/cognee/main.tf +766 -0
- package/dist/plugins/company-brain/terraform/cognee/outputs.tf +144 -0
- package/dist/plugins/company-brain/terraform/cognee/variables.tf +402 -0
- package/dist/plugins/company-brain/test/api/cognee-client.test.ts +562 -0
- package/dist/plugins/company-brain/test/api/cognee-memory-scope.test.ts +74 -0
- package/dist/plugins/company-brain/test/api/context-engine-provider.test.ts +447 -0
- package/dist/plugins/company-brain/test/api/migration.test.ts +465 -0
- package/dist/plugins/company-brain/test/manifest.test.ts +95 -0
- package/dist/plugins/company-brain/tsconfig.json +8 -0
- package/dist/plugins/company-data/README.md +49 -0
- package/dist/plugins/company-data/package.json +21 -0
- package/dist/plugins/company-data/src/index.ts +30 -0
- package/dist/plugins/company-data/src/manifest.ts +26 -0
- package/dist/plugins/company-data/test/manifest.test.ts +116 -0
- package/dist/plugins/company-data/tsconfig.json +8 -0
- package/dist/plugins/company-etl/README.md +46 -0
- package/dist/plugins/company-etl/package.json +21 -0
- package/dist/plugins/company-etl/src/index.ts +29 -0
- package/dist/plugins/company-etl/src/manifest.ts +26 -0
- package/dist/plugins/company-etl/test/manifest.test.ts +108 -0
- package/dist/plugins/company-etl/tsconfig.json +8 -0
- package/dist/plugins/email-channel/README.md +41 -0
- package/dist/plugins/email-channel/package.json +22 -0
- package/dist/plugins/email-channel/src/index.ts +36 -0
- package/dist/plugins/email-channel/src/manifest.ts +44 -0
- package/dist/plugins/email-channel/src/provider-contract.ts +36 -0
- package/dist/plugins/email-channel/test/manifest.test.ts +119 -0
- package/dist/plugins/email-channel/tsconfig.json +8 -0
- package/dist/plugins/lastmile/README.md +50 -0
- package/dist/plugins/lastmile/package.json +23 -0
- package/dist/plugins/lastmile/smoke/lastmile-plugin-smoke.mjs +661 -0
- package/dist/plugins/lastmile/src/api/tasks-adapter.ts +572 -0
- package/dist/plugins/lastmile/src/discovery.fixture.ts +64 -0
- package/dist/plugins/lastmile/src/index.ts +46 -0
- package/dist/plugins/lastmile/src/manifest.ts +139 -0
- package/dist/plugins/lastmile/test/api/tasks-adapter.test.ts +266 -0
- package/dist/plugins/lastmile/test/discovery.test.ts +88 -0
- package/dist/plugins/lastmile/tsconfig.json +8 -0
- package/dist/plugins/n8n/README.md +201 -0
- package/dist/plugins/n8n/n8n-app/README.md +33 -0
- package/dist/plugins/n8n/n8n-app/package.json +23 -0
- package/dist/plugins/n8n/n8n-app/src/application-config.ts +45 -0
- package/dist/plugins/n8n/n8n-app/src/front-components/thinkwork-workflows.front-component.tsx +970 -0
- package/dist/plugins/n8n/n8n-app/src/lib/n8n-app-data.ts +190 -0
- package/dist/plugins/n8n/n8n-app/src/vite-env.d.ts +7 -0
- package/dist/plugins/n8n/n8n-app/tsconfig.json +15 -0
- package/dist/plugins/n8n/package.json +35 -0
- package/dist/plugins/n8n/runtime/Dockerfile +18 -0
- package/dist/plugins/n8n/runtime/n8n-task-runners.json +14 -0
- package/dist/plugins/n8n/runtime/n8n-task-runners.json.template +14 -0
- package/dist/plugins/n8n/runtime/package-lock.json +13 -0
- package/dist/plugins/n8n/runtime/package.json +7 -0
- package/dist/plugins/n8n/scripts/sync-thinkwork-app.mjs +268 -0
- package/dist/plugins/n8n/smoke/README.md +95 -0
- package/dist/plugins/n8n/smoke/n8n-agent-step-bridge-smoke.mjs +866 -0
- package/dist/plugins/n8n/smoke/n8n-integrated-app-smoke.mjs +262 -0
- package/dist/plugins/n8n/smoke/n8n-managed-app-smoke.mjs +409 -0
- package/dist/plugins/n8n/smoke/n8n-mcp-smoke.mjs +624 -0
- package/dist/plugins/n8n/src/deployment/image-build.ts +172 -0
- package/dist/plugins/n8n/src/deployment/managed-app.ts +429 -0
- package/dist/plugins/n8n/src/index.ts +79 -0
- package/dist/plugins/n8n/src/manifest.ts +403 -0
- package/dist/plugins/n8n/src/package-config.ts +186 -0
- package/dist/plugins/n8n/src/skills/n8n-workflow-operator/SKILL.md +76 -0
- package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/mcp-tooling.md +40 -0
- package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/validation-and-handoff.md +40 -0
- package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/workflow-authoring.md +45 -0
- package/dist/plugins/n8n/terraform/n8n/README.md +113 -0
- package/dist/plugins/n8n/terraform/n8n/main.tf +918 -0
- package/dist/plugins/n8n/terraform/n8n/outputs.tf +124 -0
- package/dist/plugins/n8n/terraform/n8n/scripts/sync-database.py +250 -0
- package/dist/plugins/n8n/terraform/n8n/scripts/test_sync_database.py +55 -0
- package/dist/plugins/n8n/terraform/n8n/variables.tf +354 -0
- package/dist/plugins/n8n/test/image-build.test.ts +118 -0
- package/dist/plugins/n8n/test/integrated-app-contract.test.ts +353 -0
- package/dist/plugins/n8n/test/manifest.test.ts +278 -0
- package/dist/plugins/n8n/test/package-config.test.ts +57 -0
- package/dist/plugins/n8n/tsconfig.json +8 -0
- package/dist/plugins/sendgrid/README.md +30 -0
- package/dist/plugins/sendgrid/package.json +22 -0
- package/dist/plugins/sendgrid/src/index.ts +36 -0
- package/dist/plugins/sendgrid/src/manifest.ts +37 -0
- package/dist/plugins/sendgrid/src/provider-contract.ts +14 -0
- package/dist/plugins/sendgrid/test/manifest.test.ts +80 -0
- package/dist/plugins/sendgrid/tsconfig.json +8 -0
- package/dist/plugins/twenty/README.md +78 -0
- package/dist/plugins/twenty/package.json +27 -0
- package/dist/plugins/twenty/scripts/__tests__/sync-thinkwork-app.test.mjs +67 -0
- package/dist/plugins/twenty/scripts/sync-thinkwork-app.mjs +185 -0
- package/dist/plugins/twenty/scripts/wire-thinkwork-workflow.mjs +658 -0
- package/dist/plugins/twenty/smoke/twenty-managed-app-smoke.mjs +359 -0
- package/dist/plugins/twenty/smoke/twenty-mcp-oauth-smoke.mjs +574 -0
- package/dist/plugins/twenty/src/api/cutover.ts +209 -0
- package/dist/plugins/twenty/src/deployment/managed-app.ts +253 -0
- package/dist/plugins/twenty/src/index.ts +55 -0
- package/dist/plugins/twenty/src/manifest.ts +259 -0
- package/dist/plugins/twenty/terraform/twenty/README.md +97 -0
- package/dist/plugins/twenty/terraform/twenty/main.tf +829 -0
- package/dist/plugins/twenty/terraform/twenty/outputs.tf +79 -0
- package/dist/plugins/twenty/terraform/twenty/variables.tf +268 -0
- package/dist/plugins/twenty/test/api/cutover.test.ts +183 -0
- package/dist/plugins/twenty/test/manifest.test.ts +463 -0
- package/dist/plugins/twenty/tsconfig.json +9 -0
- package/dist/plugins/twenty/twenty-app/.nvmrc +1 -0
- package/dist/plugins/twenty/twenty-app/README.md +148 -0
- package/dist/plugins/twenty/twenty-app/package.json +30 -0
- package/dist/plugins/twenty/twenty-app/src/application-config.ts +44 -0
- package/dist/plugins/twenty/twenty-app/src/constants/universal-identifiers.ts +18 -0
- package/dist/plugins/twenty/twenty-app/src/default-role.ts +24 -0
- package/dist/plugins/twenty/twenty-app/src/front-components/thinkwork-settings.front-component.tsx +299 -0
- package/dist/plugins/twenty/twenty-app/src/logic-functions/thinkwork-webhook.logic-function.ts +354 -0
- package/dist/plugins/twenty/twenty-app/tsconfig.json +14 -0
- package/dist/plugins/twenty/twenty-app/yarn.lock +4144 -0
- package/dist/plugins/workos-auth/package.json +22 -0
- package/dist/plugins/workos-auth/src/index.ts +30 -0
- package/dist/plugins/workos-auth/src/manifest.ts +40 -0
- package/dist/plugins/workos-auth/src/provider-contract.ts +39 -0
- package/dist/plugins/workos-auth/test/manifest.test.ts +94 -0
- package/dist/plugins/workos-auth/tsconfig.json +8 -0
- package/dist/scripts/bootstrap-workspace.sh +162 -0
- package/dist/scripts/post-deploy.sh +290 -0
- package/dist/terraform/examples/greenfield/main.tf +903 -75
- package/dist/terraform/examples/greenfield/terraform.tfvars.example +67 -8
- package/dist/terraform/modules/app/agentcore-code-interpreter/Dockerfile.sandbox-base +2 -2
- package/dist/terraform/modules/app/agentcore-code-interpreter/README.md +8 -9
- package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/sitecustomize.py +227 -0
- package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/test_sitecustomize.py +277 -0
- package/dist/terraform/modules/app/agentcore-memory/README.md +6 -6
- package/dist/terraform/modules/app/agentcore-memory/main.tf +1 -1
- package/dist/terraform/modules/app/agentcore-memory/scripts/create_or_find_memory.sh +40 -9
- package/dist/terraform/modules/app/agentcore-pi/README.md +61 -0
- package/dist/terraform/modules/app/agentcore-pi/main.tf +453 -0
- package/dist/terraform/modules/app/agentcore-pi/outputs.tf +38 -0
- package/dist/terraform/modules/app/agentcore-pi/variables.tf +145 -0
- package/dist/terraform/modules/app/agentcore-platform/main.tf +83 -0
- package/dist/terraform/modules/app/agentcore-runtime/main.tf +9 -11
- package/dist/terraform/modules/app/appsync-subscriptions/main.tf +5 -1
- package/dist/terraform/modules/app/customer-domain/main.tf +483 -0
- package/dist/terraform/modules/app/deployment-control-plane/README.md +47 -0
- package/dist/terraform/modules/app/deployment-control-plane/buildspec.yml +24 -0
- package/dist/terraform/modules/app/deployment-control-plane/main.tf +614 -0
- package/dist/terraform/modules/app/deployment-control-plane/outputs.tf +54 -0
- package/dist/terraform/modules/app/deployment-control-plane/runner.py +4720 -0
- package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +3026 -0
- package/dist/terraform/modules/app/deployment-control-plane/variables.tf +96 -0
- package/dist/terraform/modules/app/hindsight-memory/README.md +25 -23
- package/dist/terraform/modules/app/hindsight-memory/main.tf +26 -2
- package/dist/terraform/modules/app/lambda-api/eval-fanout.tf +17 -50
- package/dist/terraform/modules/app/lambda-api/handlers.tf +1290 -679
- package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +933 -0
- package/dist/terraform/modules/app/lambda-api/main.tf +14 -527
- package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +3 -19
- package/dist/terraform/modules/app/lambda-api/outputs.tf +50 -6
- package/dist/terraform/modules/app/lambda-api/runtime-config.tf +163 -0
- package/dist/terraform/modules/app/lambda-api/slack-app-secrets.tf +3 -1
- package/dist/terraform/modules/app/lambda-api/stripe-secrets.tf +3 -1
- package/dist/terraform/modules/app/lambda-api/variables.tf +240 -53
- package/dist/terraform/modules/app/lambda-api/workspace-events.tf +2 -25
- package/dist/terraform/modules/app/ses-email/main.tf +143 -30
- package/dist/terraform/modules/app/static-site/main.tf +4 -3
- package/dist/terraform/modules/app/www-dns/main.tf +45 -5
- package/dist/terraform/modules/app/www-dns/outputs.tf +10 -0
- package/dist/terraform/modules/app/www-dns/variables.tf +24 -0
- package/dist/terraform/modules/data/aurora-postgres/main.tf +15 -1
- package/dist/terraform/modules/data/compliance-exports-bucket/main.tf +1 -1
- package/dist/terraform/modules/data/compliance-exports-bucket/variables.tf +6 -0
- package/dist/terraform/modules/foundation/cognito/main.tf +167 -11
- package/dist/terraform/modules/foundation/cognito/outputs.tf +5 -0
- package/dist/terraform/modules/foundation/cognito/variables.tf +110 -0
- package/dist/terraform/modules/foundation/vpc/main.tf +45 -3
- package/dist/terraform/modules/foundation/vpc/outputs.tf +20 -0
- package/dist/terraform/modules/foundation/vpc/variables.tf +18 -0
- package/dist/terraform/modules/thinkwork/README.md +71 -0
- package/dist/terraform/modules/thinkwork/main.tf +1325 -174
- package/dist/terraform/modules/thinkwork/outputs.tf +457 -24
- package/dist/terraform/modules/thinkwork/variables.tf +1169 -93
- package/dist/terraform/schema.graphql +82 -9
- package/dist/workspace-defaults/files/AGENTS.md +344 -0
- package/dist/workspace-defaults/files/CONTEXT.md +8 -0
- package/dist/workspace-defaults/files/GUARDRAILS.md +51 -0
- package/dist/workspace-defaults/files/MEMORY_GUIDE.md +65 -0
- package/dist/workspace-defaults/files/ROUTER.md +24 -0
- package/dist/workspace-defaults/files/SPACE.md +62 -0
- package/dist/workspace-defaults/files/TOOLS.md +65 -0
- package/dist/workspace-defaults/files/USER.md +40 -0
- package/dist/workspace-defaults/files/mcp.json +3 -0
- package/dist/workspace-defaults/files/memory/contacts.md +13 -0
- package/dist/workspace-defaults/files/memory/lessons.md +13 -0
- package/dist/workspace-defaults/files/memory/preferences.md +12 -0
- package/dist/workspace-defaults/files/skills/.gitkeep +1 -0
- package/dist/workspace-defaults/files/skills/artifact-builder/SKILL.md +79 -0
- package/dist/workspace-defaults/files/skills/artifact-builder/references/crm-dashboard.md +166 -0
- package/dist/workspace-defaults/files/skills/automation-loop-designer/SKILL.md +120 -0
- package/dist/workspace-defaults/files/skills/skill-creator/LICENSE.txt +202 -0
- package/dist/workspace-defaults/files/skills/skill-creator/SKILL.md +485 -0
- package/dist/workspace-defaults/files/skills/skill-creator/UPSTREAM.json +124 -0
- package/dist/workspace-defaults/files/skills/skill-creator/agents/analyzer.md +274 -0
- package/dist/workspace-defaults/files/skills/skill-creator/agents/comparator.md +202 -0
- package/dist/workspace-defaults/files/skills/skill-creator/agents/grader.md +223 -0
- package/dist/workspace-defaults/files/skills/skill-creator/assets/eval_review.html +146 -0
- package/dist/workspace-defaults/files/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/dist/workspace-defaults/files/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/dist/workspace-defaults/files/skills/skill-creator/references/schemas.md +430 -0
- package/dist/workspace-defaults/files/skills/skill-creator/scripts/__init__.py +0 -0
- package/dist/workspace-defaults/files/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/dist/workspace-defaults/files/skills/skill-creator/scripts/generate_report.py +326 -0
- package/dist/workspace-defaults/files/skills/skill-creator/scripts/improve_description.py +247 -0
- package/dist/workspace-defaults/files/skills/skill-creator/scripts/package_skill.py +136 -0
- package/dist/workspace-defaults/files/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/dist/workspace-defaults/files/skills/skill-creator/scripts/run_eval.py +310 -0
- package/dist/workspace-defaults/files/skills/skill-creator/scripts/run_loop.py +328 -0
- package/dist/workspace-defaults/files/skills/skill-creator/scripts/utils.py +47 -0
- package/package.json +1 -1
- package/dist/terraform/modules/app/agentcore-flue/README.md +0 -58
- package/dist/terraform/modules/app/agentcore-flue/main.tf +0 -323
- package/dist/terraform/modules/app/agentcore-flue/outputs.tf +0 -23
- package/dist/terraform/modules/app/agentcore-flue/variables.tf +0 -97
- package/dist/terraform/modules/app/computer-runtime/README.md +0 -15
- package/dist/terraform/modules/app/computer-runtime/main.tf +0 -406
- package/dist/terraform/modules/app/computer-runtime/outputs.tf +0 -75
- package/dist/terraform/modules/app/computer-runtime/variables.tf +0 -66
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ thinkwork plan -s dev
|
|
|
38
38
|
# 5. Deploy (~5 min)
|
|
39
39
|
thinkwork deploy -s dev
|
|
40
40
|
|
|
41
|
-
# 6. Seed workspace files
|
|
41
|
+
# 6. Seed workspace files
|
|
42
42
|
thinkwork bootstrap -s dev
|
|
43
43
|
|
|
44
44
|
# 7. Show what was deployed
|
|
@@ -66,36 +66,40 @@ No repo clone required — `thinkwork init` scaffolds all Terraform modules from
|
|
|
66
66
|
|
|
67
67
|
### Setup
|
|
68
68
|
|
|
69
|
-
| Command
|
|
70
|
-
|
|
71
|
-
| `thinkwork login`
|
|
72
|
-
| `thinkwork login --stage <s>`
|
|
73
|
-
| `thinkwork login --stage <s> --api-key <secret>` | Non-interactive CI path; stores the api_auth_secret as the session
|
|
74
|
-
| `thinkwork logout [--stage <s> \| --all]`
|
|
75
|
-
| `thinkwork me [--stage <s>]`
|
|
76
|
-
| `thinkwork init -s <stage>`
|
|
77
|
-
| `thinkwork doctor -s <stage>`
|
|
69
|
+
| Command | Description |
|
|
70
|
+
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| `thinkwork login` | Configure AWS credentials (access keys or `--sso`) |
|
|
72
|
+
| `thinkwork login --stage <s>` | Sign in to a deployed stack via Cognito (OAuth; Google supported). Caches tokens in `~/.thinkwork/config.json` |
|
|
73
|
+
| `thinkwork login --stage <s> --api-key <secret>` | Non-interactive CI path; stores the api_auth_secret as the session |
|
|
74
|
+
| `thinkwork logout [--stage <s> \| --all]` | Forget stored sessions |
|
|
75
|
+
| `thinkwork me [--stage <s>]` | Print who you're signed in as on a stage (verifies via a live `me` query) |
|
|
76
|
+
| `thinkwork init -s <stage>` | Initialize a new environment — generates terraform.tfvars, scaffolds Terraform modules, runs `terraform init` |
|
|
77
|
+
| `thinkwork doctor -s <stage>` | Check prerequisites (AWS CLI, Terraform, credentials, Bedrock access) |
|
|
78
78
|
|
|
79
79
|
### Deploy
|
|
80
80
|
|
|
81
|
-
| Command
|
|
82
|
-
|
|
83
|
-
| `thinkwork plan -s <stage>`
|
|
84
|
-
| `thinkwork deploy -s <stage>`
|
|
85
|
-
| `thinkwork
|
|
86
|
-
| `thinkwork
|
|
81
|
+
| Command | Description |
|
|
82
|
+
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
83
|
+
| `thinkwork plan -s <stage>` | Preview infrastructure changes |
|
|
84
|
+
| `thinkwork deploy -s <stage>` | Full deploy pipeline: preflight checks → terraform apply → release artifacts → schema migrations → post-deploy verification. Reruns converge from any partial failure. |
|
|
85
|
+
| `thinkwork verify -s <stage>` | Prove a deployed stage works: GraphQL, authenticated call, web, database schema, Hindsight, seeding, deployed-artifact evidence, pending-approvals checklist |
|
|
86
|
+
| `thinkwork bootstrap -s <stage>` | Seed workspace defaults and per-tenant workspace files |
|
|
87
|
+
| `thinkwork destroy -s <stage>` | Tear down to a redeployable clean slate: buckets pre-emptied (all versions), bounded retry, lingering secrets force-deleted, orphan scan |
|
|
88
|
+
|
|
89
|
+
`deploy` details: preflight runs the `doctor` check registry (credentials + expiry margin, Bedrock invocation, Lambda quota, state backend, domain DNS delegation) and reports **all** blockers before any resource is created (`--skip-preflight` to bypass). Init-scaffolded environments get a per-account Terraform state backend (versioned, encrypted S3 + DynamoDB locking) and deploy a pinned ThinkWork release (`--release-version <tag>` to override). SES production access pending approval never blocks — it's tracked as a checklist item. A stale state lock from an interrupted run gets guided recovery on the next deploy.
|
|
87
90
|
|
|
88
91
|
### Manage
|
|
89
92
|
|
|
90
|
-
| Command
|
|
91
|
-
|
|
92
|
-
| `thinkwork status`
|
|
93
|
-
| `thinkwork status -s <stage>`
|
|
94
|
-
| `thinkwork outputs -s <stage>`
|
|
95
|
-
| `thinkwork config list`
|
|
96
|
-
| `thinkwork config list -s <stage>`
|
|
97
|
-
| `thinkwork config get <key> -s <stage>`
|
|
98
|
-
| `thinkwork config set <key> <value> -s <stage>` | Update a configuration value
|
|
93
|
+
| Command | Description |
|
|
94
|
+
| ----------------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
95
|
+
| `thinkwork status` | Discover all deployed environments in AWS (clickable URLs) |
|
|
96
|
+
| `thinkwork status -s <stage>` | Detailed view for one environment |
|
|
97
|
+
| `thinkwork outputs -s <stage>` | Show deployment outputs (API URL, Cognito IDs, etc.) |
|
|
98
|
+
| `thinkwork config list` | List all initialized environments |
|
|
99
|
+
| `thinkwork config list -s <stage>` | Show full config for an environment (secrets masked) |
|
|
100
|
+
| `thinkwork config get <key> -s <stage>` | Read a configuration value |
|
|
101
|
+
| `thinkwork config set <key> <value> -s <stage>` | Update a configuration value |
|
|
102
|
+
| `thinkwork config graduate <stage>` | Mark a stage as a graduated persistent environment (arms destroy's strongest guard) |
|
|
99
103
|
|
|
100
104
|
### Wiki (Compounding Memory)
|
|
101
105
|
|
|
@@ -103,11 +107,11 @@ Admin-only. Operator controls for the wiki compile pipeline — kick a compile,
|
|
|
103
107
|
rebuild from scratch, or inspect recent compile jobs without leaving the
|
|
104
108
|
terminal.
|
|
105
109
|
|
|
106
|
-
| Command
|
|
107
|
-
|
|
108
|
-
| `thinkwork wiki compile`
|
|
109
|
-
| `thinkwork wiki rebuild --agent <id>` | Destructive: archive the agent's active pages, clear the compile cursor, and enqueue a fresh compile. Confirm unless `--yes`. `--all` is intentionally rejected.
|
|
110
|
-
| `thinkwork wiki status`
|
|
110
|
+
| Command | Description |
|
|
111
|
+
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
112
|
+
| `thinkwork wiki compile` | Enqueue a compile for one agent (`--agent`) or every tenant agent (`--all`). `--model <id>` spikes a non-default Bedrock model for one run. `--watch` follows the job (single-agent only). |
|
|
113
|
+
| `thinkwork wiki rebuild --agent <id>` | Destructive: archive the agent's active pages, clear the compile cursor, and enqueue a fresh compile. Confirm unless `--yes`. `--all` is intentionally rejected. |
|
|
114
|
+
| `thinkwork wiki status` | Show recent compile jobs for a tenant. `--agent <id>` restricts to one scope. `--watch` polls until the latest job reaches a terminal state. |
|
|
111
115
|
|
|
112
116
|
Requires admin credentials (api-key session, or an admin-promoted tenant
|
|
113
117
|
membership). Cognito end-user sessions see a clear "admin access required"
|
|
@@ -142,14 +146,14 @@ Any flag accepted by a command is also inferrable from env vars:
|
|
|
142
146
|
All 25 originally-scaffolded commands across Phases 1–5 are now live.
|
|
143
147
|
`thinkwork <cmd> --help` is authoritative for flags + examples.
|
|
144
148
|
|
|
145
|
-
| Phase | Domain
|
|
146
|
-
|
|
147
|
-
| 0
|
|
148
|
-
| 1
|
|
149
|
-
| 2
|
|
150
|
-
| 3
|
|
151
|
-
| 4
|
|
152
|
-
| 5
|
|
149
|
+
| Phase | Domain | Commands |
|
|
150
|
+
| ----- | ------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
151
|
+
| 0 | Foundation | `login` (chains AWS profile + Cognito API session), `logout`, `me`, `--json`, GraphQL client, codegen, shared helpers |
|
|
152
|
+
| 1 | Work & approvals | `thread`, `message`, `label`, `inbox` |
|
|
153
|
+
| 2 | Agents & workspace | `member`, `team`, `kb`, `template`, `tenant`, `agent` |
|
|
154
|
+
| 3 | Automation & integrations | `routine`, `scheduled-job`, `turn`, `wakeup`, `webhook`, `skill` (`connector` retired) |
|
|
155
|
+
| 4 | Memory & artifacts | `memory`, `recipe`, `artifact` |
|
|
156
|
+
| 5 | Observability & spend | `cost`, `budget`, `performance`, `trace`, `dashboard` |
|
|
153
157
|
|
|
154
158
|
`skill create` and `skill update` were retired in favor of
|
|
155
159
|
`thinkwork skill push <folder>` — that's the real custom-skill authoring
|
|
@@ -5,7 +5,7 @@ var __export = (target, all) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/api-client.ts
|
|
8
|
-
import { readFileSync as
|
|
8
|
+
import { readFileSync as readFileSync3, existsSync as existsSync4 } from "fs";
|
|
9
9
|
import { execSync as execSync2 } from "child_process";
|
|
10
10
|
|
|
11
11
|
// src/environments.ts
|
|
@@ -77,26 +77,271 @@ function resolveTerraformDir(stage) {
|
|
|
77
77
|
|
|
78
78
|
// src/terraform.ts
|
|
79
79
|
import { spawn } from "child_process";
|
|
80
|
-
import { existsSync as
|
|
80
|
+
import { existsSync as existsSync3 } from "fs";
|
|
81
|
+
import path2 from "path";
|
|
82
|
+
|
|
83
|
+
// src/lib/state-backend.ts
|
|
84
|
+
import { spawnSync } from "child_process";
|
|
85
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync as readdirSync2 } from "fs";
|
|
81
86
|
import path from "path";
|
|
87
|
+
var NONCURRENT_VERSION_RETENTION_DAYS = 90;
|
|
88
|
+
function defaultExec(args) {
|
|
89
|
+
const proc = spawnSync("aws", args, { encoding: "utf8" });
|
|
90
|
+
return {
|
|
91
|
+
status: proc.status ?? 1,
|
|
92
|
+
stdout: proc.stdout ?? "",
|
|
93
|
+
stderr: proc.stderr ?? ""
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function backendResourceNames(accountId) {
|
|
97
|
+
return {
|
|
98
|
+
bucket: `thinkwork-tfstate-${accountId}`,
|
|
99
|
+
lockTable: `thinkwork-tflocks-${accountId}`
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function backendKey(stage) {
|
|
103
|
+
return `thinkwork/${stage}/terraform.tfstate`;
|
|
104
|
+
}
|
|
105
|
+
function backendTarget(accountId, region, stage) {
|
|
106
|
+
const names = backendResourceNames(accountId);
|
|
107
|
+
return {
|
|
108
|
+
bucket: names.bucket,
|
|
109
|
+
lockTable: names.lockTable,
|
|
110
|
+
key: backendKey(stage),
|
|
111
|
+
region
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function backendConfigArgs(target) {
|
|
115
|
+
return [
|
|
116
|
+
`-backend-config=bucket=${target.bucket}`,
|
|
117
|
+
`-backend-config=key=${target.key}`,
|
|
118
|
+
`-backend-config=region=${target.region}`,
|
|
119
|
+
`-backend-config=dynamodb_table=${target.lockTable}`,
|
|
120
|
+
`-backend-config=encrypt=true`
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
function ensureStateBackend(accountId, region, stage, exec = defaultExec) {
|
|
124
|
+
const target = backendTarget(accountId, region, stage);
|
|
125
|
+
const head = exec(["s3api", "head-bucket", "--bucket", target.bucket]);
|
|
126
|
+
let createdBucket = false;
|
|
127
|
+
if (head.status !== 0) {
|
|
128
|
+
const createArgs = [
|
|
129
|
+
"s3api",
|
|
130
|
+
"create-bucket",
|
|
131
|
+
"--bucket",
|
|
132
|
+
target.bucket,
|
|
133
|
+
"--region",
|
|
134
|
+
region
|
|
135
|
+
];
|
|
136
|
+
if (region !== "us-east-1") {
|
|
137
|
+
createArgs.push(
|
|
138
|
+
"--create-bucket-configuration",
|
|
139
|
+
`LocationConstraint=${region}`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
const created = exec(createArgs);
|
|
143
|
+
if (created.status !== 0) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
`Could not create state bucket ${target.bucket}: ${created.stderr.trim()}`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
createdBucket = true;
|
|
149
|
+
}
|
|
150
|
+
const hardening = [
|
|
151
|
+
[
|
|
152
|
+
"s3api",
|
|
153
|
+
"put-bucket-versioning",
|
|
154
|
+
"--bucket",
|
|
155
|
+
target.bucket,
|
|
156
|
+
"--versioning-configuration",
|
|
157
|
+
"Status=Enabled"
|
|
158
|
+
],
|
|
159
|
+
[
|
|
160
|
+
"s3api",
|
|
161
|
+
"put-bucket-encryption",
|
|
162
|
+
"--bucket",
|
|
163
|
+
target.bucket,
|
|
164
|
+
"--server-side-encryption-configuration",
|
|
165
|
+
'{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'
|
|
166
|
+
],
|
|
167
|
+
[
|
|
168
|
+
"s3api",
|
|
169
|
+
"put-public-access-block",
|
|
170
|
+
"--bucket",
|
|
171
|
+
target.bucket,
|
|
172
|
+
"--public-access-block-configuration",
|
|
173
|
+
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
|
|
174
|
+
],
|
|
175
|
+
[
|
|
176
|
+
"s3api",
|
|
177
|
+
"put-bucket-lifecycle-configuration",
|
|
178
|
+
"--bucket",
|
|
179
|
+
target.bucket,
|
|
180
|
+
"--lifecycle-configuration",
|
|
181
|
+
JSON.stringify({
|
|
182
|
+
Rules: [
|
|
183
|
+
{
|
|
184
|
+
ID: "expire-noncurrent-state-versions",
|
|
185
|
+
Status: "Enabled",
|
|
186
|
+
Filter: {},
|
|
187
|
+
NoncurrentVersionExpiration: {
|
|
188
|
+
NoncurrentDays: NONCURRENT_VERSION_RETENTION_DAYS
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
})
|
|
193
|
+
]
|
|
194
|
+
];
|
|
195
|
+
for (const args of hardening) {
|
|
196
|
+
const res = exec(args);
|
|
197
|
+
if (res.status !== 0) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
`Could not apply ${args[1]} to ${target.bucket}: ${res.stderr.trim()}`
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const describe = exec([
|
|
204
|
+
"dynamodb",
|
|
205
|
+
"describe-table",
|
|
206
|
+
"--table-name",
|
|
207
|
+
target.lockTable,
|
|
208
|
+
"--region",
|
|
209
|
+
region
|
|
210
|
+
]);
|
|
211
|
+
let createdLockTable = false;
|
|
212
|
+
if (describe.status !== 0) {
|
|
213
|
+
const created = exec([
|
|
214
|
+
"dynamodb",
|
|
215
|
+
"create-table",
|
|
216
|
+
"--table-name",
|
|
217
|
+
target.lockTable,
|
|
218
|
+
"--attribute-definitions",
|
|
219
|
+
"AttributeName=LockID,AttributeType=S",
|
|
220
|
+
"--key-schema",
|
|
221
|
+
"AttributeName=LockID,KeyType=HASH",
|
|
222
|
+
"--billing-mode",
|
|
223
|
+
"PAY_PER_REQUEST",
|
|
224
|
+
"--region",
|
|
225
|
+
region
|
|
226
|
+
]);
|
|
227
|
+
if (created.status !== 0) {
|
|
228
|
+
throw new Error(
|
|
229
|
+
`Could not create lock table ${target.lockTable}: ${created.stderr.trim()}`
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
createdLockTable = true;
|
|
233
|
+
}
|
|
234
|
+
return { target, createdBucket, createdLockTable };
|
|
235
|
+
}
|
|
236
|
+
function readRecordedBackend(cwd) {
|
|
237
|
+
const recordPath = path.join(cwd, ".terraform", "terraform.tfstate");
|
|
238
|
+
if (!existsSync2(recordPath)) return null;
|
|
239
|
+
try {
|
|
240
|
+
const parsed = JSON.parse(readFileSync2(recordPath, "utf8"));
|
|
241
|
+
if (!parsed.backend?.type) return null;
|
|
242
|
+
const config = parsed.backend.config ?? {};
|
|
243
|
+
return {
|
|
244
|
+
type: parsed.backend.type,
|
|
245
|
+
bucket: config.bucket,
|
|
246
|
+
key: config.key,
|
|
247
|
+
region: config.region,
|
|
248
|
+
dynamodb_table: config.dynamodb_table
|
|
249
|
+
};
|
|
250
|
+
} catch {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function backendMatches(recorded, target) {
|
|
255
|
+
return recorded !== null && recorded.type === "s3" && recorded.bucket === target.bucket && recorded.key === target.key && recorded.dynamodb_table === target.lockTable;
|
|
256
|
+
}
|
|
257
|
+
function detectLocalStateOrphanRisk(cwd) {
|
|
258
|
+
const candidates = [path.join(cwd, "terraform.tfstate")];
|
|
259
|
+
const workspaceDir = path.join(cwd, "terraform.tfstate.d");
|
|
260
|
+
if (existsSync2(workspaceDir)) {
|
|
261
|
+
try {
|
|
262
|
+
for (const ws of readdirSync2(workspaceDir)) {
|
|
263
|
+
candidates.push(path.join(workspaceDir, ws, "terraform.tfstate"));
|
|
264
|
+
}
|
|
265
|
+
} catch {
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
for (const candidate of candidates) {
|
|
269
|
+
if (!existsSync2(candidate)) continue;
|
|
270
|
+
try {
|
|
271
|
+
const parsed = JSON.parse(readFileSync2(candidate, "utf8"));
|
|
272
|
+
if ((parsed.resources?.length ?? 0) > 0) return true;
|
|
273
|
+
} catch {
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
function parseLockError(text) {
|
|
280
|
+
if (!/Error acquiring the state lock/i.test(text)) return null;
|
|
281
|
+
const field = (name) => {
|
|
282
|
+
const match = text.match(
|
|
283
|
+
new RegExp(`(?:^|[^A-Za-z])${name}:\\s*(.+)`, "i")
|
|
284
|
+
);
|
|
285
|
+
return match?.[1]?.replace(/[│,]/g, " ").trim();
|
|
286
|
+
};
|
|
287
|
+
const rawId = field("ID");
|
|
288
|
+
return {
|
|
289
|
+
id: rawId?.split(/\s+/)[0],
|
|
290
|
+
who: field("Who"),
|
|
291
|
+
operation: field("Operation"),
|
|
292
|
+
created: field("Created")
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/terraform.ts
|
|
297
|
+
function resolveTerraformRoot(startDir = process.cwd()) {
|
|
298
|
+
const configured = process.env.THINKWORK_TERRAFORM_DIR;
|
|
299
|
+
if (configured) return configured;
|
|
300
|
+
let current = path2.resolve(startDir);
|
|
301
|
+
while (true) {
|
|
302
|
+
if (isTerraformRoot(current)) return current;
|
|
303
|
+
const nestedTerraform = path2.join(current, "terraform");
|
|
304
|
+
if (isTerraformRoot(nestedTerraform)) return nestedTerraform;
|
|
305
|
+
const parent = path2.dirname(current);
|
|
306
|
+
if (parent === current) return path2.resolve(startDir);
|
|
307
|
+
current = parent;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function isTerraformRoot(dir) {
|
|
311
|
+
return existsSync3(path2.join(dir, "examples", "greenfield")) || existsSync3(path2.join(dir, "environments")) || existsSync3(path2.join(dir, "main.tf"));
|
|
312
|
+
}
|
|
82
313
|
function resolveTierDir(terraformDir, stage, tier) {
|
|
83
|
-
const envDir =
|
|
84
|
-
if (
|
|
314
|
+
const envDir = path2.join(terraformDir, "environments", stage, tier);
|
|
315
|
+
if (existsSync3(envDir)) {
|
|
85
316
|
return envDir;
|
|
86
317
|
}
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
318
|
+
const flat = path2.join(terraformDir);
|
|
319
|
+
if (existsSync3(path2.join(flat, "main.tf")) && existsSync3(path2.join(flat, "terraform.tfvars"))) {
|
|
320
|
+
return flat;
|
|
321
|
+
}
|
|
322
|
+
const greenfield = path2.join(terraformDir, "examples", "greenfield");
|
|
323
|
+
if (existsSync3(greenfield)) {
|
|
89
324
|
return greenfield;
|
|
90
325
|
}
|
|
91
|
-
|
|
92
|
-
if (existsSync2(path.join(flat, "main.tf"))) {
|
|
326
|
+
if (existsSync3(path2.join(flat, "main.tf"))) {
|
|
93
327
|
return flat;
|
|
94
328
|
}
|
|
95
|
-
const cwdTf =
|
|
96
|
-
if (
|
|
329
|
+
const cwdTf = path2.join(process.cwd(), "terraform");
|
|
330
|
+
if (existsSync3(path2.join(cwdTf, "main.tf"))) {
|
|
97
331
|
return cwdTf;
|
|
98
332
|
}
|
|
99
|
-
|
|
333
|
+
throw new Error(
|
|
334
|
+
`No Terraform layout found for stage "${stage}" (tier "${tier}").
|
|
335
|
+
Looked for:
|
|
336
|
+
- ${envDir}
|
|
337
|
+
- ${greenfield}
|
|
338
|
+
- ${path2.join(flat, "main.tf")}
|
|
339
|
+
- ${path2.join(cwdTf, "main.tf")}
|
|
340
|
+
Run \`thinkwork init -s ${stage}\` to scaffold an environment, or run from its directory.`
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
function isInitScaffoldedLayout(cwd) {
|
|
344
|
+
return existsSync3(path2.join(cwd, "main.tf")) && !cwd.endsWith(path2.join("examples", "greenfield")) && existsSync3(path2.join(cwd, "modules"));
|
|
100
345
|
}
|
|
101
346
|
async function ensureWorkspace(cwd, stage) {
|
|
102
347
|
const list = await runTerraformRaw(cwd, ["workspace", "list"]);
|
|
@@ -119,7 +364,12 @@ function runTerraformRaw(cwd, args) {
|
|
|
119
364
|
proc.stderr.on("data", (d) => stderr += d);
|
|
120
365
|
proc.on("close", (code) => {
|
|
121
366
|
if (code === 0) resolve(stdout);
|
|
122
|
-
else
|
|
367
|
+
else
|
|
368
|
+
reject(
|
|
369
|
+
new Error(
|
|
370
|
+
`terraform ${args.join(" ")} failed (exit ${code}): ${stderr}`
|
|
371
|
+
)
|
|
372
|
+
);
|
|
123
373
|
});
|
|
124
374
|
});
|
|
125
375
|
}
|
|
@@ -135,14 +385,62 @@ function runTerraform(cwd, args) {
|
|
|
135
385
|
proc.on("close", (code) => resolve(code ?? 1));
|
|
136
386
|
});
|
|
137
387
|
}
|
|
138
|
-
async function ensureInit(cwd) {
|
|
139
|
-
const dotTerraform =
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
388
|
+
async function ensureInit(cwd, backend) {
|
|
389
|
+
const dotTerraform = path2.join(cwd, ".terraform");
|
|
390
|
+
const backendArgs = backend ? backendConfigArgs(backend) : [];
|
|
391
|
+
if (!existsSync3(dotTerraform)) {
|
|
392
|
+
const code2 = await runTerraform(cwd, ["init", ...backendArgs]);
|
|
393
|
+
if (code2 !== 0) {
|
|
143
394
|
throw new Error("terraform init failed");
|
|
144
395
|
}
|
|
396
|
+
return;
|
|
145
397
|
}
|
|
398
|
+
if (!backend) return;
|
|
399
|
+
const recorded = readRecordedBackend(cwd);
|
|
400
|
+
if (backendMatches(recorded, backend)) return;
|
|
401
|
+
if (detectLocalStateOrphanRisk(cwd)) {
|
|
402
|
+
throw new Error(
|
|
403
|
+
`This directory has local Terraform state with resources, but the deploy now targets the remote backend s3://${backend.bucket}/${backend.key}.
|
|
404
|
+
Switching with -reconfigure would orphan that state. Migrate it first:
|
|
405
|
+
terraform init -migrate-state ${backendConfigArgs(backend).join(" ")}
|
|
406
|
+
(run inside ${cwd})`
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
console.log(
|
|
410
|
+
` Backend changed (recorded: ${recorded ? `${recorded.type}${recorded.bucket ? ` s3://${recorded.bucket}/${recorded.key}` : ""}` : "none"} \u2192 s3://${backend.bucket}/${backend.key}); re-running terraform init -reconfigure`
|
|
411
|
+
);
|
|
412
|
+
const code = await runTerraform(cwd, [
|
|
413
|
+
"init",
|
|
414
|
+
"-reconfigure",
|
|
415
|
+
...backendArgs
|
|
416
|
+
]);
|
|
417
|
+
if (code !== 0) {
|
|
418
|
+
throw new Error("terraform init -reconfigure failed");
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
function terraformOutput(cwd, key) {
|
|
422
|
+
return runTerraformRaw(cwd, ["output", "-raw", key]).then((v) => v.trim());
|
|
423
|
+
}
|
|
424
|
+
function runTerraformTee(cwd, args) {
|
|
425
|
+
return new Promise((resolve) => {
|
|
426
|
+
console.log(`
|
|
427
|
+
\u2192 terraform ${args.join(" ")}
|
|
428
|
+
`);
|
|
429
|
+
const proc = spawn("terraform", args, {
|
|
430
|
+
cwd,
|
|
431
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
432
|
+
});
|
|
433
|
+
let output = "";
|
|
434
|
+
proc.stdout.on("data", (d) => {
|
|
435
|
+
output += d.toString();
|
|
436
|
+
process.stdout.write(d);
|
|
437
|
+
});
|
|
438
|
+
proc.stderr.on("data", (d) => {
|
|
439
|
+
output += d.toString();
|
|
440
|
+
process.stderr.write(d);
|
|
441
|
+
});
|
|
442
|
+
proc.on("close", (code) => resolve({ code: code ?? 1, output }));
|
|
443
|
+
});
|
|
146
444
|
}
|
|
147
445
|
|
|
148
446
|
// src/aws-discovery.ts
|
|
@@ -225,7 +523,11 @@ function printHeader(command, stage, identity) {
|
|
|
225
523
|
console.log(chalk.bold.cyan(" \u2B21 Thinkwork") + chalk.dim(` \u2014 ${command}`));
|
|
226
524
|
console.log(chalk.dim(` Stage: ${chalk.white(stage)}`));
|
|
227
525
|
if (identity) {
|
|
228
|
-
console.log(
|
|
526
|
+
console.log(
|
|
527
|
+
chalk.dim(
|
|
528
|
+
` AWS: ${chalk.white(identity.account)} / ${chalk.white(identity.region)}`
|
|
529
|
+
)
|
|
530
|
+
);
|
|
229
531
|
}
|
|
230
532
|
console.log("");
|
|
231
533
|
}
|
|
@@ -259,9 +561,7 @@ function printMissingApiSessionError(stage, hasSession) {
|
|
|
259
561
|
console.log("");
|
|
260
562
|
console.log(` ${chalk.bold("To fix:")} thinkwork login --stage ${stage}`);
|
|
261
563
|
console.log(
|
|
262
|
-
chalk.dim(
|
|
263
|
-
` Or pass --tenant <slug>, or set THINKWORK_TENANT.`
|
|
264
|
-
)
|
|
564
|
+
chalk.dim(` Or pass --tenant <slug>, or set THINKWORK_TENANT.`)
|
|
265
565
|
);
|
|
266
566
|
console.log("");
|
|
267
567
|
}
|
|
@@ -275,15 +575,17 @@ function printSummary(command, stage, tiers, startTime) {
|
|
|
275
575
|
console.log(chalk.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
276
576
|
console.log(` ${chalk.bold("Command:")} ${command}`);
|
|
277
577
|
console.log(` ${chalk.bold("Stage:")} ${stage}`);
|
|
278
|
-
console.log(
|
|
578
|
+
console.log(
|
|
579
|
+
` ${chalk.bold("Tiers:")} ${tiers.map((t) => TIER_LABELS[t] ?? t).join(" \u2192 ")}`
|
|
580
|
+
);
|
|
279
581
|
console.log(` ${chalk.bold("Time:")} ${elapsed}s`);
|
|
280
582
|
console.log(chalk.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
281
583
|
}
|
|
282
584
|
|
|
283
585
|
// src/api-client.ts
|
|
284
586
|
function readTfVar(tfvarsPath, key) {
|
|
285
|
-
if (!
|
|
286
|
-
const content =
|
|
587
|
+
if (!existsSync4(tfvarsPath)) return null;
|
|
588
|
+
const content = readFileSync3(tfvarsPath, "utf-8");
|
|
287
589
|
const match = content.match(new RegExp(`^${key}\\s*=\\s*"([^"]*)"`, "m"));
|
|
288
590
|
return match ? match[1] : null;
|
|
289
591
|
}
|
|
@@ -291,9 +593,9 @@ function resolveTfvarsPath(stage) {
|
|
|
291
593
|
const tfDir = resolveTerraformDir(stage);
|
|
292
594
|
if (tfDir) {
|
|
293
595
|
const direct = `${tfDir}/terraform.tfvars`;
|
|
294
|
-
if (
|
|
596
|
+
if (existsSync4(direct)) return direct;
|
|
295
597
|
}
|
|
296
|
-
const terraformDir =
|
|
598
|
+
const terraformDir = resolveTerraformRoot();
|
|
297
599
|
const cwd = resolveTierDir(terraformDir, stage, "app");
|
|
298
600
|
return `${cwd}/terraform.tfvars`;
|
|
299
601
|
}
|
|
@@ -308,8 +610,8 @@ function getApiEndpoint2(stage, region) {
|
|
|
308
610
|
return null;
|
|
309
611
|
}
|
|
310
612
|
}
|
|
311
|
-
async function apiFetch(apiUrl, authSecret,
|
|
312
|
-
const res = await fetch(`${apiUrl}${
|
|
613
|
+
async function apiFetch(apiUrl, authSecret, path3, options = {}, extraHeaders = {}) {
|
|
614
|
+
const res = await fetch(`${apiUrl}${path3}`, {
|
|
313
615
|
...options,
|
|
314
616
|
headers: {
|
|
315
617
|
"Content-Type": "application/json",
|
|
@@ -324,8 +626,8 @@ async function apiFetch(apiUrl, authSecret, path2, options = {}, extraHeaders =
|
|
|
324
626
|
}
|
|
325
627
|
return res.json();
|
|
326
628
|
}
|
|
327
|
-
async function apiFetchRaw(apiUrl, authSecret,
|
|
328
|
-
const res = await fetch(`${apiUrl}${
|
|
629
|
+
async function apiFetchRaw(apiUrl, authSecret, path3, options = {}, extraHeaders = {}) {
|
|
630
|
+
const res = await fetch(`${apiUrl}${path3}`, {
|
|
329
631
|
...options,
|
|
330
632
|
headers: {
|
|
331
633
|
"Content-Type": "application/json",
|
|
@@ -361,10 +663,18 @@ function resolveApiConfig(stage, regionOverride) {
|
|
|
361
663
|
|
|
362
664
|
export {
|
|
363
665
|
__export,
|
|
666
|
+
backendTarget,
|
|
667
|
+
backendConfigArgs,
|
|
668
|
+
ensureStateBackend,
|
|
669
|
+
parseLockError,
|
|
670
|
+
resolveTerraformRoot,
|
|
364
671
|
resolveTierDir,
|
|
672
|
+
isInitScaffoldedLayout,
|
|
365
673
|
ensureWorkspace,
|
|
366
674
|
runTerraform,
|
|
367
675
|
ensureInit,
|
|
676
|
+
terraformOutput,
|
|
677
|
+
runTerraformTee,
|
|
368
678
|
printHeader,
|
|
369
679
|
printTierHeader,
|
|
370
680
|
printSuccess,
|