qa360 2.0.7 ā 2.0.9
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/commands/history.js +8 -4
- package/dist/core/secrets/crypto.js +2 -4
- package/dist/index.js +18 -24
- package/package.json +2 -2
package/dist/commands/history.js
CHANGED
|
@@ -51,8 +51,12 @@ export class QA360History {
|
|
|
51
51
|
// Display table
|
|
52
52
|
console.log(chalk.bold('\nš QA360 Run History\n'));
|
|
53
53
|
const table = runs.map((run) => {
|
|
54
|
-
const duration = run.ended_at ? run.ended_at - run.started_at : null;
|
|
55
|
-
|
|
54
|
+
const duration = run.ended_at && run.started_at ? run.ended_at - run.started_at : null;
|
|
55
|
+
let durationStr = 'running';
|
|
56
|
+
if (duration !== null) {
|
|
57
|
+
const durationSec = Math.round(duration / 1000);
|
|
58
|
+
durationStr = durationSec > 0 ? `${durationSec}s` : '< 1s';
|
|
59
|
+
}
|
|
56
60
|
// Format status without chalk for console.table compatibility
|
|
57
61
|
const statusIcon = run.status === 'passed' ? 'ā
' :
|
|
58
62
|
run.status === 'failed' ? 'ā' :
|
|
@@ -425,8 +429,8 @@ export class QA360History {
|
|
|
425
429
|
}
|
|
426
430
|
// 1. Find runs to delete (beyond keepLast, not pinned)
|
|
427
431
|
const allRuns = await vault.listRuns({ limit: 1000 });
|
|
428
|
-
const pinnedRuns = allRuns.filter(r => r.pinned);
|
|
429
|
-
const unpinnedRuns = allRuns.filter(r => !r.pinned);
|
|
432
|
+
const pinnedRuns = allRuns.filter((r) => r.pinned);
|
|
433
|
+
const unpinnedRuns = allRuns.filter((r) => !r.pinned);
|
|
430
434
|
console.log(chalk.gray(`š Total runs: ${allRuns.length}`));
|
|
431
435
|
console.log(chalk.gray(`š Pinned runs: ${pinnedRuns.length}`));
|
|
432
436
|
console.log(chalk.gray(`š¦ Unpinned runs: ${unpinnedRuns.length}`));
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* AES-256-GCM encryption with PBKDF2 key derivation
|
|
4
4
|
*/
|
|
5
5
|
import { createCipheriv, createDecipheriv, randomBytes, pbkdf2Sync, createHash } from 'crypto';
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
import os from 'os';
|
|
6
8
|
export class SecretsCrypto {
|
|
7
9
|
static ALGORITHM = 'aes-256-gcm';
|
|
8
10
|
static KEY_LENGTH = 32; // 256 bits
|
|
@@ -126,7 +128,6 @@ export class SecretsCrypto {
|
|
|
126
128
|
* Get password from macOS Keychain
|
|
127
129
|
*/
|
|
128
130
|
static async getMacOSKeychainPassword() {
|
|
129
|
-
const { execSync } = require('child_process');
|
|
130
131
|
try {
|
|
131
132
|
// Try to get existing password
|
|
132
133
|
const result = execSync('security find-generic-password -a qa360 -s "QA360 Secrets" -w', { encoding: 'utf8', stdio: 'pipe' });
|
|
@@ -143,7 +144,6 @@ export class SecretsCrypto {
|
|
|
143
144
|
* Get password from Linux keyring (using secret-tool)
|
|
144
145
|
*/
|
|
145
146
|
static async getLinuxKeychainPassword() {
|
|
146
|
-
const { execSync } = require('child_process');
|
|
147
147
|
try {
|
|
148
148
|
// Try to get existing password
|
|
149
149
|
const result = execSync('secret-tool lookup application qa360 service secrets', { encoding: 'utf8', stdio: 'pipe' });
|
|
@@ -160,7 +160,6 @@ export class SecretsCrypto {
|
|
|
160
160
|
* Get password from Windows Credential Manager
|
|
161
161
|
*/
|
|
162
162
|
static async getWindowsCredentialPassword() {
|
|
163
|
-
const { execSync } = require('child_process');
|
|
164
163
|
try {
|
|
165
164
|
// Try to get existing password
|
|
166
165
|
const result = execSync('powershell -Command "Get-StoredCredential -Target QA360-Secrets | Select-Object -ExpandProperty Password"', { encoding: 'utf8', stdio: 'pipe' });
|
|
@@ -177,7 +176,6 @@ export class SecretsCrypto {
|
|
|
177
176
|
* Generate machine-specific password as fallback
|
|
178
177
|
*/
|
|
179
178
|
static generateMachinePassword() {
|
|
180
|
-
const os = require('os');
|
|
181
179
|
// Collect machine-specific data
|
|
182
180
|
const machineData = [
|
|
183
181
|
os.hostname(),
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import { runCommand } from './commands/run.js';
|
|
|
22
22
|
import { reportCommand } from './commands/report.js';
|
|
23
23
|
import { verifyCommand } from './commands/verify.js';
|
|
24
24
|
import { explainCommand } from './commands/explain.js';
|
|
25
|
-
|
|
25
|
+
import { packValidateCommand, packLintCommand, packMigrateCommand } from './commands/pack.js';
|
|
26
26
|
import { secretsAddCommand, secretsListCommand, secretsRemoveCommand, secretsDoctorCommand, secretsExportCommand } from './commands/secrets.js';
|
|
27
27
|
import { createHistoryCommands } from './commands/history.js';
|
|
28
28
|
import { createAICommands } from './commands/ai.js';
|
|
@@ -138,36 +138,30 @@ program
|
|
|
138
138
|
await explainCommand(input, options);
|
|
139
139
|
});
|
|
140
140
|
// Pack commands (Phase 2)
|
|
141
|
-
/*
|
|
142
|
-
// TODO: Re-enable after fixing pack v2 imports
|
|
143
141
|
const packCommand = program
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
.command('pack')
|
|
143
|
+
.description('Pack configuration management');
|
|
147
144
|
packCommand
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
145
|
+
.command('validate [pack]')
|
|
146
|
+
.description('Validate pack.yml (auto-detects v1 or v2)')
|
|
147
|
+
.option('--check-files', 'Verify that referenced test files exist')
|
|
148
|
+
.action(async (pack, options) => {
|
|
152
149
|
await packValidateCommand(pack, options);
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
});
|
|
155
151
|
packCommand
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
152
|
+
.command('lint [pack]')
|
|
153
|
+
.description('Auto-fix pack.yml formatting and structure')
|
|
154
|
+
.action(async (pack) => {
|
|
159
155
|
await packLintCommand(pack);
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
});
|
|
162
157
|
packCommand
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
158
|
+
.command('migrate [pack]')
|
|
159
|
+
.description('Migrate pack v1 to v2 format')
|
|
160
|
+
.option('--output <file>', 'Output file path')
|
|
161
|
+
.option('--dry-run', 'Preview changes without writing files')
|
|
162
|
+
.action(async (pack, options) => {
|
|
168
163
|
await packMigrateCommand(pack, options);
|
|
169
|
-
|
|
170
|
-
*/
|
|
164
|
+
});
|
|
171
165
|
// Secrets commands (Phase 2)
|
|
172
166
|
const secretsCommand = program
|
|
173
167
|
.command('secrets')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qa360",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.9",
|
|
4
4
|
"description": "QA360 Proof CLI - Quality as Cryptographic Proof",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -73,4 +73,4 @@
|
|
|
73
73
|
"bugs": {
|
|
74
74
|
"url": "https://github.com/xyqotech/qa360/issues"
|
|
75
75
|
}
|
|
76
|
-
}
|
|
76
|
+
}
|