synapse-compiler 0.0.0-stage → 0.2.2
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 +27 -2
- package/dist/causal-build.d.ts +51 -0
- package/dist/causal-graph.d.ts +6 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +1276 -0
- package/dist/core/config.d.ts +16 -0
- package/dist/core/engine.d.ts +17 -0
- package/dist/core/reporter.d.ts +5 -0
- package/dist/i18n.d.ts +281 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +1973 -0
- package/dist/plugins/cpp.d.ts +19 -0
- package/dist/plugins/csharp.d.ts +13 -0
- package/dist/plugins/go.d.ts +15 -0
- package/dist/plugins/java.d.ts +16 -0
- package/dist/plugins/native.d.ts +12 -0
- package/dist/plugins/nsis.d.ts +8 -0
- package/dist/plugins/python.d.ts +21 -0
- package/dist/plugins/rust.d.ts +9 -0
- package/dist/plugins/schema.d.ts +12 -0
- package/dist/plugins/svelte.d.ts +10 -0
- package/dist/plugins/typescript.d.ts +23 -0
- package/dist/types.d.ts +72 -0
- package/package.json +41 -4
package/dist/cli.js
ADDED
|
@@ -0,0 +1,1276 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
|
|
4
|
+
// cli.ts
|
|
5
|
+
import { resolve as resolve4 } from "path";
|
|
6
|
+
import { existsSync as existsSync4 } from "fs";
|
|
7
|
+
import { writeFile } from "fs/promises";
|
|
8
|
+
// ../package.json
|
|
9
|
+
var package_default = {
|
|
10
|
+
name: "synapse-kit",
|
|
11
|
+
version: "0.2.2",
|
|
12
|
+
private: false,
|
|
13
|
+
publishConfig: {
|
|
14
|
+
access: "public"
|
|
15
|
+
},
|
|
16
|
+
description: "AI-Native Unified Twin-Core: Polyglot Compiler Engine & Causal Memory 2.0 Brain for Monorepos and Agents",
|
|
17
|
+
type: "module",
|
|
18
|
+
main: "dist/index.js",
|
|
19
|
+
types: "dist/index.d.ts",
|
|
20
|
+
bin: {
|
|
21
|
+
synapse: "./dist/compiler/cli.js",
|
|
22
|
+
"synapse-kit": "./dist/compiler/cli.js",
|
|
23
|
+
"synapse-memory": "./dist/memory/cli.js"
|
|
24
|
+
},
|
|
25
|
+
exports: {
|
|
26
|
+
".": {
|
|
27
|
+
types: "./dist/index.d.ts",
|
|
28
|
+
import: "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./compiler": {
|
|
31
|
+
types: "./dist/compiler/index.d.ts",
|
|
32
|
+
import: "./dist/compiler/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./memory": {
|
|
35
|
+
types: "./dist/memory/index.d.ts",
|
|
36
|
+
import: "./dist/memory/index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
workspaces: [
|
|
40
|
+
"compiler",
|
|
41
|
+
"memory"
|
|
42
|
+
],
|
|
43
|
+
files: [
|
|
44
|
+
"dist",
|
|
45
|
+
"README.md",
|
|
46
|
+
"README.ko.md",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
],
|
|
49
|
+
scripts: {
|
|
50
|
+
"build:compiler": "cd compiler && bun run build",
|
|
51
|
+
"build:memory": "cd memory && bun run build",
|
|
52
|
+
"build:root": "bun build compiler/cli.ts --outfile dist/compiler/cli.js --target bun && bun build memory/cli.ts --outfile dist/memory/cli.js --target bun && bun build index.ts --outfile dist/index.js --target bun && bun build compiler/index.ts --outfile dist/compiler/index.js --target bun && bun build memory/index.ts --outfile dist/memory/index.js --target bun && tsc -p tsconfig.build.json",
|
|
53
|
+
build: "bun run build:root && bun run build:compiler && bun run build:memory",
|
|
54
|
+
prepublishOnly: "bun run build",
|
|
55
|
+
start: "bun run compiler/cli.ts",
|
|
56
|
+
check: "bun run compiler/cli.ts check",
|
|
57
|
+
test: "bun test"
|
|
58
|
+
},
|
|
59
|
+
repository: {
|
|
60
|
+
type: "git",
|
|
61
|
+
url: "git+https://github.com/minseokk77/synapse-kit.git"
|
|
62
|
+
},
|
|
63
|
+
homepage: "https://github.com/minseokk77/synapse-kit#readme",
|
|
64
|
+
bugs: {
|
|
65
|
+
url: "https://github.com/minseokk77/synapse-kit/issues"
|
|
66
|
+
},
|
|
67
|
+
keywords: [
|
|
68
|
+
"tauri",
|
|
69
|
+
"compiler",
|
|
70
|
+
"verification",
|
|
71
|
+
"rust",
|
|
72
|
+
"svelte",
|
|
73
|
+
"typescript",
|
|
74
|
+
"ai-native",
|
|
75
|
+
"causal-memory",
|
|
76
|
+
"bun"
|
|
77
|
+
],
|
|
78
|
+
author: "Vesper",
|
|
79
|
+
license: "MIT",
|
|
80
|
+
devDependencies: {
|
|
81
|
+
"@types/bun": "^1.4.4",
|
|
82
|
+
typescript: "^5.6.3"
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// core/config.ts
|
|
87
|
+
import { resolve } from "path";
|
|
88
|
+
import { existsSync } from "fs";
|
|
89
|
+
var CONFIG_FILENAMES = [
|
|
90
|
+
"synapse.config.ts",
|
|
91
|
+
"synapse.config.js",
|
|
92
|
+
"synapse.config.mjs"
|
|
93
|
+
];
|
|
94
|
+
async function loadSynapseConfig(targetDir = process.cwd()) {
|
|
95
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
96
|
+
const candidate = resolve(targetDir, filename);
|
|
97
|
+
if (existsSync(candidate)) {
|
|
98
|
+
try {
|
|
99
|
+
const imported = await import(candidate);
|
|
100
|
+
const config = imported.default || imported;
|
|
101
|
+
return {
|
|
102
|
+
config: {
|
|
103
|
+
...config,
|
|
104
|
+
rootDir: config.rootDir ? resolve(targetDir, config.rootDir) : targetDir
|
|
105
|
+
},
|
|
106
|
+
configPath: candidate
|
|
107
|
+
};
|
|
108
|
+
} catch (error) {
|
|
109
|
+
throw new Error(`\uC124\uC815 \uD30C\uC77C(${candidate}) \uB85C\uB529 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4: ${error instanceof Error ? error.message : String(error)}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
throw new Error(`\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8(${targetDir})\uC5D0\uC11C synapse.config.ts \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
114
|
+
` + `'synapse init' \uBA85\uB839\uC5B4\uB97C \uC2E4\uD589\uD558\uC5EC \uAE30\uBCF8 \uC124\uC815 \uD30C\uC77C\uC744 \uC0DD\uC131\uD574 \uC8FC\uC138\uC694.`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// core/engine.ts
|
|
118
|
+
var {spawn: spawn2 } = globalThis.Bun;
|
|
119
|
+
import { existsSync as existsSync3, readdirSync, watch } from "fs";
|
|
120
|
+
import { resolve as resolve3 } from "path";
|
|
121
|
+
|
|
122
|
+
// causal-build.ts
|
|
123
|
+
var {spawn } = globalThis.Bun;
|
|
124
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync, statSync } from "fs";
|
|
125
|
+
import { resolve as resolve2 } from "path";
|
|
126
|
+
import { createHash } from "crypto";
|
|
127
|
+
function loadBuildCache(rootDir) {
|
|
128
|
+
const cacheFile = resolve2(rootDir, ".synapse/build-cache.json");
|
|
129
|
+
try {
|
|
130
|
+
if (existsSync2(cacheFile)) {
|
|
131
|
+
const content = readFileSync(cacheFile, "utf-8");
|
|
132
|
+
const parsed = JSON.parse(content);
|
|
133
|
+
return {
|
|
134
|
+
lastVerifiedHead: parsed.lastVerifiedHead,
|
|
135
|
+
tracks: parsed.tracks || {},
|
|
136
|
+
sign: parsed.sign
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
} catch {}
|
|
140
|
+
return { tracks: {} };
|
|
141
|
+
}
|
|
142
|
+
function saveBuildCache(rootDir, cache) {
|
|
143
|
+
const cacheDir = resolve2(rootDir, ".synapse");
|
|
144
|
+
const cacheFile = resolve2(cacheDir, "build-cache.json");
|
|
145
|
+
try {
|
|
146
|
+
if (!existsSync2(cacheDir)) {
|
|
147
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
148
|
+
}
|
|
149
|
+
writeFileSync(cacheFile, JSON.stringify(cache, null, 2), "utf-8");
|
|
150
|
+
} catch {}
|
|
151
|
+
}
|
|
152
|
+
async function getGitState(rootDir) {
|
|
153
|
+
try {
|
|
154
|
+
const rootProc = spawn(["git", "rev-parse", "--show-toplevel"], { cwd: rootDir, stdout: "pipe" });
|
|
155
|
+
const repoRoot = (await new Response(rootProc.stdout).text()).trim().replaceAll("\\", "/");
|
|
156
|
+
await rootProc.exited;
|
|
157
|
+
const headProc = spawn(["git", "rev-parse", "HEAD"], { cwd: rootDir, stdout: "pipe" });
|
|
158
|
+
const head = (await new Response(headProc.stdout).text()).trim();
|
|
159
|
+
await headProc.exited;
|
|
160
|
+
const statusProc = spawn(["git", "status", "--porcelain", "-uall"], { cwd: rootDir, stdout: "pipe" });
|
|
161
|
+
const statusText = await new Response(statusProc.stdout).text();
|
|
162
|
+
await statusProc.exited;
|
|
163
|
+
const modifiedFiles = statusText.split(`
|
|
164
|
+
`).map((line) => line.slice(3).trim().replaceAll("\\", "/")).filter((line) => line.length > 0 && !line.startsWith(".synapse/") && !line.includes("/.synapse/"));
|
|
165
|
+
return { head, modifiedFiles, repoRoot: repoRoot || rootDir };
|
|
166
|
+
} catch {
|
|
167
|
+
return { head: "unknown", modifiedFiles: [], repoRoot: rootDir };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function shouldSkipBuildTrack(track, rootDir, repoRoot, cache, modifiedFiles, isForce) {
|
|
171
|
+
if (isForce) {
|
|
172
|
+
return { skip: false, reason: "\uAC15\uC81C \uBE4C\uB4DC \uBAA8\uB4DC(--force)" };
|
|
173
|
+
}
|
|
174
|
+
const artifacts = track.artifacts || [];
|
|
175
|
+
if (artifacts.length > 0) {
|
|
176
|
+
for (const art of artifacts) {
|
|
177
|
+
const fullPath = resolve2(track.cwd || rootDir, art);
|
|
178
|
+
if (!existsSync2(fullPath)) {
|
|
179
|
+
return { skip: false, reason: `\uC0B0\uCD9C\uBB3C \uB204\uB77D: ${art}` };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const record = cache.tracks[track.name];
|
|
184
|
+
if (!record) {
|
|
185
|
+
return { skip: false, reason: "\uCD08\uAE30 \uBE4C\uB4DC \uAE30\uB85D \uC5C6\uC74C" };
|
|
186
|
+
}
|
|
187
|
+
const sources = track.sources || [];
|
|
188
|
+
if (sources.length > 0) {
|
|
189
|
+
const lastBuildEpoch = new Date(record.lastBuildTime).getTime();
|
|
190
|
+
const hasModifiedSource = modifiedFiles.some((file) => {
|
|
191
|
+
const isMatch = sources.some((src) => file.includes(src.replaceAll("\\", "/")));
|
|
192
|
+
if (!isMatch)
|
|
193
|
+
return false;
|
|
194
|
+
const fullPath = resolve2(repoRoot, file);
|
|
195
|
+
if (existsSync2(fullPath)) {
|
|
196
|
+
try {
|
|
197
|
+
const stat = statSync(fullPath);
|
|
198
|
+
return stat.mtimeMs > lastBuildEpoch;
|
|
199
|
+
} catch {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return true;
|
|
204
|
+
});
|
|
205
|
+
if (hasModifiedSource) {
|
|
206
|
+
return { skip: false, reason: "\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC \uC774\uD6C4 \uC18C\uC2A4 \uCF54\uB4DC \uBCC0\uACBD \uAC10\uC9C0" };
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return { skip: true, reason: "\uC778\uACFC\uC728 \uBA54\uBAA8\uB9AC \uC77C\uCE58 (\uC18C\uC2A4 \uBCC0\uACBD \uC5C6\uC74C)" };
|
|
210
|
+
}
|
|
211
|
+
function computeFileHash(filePath) {
|
|
212
|
+
try {
|
|
213
|
+
const buffer = readFileSync(filePath);
|
|
214
|
+
return createHash("sha256").update(buffer).digest("hex");
|
|
215
|
+
} catch {
|
|
216
|
+
return "";
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function shouldSkipSign(installerPath, signaturePath, cache, isForce) {
|
|
220
|
+
if (isForce) {
|
|
221
|
+
return { skip: false, reason: "\uAC15\uC81C \uC11C\uBA85 \uBAA8\uB4DC(--force)", currentHash: "" };
|
|
222
|
+
}
|
|
223
|
+
if (!existsSync2(installerPath)) {
|
|
224
|
+
return { skip: false, reason: "\uC11C\uBA85 \uB300\uC0C1 \uC778\uC2A4\uD1A8\uB7EC \uBBF8\uC874\uC7AC", currentHash: "" };
|
|
225
|
+
}
|
|
226
|
+
if (!existsSync2(signaturePath)) {
|
|
227
|
+
return { skip: false, reason: "\uAE30\uC874 \uC11C\uBA85(.sig) \uD30C\uC77C \uBBF8\uC874\uC7AC", currentHash: "" };
|
|
228
|
+
}
|
|
229
|
+
const currentHash = computeFileHash(installerPath);
|
|
230
|
+
if (!currentHash) {
|
|
231
|
+
return { skip: false, reason: "\uC778\uC2A4\uD1A8\uB7EC \uD574\uC2DC \uACC4\uC0B0 \uBD88\uAC00", currentHash: "" };
|
|
232
|
+
}
|
|
233
|
+
const record = cache.sign;
|
|
234
|
+
if (record && record.installerHash === currentHash && record.signaturePath === signaturePath) {
|
|
235
|
+
return { skip: true, reason: "\uC778\uC2A4\uD1A8\uB7EC \uBC14\uC774\uB108\uB9AC \uBD88\uBCC0 (\uC11C\uBA85 \uCE90\uC2DC \uC801\uC911)", currentHash };
|
|
236
|
+
}
|
|
237
|
+
return { skip: false, reason: "\uC778\uC2A4\uD1A8\uB7EC \uBC14\uC774\uB108\uB9AC \uBCC0\uACBD \uAC10\uC9C0", currentHash };
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// i18n.ts
|
|
241
|
+
var currentLocale = "en";
|
|
242
|
+
var MESSAGES = {
|
|
243
|
+
ko: {
|
|
244
|
+
cliTitle: "\uD83E\uDDE0 Synapse Kit - AI-Native \uD1B5\uD569 \uCEF4\uD30C\uC77C, \uBE4C\uB4DC & \uD328\uD0A4\uC9D5 \uD504\uB808\uC784\uC6CC\uD06C",
|
|
245
|
+
cliUsage: "\uC0AC\uC6A9\uBC95:",
|
|
246
|
+
cliCommands: "\uD575\uC2EC \uBA85\uB839\uC5B4:",
|
|
247
|
+
cmdCheck: "\uB4F1\uB85D\uB41C \uD50C\uB7EC\uADF8\uC778 \uBB34\uACB0\uC131 \uAC80\uC99D (\uAE30\uBCF8: AI \uC778\uACFC\uC728 \uC2A4\uB9C8\uD2B8 \uAC80\uC0AC)",
|
|
248
|
+
cmdBuild: "\uB4F1\uB85D\uB41C buildTracks \uCD08\uACE0\uC18D \uC778\uACFC\uC728 \uBCD1\uB82C \uC99D\uBD84 \uBE4C\uB4DC (0\uCD08\uB300 \uCE90\uC2DC)",
|
|
249
|
+
cmdPackage: "\uB2E8\uC77C NSIS + zlib \uACE0\uC18D \uC778\uC2A4\uD1A8\uB7EC \uD328\uD0A4\uC9D5 \uBC88\uB4E4\uB7EC",
|
|
250
|
+
cmdSign: "\uC778\uACFC\uC728 \uC554\uD638\uD654 \uC11C\uBA85 \uC5D4\uC9C4 (Minisign / Ed25519)",
|
|
251
|
+
cmdInit: "\uD604\uC7AC \uB514\uB809\uD130\uB9AC\uC5D0 \uCD5C\uC801\uD654\uB41C synapse.config.ts \uC0DD\uC131",
|
|
252
|
+
cmdMemory: "\uC778\uACFC\uC728 \uBA54\uBAA8\uB9AC(Causal Memory) \uCD08\uACBD\uB7C9 \uACF5\uBA85 \uC870\uD68C, \uAD00\uB9AC \uBC0F \uB85C\uCEEC \uB370\uBAAC \uAD6C\uB3D9",
|
|
253
|
+
cliOptions: "\uC635\uC158:",
|
|
254
|
+
optAll: "\uC778\uACFC\uC728 \uC2A4\uD0B5\uC744 \uB044\uACE0 \uC804\uBC29\uC704 \uAC15\uC81C \uAC80\uC0AC",
|
|
255
|
+
optForce: "\uBE4C\uB4DC/\uC11C\uBA85 \uC2DC \uC778\uACFC\uC728 \uCE90\uC2DC\uB97C \uBB34\uC2DC\uD558\uACE0 \uAC15\uC81C \uC7AC\uC2E4\uD589",
|
|
256
|
+
optAgent: "AI \uC5D0\uC774\uC804\uD2B8(Claude Code, Antigravity \uB4F1) \uC5F0\uB3D9\uC6A9 \uAD6C\uC870\uD654\uB41C JSON \uCD9C\uB825",
|
|
257
|
+
optCompact: "AI \uD1A0\uD070 \uADF9\uB2E8\uC801 \uCD5C\uC18C\uD654 \uBAA8\uB4DC (\uC131\uACF5 \uC2DC \uB2E8 11 \uD1A0\uD070)",
|
|
258
|
+
optInteractive: "\uC624\uB958 \uBC1C\uC0DD \uC2DC \uD504\uB85C\uC138\uC2A4\uB97C \uC77C\uC2DC\uC815\uC9C0\uD558\uACE0 \uC2E4\uC2DC\uAC04 \uCF54\uB4DC \uC218\uC815 \uB300\uAE30 (\uC778\uACFC \uD56B\uD53D\uC2A4)",
|
|
259
|
+
optWatch: "\uD30C\uC77C \uBCC0\uACBD \uAC10\uC9C0 \uBC31\uADF8\uB77C\uC6B4\uB4DC \uBAA8\uB4DC",
|
|
260
|
+
optLang: "\uCD9C\uB825 \uC5B8\uC5B4 \uAC15\uC81C \uC9C0\uC815 (ko | en)",
|
|
261
|
+
optHelp: "\uB3C4\uC6C0\uB9D0 \uD45C\uC2DC",
|
|
262
|
+
optVersion: "\uBC84\uC804 \uC815\uBCF4 \uD45C\uC2DC",
|
|
263
|
+
unknownCmd: "\uC54C \uC218 \uC5C6\uB294 \uBA85\uB839\uC5B4:",
|
|
264
|
+
errPrefix: "\uD83D\uDEA8 \uC624\uB958:",
|
|
265
|
+
configExists: "\uC774\uBBF8 \uC124\uC815 \uD30C\uC77C\uC774 \uC874\uC7AC\uD569\uB2C8\uB2E4:",
|
|
266
|
+
configCreated: "synapse.config.ts \uD15C\uD50C\uB9BF\uC774 \uC131\uACF5\uC801\uC73C\uB85C \uC0DD\uC131\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",
|
|
267
|
+
checkHeader: "\uD83E\uDDE0 [Synapse Kit] AI-Native \uD1B5\uD569 \uCEF4\uD30C\uC77C & \uAC80\uC0AC \uD504\uB808\uC784\uC6CC\uD06C",
|
|
268
|
+
causalAll: "\uC804\uCCB4 \uAC80\uC0AC \uBAA8\uB4DC(--all) \uC694\uCCAD: \uBAA8\uB4E0 \uD50C\uB7EC\uADF8\uC778 \uAC80\uC0AC\uAE30\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4.",
|
|
269
|
+
causalDirty: (count, plugins) => `\uBCC0\uACBD\uB41C ${count}\uAC1C \uD30C\uC77C \uC778\uACFC \uBD84\uC11D \uC644\uB8CC: [${plugins}] \uD50C\uB7EC\uADF8\uC778\uB9CC \uC120\uBCC4 \uC2E4\uD589\uD569\uB2C8\uB2E4.`,
|
|
270
|
+
causalClean: "\uBCC0\uACBD\uB41C \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uBAA8\uB4E0 \uAC80\uC99D \uD50C\uB7EC\uADF8\uC778\uC744 0.00\uCD08 \uC2A4\uD0B5\uD569\uB2C8\uB2E4.",
|
|
271
|
+
causalCleanCacheHit: "\uC791\uC5C5 \uD2B8\uB9AC\uC5D0 \uBCC0\uACBD \uD30C\uC77C\uC774 \uC5C6\uC73C\uBA70 \uC774\uC804 \uAC80\uC99D \uD1B5\uACFC \uCEE4\uBC0B\uACFC \uC77C\uCE58\uD558\uC5EC 0.00\uCD08 \uC2A4\uD0B5\uD569\uB2C8\uB2E4.",
|
|
272
|
+
causalBaseline: "\uC791\uC5C5 \uD2B8\uB9AC\uC5D0 \uBCC0\uACBD\uB41C \uD30C\uC77C\uC774 \uC5C6\uC5B4 \uC804\uCCB4 \uBCA0\uC774\uC2A4\uB77C\uC778 \uAC80\uC99D\uC744 \uC218\uD589\uD569\uB2C8\uB2E4.",
|
|
273
|
+
causalUnrelated: (count) => `\uBCC0\uACBD\uB41C ${count}\uAC1C \uD30C\uC77C\uC774 \uB4F1\uB85D\uB41C \uAC80\uC0AC \uD50C\uB7EC\uADF8\uC778\uC758 \uC601\uD5A5 \uBC94\uC704\uC5D0 \uC18D\uD558\uC9C0 \uC54A\uC544 \uC804\uCCB4 \uAC80\uC0AC\uB97C \uC2A4\uD0B5\uD569\uB2C8\uB2E4.`,
|
|
274
|
+
causalGitFail: "Git \uBCC0\uACBD \uCD94\uC801 \uBD88\uAC00\uB85C \uC548\uC804 \uBAA8\uB4DC(\uC804\uCCB4 \uAC80\uC0AC)\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4.",
|
|
275
|
+
checkPassed: "\uD1B5\uACFC",
|
|
276
|
+
checkSkipped: "\uC0DD\uB7B5 (\uC778\uACFC\uC728 0\uCD08 \uC2A4\uD0B5)",
|
|
277
|
+
checkFailed: "\uC2E4\uD328",
|
|
278
|
+
checkSuccessSummary: (errs, warns, skips, sec) => `\u2728 \uC2DC\uB0C5\uC2A4 \uAC80\uC99D \uC131\uACF5: ${errs} Errors, ${warns} Warnings, ${skips} Skipped (\uCD1D \uC18C\uC694 \uC2DC\uAC04: ${sec}\uCD08)`,
|
|
279
|
+
checkFailureSummary: (errs, warns, sec) => `\u274C \uC2DC\uB0C5\uC2A4 \uAC80\uC99D \uC2E4\uD328: ${errs}\uAC1C \uAC80\uC0AC\uAE30 \uC624\uB958 \uBC1C\uC0DD (\uCD1D \uC18C\uC694 \uC2DC\uAC04: ${sec}\uCD08)`,
|
|
280
|
+
interactivePause: "\u23F8\uFE0F \uC5D0\uB7EC \uBC1C\uC0DD\uC73C\uB85C \uC77C\uC2DC\uC815\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uD30C\uC77C\uC744 \uC218\uC815\uD55C \uB4A4 \uC800\uC7A5\uD558\uBA74 0.05\uCD08 \uB9CC\uC5D0 \uD56B \uC7AC\uAC80\uC99D\uD569\uB2C8\uB2E4. (\uC885\uB8CC: Ctrl+C)",
|
|
281
|
+
interactiveReload: "\u26A1 \uD30C\uC77C \uBCC0\uACBD \uAC10\uC9C0! \uC778\uBA54\uBAA8\uB9AC \uD56B \uC7AC\uAC80\uC99D\uC744 \uC989\uC2DC \uAC00\uB3D9\uD569\uB2C8\uB2E4...",
|
|
282
|
+
interactiveTitle: "\u23F8\uFE0F [\uB300\uD654\uD615 \uC778\uACFC \uD56B\uD53D\uC2A4 \uBAA8\uB4DC] \uC624\uB958 \uBC1C\uC0DD\uC73C\uB85C \uD504\uB85C\uC138\uC2A4\uB97C \uC77C\uC2DC\uC815\uC9C0\uD588\uC2B5\uB2C8\uB2E4.",
|
|
283
|
+
interactiveTarget: "\uB300\uC0C1 \uD50C\uB7EC\uADF8\uC778",
|
|
284
|
+
interactiveWatching: "\uAC10\uC2DC \uC0C1\uD0DC : \uD83D\uDC40 \uC18C\uC2A4 \uCF54\uB4DC \uC218\uC815 \uB300\uAE30 \uC911... (\uC800\uC7A5 \uC2DC 0.05\uCD08 \uB9CC\uC5D0 \uD56B \uC7AC\uCEF4\uD30C\uC77C)",
|
|
285
|
+
interactiveExit: "\uC138\uC158 \uC885\uB8CC : \uD130\uBBF8\uB110\uC5D0\uC11C Ctrl+C \uC785\uB825",
|
|
286
|
+
interactiveDetected: (time, file) => `\u26A1 [\uC800\uC7A5 \uAC10\uC9C0 ${time}] ${file} \uC218\uC815 \uAC10\uC9C0 \u279C \uD56B \uC7AC\uCEF4\uD30C\uC77C \uC2E4\uD589 \uC911...`,
|
|
287
|
+
interactivePassed: (sec) => `\u2728 [\uD56B \uC7AC\uCEF4\uD30C\uC77C \uD1B5\uACFC] (${sec}s) \uACB0\uD568\uC774 \uC644\uC804\uD788 \uD574\uACB0\uB418\uC5C8\uC2B5\uB2C8\uB2E4!`,
|
|
288
|
+
interactiveResumed: "\u25B6\uFE0F [\uD30C\uC774\uD504\uB77C\uC778 \uC7AC\uAC1C] \uBAA8\uB4E0 \uAC80\uC99D \uD1B5\uACFC \uC644\uB8CC. \uD504\uB85C\uC138\uC2A4\uB97C \uC815\uC0C1 \uC885\uB8CC\uD569\uB2C8\uB2E4.",
|
|
289
|
+
interactiveFailed: "\u274C [\uC7AC\uAC80\uC99D \uC2E4\uD328] \uC5EC\uC804\uD788 \uC624\uB958\uAC00 \uB0A8\uC544\uC788\uC2B5\uB2C8\uB2E4. \uCF54\uB4DC\uB97C \uB2E4\uC2DC \uC218\uC815\uD558\uACE0 \uC800\uC7A5\uD574 \uC8FC\uC138\uC694.",
|
|
290
|
+
buildHeader: "\u26A1 [Synapse Build] \uC778\uACFC\uC728 \uBA40\uD2F0\uD2B8\uB799 \uBCD1\uB82C \uC99D\uBD84 \uBE4C\uB354",
|
|
291
|
+
buildSkipped: "\u23ED\uFE0F \uC18C\uC2A4 \uBBF8\uBCC0\uACBD \uAC10\uC9C0: 0.00\uCD08 \uC2A4\uD0B5",
|
|
292
|
+
buildSuccess: "\u2705 \uBE4C\uB4DC \uC644\uACB0",
|
|
293
|
+
buildFailed: "\u274C \uBE4C\uB4DC \uC2E4\uD328",
|
|
294
|
+
buildAllUpToDate: "\u2728 \uBAA8\uB4E0 \uBE4C\uB4DC \uD2B8\uB799\uC774 \uCD5C\uC2E0 \uC0C1\uD0DC\uC785\uB2C8\uB2E4. (\uC804\uCCB4 \uBE4C\uB4DC \uC0DD\uB7B5: 0.00\uCD08)",
|
|
295
|
+
buildComplete: (sec) => `\u2728 \uC804\uCCB4 \uC778\uACFC\uC728 \uC99D\uBD84 \uBE4C\uB4DC \uC644\uACB0 (\uCD1D \uC18C\uC694 \uC2DC\uAC04: ${sec}\uCD08)`,
|
|
296
|
+
packageHeader: "\uD83D\uDCE6 [Synapse Package] \uCD08\uACE0\uC18D \uC778\uC2A4\uD1A8\uB7EC \uBC88\uB4E4\uB7EC",
|
|
297
|
+
packageSuccess: (sec) => `\u2728 \uC778\uC2A4\uD1A8\uB7EC \uD328\uD0A4\uC9D5 \uC131\uACF5 (\uC18C\uC694 \uC2DC\uAC04: ${sec}\uCD08)`,
|
|
298
|
+
packageFailed: (sec) => `\u274C \uC778\uC2A4\uD1A8\uB7EC \uD328\uD0A4\uC9D5 \uC2E4\uD328 (\uC18C\uC694 \uC2DC\uAC04: ${sec}\uCD08)`,
|
|
299
|
+
signHeader: "\uD83D\uDD10 [Synapse Sign] \uC778\uACFC\uC728 \uC554\uD638\uD654 \uC11C\uBA85 \uD30C\uC774\uD504\uB77C\uC778",
|
|
300
|
+
signSkipped: "\u23ED\uFE0F \uC778\uC2A4\uD1A8\uB7EC \uBC14\uC774\uB108\uB9AC \uD574\uC2DC \uBD88\uBCC0: \uC11C\uBA85 0.00\uCD08 \uC2A4\uD0B5",
|
|
301
|
+
signSuccess: (sec) => `\u2728 \uC778\uC2A4\uD1A8\uB7EC Ed25519 \uB514\uC9C0\uD138 \uC11C\uBA85 \uBC1C\uD589 \uC644\uB8CC (\uC18C\uC694 \uC2DC\uAC04: ${sec}\uCD08)`,
|
|
302
|
+
signFailed: (sec) => `\u274C \uC11C\uBA85 \uC0DD\uC131 \uC2E4\uD328 (\uC18C\uC694 \uC2DC\uAC04: ${sec}\uCD08)`,
|
|
303
|
+
signNoConfig: "\u274C \uC11C\uBA85 \uC124\uC815(sign.privateKeyPath)\uC774 synapse.config.ts\uC5D0 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.",
|
|
304
|
+
signNoKey: (p) => `\u274C \uC11C\uBA85 \uAC1C\uC778\uD0A4 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${p}`,
|
|
305
|
+
signNoInstaller: "\u274C \uC11C\uBA85 \uB300\uC0C1 \uC778\uC2A4\uD1A8\uB7EC(.exe) \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
306
|
+
signTarget: "\uB300\uC0C1 \uC778\uC2A4\uD1A8\uB7EC",
|
|
307
|
+
signStatus: "\uC11C\uBA85 \uC0C1\uD0DC",
|
|
308
|
+
signFile: "\uC11C\uBA85 \uD30C\uC77C",
|
|
309
|
+
signReasonLabel: "\uC11C\uBA85 \uC0AC\uC720",
|
|
310
|
+
signEngineLabel: "\uC11C\uBA85 \uC5D4\uC9C4",
|
|
311
|
+
signCacheHit: "\uC2A4\uD0B5 [\uC778\uACFC\uC728 \uCE90\uC2DC \uC801\uC911: \uBC14\uC774\uB108\uB9AC \uD574\uC2DC \uBD88\uBCC0]",
|
|
312
|
+
signExistingKeep: (p) => `\uAE30\uC874 \uC11C\uBA85 \uD30C\uC77C \uC720\uC9C0 (${p})`,
|
|
313
|
+
signIntegrityPass: "\u2728 \uC11C\uBA85 \uBB34\uACB0\uC131 \uD655\uC778 \uC644\uB8CC (0.00\uCD08)",
|
|
314
|
+
statusSuccess: "\uD1B5\uACFC",
|
|
315
|
+
statusSkipped: "\uC2A4\uD0B5 (\uC778\uACFC\uC728 \uC0DD\uB7B5)",
|
|
316
|
+
statusWarning: "\uACBD\uACE0",
|
|
317
|
+
statusError: "\uC2E4\uD328",
|
|
318
|
+
causalAnalysis: "\uC778\uACFC \uBA54\uBAA8\uB9AC \uBD84\uC11D",
|
|
319
|
+
trackSkipped: "\uC2A4\uD0B5 [\uC778\uACFC\uC728 \uCE90\uC2DC \uC801\uC911]",
|
|
320
|
+
trackComplete: "\uBE4C\uB4DC \uC644\uB8CC",
|
|
321
|
+
trackFailed: "\uBE4C\uB4DC \uC2E4\uD328",
|
|
322
|
+
noBuildTracks: "\u274C \uB4F1\uB85D\uB41C \uBE4C\uB4DC \uD2B8\uB799(buildTracks)\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. synapse.config.ts\uB97C \uD655\uC778\uD574 \uC8FC\uC138\uC694.",
|
|
323
|
+
buildSuccessSummary: (tracks, sec) => `\u2728 \uC778\uACFC\uC728 \uBCD1\uB82C \uBE4C\uB4DC \uC131\uACF5: \uC804\uCCB4 ${tracks}\uAC1C \uD2B8\uB799 \uC644\uB8CC (\uCD1D \uC18C\uC694 \uC2DC\uAC04: ${sec}\uCD08)`,
|
|
324
|
+
buildFailureSummary: "\uD83D\uDEA8 \uBCD1\uB82C \uBE4C\uB4DC \uC2E4\uD328: \uD558\uB098 \uC774\uC0C1\uC758 \uD2B8\uB799\uC5D0\uC11C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.",
|
|
325
|
+
packagingPreBuild: "\u2139\uFE0F \uC0AC\uC804 \uC544\uD2F0\uD329\uD2B8 \uC778\uACFC\uC728 \uBE4C\uB4DC \uD655\uC778 \uC911...",
|
|
326
|
+
packagingStart: "\uD83D\uDE80 Tauri \uC778\uC2A4\uD1A8\uB7EC \uBC88\uB4E4\uB9C1 \uC2DC\uC791...",
|
|
327
|
+
packagingGuide: `\u26A0\uFE0F [\uD328\uD0A4\uC9D5 \uAC00\uC774\uB4DC] tauri.conf.json\uC758 targets\uAC00 "all"\uB85C \uC124\uC815\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.
|
|
328
|
+
\u21B3 WiX MSI \uC911\uBCF5 \uBE4C\uB4DC\uB85C \uC2DC\uAC04\uC774 \uC18C\uC694\uB429\uB2C8\uB2E4. targets: ["nsis"] \uC124\uC815\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.`,
|
|
329
|
+
pluginRustTitle: "Rust \uBC31\uC5D4\uB4DC \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 (Check & Clippy)",
|
|
330
|
+
pluginRustSuccess: "Rust \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uCEF4\uD30C\uC77C \uBC0F Clippy \uBB34\uACB0\uC131 \uD655\uC778 \uC644\uB8CC (0 Warnings, 0 Errors)",
|
|
331
|
+
pluginRustClippyWarn: (count) => `\uCEF4\uD30C\uC77C \uD1B5\uACFC \uC644\uB8CC (${count}\uAC1C Clippy \uAD8C\uC7A5\uC0AC\uD56D \uAC10\uC9C0\uB428)`,
|
|
332
|
+
pluginRustCompileFail: "Rust \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uCEF4\uD30C\uC77C\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
|
|
333
|
+
pluginRustExecFail: (msg) => `Rust \uAC80\uC0AC \uB3C4\uAD6C \uC2E4\uD589 \uC2E4\uD328: ${msg}`,
|
|
334
|
+
pluginSvelteTitle: "Svelte 5 & TypeScript (svelte-check)",
|
|
335
|
+
pluginSvelteSuccess: "Svelte 5 Runes \uBC0F TS \uD0C0\uC785 \uBB34\uACB0\uC131 \uAC80\uC99D \uC644\uB8CC (0 Errors, 0 Warnings)",
|
|
336
|
+
pluginSvelteError: "Svelte \uD15C\uD50C\uB9BF \uB610\uB294 TypeScript \uD0C0\uC785 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.",
|
|
337
|
+
pluginSvelteExecFail: (msg) => `Svelte \uAC80\uC0AC \uB3C4\uAD6C \uC2E4\uD589 \uC2E4\uD328: ${msg}`,
|
|
338
|
+
pluginJavaTitle: "Java \uC5D4\uD130\uD504\uB77C\uC774\uC988 \uCEF4\uD30C\uC77C\uB7EC (javac)",
|
|
339
|
+
pluginJavaSuccess: (count) => `Java ${count}\uAC1C \uC18C\uC2A4 \uD30C\uC77C \uBC14\uC774\uD2B8\uCF54\uB4DC \uCEF4\uD30C\uC77C \uBB34\uACB0\uC131 \uAC80\uC99D \uC644\uB8CC`,
|
|
340
|
+
pluginJavaNoFiles: "\uAC80\uC99D\uD560 Java \uC18C\uC2A4 \uD30C\uC77C(.java)\uC774 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
341
|
+
pluginJavaError: "javac \uCEF4\uD30C\uC77C \uC2E4\uD328",
|
|
342
|
+
pluginCppTitle: "C/C++ \uB124\uC774\uD2F0\uBE0C \uCEE4\uB110 \uAC80\uC99D\uAE30 (g++/clang++)",
|
|
343
|
+
pluginCppSuccess: (count) => `C/C++ ${count}\uAC1C \uC18C\uC2A4 \uD30C\uC77C \uAD6C\uBB38 \uBC0F \uD5E4\uB354 \uBB34\uACB0\uC131 \uAC80\uC99D \uC644\uB8CC`,
|
|
344
|
+
pluginCppNoFiles: "\uAC80\uC99D\uD560 C/C++ \uC18C\uC2A4 \uD30C\uC77C\uC774 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
345
|
+
pluginCppError: "C/C++ \uAD6C\uBB38 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.",
|
|
346
|
+
pluginCsharpTitle: "C# .NET \uC194\uB8E8\uC158 \uAC80\uC99D\uAE30 (dotnet build)",
|
|
347
|
+
pluginCsharpSuccess: "C# .NET \uD504\uB85C\uC81D\uD2B8 \uBE4C\uB4DC \uBC0F \uD0C0\uC785 \uBB34\uACB0\uC131 \uAC80\uC99D \uC644\uB8CC",
|
|
348
|
+
pluginCsharpError: "C# .NET \uBE4C\uB4DC \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.",
|
|
349
|
+
pluginGoTitle: "Go \uBC31\uC5D4\uB4DC \uD328\uD0A4\uC9C0 \uAC80\uC99D\uAE30 (go vet)",
|
|
350
|
+
pluginGoSuccess: "Go \uB3D9\uC2DC\uC131 \uB8E8\uD2F4 \uBC0F \uD328\uD0A4\uC9C0 \uC815\uC801 \uBD84\uC11D \uD1B5\uACFC",
|
|
351
|
+
pluginGoError: "Go \uC815\uC801 \uBD84\uC11D \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.",
|
|
352
|
+
pluginPythonTitle: "Python \uBC14\uC774\uD2B8\uCF54\uB4DC \uAC80\uC99D\uAE30 (py_compile)",
|
|
353
|
+
pluginPythonSuccess: (count) => `Python ${count}\uAC1C \uBAA8\uB4C8 \uBC14\uC774\uD2B8\uCF54\uB4DC \uBB34\uACB0\uC131 \uAC80\uC99D \uC644\uB8CC`,
|
|
354
|
+
pluginPythonNoFiles: "\uAC80\uC99D\uD560 Python \uC18C\uC2A4 \uD30C\uC77C\uC774 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
355
|
+
pluginPythonError: "Python \uAD6C\uBB38 \uBD84\uC11D \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.",
|
|
356
|
+
pluginTypescriptTitlePure: "\uC21C\uC218 TypeScript \uACF5\uC2DD \uCEF4\uD30C\uC77C\uB7EC (tsc)",
|
|
357
|
+
pluginTypescriptTitleNative: "TypeScript \uB124\uC774\uD2F0\uBE0C Rust Oxc (tsrs)",
|
|
358
|
+
pluginTypescriptSuccess: (mode) => `TypeScript \uD0C0\uC785 \uBB34\uACB0\uC131 \uAC80\uC99D \uC644\uB8CC (${mode})`,
|
|
359
|
+
pluginTypescriptError: "TypeScript \uD0C0\uC785 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.",
|
|
360
|
+
pluginSchemaTitle: "\uB370\uC774\uD130 \uBC0F \uC124\uC815 \uC2A4\uD0A4\uB9C8 \uBB34\uACB0\uC131 \uAC80\uC0AC",
|
|
361
|
+
pluginSchemaSuccess: (count) => `${count}\uAC1C \uC2A4\uD0A4\uB9C8/\uB370\uC774\uD130 \uD30C\uC77C \uC815\uC0C1 \uD655\uC778 \uC644\uB8CC`,
|
|
362
|
+
pluginSchemaParseFail: (path, err) => `${path} \uD30C\uC2F1 \uC2E4\uD328: ${err}`,
|
|
363
|
+
pluginNativeTitle: "\uB124\uC774\uD2F0\uBE0C \uBC14\uC774\uB108\uB9AC & \uC5D0\uC14B \uAC80\uC0AC",
|
|
364
|
+
pluginNativeSuccess: (count) => `${count}\uAC1C \uBC14\uC774\uB108\uB9AC \uBC0F \uB9AC\uC18C\uC2A4 \uBB34\uACB0\uC131 \uD655\uC778 \uC644\uB8CC`,
|
|
365
|
+
pluginNativeMissing: (path) => `\uD544\uC218 \uBC14\uC774\uB108\uB9AC\uAC00 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4: ${path}`,
|
|
366
|
+
pluginNativeNotPe: (path) => `${path}: \uC62C\uBC14\uB978 PE \uD3EC\uB9F7(MZ \uC2DC\uADF8\uB2C8\uCC98 \uB204\uB77D)\uC774 \uC544\uB2D9\uB2C8\uB2E4.`,
|
|
367
|
+
pluginNativeInvalidPe: (path) => `${path}: \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 PE \uC2DC\uADF8\uB2C8\uCC98\uC785\uB2C8\uB2E4.`,
|
|
368
|
+
pluginNativeInvalidArch: (path, code) => `${path}: 64\uBE44\uD2B8(x64) \uBC14\uC774\uB108\uB9AC\uAC00 \uC544\uB2D9\uB2C8\uB2E4 (\uBA38\uC2E0 \uCF54\uB4DC: 0x${code}).`,
|
|
369
|
+
pluginNsisTitle: "NSIS \uC778\uC2A4\uD1A8\uB7EC \uD15C\uD50C\uB9BF \uAD6C\uBB38 \uAC80\uC0AC",
|
|
370
|
+
pluginNsisSuccess: (path) => `${path} \uAD6C\uBB38 \uBC0F \uD544\uC218 \uC9C0\uC2DC\uBB38 \uD655\uC778 \uC644\uB8CC`,
|
|
371
|
+
pluginNsisMissing: (path) => `NSIS \uD15C\uD50C\uB9BF \uD30C\uC77C\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4: ${path}`,
|
|
372
|
+
pluginNsisCorrupt: "NSIS \uD15C\uD50C\uB9BF \uD30C\uC77C \uB0B4\uC6A9\uC774 \uBE44\uC5B4 \uC788\uAC70\uB098 \uC190\uC0C1\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",
|
|
373
|
+
pluginNsisDirectiveMissing: (dir) => `NSIS \uD544\uC218 \uC9C0\uC2DC\uBB38 \uB204\uB77D: '${dir}' \uAD6C\uBB38\uC774 \uBC1C\uACAC\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`
|
|
374
|
+
},
|
|
375
|
+
en: {
|
|
376
|
+
cliTitle: "\uD83E\uDDE0 Synapse Kit - AI-Native Unified Compiler, Build & Packaging Framework",
|
|
377
|
+
cliUsage: "Usage:",
|
|
378
|
+
cliCommands: "Core Commands:",
|
|
379
|
+
cmdCheck: "Run multi-track verification with AI causal smart skipping",
|
|
380
|
+
cmdBuild: "Fast incremental multi-track build (0.00s skip on unchanged sources)",
|
|
381
|
+
cmdPackage: "Single NSIS + zlib high-speed installer packager",
|
|
382
|
+
cmdSign: "Causal cryptographic signing engine (Minisign / Ed25519)",
|
|
383
|
+
cmdInit: "Generate optimized synapse.config.ts template in current directory",
|
|
384
|
+
cmdMemory: "Query, manage and serve zero-cost Causal Memory & Local Daemon",
|
|
385
|
+
cliOptions: "Options:",
|
|
386
|
+
optAll: "Disable causal skipping and force full verification",
|
|
387
|
+
optForce: "Ignore cache and force re-execution of build and signing",
|
|
388
|
+
optAgent: "Structured JSON output for AI coding agents (Claude, Cursor, Antigravity)",
|
|
389
|
+
optCompact: "Extreme token-diet mode for AI agents (only 11 tokens on pass)",
|
|
390
|
+
optInteractive: "Pause on error and wait for live code modification (0.05s live-fix)",
|
|
391
|
+
optWatch: "Background file-watcher mode",
|
|
392
|
+
optLang: "Force display language (ko | en)",
|
|
393
|
+
optHelp: "Display help information",
|
|
394
|
+
optVersion: "Display version information",
|
|
395
|
+
unknownCmd: "Unknown command:",
|
|
396
|
+
errPrefix: "\uD83D\uDEA8 Error:",
|
|
397
|
+
configExists: "Configuration file already exists:",
|
|
398
|
+
configCreated: "synapse.config.ts template created successfully.",
|
|
399
|
+
checkHeader: "\uD83E\uDDE0 [Synapse Kit] AI-Native Unified Compiler & Verification Framework",
|
|
400
|
+
causalAll: "Full check requested (--all): Executing all registered checkers.",
|
|
401
|
+
causalDirty: (count, plugins) => `${count} modified files detected: Running [${plugins}] plugins only.`,
|
|
402
|
+
causalClean: "No source changes detected. All checkers skipped in 0.00s.",
|
|
403
|
+
causalCleanCacheHit: "No file changes and matches last verified commit. Skipped in 0.00s.",
|
|
404
|
+
causalBaseline: "No changes detected; performing baseline verification for initial state.",
|
|
405
|
+
causalUnrelated: (count) => `${count} modified files do not affect registered plugins. Skipping all checkers.`,
|
|
406
|
+
causalGitFail: "Cannot track Git changes; running full verification in safe mode.",
|
|
407
|
+
checkPassed: "PASSED",
|
|
408
|
+
checkSkipped: "SKIPPED (Causal 0.00s)",
|
|
409
|
+
checkFailed: "FAILED",
|
|
410
|
+
checkSuccessSummary: (errs, warns, skips, sec) => `\u2728 Verification Passed: ${errs} Errors, ${warns} Warnings, ${skips} Skipped (Total: ${sec}s)`,
|
|
411
|
+
checkFailureSummary: (errs, warns, sec) => `\u274C Verification Failed: ${errs} check failures (Total: ${sec}s)`,
|
|
412
|
+
interactivePause: "\u23F8\uFE0F Paused due to errors. Save modified files to hot-recheck in 0.05s. (Exit: Ctrl+C)",
|
|
413
|
+
interactiveReload: "\u26A1 File changes detected! Launching in-memory hot-recheck...",
|
|
414
|
+
interactiveTitle: "\u23F8\uFE0F [Interactive Causal Hotfix] Process paused due to verification errors.",
|
|
415
|
+
interactiveTarget: "Target Plugins",
|
|
416
|
+
interactiveWatching: "Watch Status : \uD83D\uDC40 Waiting for code changes... (hot-rechecks in 0.05s on save)",
|
|
417
|
+
interactiveExit: "Exit Session : Press Ctrl+C in terminal",
|
|
418
|
+
interactiveDetected: (time, file) => `\u26A1 [Save Detected ${time}] ${file} changed \u279C Running hot-recheck...`,
|
|
419
|
+
interactivePassed: (sec) => `\u2728 [Hot-recheck Passed] (${sec}s) All issues resolved!`,
|
|
420
|
+
interactiveResumed: "\u25B6\uFE0F [Pipeline Resumed] All verifications passed. Exiting cleanly.",
|
|
421
|
+
interactiveFailed: "\u274C [Hot-recheck Failed] Errors remain. Please edit and save again.",
|
|
422
|
+
buildHeader: "\u26A1 [Synapse Build] Causal Multi-Track Parallel Incremental Builder",
|
|
423
|
+
buildSkipped: "\u23ED\uFE0F Unchanged source detected: 0.00s skipped",
|
|
424
|
+
buildSuccess: "\u2705 Build completed",
|
|
425
|
+
buildFailed: "\u274C Build failed",
|
|
426
|
+
buildAllUpToDate: "\u2728 All build tracks are up-to-date. (Skipped all tracks: 0.00s)",
|
|
427
|
+
buildComplete: (sec) => `\u2728 Causal incremental build completed (Total: ${sec}s)`,
|
|
428
|
+
packageHeader: "\uD83D\uDCE6 [Synapse Package] High-Speed Installer Bundler",
|
|
429
|
+
packageSuccess: (sec) => `\u2728 Installer package bundled successfully (Elapsed: ${sec}s)`,
|
|
430
|
+
packageFailed: (sec) => `\u274C Installer packaging failed (Elapsed: ${sec}s)`,
|
|
431
|
+
signHeader: "\uD83D\uDD10 [Synapse Sign] Causal Cryptographic Signing Pipeline",
|
|
432
|
+
signSkipped: "\u23ED\uFE0F Binary SHA-256 unchanged: Signature skipped in 0.00s",
|
|
433
|
+
signSuccess: (sec) => `\u2728 Ed25519 digital signature generated (Elapsed: ${sec}s)`,
|
|
434
|
+
signFailed: (sec) => `\u274C Signature generation failed (Elapsed: ${sec}s)`,
|
|
435
|
+
signNoConfig: "\u274C Signing configuration (sign.privateKeyPath) is missing in synapse.config.ts.",
|
|
436
|
+
signNoKey: (p) => `\u274C Signing private key not found: ${p}`,
|
|
437
|
+
signNoInstaller: "\u274C Target installer (.exe) not found for signing.",
|
|
438
|
+
signTarget: "Target Installer",
|
|
439
|
+
signStatus: "Signing Status",
|
|
440
|
+
signFile: "Signature File",
|
|
441
|
+
signReasonLabel: "Reason",
|
|
442
|
+
signEngineLabel: "Signing Engine",
|
|
443
|
+
signCacheHit: "SKIPPED [Causal Cache Hit: Binary hash identical]",
|
|
444
|
+
signExistingKeep: (p) => `Keeping existing signature file (${p})`,
|
|
445
|
+
signIntegrityPass: "\u2728 Signature integrity verified (0.00s)",
|
|
446
|
+
statusSuccess: "PASSED",
|
|
447
|
+
statusSkipped: "SKIPPED (Causal skip)",
|
|
448
|
+
statusWarning: "WARNING",
|
|
449
|
+
statusError: "FAILED",
|
|
450
|
+
causalAnalysis: "Causal Analysis",
|
|
451
|
+
trackSkipped: "SKIPPED [Causal Cache Hit]",
|
|
452
|
+
trackComplete: "Build Passed",
|
|
453
|
+
trackFailed: "Build Failed",
|
|
454
|
+
noBuildTracks: "\u274C No buildTracks found in synapse.config.ts.",
|
|
455
|
+
buildSuccessSummary: (tracks, sec) => `\u2728 Causal Parallel Build Passed: All ${tracks} tracks completed (Total: ${sec}s)`,
|
|
456
|
+
buildFailureSummary: "\uD83D\uDEA8 Parallel Build Failed: Errors occurred in one or more tracks.",
|
|
457
|
+
packagingPreBuild: "\u2139\uFE0F Verifying prerequisite artifact causal builds...",
|
|
458
|
+
packagingStart: "\uD83D\uDE80 Starting Tauri installer bundling...",
|
|
459
|
+
packagingGuide: `\u26A0\uFE0F [Packaging Notice] tauri.conf.json has targets set to "all".
|
|
460
|
+
\u21B3 WiX MSI adds redundant delay. Recommended setting: targets: ["nsis"].`,
|
|
461
|
+
pluginRustTitle: "Rust Backend Workspace (Check & Clippy)",
|
|
462
|
+
pluginRustSuccess: "Rust workspace compilation & Clippy integrity verified (0 Warnings, 0 Errors)",
|
|
463
|
+
pluginRustClippyWarn: (count) => `Compilation passed (${count} Clippy recommendations detected)`,
|
|
464
|
+
pluginRustCompileFail: "Rust workspace compilation failed.",
|
|
465
|
+
pluginRustExecFail: (msg) => `Failed to execute Rust checker tool: ${msg}`,
|
|
466
|
+
pluginSvelteTitle: "Svelte 5 & TypeScript (svelte-check)",
|
|
467
|
+
pluginSvelteSuccess: "Svelte 5 Runes & TS type integrity verified (0 Errors, 0 Warnings)",
|
|
468
|
+
pluginSvelteError: "Errors detected in Svelte template or TypeScript types.",
|
|
469
|
+
pluginSvelteExecFail: (msg) => `Failed to execute Svelte checker tool: ${msg}`,
|
|
470
|
+
pluginJavaTitle: "Java Enterprise Compiler (javac)",
|
|
471
|
+
pluginJavaSuccess: (count) => `Java bytecode compilation verified for ${count} source files`,
|
|
472
|
+
pluginJavaNoFiles: "No Java source files (*.java) found to verify.",
|
|
473
|
+
pluginJavaError: "javac compilation failed",
|
|
474
|
+
pluginCppTitle: "C/C++ Native Kernel Checker (g++/clang++)",
|
|
475
|
+
pluginCppSuccess: (count) => `C/C++ syntax & header integrity verified for ${count} files`,
|
|
476
|
+
pluginCppNoFiles: "No C/C++ source files found to verify.",
|
|
477
|
+
pluginCppError: "C/C++ compilation syntax errors detected.",
|
|
478
|
+
pluginCsharpTitle: "C# .NET Solution Checker (dotnet build)",
|
|
479
|
+
pluginCsharpSuccess: "C# .NET project build and type integrity verified",
|
|
480
|
+
pluginCsharpError: "Errors detected during C# .NET build.",
|
|
481
|
+
pluginGoTitle: "Go Backend Package Checker (go vet)",
|
|
482
|
+
pluginGoSuccess: "Go concurrency routines and packages passed static analysis",
|
|
483
|
+
pluginGoError: "Errors detected during Go static analysis.",
|
|
484
|
+
pluginPythonTitle: "Python Bytecode Checker (py_compile)",
|
|
485
|
+
pluginPythonSuccess: (count) => `Python bytecode integrity verified for ${count} modules`,
|
|
486
|
+
pluginPythonNoFiles: "No Python source files found to verify.",
|
|
487
|
+
pluginPythonError: "Syntax errors detected in Python source.",
|
|
488
|
+
pluginTypescriptTitlePure: "Pure TypeScript Official Compiler (tsc)",
|
|
489
|
+
pluginTypescriptTitleNative: "TypeScript Native Rust Oxc (tsrs)",
|
|
490
|
+
pluginTypescriptSuccess: (mode) => `TypeScript type integrity verified (${mode})`,
|
|
491
|
+
pluginTypescriptError: "TypeScript type errors detected.",
|
|
492
|
+
pluginSchemaTitle: "Data & Config Schema Integrity Checker",
|
|
493
|
+
pluginSchemaSuccess: (count) => `Verified ${count} schema/data files successfully`,
|
|
494
|
+
pluginSchemaParseFail: (path, err) => `${path} parse failure: ${err}`,
|
|
495
|
+
pluginNativeTitle: "Native Binary & Asset Checker",
|
|
496
|
+
pluginNativeSuccess: (count) => `Verified ${count} binaries & resources successfully`,
|
|
497
|
+
pluginNativeMissing: (path) => `Required binary is missing: ${path}`,
|
|
498
|
+
pluginNativeNotPe: (path) => `${path}: Not a valid PE format (MZ signature missing).`,
|
|
499
|
+
pluginNativeInvalidPe: (path) => `${path}: Invalid PE signature.`,
|
|
500
|
+
pluginNativeInvalidArch: (path, code) => `${path}: Not a 64-bit (x64) binary (Machine code: 0x${code}).`,
|
|
501
|
+
pluginNsisTitle: "NSIS Installer Template Checker",
|
|
502
|
+
pluginNsisSuccess: (path) => `${path} syntax & required directives verified`,
|
|
503
|
+
pluginNsisMissing: (path) => `NSIS template file is missing: ${path}`,
|
|
504
|
+
pluginNsisCorrupt: "NSIS template content is empty or corrupted.",
|
|
505
|
+
pluginNsisDirectiveMissing: (dir) => `Required NSIS directive missing: '${dir}'.`
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
function detectLocale(explicitLang) {
|
|
509
|
+
if (explicitLang === "ko" || explicitLang === "en") {
|
|
510
|
+
currentLocale = explicitLang;
|
|
511
|
+
return currentLocale;
|
|
512
|
+
}
|
|
513
|
+
const envLang = process.env.SYNAPSE_LANG || process.env.LANG || process.env.LC_ALL || process.env.LC_MESSAGES || "";
|
|
514
|
+
if (envLang.toLowerCase().includes("ko")) {
|
|
515
|
+
currentLocale = "ko";
|
|
516
|
+
return "ko";
|
|
517
|
+
}
|
|
518
|
+
try {
|
|
519
|
+
const sysLocale = Intl.DateTimeFormat().resolvedOptions().locale.toLowerCase();
|
|
520
|
+
if (sysLocale.startsWith("ko")) {
|
|
521
|
+
currentLocale = "ko";
|
|
522
|
+
return "ko";
|
|
523
|
+
}
|
|
524
|
+
} catch {}
|
|
525
|
+
currentLocale = "en";
|
|
526
|
+
return "en";
|
|
527
|
+
}
|
|
528
|
+
function t(key, ...args) {
|
|
529
|
+
const dict = MESSAGES[currentLocale] || MESSAGES.en;
|
|
530
|
+
const val = dict[key] ?? MESSAGES.en[key] ?? key;
|
|
531
|
+
if (typeof val === "function") {
|
|
532
|
+
return val(...args);
|
|
533
|
+
}
|
|
534
|
+
return val;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// causal-graph.ts
|
|
538
|
+
async function analyzeCausalGraph(rootDir, plugins, options) {
|
|
539
|
+
const allPluginNames = new Set(plugins.map((p) => p.name));
|
|
540
|
+
if (options.mode === "all") {
|
|
541
|
+
return {
|
|
542
|
+
runAll: true,
|
|
543
|
+
activePluginNames: allPluginNames,
|
|
544
|
+
reason: t("causalAll"),
|
|
545
|
+
modifiedFiles: []
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
try {
|
|
549
|
+
const { head, modifiedFiles } = await getGitState(rootDir);
|
|
550
|
+
if (modifiedFiles.length === 0) {
|
|
551
|
+
const cache = loadBuildCache(rootDir);
|
|
552
|
+
if (cache.lastVerifiedHead && cache.lastVerifiedHead === head && head !== "unknown") {
|
|
553
|
+
return {
|
|
554
|
+
runAll: false,
|
|
555
|
+
activePluginNames: new Set,
|
|
556
|
+
reason: t("causalCleanCacheHit"),
|
|
557
|
+
modifiedFiles: []
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
return {
|
|
561
|
+
runAll: true,
|
|
562
|
+
activePluginNames: allPluginNames,
|
|
563
|
+
reason: t("causalBaseline"),
|
|
564
|
+
modifiedFiles: []
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
const activePluginNames = new Set;
|
|
568
|
+
for (const plugin of plugins) {
|
|
569
|
+
const isTriggered = plugin.triggers.some((pattern) => {
|
|
570
|
+
const cleanPattern = pattern.replaceAll("\\", "/").replace(/^\.\//, "");
|
|
571
|
+
const isExtension = cleanPattern.startsWith(".");
|
|
572
|
+
return modifiedFiles.some((file) => {
|
|
573
|
+
if (isExtension) {
|
|
574
|
+
return file.endsWith(cleanPattern);
|
|
575
|
+
}
|
|
576
|
+
return file.includes(cleanPattern);
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
if (isTriggered) {
|
|
580
|
+
activePluginNames.add(plugin.name);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
if (activePluginNames.size === 0) {
|
|
584
|
+
return {
|
|
585
|
+
runAll: false,
|
|
586
|
+
activePluginNames: new Set,
|
|
587
|
+
reason: t("causalUnrelated", modifiedFiles.length),
|
|
588
|
+
modifiedFiles
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
return {
|
|
592
|
+
runAll: false,
|
|
593
|
+
activePluginNames,
|
|
594
|
+
reason: t("causalDirty", modifiedFiles.length, Array.from(activePluginNames).join(", ")),
|
|
595
|
+
modifiedFiles
|
|
596
|
+
};
|
|
597
|
+
} catch {
|
|
598
|
+
return {
|
|
599
|
+
runAll: true,
|
|
600
|
+
activePluginNames: allPluginNames,
|
|
601
|
+
reason: t("causalGitFail"),
|
|
602
|
+
modifiedFiles: []
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// core/reporter.ts
|
|
608
|
+
var RESET = "\x1B[0m";
|
|
609
|
+
var BOLD = "\x1B[1m";
|
|
610
|
+
var GREEN = "\x1B[32m";
|
|
611
|
+
var RED = "\x1B[31m";
|
|
612
|
+
var YELLOW = "\x1B[33m";
|
|
613
|
+
var CYAN = "\x1B[36m";
|
|
614
|
+
var GRAY = "\x1B[90m";
|
|
615
|
+
function reportResults(decision, results, totalDurationMs, options) {
|
|
616
|
+
const totalSeconds = (totalDurationMs / 1000).toFixed(2);
|
|
617
|
+
const errorResults = results.filter((r) => r.status === "error");
|
|
618
|
+
const warningResults = results.filter((r) => r.status === "warning");
|
|
619
|
+
const skippedResults = results.filter((r) => r.status === "skipped");
|
|
620
|
+
const successResults = results.filter((r) => r.status === "success");
|
|
621
|
+
if (options.agentMode || options.compactMode) {
|
|
622
|
+
const isCleanPass = errorResults.length === 0 && warningResults.length === 0;
|
|
623
|
+
if (isCleanPass && options.compactMode) {
|
|
624
|
+
const minimalPayload = {
|
|
625
|
+
ok: true,
|
|
626
|
+
duration: `${totalSeconds}s`,
|
|
627
|
+
skipped: skippedResults.map((r) => r.name)
|
|
628
|
+
};
|
|
629
|
+
process.stdout.write(`${JSON.stringify(minimalPayload)}
|
|
630
|
+
`);
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
const payload = {
|
|
634
|
+
ok: errorResults.length === 0,
|
|
635
|
+
duration: `${totalSeconds}s`,
|
|
636
|
+
summary: {
|
|
637
|
+
pass: successResults.length,
|
|
638
|
+
warn: warningResults.length,
|
|
639
|
+
err: errorResults.length,
|
|
640
|
+
skip: skippedResults.length
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
if (errorResults.length > 0) {
|
|
644
|
+
payload.errors = errorResults.map((r) => ({
|
|
645
|
+
plugin: r.name,
|
|
646
|
+
details: r.details,
|
|
647
|
+
diagnostics: r.diagnostics
|
|
648
|
+
}));
|
|
649
|
+
}
|
|
650
|
+
if (warningResults.length > 0) {
|
|
651
|
+
payload.warnings = warningResults.map((r) => ({
|
|
652
|
+
plugin: r.name,
|
|
653
|
+
details: r.details,
|
|
654
|
+
diagnostics: r.diagnostics
|
|
655
|
+
}));
|
|
656
|
+
}
|
|
657
|
+
if (skippedResults.length > 0) {
|
|
658
|
+
payload.skipped = skippedResults.map((r) => r.name);
|
|
659
|
+
}
|
|
660
|
+
const outputString = options.compactMode ? JSON.stringify(payload) : JSON.stringify(payload, null, 2);
|
|
661
|
+
process.stdout.write(`${outputString}
|
|
662
|
+
`);
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
const line = "\u2501".repeat(68);
|
|
666
|
+
process.stdout.write(`
|
|
667
|
+
${BOLD}${CYAN}${t("checkHeader")}${RESET}
|
|
668
|
+
`);
|
|
669
|
+
process.stdout.write(`${GRAY}${line}${RESET}
|
|
670
|
+
`);
|
|
671
|
+
process.stdout.write(`${GRAY}\uD83D\uDCA1 ${t("causalAnalysis")}: ${decision.reason}${RESET}
|
|
672
|
+
`);
|
|
673
|
+
process.stdout.write(`${GRAY}${line}${RESET}
|
|
674
|
+
`);
|
|
675
|
+
for (const result of results) {
|
|
676
|
+
const duration = (result.durationMs / 1000).toFixed(2);
|
|
677
|
+
let statusBadge = "";
|
|
678
|
+
switch (result.status) {
|
|
679
|
+
case "success":
|
|
680
|
+
statusBadge = `${GREEN}\u2705 ${t("statusSuccess")} (${duration}s)${RESET}`;
|
|
681
|
+
break;
|
|
682
|
+
case "skipped":
|
|
683
|
+
statusBadge = `${GRAY}\u23ED\uFE0F ${t("statusSkipped")}${RESET}`;
|
|
684
|
+
break;
|
|
685
|
+
case "warning":
|
|
686
|
+
statusBadge = `${YELLOW}\u26A0\uFE0F ${t("statusWarning")} (${duration}s)${RESET}`;
|
|
687
|
+
break;
|
|
688
|
+
case "error":
|
|
689
|
+
statusBadge = `${RED}\u274C ${t("statusError")} (${duration}s)${RESET}`;
|
|
690
|
+
break;
|
|
691
|
+
}
|
|
692
|
+
const titlePadded = result.title.padEnd(36, " ");
|
|
693
|
+
process.stdout.write(` \u2022 ${BOLD}${titlePadded}${RESET} : ${statusBadge}
|
|
694
|
+
`);
|
|
695
|
+
if (result.status !== "skipped" && result.details) {
|
|
696
|
+
process.stdout.write(` ${GRAY}\u2514\u2500 ${result.details}${RESET}
|
|
697
|
+
`);
|
|
698
|
+
}
|
|
699
|
+
if (result.diagnostics && result.diagnostics.length > 0) {
|
|
700
|
+
for (const diag of result.diagnostics) {
|
|
701
|
+
process.stdout.write(` ${RED}\u25B6 ${diag.message}${RESET}
|
|
702
|
+
`);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
process.stdout.write(`${GRAY}${line}${RESET}
|
|
707
|
+
`);
|
|
708
|
+
if (errorResults.length === 0) {
|
|
709
|
+
process.stdout.write(`${BOLD}${GREEN}${t("checkSuccessSummary", 0, warningResults.length, skippedResults.length, totalSeconds)}${RESET}
|
|
710
|
+
|
|
711
|
+
`);
|
|
712
|
+
} else {
|
|
713
|
+
process.stdout.write(`${BOLD}${RED}${t("checkFailureSummary", errorResults.length, warningResults.length, totalSeconds)}${RESET}
|
|
714
|
+
|
|
715
|
+
`);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// core/engine.ts
|
|
720
|
+
var RESET2 = "\x1B[0m";
|
|
721
|
+
var BOLD2 = "\x1B[1m";
|
|
722
|
+
var GREEN2 = "\x1B[32m";
|
|
723
|
+
var RED2 = "\x1B[31m";
|
|
724
|
+
var YELLOW2 = "\x1B[33m";
|
|
725
|
+
var CYAN2 = "\x1B[36m";
|
|
726
|
+
var GRAY2 = "\x1B[90m";
|
|
727
|
+
async function runPluginChecker(plugin, isActive, rootDir, options) {
|
|
728
|
+
if (!isActive) {
|
|
729
|
+
return {
|
|
730
|
+
name: plugin.name,
|
|
731
|
+
title: plugin.title,
|
|
732
|
+
status: "skipped",
|
|
733
|
+
durationMs: 0,
|
|
734
|
+
details: t("checkSkipped")
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
try {
|
|
738
|
+
return await plugin.check({ rootDir, options });
|
|
739
|
+
} catch (error) {
|
|
740
|
+
return {
|
|
741
|
+
name: plugin.name,
|
|
742
|
+
title: plugin.title,
|
|
743
|
+
status: "error",
|
|
744
|
+
durationMs: 0,
|
|
745
|
+
details: `Critical plugin execution failure: ${error instanceof Error ? error.message : String(error)}`
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
async function executeChecks(config, options) {
|
|
750
|
+
const rootDir = config.rootDir || process.cwd();
|
|
751
|
+
const startTime = performance.now();
|
|
752
|
+
const decision = await analyzeCausalGraph(rootDir, config.plugins, options);
|
|
753
|
+
const results = await Promise.all(config.plugins.map((plugin) => runPluginChecker(plugin, decision.activePluginNames.has(plugin.name), rootDir, options)));
|
|
754
|
+
const totalDurationMs = performance.now() - startTime;
|
|
755
|
+
reportResults(decision, results, totalDurationMs, options);
|
|
756
|
+
const hasError = results.some((r) => r.status === "error");
|
|
757
|
+
if (!hasError) {
|
|
758
|
+
const cache = loadBuildCache(rootDir);
|
|
759
|
+
const { head } = await getGitState(rootDir);
|
|
760
|
+
if (head && head !== "unknown") {
|
|
761
|
+
cache.lastVerifiedHead = head;
|
|
762
|
+
saveBuildCache(rootDir, cache);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (hasError && options.interactive) {
|
|
766
|
+
const failedNames = new Set(results.filter((r) => r.status === "error").map((r) => r.name));
|
|
767
|
+
const failedPlugins = config.plugins.filter((p) => failedNames.has(p.name));
|
|
768
|
+
return await runInteractiveLoop(failedPlugins, rootDir, options);
|
|
769
|
+
}
|
|
770
|
+
return hasError ? 1 : 0;
|
|
771
|
+
}
|
|
772
|
+
async function runInteractiveLoop(failedPlugins, rootDir, options) {
|
|
773
|
+
const line = "\u2501".repeat(68);
|
|
774
|
+
process.stdout.write(`
|
|
775
|
+
${BOLD2}${CYAN2}${t("interactiveTitle")}${RESET2}
|
|
776
|
+
`);
|
|
777
|
+
process.stdout.write(`${GRAY2}${line}${RESET2}
|
|
778
|
+
`);
|
|
779
|
+
process.stdout.write(` \u2022 ${t("interactiveTarget")} : ${BOLD2}${failedPlugins.map((p) => p.name).join(", ")}${RESET2}
|
|
780
|
+
`);
|
|
781
|
+
process.stdout.write(` \u2022 ${t("interactiveWatching")}
|
|
782
|
+
`);
|
|
783
|
+
process.stdout.write(` \u2022 ${t("interactiveExit")}
|
|
784
|
+
`);
|
|
785
|
+
process.stdout.write(`${GRAY2}${line}${RESET2}
|
|
786
|
+
|
|
787
|
+
`);
|
|
788
|
+
return new Promise((resolve) => {
|
|
789
|
+
let isChecking = false;
|
|
790
|
+
let debounceTimer = null;
|
|
791
|
+
const watcher = watch(rootDir, { recursive: true }, async (_eventType, filename) => {
|
|
792
|
+
if (!filename)
|
|
793
|
+
return;
|
|
794
|
+
const normalized = filename.replace(/\\/g, "/");
|
|
795
|
+
if (normalized.includes("target/") || normalized.includes("node_modules/") || normalized.includes(".git/") || normalized.includes(".svelte-kit/") || normalized.includes("dist/") || normalized.includes(".synapse/")) {
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
if (debounceTimer)
|
|
799
|
+
clearTimeout(debounceTimer);
|
|
800
|
+
debounceTimer = setTimeout(async () => {
|
|
801
|
+
if (isChecking)
|
|
802
|
+
return;
|
|
803
|
+
isChecking = true;
|
|
804
|
+
const timeStr = new Date().toLocaleTimeString("ko-KR", { hour12: false });
|
|
805
|
+
process.stdout.write(`
|
|
806
|
+
${CYAN2}${t("interactiveDetected", timeStr, normalized)}${RESET2}
|
|
807
|
+
`);
|
|
808
|
+
const retryStart = performance.now();
|
|
809
|
+
const retryResults = await Promise.all(failedPlugins.map((p) => p.check({ rootDir, options })));
|
|
810
|
+
const retryDuration = ((performance.now() - retryStart) / 1000).toFixed(2);
|
|
811
|
+
const stillFailed = retryResults.some((r) => r.status === "error");
|
|
812
|
+
if (!stillFailed) {
|
|
813
|
+
process.stdout.write(`${BOLD2}${GREEN2}${t("interactivePassed", retryDuration)}${RESET2}
|
|
814
|
+
`);
|
|
815
|
+
process.stdout.write(`${BOLD2}${CYAN2}${t("interactiveResumed")}${RESET2}
|
|
816
|
+
|
|
817
|
+
`);
|
|
818
|
+
watcher.close();
|
|
819
|
+
const cache = loadBuildCache(rootDir);
|
|
820
|
+
const { head } = await getGitState(rootDir);
|
|
821
|
+
if (head && head !== "unknown") {
|
|
822
|
+
cache.lastVerifiedHead = head;
|
|
823
|
+
saveBuildCache(rootDir, cache);
|
|
824
|
+
}
|
|
825
|
+
resolve(0);
|
|
826
|
+
} else {
|
|
827
|
+
process.stdout.write(`${BOLD2}${RED2}${t("interactiveFailed")}${RESET2}
|
|
828
|
+
`);
|
|
829
|
+
for (const res of retryResults) {
|
|
830
|
+
if (res.status === "error" && res.details) {
|
|
831
|
+
process.stdout.write(` \u2514\u2500 ${GRAY2}${res.details}${RESET2}
|
|
832
|
+
`);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
isChecking = false;
|
|
836
|
+
}
|
|
837
|
+
}, 60);
|
|
838
|
+
});
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
async function executeBuild(config, options = { mode: "smart", agentMode: false, compactMode: false, watch: false }) {
|
|
842
|
+
const rootDir = config.rootDir || process.cwd();
|
|
843
|
+
const tracks = config.buildTracks || [];
|
|
844
|
+
if (tracks.length === 0) {
|
|
845
|
+
process.stderr.write(`${RED2}${t("noBuildTracks")}${RESET2}
|
|
846
|
+
`);
|
|
847
|
+
return 1;
|
|
848
|
+
}
|
|
849
|
+
const startTime = performance.now();
|
|
850
|
+
const line = "\u2501".repeat(68);
|
|
851
|
+
process.stdout.write(`
|
|
852
|
+
${BOLD2}${CYAN2}${t("buildHeader")} (${tracks.length})${RESET2}
|
|
853
|
+
`);
|
|
854
|
+
process.stdout.write(`${GRAY2}${line}${RESET2}
|
|
855
|
+
`);
|
|
856
|
+
const cache = loadBuildCache(rootDir);
|
|
857
|
+
const { head: currentHead, modifiedFiles, repoRoot } = await getGitState(rootDir);
|
|
858
|
+
const isForce = options.force || options.mode === "all";
|
|
859
|
+
const taskPromises = tracks.map(async (track) => {
|
|
860
|
+
const { skip, reason } = shouldSkipBuildTrack(track, rootDir, repoRoot, cache, modifiedFiles, isForce);
|
|
861
|
+
if (skip) {
|
|
862
|
+
return {
|
|
863
|
+
name: track.name,
|
|
864
|
+
durationMs: 0,
|
|
865
|
+
exitCode: 0,
|
|
866
|
+
skipped: true,
|
|
867
|
+
reason
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
const trackStart = performance.now();
|
|
871
|
+
const proc = spawn2([...track.command], {
|
|
872
|
+
cwd: track.cwd || rootDir,
|
|
873
|
+
stdout: "inherit",
|
|
874
|
+
stderr: "inherit"
|
|
875
|
+
});
|
|
876
|
+
const exitCode = await proc.exited;
|
|
877
|
+
const durationMs = performance.now() - trackStart;
|
|
878
|
+
return {
|
|
879
|
+
name: track.name,
|
|
880
|
+
durationMs,
|
|
881
|
+
exitCode,
|
|
882
|
+
skipped: false,
|
|
883
|
+
reason
|
|
884
|
+
};
|
|
885
|
+
});
|
|
886
|
+
const taskResults = await Promise.all(taskPromises);
|
|
887
|
+
const totalDuration = ((performance.now() - startTime) / 1000).toFixed(2);
|
|
888
|
+
const hasFailed = taskResults.some((t) => t.exitCode !== 0);
|
|
889
|
+
process.stdout.write(`${GRAY2}${line}${RESET2}
|
|
890
|
+
`);
|
|
891
|
+
for (const res of taskResults) {
|
|
892
|
+
if (res.skipped) {
|
|
893
|
+
process.stdout.write(` \u2022 ${BOLD2}${res.name.padEnd(38, " ")}${RESET2} : ${YELLOW2}\u26A1 ${t("trackSkipped")}${RESET2} ${GRAY2}(0.00s)${RESET2}
|
|
894
|
+
`);
|
|
895
|
+
} else {
|
|
896
|
+
const sec = (res.durationMs / 1000).toFixed(2);
|
|
897
|
+
const badge = res.exitCode === 0 ? `${GREEN2}\u2705 ${t("trackComplete")} (${sec}s)${RESET2}` : `${RED2}\u274C ${t("trackFailed")} (${sec}s)${RESET2}`;
|
|
898
|
+
process.stdout.write(` \u2022 ${BOLD2}${res.name.padEnd(38, " ")}${RESET2} : ${badge}
|
|
899
|
+
`);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
process.stdout.write(`${GRAY2}${line}${RESET2}
|
|
903
|
+
`);
|
|
904
|
+
if (!hasFailed) {
|
|
905
|
+
const now = new Date().toISOString();
|
|
906
|
+
for (const res of taskResults) {
|
|
907
|
+
if (!res.skipped && res.exitCode === 0) {
|
|
908
|
+
cache.tracks[res.name] = {
|
|
909
|
+
lastBuildTime: now,
|
|
910
|
+
gitCommit: currentHead,
|
|
911
|
+
artifactExists: true
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
saveBuildCache(rootDir, cache);
|
|
916
|
+
process.stdout.write(`${BOLD2}${GREEN2}${t("buildSuccessSummary", tracks.length, totalDuration)}${RESET2}
|
|
917
|
+
|
|
918
|
+
`);
|
|
919
|
+
return 0;
|
|
920
|
+
} else {
|
|
921
|
+
process.stdout.write(`${BOLD2}${RED2}${t("buildFailureSummary")}${RESET2}
|
|
922
|
+
|
|
923
|
+
`);
|
|
924
|
+
return 1;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
async function executePackage(config, options = { mode: "smart", agentMode: false, compactMode: false, watch: false }) {
|
|
928
|
+
const rootDir = config.rootDir || process.cwd();
|
|
929
|
+
const startTime = performance.now();
|
|
930
|
+
const line = "\u2501".repeat(68);
|
|
931
|
+
process.stdout.write(`
|
|
932
|
+
${BOLD2}${CYAN2}${t("packageHeader")}${RESET2}
|
|
933
|
+
`);
|
|
934
|
+
process.stdout.write(`${GRAY2}${line}${RESET2}
|
|
935
|
+
`);
|
|
936
|
+
if (config.buildTracks && config.buildTracks.length > 0) {
|
|
937
|
+
process.stdout.write(`${CYAN2}${t("packagingPreBuild")}${RESET2}
|
|
938
|
+
`);
|
|
939
|
+
const buildExit = await executeBuild(config, options);
|
|
940
|
+
if (buildExit !== 0)
|
|
941
|
+
return buildExit;
|
|
942
|
+
}
|
|
943
|
+
const tauriConfCandidates = [
|
|
944
|
+
resolve3(rootDir, "src-tauri/tauri.conf.json"),
|
|
945
|
+
resolve3(rootDir, "tauri.conf.json")
|
|
946
|
+
];
|
|
947
|
+
const tauriConfPath = tauriConfCandidates.find((p) => existsSync3(p));
|
|
948
|
+
if (tauriConfPath) {
|
|
949
|
+
try {
|
|
950
|
+
const content = await Bun.file(tauriConfPath).json();
|
|
951
|
+
const targets = content?.bundle?.targets;
|
|
952
|
+
if (targets === "all") {
|
|
953
|
+
process.stdout.write(`${YELLOW2}${t("packagingGuide")}${RESET2}
|
|
954
|
+
`);
|
|
955
|
+
}
|
|
956
|
+
} catch {}
|
|
957
|
+
}
|
|
958
|
+
process.stdout.write(`${BOLD2}${t("packagingStart")}${RESET2}
|
|
959
|
+
`);
|
|
960
|
+
const pkgProc = spawn2(["bun", "x", "tauri", "build", "--bundles", "nsis"], {
|
|
961
|
+
cwd: rootDir,
|
|
962
|
+
stdout: "inherit",
|
|
963
|
+
stderr: "inherit"
|
|
964
|
+
});
|
|
965
|
+
const exitCode = await pkgProc.exited;
|
|
966
|
+
const duration = ((performance.now() - startTime) / 1000).toFixed(2);
|
|
967
|
+
process.stdout.write(`${GRAY2}${line}${RESET2}
|
|
968
|
+
`);
|
|
969
|
+
if (exitCode === 0) {
|
|
970
|
+
process.stdout.write(`${BOLD2}${GREEN2}${t("packageSuccess", duration)}${RESET2}
|
|
971
|
+
|
|
972
|
+
`);
|
|
973
|
+
return 0;
|
|
974
|
+
} else {
|
|
975
|
+
process.stdout.write(`${BOLD2}${RED2}${t("packageFailed", duration)}${RESET2}
|
|
976
|
+
|
|
977
|
+
`);
|
|
978
|
+
return exitCode;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
async function executeSign(config, options = { mode: "smart", agentMode: false, compactMode: false, watch: false }) {
|
|
982
|
+
const rootDir = config.rootDir || process.cwd();
|
|
983
|
+
const startTime = performance.now();
|
|
984
|
+
const line = "\u2501".repeat(68);
|
|
985
|
+
process.stdout.write(`
|
|
986
|
+
${BOLD2}${CYAN2}${t("signHeader")}${RESET2}
|
|
987
|
+
`);
|
|
988
|
+
process.stdout.write(`${GRAY2}${line}${RESET2}
|
|
989
|
+
`);
|
|
990
|
+
const signConfig = config.sign;
|
|
991
|
+
if (!signConfig || !signConfig.privateKeyPath) {
|
|
992
|
+
process.stderr.write(`${RED2}${t("signNoConfig")}${RESET2}
|
|
993
|
+
`);
|
|
994
|
+
return 1;
|
|
995
|
+
}
|
|
996
|
+
const keyPath = resolve3(rootDir, signConfig.privateKeyPath);
|
|
997
|
+
if (!existsSync3(keyPath)) {
|
|
998
|
+
process.stderr.write(`${RED2}${t("signNoKey", keyPath)}${RESET2}
|
|
999
|
+
`);
|
|
1000
|
+
return 1;
|
|
1001
|
+
}
|
|
1002
|
+
let installerPath = signConfig.targetInstaller ? resolve3(rootDir, signConfig.targetInstaller) : "";
|
|
1003
|
+
if (!installerPath || !existsSync3(installerPath)) {
|
|
1004
|
+
const candidates = [
|
|
1005
|
+
resolve3(rootDir, "target/release/bundle/nsis"),
|
|
1006
|
+
resolve3(rootDir, "src-tauri/target/release/bundle/nsis"),
|
|
1007
|
+
resolve3(rootDir, "../target/release/bundle/nsis")
|
|
1008
|
+
];
|
|
1009
|
+
for (const dir of candidates) {
|
|
1010
|
+
if (existsSync3(dir)) {
|
|
1011
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(".exe") && !f.endsWith(".sig"));
|
|
1012
|
+
if (files.length > 0) {
|
|
1013
|
+
installerPath = resolve3(dir, files[0]);
|
|
1014
|
+
break;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
if (!installerPath || !existsSync3(installerPath)) {
|
|
1020
|
+
process.stderr.write(`${RED2}${t("signNoInstaller")}${RESET2}
|
|
1021
|
+
`);
|
|
1022
|
+
return 1;
|
|
1023
|
+
}
|
|
1024
|
+
const signaturePath = `${installerPath}.sig`;
|
|
1025
|
+
const cache = loadBuildCache(rootDir);
|
|
1026
|
+
const isForce = options.force || options.mode === "all";
|
|
1027
|
+
const { skip, reason, currentHash } = shouldSkipSign(installerPath, signaturePath, cache, isForce);
|
|
1028
|
+
if (skip) {
|
|
1029
|
+
process.stdout.write(` \u2022 ${t("signTarget")} : ${BOLD2}${installerPath}${RESET2}
|
|
1030
|
+
` + ` \u2022 ${t("signStatus")} : ${YELLOW2}\u26A1 ${t("signCacheHit")}${RESET2} ${GRAY2}(0.00s)${RESET2}
|
|
1031
|
+
` + ` \u2022 ${t("signFile")} : ${GREEN2}\u2705 ${t("signExistingKeep", signaturePath)}${RESET2}
|
|
1032
|
+
`);
|
|
1033
|
+
process.stdout.write(`${GRAY2}${line}${RESET2}
|
|
1034
|
+
`);
|
|
1035
|
+
process.stdout.write(`${BOLD2}${GREEN2}${t("signIntegrityPass")}${RESET2}
|
|
1036
|
+
|
|
1037
|
+
`);
|
|
1038
|
+
return 0;
|
|
1039
|
+
}
|
|
1040
|
+
process.stdout.write(` \u2022 ${t("signTarget")} : ${BOLD2}${installerPath}${RESET2}
|
|
1041
|
+
`);
|
|
1042
|
+
process.stdout.write(` \u2022 ${t("signReasonLabel")} : ${CYAN2}${reason}${RESET2}
|
|
1043
|
+
`);
|
|
1044
|
+
process.stdout.write(` \u2022 ${t("signEngineLabel")} : ${BOLD2}Bun Native Tauri Signer (Ed25519)${RESET2}
|
|
1045
|
+
`);
|
|
1046
|
+
const passwordEnvName = signConfig.passwordEnv || "TAURI_KEY_PASSWORD";
|
|
1047
|
+
const passwordVal = process.env[passwordEnvName] || process.env.TAURI_PRIVATE_KEY_PASSWORD || process.env.TAURI_KEY_PASSWORD || "";
|
|
1048
|
+
const signArgs = [
|
|
1049
|
+
"bun",
|
|
1050
|
+
"x",
|
|
1051
|
+
"tauri",
|
|
1052
|
+
"signer",
|
|
1053
|
+
"sign",
|
|
1054
|
+
"--private-key-path",
|
|
1055
|
+
keyPath
|
|
1056
|
+
];
|
|
1057
|
+
if (passwordVal) {
|
|
1058
|
+
signArgs.push("--password", passwordVal);
|
|
1059
|
+
}
|
|
1060
|
+
signArgs.push(installerPath);
|
|
1061
|
+
const proc = spawn2(signArgs, {
|
|
1062
|
+
cwd: rootDir,
|
|
1063
|
+
env: {
|
|
1064
|
+
...process.env,
|
|
1065
|
+
TAURI_PRIVATE_KEY_PASSWORD: passwordVal,
|
|
1066
|
+
TAURI_KEY_PASSWORD: passwordVal
|
|
1067
|
+
},
|
|
1068
|
+
stdout: "inherit",
|
|
1069
|
+
stderr: "inherit"
|
|
1070
|
+
});
|
|
1071
|
+
const exitCode = await proc.exited;
|
|
1072
|
+
const duration = ((performance.now() - startTime) / 1000).toFixed(2);
|
|
1073
|
+
process.stdout.write(`${GRAY2}${line}${RESET2}
|
|
1074
|
+
`);
|
|
1075
|
+
if (exitCode === 0) {
|
|
1076
|
+
cache.sign = {
|
|
1077
|
+
lastSignTime: new Date().toISOString(),
|
|
1078
|
+
installerHash: currentHash || computeFileHash(installerPath),
|
|
1079
|
+
signaturePath
|
|
1080
|
+
};
|
|
1081
|
+
saveBuildCache(rootDir, cache);
|
|
1082
|
+
process.stdout.write(`${BOLD2}${GREEN2}${t("signSuccess", duration)}${RESET2}
|
|
1083
|
+
` + ` \u2022 ${t("signFile")}: ${BOLD2}${signaturePath}${RESET2}
|
|
1084
|
+
|
|
1085
|
+
`);
|
|
1086
|
+
return 0;
|
|
1087
|
+
} else {
|
|
1088
|
+
process.stdout.write(`${BOLD2}${RED2}${t("signFailed", duration)}${RESET2}
|
|
1089
|
+
|
|
1090
|
+
`);
|
|
1091
|
+
return exitCode;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
// cli.ts
|
|
1096
|
+
var RESET3 = "\x1B[0m";
|
|
1097
|
+
var BOLD3 = "\x1B[1m";
|
|
1098
|
+
var CYAN3 = "\x1B[36m";
|
|
1099
|
+
var GREEN3 = "\x1B[32m";
|
|
1100
|
+
var RED3 = "\x1B[31m";
|
|
1101
|
+
async function handleInit(targetDir = process.cwd()) {
|
|
1102
|
+
const configPath = resolve4(targetDir, "synapse.config.ts");
|
|
1103
|
+
if (existsSync4(configPath)) {
|
|
1104
|
+
process.stderr.write(`${RED3}\u274C ${t("configExists")} ${configPath}${RESET3}
|
|
1105
|
+
`);
|
|
1106
|
+
return 1;
|
|
1107
|
+
}
|
|
1108
|
+
const template = `import { defineConfig, rustChecker, svelteChecker, schemaChecker, nativeChecker, nsisChecker } from 'synapse-kit';
|
|
1109
|
+
|
|
1110
|
+
export default defineConfig({
|
|
1111
|
+
aiMemory: {
|
|
1112
|
+
enabled: true,
|
|
1113
|
+
smartSkipping: true,
|
|
1114
|
+
},
|
|
1115
|
+
plugins: [
|
|
1116
|
+
rustChecker({ workspaceDir: './src-tauri' }),
|
|
1117
|
+
svelteChecker({ tsconfig: './tsconfig.json' }),
|
|
1118
|
+
schemaChecker({
|
|
1119
|
+
targets: [
|
|
1120
|
+
{ path: './src-tauri/tauri.conf.json' },
|
|
1121
|
+
],
|
|
1122
|
+
}),
|
|
1123
|
+
nativeChecker({
|
|
1124
|
+
targets: [
|
|
1125
|
+
{ path: './src-tauri/resources/vesper_apo.dll', expectedArchitecture: 'x64' },
|
|
1126
|
+
],
|
|
1127
|
+
}),
|
|
1128
|
+
nsisChecker({
|
|
1129
|
+
templatePath: './installer-template.nsi',
|
|
1130
|
+
}),
|
|
1131
|
+
],
|
|
1132
|
+
buildTracks: [
|
|
1133
|
+
{
|
|
1134
|
+
name: 'APO DLL \uBE4C\uB4DC',
|
|
1135
|
+
command: ['bun', 'tooling/build-apo.mjs'],
|
|
1136
|
+
sources: ['vesper-apo/'],
|
|
1137
|
+
artifacts: ['src-tauri/resources/vesper_apo.dll'],
|
|
1138
|
+
},
|
|
1139
|
+
{
|
|
1140
|
+
name: 'Taskbar \uC704\uC82F \uBE4C\uB4DC',
|
|
1141
|
+
command: ['bun', 'tooling/build-taskbar.mjs'],
|
|
1142
|
+
sources: ['windhawk/', 'standalone/'],
|
|
1143
|
+
artifacts: ['src-tauri/resources/taskbar/VesperTaskbar.dll'],
|
|
1144
|
+
},
|
|
1145
|
+
{
|
|
1146
|
+
name: 'Svelte UI \uBE4C\uB4DC',
|
|
1147
|
+
command: ['bun', 'run', 'build'],
|
|
1148
|
+
sources: ['src/', 'static/'],
|
|
1149
|
+
artifacts: ['build/index.html'],
|
|
1150
|
+
},
|
|
1151
|
+
],
|
|
1152
|
+
package: {
|
|
1153
|
+
framework: 'tauri',
|
|
1154
|
+
targets: ['nsis'],
|
|
1155
|
+
compression: 'zlib',
|
|
1156
|
+
},
|
|
1157
|
+
sign: {
|
|
1158
|
+
privateKeyPath: 'src-tauri/keys/updater',
|
|
1159
|
+
passwordEnv: 'TAURI_KEY_PASSWORD',
|
|
1160
|
+
},
|
|
1161
|
+
});
|
|
1162
|
+
`;
|
|
1163
|
+
await writeFile(configPath, template, "utf8");
|
|
1164
|
+
process.stdout.write(`${BOLD3}${GREEN3}\u2705 ${t("configCreated")}${RESET3}
|
|
1165
|
+
`);
|
|
1166
|
+
return 0;
|
|
1167
|
+
}
|
|
1168
|
+
function printHelp() {
|
|
1169
|
+
process.stdout.write(`
|
|
1170
|
+
${BOLD3}${CYAN3}${t("cliTitle")}${RESET3}
|
|
1171
|
+
|
|
1172
|
+
${BOLD3}${t("cliUsage")}${RESET3}
|
|
1173
|
+
synapse <command> [options]
|
|
1174
|
+
|
|
1175
|
+
${BOLD3}${t("cliCommands")}${RESET3}
|
|
1176
|
+
check ${t("cmdCheck")}
|
|
1177
|
+
build ${t("cmdBuild")}
|
|
1178
|
+
package ${t("cmdPackage")}
|
|
1179
|
+
sign ${t("cmdSign")}
|
|
1180
|
+
init ${t("cmdInit")}
|
|
1181
|
+
memory ${t("cmdMemory")}
|
|
1182
|
+
|
|
1183
|
+
${BOLD3}${t("cliOptions")}${RESET3}
|
|
1184
|
+
--all ${t("optAll")}
|
|
1185
|
+
-f, --force ${t("optForce")}
|
|
1186
|
+
--agent ${t("optAgent")}
|
|
1187
|
+
--compact ${t("optCompact")}
|
|
1188
|
+
-i, --interactive ${t("optInteractive")}
|
|
1189
|
+
--watch ${t("optWatch")}
|
|
1190
|
+
--lang <ko|en> ${t("optLang")}
|
|
1191
|
+
--help, -h ${t("optHelp")}
|
|
1192
|
+
--version, -v ${t("optVersion")}
|
|
1193
|
+
|
|
1194
|
+
`);
|
|
1195
|
+
}
|
|
1196
|
+
async function main() {
|
|
1197
|
+
const args = process.argv.slice(2);
|
|
1198
|
+
let explicitLang;
|
|
1199
|
+
for (let i = 0;i < args.length; i++) {
|
|
1200
|
+
if (args[i].startsWith("--lang=")) {
|
|
1201
|
+
explicitLang = args[i].split("=")[1];
|
|
1202
|
+
} else if (args[i] === "--lang" && args[i + 1]) {
|
|
1203
|
+
explicitLang = args[i + 1];
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
detectLocale(explicitLang);
|
|
1207
|
+
if (args.includes("--help") || args.includes("-h") || args[0] === "help") {
|
|
1208
|
+
printHelp();
|
|
1209
|
+
process.exit(0);
|
|
1210
|
+
}
|
|
1211
|
+
if (args.includes("--version") || args.includes("-v") || args[0] === "version") {
|
|
1212
|
+
process.stdout.write(`synapse-kit v${package_default.version}
|
|
1213
|
+
`);
|
|
1214
|
+
process.exit(0);
|
|
1215
|
+
}
|
|
1216
|
+
const command = args.find((a) => !a.startsWith("-")) || "check";
|
|
1217
|
+
if (command === "init") {
|
|
1218
|
+
const code = await handleInit();
|
|
1219
|
+
process.exit(code);
|
|
1220
|
+
}
|
|
1221
|
+
const isInteractive = args.includes("--interactive") || args.includes("-i");
|
|
1222
|
+
const isForce = args.includes("--force") || args.includes("-f");
|
|
1223
|
+
const options = {
|
|
1224
|
+
mode: args.includes("--all") ? "all" : "smart",
|
|
1225
|
+
agentMode: args.includes("--agent") || args.includes("--compact"),
|
|
1226
|
+
compactMode: args.includes("--compact"),
|
|
1227
|
+
watch: args.includes("--watch"),
|
|
1228
|
+
interactive: isInteractive,
|
|
1229
|
+
force: isForce
|
|
1230
|
+
};
|
|
1231
|
+
if (command === "memory") {
|
|
1232
|
+
try {
|
|
1233
|
+
const { handleMemoryCommand } = await import("../../memory/cli");
|
|
1234
|
+
const code = await handleMemoryCommand(args, options);
|
|
1235
|
+
process.exit(code);
|
|
1236
|
+
} catch {
|
|
1237
|
+
process.stderr.write(`${RED3}\u274C Causal Memory \uBAA8\uB4C8\uC774 \uC124\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. '@synapse-kit/memory' \uD328\uD0A4\uC9C0\uB97C \uC124\uCE58\uD558\uAC70\uB098 'synapse-memory' \uBA85\uB839\uC5B4\uB97C \uC0AC\uC6A9\uD558\uC138\uC694.${RESET3}
|
|
1238
|
+
`);
|
|
1239
|
+
process.exit(1);
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
try {
|
|
1243
|
+
const { config } = await loadSynapseConfig();
|
|
1244
|
+
if (command === "check") {
|
|
1245
|
+
const code = await executeChecks(config, options);
|
|
1246
|
+
process.exit(code);
|
|
1247
|
+
} else if (command === "build") {
|
|
1248
|
+
const code = await executeBuild(config, options);
|
|
1249
|
+
process.exit(code);
|
|
1250
|
+
} else if (command === "package") {
|
|
1251
|
+
const code = await executePackage(config, options);
|
|
1252
|
+
process.exit(code);
|
|
1253
|
+
} else if (command === "sign") {
|
|
1254
|
+
const code = await executeSign(config, options);
|
|
1255
|
+
process.exit(code);
|
|
1256
|
+
} else {
|
|
1257
|
+
process.stderr.write(`${RED3}\u274C ${t("unknownCmd")} '${command}'${RESET3}
|
|
1258
|
+
`);
|
|
1259
|
+
printHelp();
|
|
1260
|
+
process.exit(1);
|
|
1261
|
+
}
|
|
1262
|
+
} catch (error) {
|
|
1263
|
+
if (options.agentMode) {
|
|
1264
|
+
process.stdout.write(JSON.stringify({
|
|
1265
|
+
success: false,
|
|
1266
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1267
|
+
}) + `
|
|
1268
|
+
`);
|
|
1269
|
+
} else {
|
|
1270
|
+
process.stderr.write(`${RED3}${t("errPrefix")}${RESET3} ${error instanceof Error ? error.message : String(error)}
|
|
1271
|
+
`);
|
|
1272
|
+
}
|
|
1273
|
+
process.exit(1);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
main();
|