xiaohongshu
xiaohongshu
configuration
Reads config.json and prompts user for application parameters. Merges configuration with defaults for project generation.
Full skill instructions
Read and merge application configuration from config.json file with interactive prompts and default values.
IMPORTANT: When prompting users interactively, ask questions ONE AT A TIME in a conversational manner. Wait for each answer before asking the next question.
Execute this skill at the beginning of the application generation process (Step 2 in AGENT_INSTRUCTIONS.md).
None - reads from project root
const configPath = path.join(process.cwd(), 'config.json');
const configExists = fs.existsSync(configPath);
if (configExists) {
console.log('✓ Found config.json - loading configuration...\n');
} else {
console.log('ℹ No config.json found - will use interactive prompts\n');
}
let userConfig = {};
if (configExists) {
const configContent = fs.readFileSync(configPath, 'utf-8');
userConfig = JSON.parse(configContent);
// Validate against schema
const schemaPath = '.github/agents/agents-context/app-starter/config.schema.json';
const schema = JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
// Use a JSON schema validator (e.g., ajv)
const valid = validateSchema(userConfig, schema);
if (!valid) {
console.error('❌ config.json validation failed');
console.error(' Please check your configuration against config.schema.json');
process.exit(1);
}
console.log('✓ Configuration validated successfully\n');
}
// Static defaults
const defaults = {
node_version: "v22.16.0",
vue_version: "^3.5.13",
vite_version: "^6.3.5",
typescript_version: "^5.7.3",
test_framework: "jest",
state_management: "vuex",
enable_single_spa: true,
enable_datadog: true,
include_component_library: false, // Default to no component library
component_library: "@royalaholddelhaize/pdl-spectrum-component-library-web",
component_library_version: "^1.0.3"
};
// Merge with defaults (config.json values take priority)
userConfig = { ...defaults, ...userConfig };
Ask questions ONE AT A TIME in order. Wait for user response before asking next question.
const requiredFields = [
'application_name',
'project_scope',
'router_base_path',
'api_base_path',
'default_port',
'application_type',
'use_latest_versions' // Added as required field
];
// Ask ONE question at a time
for (const field of requiredFields) {
if (!userConfig[field]) {
// Show context and ask single question
console.log(`\n📝 Question ${requiredFields.indexOf(field) + 1}/${requiredFields.length}`);
userConfig[field] = await promptUser(field);
// Confirm response before moving to next question
console.log(`✓ Got it: ${userConfig[field]}\n`);
} else {
console.log(`✓ Using ${field} from config: ${userConfig[field]}`);
}
}
If user chose NOT to use latest versions, ask about test framework and state management.
// Only ask these if user chose stable versions (not latest)
if (userConfig.use_latest_versions === false || userConfig.use_latest_versions === 'no') {
// Prompt for test framework if not set
if (!userConfig.test_framework) {
console.log('\n🧪 Testing framework:');
userConfig.test_framework = await promptUser('test_framework', {
choices: ['jest', 'vitest'],
default: 'jest',
message: 'Which testing framework do you want to use?'
});
console.log(`✓ Will use ${userConfig.test_framework}\n`);
}
// Prompt for state management if not set
if (!userConfig.state_management) {
console.log('\n📊 State management:');
userConfig.state_management = await promptUser('state_management', {
choices: ['vuex', 'pinia'],
default: 'vuex',
message: 'Which state management library do you want to use?'
});
console.log(`✓ Will use ${userConfig.state_management}\n`);
}
} else {
// User chose latest versions - use recommended defaults
console.log('\n✓ Using latest versions with recommended tools:');
userConfig.test_framework = 'vitest'; // Latest recommendation
userConfig.state_management = 'pinia'; // Latest recommendation
console.log(' • Testing: Vitest (latest)');
console.log(' • State Management: Pinia (latest)\n');
}
Only ask for GitHub token if user wants component library.
// First, ask if they want a component library
let needsComponentLibrary = false;
if (userConfig.include_component_library === undefined) {
console.log('\n📦 Component library:');
needsComponentLibrary = await promptUser('include_component_library', {
type: 'confirm',
message: 'Do you want to include a component library?',
default: false,
hint: '(@RoyalAholdDelhaize/pdl-spectrum-component-library-web)'
});
userConfig.include_component_library = needsComponentLibrary;
console.log(`✓ ${needsComponentLibrary ? 'Will include component library' : 'No component library'}\n`);
}
// Derive main_component_name from application_name
// Example: "omni-inventory-manager-web" → "OmniInventoryManagerWeb"
userConfig.main_component_name = userConfig.application_name
.split('-')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join('');
// application_id and service_name same as application_name
userConfig.application_id = userConfig.application_name;
userConfig.service_name = userConfig.application_name;
// Determine if standalone or micro-frontend
userConfig.is_standalone = userConfig.application_type === 'standalone';
userConfig.is_microfrontend = userConfig.application_type === 'micro-frontend';
// Map application_type to vite_build_format
userConfig.vite_build_format = userConfig.is_microfrontend ? 'system' : 'es';
console.log('\n' + '═'.repeat(60));
console.log(' CONFIGURATION SUMMARY');
console.log('═'.repeat(60));
console.log(`Application: ${userConfig.application_name}`);
console.log(`Scope: ${userConfig.project_scope}`);
console.log(`Type: ${userConfig.application_type}`);
console.log(`Router Base: ${userConfig.router_base_path}`);
console.log(`API Base: ${userConfig.api_base_path}`);
console.log(`Port: ${userConfig.default_port}`);
console.log(`Test Framework: ${userConfig.test_framework}`);
console.log(`State Management: ${userConfig.state_management}`);
console.log(`Component Library: ${userConfig.component_library || 'None'}`);
console.log('═'.repeat(60) + '\n');
// Only offer to save if user provided parameters via prompts
if (!configExists || missingFields.length > 0) {
const shouldSave = await promptUser('saveConfig', {
message: 'Save this configuration to config.json for future use?',
type: 'confirm',
default: true
});
if (shouldSave) {
// Prepare config object (exclude sensitive data)
const configToSave = {
application_name: userConfig.application_name,
project_scope: userConfig.project_scope,
router_base_path: userConfig.router_base_path,
api_base_path: userConfig.api_base_path,
default_port: userConfig.default_port,
application_type: userConfig.application_type,
test_framework: userConfig.test_framework,
state_management: userConfig.state_management,
node_version: userConfig.node_version,
vue_version: userConfig.vue_version,
vite_version: userConfig.vite_version,
typescript_version: userConfig.typescript_version,
enable_single_spa: userConfig.enable_single_spa,
enable_datadog: userConfig.enable_datadog,
component_library: userConfig.component_library,
component_library_version: userConfig.component_library_version
};
// Write to config.json
fs.writeFileSync(
path.join(process.cwd(), 'config.json'),
JSON.stringify(configToSave, null, 2) + '\n'
);
console.log('✓ Configuration saved to config.json');
console.log('⚠️ Note: GitHub token (if provided) was NOT saved for security');
console.log(' You can manually add it to config.json if needed (it will be gitignored)\n');
// Add config.json to .gitignore if not already there
const gitignorePath = path.join(process.cwd(), '.gitignore');
if (fs.existsSync(gitignorePath)) {
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8');
if (!gitignoreContent.includes('config.json')) {
fs.appendFileSync(gitignorePath, '\nconfig.json\n');
console.log('✓ Added config.json to .gitignore\n');
}
}
}
}
userConfig object with all configuration valuesconfig.json file saved in project root (if user confirms)my-app-web)@ (e.g., @myorg)/ (e.g., /my-app)/ (e.g., /api)"standalone" or "micro-frontend""jest" or "vitest""vuex" or "pinia"See conditional-generation skill for application type specific validations.
Run the agent and answer the prompts interactively.
IMPORTANT: Questions are asked ONE AT A TIME in a conversational flow:
Example Interactive Flow:
Agent: 📝 Question 1/7
What is the name of your application? (in kebab-case)
User: my-inventory-app-web
Agent: ✓ Got it: my-inventory-app-web
Agent: 📝 Question 2/7
What is your NPM scope/organization? (e.g., @my-org)
User: @my-company
Agent: ✓ Got it: @my-company
Agent: 📝 Question 3/7
What base path should the router use?
User: /my-inventory-app
Agent: ✓ Got it: /my-inventory-app
... continues through question 7 ...
Agent: 📝 Question 7/7
Do you want to use the latest package versions from npm?
User: yes
Agent: ✓ Got it: yes
✓ Using latest versions with recommended tools:
• Testing: Vitest (latest)
• State Management: Pinia (latest)
Agent: 📦 Component library:
Do you want to include a component library?
User: no
Agent: ✓ No component library
ℹ Skipping GitHub token (no component library needed)
... and so on
Create a config.json file in the project root. The agent will read values and skip prompting.
Provide some values in config.json and the agent will only prompt for missing required values (ONE AT A TIME).
User's configuration file (optional). If exists, values are loaded from here.
All configuration fields, validation rules, and defaults are documented in examples.md.
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience