@atlashub/smartstack-cli 4.75.0 → 4.76.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.
- package/dist/index.js +87 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/skills/apex/SKILL.md +2 -2
- package/templates/skills/apex/references/checks/frontend-checks.sh +26 -0
- package/templates/skills/apex/references/checks/seed-checks.sh +47 -7
- package/templates/skills/apex/references/core-seed-data.md +20 -18
- package/templates/skills/apex/references/post-checks.md +18 -1
- package/templates/skills/apex/references/smartstack-api.md +4 -4
- package/templates/skills/apex/references/smartstack-frontend.md +1 -1
- package/templates/skills/apex/references/smartstack-layers.md +6 -6
- package/templates/skills/apex/steps/step-00-init.md +1 -1
- package/templates/skills/apex/steps/step-03b-layer1-seed.md +26 -0
- package/templates/skills/apex/steps/step-03d-layer3-frontend.md +124 -2
- package/templates/skills/apex/steps/step-04-examine.md +163 -0
- package/templates/skills/apex-verify/SKILL.md +110 -0
- package/templates/skills/apex-verify/references/audit-rules.md +50 -0
- package/templates/skills/apex-verify/steps/step-00-init.md +119 -0
- package/templates/skills/apex-verify/steps/step-01-nav-audit.md +92 -0
- package/templates/skills/apex-verify/steps/step-02-crud-audit.md +127 -0
- package/templates/skills/apex-verify/steps/step-03-perm-audit.md +119 -0
- package/templates/skills/apex-verify/steps/step-04-route-audit.md +98 -0
- package/templates/skills/apex-verify/steps/step-05-report.md +110 -0
- package/templates/skills/application/templates-frontend.md +2 -2
- package/templates/skills/business-analyse/SKILL.md +3 -3
- package/templates/skills/business-analyse/_shared.md +37 -0
- package/templates/skills/business-analyse/references/03-json-schemas.md +11 -3
- package/templates/skills/business-analyse/references/03-post-check-validation.md +64 -0
- package/templates/skills/business-analyse/references/canonical-json-formats.md +7 -3
- package/templates/skills/business-analyse/references/robustness-checks.md +1 -1
- package/templates/skills/business-analyse/references/validation-checklist.md +5 -5
- package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +15 -4
- package/templates/skills/business-analyse/steps/step-03-specify.md +162 -4
- package/templates/skills/business-analyse/steps/step-04-consolidate.md +211 -1
- package/templates/skills/business-analyse-handoff/references/agent-handoff-transform-prompt.md +3 -0
- package/templates/skills/business-analyse-html/html/ba-interactive.html +198 -16
- package/templates/skills/business-analyse-html/html/src/scripts/01-data-init.js +64 -0
- package/templates/skills/business-analyse-html/html/src/scripts/05-render-specs.js +80 -11
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-consolidation.js +2 -2
- package/templates/skills/business-analyse-html/html/src/scripts/06-render-mockups.js +6 -3
- package/templates/skills/business-analyse-html/html/src/scripts/12-render-diagrams.js +46 -0
- package/templates/skills/business-analyse-html/references/02-feature-data-building.md +4 -2
- package/templates/skills/business-analyse-html/references/data-build.md +2 -0
- package/templates/skills/business-analyse-html/references/data-mapping.md +88 -21
- package/templates/skills/business-analyse-html/steps/step-02-build-data.md +6 -0
- package/templates/skills/business-analyse-html/steps/step-04-verify.md +92 -3
- package/templates/skills/business-analyse-quick/SKILL.md +807 -0
- package/templates/skills/{sketch → business-analyse-quick}/references/domain-heuristics.md +59 -3
- package/templates/skills/business-analyse-quick/references/prd-schema.md +268 -0
- package/templates/skills/business-analyse-review/references/review-data-mapping.md +6 -0
- package/templates/skills/dev-start/SKILL.md +7 -7
- package/templates/skills/sketch/SKILL.md +15 -153
- package/templates/skills/ui-components/SKILL.md +1 -1
- package/templates/skills/ui-components/patterns/data-table.md +1 -1
package/dist/index.js
CHANGED
|
@@ -128062,7 +128062,6 @@ var import_bcryptjs = __toESM(require_bcryptjs());
|
|
|
128062
128062
|
var import_fs4 = require("fs");
|
|
128063
128063
|
var import_path14 = require("path");
|
|
128064
128064
|
var import_os6 = require("os");
|
|
128065
|
-
var import_crypto8 = require("crypto");
|
|
128066
128065
|
var import_child_process9 = require("child_process");
|
|
128067
128066
|
function tryLoadNativeDriver() {
|
|
128068
128067
|
try {
|
|
@@ -128079,25 +128078,11 @@ var DEFAULT_CONFIG = {
|
|
|
128079
128078
|
var PASSWORD_CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789!@#$%&*";
|
|
128080
128079
|
var PASSWORD_LENGTH = 16;
|
|
128081
128080
|
function generatePassword() {
|
|
128082
|
-
|
|
128083
|
-
const chars = [];
|
|
128081
|
+
let password = "";
|
|
128084
128082
|
for (let i = 0; i < PASSWORD_LENGTH; i++) {
|
|
128085
|
-
|
|
128086
|
-
}
|
|
128087
|
-
|
|
128088
|
-
for (const c of chars) {
|
|
128089
|
-
if (c >= "a" && c <= "z") hasLower = true;
|
|
128090
|
-
else if (c >= "A" && c <= "Z") hasUpper = true;
|
|
128091
|
-
else if (c >= "0" && c <= "9") hasDigit = true;
|
|
128092
|
-
else hasSpecial = true;
|
|
128093
|
-
}
|
|
128094
|
-
const extra = (0, import_crypto8.randomBytes)(4);
|
|
128095
|
-
let pos = 0;
|
|
128096
|
-
if (!hasLower) chars[pos++] = "abcdefghjkmnpqrstuvwxyz"[extra[0] % 23];
|
|
128097
|
-
if (!hasUpper) chars[pos++] = "ABCDEFGHJKLMNPQRSTUVWXYZ"[extra[1] % 24];
|
|
128098
|
-
if (!hasDigit) chars[pos++] = "23456789"[extra[2] % 8];
|
|
128099
|
-
if (!hasSpecial) chars[pos] = "!@#$%&*"[extra[3] % 7];
|
|
128100
|
-
return chars.join("");
|
|
128083
|
+
password += PASSWORD_CHARS.charAt(Math.floor(Math.random() * PASSWORD_CHARS.length));
|
|
128084
|
+
}
|
|
128085
|
+
return password;
|
|
128101
128086
|
}
|
|
128102
128087
|
function findAppSettings(apiFolder) {
|
|
128103
128088
|
if (!(0, import_fs4.existsSync)(apiFolder)) {
|
|
@@ -128275,8 +128260,10 @@ adminCommand.command("reset").description("Reset the localAdmin account password
|
|
|
128275
128260
|
const resetViaSqlCmd = async (sqlAuth) => {
|
|
128276
128261
|
const authLabel = sqlAuth ? "SQL Server Authentication" : "Windows Authentication";
|
|
128277
128262
|
spinner.text = `Using ${authLabel} (sqlcmd)...`;
|
|
128278
|
-
|
|
128263
|
+
logger.debug(`[admin-reset] Using sqlcmd path (${authLabel})`);
|
|
128264
|
+
const checkQuery = `SET NOCOUNT ON; SELECT COUNT(*) FROM [core].[auth_Users] WHERE Email = '${adminEmail}'`;
|
|
128279
128265
|
const countResult = executeSqlCmd(connInfo.server, connInfo.database, checkQuery, sqlAuth);
|
|
128266
|
+
logger.debug(`[admin-reset] COUNT result: "${countResult}"`);
|
|
128280
128267
|
const exists = parseInt(countResult, 10) > 0;
|
|
128281
128268
|
if (!exists) {
|
|
128282
128269
|
spinner.fail(`Account ${source_default.yellow(adminEmail)} does not exist.`);
|
|
@@ -128287,23 +128274,50 @@ adminCommand.command("reset").description("Reset the localAdmin account password
|
|
|
128287
128274
|
spinner.text = "Generating new password...";
|
|
128288
128275
|
const newPassword = generatePassword();
|
|
128289
128276
|
const passwordHash = await import_bcryptjs.default.hash(newPassword, 12);
|
|
128290
|
-
|
|
128291
|
-
|
|
128292
|
-
|
|
128293
|
-
|
|
128294
|
-
|
|
128295
|
-
sqlAuth
|
|
128296
|
-
).trim();
|
|
128297
|
-
const updateQuery = `UPDATE [core].[auth_Users] SET PasswordHash = '${passwordHash}', MustChangePassword = 0, IsLocked = 0, LockoutEnd = NULL, UpdatedAt = GETUTCDATE() WHERE Email = '${adminEmail}'`;
|
|
128298
|
-
executeSqlCmd(connInfo.server, connInfo.database, updateQuery, sqlAuth);
|
|
128299
|
-
const deleteSessionsQuery = `DELETE FROM [core].[auth_Sessions] WHERE UserId = '${userId}' AND IsSuccessful = 0`;
|
|
128277
|
+
logger.debug(`[admin-reset] Password length: ${newPassword.length}, Hash prefix: ${passwordHash.substring(0, 7)}`);
|
|
128278
|
+
spinner.text = "Updating password...";
|
|
128279
|
+
const updateQuery = `SET NOCOUNT ON; UPDATE [core].[auth_Users] SET PasswordHash = '${passwordHash}', MustChangePassword = 0, UpdatedAt = GETUTCDATE() WHERE Email = '${adminEmail}'`;
|
|
128280
|
+
const updateResult = executeSqlCmd(connInfo.server, connInfo.database, updateQuery, sqlAuth);
|
|
128281
|
+
logger.debug(`[admin-reset] UPDATE result: "${updateResult}"`);
|
|
128300
128282
|
try {
|
|
128301
|
-
executeSqlCmd(
|
|
128302
|
-
|
|
128283
|
+
executeSqlCmd(
|
|
128284
|
+
connInfo.server,
|
|
128285
|
+
connInfo.database,
|
|
128286
|
+
`SET NOCOUNT ON; UPDATE [core].[auth_Users] SET IsLocked = 0, LockoutEnd = NULL WHERE Email = '${adminEmail}'`,
|
|
128287
|
+
sqlAuth
|
|
128288
|
+
);
|
|
128289
|
+
logger.debug("[admin-reset] Account unlocked (IsLocked = 0)");
|
|
128290
|
+
} catch (unlockErr) {
|
|
128291
|
+
logger.debug(`[admin-reset] Unlock skipped (columns may not exist): ${unlockErr instanceof Error ? unlockErr.message : unlockErr}`);
|
|
128303
128292
|
}
|
|
128304
|
-
|
|
128293
|
+
try {
|
|
128294
|
+
executeSqlCmd(
|
|
128295
|
+
connInfo.server,
|
|
128296
|
+
connInfo.database,
|
|
128297
|
+
`SET NOCOUNT ON; DELETE FROM [core].[auth_Sessions] WHERE UserId = (SELECT Id FROM [core].[auth_Users] WHERE Email = '${adminEmail}') AND IsSuccessful = 0`,
|
|
128298
|
+
sqlAuth
|
|
128299
|
+
);
|
|
128300
|
+
logger.debug("[admin-reset] Failed login sessions cleared");
|
|
128301
|
+
} catch (sessionErr) {
|
|
128302
|
+
logger.debug(`[admin-reset] Session cleanup skipped: ${sessionErr instanceof Error ? sessionErr.message : sessionErr}`);
|
|
128303
|
+
}
|
|
128304
|
+
const verifyQuery = `SET NOCOUNT ON; SELECT PasswordHash FROM [core].[auth_Users] WHERE Email = '${adminEmail}'`;
|
|
128305
|
+
const storedHash = executeSqlCmd(connInfo.server, connInfo.database, verifyQuery, sqlAuth).trim();
|
|
128306
|
+
if (!storedHash) {
|
|
128307
|
+
spinner.fail("Password update failed: no hash found in database after UPDATE");
|
|
128308
|
+
process.exit(1);
|
|
128309
|
+
}
|
|
128310
|
+
const hashMatch = await import_bcryptjs.default.compare(newPassword, storedHash);
|
|
128311
|
+
if (!hashMatch) {
|
|
128312
|
+
spinner.fail("Password update failed: stored hash does not match generated password");
|
|
128313
|
+
logger.error(`Expected hash prefix: ${passwordHash.substring(0, 10)}`);
|
|
128314
|
+
logger.error(`Stored hash prefix: ${storedHash.substring(0, 10)}`);
|
|
128315
|
+
logger.error(`Hash lengths: expected=${passwordHash.length}, stored=${storedHash.length}`);
|
|
128316
|
+
process.exit(1);
|
|
128317
|
+
}
|
|
128318
|
+
logger.debug(`[admin-reset] Verification OK \u2014 hash matches password`);
|
|
128319
|
+
spinner.succeed("Password reset successfully!");
|
|
128305
128320
|
displayPasswordResult(adminEmail, newPassword);
|
|
128306
|
-
spinner.stop();
|
|
128307
128321
|
};
|
|
128308
128322
|
const displayPasswordResult = (email, password) => {
|
|
128309
128323
|
if (options.json) {
|
|
@@ -128330,6 +128344,7 @@ adminCommand.command("reset").description("Reset the localAdmin account password
|
|
|
128330
128344
|
console.log();
|
|
128331
128345
|
};
|
|
128332
128346
|
const resetViaMssql = async (sqlModule) => {
|
|
128347
|
+
logger.debug(`[admin-reset] Using mssql (node driver) path`);
|
|
128333
128348
|
spinner.text = "Connected. Checking account...";
|
|
128334
128349
|
const checkResult = await sqlModule.query`
|
|
128335
128350
|
SELECT COUNT(*) as count
|
|
@@ -128347,28 +128362,57 @@ adminCommand.command("reset").description("Reset the localAdmin account password
|
|
|
128347
128362
|
spinner.text = "Generating new password...";
|
|
128348
128363
|
const newPassword = generatePassword();
|
|
128349
128364
|
const passwordHash = await import_bcryptjs.default.hash(newPassword, 12);
|
|
128350
|
-
|
|
128351
|
-
|
|
128365
|
+
logger.debug(`[admin-reset] Password length: ${newPassword.length}, Hash prefix: ${passwordHash.substring(0, 7)}`);
|
|
128366
|
+
spinner.text = "Updating password...";
|
|
128367
|
+
const updateResult = await sqlModule.query`
|
|
128352
128368
|
UPDATE [core].[auth_Users]
|
|
128353
128369
|
SET PasswordHash = ${passwordHash},
|
|
128354
128370
|
MustChangePassword = ${false},
|
|
128355
|
-
IsLocked = ${false},
|
|
128356
|
-
LockoutEnd = ${null},
|
|
128357
128371
|
UpdatedAt = ${/* @__PURE__ */ new Date()}
|
|
128358
128372
|
WHERE Email = ${adminEmail}
|
|
128359
128373
|
`;
|
|
128374
|
+
logger.debug(`[admin-reset] UPDATE rowsAffected: ${JSON.stringify(updateResult.rowsAffected)}`);
|
|
128375
|
+
if (!updateResult.rowsAffected || updateResult.rowsAffected[0] === 0) {
|
|
128376
|
+
await sqlModule.close();
|
|
128377
|
+
spinner.fail("Password update failed: UPDATE affected 0 rows");
|
|
128378
|
+
process.exit(1);
|
|
128379
|
+
}
|
|
128380
|
+
try {
|
|
128381
|
+
await sqlModule.query`
|
|
128382
|
+
UPDATE [core].[auth_Users]
|
|
128383
|
+
SET IsLocked = ${false}, LockoutEnd = ${null}
|
|
128384
|
+
WHERE Email = ${adminEmail}
|
|
128385
|
+
`;
|
|
128386
|
+
logger.debug("[admin-reset] Account unlocked (IsLocked = 0)");
|
|
128387
|
+
} catch (unlockErr) {
|
|
128388
|
+
logger.debug(`[admin-reset] Unlock skipped (columns may not exist): ${unlockErr instanceof Error ? unlockErr.message : unlockErr}`);
|
|
128389
|
+
}
|
|
128360
128390
|
try {
|
|
128361
128391
|
await sqlModule.query`
|
|
128362
128392
|
DELETE FROM [core].[auth_Sessions]
|
|
128363
128393
|
WHERE UserId = (SELECT Id FROM [core].[auth_Users] WHERE Email = ${adminEmail})
|
|
128364
128394
|
AND IsSuccessful = ${false}
|
|
128365
128395
|
`;
|
|
128366
|
-
|
|
128396
|
+
logger.debug("[admin-reset] Failed login sessions cleared");
|
|
128397
|
+
} catch (sessionErr) {
|
|
128398
|
+
logger.debug(`[admin-reset] Session cleanup skipped: ${sessionErr instanceof Error ? sessionErr.message : sessionErr}`);
|
|
128399
|
+
}
|
|
128400
|
+
const verifyResult = await sqlModule.query`
|
|
128401
|
+
SELECT PasswordHash FROM [core].[auth_Users] WHERE Email = ${adminEmail}
|
|
128402
|
+
`;
|
|
128403
|
+
const storedHash = verifyResult.recordset[0]?.PasswordHash;
|
|
128404
|
+
const hashMatch = storedHash ? await import_bcryptjs.default.compare(newPassword, storedHash) : false;
|
|
128405
|
+
if (!hashMatch) {
|
|
128406
|
+
await sqlModule.close();
|
|
128407
|
+
spinner.fail("Password update failed: stored hash does not match generated password");
|
|
128408
|
+
logger.error(`Expected hash prefix: ${passwordHash.substring(0, 10)}`);
|
|
128409
|
+
logger.error(`Stored hash prefix: ${(storedHash || "(null)").substring(0, 10)}`);
|
|
128410
|
+
process.exit(1);
|
|
128367
128411
|
}
|
|
128412
|
+
logger.debug(`[admin-reset] Verification OK \u2014 hash matches password`);
|
|
128368
128413
|
await sqlModule.close();
|
|
128369
|
-
spinner.succeed("Password reset
|
|
128414
|
+
spinner.succeed("Password reset successfully!");
|
|
128370
128415
|
displayPasswordResult(adminEmail, newPassword);
|
|
128371
|
-
spinner.stop();
|
|
128372
128416
|
};
|
|
128373
128417
|
const tryWithSqlCmd = async () => {
|
|
128374
128418
|
try {
|
|
@@ -128389,8 +128433,10 @@ adminCommand.command("reset").description("Reset the localAdmin account password
|
|
|
128389
128433
|
}
|
|
128390
128434
|
};
|
|
128391
128435
|
try {
|
|
128436
|
+
logger.debug(`[admin-reset] Windows Auth: ${connInfo.useWindowsAuth}, Server: ${connInfo.server}, Database: ${connInfo.database}`);
|
|
128392
128437
|
if (connInfo.useWindowsAuth) {
|
|
128393
128438
|
const nativeDriver = tryLoadNativeDriver();
|
|
128439
|
+
logger.debug(`[admin-reset] msnodesqlv8 available: ${!!nativeDriver}`);
|
|
128394
128440
|
let nativeConnected = false;
|
|
128395
128441
|
if (nativeDriver) {
|
|
128396
128442
|
try {
|