thinkwork-cli 0.12.12 → 0.12.16
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-JUBCQQDF.js} +1 -1
- package/dist/{chunk-JEHV35EU.js → chunk-STY44FQO.js} +353 -30
- package/dist/cli.js +23823 -10151
- 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/0197_rcm_context_columns.sql +28 -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 +466 -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 +2 -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,283 @@ 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
|
+
}
|
|
313
|
+
function resolveTerraformRootForStage(stage, recordedDir, startDir = process.cwd()) {
|
|
314
|
+
const cwdRoot = resolveTerraformRoot(startDir);
|
|
315
|
+
try {
|
|
316
|
+
resolveTierDir(cwdRoot, stage, "app");
|
|
317
|
+
return cwdRoot;
|
|
318
|
+
} catch {
|
|
319
|
+
if (recordedDir && existsSync3(path2.join(recordedDir, "main.tf"))) {
|
|
320
|
+
return recordedDir;
|
|
321
|
+
}
|
|
322
|
+
return cwdRoot;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
82
325
|
function resolveTierDir(terraformDir, stage, tier) {
|
|
83
|
-
const envDir =
|
|
84
|
-
if (
|
|
326
|
+
const envDir = path2.join(terraformDir, "environments", stage, tier);
|
|
327
|
+
if (existsSync3(envDir)) {
|
|
85
328
|
return envDir;
|
|
86
329
|
}
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
330
|
+
const flat = path2.join(terraformDir);
|
|
331
|
+
if (existsSync3(path2.join(flat, "main.tf")) && existsSync3(path2.join(flat, "terraform.tfvars"))) {
|
|
332
|
+
return flat;
|
|
333
|
+
}
|
|
334
|
+
const greenfield = path2.join(terraformDir, "examples", "greenfield");
|
|
335
|
+
if (existsSync3(greenfield)) {
|
|
89
336
|
return greenfield;
|
|
90
337
|
}
|
|
91
|
-
|
|
92
|
-
if (existsSync2(path.join(flat, "main.tf"))) {
|
|
338
|
+
if (existsSync3(path2.join(flat, "main.tf"))) {
|
|
93
339
|
return flat;
|
|
94
340
|
}
|
|
95
|
-
const cwdTf =
|
|
96
|
-
if (
|
|
341
|
+
const cwdTf = path2.join(process.cwd(), "terraform");
|
|
342
|
+
if (existsSync3(path2.join(cwdTf, "main.tf"))) {
|
|
97
343
|
return cwdTf;
|
|
98
344
|
}
|
|
99
|
-
|
|
345
|
+
throw new Error(
|
|
346
|
+
`No Terraform layout found for stage "${stage}" (tier "${tier}").
|
|
347
|
+
Looked for:
|
|
348
|
+
- ${envDir}
|
|
349
|
+
- ${greenfield}
|
|
350
|
+
- ${path2.join(flat, "main.tf")}
|
|
351
|
+
- ${path2.join(cwdTf, "main.tf")}
|
|
352
|
+
Run \`thinkwork init -s ${stage}\` to scaffold an environment, or run from its directory.`
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
function isInitScaffoldedLayout(cwd) {
|
|
356
|
+
return existsSync3(path2.join(cwd, "main.tf")) && !cwd.endsWith(path2.join("examples", "greenfield")) && existsSync3(path2.join(cwd, "modules"));
|
|
100
357
|
}
|
|
101
358
|
async function ensureWorkspace(cwd, stage) {
|
|
102
359
|
const list = await runTerraformRaw(cwd, ["workspace", "list"]);
|
|
@@ -119,7 +376,12 @@ function runTerraformRaw(cwd, args) {
|
|
|
119
376
|
proc.stderr.on("data", (d) => stderr += d);
|
|
120
377
|
proc.on("close", (code) => {
|
|
121
378
|
if (code === 0) resolve(stdout);
|
|
122
|
-
else
|
|
379
|
+
else
|
|
380
|
+
reject(
|
|
381
|
+
new Error(
|
|
382
|
+
`terraform ${args.join(" ")} failed (exit ${code}): ${stderr}`
|
|
383
|
+
)
|
|
384
|
+
);
|
|
123
385
|
});
|
|
124
386
|
});
|
|
125
387
|
}
|
|
@@ -135,15 +397,63 @@ function runTerraform(cwd, args) {
|
|
|
135
397
|
proc.on("close", (code) => resolve(code ?? 1));
|
|
136
398
|
});
|
|
137
399
|
}
|
|
138
|
-
async function ensureInit(cwd) {
|
|
139
|
-
const dotTerraform =
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
400
|
+
async function ensureInit(cwd, backend) {
|
|
401
|
+
const dotTerraform = path2.join(cwd, ".terraform");
|
|
402
|
+
const backendArgs = backend ? backendConfigArgs(backend) : [];
|
|
403
|
+
if (!existsSync3(dotTerraform)) {
|
|
404
|
+
const code2 = await runTerraform(cwd, ["init", ...backendArgs]);
|
|
405
|
+
if (code2 !== 0) {
|
|
143
406
|
throw new Error("terraform init failed");
|
|
144
407
|
}
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (!backend) return;
|
|
411
|
+
const recorded = readRecordedBackend(cwd);
|
|
412
|
+
if (backendMatches(recorded, backend)) return;
|
|
413
|
+
if (detectLocalStateOrphanRisk(cwd)) {
|
|
414
|
+
throw new Error(
|
|
415
|
+
`This directory has local Terraform state with resources, but the deploy now targets the remote backend s3://${backend.bucket}/${backend.key}.
|
|
416
|
+
Switching with -reconfigure would orphan that state. Migrate it first:
|
|
417
|
+
terraform init -migrate-state ${backendConfigArgs(backend).join(" ")}
|
|
418
|
+
(run inside ${cwd})`
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
console.log(
|
|
422
|
+
` 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`
|
|
423
|
+
);
|
|
424
|
+
const code = await runTerraform(cwd, [
|
|
425
|
+
"init",
|
|
426
|
+
"-reconfigure",
|
|
427
|
+
...backendArgs
|
|
428
|
+
]);
|
|
429
|
+
if (code !== 0) {
|
|
430
|
+
throw new Error("terraform init -reconfigure failed");
|
|
145
431
|
}
|
|
146
432
|
}
|
|
433
|
+
function terraformOutput(cwd, key) {
|
|
434
|
+
return runTerraformRaw(cwd, ["output", "-raw", key]).then((v) => v.trim());
|
|
435
|
+
}
|
|
436
|
+
function runTerraformTee(cwd, args) {
|
|
437
|
+
return new Promise((resolve) => {
|
|
438
|
+
console.log(`
|
|
439
|
+
\u2192 terraform ${args.join(" ")}
|
|
440
|
+
`);
|
|
441
|
+
const proc = spawn("terraform", args, {
|
|
442
|
+
cwd,
|
|
443
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
444
|
+
});
|
|
445
|
+
let output = "";
|
|
446
|
+
proc.stdout.on("data", (d) => {
|
|
447
|
+
output += d.toString();
|
|
448
|
+
process.stdout.write(d);
|
|
449
|
+
});
|
|
450
|
+
proc.stderr.on("data", (d) => {
|
|
451
|
+
output += d.toString();
|
|
452
|
+
process.stderr.write(d);
|
|
453
|
+
});
|
|
454
|
+
proc.on("close", (code) => resolve({ code: code ?? 1, output }));
|
|
455
|
+
});
|
|
456
|
+
}
|
|
147
457
|
|
|
148
458
|
// src/aws-discovery.ts
|
|
149
459
|
import { execSync } from "child_process";
|
|
@@ -225,7 +535,11 @@ function printHeader(command, stage, identity) {
|
|
|
225
535
|
console.log(chalk.bold.cyan(" \u2B21 Thinkwork") + chalk.dim(` \u2014 ${command}`));
|
|
226
536
|
console.log(chalk.dim(` Stage: ${chalk.white(stage)}`));
|
|
227
537
|
if (identity) {
|
|
228
|
-
console.log(
|
|
538
|
+
console.log(
|
|
539
|
+
chalk.dim(
|
|
540
|
+
` AWS: ${chalk.white(identity.account)} / ${chalk.white(identity.region)}`
|
|
541
|
+
)
|
|
542
|
+
);
|
|
229
543
|
}
|
|
230
544
|
console.log("");
|
|
231
545
|
}
|
|
@@ -259,9 +573,7 @@ function printMissingApiSessionError(stage, hasSession) {
|
|
|
259
573
|
console.log("");
|
|
260
574
|
console.log(` ${chalk.bold("To fix:")} thinkwork login --stage ${stage}`);
|
|
261
575
|
console.log(
|
|
262
|
-
chalk.dim(
|
|
263
|
-
` Or pass --tenant <slug>, or set THINKWORK_TENANT.`
|
|
264
|
-
)
|
|
576
|
+
chalk.dim(` Or pass --tenant <slug>, or set THINKWORK_TENANT.`)
|
|
265
577
|
);
|
|
266
578
|
console.log("");
|
|
267
579
|
}
|
|
@@ -275,15 +587,17 @@ function printSummary(command, stage, tiers, startTime) {
|
|
|
275
587
|
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
588
|
console.log(` ${chalk.bold("Command:")} ${command}`);
|
|
277
589
|
console.log(` ${chalk.bold("Stage:")} ${stage}`);
|
|
278
|
-
console.log(
|
|
590
|
+
console.log(
|
|
591
|
+
` ${chalk.bold("Tiers:")} ${tiers.map((t) => TIER_LABELS[t] ?? t).join(" \u2192 ")}`
|
|
592
|
+
);
|
|
279
593
|
console.log(` ${chalk.bold("Time:")} ${elapsed}s`);
|
|
280
594
|
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
595
|
}
|
|
282
596
|
|
|
283
597
|
// src/api-client.ts
|
|
284
598
|
function readTfVar(tfvarsPath, key) {
|
|
285
|
-
if (!
|
|
286
|
-
const content =
|
|
599
|
+
if (!existsSync4(tfvarsPath)) return null;
|
|
600
|
+
const content = readFileSync3(tfvarsPath, "utf-8");
|
|
287
601
|
const match = content.match(new RegExp(`^${key}\\s*=\\s*"([^"]*)"`, "m"));
|
|
288
602
|
return match ? match[1] : null;
|
|
289
603
|
}
|
|
@@ -291,9 +605,9 @@ function resolveTfvarsPath(stage) {
|
|
|
291
605
|
const tfDir = resolveTerraformDir(stage);
|
|
292
606
|
if (tfDir) {
|
|
293
607
|
const direct = `${tfDir}/terraform.tfvars`;
|
|
294
|
-
if (
|
|
608
|
+
if (existsSync4(direct)) return direct;
|
|
295
609
|
}
|
|
296
|
-
const terraformDir =
|
|
610
|
+
const terraformDir = resolveTerraformRoot();
|
|
297
611
|
const cwd = resolveTierDir(terraformDir, stage, "app");
|
|
298
612
|
return `${cwd}/terraform.tfvars`;
|
|
299
613
|
}
|
|
@@ -308,8 +622,8 @@ function getApiEndpoint2(stage, region) {
|
|
|
308
622
|
return null;
|
|
309
623
|
}
|
|
310
624
|
}
|
|
311
|
-
async function apiFetch(apiUrl, authSecret,
|
|
312
|
-
const res = await fetch(`${apiUrl}${
|
|
625
|
+
async function apiFetch(apiUrl, authSecret, path3, options = {}, extraHeaders = {}) {
|
|
626
|
+
const res = await fetch(`${apiUrl}${path3}`, {
|
|
313
627
|
...options,
|
|
314
628
|
headers: {
|
|
315
629
|
"Content-Type": "application/json",
|
|
@@ -324,8 +638,8 @@ async function apiFetch(apiUrl, authSecret, path2, options = {}, extraHeaders =
|
|
|
324
638
|
}
|
|
325
639
|
return res.json();
|
|
326
640
|
}
|
|
327
|
-
async function apiFetchRaw(apiUrl, authSecret,
|
|
328
|
-
const res = await fetch(`${apiUrl}${
|
|
641
|
+
async function apiFetchRaw(apiUrl, authSecret, path3, options = {}, extraHeaders = {}) {
|
|
642
|
+
const res = await fetch(`${apiUrl}${path3}`, {
|
|
329
643
|
...options,
|
|
330
644
|
headers: {
|
|
331
645
|
"Content-Type": "application/json",
|
|
@@ -361,10 +675,19 @@ function resolveApiConfig(stage, regionOverride) {
|
|
|
361
675
|
|
|
362
676
|
export {
|
|
363
677
|
__export,
|
|
678
|
+
backendTarget,
|
|
679
|
+
backendConfigArgs,
|
|
680
|
+
ensureStateBackend,
|
|
681
|
+
parseLockError,
|
|
682
|
+
resolveTerraformRoot,
|
|
683
|
+
resolveTerraformRootForStage,
|
|
364
684
|
resolveTierDir,
|
|
685
|
+
isInitScaffoldedLayout,
|
|
365
686
|
ensureWorkspace,
|
|
366
687
|
runTerraform,
|
|
367
688
|
ensureInit,
|
|
689
|
+
terraformOutput,
|
|
690
|
+
runTerraformTee,
|
|
368
691
|
printHeader,
|
|
369
692
|
printTierHeader,
|
|
370
693
|
printSuccess,
|