@atlashub/smartstack-cli 2.7.3 → 2.8.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 (56) hide show
  1. package/.documentation/agents.html +0 -4
  2. package/.documentation/business-analyse.html +0 -4
  3. package/.documentation/cli-commands.html +0 -4
  4. package/.documentation/commands.html +0 -77
  5. package/.documentation/css/styles.css +0 -8
  6. package/.documentation/efcore.html +0 -4
  7. package/.documentation/gitflow.html +0 -4
  8. package/.documentation/hooks.html +0 -4
  9. package/.documentation/index.html +2 -28
  10. package/.documentation/init.html +8 -14
  11. package/.documentation/installation.html +0 -11
  12. package/.documentation/js/app.js +2 -16
  13. package/.documentation/ralph-loop.html +0 -4
  14. package/.documentation/test-web.html +0 -4
  15. package/README.md +0 -1
  16. package/dist/index.js +100 -23
  17. package/dist/index.js.map +1 -1
  18. package/package.json +2 -3
  19. package/templates/agents/docs-sync-checker.md +2 -2
  20. package/templates/hooks/docs-drift-check.md +4 -5
  21. package/templates/skills/_resources/context-digest-template.md +2 -2
  22. package/templates/skills/_resources/doc-context-cache.md +0 -2
  23. package/templates/skills/_resources/docs-manifest-schema.md +1 -3
  24. package/templates/skills/_resources/mcp-validate-documentation-spec.md +1 -3
  25. package/templates/skills/_shared.md +24 -25
  26. package/templates/skills/application/steps/step-04-backend.md +185 -11
  27. package/templates/skills/application/steps/step-06-migration.md +41 -2
  28. package/templates/skills/application/templates-seed.md +151 -0
  29. package/templates/skills/business-analyse/steps/step-05-handoff.md +59 -17
  30. package/templates/skills/controller/steps/step-01-analyze.md +1 -1
  31. package/templates/skills/ralph-loop/steps/step-01-task.md +21 -1
  32. package/templates/skills/ralph-loop/steps/step-02-execute.md +75 -3
  33. package/.documentation/apex.html +0 -1027
  34. package/templates/skills/apex/SKILL.md +0 -297
  35. package/templates/skills/apex/steps/step-00-init.md +0 -212
  36. package/templates/skills/apex/steps/step-01-analyze.md +0 -263
  37. package/templates/skills/apex/steps/step-02-plan.md +0 -255
  38. package/templates/skills/apex/steps/step-03-execute.md +0 -217
  39. package/templates/skills/apex/steps/step-04-validate.md +0 -273
  40. package/templates/skills/apex/steps/step-04b-doc-sync.md +0 -162
  41. package/templates/skills/apex/steps/step-05-examine.md +0 -214
  42. package/templates/skills/apex/steps/step-06-resolve.md +0 -181
  43. package/templates/skills/apex/steps/step-07-tests.md +0 -206
  44. package/templates/skills/apex/steps/step-08-run-tests.md +0 -207
  45. package/templates/skills/apex/templates/00-context.md +0 -46
  46. package/templates/skills/apex/templates/01-analyze.md +0 -63
  47. package/templates/skills/apex/templates/02-plan.md +0 -63
  48. package/templates/skills/apex/templates/03-execute.md +0 -34
  49. package/templates/skills/apex/templates/04-validate.md +0 -61
  50. package/templates/skills/apex/templates/04b-doc-sync.md +0 -31
  51. package/templates/skills/apex/templates/05-examine.md +0 -58
  52. package/templates/skills/apex/templates/06-resolve.md +0 -39
  53. package/templates/skills/apex/templates/07-tests.md +0 -56
  54. package/templates/skills/apex/templates/08-run-tests.md +0 -41
  55. package/templates/skills/apex/templates/README.md +0 -69
  56. package/templates/skills/apex/templates/context-digest.md +0 -35
