@atlashub/smartstack-cli 3.1.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/.documentation/prd-json-v2.0.0.md +396 -0
  2. package/.documentation/testing-ba-e2e.md +462 -0
  3. package/dist/index.js +605 -25
  4. package/dist/index.js.map +1 -1
  5. package/package.json +6 -2
  6. package/templates/agents/ba-reader.md +1 -1
  7. package/templates/agents/ba-writer.md +8 -1
  8. package/templates/skills/business-analyse/SKILL.md +46 -31
  9. package/templates/skills/business-analyse/_architecture.md +123 -0
  10. package/templates/skills/business-analyse/_elicitation.md +206 -0
  11. package/templates/skills/business-analyse/_module-loop.md +56 -0
  12. package/templates/skills/business-analyse/_shared.md +75 -531
  13. package/templates/skills/business-analyse/_suggestions.md +34 -0
  14. package/templates/skills/business-analyse/html/ba-interactive.html +146 -57
  15. package/templates/skills/business-analyse/questionnaire/06-security.md +1 -1
  16. package/templates/skills/business-analyse/questionnaire.md +22 -17
  17. package/templates/skills/business-analyse/react/components.md +1 -1
  18. package/templates/skills/business-analyse/react/schema.md +1 -1
  19. package/templates/skills/business-analyse/references/html-data-mapping.md +294 -0
  20. package/templates/skills/business-analyse/schemas/feature-schema.json +1 -1
  21. package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +1 -1
  22. package/templates/skills/business-analyse/schemas/sections/handoff-schema.json +1 -1
  23. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +1 -1
  24. package/templates/skills/business-analyse/steps/step-00-init.md +85 -59
  25. package/templates/skills/business-analyse/steps/step-01-cadrage.md +2 -0
  26. package/templates/skills/business-analyse/steps/step-02-decomposition.md +5 -3
  27. package/templates/skills/business-analyse/steps/{step-03-specify.md → step-03a-specify.md} +16 -606
  28. package/templates/skills/business-analyse/steps/step-03b-compile.md +670 -0
  29. package/templates/skills/business-analyse/steps/step-04-consolidation.md +7 -5
  30. package/templates/skills/business-analyse/steps/step-05a-handoff.md +727 -0
  31. package/templates/skills/business-analyse/steps/step-05b-deploy.md +479 -0
  32. package/templates/skills/business-analyse/steps/step-06-extract.md +134 -4
  33. package/templates/skills/business-analyse/templates/tpl-frd.md +1 -1
  34. package/templates/skills/business-analyse/templates/tpl-launch-displays.md +161 -0
  35. package/templates/skills/business-analyse/templates/tpl-progress.md +171 -0
  36. package/templates/skills/ralph-loop/SKILL.md +138 -20
  37. package/templates/skills/ralph-loop/steps/step-01-task.md +75 -18
  38. package/templates/skills/ralph-loop/steps/step-04-check.md +72 -5
  39. package/templates/skills/business-analyse/steps/step-05-handoff.md +0 -1414
