5.5 KiB
Coding Conventions
Analysis Date: 2026-03-12
Language
Primary: JavaScript (Node.js)
- All source files use CommonJS (
.cjsextension) - ESM imports used in test files with
.test.cjsextension
File Naming
Pattern: kebab-case
- Commands:
allow-read-config.cjs,get-profile.cjs,set-profile.cjs - Libraries:
oc-core.cjs,oc-config.cjs,oc-models.cjs - Tests:
get-profile.test.cjs,allow-read-config.test.cjs
Directories:
- Commands:
bin/gsd-oc-commands/ - Libraries:
bin/gsd-oc-lib/orbin/lib/ - Tests:
bin/test/
Code Style
Formatting
No explicit formatter configured. Code uses:
- 2-space indentation
- Consistent brace placement
- Max line length ~100 characters
Example from bin/gsd-oc-commands/get-profile.cjs:
function getProfile(cwd, args) {
const verbose = args.includes('--verbose');
const raw = args.includes('--raw');
const log = verbose ? (...args) => console.error('[get-profile]', ...args) : () => {};
// ...
}
Linting
No ESLint or Prettier configuration detected.
Import Organization
Order in source files:
- Node.js built-ins (
fs,path,os) - Local modules relative paths
Example from bin/gsd-oc-commands/allow-read-config.cjs:
const fs = require('fs');
const path = require('path');
const os = require('os');
const { output, error, createBackup } = require('../gsd-oc-lib/oc-core.cjs');
Function Design
Naming
- Commands: lowercase with hyphens (e.g.,
getProfile,allowReadConfig) - Helper functions: camelCase
- Error code constants: UPPER_SNAKE_CASE
Documentation
Every file includes a JSDoc-style header:
/**
* get-profile.cjs — Retrieve profile definitions from oc_config.json
*
* Command module that exports getProfile(cwd, args) function with two operation modes:
* 1. No parameters: Returns current profile definition
* 2. Profile name parameter: Returns specified profile definition
*
* Output format: JSON envelope {success: true, data: {...}}
* Flags: --raw (output raw JSON without envelope), --verbose (output diagnostics to stderr)
*
* Usage: node get-profile.cjs [profile-name] [--raw] [--verbose]
*/
Function JSDoc:
/**
* Main command function
*
* @param {string} cwd - Current working directory
* @param {string[]} args - Command line arguments
*/
function getProfile(cwd, args) {
Error Handling
Error Codes
Pattern: Constant object with error codes, used with custom error function
From bin/gsd-oc-lib/oc-profile-config.cjs:
const ERROR_CODES = {
CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',
INVALID_JSON: 'INVALID_JSON',
PROFILE_NOT_FOUND: 'PROFILE_NOT_FOUND',
INVALID_MODELS: 'INVALID_MODELS',
INCOMPLETE_PROFILE: 'INCOMPLETE_PROFILE',
WRITE_FAILED: 'WRITE_FAILED',
APPLY_FAILED: 'APPLY_FAILED',
ROLLBACK_FAILED: 'ROLLBACK_FAILED'
};
Output Pattern
Success output: JSON envelope with success: true and data
output({ success: true, data: result });
Error output: Uses centralized error() function from oc-core.cjs
error('current_oc_profile not set in oc_config.json', 'MISSING_CURRENT_PROFILE');
From bin/gsd-oc-lib/oc-core.cjs:
function error(message, code = 'UNKNOWN_ERROR') {
const errorEnvelope = {
success: false,
error: {
code,
message
}
};
console.error(JSON.stringify(errorEnvelope, null, 2));
process.exit(1);
}
Return Patterns
Result Objects
Pattern: Return object with success: boolean and either data or error
From bin/gsd-oc-lib/oc-profile-config.cjs:
function loadOcProfileConfig(cwd) {
try {
const configPath = path.join(cwd, '.planning', 'oc_config.json');
if (!fs.existsSync(configPath)) {
return {
success: false,
error: {
code: ERROR_CODES.CONFIG_NOT_FOUND,
message: `.planning/oc_config.json not found at ${configPath}`
}
};
}
return { success: true, config, configPath };
} catch (err) {
// ...
}
}
Module Design
Exports
Pattern: Single function export via module.exports
module.exports = getProfile;
Command Module Structure
- JSDoc header with description
- Require statements
- Error code constants
- Helper functions
- Main command function
module.exports
CLI Patterns
Flag Handling
Pattern: Simple array filtering
const verbose = args.includes('--verbose');
const raw = args.includes('--raw');
const profileArgs = args.filter(arg => !arg.startsWith('--'));
Output Functions
From bin/gsd-oc-lib/oc-core.cjs:
function output(result, raw = false, rawValue = null) {
let outputStr;
if (raw && rawValue !== null) {
outputStr = rawValue;
} else {
outputStr = JSON.stringify(result, null, 2);
}
// Large payload handling (>50KB)
if (outputStr.length > 50 * 1024) {
const tempFile = path.join(require('os').tmpdir(), `gsd-oc-${Date.now()}.json`);
fs.writeFileSync(tempFile, outputStr, 'utf8');
console.log(`@file:${tempFile}`);
} else {
console.log(outputStr);
}
}
Logging
Verbose Logging Pattern
Conditional logging based on flag:
const log = verbose ? (...args) => console.error('[get-profile]', ...args) : () => {};
log('Loading oc_config.json');
log(`Config loaded from ${configPath}`);
Testing Conventions
Tests co-located in bin/test/ directory with .test.cjs suffix.
Convention analysis: 2026-03-12