The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "AI Technical Analysis \u2192 Preview via gh models CLI (GitHub Copilot)",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "preview-gh",
"responseMode": "responseNode",
"options": {}
},
"id": "g1000000-0000-0000-0000-000000000001",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
300
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "feature-desc",
"name": "featureDescription",
"value": "={{ $json.body.featureDescription }}",
"type": "string"
},
{
"id": "additional-context",
"name": "additionalContext",
"value": "={{ $json.body.additionalContext || '' }}",
"type": "string"
},
{
"id": "template-id",
"name": "template",
"value": "={{ $json.body.template || 'generic' }}",
"type": "string"
},
{
"id": "custom-role",
"name": "customRole",
"value": "={{ $json.body.customRole || '' }}",
"type": "string"
},
{
"id": "custom-schema",
"name": "customSchema",
"value": "={{ $json.body.customSchema || '' }}",
"type": "string"
}
]
}
},
"id": "g1000000-0000-0000-0000-000000000002",
"name": "Set Variables",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
460,
300
]
},
{
"parameters": {
"jsCode": "const featureDescription = $input.first().json.featureDescription || '';\nconst additionalContext = $input.first().json.additionalContext || '';\nconst template = $input.first().json.template || 'generic';\n\nconst ROLES = {\n 'generic': 'You are a senior software architect performing technical analysis.',\n 'new-feature': 'You are a senior software architect designing a new feature.',\n 'tech-migration': 'You are a senior architect planning a technology migration. Must be incremental and reversible.',\n 'large-refactoring': 'You are a senior architect planning a major refactoring. Must preserve existing behavior.',\n 'api-breaking-change': 'You are a senior API architect planning a breaking change. Minimize consumer disruption.',\n 'security-audit': 'You are a senior security engineer documenting audit findings with severity scores and fixes.',\n 'performance-optimization': 'You are a senior performance engineer with measurable improvement targets.',\n 'scheduled-task-migration': 'You are a senior architect migrating a legacy scheduled task to a modern job framework. Produce a Discovery Document and Migration Plan.',\n 'adr': 'You are a senior architect documenting an Architecture Decision Record.',\n 'post-mortem': 'You are a senior SRE writing a blameless post-mortem.',\n 'runbook': 'You are a senior SRE writing a runbook. Every command must be copy-pasteable.',\n 'service-documentation': 'You are a senior software engineer writing internal documentation for a service, application, or library. Your audience is developers new to this codebase who need to get up to speed quickly. Be specific and practical.',\n 'bug-fix': 'You are a senior developer triaging a bug with root cause analysis.',\n 'dependency-update': 'You are a senior developer planning a dependency upgrade.',\n 'tech-debt': 'You are a senior developer documenting tech debt with business justification.',\n 'quick-enhancement': 'You are a senior developer scoping a small enhancement (< 1 day).',\n 'legacy-technical': 'You are a senior software architect performing technical analysis.',\n 'legacy-bug': 'You are a senior engineer performing root cause analysis on a bug.',\n 'legacy-spike': 'You are a senior architect evaluating technical options.'\n};\n\nconst SCHEMAS = {\n 'scheduled-task-migration': 'Produce JSON with: title, summary, discoveryDocument (purpose with what/why/when, codeLocation with workerClass/baseClass/entryPoint/projectFile/supportingFiles each with path, howItWorks with entryFlow and coreAlgorithm steps each with codeSample and sourceFile and lineRange, dataAccess with databases and externalServices, errorHandling with strategy and codeSample, inputsAndOutputs with inputs/outputs/sideEffects, configuration, knownIssues, runInstructions with prerequisites/buildSteps/runSteps/debugSteps/testSteps), migrationPlan (targetDesign with projectName/className/jobId/interface/targetPath/namespace, dependencyMapping with mappings each having legacy/legacyFile/target/action, phases each with name/goal/prerequisite/canRollback/rollbackSteps/attentionPoints/tasks/validationChecks, improvements with codeQuality/linting/testing/performance/observability, cleanupPhase with filesToRemove and configToRemove, risks, openQuestions), estimatedComplexity, suggestedApproach. Every code reference MUST include file path.',\n 'adr': 'Produce JSON with: title, status (Proposed), date, context (background, constraints, drivers, assumptions), options (each with name, description, pros, cons, effort, risk, operationalImpact, teamFamiliarity), decision (chosen, reasoning, dissent), consequences (positive, negative, neutral), followUp (actions, reviewDate, reversibility).',\n 'post-mortem': 'Produce JSON with: title, severity (SEV1-4), duration, status, summary, impact (usersAffected, revenueImpact, dataLoss, slaBreached), timeline (timestamp, event, actor), rootCause (primary, contributing, fiveWhys), detection (howDetected, timeToDetect, alertsFired, alertsExpectedButMissing), response (timeToMitigate, mitigationSteps, whatWorkedWell, whatCouldBeImproved), actionItems (description, type: prevent|detect|mitigate, priority, owner, deadline), lessonsLearned.',\n 'runbook': 'Produce JSON with: title, service, overview (purpose, criticality, dependencies, dependents), healthChecks (name, command, healthyOutput, unhealthyOutput), commonIssues (symptom, cause, diagnosis steps, resolution steps, escalation), procedures (name, when, steps with instruction/expectedResult/ifFailed, rollback), contacts, links.',\n 'service-documentation': 'Produce JSON with: title, summary, overview (purpose, type: service|application|library|cli-tool|worker|scheduled-job, techStack, repository, owners), keyFiles (path, purpose, notes), architecture (overview, entryPoint, keyModules with name/path/responsibility/publicInterface, dataFlow), howToRun (prerequisites, setup steps, run with development/production/docker commands, environment with variable/description/required/default, verification), directoryStructure (description, tree with path/description), potentialIssues (issue, severity: low|medium|high, context, workaround), improvements (title, description, effort: XS|S|M|L|XL, impact: low|medium|high, category: code-quality|performance|reliability|developer-experience|security|testing), dependencies (runtime, external, consumers), testing (howToTest, testStructure, coverage).',\n 'bug-fix': 'Produce JSON with: title, severity, description, reproductionSteps, expectedBehavior, actualBehavior, rootCause (hypothesis, confidence, investigation), fixApproach (description, affectedFiles, riskLevel), tasks as subtasks with acceptanceCriteria, testPlan (unitTests, manualVerification), workaround.',\n 'dependency-update': 'Produce JSON with: title, packages (name, currentVersion, targetVersion, changelog, breakingChanges with description/affectedCode/migration, newFeatures, deprecations), riskAssessment (overall, peerDependencies, knownIssues), tasks as subtasks, verificationPlan, rollbackPlan.',\n 'tech-debt': 'Produce JSON with: title, currentState (description, pain, frequency), desiredState (description, benefit), justification (developerProductivity, reliability, riskReduction, onboarding), approach (description, canBeIncremental, estimatedEffort, bestTimeToFix), acceptanceCriteria, risks.',\n 'quick-enhancement': 'Produce JSON with: title, description, scope (includes, excludes, isActuallyBigger, biggerNote), implementation (approach, affectedFiles, estimate max M), acceptanceCriteria (max 5), testPlan.',\n 'api-breaking-change': 'Produce JSON with: title, summary, currentContract (endpoints, consumers with impactLevel), proposedContract (endpoints with changeType, versioningStrategy), diff (field, before, after, breakingReason, migrationAction), migrationPlan (strategy, phases, deprecationTimeline, migrationGuide with steps and codeExamples), communication (announcement, channels, faq), tasks, testing (contractTests, migrationTests, compatibilityTests), rollbackPlan, risks.',\n 'security-audit': 'Produce JSON with: title, auditScope (areasReviewed, areasOutOfScope, methodology), overallRisk, findingsCount by severity, findings (id like SEC-001, title, severity, category, owaspCategory, description, affectedComponent, reproductionSteps, impact, exploitability, evidence, remediation with recommendation/codeExample/effort/priority), positiveFindings, recommendations (immediate, shortTerm, longTerm), tasks, complianceNotes, retestDate.',\n 'performance-optimization': 'Produce JSON with: title, currentState (metrics with name/currentValue/target/gap, userImpact, businessImpact), analysis (bottlenecks with location/type/description/evidence/contribution%, hotPaths, redHerrings), optimizations (id like OPT-001, title, description, type, targetBottleneck, expectedImprovement, confidence, effort, risk, tradeoff), quickWins, benchmarkPlan (tooling, baselineTests, regressionTests, loadProfile), tasks, monitoringPlan (dashboards, alerts, continuousBaseline), antiPatterns.',\n 'tech-migration': 'Produce JSON with: title, currentState (technology, version, usage, knownIssues), targetState (technology, version, benefits, tradeoffs), impactAnalysis (affectedServices with impactLevel, affectedTeams, breakingChanges, dataChanges), migrationStrategy (approach: strangler-fig|parallel-run|feature-flag, reasoning, parallelRunPeriod, featureFlags), phases (name, goal, prerequisite, canRollback, rollbackSteps, tasks, validationChecks), rollbackPlan (fullRollbackSteps, pointOfNoReturn, dataRollback), testing (parallelRunTests, regressionTests, newTests, performanceBenchmarks), risks with contingency, timeline.'\n};\n\nconst DEFAULT_SCHEMA = 'Produce JSON with: title, summary, architecture (overview, components with name/type/description/changes, dataFlow), apiContracts (method, path, description, requestBody, responseBody, statusCodes), databaseChanges (type, entity, description, fields with name/type/nullable), edgeCases (scenario, impact, mitigation), securityConsiderations, testingStrategy (unitTests, integrationTests, e2eTests), tasks (type: epic|story|subtask, summary, description, component, estimate: XS|S|M|L|XL, priority, acceptanceCriteria in Given/When/Then), estimatedComplexity, suggestedApproach.';\n\nconst customRole = $input.first().json.customRole || '';\nconst customSchema = $input.first().json.customSchema || '';\n\nconst role = customRole || ROLES[template] || ROLES['generic'];\nconst schema = customSchema || SCHEMAS[template] || DEFAULT_SCHEMA;\n\nconst userPrompt = 'Analyze the following and produce a detailed JSON response.\\n\\n## Description\\n' + featureDescription + '\\n\\n## Additional Context\\n' + additionalContext + '\\n\\n## Output\\n\\nRespond ONLY with valid JSON. No markdown code fences, no explanation \u2014 just the JSON object.\\n\\n' + schema + '\\n\\nAlso include: title, summary, estimatedComplexity (low|medium|high), suggestedApproach.\\nRules: Tasks 1-3 day items. Gherkin acceptance criteria. Be specific. XS(<2h) S(2-4h) M(4-8h) L(1-2d) XL(2-3d).';\n\nconst model = $env.GH_MODELS_MODEL || $env.AI_MODEL || 'anthropic/claude-4-opus';\n\nreturn [{ json: { userPrompt, systemPrompt: role, model, featureDescription, additionalContext, template } }];"
},
"id": "g1000000-0000-0000-0000-000000000003",
"name": "Build Prompt",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
680,
300
]
},
{
"parameters": {
"command": "={{ 'echo ' + JSON.stringify($json.userPrompt) + ' | gh models run ' + JSON.stringify($json.model) + ' --system-prompt ' + JSON.stringify($json.systemPrompt) }}",
"options": {
"timeout": 120000
}
},
"id": "g1000000-0000-0000-0000-000000000004",
"name": "Call gh models CLI",
"type": "n8n-nodes-base.executeCommand",
"typeVersion": 1,
"position": [
900,
300
]
},
{
"parameters": {
"jsCode": "const output = $input.first().json.stdout || '';\n\nlet jsonStr = output.trim();\nif (jsonStr.includes('```json')) jsonStr = jsonStr.split('```json')[1].split('```')[0].trim();\nelse if (jsonStr.includes('```')) jsonStr = jsonStr.split('```')[1].split('```')[0].trim();\n\nlet analysis;\ntry { analysis = JSON.parse(jsonStr); }\ncatch (e) { throw new Error('Failed to parse gh models response as JSON: ' + e.message + '\\n\\nRaw (first 500 chars): ' + output.substring(0, 500)); }\n\nreturn [{ json: { analysis, featureDescription: $('Set Variables').first().json.featureDescription } }];"
},
"id": "g1000000-0000-0000-0000-000000000005",
"name": "Parse CLI Response",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1120,
300
]
},
{
"parameters": {
"jsCode": "const { analysis } = $input.first().json;\nconst date = new Date().toISOString().split('T')[0];\nlet md = '';\n\nmd += '# ' + (analysis.title || 'Analysis') + '\\n\\n';\nmd += '> Generated on ' + date + ' by [ai-confluence-pipeline](https://github.com/openmindednewby/ai-confluence-pipeline) via gh models CLI\\n\\n';\nif (analysis.estimatedComplexity) md += '**Complexity:** ' + analysis.estimatedComplexity;\nif (analysis.suggestedApproach) md += ' | **Approach:** ' + analysis.suggestedApproach;\nmd += '\\n\\n---\\n\\n';\nif (analysis.summary) md += '## Summary\\n\\n' + analysis.summary + '\\n\\n';\n\nfunction renderSection(obj, depth) {\n if (!obj || typeof obj !== 'object') return String(obj || '') + '\\n';\n let out = '';\n if (Array.isArray(obj)) {\n if (obj.length > 0 && typeof obj[0] === 'object' && !Array.isArray(obj[0])) {\n const keys = Object.keys(obj[0]);\n if (keys.length <= 8 && keys.length >= 2 && obj.every(item => typeof item === 'object' && !Array.isArray(item))) {\n out += '| ' + keys.map(k => k.replace(/([A-Z])/g, ' $1').trim()).join(' | ') + ' |\\n';\n out += '| ' + keys.map(() => '---').join(' | ') + ' |\\n';\n for (const item of obj) {\n out += '| ' + keys.map(k => {\n const v = item[k];\n if (Array.isArray(v)) return v.join(', ');\n if (typeof v === 'object' && v !== null) return JSON.stringify(v);\n return String(v ?? '');\n }).join(' | ') + ' |\\n';\n }\n out += '\\n';\n return out;\n }\n }\n for (const item of obj) {\n if (typeof item === 'string') out += '- ' + item + '\\n';\n else if (typeof item === 'object') out += renderSection(item, depth);\n }\n out += '\\n';\n return out;\n }\n const skip = ['title', 'summary', 'estimatedComplexity', 'suggestedApproach'];\n for (const [key, value] of Object.entries(obj)) {\n if (skip.includes(key) && depth === 0) continue;\n const heading = key.replace(/([A-Z])/g, ' $1').replace(/^./, s => s.toUpperCase()).trim();\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n out += '**' + heading + ':** ' + value + '\\n\\n';\n } else if (Array.isArray(value) && value.length > 0 && typeof value[0] === 'string') {\n out += '**' + heading + ':**\\n';\n for (const item of value) out += '- ' + item + '\\n';\n out += '\\n';\n } else if (value && typeof value === 'object') {\n const hPrefix = '#'.repeat(Math.min(depth + 2, 4));\n out += hPrefix + ' ' + heading + '\\n\\n';\n out += renderSection(value, depth + 1);\n }\n }\n return out;\n}\n\nmd += renderSection(analysis, 0);\n\nreturn [{ json: { success: true, title: analysis.title || 'Analysis', markdown: md, analysis } }];"
},
"id": "g1000000-0000-0000-0000-000000000006",
"name": "Format as Markdown",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
300
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json) }}"
},
"id": "g1000000-0000-0000-0000-000000000007",
"name": "Send Response",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
1560,
300
]
}
],
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Set Variables",
"type": "main",
"index": 0
}
]
]
},
"Set Variables": {
"main": [
[
{
"node": "Build Prompt",
"type": "main",
"index": 0
}
]
]
},
"Build Prompt": {
"main": [
[
{
"node": "Call gh models CLI",
"type": "main",
"index": 0
}
]
]
},
"Call gh models CLI": {
"main": [
[
{
"node": "Parse CLI Response",
"type": "main",
"index": 0
}
]
]
},
"Parse CLI Response": {
"main": [
[
{
"node": "Format as Markdown",
"type": "main",
"index": 0
}
]
]
},
"Format as Markdown": {
"main": [
[
{
"node": "Send Response",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"tags": [
{
"name": "ai-pipeline"
},
{
"name": "preview"
},
{
"name": "cli"
},
{
"name": "github-copilot"
}
]
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
AI Technical Analysis → Preview via gh models CLI (GitHub Copilot). Uses executeCommand. Webhook trigger; 7 nodes.
Source: https://github.com/openmindednewby/ai-confluence-pipeline/blob/master/workflows/gh-models-cli-pipeline.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
The Docker Immich WHMCS module uses a specially designed workflow for n8n to automate deployment processes. The workflow provides an API interface for the module, receives specific commands, and conne
The Docker n8n WHMCS module uses a specially designed workflow for n8n to automate deployment processes. The workflow provides an API interface for the module, receives specific commands, and connects
The Docker MinIO WHMCS module uses a specially designed workflow for n8n to automate deployment processes. The workflow provides an API interface for the module, receives specific commands, and connec
The Docker Grafana WHMCS module uses a specially designed workflow for n8n to automate deployment processes. The workflow provides an API interface for the module, receives specific commands, and conn