Files
gstack/scripts/host-config-export.ts
T
Garry TanandClaude Fable 5 60134c4320 fix(bin): delete zero-caller scripts; make host-config-export's docstring honest
- bin/gstack-open-url (14 lines): announced in a CHANGELOG entry, wired into
  nothing, ever. bin/gstack-platform-detect (27 lines): zero callers, and its
  hand-rolled host list was already stale (SLATE_HOST.md cites it as a
  problem). Note: the deprecated gstack-brain-consumer/reader pair the audit
  flagged was already deleted upstream in v1.63 with a stay-deleted tripwire.
- scripts/task-emission-schema.ts (61 lines): a typed schema module nothing
  imported; the tasks-section comment now documents the JSONL fields inline.
- scripts/host-config-export.ts claimed to be the 'shell bridge for the bash
  setup script' — setup never calls it (its hand-rolled host lists drifting
  is a known follow-up). Docstring now states what it IS: a standalone,
  test-pinned query CLI not yet wired into setup. Its validateValue +
  CLI_REGEX/PATH_REGEX internals were dead (defined for a guarantee the
  header claimed but nothing enforced).
- KEPT deliberately: scripts/preflight-agent-sdk.ts — a documented manual
  diagnostic (CONTRIBUTING.md + USING_GBRAIN_WITH_GSTACK.md reference it).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 21:12:20 -07:00

117 lines
3.4 KiB
TypeScript

#!/usr/bin/env bun
/**
* Standalone query CLI for host configs (list / get / detect / validate).
*
* NOT yet wired into ./setup — setup still hand-rolls its host lists (a
* known drift source; driving setup from this CLI is queued follow-up work).
* Behavior is pinned by test/host-config.test.ts.
*
* Usage: bun run scripts/host-config-export.ts <command> [args]
*
* Commands:
* list Print all host names, one per line
* get <host> <field> Print a single config field value
* detect Print names of hosts whose CLI binary is on PATH
* validate Validate all configs, exit 1 on error
*
* All output is shell-safe (single-quoted values, no eval needed).
*/
import { ALL_HOST_CONFIGS, getHostConfig, ALL_HOST_NAMES } from '../hosts/index';
import { validateAllConfigs } from './host-config';
import { RESOLVERS } from './resolvers';
import { execSync } from 'child_process';
function shellEscape(s: string): string {
return "'" + s.replace(/'/g, "'\\''") + "'";
}
const [command, ...args] = process.argv.slice(2);
switch (command) {
case 'list':
for (const name of ALL_HOST_NAMES) {
console.log(name);
}
break;
case 'get': {
const [hostName, field] = args;
if (!hostName || !field) {
console.error('Usage: host-config-export.ts get <host> <field>');
process.exit(1);
}
const config = getHostConfig(hostName);
const value = (config as any)[field];
if (value === undefined) {
console.error(`Unknown field: ${field}`);
process.exit(1);
}
if (typeof value === 'string') {
console.log(value);
} else if (typeof value === 'boolean') {
console.log(value ? '1' : '0');
} else if (Array.isArray(value)) {
for (const item of value) {
console.log(typeof item === 'string' ? item : JSON.stringify(item));
}
} else {
console.log(JSON.stringify(value));
}
break;
}
case 'detect': {
for (const config of ALL_HOST_CONFIGS) {
const commands = [config.cliCommand, ...(config.cliAliases || [])];
for (const cmd of commands) {
try {
execSync(`command -v ${shellEscape(cmd)}`, { stdio: 'pipe' });
console.log(config.name);
break; // Found this host, move to next
} catch {
// Binary not found, try next alias
}
}
}
break;
}
case 'validate': {
const errors = validateAllConfigs(ALL_HOST_CONFIGS, new Set(Object.keys(RESOLVERS)));
if (errors.length > 0) {
for (const error of errors) {
console.error(`ERROR: ${error}`);
}
process.exit(1);
}
console.log(`All ${ALL_HOST_CONFIGS.length} configs valid`);
break;
}
case 'symlinks': {
const [hostName] = args;
if (!hostName) {
console.error('Usage: host-config-export.ts symlinks <host>');
process.exit(1);
}
const config = getHostConfig(hostName);
for (const link of config.runtimeRoot.globalSymlinks) {
console.log(link);
}
if (config.runtimeRoot.globalFiles) {
for (const [dir, files] of Object.entries(config.runtimeRoot.globalFiles)) {
for (const file of files) {
console.log(`${dir}/${file}`);
}
}
}
break;
}
default:
console.error('Usage: host-config-export.ts <list|get|detect|validate|symlinks> [args]');
process.exit(1);
}