summer-engine 2.5.0 → 2.6.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +5 -4
- package/.codex-plugin/plugin.json +5 -4
- package/.cursor-plugin/plugin.json +4 -3
- package/.factory-plugin/plugin.json +3 -3
- package/AGENTS.md +6 -4
- package/CHANGELOG.md +20 -2
- package/GEMINI.md +3 -3
- package/README.md +83 -97
- package/dist/bin/summer.js +6 -1
- package/dist/commands/cloud.d.ts +2 -0
- package/dist/commands/cloud.js +80 -0
- package/dist/commands/doctor.js +19 -0
- package/dist/commands/login.js +4 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/open.js +1 -1
- package/dist/commands/plan.d.ts +2 -0
- package/dist/commands/plan.js +60 -0
- package/dist/commands/run.js +132 -35
- package/dist/lib/auth.d.ts +2 -0
- package/dist/lib/auth.js +13 -0
- package/dist/lib/cloud/api.d.ts +79 -0
- package/dist/lib/cloud/api.js +107 -0
- package/dist/lib/cloud/apply.d.ts +32 -0
- package/dist/lib/cloud/apply.js +294 -0
- package/dist/lib/cloud/checkpoint.d.ts +26 -0
- package/dist/lib/cloud/checkpoint.js +142 -0
- package/dist/lib/cloud/conflicts.d.ts +55 -0
- package/dist/lib/cloud/conflicts.js +131 -0
- package/dist/lib/cloud/containment.d.ts +8 -0
- package/dist/lib/cloud/containment.js +52 -0
- package/dist/lib/cloud/diff.d.ts +39 -0
- package/dist/lib/cloud/diff.js +138 -0
- package/dist/lib/cloud/engine-bridge.d.ts +21 -0
- package/dist/lib/cloud/engine-bridge.js +105 -0
- package/dist/lib/cloud/hash-cache.d.ts +23 -0
- package/dist/lib/cloud/hash-cache.js +44 -0
- package/dist/lib/cloud/hash.d.ts +10 -0
- package/dist/lib/cloud/hash.js +111 -0
- package/dist/lib/cloud/http.d.ts +17 -0
- package/dist/lib/cloud/http.js +47 -0
- package/dist/lib/cloud/lock-path.d.ts +1 -0
- package/dist/lib/cloud/lock-path.js +5 -0
- package/dist/lib/cloud/lock.d.ts +14 -0
- package/dist/lib/cloud/lock.js +143 -0
- package/dist/lib/cloud/manifest.d.ts +6 -0
- package/dist/lib/cloud/manifest.js +41 -0
- package/dist/lib/cloud/paths.d.ts +20 -0
- package/dist/lib/cloud/paths.js +90 -0
- package/dist/lib/cloud/project-godot-merge.d.ts +32 -0
- package/dist/lib/cloud/project-godot-merge.js +185 -0
- package/dist/lib/cloud/rules.d.ts +39 -0
- package/dist/lib/cloud/rules.js +159 -0
- package/dist/lib/cloud/sync.d.ts +21 -0
- package/dist/lib/cloud/sync.js +518 -0
- package/dist/lib/cloud/transfer.d.ts +23 -0
- package/dist/lib/cloud/transfer.js +184 -0
- package/dist/lib/cloud/types.d.ts +62 -0
- package/dist/lib/cloud/types.js +1 -0
- package/dist/lib/cloud/validate-path.d.ts +23 -0
- package/dist/lib/cloud/validate-path.js +103 -0
- package/dist/lib/engine.d.ts +6 -0
- package/dist/lib/engine.js +36 -1
- package/dist/lib/game-task-plan.d.ts +42 -0
- package/dist/lib/game-task-plan.js +376 -0
- package/dist/mcp/server.js +2 -0
- package/dist/mcp/tools/asset-tools.js +265 -45
- package/dist/mcp/tools/cloud-tools.d.ts +2 -0
- package/dist/mcp/tools/cloud-tools.js +42 -0
- package/dist/mcp/tools/generate-tools.js +101 -13
- package/dist/mcp/tools/project-tools.js +59 -16
- package/gemini-extension.json +3 -3
- package/package.json +16 -5
- package/skills/3d-assets/character-model/SKILL.md +27 -5
- package/skills/3d-assets/environment-kit/SKILL.md +7 -2
- package/skills/3d-assets/organic-model/SKILL.md +4 -3
- package/skills/3d-assets/prop-model/SKILL.md +16 -8
- package/skills/3d-assets/vehicle-model/SKILL.md +4 -3
- package/skills/animation/animation-tree/SKILL.md +2 -0
- package/skills/animation/generate-motion/SKILL.md +25 -4
- package/skills/asset-pipeline/asset-strategy/SKILL.md +3 -2
- package/skills/workflow/mcpupdate/SKILL.md +134 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { readFile } from "fs/promises";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
/**
|
|
4
|
+
* Tracked-set rules (spec section 13). Full-project sync, single mode.
|
|
5
|
+
* Hard excludes cannot be re-included; .summercloudignore can only exclude
|
|
6
|
+
* further. The built-in rule set carries RULES_VERSION; manifests record the
|
|
7
|
+
* rulesVersion that produced them so stale clients can operate restricted.
|
|
8
|
+
*/
|
|
9
|
+
export const RULES_VERSION = 1;
|
|
10
|
+
/** Directory names hard-excluded at any depth. */
|
|
11
|
+
const EXCLUDED_DIR_NAMES = new Set([
|
|
12
|
+
".git",
|
|
13
|
+
".godot",
|
|
14
|
+
"node_modules",
|
|
15
|
+
".next",
|
|
16
|
+
".claude",
|
|
17
|
+
".specstory",
|
|
18
|
+
]);
|
|
19
|
+
/** Root-only excluded directories. */
|
|
20
|
+
const EXCLUDED_ROOT_DIRS = new Set(["android"]);
|
|
21
|
+
/** Exact file basenames hard-excluded everywhere. */
|
|
22
|
+
const EXCLUDED_FILE_NAMES = new Set([".DS_Store", "Thumbs.db", "desktop.ini", "project.godot.bak"]);
|
|
23
|
+
export function isHardExcludedDir(relPath, name) {
|
|
24
|
+
if (EXCLUDED_DIR_NAMES.has(name))
|
|
25
|
+
return true;
|
|
26
|
+
if (EXCLUDED_ROOT_DIRS.has(name) && relPath === name)
|
|
27
|
+
return true;
|
|
28
|
+
// .summer/local/ is machine state; the rest of .summer/** is tracked.
|
|
29
|
+
if (relPath === ".summer/local")
|
|
30
|
+
return true;
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Hard-excluded files. `siblings` is the set of basenames in the same
|
|
35
|
+
* directory, used to detect Godot safe-save temps (name-XXXXXX with the base
|
|
36
|
+
* file present).
|
|
37
|
+
*/
|
|
38
|
+
export function isHardExcludedFile(relPath, name, siblings) {
|
|
39
|
+
if (EXCLUDED_FILE_NAMES.has(name))
|
|
40
|
+
return true;
|
|
41
|
+
if (name.startsWith(".env"))
|
|
42
|
+
return true;
|
|
43
|
+
if (name.endsWith(".translation"))
|
|
44
|
+
return true;
|
|
45
|
+
if (name.endsWith(".tmp"))
|
|
46
|
+
return true;
|
|
47
|
+
if (isGodotSafeSaveTemp(name, siblings))
|
|
48
|
+
return true;
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
/** Godot safe-save writes `name-XXXXXX` (six trailing random chars) next to `name`. */
|
|
52
|
+
export function isGodotSafeSaveTemp(name, siblings) {
|
|
53
|
+
const match = /^(.+)-[A-Za-z0-9]{6}$/.exec(name);
|
|
54
|
+
if (!match)
|
|
55
|
+
return false;
|
|
56
|
+
return siblings.has(match[1]);
|
|
57
|
+
}
|
|
58
|
+
/** True when a manifest key falls under the built-in hard excludes. */
|
|
59
|
+
export function isHardExcludedPath(path) {
|
|
60
|
+
if (path === ".summer/local" || path.startsWith(".summer/local/"))
|
|
61
|
+
return true;
|
|
62
|
+
const segments = path.split("/");
|
|
63
|
+
let prefix = "";
|
|
64
|
+
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
65
|
+
prefix = prefix ? `${prefix}/${segments[i]}` : segments[i];
|
|
66
|
+
if (isHardExcludedDir(prefix, segments[i]))
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
const name = segments[segments.length - 1];
|
|
70
|
+
if (EXCLUDED_DIR_NAMES.has(name))
|
|
71
|
+
return true;
|
|
72
|
+
return isHardExcludedFile(path, name, new Set());
|
|
73
|
+
}
|
|
74
|
+
export async function loadTrackedRules(projectRoot) {
|
|
75
|
+
let raw = "";
|
|
76
|
+
try {
|
|
77
|
+
raw = await readFile(join(projectRoot, ".summercloudignore"), "utf8");
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return { rulesVersion: RULES_VERSION, ignore: [] };
|
|
81
|
+
}
|
|
82
|
+
return { rulesVersion: RULES_VERSION, ignore: parseIgnoreRules(raw) };
|
|
83
|
+
}
|
|
84
|
+
export function parseIgnoreRules(raw) {
|
|
85
|
+
return raw
|
|
86
|
+
.split(/\r?\n/)
|
|
87
|
+
.map((line) => line.trim())
|
|
88
|
+
.filter((line) => line && !line.startsWith("#") && !line.startsWith("!"))
|
|
89
|
+
.map((line) => {
|
|
90
|
+
const directory = line.endsWith("/");
|
|
91
|
+
let cleaned = directory ? line.slice(0, -1) : line;
|
|
92
|
+
const anchored = cleaned.startsWith("/");
|
|
93
|
+
if (anchored)
|
|
94
|
+
cleaned = cleaned.slice(1);
|
|
95
|
+
return { raw: cleaned, directory, anchored, regex: globToRegex(cleaned, anchored) };
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function globToRegex(pattern, anchored) {
|
|
99
|
+
let out = "";
|
|
100
|
+
for (let i = 0; i < pattern.length; i += 1) {
|
|
101
|
+
const ch = pattern[i];
|
|
102
|
+
if (ch === "*") {
|
|
103
|
+
if (pattern[i + 1] === "*") {
|
|
104
|
+
out += ".*";
|
|
105
|
+
i += 1;
|
|
106
|
+
if (pattern[i + 1] === "/")
|
|
107
|
+
i += 1;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
out += "[^/]*";
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (ch === "?") {
|
|
114
|
+
out += "[^/]";
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
out += escapeRegex(ch);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Gitignore semantics: an unanchored pattern without a slash matches at any
|
|
121
|
+
// depth; a pattern containing a slash is root-relative.
|
|
122
|
+
const prefix = anchored || pattern.includes("/") ? "^" : "(^|/)";
|
|
123
|
+
return new RegExp(`${prefix}${out}$`);
|
|
124
|
+
}
|
|
125
|
+
function escapeRegex(value) {
|
|
126
|
+
return value.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
127
|
+
}
|
|
128
|
+
export function isIgnoredByRules(path, isDirectory, rules) {
|
|
129
|
+
for (const rule of rules.ignore) {
|
|
130
|
+
if (rule.regex.test(path)) {
|
|
131
|
+
if (rule.directory && !isDirectory)
|
|
132
|
+
continue;
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
// A directory rule also excludes everything under a matching directory.
|
|
136
|
+
const segments = path.split("/");
|
|
137
|
+
let prefix = "";
|
|
138
|
+
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
139
|
+
prefix = prefix ? `${prefix}/${segments[i]}` : segments[i];
|
|
140
|
+
if (rule.regex.test(prefix))
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Deletion semantics (spec 13): a path may be marked deleted only if it
|
|
148
|
+
* matches the CURRENT tracked rules AND is absent on disk. Paths that merely
|
|
149
|
+
* stopped matching rules are carried forward unchanged.
|
|
150
|
+
*/
|
|
151
|
+
export function isTrackedByCurrentRules(path, rules) {
|
|
152
|
+
if (path === "summer-cloud.json")
|
|
153
|
+
return false;
|
|
154
|
+
if (isHardExcludedPath(path))
|
|
155
|
+
return false;
|
|
156
|
+
if (isIgnoredByRules(path, false, rules))
|
|
157
|
+
return false;
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SyncOptions, SyncResult } from "./types.js";
|
|
2
|
+
/** Jittered 409 backoff schedule. Exported so tests can shrink the delays. */
|
|
3
|
+
export declare const CAS_BACKOFF_MS: number[];
|
|
4
|
+
type Face = "cli" | "mcp" | "engine";
|
|
5
|
+
export interface SyncRunOptions extends SyncOptions {
|
|
6
|
+
face?: Face;
|
|
7
|
+
}
|
|
8
|
+
export declare function cloudInit(options?: SyncRunOptions): Promise<SyncResult>;
|
|
9
|
+
export declare function cloudStatus(options?: SyncRunOptions): Promise<SyncResult>;
|
|
10
|
+
export declare function cloudPush(options?: SyncRunOptions): Promise<SyncResult>;
|
|
11
|
+
export declare function cloudPull(options?: SyncRunOptions): Promise<SyncResult>;
|
|
12
|
+
export declare function cloudConflicts(options?: SyncRunOptions & {
|
|
13
|
+
restorePath?: string;
|
|
14
|
+
set?: string;
|
|
15
|
+
}): Promise<SyncResult>;
|
|
16
|
+
export declare function cloudRestore(options?: SyncRunOptions & {
|
|
17
|
+
version?: number;
|
|
18
|
+
checkpoint?: string;
|
|
19
|
+
}): Promise<SyncResult>;
|
|
20
|
+
export declare function cloudCheckpoints(options?: SyncRunOptions): Promise<SyncResult>;
|
|
21
|
+
export {};
|