thinkwork-cli 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +197 -61
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -485,19 +485,67 @@ function registerOutputsCommand(program2) {
|
|
|
485
485
|
}
|
|
486
486
|
|
|
487
487
|
// src/commands/config.ts
|
|
488
|
-
import { readFileSync, writeFileSync, existsSync as
|
|
488
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync3 } from "fs";
|
|
489
|
+
import chalk3 from "chalk";
|
|
490
|
+
|
|
491
|
+
// src/environments.ts
|
|
492
|
+
import { existsSync as existsSync2, mkdirSync, writeFileSync, readFileSync, readdirSync } from "fs";
|
|
493
|
+
import { join } from "path";
|
|
494
|
+
import { homedir } from "os";
|
|
495
|
+
var THINKWORK_HOME = join(homedir(), ".thinkwork");
|
|
496
|
+
var ENVIRONMENTS_DIR = join(THINKWORK_HOME, "environments");
|
|
497
|
+
function ensureDir(dir) {
|
|
498
|
+
if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
|
|
499
|
+
}
|
|
500
|
+
function saveEnvironment(config) {
|
|
501
|
+
ensureDir(ENVIRONMENTS_DIR);
|
|
502
|
+
const envDir = join(ENVIRONMENTS_DIR, config.stage);
|
|
503
|
+
ensureDir(envDir);
|
|
504
|
+
writeFileSync(
|
|
505
|
+
join(envDir, "config.json"),
|
|
506
|
+
JSON.stringify(config, null, 2) + "\n"
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
function loadEnvironment(stage) {
|
|
510
|
+
const configPath = join(ENVIRONMENTS_DIR, stage, "config.json");
|
|
511
|
+
if (!existsSync2(configPath)) return null;
|
|
512
|
+
return JSON.parse(readFileSync(configPath, "utf-8"));
|
|
513
|
+
}
|
|
514
|
+
function listEnvironments() {
|
|
515
|
+
if (!existsSync2(ENVIRONMENTS_DIR)) return [];
|
|
516
|
+
return readdirSync(ENVIRONMENTS_DIR).filter((name) => {
|
|
517
|
+
return existsSync2(join(ENVIRONMENTS_DIR, name, "config.json"));
|
|
518
|
+
}).map((name) => {
|
|
519
|
+
return JSON.parse(
|
|
520
|
+
readFileSync(join(ENVIRONMENTS_DIR, name, "config.json"), "utf-8")
|
|
521
|
+
);
|
|
522
|
+
}).sort((a, b) => a.stage.localeCompare(b.stage));
|
|
523
|
+
}
|
|
524
|
+
function resolveTerraformDir(stage) {
|
|
525
|
+
const env = loadEnvironment(stage);
|
|
526
|
+
if (env?.terraformDir && existsSync2(env.terraformDir)) {
|
|
527
|
+
return env.terraformDir;
|
|
528
|
+
}
|
|
529
|
+
const envVar = process.env.THINKWORK_TERRAFORM_DIR;
|
|
530
|
+
if (envVar && existsSync2(envVar)) return envVar;
|
|
531
|
+
const cwdTf = join(process.cwd(), "terraform");
|
|
532
|
+
if (existsSync2(join(cwdTf, "main.tf"))) return cwdTf;
|
|
533
|
+
return null;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// src/commands/config.ts
|
|
489
537
|
var VALID_MEMORY_ENGINES = ["managed", "hindsight"];
|
|
490
538
|
function readTfVar(tfvarsPath, key) {
|
|
491
|
-
if (!
|
|
492
|
-
const content =
|
|
539
|
+
if (!existsSync3(tfvarsPath)) return null;
|
|
540
|
+
const content = readFileSync2(tfvarsPath, "utf-8");
|
|
493
541
|
const match = content.match(new RegExp(`^${key}\\s*=\\s*"([^"]*)"`, "m"));
|
|
494
542
|
return match ? match[1] : null;
|
|
495
543
|
}
|
|
496
544
|
function setTfVar(tfvarsPath, key, value) {
|
|
497
|
-
if (!
|
|
545
|
+
if (!existsSync3(tfvarsPath)) {
|
|
498
546
|
throw new Error(`terraform.tfvars not found at ${tfvarsPath}`);
|
|
499
547
|
}
|
|
500
|
-
let content =
|
|
548
|
+
let content = readFileSync2(tfvarsPath, "utf-8");
|
|
501
549
|
const regex = new RegExp(`^(${key}\\s*=\\s*)"[^"]*"`, "m");
|
|
502
550
|
if (regex.test(content)) {
|
|
503
551
|
content = content.replace(regex, `$1"${value}"`);
|
|
@@ -506,19 +554,93 @@ function setTfVar(tfvarsPath, key, value) {
|
|
|
506
554
|
${key} = "${value}"
|
|
507
555
|
`;
|
|
508
556
|
}
|
|
509
|
-
|
|
557
|
+
writeFileSync2(tfvarsPath, content);
|
|
558
|
+
}
|
|
559
|
+
function resolveTfvarsPath(stage) {
|
|
560
|
+
const tfDir = resolveTerraformDir(stage);
|
|
561
|
+
if (tfDir) {
|
|
562
|
+
const direct = `${tfDir}/terraform.tfvars`;
|
|
563
|
+
if (existsSync3(direct)) return direct;
|
|
564
|
+
}
|
|
565
|
+
const terraformDir = process.env.THINKWORK_TERRAFORM_DIR || process.cwd();
|
|
566
|
+
const cwd = resolveTierDir(terraformDir, stage, "app");
|
|
567
|
+
return `${cwd}/terraform.tfvars`;
|
|
510
568
|
}
|
|
511
569
|
function registerConfigCommand(program2) {
|
|
512
570
|
const config = program2.command("config").description("View or change stack configuration");
|
|
571
|
+
config.command("list").description("List all environments, or show config for a specific stage").option("-s, --stage <name>", "Show config for a specific stage").action((opts) => {
|
|
572
|
+
if (opts.stage) {
|
|
573
|
+
const env = loadEnvironment(opts.stage);
|
|
574
|
+
if (!env) {
|
|
575
|
+
printError(`Environment "${opts.stage}" not found. Run \`thinkwork init -s ${opts.stage}\` first.`);
|
|
576
|
+
process.exit(1);
|
|
577
|
+
}
|
|
578
|
+
console.log("");
|
|
579
|
+
console.log(chalk3.bold.cyan(` \u2B21 ${env.stage}`));
|
|
580
|
+
console.log(chalk3.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\u2500\u2500\u2500\u2500"));
|
|
581
|
+
console.log(` ${chalk3.bold("Region:")} ${env.region}`);
|
|
582
|
+
console.log(` ${chalk3.bold("Account:")} ${env.accountId}`);
|
|
583
|
+
console.log(` ${chalk3.bold("Database:")} ${env.databaseEngine}`);
|
|
584
|
+
console.log(` ${chalk3.bold("Memory:")} ${env.memoryEngine}`);
|
|
585
|
+
console.log(` ${chalk3.bold("Terraform dir:")} ${env.terraformDir}`);
|
|
586
|
+
console.log(` ${chalk3.bold("Created:")} ${env.createdAt}`);
|
|
587
|
+
console.log(` ${chalk3.bold("Updated:")} ${env.updatedAt}`);
|
|
588
|
+
console.log(chalk3.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\u2500\u2500\u2500\u2500"));
|
|
589
|
+
const tfvarsPath = `${env.terraformDir}/terraform.tfvars`;
|
|
590
|
+
if (existsSync3(tfvarsPath)) {
|
|
591
|
+
console.log("");
|
|
592
|
+
console.log(chalk3.dim(" terraform.tfvars:"));
|
|
593
|
+
const content = readFileSync2(tfvarsPath, "utf-8");
|
|
594
|
+
for (const line of content.split("\n")) {
|
|
595
|
+
if (line.trim() && !line.trim().startsWith("#")) {
|
|
596
|
+
const masked = line.replace(
|
|
597
|
+
/^(db_password\s*=\s*)".*"/,
|
|
598
|
+
'$1"********"'
|
|
599
|
+
).replace(
|
|
600
|
+
/^(api_auth_secret\s*=\s*)".*"/,
|
|
601
|
+
'$1"********"'
|
|
602
|
+
).replace(
|
|
603
|
+
/^(google_oauth_client_secret\s*=\s*)".*"/,
|
|
604
|
+
'$1"********"'
|
|
605
|
+
);
|
|
606
|
+
console.log(` ${chalk3.dim(masked)}`);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
console.log("");
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
const envs = listEnvironments();
|
|
614
|
+
if (envs.length === 0) {
|
|
615
|
+
console.log("");
|
|
616
|
+
console.log(" No environments found.");
|
|
617
|
+
console.log(` Run ${chalk3.cyan("thinkwork init -s <stage>")} to create one.`);
|
|
618
|
+
console.log("");
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
console.log("");
|
|
622
|
+
console.log(chalk3.bold(" Environments"));
|
|
623
|
+
console.log(chalk3.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\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"));
|
|
624
|
+
for (const env of envs) {
|
|
625
|
+
const memBadge = env.memoryEngine === "hindsight" ? chalk3.magenta("hindsight") : chalk3.dim("managed");
|
|
626
|
+
const dbBadge = env.databaseEngine === "rds-postgres" ? chalk3.yellow("rds") : chalk3.dim("aurora");
|
|
627
|
+
console.log(
|
|
628
|
+
` ${chalk3.bold.cyan(env.stage.padEnd(16))}${env.region.padEnd(14)}${env.accountId.padEnd(16)}${dbBadge.padEnd(20)}${memBadge}`
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
console.log(chalk3.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\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"));
|
|
632
|
+
console.log(chalk3.dim(` ${envs.length} environment(s)`));
|
|
633
|
+
console.log("");
|
|
634
|
+
console.log(` Show details: ${chalk3.cyan("thinkwork config list -s <stage>")}`);
|
|
635
|
+
console.log("");
|
|
636
|
+
});
|
|
513
637
|
config.command("get <key>").description("Get a configuration value (e.g. memory-engine)").requiredOption("-s, --stage <name>", "Deployment stage").action((key, opts) => {
|
|
514
638
|
const stageCheck = validateStage(opts.stage);
|
|
515
639
|
if (!stageCheck.valid) {
|
|
516
640
|
printError(stageCheck.error);
|
|
517
641
|
process.exit(1);
|
|
518
642
|
}
|
|
519
|
-
const
|
|
520
|
-
const cwd = resolveTierDir(terraformDir, opts.stage, "app");
|
|
521
|
-
const tfvarsPath = `${cwd}/terraform.tfvars`;
|
|
643
|
+
const tfvarsPath = resolveTfvarsPath(opts.stage);
|
|
522
644
|
const tfKey = key.replace(/-/g, "_");
|
|
523
645
|
const value = readTfVar(tfvarsPath, tfKey);
|
|
524
646
|
if (value === null) {
|
|
@@ -527,7 +649,7 @@ function registerConfigCommand(program2) {
|
|
|
527
649
|
console.log(` ${key} = ${value}`);
|
|
528
650
|
}
|
|
529
651
|
});
|
|
530
|
-
config.command("set <key> <value>").description("Set a configuration value and optionally deploy
|
|
652
|
+
config.command("set <key> <value>").description("Set a configuration value and optionally deploy").requiredOption("-s, --stage <name>", "Deployment stage").option("--apply", "Run terraform apply after changing the value").action(async (key, value, opts) => {
|
|
531
653
|
const stageCheck = validateStage(opts.stage);
|
|
532
654
|
if (!stageCheck.valid) {
|
|
533
655
|
printError(stageCheck.error);
|
|
@@ -540,18 +662,21 @@ function registerConfigCommand(program2) {
|
|
|
540
662
|
}
|
|
541
663
|
const identity = getAwsIdentity();
|
|
542
664
|
printHeader("config set", opts.stage, identity);
|
|
543
|
-
const
|
|
544
|
-
const cwd = resolveTierDir(terraformDir, opts.stage, "app");
|
|
545
|
-
const tfvarsPath = `${cwd}/terraform.tfvars`;
|
|
665
|
+
const tfvarsPath = resolveTfvarsPath(opts.stage);
|
|
546
666
|
const oldValue = readTfVar(tfvarsPath, tfKey);
|
|
547
667
|
setTfVar(tfvarsPath, tfKey, value);
|
|
548
668
|
console.log(` ${key}: ${oldValue ?? "(unset)"} \u2192 ${value}`);
|
|
549
669
|
if (opts.apply) {
|
|
670
|
+
const tfDir = resolveTerraformDir(opts.stage);
|
|
671
|
+
if (!tfDir) {
|
|
672
|
+
printError("Cannot find terraform directory. Run `thinkwork init` first.");
|
|
673
|
+
process.exit(1);
|
|
674
|
+
}
|
|
550
675
|
console.log("");
|
|
551
676
|
console.log(" Applying configuration change...");
|
|
552
|
-
await ensureInit(
|
|
553
|
-
await ensureWorkspace(
|
|
554
|
-
const code = await runTerraform(
|
|
677
|
+
await ensureInit(tfDir);
|
|
678
|
+
await ensureWorkspace(tfDir, opts.stage);
|
|
679
|
+
const code = await runTerraform(tfDir, [
|
|
555
680
|
"apply",
|
|
556
681
|
"-auto-approve",
|
|
557
682
|
`-var=stage=${opts.stage}`
|
|
@@ -721,16 +846,16 @@ function registerLoginCommand(program2) {
|
|
|
721
846
|
}
|
|
722
847
|
|
|
723
848
|
// src/commands/init.ts
|
|
724
|
-
import { existsSync as
|
|
725
|
-
import { resolve as resolve2, join, dirname } from "path";
|
|
849
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3, cpSync } from "fs";
|
|
850
|
+
import { resolve as resolve2, join as join2, dirname } from "path";
|
|
726
851
|
import { execSync as execSync4 } from "child_process";
|
|
727
852
|
import { fileURLToPath } from "url";
|
|
728
853
|
import { createInterface as createInterface3 } from "readline";
|
|
729
|
-
import
|
|
854
|
+
import chalk4 from "chalk";
|
|
730
855
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
731
856
|
function ask2(prompt, defaultVal = "") {
|
|
732
857
|
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
733
|
-
const suffix = defaultVal ?
|
|
858
|
+
const suffix = defaultVal ? chalk4.dim(` [${defaultVal}]`) : "";
|
|
734
859
|
return new Promise((resolve3) => {
|
|
735
860
|
rl.question(` ${prompt}${suffix}: `, (answer) => {
|
|
736
861
|
rl.close();
|
|
@@ -739,7 +864,7 @@ function ask2(prompt, defaultVal = "") {
|
|
|
739
864
|
});
|
|
740
865
|
}
|
|
741
866
|
function choose(prompt, options, defaultVal) {
|
|
742
|
-
const optStr = options.map((o) => o === defaultVal ?
|
|
867
|
+
const optStr = options.map((o) => o === defaultVal ? chalk4.bold(o) : chalk4.dim(o)).join(" / ");
|
|
743
868
|
return ask2(`${prompt} (${optStr})`, defaultVal);
|
|
744
869
|
}
|
|
745
870
|
function generateSecret(length = 32) {
|
|
@@ -752,9 +877,9 @@ function generateSecret(length = 32) {
|
|
|
752
877
|
}
|
|
753
878
|
function findBundledTerraform() {
|
|
754
879
|
const bundled = resolve2(__dirname, "..", "terraform");
|
|
755
|
-
if (
|
|
880
|
+
if (existsSync4(join2(bundled, "modules"))) return bundled;
|
|
756
881
|
const repoTf = resolve2(__dirname, "..", "..", "..", "..", "terraform");
|
|
757
|
-
if (
|
|
882
|
+
if (existsSync4(join2(repoTf, "modules"))) return repoTf;
|
|
758
883
|
throw new Error(
|
|
759
884
|
"Terraform modules not found. The CLI package may be incomplete.\nTry reinstalling: npm install -g thinkwork-cli@latest"
|
|
760
885
|
);
|
|
@@ -818,9 +943,9 @@ function registerInitCommand(program2) {
|
|
|
818
943
|
process.exit(1);
|
|
819
944
|
}
|
|
820
945
|
const targetDir = resolve2(opts.dir);
|
|
821
|
-
const tfDir =
|
|
822
|
-
const tfvarsPath =
|
|
823
|
-
if (
|
|
946
|
+
const tfDir = join2(targetDir, "terraform");
|
|
947
|
+
const tfvarsPath = join2(tfDir, "terraform.tfvars");
|
|
948
|
+
if (existsSync4(tfvarsPath)) {
|
|
824
949
|
printWarning(`terraform.tfvars already exists at ${tfvarsPath}`);
|
|
825
950
|
const overwrite = await ask2("Overwrite?", "N");
|
|
826
951
|
if (overwrite.toLowerCase() !== "y") {
|
|
@@ -844,19 +969,19 @@ function registerInitCommand(program2) {
|
|
|
844
969
|
config.admin_url = "http://localhost:5174";
|
|
845
970
|
config.mobile_scheme = "thinkwork";
|
|
846
971
|
} else {
|
|
847
|
-
console.log(
|
|
972
|
+
console.log(chalk4.bold(" Configure your Thinkwork environment\n"));
|
|
848
973
|
const defaultRegion = identity.region !== "unknown" ? identity.region : "us-east-1";
|
|
849
974
|
config.region = await ask2("AWS Region", defaultRegion);
|
|
850
975
|
console.log("");
|
|
851
|
-
console.log(
|
|
976
|
+
console.log(chalk4.dim(" \u2500\u2500 Database \u2500\u2500"));
|
|
852
977
|
config.database_engine = await choose("Database engine", ["aurora-serverless", "rds-postgres"], "aurora-serverless");
|
|
853
978
|
console.log("");
|
|
854
|
-
console.log(
|
|
855
|
-
console.log(
|
|
856
|
-
console.log(
|
|
979
|
+
console.log(chalk4.dim(" \u2500\u2500 Memory \u2500\u2500"));
|
|
980
|
+
console.log(chalk4.dim(" managed = Built-in AgentCore memory (remember/recall/forget)"));
|
|
981
|
+
console.log(chalk4.dim(" hindsight = ECS Fargate service with semantic + graph retrieval"));
|
|
857
982
|
config.memory_engine = await choose("Memory engine", ["managed", "hindsight"], "managed");
|
|
858
983
|
console.log("");
|
|
859
|
-
console.log(
|
|
984
|
+
console.log(chalk4.dim(" \u2500\u2500 Auth \u2500\u2500"));
|
|
860
985
|
const useGoogle = await ask2("Enable Google OAuth login? (y/N)", "N");
|
|
861
986
|
if (useGoogle.toLowerCase() === "y") {
|
|
862
987
|
config.google_oauth_client_id = await ask2("Google OAuth Client ID");
|
|
@@ -866,13 +991,13 @@ function registerInitCommand(program2) {
|
|
|
866
991
|
config.google_oauth_client_secret = "";
|
|
867
992
|
}
|
|
868
993
|
console.log("");
|
|
869
|
-
console.log(
|
|
994
|
+
console.log(chalk4.dim(" \u2500\u2500 Frontend URLs \u2500\u2500"));
|
|
870
995
|
config.admin_url = await ask2("Admin UI URL", "http://localhost:5174");
|
|
871
996
|
config.mobile_scheme = await ask2("Mobile app URL scheme", "thinkwork");
|
|
872
997
|
console.log("");
|
|
873
|
-
console.log(
|
|
874
|
-
console.log(
|
|
875
|
-
console.log(
|
|
998
|
+
console.log(chalk4.dim(" \u2500\u2500 Secrets (auto-generated) \u2500\u2500"));
|
|
999
|
+
console.log(chalk4.dim(` DB password: ${config.db_password.slice(0, 8)}...`));
|
|
1000
|
+
console.log(chalk4.dim(` API auth secret: ${config.api_auth_secret.slice(0, 16)}...`));
|
|
876
1001
|
}
|
|
877
1002
|
console.log("");
|
|
878
1003
|
console.log(" Scaffolding Terraform modules...");
|
|
@@ -883,24 +1008,24 @@ function registerInitCommand(program2) {
|
|
|
883
1008
|
printError(String(err));
|
|
884
1009
|
process.exit(1);
|
|
885
1010
|
}
|
|
886
|
-
|
|
1011
|
+
mkdirSync2(tfDir, { recursive: true });
|
|
887
1012
|
const copyDirs = ["modules", "examples"];
|
|
888
1013
|
for (const dir of copyDirs) {
|
|
889
|
-
const src =
|
|
890
|
-
const dst =
|
|
891
|
-
if (
|
|
1014
|
+
const src = join2(bundledTf, dir);
|
|
1015
|
+
const dst = join2(tfDir, dir);
|
|
1016
|
+
if (existsSync4(src) && !existsSync4(dst)) {
|
|
892
1017
|
cpSync(src, dst, { recursive: true });
|
|
893
1018
|
}
|
|
894
1019
|
}
|
|
895
|
-
const schemaPath =
|
|
896
|
-
if (
|
|
897
|
-
cpSync(schemaPath,
|
|
1020
|
+
const schemaPath = join2(bundledTf, "schema.graphql");
|
|
1021
|
+
if (existsSync4(schemaPath) && !existsSync4(join2(tfDir, "schema.graphql"))) {
|
|
1022
|
+
cpSync(schemaPath, join2(tfDir, "schema.graphql"));
|
|
898
1023
|
}
|
|
899
1024
|
const tfvars = buildTfvars(config);
|
|
900
|
-
|
|
901
|
-
const mainTfPath =
|
|
902
|
-
if (!
|
|
903
|
-
|
|
1025
|
+
writeFileSync3(tfvarsPath, tfvars);
|
|
1026
|
+
const mainTfPath = join2(tfDir, "main.tf");
|
|
1027
|
+
if (!existsSync4(mainTfPath)) {
|
|
1028
|
+
writeFileSync3(mainTfPath, `################################################################################
|
|
904
1029
|
# Thinkwork \u2014 ${config.stage}
|
|
905
1030
|
# Generated by: thinkwork init -s ${config.stage}
|
|
906
1031
|
################################################################################
|
|
@@ -977,17 +1102,17 @@ output "memory_engine" { value = module.thinkwork.memory_engine }
|
|
|
977
1102
|
output "hindsight_endpoint" { value = module.thinkwork.hindsight_endpoint }
|
|
978
1103
|
`);
|
|
979
1104
|
}
|
|
980
|
-
console.log(` Wrote ${
|
|
1105
|
+
console.log(` Wrote ${chalk4.cyan(tfDir + "/")}`);
|
|
981
1106
|
console.log("");
|
|
982
|
-
console.log(
|
|
983
|
-
console.log(` ${
|
|
984
|
-
console.log(` ${
|
|
985
|
-
console.log(` ${
|
|
986
|
-
console.log(` ${
|
|
987
|
-
console.log(` ${
|
|
988
|
-
console.log(` ${
|
|
989
|
-
console.log(` ${
|
|
990
|
-
console.log(
|
|
1107
|
+
console.log(chalk4.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\u2500\u2500\u2500\u2500"));
|
|
1108
|
+
console.log(` ${chalk4.bold("Stage:")} ${config.stage}`);
|
|
1109
|
+
console.log(` ${chalk4.bold("Region:")} ${config.region}`);
|
|
1110
|
+
console.log(` ${chalk4.bold("Account:")} ${config.account_id}`);
|
|
1111
|
+
console.log(` ${chalk4.bold("Database:")} ${config.database_engine}`);
|
|
1112
|
+
console.log(` ${chalk4.bold("Memory:")} ${config.memory_engine}`);
|
|
1113
|
+
console.log(` ${chalk4.bold("Google OAuth:")} ${config.google_oauth_client_id ? "enabled" : "disabled"}`);
|
|
1114
|
+
console.log(` ${chalk4.bold("Directory:")} ${tfDir}`);
|
|
1115
|
+
console.log(chalk4.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\u2500\u2500\u2500\u2500"));
|
|
991
1116
|
console.log("\n Initializing Terraform...\n");
|
|
992
1117
|
try {
|
|
993
1118
|
execSync4("terraform init", { cwd: tfDir, stdio: "inherit" });
|
|
@@ -995,13 +1120,24 @@ output "hindsight_endpoint" { value = module.thinkwork.hindsight_endpoint }
|
|
|
995
1120
|
printWarning("Terraform init failed. Run `thinkwork doctor -s " + opts.stage + "` to check prerequisites.");
|
|
996
1121
|
return;
|
|
997
1122
|
}
|
|
1123
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1124
|
+
saveEnvironment({
|
|
1125
|
+
stage: config.stage,
|
|
1126
|
+
region: config.region,
|
|
1127
|
+
accountId: config.account_id,
|
|
1128
|
+
terraformDir: tfDir,
|
|
1129
|
+
databaseEngine: config.database_engine,
|
|
1130
|
+
memoryEngine: config.memory_engine,
|
|
1131
|
+
createdAt: now,
|
|
1132
|
+
updatedAt: now
|
|
1133
|
+
});
|
|
998
1134
|
printSuccess(`Environment "${opts.stage}" initialized`);
|
|
999
1135
|
console.log("");
|
|
1000
1136
|
console.log(" Next steps:");
|
|
1001
|
-
console.log(` ${
|
|
1002
|
-
console.log(` ${
|
|
1003
|
-
console.log(` ${
|
|
1004
|
-
console.log(` ${
|
|
1137
|
+
console.log(` ${chalk4.cyan("1.")} thinkwork plan -s ${opts.stage} ${chalk4.dim("# Review infrastructure plan")}`);
|
|
1138
|
+
console.log(` ${chalk4.cyan("2.")} thinkwork deploy -s ${opts.stage} ${chalk4.dim("# Deploy to AWS (~5 min)")}`);
|
|
1139
|
+
console.log(` ${chalk4.cyan("3.")} thinkwork bootstrap -s ${opts.stage} ${chalk4.dim("# Seed workspace files + skills")}`);
|
|
1140
|
+
console.log(` ${chalk4.cyan("4.")} thinkwork outputs -s ${opts.stage} ${chalk4.dim("# Show API URL, Cognito IDs, etc.")}`);
|
|
1005
1141
|
console.log("");
|
|
1006
1142
|
});
|
|
1007
1143
|
}
|