Skip to content

Commit 0a67b24

Browse files
chore: tune dev workflow and CLI update detection
Enable STX page caching, only clear .stx cache with --fresh, widen process broadcast interval, and extend the CLI check command for macOS and CLT updates. Scope bun test to workspace packages to avoid pantry noise. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 6933170 commit 0a67b24

5 files changed

Lines changed: 54 additions & 19 deletions

File tree

channels.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getTopProcesses, summarizeProcesses } from '@system-cleaner/monitor'
33

44
export default function ({ channel }: ChannelRegistrar) {
55
channel('processes', {
6-
interval: 3000,
6+
interval: 5000,
77

88
async data() {
99
const procs = await getTopProcesses(20)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"lint": "bunx --bun pickier .",
1919
"lint:fix": "bunx --bun pickier . --fix",
2020
"typecheck": "bun --bun tsc --noEmit",
21-
"test": "bun test"
21+
"test": "bun test packages test/smoke.test.ts"
2222
},
2323
"dependencies": {
2424
"@stacksjs/bun-router": "^0.0.14",

packages/cli/src/commands/check.ts

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { CLI } from '@stacksjs/clapp'
2-
import { exec, formatBytes, formatPercent, getSystemInfo } from '@system-cleaner/core'
2+
import { exec, formatBytes, formatPercent, getSystemInfo, checkSoftwareUpdates } from '@system-cleaner/core'
33
import { getMemoryMetrics } from '@system-cleaner/monitor'
44

55
interface CheckResult {
@@ -31,15 +31,20 @@ export function registerCheckCommand(app: CLI): void {
3131
checkMemory(),
3232
checkSwap(),
3333
checkHomebrewUpdates(),
34-
checkMacosUpdates(),
34+
checkSystemUpdates(),
3535
checkTouchIdSudo(),
3636
checkRosetta(),
3737
checkGitConfig(),
3838
])
3939

4040
for (const result of results) {
41-
if (result.status === 'fulfilled')
42-
checks.push(result.value)
41+
if (result.status === 'fulfilled') {
42+
const value = result.value
43+
if (Array.isArray(value))
44+
checks.push(...value)
45+
else
46+
checks.push(value)
47+
}
4348
}
4449

4550
s.stop(`Completed ${checks.length} checks`)
@@ -82,7 +87,7 @@ export function registerCheckCommand(app: CLI): void {
8287
// Updates
8388
log.info('')
8489
log.info('──── Updates ─────────────────────────')
85-
for (const c of checks.filter(c => ['Homebrew Updates', 'macOS Updates'].includes(c.name))) {
90+
for (const c of checks.filter(c => ['Homebrew Updates', 'macOS Updates', 'Xcode CLT'].includes(c.name))) {
8691
// eslint-disable-next-line no-console
8792
console.log(` ${colors[c.status]}${icons[c.status]}${reset} ${c.name}: ${c.message}`)
8893
}
@@ -178,15 +183,42 @@ async function checkHomebrewUpdates(): Promise<CheckResult> {
178183
return { name: 'Homebrew Updates', status: 'pass', message: 'All packages up to date' }
179184
}
180185

181-
async function checkMacosUpdates(): Promise<CheckResult> {
182-
// --no-scan uses cached results (fast but may be stale)
183-
const r = await exec('softwareupdate -l --no-scan 2>&1', { timeout: 15_000 })
184-
if (!r.ok || r.stdout.includes('No new software available'))
185-
return { name: 'macOS Updates', status: 'pass', message: 'System up to date (cached check)' }
186-
const count = (r.stdout.match(/\*/g) || []).length
187-
if (count > 0)
188-
return { name: 'macOS Updates', status: 'warn', message: `${count} update(s) available` }
189-
return { name: 'macOS Updates', status: 'pass', message: 'System up to date' }
186+
async function checkSystemUpdates(): Promise<CheckResult[]> {
187+
const result = await checkSoftwareUpdates({ fullScan: false })
188+
const macosUpdates = result.updates.filter(u => u.kind === 'macos')
189+
const cltUpdates = result.updates.filter(u => u.kind === 'cltools')
190+
const otherSystem = result.updates.filter(u => u.kind !== 'macos' && u.kind !== 'cltools')
191+
const installed = result.clToolsInfo.version
192+
193+
const macosCheck: CheckResult = result.updates.length === 0
194+
? { name: 'macOS Updates', status: 'pass', message: 'System up to date (cached check)' }
195+
: {
196+
name: 'macOS Updates',
197+
status: 'warn',
198+
message: (() => {
199+
const parts: string[] = []
200+
if (macosUpdates.length > 0) parts.push(`${macosUpdates.length} macOS`)
201+
if (cltUpdates.length > 0) parts.push(`${cltUpdates.length} CLT`)
202+
if (otherSystem.length > 0) parts.push(`${otherSystem.length} other`)
203+
return `${result.updates.length} update(s) available (${parts.join(', ')})`
204+
})(),
205+
}
206+
207+
const cltCheck: CheckResult = cltUpdates.length === 0
208+
? {
209+
name: 'Xcode CLT',
210+
status: 'pass',
211+
message: installed ? `Command Line Tools ${installed} up to date` : 'No CLT updates pending',
212+
}
213+
: {
214+
name: 'Xcode CLT',
215+
status: 'warn',
216+
message: installed
217+
? `Update available: ${installed}${cltUpdates[0]?.version || '?'}`
218+
: `${cltUpdates.length} Command Line Tools update(s) available (${cltUpdates[0]?.version || '?'})`,
219+
}
220+
221+
return [macosCheck, cltCheck]
190222
}
191223

192224
async function checkTouchIdSudo(): Promise<CheckResult> {

scripts/dev.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,11 @@ for (const port of [PORT, BROADCAST_PORT]) {
123123
}
124124
}
125125

126-
// Clear STX cache (preserves prior behavior)
127-
try { fs.rmSync('.stx', { recursive: true, force: true }) } catch {}
126+
// Clear STX cache unless --fresh is passed
127+
const fresh = process.argv.includes('--fresh')
128+
if (fresh) {
129+
try { fs.rmSync('.stx', { recursive: true, force: true }) } catch {}
130+
}
128131

129132
// Locate the stx CLI. The pantry symlink (`pantry/.bin/stx`) is the
130133
// fast path on this machine, but `pantry/` is gitignored so a fresh

stx.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const config: StxOptions = {
1313
// mean "no auto-wrap" but isn't in the published types yet.
1414
defaultLayout: false as unknown as string,
1515
debug: false,
16-
cache: false,
16+
cache: true,
1717

1818
broadcasting: {
1919
enabled: true,

0 commit comments

Comments
 (0)