flavor-code 1.3.18 → 1.3.20
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 +8 -0
- package/README.zh-CN.md +8 -0
- package/dist/{app-LKK5RBTO.js → app-EGG3BYQQ.js} +8 -44
- package/dist/{chunk-36UKDXPF.js → chunk-3HWWQV2A.js} +0 -11
- package/dist/{chunk-2BF7CVWZ.js → chunk-7OICVL2M.js} +42 -0
- package/dist/chunk-OTYFL4AG.js +16 -0
- package/dist/{chunk-HJOCNKPN.js → chunk-RPFWB45Y.js} +2 -1
- package/dist/{chunk-6LDYDQ3P.js → chunk-VEUSROUQ.js} +1 -1
- package/dist/{chunk-PF457XCH.js → chunk-Z62P4LL7.js} +533 -259
- package/dist/{claude-ink-AUZBJ3BE.js → claude-ink-3K3NG7BF.js} +2 -1
- package/dist/cli-main.js +83 -79
- package/dist/config/schema.d.ts +1 -1
- package/dist/desktop/main.js +640 -425
- package/dist/desktop-renderer/assets/{index-CxOMqdQf.js → index-D75ozXnZ.js} +2 -2
- package/dist/desktop-renderer/assets/{interactive-terminal-BK8GS4b3.js → interactive-terminal-CTFo4fK9.js} +1 -1
- package/dist/desktop-renderer/index.html +1 -1
- package/dist/{load-DELQW42K.js → load-4FWNXE6F.js} +1 -1
- package/dist/sdk/index.js +3 -3
- package/dist/session/store.d.ts +6 -0
- package/dist/utils/crash-guard.d.ts +9 -0
- package/dist/utils/spawn-executable.d.ts +16 -0
- package/package.json +1 -1
package/dist/cli-main.js
CHANGED
|
@@ -3,10 +3,12 @@ import { createRequire } from "node:module"; const require = createRequire(impor
|
|
|
3
3
|
import {
|
|
4
4
|
FlavorRpcServer,
|
|
5
5
|
TraceRecorder
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VEUSROUQ.js";
|
|
7
7
|
import {
|
|
8
|
+
NPM_PACKAGE_NAME,
|
|
9
|
+
fetchLatestVersion,
|
|
8
10
|
staticTaskLines
|
|
9
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-7OICVL2M.js";
|
|
10
12
|
import {
|
|
11
13
|
DEFAULT_MAX_OUTPUT_BYTES,
|
|
12
14
|
MAX_ALIAS_LENGTH,
|
|
@@ -19,11 +21,13 @@ import {
|
|
|
19
21
|
createProductionRuntime,
|
|
20
22
|
executeShell,
|
|
21
23
|
initializeFlavor,
|
|
24
|
+
installCrashGuard,
|
|
22
25
|
message,
|
|
23
26
|
packageVersion,
|
|
27
|
+
prepareSpawnInvocation,
|
|
24
28
|
redactErrorText,
|
|
25
29
|
runPalBroker
|
|
26
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-Z62P4LL7.js";
|
|
27
31
|
import "./chunk-CIVPKHF4.js";
|
|
28
32
|
import {
|
|
29
33
|
McpServerConfigSchema,
|
|
@@ -33,7 +37,11 @@ import {
|
|
|
33
37
|
readRecoverableFile,
|
|
34
38
|
setProjectSkillDisabled,
|
|
35
39
|
updateProtectedFile
|
|
36
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-RPFWB45Y.js";
|
|
41
|
+
import {
|
|
42
|
+
gt,
|
|
43
|
+
isValidVersion
|
|
44
|
+
} from "./chunk-OTYFL4AG.js";
|
|
37
45
|
import "./chunk-RQTYHUMK.js";
|
|
38
46
|
import "./chunk-S32JRDZK.js";
|
|
39
47
|
|
|
@@ -45,71 +53,39 @@ import { posix, resolve as resolve3 } from "path";
|
|
|
45
53
|
import { fileURLToPath } from "url";
|
|
46
54
|
import { Command, Option } from "commander";
|
|
47
55
|
|
|
48
|
-
// src/
|
|
49
|
-
import {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return path;
|
|
76
|
-
} catch {
|
|
77
|
-
return void 0;
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
const restoreTerminal = () => {
|
|
81
|
-
try {
|
|
82
|
-
if (process.stdout.isTTY === true) process.stdout.write("\x1B[?25h\x1B[?1049l");
|
|
83
|
-
} catch {
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
const describe = (reason) => {
|
|
87
|
-
if (reason instanceof Error) return `${reason.name}: ${reason.message}
|
|
88
|
-
${reason.stack ?? ""}`;
|
|
89
|
-
return String(reason);
|
|
90
|
-
};
|
|
91
|
-
const crash = (kind, reason) => {
|
|
92
|
-
const detail = describe(reason);
|
|
93
|
-
const logPath = writeCrashLog(kind, detail);
|
|
94
|
-
restoreTerminal();
|
|
95
|
-
try {
|
|
96
|
-
const safe = redactErrorText(detail.split("\n").slice(0, 3).join("\n"));
|
|
97
|
-
process.stderr.write(`flavor crashed (${kind}): ${safe}
|
|
98
|
-
`);
|
|
99
|
-
if (logPath !== void 0) process.stderr.write(`crash log: ${logPath}
|
|
100
|
-
`);
|
|
101
|
-
} catch {
|
|
102
|
-
}
|
|
103
|
-
process.exit(1);
|
|
104
|
-
};
|
|
105
|
-
process.on("unhandledRejection", (reason) => crash("unhandledRejection", reason));
|
|
106
|
-
process.on("uncaughtException", (error) => crash("uncaughtException", error));
|
|
56
|
+
// src/update/apply.ts
|
|
57
|
+
import { spawn } from "child_process";
|
|
58
|
+
function npmExecutable(platform = process.platform) {
|
|
59
|
+
return platform === "win32" ? "npm.cmd" : "npm";
|
|
60
|
+
}
|
|
61
|
+
var defaultInstall = (command, args) => new Promise((resolve4, reject) => {
|
|
62
|
+
const invocation = prepareSpawnInvocation(command, args);
|
|
63
|
+
const child = spawn(invocation.command, invocation.args, {
|
|
64
|
+
stdio: "inherit",
|
|
65
|
+
...invocation.windowsVerbatimArguments === void 0 ? {} : { windowsVerbatimArguments: invocation.windowsVerbatimArguments }
|
|
66
|
+
});
|
|
67
|
+
child.on("error", reject);
|
|
68
|
+
child.on("close", (code) => resolve4(code));
|
|
69
|
+
});
|
|
70
|
+
async function runUpdate(options = {}) {
|
|
71
|
+
const current = options.current ?? packageVersion();
|
|
72
|
+
const latest = await fetchLatestVersion(options);
|
|
73
|
+
if (latest === void 0 || !isValidVersion(latest)) return { status: "check-failed", current };
|
|
74
|
+
if (!gt(latest, current)) return { status: "up-to-date", current, latest };
|
|
75
|
+
const install = options.install ?? defaultInstall;
|
|
76
|
+
let exitCode;
|
|
77
|
+
try {
|
|
78
|
+
exitCode = await install(npmExecutable(options.platform), ["install", "-g", `${NPM_PACKAGE_NAME}@${latest}`]);
|
|
79
|
+
} catch {
|
|
80
|
+
exitCode = null;
|
|
81
|
+
}
|
|
82
|
+
return exitCode === 0 ? { status: "updated", current, latest } : { status: "install-failed", current, latest, exitCode };
|
|
107
83
|
}
|
|
108
84
|
|
|
109
85
|
// src/skills/manager.ts
|
|
110
86
|
import { lstat, mkdir, readFile, readdir, realpath, rm, writeFile } from "fs/promises";
|
|
111
87
|
import { homedir } from "os";
|
|
112
|
-
import { isAbsolute, join
|
|
88
|
+
import { isAbsolute, join, relative, resolve, sep } from "path";
|
|
113
89
|
import { stringify } from "yaml";
|
|
114
90
|
var SkillManager = class {
|
|
115
91
|
#workspace;
|
|
@@ -132,7 +108,7 @@ var SkillManager = class {
|
|
|
132
108
|
async create(draft) {
|
|
133
109
|
const value = parseDraft(draft);
|
|
134
110
|
const projectRoot = this.#projectRoot();
|
|
135
|
-
const directory =
|
|
111
|
+
const directory = join(projectRoot, value.name);
|
|
136
112
|
await mkdir(projectRoot, { recursive: true, mode: 448 });
|
|
137
113
|
try {
|
|
138
114
|
await mkdir(directory, { mode: 448 });
|
|
@@ -141,7 +117,7 @@ var SkillManager = class {
|
|
|
141
117
|
throw error;
|
|
142
118
|
}
|
|
143
119
|
try {
|
|
144
|
-
await writeFile(
|
|
120
|
+
await writeFile(join(directory, "SKILL.md"), renderSkill(value), { encoding: "utf8", flag: "wx", mode: 384 });
|
|
145
121
|
await this.#persistEnabled(value.name, true);
|
|
146
122
|
return this.get(value.name);
|
|
147
123
|
} catch (error) {
|
|
@@ -159,7 +135,7 @@ var SkillManager = class {
|
|
|
159
135
|
throw error;
|
|
160
136
|
});
|
|
161
137
|
if (!info.isDirectory() || info.isSymbolicLink()) throw new Error(`Project skill path is not a real directory: ${validName}`);
|
|
162
|
-
const skillFile =
|
|
138
|
+
const skillFile = join(directory, "SKILL.md");
|
|
163
139
|
const fileInfo = await lstat(skillFile);
|
|
164
140
|
if (!fileInfo.isFile() || fileInfo.isSymbolicLink()) throw new Error(`Project skill file is not a real file: ${validName}`);
|
|
165
141
|
await writeFile(skillFile, renderSkill(value), { encoding: "utf8", mode: 384 });
|
|
@@ -191,12 +167,12 @@ var SkillManager = class {
|
|
|
191
167
|
async #registry() {
|
|
192
168
|
const loaded = await loadConfig({ cwd: this.#workspace, home: this.#home });
|
|
193
169
|
const [globalPluginRoots, projectPluginRoots] = await Promise.all([
|
|
194
|
-
discoverPluginSkillRoots(
|
|
195
|
-
discoverPluginSkillRoots(
|
|
170
|
+
discoverPluginSkillRoots(join(this.#home, ".flavor-code", "plugins")),
|
|
171
|
+
discoverPluginSkillRoots(join(this.#workspace, ".flavor", "plugins"))
|
|
196
172
|
]);
|
|
197
173
|
return {
|
|
198
174
|
registry: new SkillRegistry({
|
|
199
|
-
globalRoots: [
|
|
175
|
+
globalRoots: [join(this.#home, ".flavor-code", "skills"), ...globalPluginRoots],
|
|
200
176
|
projectRoots: [this.#projectRoot(), ...projectPluginRoots]
|
|
201
177
|
}),
|
|
202
178
|
disabled: new Set(loaded.config.skills.disabled)
|
|
@@ -212,10 +188,10 @@ var SkillManager = class {
|
|
|
212
188
|
};
|
|
213
189
|
}
|
|
214
190
|
#projectRoot() {
|
|
215
|
-
return
|
|
191
|
+
return join(this.#workspace, ".flavor", "skills");
|
|
216
192
|
}
|
|
217
193
|
#projectSkillDirectory(name) {
|
|
218
|
-
return
|
|
194
|
+
return join(this.#projectRoot(), name);
|
|
219
195
|
}
|
|
220
196
|
};
|
|
221
197
|
function parseName(value) {
|
|
@@ -256,9 +232,9 @@ async function discoverPluginSkillRoots(directory) {
|
|
|
256
232
|
const roots = [];
|
|
257
233
|
for (const entry of entries) {
|
|
258
234
|
if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
|
|
259
|
-
const pluginRoot = await realpath(
|
|
235
|
+
const pluginRoot = await realpath(join(directory, entry.name));
|
|
260
236
|
try {
|
|
261
|
-
const manifest = PluginManifestSchema.parse(JSON.parse(await readFile(
|
|
237
|
+
const manifest = PluginManifestSchema.parse(JSON.parse(await readFile(join(pluginRoot, "flavor-plugin.json"), "utf8")));
|
|
262
238
|
for (const contribution of manifest.contributes.skillRoots) {
|
|
263
239
|
const candidate = resolve(pluginRoot, contribution.path);
|
|
264
240
|
const info = await lstat(candidate);
|
|
@@ -390,11 +366,11 @@ function parseMemoryType(value) {
|
|
|
390
366
|
}
|
|
391
367
|
|
|
392
368
|
// src/mcp/config-manager.ts
|
|
393
|
-
import { join as
|
|
369
|
+
import { join as join2 } from "path";
|
|
394
370
|
var ProjectMcpConfigManager = class {
|
|
395
371
|
path;
|
|
396
372
|
constructor(workspace) {
|
|
397
|
-
this.path =
|
|
373
|
+
this.path = join2(workspace, ".flavor", "flavor.json");
|
|
398
374
|
}
|
|
399
375
|
async list() {
|
|
400
376
|
const document = await readRecoverableFile(this.path, (raw) => parseDocument(this.path, raw));
|
|
@@ -751,7 +727,7 @@ async function runEvaluationFile(path, outputPath) {
|
|
|
751
727
|
})),
|
|
752
728
|
...parsed.maxTokens === void 0 ? {} : { maxTokens: parsed.maxTokens }
|
|
753
729
|
};
|
|
754
|
-
const configured = await import("./load-
|
|
730
|
+
const configured = await import("./load-4FWNXE6F.js").then(({ loadConfig: loadConfig2 }) => loadConfig2({ cwd: workspace, home: process.env.USERPROFILE ?? process.env.HOME ?? workspace }));
|
|
755
731
|
const environment = createExecutionEnvironment(workspace, configured.config.execution) ?? new LocalExecutionEnvironment();
|
|
756
732
|
let report;
|
|
757
733
|
try {
|
|
@@ -784,6 +760,34 @@ function createProgram(dependencies = {}) {
|
|
|
784
760
|
`);
|
|
785
761
|
} catch (error) {
|
|
786
762
|
process.stderr.write(`init: ${safeError(error)}
|
|
763
|
+
`);
|
|
764
|
+
process.exitCode = 1;
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
program.command("update").description(`Update the globally installed ${NPM_PACKAGE_NAME} to the latest npm release`).action(async () => {
|
|
768
|
+
try {
|
|
769
|
+
const outcome = await (dependencies.runUpdate ?? runUpdate)();
|
|
770
|
+
switch (outcome.status) {
|
|
771
|
+
case "up-to-date":
|
|
772
|
+
process.stdout.write(`${NPM_PACKAGE_NAME} is already up to date (v${outcome.current}).
|
|
773
|
+
`);
|
|
774
|
+
break;
|
|
775
|
+
case "updated":
|
|
776
|
+
process.stdout.write(`Updated ${NPM_PACKAGE_NAME} v${outcome.current} \u2192 v${outcome.latest}. Restart flavor to use it.
|
|
777
|
+
`);
|
|
778
|
+
break;
|
|
779
|
+
case "check-failed":
|
|
780
|
+
process.stderr.write("update: could not reach the npm registry to determine the latest version.\n");
|
|
781
|
+
process.exitCode = 1;
|
|
782
|
+
break;
|
|
783
|
+
case "install-failed":
|
|
784
|
+
process.stderr.write(`update: npm install failed${outcome.exitCode === null ? " (npm could not be started)" : ` with exit code ${outcome.exitCode}`}. Install manually with: npm i -g ${NPM_PACKAGE_NAME}
|
|
785
|
+
`);
|
|
786
|
+
process.exitCode = 1;
|
|
787
|
+
break;
|
|
788
|
+
}
|
|
789
|
+
} catch (error) {
|
|
790
|
+
process.stderr.write(`update: ${safeError(error)}
|
|
787
791
|
`);
|
|
788
792
|
process.exitCode = 1;
|
|
789
793
|
}
|
|
@@ -876,9 +880,9 @@ function createProgram(dependencies = {}) {
|
|
|
876
880
|
}
|
|
877
881
|
async function runInteractiveCli(props) {
|
|
878
882
|
const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
|
|
879
|
-
import("./claude-ink-
|
|
883
|
+
import("./claude-ink-3K3NG7BF.js"),
|
|
880
884
|
import("react"),
|
|
881
|
-
import("./app-
|
|
885
|
+
import("./app-EGG3BYQQ.js")
|
|
882
886
|
]);
|
|
883
887
|
const instance = await render(createElement(
|
|
884
888
|
AlternateScreen,
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -124,7 +124,7 @@ export declare const FlavorConfigSchema: z.ZodObject<{
|
|
|
124
124
|
autoStoreThreshold: z.ZodDefault<z.ZodNumber>;
|
|
125
125
|
ignoreStreakLimit: z.ZodDefault<z.ZodNumber>;
|
|
126
126
|
reviewAutoDismissSeconds: z.ZodDefault<z.ZodNumber>;
|
|
127
|
-
maxCandidatesPerTask: z.ZodDefault<z.
|
|
127
|
+
maxCandidatesPerTask: z.ZodDefault<z.ZodLiteral<1>>;
|
|
128
128
|
retrievalTopK: z.ZodDefault<z.ZodNumber>;
|
|
129
129
|
maxEntries: z.ZodDefault<z.ZodNumber>;
|
|
130
130
|
maxEntryChars: z.ZodDefault<z.ZodNumber>;
|