package/dist/index.js CHANGED
@@ -37233,7 +37233,7 @@ var require_lodash5 = __commonJS({
37233
37233
  function isObjectLike(value) {
37234
37234
  return !!value && typeof value == "object";
37235
37235
  }
37236
- function isPlainObject(value) {
37236
+ function isPlainObject2(value) {
37237
37237
  if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
37238
37238
  return false;
37239
37239
  }
@@ -37244,7 +37244,7 @@ var require_lodash5 = __commonJS({
37244
37244
  var Ctor = hasOwnProperty.call(proto2, "constructor") && proto2.constructor;
37245
37245
  return typeof Ctor == "function" && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString;
37246
37246
  }
37247
- module2.exports = isPlainObject;
37247
+ module2.exports = isPlainObject2;
37248
37248
  }
37249
37249
  });
37250
37250
 
@@ -37360,7 +37360,7 @@ var require_sign = __commonJS({
37360
37360
  var isBoolean = require_lodash2();
37361
37361
  var isInteger = require_lodash3();
37362
37362
  var isNumber = require_lodash4();
37363
- var isPlainObject = require_lodash5();
37363
+ var isPlainObject2 = require_lodash5();
37364
37364
  var isString = require_lodash6();
37365
37365
  var once = require_lodash7();
37366
37366
  var { KeyObject, createSecretKey, createPrivateKey } = require("crypto");
@@ -37379,7 +37379,7 @@ var require_sign = __commonJS({
37379
37379
  return isString(value) || Array.isArray(value);
37380
37380
  }, message: '"audience" must be a string or array' },
37381
37381
  algorithm: { isValid: includes.bind(null, SUPPORTED_ALGS), message: '"algorithm" must be a valid string enum value' },
37382
- header: { isValid: isPlainObject, message: '"header" must be an object' },
37382
+ header: { isValid: isPlainObject2, message: '"header" must be an object' },
37383
37383
  encoding: { isValid: isString, message: '"encoding" must be a string' },
37384
37384
  issuer: { isValid: isString, message: '"issuer" must be a string' },
37385
37385
  subject: { isValid: isString, message: '"subject" must be a string' },
@@ -37396,7 +37396,7 @@ var require_sign = __commonJS({
37396
37396
  nbf: { isValid: isNumber, message: '"nbf" should be a number of seconds' }
37397
37397
  };
37398
37398
  function validate3(schema, allowUnknown, object, parameterName) {
37399
- if (!isPlainObject(object)) {
37399
+ if (!isPlainObject2(object)) {
37400
37400
  throw new Error('Expected "' + parameterName + '" to be a plain object.');
37401
37401
  }
37402
37402
  Object.keys(object).forEach(function(key) {
@@ -44464,16 +44464,16 @@ var require_chainedTokenCredential = __commonJS({
44464
44464
  // node_modules/uuid/dist/esm-node/rng.js
44465
44465
  function rng() {
44466
44466
  if (poolPtr > rnds8Pool.length - 16) {
44467
- import_crypto3.default.randomFillSync(rnds8Pool);
44467
+ import_crypto4.default.randomFillSync(rnds8Pool);
44468
44468
  poolPtr = 0;
44469
44469
  }
44470
44470
  return rnds8Pool.slice(poolPtr, poolPtr += 16);
44471
44471
  }
44472
- var import_crypto3, rnds8Pool, poolPtr;
44472
+ var import_crypto4, rnds8Pool, poolPtr;
44473
44473
  var init_rng = __esm({
44474
44474
  "node_modules/uuid/dist/esm-node/rng.js"() {
44475
44475
  "use strict";
44476
- import_crypto3 = __toESM(require("crypto"));
44476
+ import_crypto4 = __toESM(require("crypto"));
44477
44477
  rnds8Pool = new Uint8Array(256);
44478
44478
  poolPtr = rnds8Pool.length;
44479
44479
  }
@@ -44678,13 +44678,13 @@ function md5(bytes) {
44678
44678
  } else if (typeof bytes === "string") {
44679
44679
  bytes = Buffer.from(bytes, "utf8");
44680
44680
  }
44681
- return import_crypto4.default.createHash("md5").update(bytes).digest();
44681
+ return import_crypto5.default.createHash("md5").update(bytes).digest();
44682
44682
  }
44683
- var import_crypto4, md5_default;
44683
+ var import_crypto5, md5_default;
44684
44684
  var init_md5 = __esm({
44685
44685
  "node_modules/uuid/dist/esm-node/md5.js"() {
44686
44686
  "use strict";
44687
- import_crypto4 = __toESM(require("crypto"));
44687
+ import_crypto5 = __toESM(require("crypto"));
44688
44688
  md5_default = md5;
44689
44689
  }
44690
44690
  });
@@ -44733,13 +44733,13 @@ function sha1(bytes) {
44733
44733
  } else if (typeof bytes === "string") {
44734
44734
  bytes = Buffer.from(bytes, "utf8");
44735
44735
  }
44736
- return import_crypto5.default.createHash("sha1").update(bytes).digest();
44736
+ return import_crypto6.default.createHash("sha1").update(bytes).digest();
44737
44737
  }
44738
- var import_crypto5, sha1_default;
44738
+ var import_crypto6, sha1_default;
44739
44739
  var init_sha1 = __esm({
44740
44740
  "node_modules/uuid/dist/esm-node/sha1.js"() {
44741
44741
  "use strict";
44742
- import_crypto5 = __toESM(require("crypto"));
44742
+ import_crypto6 = __toESM(require("crypto"));
44743
44743
  sha1_default = sha1;
44744
44744
  }
44745
44745
  });
@@ -112849,8 +112849,6 @@ async function uninstallCommands(options = {}) {
112849
112849
  const ourDirs = [
112850
112850
  "gitflow",
112851
112851
  "gitflow.md",
112852
- "apex",
112853
- "apex.md",
112854
112852
  "efcore",
112855
112853
  "efcore.md",
112856
112854
  "business-analyse",
@@ -113022,8 +113020,7 @@ async function checkInstallation(options = {}) {
113022
113020
  const commandsDir = (0, import_path2.join)(claudeDir, "commands");
113023
113021
  if (await import_fs_extra2.default.pathExists(commandsDir)) {
113024
113022
  const gitflowExists = await import_fs_extra2.default.pathExists((0, import_path2.join)(commandsDir, "gitflow.md"));
113025
- const apexExists = await import_fs_extra2.default.pathExists((0, import_path2.join)(commandsDir, "apex.md"));
113026
- result.components.commands.installed = gitflowExists || apexExists;
113023
+ result.components.commands.installed = gitflowExists;
113027
113024
  const files = await getTemplateFiles(commandsDir);
113028
113025
  result.components.commands.count = files.filter((f) => f.endsWith(".md")).length;
113029
113026
  }
@@ -113386,7 +113383,6 @@ var installCommand = new Command("install").alias("i").description("Install Smar
113386
113383
  ` ${source_default.cyan("/gitflow finish")} - Finish and merge`,
113387
113384
  "",
113388
113385
  source_default.bold("Development:"),
113389
- ` ${source_default.cyan("/apex")} - APEX methodology`,
113390
113386
  ` ${source_default.cyan("/debug")} - Systematic debugging`,
113391
113387
  ` ${source_default.cyan("/refactor")} - Code refactoring`,
113392
113388
  "",
@@ -115918,7 +115914,7 @@ var updateCommand = new Command("update").description("Update commands to the la
115918
115914
  // src/commands/docs.ts
115919
115915
  var import_path4 = require("path");
115920
115916
  var import_fs2 = require("fs");
115921
- var DOCS_PAGES = ["index", "installation", "init", "commands", "cli-commands", "agents", "apex", "business-analyse", "gitflow", "efcore", "hooks", "ralph-loop", "test-web"];
115917
+ var DOCS_PAGES = ["index", "installation", "init", "commands", "cli-commands", "agents", "business-analyse", "gitflow", "efcore", "hooks", "ralph-loop", "test-web"];
115922
115918
  var docsCommand = new Command("docs").alias("d").description("Open SmartStack documentation in browser").argument("[page]", "Documentation page to open", "index").option("-l, --list", "List available documentation pages").action(async (page, options) => {
115923
115919
  if (options.list) {
115924
115920
  logger.header("Available Documentation Pages");
@@ -116586,6 +116582,13 @@ EndGlobal
116586
116582
  }
116587
116583
  }
116588
116584
  }
116585
+ for (const placeholder of ["appsettings.json", "appsettings.Development.json"]) {
116586
+ const placeholderPath = (0, import_path6.join)(apiDir, placeholder);
116587
+ if (await import_fs_extra5.default.pathExists(placeholderPath)) {
116588
+ await import_fs_extra5.default.remove(placeholderPath);
116589
+ logger.info(`Removed placeholder: ${projectName}.Api/${placeholder}`);
116590
+ }
116591
+ }
116589
116592
  }
116590
116593
  if (!dryRun) {
116591
116594
  for (const { proj } of projects) {
@@ -124531,7 +124534,36 @@ var glob = Object.assign(glob_, {
124531
124534
  });
124532
124535
  glob.glob = glob;
124533
124536
 
124537
+ // src/lib/config-sync.ts
124538
+ var import_crypto3 = require("crypto");
124539
+ function addMissingKeys(target, template, prefix = "") {
124540
+ const added = [];
124541
+ for (const key of Object.keys(template)) {
124542
+ const path5 = prefix ? `${prefix}.${key}` : key;
124543
+ if (!(key in target)) {
124544
+ target[key] = template[key];
124545
+ added.push(path5);
124546
+ } else if (isPlainObject(target[key]) && isPlainObject(template[key])) {
124547
+ const nested = addMissingKeys(
124548
+ target[key],
124549
+ template[key],
124550
+ path5
124551
+ );
124552
+ added.push(...nested);
124553
+ }
124554
+ }
124555
+ return added;
124556
+ }
124557
+ function resolveTemplatePlaceholders(content, projectName) {
124558
+ const secret = (0, import_crypto3.randomBytes)(32).toString("hex");
124559
+ return content.replace(/\{\{ProjectName\}\}/g, projectName).replace(/\{\{GenerateRandomSecret\}\}/g, secret).replace(/\{\{ProjectDomain\}\}/g, `${projectName.toLowerCase()}.app`).replace(/\{\{ProjectNameLower\}\}/g, projectName.toLowerCase());
124560
+ }
124561
+ function isPlainObject(value) {
124562
+ return typeof value === "object" && value !== null && !Array.isArray(value);
124563
+ }
124564
+
124534
124565
  // src/commands/upgrade.ts
124566
+ var TEMPLATES_DIR3 = (0, import_path7.join)((0, import_path7.dirname)(__dirname), "templates", "project");
124535
124567
  async function getLatestNuGetVersion2(packageName, prerelease) {
124536
124568
  try {
124537
124569
  const response = await fetch(`https://api.nuget.org/v3-flatcontainer/${packageName.toLowerCase()}/index.json`);
@@ -124789,6 +124821,31 @@ async function executeMigrations(projectDir, fromVersion, toVersion, dryRun) {
124789
124821
  hasErrors
124790
124822
  };
124791
124823
  }
124824
+ async function syncAppSettings(projectDir, baseNamespace, dryRun) {
124825
+ const appSettingsPath = (0, import_path7.join)(projectDir, "src", `${baseNamespace}.Api`, "appsettings.json");
124826
+ if (!await import_fs_extra6.default.pathExists(appSettingsPath)) {
124827
+ logger.warning("appsettings.json not found, skipping config sync");
124828
+ return [];
124829
+ }
124830
+ const templatePath = (0, import_path7.join)(TEMPLATES_DIR3, "appsettings.json.template");
124831
+ if (!await import_fs_extra6.default.pathExists(templatePath)) {
124832
+ logger.warning("appsettings.json.template not found, skipping config sync");
124833
+ return [];
124834
+ }
124835
+ const rawTemplate = await import_fs_extra6.default.readFile(templatePath, "utf-8");
124836
+ const resolvedTemplate = resolveTemplatePlaceholders(rawTemplate, baseNamespace);
124837
+ const templateJson = JSON.parse(resolvedTemplate);
124838
+ const clientContent = await import_fs_extra6.default.readFile(appSettingsPath, "utf-8");
124839
+ const clientJson = JSON.parse(clientContent);
124840
+ const added = addMissingKeys(clientJson, templateJson);
124841
+ if (added.length === 0) {
124842
+ return [];
124843
+ }
124844
+ if (!dryRun) {
124845
+ await import_fs_extra6.default.writeFile(appSettingsPath, JSON.stringify(clientJson, null, 2));
124846
+ }
124847
+ return added;
124848
+ }
124792
124849
  var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack packages to the latest version").option("--preview", "Upgrade to latest preview/prerelease version").option("--dry-run", "Show what would be upgraded without actually upgrading").action(async (options) => {
124793
124850
  logger.header("SmartStack Package Upgrade");
124794
124851
  const dryRun = options.dryRun || false;
@@ -124800,7 +124857,8 @@ var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack pack
124800
124857
  otherPkgSkipped: 0,
124801
124858
  otherPkgFailed: 0,
124802
124859
  npmUpgraded: false,
124803
- npmSkipped: false
124860
+ npmSkipped: false,
124861
+ configSynced: 0
124804
124862
  };
124805
124863
  if (dryRun) {
124806
124864
  logger.warning("DRY RUN MODE - No packages will be upgraded");
@@ -124975,6 +125033,22 @@ var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack pack
124975
125033
  logger.info("No code migrations needed.");
124976
125034
  console.log();
124977
125035
  }
125036
+ logger.info("Syncing appsettings.json...");
125037
+ const addedKeys = await syncAppSettings(projectDir, config.baseNamespace, dryRun);
125038
+ result.configSynced = addedKeys.length;
125039
+ if (addedKeys.length > 0) {
125040
+ if (dryRun) {
125041
+ logger.warning(`[DRY RUN] Would add ${addedKeys.length} new setting(s) to appsettings.json`);
125042
+ }
125043
+ for (const key of addedKeys) {
125044
+ logger.info(` ${source_default.green("+")} ${key}`);
125045
+ }
125046
+ logger.success(`${addedKeys.length} new setting(s) added to appsettings.json`);
125047
+ console.log();
125048
+ } else {
125049
+ logger.info(`appsettings.json ${source_default.green("\u2713")} up to date`);
125050
+ console.log();
125051
+ }
124978
125052
  if (!dryRun && nugetVersion) {
124979
125053
  config.smartStackVersion = nugetVersion;
124980
125054
  const configPath = (0, import_path7.join)(projectDir, ".smartstack", "config.json");
@@ -124982,7 +125056,7 @@ var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack pack
124982
125056
  logger.success(`Updated config version to ${source_default.cyan(nugetVersion)}`);
124983
125057
  console.log();
124984
125058
  }
124985
- const totalChanged = result.nugetUpgraded + result.otherPkgUpdated + (result.npmUpgraded ? 1 : 0) + migrationSummary.totalApplied;
125059
+ const totalChanged = result.nugetUpgraded + result.otherPkgUpdated + (result.npmUpgraded ? 1 : 0) + migrationSummary.totalApplied + result.configSynced;
124986
125060
  const allUpToDate = totalChanged === 0 && result.nugetFailed === 0 && result.otherPkgFailed === 0;
124987
125061
  if (allUpToDate) {
124988
125062
  const summary = [
@@ -125023,6 +125097,9 @@ var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack pack
125023
125097
  if (migrationSummary.totalApplied > 0) {
125024
125098
  lines.push(` ${source_default.green("\u2713")} Code migrations: ${migrationSummary.totalApplied} applied`);
125025
125099
  }
125100
+ if (result.configSynced > 0) {
125101
+ lines.push(` ${source_default.green("\u2713")} Config: ${result.configSynced} new setting(s) added`);
125102
+ }
125026
125103
  lines.push("");
125027
125104
  lines.push(source_default.yellow("Next steps:"));
125028
125105
  lines.push(` 1. Review changes: ${source_default.cyan("git diff")}`);
@@ -126767,7 +126844,7 @@ async function main2() {
126767
126844
  \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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
126768
126845
  \u2551 \u2551
126769
126846
  \u2551 ${source_default.bold("SmartStack")} Claude Commands - v${pkg.version} \u2551
126770
- \u2551 GitFlow, APEX, EF Core, Prompts & more \u2551
126847
+ \u2551 GitFlow, EF Core, Prompts & more \u2551
126771
126848
  \u2551 \u2551
126772
126849
  \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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
126773
126850
  `));