package/dist/index.js CHANGED
@@ -6573,7 +6573,7 @@ var require_jsonfile = __commonJS({
6573
6573
  return obj;
6574
6574
  }
6575
6575
  var readFile2 = universalify.fromPromise(_readFile);
6576
- function readFileSync4(file, options = {}) {
6576
+ function readFileSync5(file, options = {}) {
6577
6577
  if (typeof options === "string") {
6578
6578
  options = { encoding: options };
6579
6579
  }
@@ -6598,16 +6598,16 @@ var require_jsonfile = __commonJS({
6598
6598
  await universalify.fromCallback(fs16.writeFile)(file, str, options);
6599
6599
  }
6600
6600
  var writeFile2 = universalify.fromPromise(_writeFile);
6601
- function writeFileSync2(file, obj, options = {}) {
6601
+ function writeFileSync3(file, obj, options = {}) {
6602
6602
  const fs16 = options.fs || _fs;
6603
6603
  const str = stringify2(obj, options);
6604
6604
  return fs16.writeFileSync(file, str, options);
6605
6605
  }
6606
6606
  module2.exports = {
6607
6607
  readFile: readFile2,
6608
- readFileSync: readFileSync4,
6608
+ readFileSync: readFileSync5,
6609
6609
  writeFile: writeFile2,
6610
- writeFileSync: writeFileSync2
6610
+ writeFileSync: writeFileSync3
6611
6611
  };
6612
6612
  }
6613
6613
  });
@@ -19200,7 +19200,7 @@ var require_buffer_list = __commonJS({
19200
19200
  }
19201
19201
  }, {
19202
19202
  key: "join",
19203
- value: function join14(s) {
19203
+ value: function join15(s) {
19204
19204
  if (this.length === 0) return "";
19205
19205
  var p = this.head;
19206
19206
  var ret = "" + p.data;
@@ -33660,7 +33660,7 @@ var require_table = __commonJS({
33660
33660
  var debug = require_debug();
33661
33661
  var utils = require_utils4();
33662
33662
  var tableLayout = require_layout_manager();
33663
- var Table6 = class extends Array {
33663
+ var Table7 = class extends Array {
33664
33664
  constructor(opts) {
33665
33665
  super();
33666
33666
  const options = utils.mergeOptions(opts);
@@ -33735,7 +33735,7 @@ var require_table = __commonJS({
33735
33735
  return str[0].length;
33736
33736
  }
33737
33737
  };
33738
- Table6.reset = () => debug.reset();
33738
+ Table7.reset = () => debug.reset();
33739
33739
  function doDraw(row, lineNum, result) {
33740
33740
  let line = [];
33741
33741
  row.forEach(function(cell) {
@@ -33744,7 +33744,7 @@ var require_table = __commonJS({
33744
33744
  let str = line.join("");
33745
33745
  if (str.length) result.push(str);
33746
33746
  }
33747
- module2.exports = Table6;
33747
+ module2.exports = Table7;
33748
33748
  }
33749
33749
  });
33750
33750
 
@@ -39525,9 +39525,9 @@ var require_table2 = __commonJS({
39525
39525
  var objectHasProperty = require_utils6().objectHasProperty;
39526
39526
  var MAX = 65535;
39527
39527
  var JSON_COLUMN_ID = "JSON_F52E2B61-18A1-11d1-B105-00805F49916B";
39528
- function Table6(name) {
39528
+ function Table7(name) {
39529
39529
  if (name) {
39530
- const parsed = Table6.parseName(name);
39530
+ const parsed = Table7.parseName(name);
39531
39531
  this.name = parsed.name;
39532
39532
  this.schema = parsed.schema;
39533
39533
  this.database = parsed.database;
@@ -39573,7 +39573,7 @@ var require_table2 = __commonJS({
39573
39573
  }
39574
39574
  );
39575
39575
  }
39576
- Table6.prototype._makeBulk = function _makeBulk() {
39576
+ Table7.prototype._makeBulk = function _makeBulk() {
39577
39577
  for (let i = 0; i < this.columns.length; i++) {
39578
39578
  const col = this.columns[i];
39579
39579
  switch (col.type) {
@@ -39605,7 +39605,7 @@ var require_table2 = __commonJS({
39605
39605
  }
39606
39606
  return this;
39607
39607
  };
39608
- Table6.prototype.declare = function declare() {
39608
+ Table7.prototype.declare = function declare() {
39609
39609
  const pkey = this.columns.filter((col) => col.primary === true).map((col) => `[${col.name}]`);
39610
39610
  const cols = this.columns.map((col) => {
39611
39611
  const def = [`[${col.name}] ${declareType(col.type, col)}`];
@@ -39622,7 +39622,7 @@ var require_table2 = __commonJS({
39622
39622
  const constraint = pkey.length > 1 ? `, constraint [PK_${this.temporary ? this.name.substr(1) : this.name}] primary key (${pkey.join(", ")})` : "";
39623
39623
  return `create table ${this.path} (${cols.join(", ")}${constraint})`;
39624
39624
  };
39625
- Table6.fromRecordset = function fromRecordset(recordset, name) {
39625
+ Table7.fromRecordset = function fromRecordset(recordset, name) {
39626
39626
  const t = new this(name);
39627
39627
  for (const colName in recordset.columns) {
39628
39628
  if (objectHasProperty(recordset.columns, colName)) {
@@ -39650,7 +39650,7 @@ var require_table2 = __commonJS({
39650
39650
  }
39651
39651
  return t;
39652
39652
  };
39653
- Table6.parseName = function parseName(name) {
39653
+ Table7.parseName = function parseName(name) {
39654
39654
  const length = name.length;
39655
39655
  let cursor = -1;
39656
39656
  let buffer = "";
@@ -39707,7 +39707,7 @@ var require_table2 = __commonJS({
39707
39707
  throw new Error("Invalid table name.");
39708
39708
  }
39709
39709
  };
39710
- module2.exports = Table6;
39710
+ module2.exports = Table7;
39711
39711
  }
39712
39712
  });
39713
39713
 
@@ -39716,7 +39716,7 @@ var require_shared = __commonJS({
39716
39716
  "node_modules/mssql/lib/shared.js"(exports2, module2) {
39717
39717
  "use strict";
39718
39718
  var TYPES = require_datatypes().TYPES;
39719
- var Table6 = require_table2();
39719
+ var Table7 = require_table2();
39720
39720
  var PromiseLibrary = Promise;
39721
39721
  var driver = {};
39722
39722
  var map8 = [];
@@ -39739,7 +39739,7 @@ var require_shared = __commonJS({
39739
39739
  map8.register(Boolean, TYPES.Bit);
39740
39740
  map8.register(Date, TYPES.DateTime);
39741
39741
  map8.register(Buffer, TYPES.VarBinary);
39742
- map8.register(Table6, TYPES.TVP);
39742
+ map8.register(Table7, TYPES.TVP);
39743
39743
  var getTypeByValue = function(value) {
39744
39744
  if (value === null || value === void 0) {
39745
39745
  return TYPES.NVarChar;
@@ -41872,7 +41872,7 @@ var require_base = __commonJS({
41872
41872
  var Transaction = require_transaction();
41873
41873
  var { ConnectionError, TransactionError, RequestError, PreparedStatementError, MSSQLError } = require_error2();
41874
41874
  var shared = require_shared();
41875
- var Table6 = require_table2();
41875
+ var Table7 = require_table2();
41876
41876
  var ISOLATION_LEVEL = require_isolationlevel();
41877
41877
  var { TYPES } = require_datatypes();
41878
41878
  var { connect, close, on, off, removeListener, query, batch } = require_global_connection();
@@ -41893,7 +41893,7 @@ var require_base = __commonJS({
41893
41893
  RequestError,
41894
41894
  PreparedStatementError,
41895
41895
  MSSQLError,
41896
- Table: Table6,
41896
+ Table: Table7,
41897
41897
  ISOLATION_LEVEL,
41898
41898
  TYPES,
41899
41899
  MAX: 65535,
@@ -108014,7 +108014,7 @@ var require_request3 = __commonJS({
108014
108014
  var RequestError = require_request_error();
108015
108015
  var { IDS, objectHasProperty } = require_utils6();
108016
108016
  var { TYPES, DECLARATIONS, declare, cast } = require_datatypes();
108017
- var Table6 = require_table2();
108017
+ var Table7 = require_table2();
108018
108018
  var { PARSERS: UDT } = require_udt2();
108019
108019
  var { valueHandler } = require_shared();
108020
108020
  var JSON_COLUMN_ID = "JSON_F52E2B61-18A1-11d1-B105-00805F49916B";
@@ -108239,7 +108239,7 @@ var require_request3 = __commonJS({
108239
108239
  }
108240
108240
  };
108241
108241
  var parameterCorrection = function(value) {
108242
- if (value instanceof Table6) {
108242
+ if (value instanceof Table7) {
108243
108243
  const tvp = {
108244
108244
  name: value.name,
108245
108245
  schema: value.schema,
@@ -108553,7 +108553,7 @@ var require_request3 = __commonJS({
108553
108553
  enumerable: false,
108554
108554
  configurable: true,
108555
108555
  value(name) {
108556
- return Table6.fromRecordset(this, name);
108556
+ return Table7.fromRecordset(this, name);
108557
108557
  }
108558
108558
  });
108559
108559
  recordsets.push(recordset);
@@ -108865,7 +108865,7 @@ var require_request3 = __commonJS({
108865
108865
  enumerable: false,
108866
108866
  configurable: true,
108867
108867
  value(name) {
108868
- return Table6.fromRecordset(this, name);
108868
+ return Table7.fromRecordset(this, name);
108869
108869
  }
108870
108870
  });
108871
108871
  recordsets.push(recordset);
@@ -126871,10 +126871,589 @@ Processing module: ${source_default.bold(moduleName)}`));
126871
126871
  }
126872
126872
  });
126873
126873
 
126874
- // src/index.ts
126874
+ // src/commands/tmux.ts
126875
+ var import_cli_table36 = __toESM(require_cli_table3());
126876
+
126877
+ // src/lib/wsl-provisioner.ts
126878
+ var import_child_process10 = require("child_process");
126875
126879
  var import_fs5 = require("fs");
126876
126880
  var import_path12 = require("path");
126877
- var pkg = JSON.parse((0, import_fs5.readFileSync)((0, import_path12.join)(__dirname, "..", "package.json"), "utf-8"));
126881
+ function wslExec(command, timeout = 1e4) {
126882
+ try {
126883
+ const output = (0, import_child_process10.execSync)(`wsl -e bash -c "${command.replace(/"/g, '\\"')}"`, {
126884
+ encoding: "utf-8",
126885
+ timeout,
126886
+ stdio: ["pipe", "pipe", "pipe"]
126887
+ });
126888
+ return output.split("\n").filter((l) => !l.includes("WSL") || !l.includes("ERROR")).join("\n").trim();
126889
+ } catch {
126890
+ return null;
126891
+ }
126892
+ }
126893
+ function wslInstall(command, timeout = 12e4) {
126894
+ try {
126895
+ const output = (0, import_child_process10.execSync)(`wsl -e bash -c "${command.replace(/"/g, '\\"')}"`, {
126896
+ encoding: "utf-8",
126897
+ timeout,
126898
+ stdio: ["pipe", "pipe", "pipe"]
126899
+ });
126900
+ return output.trim();
126901
+ } catch (err) {
126902
+ const msg = err instanceof Error ? err.message : String(err);
126903
+ logger.debug(`wslInstall error: ${msg}`);
126904
+ return null;
126905
+ }
126906
+ }
126907
+ function parseWslList(raw) {
126908
+ return raw.replace(/\0/g, "").split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
126909
+ }
126910
+ function checkWsl() {
126911
+ try {
126912
+ const statusRaw = (0, import_child_process10.execSync)("wsl --status", {
126913
+ encoding: "utf-8",
126914
+ timeout: 1e4,
126915
+ stdio: ["pipe", "pipe", "pipe"]
126916
+ }).replace(/\0/g, "");
126917
+ let version2 = null;
126918
+ const versionMatch = statusRaw.match(/(\d)\s*$/m) || statusRaw.match(/version.*?:\s*(\d)/i);
126919
+ if (versionMatch) version2 = parseInt(versionMatch[1], 10);
126920
+ let defaultDistro = null;
126921
+ try {
126922
+ const listRaw = (0, import_child_process10.execSync)("wsl --list --verbose", {
126923
+ encoding: "utf-8",
126924
+ timeout: 1e4,
126925
+ stdio: ["pipe", "pipe", "pipe"]
126926
+ });
126927
+ const lines = parseWslList(listRaw);
126928
+ for (const line of lines) {
126929
+ if (line.startsWith("*")) {
126930
+ const parts = line.substring(1).trim().split(/\s+/);
126931
+ defaultDistro = parts[0] || null;
126932
+ if (!version2 && parts.length >= 3) {
126933
+ version2 = parseInt(parts[parts.length - 1], 10);
126934
+ }
126935
+ break;
126936
+ }
126937
+ }
126938
+ } catch {
126939
+ }
126940
+ return { installed: true, version: version2 || 2, defaultDistro };
126941
+ } catch {
126942
+ return { installed: false, version: null, defaultDistro: null };
126943
+ }
126944
+ }
126945
+ function checkGitInWsl() {
126946
+ const out = wslExec("git --version 2>/dev/null");
126947
+ if (!out) return { installed: false, version: null };
126948
+ const match2 = out.match(/(\d+\.\d+\.\d+)/);
126949
+ return { installed: true, version: match2 ? match2[1] : out };
126950
+ }
126951
+ function checkTmuxInWsl() {
126952
+ const out = wslExec("tmux -V 2>/dev/null");
126953
+ if (!out) return { installed: false, version: null };
126954
+ const match2 = out.match(/(\d+\.\d+\w?)/);
126955
+ return { installed: true, version: match2 ? match2[1] : out };
126956
+ }
126957
+ function checkNvmInWsl() {
126958
+ const out = wslExec("source ~/.nvm/nvm.sh 2>/dev/null && nvm --version 2>/dev/null");
126959
+ if (!out) return { installed: false, version: null };
126960
+ const match2 = out.match(/(\d+\.\d+\.\d+)/);
126961
+ return { installed: true, version: match2 ? match2[1] : out };
126962
+ }
126963
+ function checkNodeInWsl() {
126964
+ const out = wslExec("source ~/.nvm/nvm.sh 2>/dev/null; node --version 2>/dev/null");
126965
+ if (!out) return { installed: false, version: null };
126966
+ const match2 = out.match(/(v?\d+\.\d+\.\d+)/);
126967
+ return { installed: true, version: match2 ? match2[1] : out };
126968
+ }
126969
+ function checkDotnetInWsl() {
126970
+ const out = wslExec("export PATH=\\$PATH:\\$HOME/.dotnet && dotnet --version 2>/dev/null");
126971
+ if (!out) return { installed: false, version: null };
126972
+ const match2 = out.match(/(\d+\.\d+\.\d+)/);
126973
+ return { installed: true, version: match2 ? match2[1] : out };
126974
+ }
126975
+ function checkClaudeInWsl() {
126976
+ const out = wslExec("source ~/.nvm/nvm.sh 2>/dev/null; claude --version 2>/dev/null");
126977
+ if (!out) return { installed: false, version: null };
126978
+ const match2 = out.match(/(\d+\.\d+\.\d+)/);
126979
+ return { installed: true, version: match2 ? match2[1] : out };
126980
+ }
126981
+ async function installGitInWsl() {
126982
+ const status = checkGitInWsl();
126983
+ if (status.installed) return { success: true, version: status.version, skipped: true };
126984
+ const spinner = logger.spinner("Installing git...");
126985
+ const result = wslInstall("sudo apt-get update -qq && sudo apt-get install -y -qq git", 6e4);
126986
+ if (!result && result !== "") {
126987
+ spinner.fail("Failed to install git");
126988
+ return { success: false, error: "apt-get install git failed" };
126989
+ }
126990
+ const check = checkGitInWsl();
126991
+ if (check.installed) {
126992
+ spinner.succeed(`git ${check.version} installed`);
126993
+ return { success: true, version: check.version };
126994
+ }
126995
+ spinner.fail("git installation could not be verified");
126996
+ return { success: false, error: "Verification failed after install" };
126997
+ }
126998
+ async function installTmuxInWsl() {
126999
+ const status = checkTmuxInWsl();
127000
+ if (status.installed) return { success: true, version: status.version, skipped: true };
127001
+ const spinner = logger.spinner("Installing tmux...");
127002
+ const result = wslInstall("sudo apt-get update -qq && sudo apt-get install -y -qq tmux", 6e4);
127003
+ if (!result && result !== "") {
127004
+ spinner.fail("Failed to install tmux");
127005
+ return { success: false, error: "apt-get install tmux failed" };
127006
+ }
127007
+ const check = checkTmuxInWsl();
127008
+ if (check.installed) {
127009
+ spinner.succeed(`tmux ${check.version} installed`);
127010
+ return { success: true, version: check.version };
127011
+ }
127012
+ spinner.fail("tmux installation could not be verified");
127013
+ return { success: false, error: "Verification failed after install" };
127014
+ }
127015
+ async function installNvmInWsl() {
127016
+ const status = checkNvmInWsl();
127017
+ if (status.installed) return { success: true, version: status.version, skipped: true };
127018
+ const spinner = logger.spinner("Installing nvm...");
127019
+ const result = wslInstall(
127020
+ "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash",
127021
+ 6e4
127022
+ );
127023
+ if (result === null) {
127024
+ spinner.fail("Failed to install nvm");
127025
+ return { success: false, error: "nvm install script failed" };
127026
+ }
127027
+ const check = checkNvmInWsl();
127028
+ if (check.installed) {
127029
+ spinner.succeed(`nvm ${check.version} installed`);
127030
+ return { success: true, version: check.version };
127031
+ }
127032
+ spinner.fail("nvm installation could not be verified");
127033
+ return { success: false, error: "Verification failed after install" };
127034
+ }
127035
+ async function installNodeInWsl() {
127036
+ const status = checkNodeInWsl();
127037
+ if (status.installed) return { success: true, version: status.version, skipped: true };
127038
+ const nvmCheck = checkNvmInWsl();
127039
+ if (!nvmCheck.installed) {
127040
+ return { success: false, error: "nvm is not installed (required for Node.js)" };
127041
+ }
127042
+ const spinner = logger.spinner("Installing Node.js LTS...");
127043
+ const result = wslInstall(
127044
+ "source ~/.nvm/nvm.sh && nvm install --lts && nvm alias default lts/*",
127045
+ 12e4
127046
+ );
127047
+ if (result === null) {
127048
+ spinner.fail("Failed to install Node.js");
127049
+ return { success: false, error: "nvm install --lts failed" };
127050
+ }
127051
+ const check = checkNodeInWsl();
127052
+ if (check.installed) {
127053
+ spinner.succeed(`Node.js ${check.version} installed`);
127054
+ return { success: true, version: check.version };
127055
+ }
127056
+ spinner.fail("Node.js installation could not be verified");
127057
+ return { success: false, error: "Verification failed after install" };
127058
+ }
127059
+ async function installDotnetInWsl() {
127060
+ const status = checkDotnetInWsl();
127061
+ if (status.installed) return { success: true, version: status.version, skipped: true };
127062
+ const spinner = logger.spinner("Installing .NET SDK 10...");
127063
+ const installCmd = [
127064
+ "wget -q https://dot.net/v1/dotnet-install.sh -O /tmp/dotnet-install.sh",
127065
+ "chmod +x /tmp/dotnet-install.sh",
127066
+ "/tmp/dotnet-install.sh --channel 10.0"
127067
+ ].join(" && ");
127068
+ const result = wslInstall(installCmd, 18e4);
127069
+ if (result === null) {
127070
+ spinner.fail("Failed to install .NET SDK 10");
127071
+ return { success: false, error: "dotnet-install.sh failed" };
127072
+ }
127073
+ wslInstall(
127074
+ `grep -q "\\$HOME/.dotnet" ~/.bashrc || echo 'export PATH="$PATH:$HOME/.dotnet"' >> ~/.bashrc`,
127075
+ 5e3
127076
+ );
127077
+ const check = checkDotnetInWsl();
127078
+ if (check.installed) {
127079
+ spinner.succeed(`.NET SDK ${check.version} installed`);
127080
+ return { success: true, version: check.version };
127081
+ }
127082
+ spinner.fail(".NET SDK installation could not be verified");
127083
+ return { success: false, error: "Verification failed after install" };
127084
+ }
127085
+ async function installClaudeInWsl() {
127086
+ const status = checkClaudeInWsl();
127087
+ if (status.installed) return { success: true, version: status.version, skipped: true };
127088
+ const nodeCheck = checkNodeInWsl();
127089
+ if (!nodeCheck.installed) {
127090
+ return { success: false, error: "Node.js is not installed (required for Claude Code)" };
127091
+ }
127092
+ const spinner = logger.spinner("Installing Claude Code...");
127093
+ const result = wslInstall(
127094
+ "source ~/.nvm/nvm.sh && npm install -g @anthropic-ai/claude-code",
127095
+ 18e4
127096
+ );
127097
+ if (result === null) {
127098
+ spinner.fail("Failed to install Claude Code");
127099
+ return { success: false, error: "npm install -g @anthropic-ai/claude-code failed" };
127100
+ }
127101
+ const check = checkClaudeInWsl();
127102
+ if (check.installed) {
127103
+ spinner.succeed(`Claude Code ${check.version} installed`);
127104
+ return { success: true, version: check.version };
127105
+ }
127106
+ spinner.fail("Claude Code installation could not be verified");
127107
+ return { success: false, error: "Verification failed after install" };
127108
+ }
127109
+ var SMARTSTACK_PROFILE_NAME = "SmartStack Dev";
127110
+ var SMARTSTACK_PROFILE_GUID = "{17ce5bfe-17ed-5f3a-ab15-5cd5baafed5b}";
127111
+ function checkWindowsTerminal() {
127112
+ try {
127113
+ (0, import_child_process10.execSync)("where wt", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 5e3 });
127114
+ return { installed: true, version: "installed" };
127115
+ } catch {
127116
+ return { installed: false, version: null };
127117
+ }
127118
+ }
127119
+ async function installWindowsTerminal() {
127120
+ const status = checkWindowsTerminal();
127121
+ if (status.installed) return { success: true, version: "installed", skipped: true };
127122
+ const spinner = logger.spinner("Installing Windows Terminal via winget...");
127123
+ try {
127124
+ (0, import_child_process10.execSync)("winget install Microsoft.WindowsTerminal --accept-source-agreements --accept-package-agreements", {
127125
+ encoding: "utf-8",
127126
+ timeout: 12e4,
127127
+ stdio: ["pipe", "pipe", "pipe"]
127128
+ });
127129
+ } catch (err) {
127130
+ const msg = err instanceof Error ? err.message : String(err);
127131
+ if (msg.includes("already installed") || msg.includes("No applicable update")) {
127132
+ spinner.succeed("Windows Terminal already installed");
127133
+ return { success: true, version: "installed", skipped: true };
127134
+ }
127135
+ spinner.fail("Failed to install Windows Terminal");
127136
+ return { success: false, error: `winget install failed: ${msg.substring(0, 200)}` };
127137
+ }
127138
+ const check = checkWindowsTerminal();
127139
+ if (check.installed) {
127140
+ spinner.succeed("Windows Terminal installed");
127141
+ return { success: true, version: "installed" };
127142
+ }
127143
+ spinner.fail("Windows Terminal installation could not be verified");
127144
+ return { success: false, error: "Verification failed after install" };
127145
+ }
127146
+ function getWtSettingsPath() {
127147
+ const localAppData = process.env.LOCALAPPDATA;
127148
+ if (!localAppData) return null;
127149
+ const standardPath = (0, import_path12.join)(localAppData, "Packages", "Microsoft.WindowsTerminal_8wekyb3d8bbwe", "LocalState", "settings.json");
127150
+ if ((0, import_fs5.existsSync)(standardPath)) return standardPath;
127151
+ const previewPath = (0, import_path12.join)(localAppData, "Packages", "Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe", "LocalState", "settings.json");
127152
+ if ((0, import_fs5.existsSync)(previewPath)) return previewPath;
127153
+ const unpackagedPath = (0, import_path12.join)(localAppData, "Microsoft", "Windows Terminal", "settings.json");
127154
+ if ((0, import_fs5.existsSync)(unpackagedPath)) return unpackagedPath;
127155
+ return null;
127156
+ }
127157
+ function configureWindowsTerminal() {
127158
+ const settingsPath = getWtSettingsPath();
127159
+ if (!settingsPath) {
127160
+ return { success: false, error: "Windows Terminal settings.json not found. Launch Windows Terminal once to generate it." };
127161
+ }
127162
+ try {
127163
+ const raw = (0, import_fs5.readFileSync)(settingsPath, "utf-8");
127164
+ const cleaned = raw.replace(/^\uFEFF/, "").replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
127165
+ const settings = JSON.parse(cleaned);
127166
+ if (!settings.profiles) settings.profiles = {};
127167
+ if (!settings.profiles.list) settings.profiles.list = [];
127168
+ const existing = settings.profiles.list.find(
127169
+ (p) => p.guid === SMARTSTACK_PROFILE_GUID || p.name === SMARTSTACK_PROFILE_NAME
127170
+ );
127171
+ if (existing) {
127172
+ return { success: true, profileExists: true };
127173
+ }
127174
+ const profile = {
127175
+ guid: SMARTSTACK_PROFILE_GUID,
127176
+ name: SMARTSTACK_PROFILE_NAME,
127177
+ commandline: 'wsl -e bash -lc "source ~/.nvm/nvm.sh 2>/dev/null; tmux new-session -A -s smartstack"',
127178
+ icon: "\u26A1",
127179
+ colorScheme: "One Half Dark",
127180
+ startingDirectory: "~"
127181
+ };
127182
+ settings.profiles.list.push(profile);
127183
+ const backupPath = settingsPath + ".bak";
127184
+ (0, import_fs5.writeFileSync)(backupPath, raw, "utf-8");
127185
+ (0, import_fs5.writeFileSync)(settingsPath, JSON.stringify(settings, null, 4), "utf-8");
127186
+ return { success: true };
127187
+ } catch (err) {
127188
+ const msg = err instanceof Error ? err.message : String(err);
127189
+ return { success: false, error: `Failed to update settings: ${msg}` };
127190
+ }
127191
+ }
127192
+ function launchWindowsTerminal() {
127193
+ try {
127194
+ (0, import_child_process10.spawn)("wt", ["-p", SMARTSTACK_PROFILE_NAME], {
127195
+ detached: true,
127196
+ stdio: "ignore"
127197
+ }).unref();
127198
+ return true;
127199
+ } catch {
127200
+ return false;
127201
+ }
127202
+ }
127203
+
127204
+ // src/commands/tmux.ts
127205
+ var tmuxCommand = new Command("tmux").description("WSL development environment setup (tmux, dotnet, claude, git)").action(() => {
127206
+ console.log(source_default.cyan(`
127207
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
127208
+ \u2551 ${source_default.bold("WSL Dev Environment")} - SmartStack \u2551
127209
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
127210
+ `));
127211
+ console.log("Available commands:");
127212
+ console.log(` ${source_default.cyan("ss tmux install")} Set up complete WSL dev environment`);
127213
+ console.log(` ${source_default.cyan("ss tmux status")} Check WSL environment status`);
127214
+ console.log();
127215
+ console.log("Installs: Windows Terminal, git, tmux, nvm, Node.js, .NET 10, Claude Code");
127216
+ console.log("Then launches Windows Terminal with Claude Code in tmux.");
127217
+ console.log();
127218
+ });
127219
+ tmuxCommand.command("install").description("Install complete WSL dev environment and launch Claude Code").option("-f, --force", "Re-install even if already present").option("-v, --verbose", "Show detailed debug output").option("--no-launch", "Do not launch Windows Terminal after install").action(async (options) => {
127220
+ if (options.verbose) logger.setVerbose(true);
127221
+ logger.header("WSL Development Environment Setup");
127222
+ const totalSteps = 10;
127223
+ logger.step(1, totalSteps, "Windows Terminal...");
127224
+ const wtStatus = checkWindowsTerminal();
127225
+ if (wtStatus.installed && !options.force) {
127226
+ logger.success("Windows Terminal already installed");
127227
+ } else {
127228
+ const wtResult = await installWindowsTerminal();
127229
+ if (!wtResult.success) {
127230
+ logger.error(`Windows Terminal: ${wtResult.error}`);
127231
+ logger.info("You can install manually: winget install Microsoft.WindowsTerminal");
127232
+ }
127233
+ }
127234
+ console.log();
127235
+ logger.step(2, totalSteps, "Checking WSL installation...");
127236
+ const wslStatus = checkWsl();
127237
+ if (!wslStatus.installed) {
127238
+ logger.error("WSL is not installed on this system");
127239
+ logger.box([
127240
+ "WSL is required to continue.",
127241
+ "",
127242
+ "Install WSL from an admin terminal:",
127243
+ " wsl --install",
127244
+ "",
127245
+ "Then restart your computer and run ss tmux install again."
127246
+ ], "error");
127247
+ process.exit(1);
127248
+ }
127249
+ logger.success(`WSL ${wslStatus.version} installed`);
127250
+ if (wslStatus.defaultDistro) {
127251
+ logger.info(`Default distro: ${wslStatus.defaultDistro}`);
127252
+ } else {
127253
+ logger.error("No Linux distribution found");
127254
+ logger.box([
127255
+ "A Linux distribution is required.",
127256
+ "",
127257
+ "Install Ubuntu:",
127258
+ " wsl --install -d Ubuntu"
127259
+ ], "error");
127260
+ process.exit(1);
127261
+ }
127262
+ console.log();
127263
+ const tools = [
127264
+ { name: "Git", step: 3, check: checkGitInWsl, install: installGitInWsl },
127265
+ { name: "tmux", step: 4, check: checkTmuxInWsl, install: installTmuxInWsl },
127266
+ { name: "nvm", step: 5, check: checkNvmInWsl, install: installNvmInWsl },
127267
+ { name: "Node.js", step: 6, check: checkNodeInWsl, install: installNodeInWsl },
127268
+ { name: ".NET SDK 10", step: 7, check: checkDotnetInWsl, install: installDotnetInWsl },
127269
+ { name: "Claude Code", step: 8, check: checkClaudeInWsl, install: installClaudeInWsl }
127270
+ ];
127271
+ let allSuccess = true;
127272
+ const results = [];
127273
+ for (const tool of tools) {
127274
+ logger.step(tool.step, totalSteps, `${tool.name}...`);
127275
+ if (!options.force) {
127276
+ const status = tool.check();
127277
+ if (status.installed) {
127278
+ logger.success(`${tool.name} already installed (${status.version})`);
127279
+ results.push({ name: tool.name, status: "skipped", version: status.version });
127280
+ console.log();
127281
+ continue;
127282
+ }
127283
+ }
127284
+ const result = await tool.install();
127285
+ if (result.success) {
127286
+ if (result.skipped) {
127287
+ logger.success(`${tool.name} already installed (${result.version})`);
127288
+ results.push({ name: tool.name, status: "skipped", version: result.version });
127289
+ } else {
127290
+ results.push({ name: tool.name, status: "ok", version: result.version });
127291
+ }
127292
+ } else {
127293
+ logger.error(`Failed to install ${tool.name}: ${result.error}`);
127294
+ results.push({ name: tool.name, status: "error", error: result.error });
127295
+ allSuccess = false;
127296
+ }
127297
+ console.log();
127298
+ }
127299
+ if (!allSuccess) {
127300
+ const failed = results.filter((r) => r.status === "error");
127301
+ logger.box([
127302
+ `${failed.length} tool(s) failed to install:`,
127303
+ ...failed.map((f) => ` - ${f.name}: ${f.error}`),
127304
+ "",
127305
+ "Run again with --verbose for details:",
127306
+ " ss tmux install --verbose"
127307
+ ], "error");
127308
+ process.exit(1);
127309
+ }
127310
+ logger.step(9, totalSteps, "Configuring Windows Terminal...");
127311
+ const wtCheck = checkWindowsTerminal();
127312
+ if (wtCheck.installed) {
127313
+ const configResult = configureWindowsTerminal();
127314
+ if (configResult.success) {
127315
+ if (configResult.profileExists) {
127316
+ logger.success("SmartStack Dev profile already configured");
127317
+ } else {
127318
+ logger.success("SmartStack Dev profile added to Windows Terminal");
127319
+ }
127320
+ } else {
127321
+ logger.warning(`Configuration skipped: ${configResult.error}`);
127322
+ logger.info("You can configure manually after launching Windows Terminal once.");
127323
+ }
127324
+ } else {
127325
+ logger.warning("Windows Terminal not available - skipping configuration");
127326
+ }
127327
+ console.log();
127328
+ logger.step(10, totalSteps, "Launching...");
127329
+ if (options.launch === false) {
127330
+ logger.info("Launch skipped (--no-launch)");
127331
+ logger.box([
127332
+ "WSL development environment ready!",
127333
+ "",
127334
+ "Launch manually:",
127335
+ ' wt -p "SmartStack Dev"'
127336
+ ], "success");
127337
+ return;
127338
+ }
127339
+ if (wtCheck.installed) {
127340
+ logger.info("Opening Windows Terminal with SmartStack Dev profile...");
127341
+ const launched = launchWindowsTerminal();
127342
+ if (launched) {
127343
+ logger.box([
127344
+ "WSL development environment ready!",
127345
+ "",
127346
+ "Windows Terminal is opening with tmux.",
127347
+ "Run claude inside tmux to start Claude Code.",
127348
+ "",
127349
+ "Next time, launch directly:",
127350
+ ' wt -p "SmartStack Dev"'
127351
+ ], "success");
127352
+ } else {
127353
+ logger.warning("Could not launch Windows Terminal automatically");
127354
+ logger.info('Launch manually: wt -p "SmartStack Dev"');
127355
+ }
127356
+ } else {
127357
+ logger.info("Opening WSL with tmux...");
127358
+ logger.box([
127359
+ "WSL development environment ready!",
127360
+ "",
127361
+ "Start manually:",
127362
+ ' wsl -e bash -c "tmux new -s smartstack"',
127363
+ " Then run: claude"
127364
+ ], "success");
127365
+ }
127366
+ });
127367
+ tmuxCommand.command("status").description("Show WSL development environment status").option("--json", "Output as JSON").option("-v, --verbose", "Show detailed information").action(async (options) => {
127368
+ if (options.verbose) logger.setVerbose(true);
127369
+ const wslStatus = checkWsl();
127370
+ const wtStatus = checkWindowsTerminal();
127371
+ const gitStatus = checkGitInWsl();
127372
+ const tmuxStatus = checkTmuxInWsl();
127373
+ const nvmStatus = checkNvmInWsl();
127374
+ const nodeStatus = checkNodeInWsl();
127375
+ const dotnetStatus = checkDotnetInWsl();
127376
+ const claudeStatus = checkClaudeInWsl();
127377
+ if (options.json) {
127378
+ console.log(JSON.stringify({
127379
+ wsl: wslStatus,
127380
+ windowsTerminal: wtStatus,
127381
+ tools: {
127382
+ git: gitStatus,
127383
+ tmux: tmuxStatus,
127384
+ nvm: nvmStatus,
127385
+ node: nodeStatus,
127386
+ dotnet: dotnetStatus,
127387
+ claude: claudeStatus
127388
+ }
127389
+ }, null, 2));
127390
+ const allInstalled2 = wtStatus.installed && gitStatus.installed && tmuxStatus.installed && nodeStatus.installed && dotnetStatus.installed && claudeStatus.installed;
127391
+ process.exit(allInstalled2 ? 0 : 1);
127392
+ }
127393
+ logger.header("WSL Development Environment Status");
127394
+ console.log(source_default.bold("Windows"));
127395
+ if (wslStatus.installed) {
127396
+ console.log(` ${source_default.green("\u2713")} WSL ${wslStatus.version} ${source_default.gray(`(${wslStatus.defaultDistro || "no distro"})`)}`);
127397
+ } else {
127398
+ console.log(` ${source_default.red("\u2717")} WSL not installed`);
127399
+ }
127400
+ console.log(` ${wtStatus.installed ? source_default.green("\u2713") : source_default.red("\u2717")} Windows Terminal`);
127401
+ console.log();
127402
+ if (!wslStatus.installed) {
127403
+ logger.box([
127404
+ "WSL is not installed.",
127405
+ "",
127406
+ "Install WSL: wsl --install"
127407
+ ], "error");
127408
+ process.exit(1);
127409
+ }
127410
+ console.log(source_default.bold("WSL Tools"));
127411
+ const table = new import_cli_table36.default({
127412
+ head: [source_default.cyan("Tool"), source_default.cyan("Status"), source_default.cyan("Version")],
127413
+ style: { head: [], border: [] },
127414
+ colWidths: [18, 15, 25]
127415
+ });
127416
+ const tools = [
127417
+ { name: "Git", s: gitStatus },
127418
+ { name: "tmux", s: tmuxStatus },
127419
+ { name: "nvm", s: nvmStatus },
127420
+ { name: "Node.js", s: nodeStatus },
127421
+ { name: ".NET SDK", s: dotnetStatus },
127422
+ { name: "Claude Code", s: claudeStatus }
127423
+ ];
127424
+ for (const t of tools) {
127425
+ table.push([
127426
+ t.name,
127427
+ t.s.installed ? source_default.green("\u2713 OK") : source_default.red("\u2717 Missing"),
127428
+ t.s.version || source_default.gray("-")
127429
+ ]);
127430
+ }
127431
+ console.log(table.toString());
127432
+ console.log();
127433
+ const allInstalled = tools.every((t) => t.s.installed) && wtStatus.installed;
127434
+ if (allInstalled) {
127435
+ logger.box([
127436
+ "All tools installed!",
127437
+ "",
127438
+ 'Launch: wt -p "SmartStack Dev"'
127439
+ ], "success");
127440
+ } else {
127441
+ const missing = [];
127442
+ if (!wtStatus.installed) missing.push("Windows Terminal");
127443
+ missing.push(...tools.filter((t) => !t.s.installed).map((t) => t.name));
127444
+ logger.box([
127445
+ `Missing: ${missing.join(", ")}`,
127446
+ "",
127447
+ `Fix with: ${source_default.cyan("ss tmux install")}`
127448
+ ], "warning");
127449
+ process.exit(1);
127450
+ }
127451
+ });
127452
+
127453
+ // src/index.ts
127454
+ var import_fs6 = require("fs");
127455
+ var import_path13 = require("path");
127456
+ var pkg = JSON.parse((0, import_fs6.readFileSync)((0, import_path13.join)(__dirname, "..", "package.json"), "utf-8"));
126878
127457
  var LICENSE_FREE_COMMANDS = ["license", "help", "--help", "-h", "--version", "-v"];
126879
127458
  async function main2() {
126880
127459
  const program2 = new Command();
@@ -126893,6 +127472,7 @@ async function main2() {
126893
127472
  program2.addCommand(adminCommand);
126894
127473
  program2.addCommand(mcpCommand);
126895
127474
  program2.addCommand(derivePrdCommand);
127475
+ program2.addCommand(tmuxCommand);
126896
127476
  const args = process.argv.slice(2);
126897
127477
  const commandName = args[0] || "";
126898
127478
  const requiresLicense = !LICENSE_FREE_COMMANDS.some(