chati-dev 4.2.1 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -53
- package/bin/chati.js +150 -5
- package/framework/agents/build/dev.md +509 -76
- package/framework/agents/deploy/devops.md +40 -25
- package/framework/agents/discover/brief.md +156 -22
- package/framework/agents/discover/brownfield-wu.md +24 -14
- package/framework/agents/discover/greenfield-wu.md +100 -14
- package/framework/agents/plan/architect-data-engineer.md +6 -6
- package/framework/agents/plan/architect-system.md +46 -12
- package/framework/agents/plan/architect.md +40 -20
- package/framework/agents/plan/detail.md +36 -24
- package/framework/agents/plan/phases.md +36 -26
- package/framework/agents/plan/tasks.md +114 -33
- package/framework/agents/plan/ux-brand-architect.md +240 -8
- package/framework/agents/plan/ux-component-engineer.md +28 -13
- package/framework/agents/plan/ux-researcher.md +7 -6
- package/framework/agents/plan/ux.md +55 -22
- package/framework/agents/quality/qa-implementation.md +143 -74
- package/framework/agents/quality/qa-planning.md +115 -42
- package/framework/agents/quality/qa-visual.md +439 -0
- package/framework/agents/shared/visualizer.md +128 -0
- package/framework/config.yaml +8 -7
- package/framework/constitution.md +127 -43
- package/framework/context/governance.md +12 -7
- package/framework/context/quality.md +6 -5
- package/framework/context/root.md +6 -6
- package/framework/data/entity-registry.yaml +377 -4
- package/framework/data/model-limits.json +19 -0
- package/framework/domains/agents/qa-visual.yaml +74 -0
- package/framework/domains/constitution.yaml +46 -2
- package/framework/domains/workflows/greenfield-fullstack.yaml +2 -2
- package/framework/hooks/advance-trigger.js +131 -0
- package/framework/hooks/brief-validator.js +83 -0
- package/framework/hooks/constitution-guard.js +91 -36
- package/framework/hooks/license-guard.js +129 -190
- package/framework/hooks/mode-governance.js +68 -16
- package/framework/hooks/model-governance.js +19 -8
- package/framework/hooks/package.json +3 -0
- package/framework/hooks/post-dev.js +207 -0
- package/framework/hooks/prism-engine.js +288 -105
- package/framework/hooks/read-protection.js +37 -9
- package/framework/hooks/reasoning-escalator.js +371 -0
- package/framework/hooks/reference-trigger.js +117 -0
- package/framework/hooks/session-digest.js +94 -20
- package/framework/hooks/settings.json +32 -1
- package/framework/hooks/style-guard.js +52 -13
- package/framework/hooks/team-quality-gate.js +58 -25
- package/framework/hooks/undercover-guard.js +34 -13
- package/framework/i18n/en.yaml +3 -3
- package/framework/i18n/es.yaml +3 -3
- package/framework/i18n/fr.yaml +3 -3
- package/framework/i18n/pt.yaml +3 -3
- package/framework/intelligence/context-engine.md +4 -5
- package/framework/intelligence/decision-engine.md +1 -1
- package/framework/intelligence/hooks-performance.md +3 -3
- package/framework/migrations/v1.0-to-v1.1.yaml +1 -1
- package/framework/migrations/v1.4-to-v2.0.yaml +11 -11
- package/framework/migrations/v4.0-to-v4.1.yaml +2 -2
- package/framework/migrations/v4.2-to-v4.3.yaml +29 -0
- package/framework/orchestrator/chati-router.js +387 -0
- package/framework/orchestrator/chati-update.md +40 -40
- package/framework/orchestrator/chati.md +318 -115
- package/framework/scaffold/motion-premium/README.md +89 -0
- package/framework/scaffold/motion-premium/app/globals.css.template +400 -0
- package/framework/scaffold/motion-premium/app/layout.tsx.template +110 -0
- package/framework/scaffold/motion-premium/components/animation/BackgroundCrossfadeProvider.tsx.template +170 -0
- package/framework/scaffold/motion-premium/components/animation/LenisProvider.tsx.template +49 -0
- package/framework/scaffold/motion-premium/components/animation/PageTransitionWrapper.tsx.template +83 -0
- package/framework/scaffold/motion-premium/components/animation/Preloader.tsx.template +171 -0
- package/framework/scaffold/motion-premium/components/ui/Container.tsx.template +69 -0
- package/framework/scaffold/motion-premium/components/ui/PageSection.tsx.template +74 -0
- package/framework/scaffold/motion-premium/lib/animations/gsap.ts.template +112 -0
- package/framework/scaffold/motion-premium/lib/animations/refreshCoordinator.ts.template +75 -0
- package/framework/scaffold/motion-premium/lib/animations/tokens.ts.template +119 -0
- package/framework/scaffold/motion-premium/lib/animations/useGsapContext.ts.template +92 -0
- package/framework/scaffold/motion-premium/lib/animations/useScrollSnapStepper.ts.template +265 -0
- package/framework/scaffold/motion-premium/lib/animations/useSmoothScroll.ts.template +67 -0
- package/framework/scaffold/motion-premium/lib/brand.ts.template +43 -0
- package/framework/scaffold/motion-premium/scaffold.yaml +174 -0
- package/framework/scaffold/motion-premium-3d/README.md +80 -0
- package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoCanvas.tsx.template +81 -0
- package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoClient.tsx.template +75 -0
- package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/page.tsx.template +26 -0
- package/framework/scaffold/motion-premium-3d/components/3d/CameraRig.tsx.template +100 -0
- package/framework/scaffold/motion-premium-3d/components/3d/CanvasProvider.tsx.template +85 -0
- package/framework/scaffold/motion-premium-3d/components/3d/InvalidateOnScroll.tsx.template +51 -0
- package/framework/scaffold/motion-premium-3d/components/3d/MeshCrossfade.tsx.template +79 -0
- package/framework/scaffold/motion-premium-3d/components/3d/ScrollCrossfade.tsx.template +88 -0
- package/framework/scaffold/motion-premium-3d/components/3d/ScrollScene.tsx.template +121 -0
- package/framework/scaffold/motion-premium-3d/components/webgl/SceneFallback.tsx.template +65 -0
- package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +68 -0
- package/framework/scaffold/motion-premium-3d/lib/webgl/detect.ts.template +69 -0
- package/framework/scaffold/motion-premium-3d/scaffold.yaml +133 -0
- package/framework/schemas/session.schema.json +109 -21
- package/framework/scripts/reference-capture.js +430 -0
- package/framework/scripts/visual-qa.js +674 -0
- package/framework/tasks/orchestrator-handoff.md +1 -1
- package/framework/tasks/orchestrator-resume.md +1 -1
- package/framework/tasks/orchestrator-route.md +1 -1
- package/framework/tasks/orchestrator-status.md +3 -3
- package/framework/tasks/qa-planning-gate-define.md +1 -1
- package/framework/templates/brandbook-html-tmpl.md +1 -1
- package/framework/templates/brandbook-tmpl.yaml +1 -1
- package/framework/templates/component-spec-tmpl.yaml +1 -1
- package/framework/templates/design-token-tmpl.yaml +1 -1
- package/framework/templates/icon-system-tmpl.yaml +1 -1
- package/framework/templates/team-planning-tasks.yaml +6 -5
- package/framework/workflows/brownfield-discovery.yaml +2 -2
- package/framework/workflows/brownfield-fullstack.yaml +15 -11
- package/framework/workflows/brownfield-service.yaml +14 -10
- package/framework/workflows/brownfield-ui.yaml +15 -11
- package/framework/workflows/greenfield-fullstack.yaml +16 -13
- package/framework/workflows/quick-flow.yaml +3 -3
- package/framework/workflows/standard-flow.yaml +12 -9
- package/package.json +10 -5
- package/src/autonomy/autonomous-gate.js +1 -0
- package/src/autonomy/build-state.js +1 -2
- package/src/autonomy/progress-reporter.js +1 -1
- package/src/config/agent-customizer.js +11 -3
- package/src/config/claude-settings-generator.js +226 -0
- package/src/config/context-file-generator.js +41 -21
- package/src/config/framework-adapter.js +1 -0
- package/src/config/gemini-hooks-generator.js +76 -6
- package/src/config/mcp-configs.js +1 -0
- package/src/context/layers/l1-global.js +2 -1
- package/src/dashboard/data-reader.js +4 -3
- package/src/dashboard/layout.js +2 -1
- package/src/decision/analyzer.js +6 -30
- package/src/decision/engine.js +4 -28
- package/src/decision/registry-healer.js +3 -2
- package/src/decision/registry-updater.js +23 -14
- package/src/extensions/loader.js +2 -8
- package/src/gates/g1-planning-complete.js +2 -1
- package/src/gates/g2-qa-planning.js +2 -1
- package/src/gates/g3-implementation.js +2 -1
- package/src/gates/g4-qa-implementation.js +3 -2
- package/src/gates/g5-deploy-ready.js +2 -1
- package/src/health/engine.js +4 -3
- package/src/installer/core.js +557 -81
- package/src/installer/preflight.js +131 -0
- package/src/installer/provider-overlay.js +3 -3
- package/src/installer/scaffold-applier.js +358 -0
- package/src/installer/templates.js +52 -31
- package/src/installer/validator.js +17 -12
- package/src/intelligence/registry-manager.js +22 -29
- package/src/intelligence/timeline.js +11 -6
- package/src/license/commands.js +1 -1
- package/src/license/wait.js +102 -0
- package/src/memory/agent-memory.js +81 -0
- package/src/memory/dream.js +32 -1
- package/src/merger/replace-merger.js +28 -15
- package/src/orchestrator/agent-selector.js +2 -1
- package/src/orchestrator/cli.js +1908 -80
- package/src/orchestrator/doctor.js +270 -0
- package/src/orchestrator/handoff-engine.js +4 -3
- package/src/orchestrator/index.js +2 -0
- package/src/orchestrator/pipeline-manager.js +306 -15
- package/src/orchestrator/session-manager.js +331 -6
- package/src/tasks/handoff.js +3 -2
- package/src/telemetry/config.js +4 -3
- package/src/telemetry/schema.js +1 -0
- package/src/terminal/collector.js +3 -2
- package/src/terminal/index.js +1 -2
- package/src/terminal/isolation.js +52 -18
- package/src/terminal/prompt-builder.js +42 -25
- package/src/terminal/run-parallel.js +1 -1
- package/src/terminal/run-team.js +3 -3
- package/src/terminal/team-task-list.js +43 -4
- package/src/upgrade/backup.js +3 -2
- package/src/upgrade/checker.js +3 -2
- package/src/upgrade/migrator.js +65 -7
- package/src/upgrade/tracked-files-detector.js +86 -0
- package/src/upgrade/user-messages.js +94 -0
- package/src/utils/config-parser.js +2 -1
- package/src/utils/feature-flags.js +2 -1
- package/src/utils/flatten-entities.js +69 -0
- package/src/utils/framework-dir.js +16 -0
- package/src/utils/model-id.js +85 -0
- package/src/utils/provider-limits.js +84 -23
- package/src/utils/schema-validator.js +1 -1
- package/src/wizard/i18n.js +5 -4
- package/src/wizard/index.js +14 -0
- package/assets/logo - c/303/263pia.png +0 -0
- package/assets/logo.svg +0 -42
- package/assets/logo2.png +0 -0
- package/assets/social-preview.png +0 -0
- package/scripts/bundle-framework.js +0 -69
- package/scripts/changelog-generator.js +0 -222
- package/scripts/codebase-mapper.js +0 -728
- package/scripts/commit-message-generator.js +0 -167
- package/scripts/coverage-analyzer.js +0 -260
- package/scripts/dependency-analyzer.js +0 -280
- package/scripts/doctor/checks/agents.js +0 -77
- package/scripts/doctor/checks/constitution.js +0 -41
- package/scripts/doctor/checks/domain-alignment.js +0 -58
- package/scripts/doctor/checks/prism-layers.js +0 -84
- package/scripts/doctor/checks/registry.js +0 -55
- package/scripts/doctor/checks/schemas.js +0 -61
- package/scripts/doctor/fixes/reference-fix.js +0 -100
- package/scripts/doctor/fixes/registry-fix.js +0 -56
- package/scripts/doctor/index.js +0 -212
- package/scripts/framework-analyzer.js +0 -308
- package/scripts/generate-constitution-domain.js +0 -253
- package/scripts/generate-signing-key.js +0 -33
- package/scripts/health-check.js +0 -481
- package/scripts/ide-sync.js +0 -326
- package/scripts/performance-analyzer.js +0 -325
- package/scripts/plan-tracker.js +0 -278
- package/scripts/populate-entity-registry.js +0 -481
- package/scripts/pr-review.js +0 -317
- package/scripts/rollback-manager.js +0 -310
- package/scripts/semantic-lint.js +0 -328
- package/scripts/sign-manifest.js +0 -53
- package/scripts/stuck-detector.js +0 -343
- package/scripts/test-quality-assessment.js +0 -257
- package/scripts/validate-agents.js +0 -368
- package/scripts/validate-package.js +0 -367
- package/scripts/validate-tasks.js +0 -465
- package/src/autonomy/worktree-manager.js +0 -250
- package/src/intelligence/decision-engine.js +0 -256
- package/src/intelligence/document-sharder.js +0 -221
- package/src/intelligence/elicitation.js +0 -265
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Post-Dev Auto-QA Hook — PostToolUse (runs after Write tool calls)
|
|
4
|
+
*
|
|
5
|
+
* Autonomous-completion v1 (ADR-AUTO-06). When dev writes its handoff file
|
|
6
|
+
* with status=completed and score >= threshold, this hook spawns
|
|
7
|
+
* visual-qa.js detached — 6 viewports + reduced-motion pass — so the next
|
|
8
|
+
* `/chati` turn finds .chati/visual-qa/report.json already populated.
|
|
9
|
+
*
|
|
10
|
+
* The user never types `pnpm build && pnpm start`. visual-qa.js owns its
|
|
11
|
+
* own dev-server (`npx next dev -p <port>` unless --no-server); this hook
|
|
12
|
+
* just spawns it with the right arguments and exits.
|
|
13
|
+
*
|
|
14
|
+
* Opt-out: set `auto_visual_qa: false` in `chati.dev/config.yaml` (or
|
|
15
|
+
* `.chati.dev/config.yaml` for installed projects). Default is true — the
|
|
16
|
+
* zero-commands thesis.
|
|
17
|
+
*
|
|
18
|
+
* Trigger condition:
|
|
19
|
+
* Write tool wrote `artifacts/handoffs/dev-handoff.md` with frontmatter
|
|
20
|
+
* `status: completed` AND `score: >= 90`.
|
|
21
|
+
*
|
|
22
|
+
* Observational: always returns `{}` — never blocks the Write call. The
|
|
23
|
+
* spawn is detached with stdio ignored so it outlives this hook process.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { existsSync, readFileSync } from 'fs';
|
|
27
|
+
import { join } from 'path';
|
|
28
|
+
import { spawn } from 'child_process';
|
|
29
|
+
|
|
30
|
+
export const DEV_SCORE_THRESHOLD = 90;
|
|
31
|
+
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Config loader — checks both installed (.chati.dev) and dev (chati.dev).
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
export function readAutoVisualQaConfig(projectDir) {
|
|
37
|
+
const candidates = [
|
|
38
|
+
join(projectDir, '.chati.dev', 'config.yaml'),
|
|
39
|
+
join(projectDir, 'chati.dev', 'config.yaml'),
|
|
40
|
+
];
|
|
41
|
+
for (const p of candidates) {
|
|
42
|
+
if (!existsSync(p)) continue;
|
|
43
|
+
try {
|
|
44
|
+
const raw = readFileSync(p, 'utf-8');
|
|
45
|
+
const match = raw.match(/^\s*auto_visual_qa:\s*(true|false)\s*$/m);
|
|
46
|
+
if (match) return match[1] === 'true';
|
|
47
|
+
} catch { /* fall through — config unreadable, use default */ }
|
|
48
|
+
}
|
|
49
|
+
return true; // default ON per ADR-AUTO-06
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Handoff frontmatter extraction.
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
export function extractHandoffMeta(markdown) {
|
|
57
|
+
if (!markdown || !markdown.startsWith('---')) return null;
|
|
58
|
+
const end = markdown.indexOf('\n---', 3);
|
|
59
|
+
if (end === -1) return null;
|
|
60
|
+
const fm = markdown.slice(3, end + 1);
|
|
61
|
+
const meta = {};
|
|
62
|
+
for (const line of fm.split('\n')) {
|
|
63
|
+
const m = line.match(/^([a-zA-Z_][\w-]*):\s*(.+)$/);
|
|
64
|
+
if (m) meta[m[1].trim()] = m[2].trim().replace(/^["']|["']$/g, '');
|
|
65
|
+
}
|
|
66
|
+
return meta;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Route discovery (duplicate of cli.js discoverAppRoutes — hooks cannot
|
|
71
|
+
// import package modules).
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
import { readdirSync } from 'fs';
|
|
75
|
+
|
|
76
|
+
export function discoverRoutes(projectDir) {
|
|
77
|
+
const candidates = [join(projectDir, 'app'), join(projectDir, 'src', 'app')];
|
|
78
|
+
const appDir = candidates.find(d => existsSync(d));
|
|
79
|
+
if (!appDir) return ['/'];
|
|
80
|
+
const routes = [];
|
|
81
|
+
const PAGE_RE = /^page\.(tsx|jsx|ts|js|mdx)$/;
|
|
82
|
+
function walk(dir, segments) {
|
|
83
|
+
let entries;
|
|
84
|
+
try { entries = readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
|
85
|
+
for (const e of entries) {
|
|
86
|
+
if (e.isDirectory()) {
|
|
87
|
+
const name = e.name;
|
|
88
|
+
if (name.startsWith('_')) continue;
|
|
89
|
+
if (name.startsWith('[')) continue;
|
|
90
|
+
const isGroup = name.startsWith('(') && name.endsWith(')');
|
|
91
|
+
const nextSegments = isGroup ? segments : [...segments, name];
|
|
92
|
+
walk(join(dir, e.name), nextSegments);
|
|
93
|
+
} else if (e.isFile() && PAGE_RE.test(e.name)) {
|
|
94
|
+
routes.push(segments.length === 0 ? '/' : '/' + segments.join('/'));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
walk(appDir, []);
|
|
99
|
+
const unique = [...new Set(routes)].sort();
|
|
100
|
+
return unique.length > 0 ? unique : ['/'];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Spawn decision — returns the command + args to run, or null when auto-QA
|
|
105
|
+
// should not fire. Pure for testability.
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @param {{ projectDir: string, toolName: string, filePath: string }} ctx
|
|
110
|
+
* @returns {{ command: string, args: string[] } | null}
|
|
111
|
+
*/
|
|
112
|
+
export function decideSpawn(ctx) {
|
|
113
|
+
if (ctx.toolName !== 'Write') return null;
|
|
114
|
+
if (!ctx.filePath) return null;
|
|
115
|
+
|
|
116
|
+
// Match only dev-handoff.md in the canonical paths.
|
|
117
|
+
const handoffMatch = ctx.filePath.match(/artifacts\/handoffs\/dev-handoff\.md$/);
|
|
118
|
+
if (!handoffMatch) return null;
|
|
119
|
+
|
|
120
|
+
// Read the handoff to confirm status=completed and score passes threshold.
|
|
121
|
+
let meta = null;
|
|
122
|
+
try {
|
|
123
|
+
const raw = readFileSync(ctx.filePath, 'utf-8');
|
|
124
|
+
meta = extractHandoffMeta(raw);
|
|
125
|
+
} catch { return null; }
|
|
126
|
+
if (!meta) return null;
|
|
127
|
+
if (meta.status !== 'completed') return null;
|
|
128
|
+
const score = parseInt(meta.score, 10);
|
|
129
|
+
if (!Number.isFinite(score) || score < DEV_SCORE_THRESHOLD) return null;
|
|
130
|
+
|
|
131
|
+
// Config opt-out wins.
|
|
132
|
+
if (!readAutoVisualQaConfig(ctx.projectDir)) return null;
|
|
133
|
+
|
|
134
|
+
// Resolve script path.
|
|
135
|
+
const scriptCandidates = [
|
|
136
|
+
join(ctx.projectDir, '.chati.dev', 'scripts', 'visual-qa.js'),
|
|
137
|
+
join(ctx.projectDir, 'chati.dev', 'scripts', 'visual-qa.js'),
|
|
138
|
+
];
|
|
139
|
+
const script = scriptCandidates.find(existsSync);
|
|
140
|
+
if (!script) return null;
|
|
141
|
+
|
|
142
|
+
const routes = discoverRoutes(ctx.projectDir);
|
|
143
|
+
const output = join(ctx.projectDir, '.chati', 'visual-qa');
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
command: 'node',
|
|
147
|
+
args: [
|
|
148
|
+
script,
|
|
149
|
+
'--pages', ...routes,
|
|
150
|
+
'--output', output,
|
|
151
|
+
'--reduced-motion', 'on', // accessibility pass; gate in P6 reads this
|
|
152
|
+
],
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// Hook entry point.
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
|
|
160
|
+
async function readStdin() {
|
|
161
|
+
let data = '';
|
|
162
|
+
for await (const chunk of process.stdin) data += chunk;
|
|
163
|
+
return data;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function main() {
|
|
167
|
+
let input;
|
|
168
|
+
try {
|
|
169
|
+
input = JSON.parse(await readStdin() || '{}');
|
|
170
|
+
} catch {
|
|
171
|
+
process.stdout.write('{}\n');
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const ctx = {
|
|
176
|
+
projectDir: input.cwd || process.cwd(),
|
|
177
|
+
toolName: input.tool_name || '',
|
|
178
|
+
filePath: (input.tool_input && input.tool_input.file_path) || '',
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// Observational default — the hook never blocks the Write call.
|
|
182
|
+
process.stdout.write('{}\n');
|
|
183
|
+
|
|
184
|
+
const plan = decideSpawn(ctx);
|
|
185
|
+
if (!plan) return;
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
const child = spawn(plan.command, plan.args, {
|
|
189
|
+
cwd: ctx.projectDir,
|
|
190
|
+
detached: true,
|
|
191
|
+
stdio: 'ignore',
|
|
192
|
+
});
|
|
193
|
+
child.unref();
|
|
194
|
+
} catch (err) {
|
|
195
|
+
process.stderr.write(`[chati] post-dev spawn failed: ${err.message}\n`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
import { fileURLToPath } from 'url';
|
|
200
|
+
import { realpathSync } from 'fs';
|
|
201
|
+
if (process.argv[1]) {
|
|
202
|
+
try {
|
|
203
|
+
if (realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) {
|
|
204
|
+
main();
|
|
205
|
+
}
|
|
206
|
+
} catch { /* not invoked as a script */ }
|
|
207
|
+
}
|