summer-engine 4.0.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +3 -2
- package/.codex-plugin/plugin.json +15 -11
- package/.cursor-plugin/plugin.json +5 -3
- package/.factory-plugin/plugin.json +3 -2
- package/AGENTS.md +2 -2
- package/CHANGELOG.md +48 -0
- package/README.md +21 -10
- package/dist/cli/command-usage.d.ts +8 -0
- package/dist/cli/command-usage.js +22 -0
- package/dist/cli/commands/config.js +3 -2
- package/dist/cli/commands/create.js +12 -3
- package/dist/cli/commands/list.d.ts +5 -0
- package/dist/cli/commands/list.js +30 -13
- package/dist/cli/commands/login.js +1 -1
- package/dist/cli/commands/memory.js +6 -2
- package/dist/cli/commands/ops.d.ts +20 -3
- package/dist/cli/commands/ops.js +60 -27
- package/dist/cli/commands/setup.d.ts +2 -0
- package/dist/cli/commands/setup.js +219 -16
- package/dist/cli/commands/skills.js +20 -7
- package/dist/cli/commands/status.d.ts +26 -0
- package/dist/cli/commands/status.js +36 -21
- package/dist/cli/commands/tool.js +4 -0
- package/dist/cli/index.js +2 -0
- package/dist/core/agent-host.d.ts +3 -0
- package/dist/core/agent-host.js +8 -2
- package/dist/core/capabilities/apps.d.ts +10 -10
- package/dist/core/capabilities/audit/args.d.ts +6 -6
- package/dist/core/capabilities/fabricate-mesh.d.ts +2 -2
- package/dist/core/capabilities/game-task-plan.d.ts +2 -2
- package/dist/core/capabilities/hdri-import.d.ts +2 -2
- package/dist/core/capabilities/motion-generation.d.ts +2 -2
- package/dist/core/capabilities/placement.d.ts +23 -23
- package/dist/core/capabilities/runtime-control.d.ts +38 -38
- package/dist/core/capabilities/seeing/args.d.ts +16 -16
- package/dist/core/capabilities/ui-control.d.ts +2 -2
- package/dist/core/capabilities/world-snapshot.d.ts +4 -4
- package/dist/core/cli-usage-beacon.d.ts +1 -0
- package/dist/core/cli-usage-beacon.js +18 -0
- package/dist/core/cli-usage.d.ts +49 -0
- package/dist/core/cli-usage.js +108 -0
- package/dist/core/feedback/client.d.ts +1 -1
- package/dist/core/feedback/client.js +3 -2
- package/dist/core/hosted-mcp.d.ts +7 -1
- package/dist/core/hosted-mcp.js +6 -4
- package/dist/core/library-search.d.ts +2 -2
- package/dist/core/ops/areas.d.ts +11 -0
- package/dist/core/ops/areas.js +24 -0
- package/dist/core/ops/catalog.d.ts +11 -0
- package/dist/core/ops/catalog.js +24 -1
- package/dist/core/ops/cloud.d.ts +10 -2
- package/dist/core/ops/cloud.js +51 -28
- package/dist/core/ops/contract.d.ts +2 -1
- package/dist/core/ops/contract.js +2 -10
- package/dist/core/ops/public-catalog.d.ts +48 -0
- package/dist/core/ops/public-catalog.js +56 -0
- package/dist/core/ops/search.d.ts +0 -1
- package/dist/core/ops/search.js +169 -37
- package/dist/core/telemetry.d.ts +10 -0
- package/dist/core/telemetry.js +58 -29
- package/dist/installer/agent-config.js +5 -0
- package/dist/installer/agent-table.d.ts +9 -0
- package/dist/installer/agent-table.js +23 -2
- package/dist/installer/cli-permissions.d.ts +65 -0
- package/dist/installer/cli-permissions.js +182 -0
- package/dist/installer/setup.d.ts +2 -0
- package/dist/installer/setup.js +3 -0
- package/dist/installer/skills-refresh.d.ts +29 -0
- package/dist/installer/skills-refresh.js +261 -0
- package/dist/installer/version-check.d.ts +22 -2
- package/dist/installer/version-check.js +66 -9
- package/dist/mcp/ops-surface.js +16 -6
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.js +38 -8
- package/dist/project-memory/agent-instructions.d.ts +47 -0
- package/dist/project-memory/agent-instructions.js +226 -0
- package/gemini-extension.json +3 -2
- package/integrations/README.md +1 -1
- package/integrations/claude/README.md +6 -0
- package/integrations/claude/manifest-target.json +4 -0
- package/integrations/gemini/README.md +11 -0
- package/integrations/windsurf/README.md +1 -1
- package/library/skills/3d-lighting/SKILL.md +16 -0
- package/library/skills/README.md +5 -4
- package/library/skills/adaptive-music/SKILL.md +21 -0
- package/library/skills/agent-playtesting/SKILL.md +22 -0
- package/library/skills/ai-characters-in-games/SKILL.md +15 -0
- package/library/skills/ambient-bed/SKILL.md +16 -0
- package/library/skills/animated-loop/SKILL.md +19 -0
- package/library/skills/animation-tree/SKILL.md +26 -0
- package/library/skills/art-direction/SKILL.md +14 -0
- package/library/skills/asset-strategy/SKILL.md +30 -0
- package/library/skills/audio-direction/SKILL.md +16 -0
- package/library/skills/auto-fire-targeting/SKILL.md +14 -0
- package/library/skills/brainstorm-game/SKILL.md +13 -0
- package/library/skills/browse-templates/SKILL.md +10 -0
- package/library/skills/camera-rigs/SKILL.md +20 -0
- package/library/skills/character-animation-wiring/SKILL.md +24 -0
- package/library/skills/character-model/SKILL.md +28 -0
- package/library/skills/character-movement/SKILL.md +24 -0
- package/library/skills/character-portrait/SKILL.md +15 -0
- package/library/skills/cinematic-cutscene/SKILL.md +21 -0
- package/library/skills/combat-basics/SKILL.md +19 -0
- package/library/skills/compatibility-renderer-traps/SKILL.md +11 -0
- package/library/skills/concept-art/SKILL.md +13 -0
- package/library/skills/concept-to-level/SKILL.md +20 -1
- package/library/skills/concept-to-level/resource.yaml +2 -2
- package/library/skills/create-asset-sheet/SKILL.md +18 -0
- package/library/skills/debug/SKILL.md +32 -0
- package/library/skills/debugging-game-feel/SKILL.md +12 -0
- package/library/skills/design-level/SKILL.md +17 -0
- package/library/skills/design-mechanic/SKILL.md +17 -0
- package/library/skills/design-npc/SKILL.md +21 -0
- package/library/skills/diagnosing-perf-regressions/SKILL.md +12 -0
- package/library/skills/driving-the-editor-ui/SKILL.md +23 -0
- package/library/skills/environment-kit/SKILL.md +23 -0
- package/library/skills/export-and-ship/SKILL.md +23 -0
- package/library/skills/fabricating-assets/SKILL.md +23 -0
- package/library/skills/facial-and-lipsync/SKILL.md +22 -0
- package/library/skills/fps-controller/SKILL.md +17 -0
- package/library/skills/game-feel/SKILL.md +26 -0
- package/library/skills/gameskill/SKILL.md +11 -0
- package/library/skills/gdscript-patterns/SKILL.md +15 -0
- package/library/skills/generate-motion/SKILL.md +21 -0
- package/library/skills/godogen-visual-proof-game-generation/SKILL.md +17 -0
- package/library/skills/grow-analytics/SKILL.md +10 -0
- package/library/skills/headless-scripting/SKILL.md +13 -0
- package/library/skills/in-game-purchases/SKILL.md +11 -0
- package/library/skills/instantiate-asset-pack/SKILL.md +17 -0
- package/library/skills/make-game/SKILL.md +29 -0
- package/library/skills/multiplayer/SKILL.md +12 -0
- package/library/skills/multiplayer-movement/SKILL.md +18 -0
- package/library/skills/multiplayer-project/SKILL.md +17 -0
- package/library/skills/multiplayer-publish/SKILL.md +17 -5
- package/library/skills/multiplayer-state/SKILL.md +16 -0
- package/library/skills/multiplayer-testing/SKILL.md +15 -0
- package/library/skills/music-track/SKILL.md +16 -0
- package/library/skills/navigate-summer/SKILL.md +15 -0
- package/library/skills/new-project/SKILL.md +11 -0
- package/library/skills/organic-model/SKILL.md +24 -0
- package/library/skills/pixel-art/SKILL.md +15 -0
- package/library/skills/play/SKILL.md +18 -0
- package/library/skills/playtesting-a-feature/SKILL.md +23 -0
- package/library/skills/procedural-animation/SKILL.md +18 -0
- package/library/skills/prop-model/SKILL.md +23 -0
- package/library/skills/publish-your-game/SKILL.md +27 -0
- package/library/skills/release-readiness/SKILL.md +12 -0
- package/library/skills/remote-deploy/SKILL.md +14 -0
- package/library/skills/retarget/SKILL.md +20 -0
- package/library/skills/running-in-the-cloud/SKILL.md +10 -0
- package/library/skills/save-load/SKILL.md +15 -0
- package/library/skills/scene-composition/SKILL.md +17 -0
- package/library/skills/scene-hierarchy-design/SKILL.md +24 -0
- package/library/skills/scene-scripting/SKILL.md +30 -0
- package/library/skills/scene-to-level/SKILL.md +22 -0
- package/library/skills/skill-test/SKILL.md +10 -0
- package/library/skills/skybox-panorama/SKILL.md +20 -0
- package/library/skills/sound-effect/SKILL.md +23 -0
- package/library/skills/spatial-placement/SKILL.md +30 -0
- package/library/skills/sprite-sheet/SKILL.md +23 -0
- package/library/skills/store-art/SKILL.md +11 -0
- package/library/skills/store-listing/SKILL.md +10 -0
- package/library/skills/summer-analytics/SKILL.md +15 -0
- package/library/skills/summer-apps/SKILL.md +29 -0
- package/library/skills/summer-assets/SKILL.md +31 -1
- package/library/skills/summer-assets/resource.yaml +2 -2
- package/library/skills/summer-cli/SKILL.md +133 -0
- package/library/skills/summer-cli/resource.yaml +31 -0
- package/library/skills/summer-friends/SKILL.md +14 -0
- package/library/skills/summer-leaderboards/SKILL.md +16 -0
- package/library/skills/summer-match-results/SKILL.md +17 -0
- package/library/skills/summer-matchmaking/SKILL.md +17 -0
- package/library/skills/summer-parties/SKILL.md +14 -0
- package/library/skills/summer-player-data/SKILL.md +14 -0
- package/library/skills/summer-store/SKILL.md +15 -0
- package/library/skills/summer-world-chat/SKILL.md +14 -0
- package/library/skills/summer-world-saves/SKILL.md +14 -0
- package/library/skills/text-to-motion/SKILL.md +15 -0
- package/library/skills/tileable-texture/SKILL.md +18 -0
- package/library/skills/trailer-shot/SKILL.md +18 -0
- package/library/skills/tune-performance/SKILL.md +26 -0
- package/library/skills/ui-basics/SKILL.md +14 -0
- package/library/skills/ui-graphics/SKILL.md +17 -0
- package/library/skills/use-widget-asset/SKILL.md +14 -0
- package/library/skills/using-summer/SKILL.md +26 -0
- package/library/skills/using-summer/resource.yaml +2 -1
- package/library/skills/vehicle-model/SKILL.md +27 -0
- package/library/skills/verifying-scenes/SKILL.md +29 -0
- package/library/skills/vfx-dissolve/SKILL.md +19 -0
- package/library/skills/vfx-fire/SKILL.md +26 -0
- package/library/skills/vfx-hit-spark/SKILL.md +23 -0
- package/library/skills/vfx-lightning/SKILL.md +23 -0
- package/library/skills/vfx-magic-glow/SKILL.md +23 -0
- package/library/skills/vfx-muzzle-flash/SKILL.md +23 -0
- package/library/skills/vfx-smoke/SKILL.md +26 -0
- package/library/skills/vfx-water-ripple/SKILL.md +23 -0
- package/library/skills/voice-line/SKILL.md +16 -0
- package/library/skills/web-and-touch-input/SKILL.md +19 -0
- package/library/skills/web-compatibility-look/SKILL.md +20 -0
- package/library/skills/world-building-3d/SKILL.md +28 -0
- package/package.json +3 -2
- package/registry/generated/counts.json +2 -2
- package/registry/generated/gemini-extension.json +3 -2
- package/registry/generated/index.json +157 -118
- package/registry/generated/marketplace.claude.json +2 -2
- package/registry/generated/plugin.claude-directory.json +168 -0
- package/registry/generated/plugin.claude.json +3 -2
- package/registry/generated/plugin.codex.json +15 -11
- package/registry/generated/plugin.cursor.json +5 -3
- package/registry/generated/plugin.factory.json +3 -2
- package/registry/generated/server.json +11 -2
- package/registry/generated/skills-index.md +5 -4
- package/registry/generated/skills-registry.json +16 -2
- package/registry/operations/legacy-names.json +35 -0
- package/registry/operations/public-catalog.json +33160 -0
|
@@ -98,12 +98,12 @@ export declare const searchLibraryInputSchema: z.ZodObject<{
|
|
|
98
98
|
include_preview: z.ZodOptional<z.ZodBoolean>;
|
|
99
99
|
}, "strict", z.ZodTypeAny, {
|
|
100
100
|
query: string;
|
|
101
|
-
kinds?: ("template" | "tool" | "
|
|
101
|
+
kinds?: ("template" | "tool" | "skill" | "reference" | "example" | "collection")[] | undefined;
|
|
102
102
|
limit?: number | undefined;
|
|
103
103
|
include_preview?: boolean | undefined;
|
|
104
104
|
}, {
|
|
105
105
|
query: string;
|
|
106
|
-
kinds?: ("template" | "tool" | "
|
|
106
|
+
kinds?: ("template" | "tool" | "skill" | "reference" | "example" | "collection")[] | undefined;
|
|
107
107
|
limit?: number | undefined;
|
|
108
108
|
include_preview?: boolean | undefined;
|
|
109
109
|
}>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where operations live and run, the part scripts/ needs too. No imports:
|
|
3
|
+
* scripts/validate-library loads this file as plain TypeScript to write the
|
|
4
|
+
* shell command of each tool a skill names.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Areas with operations today: each is one `summer <area> <action>` command
|
|
8
|
+
* (src/cli/commands/ops.ts). CLI command words stay out of this list.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CLI_AREAS: readonly ["team", "profile", "docs", "assets", "makers", "jobs", "projects", "plans", "games", "store", "jams", "pricing", "analytics", "experiments", "marketing", "content", "players", "economy", "inbox", "apps", "studio", "chats", "stories", "plugins", "engine", "account"];
|
|
11
|
+
export declare function isLocalOp(op: string): boolean;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where operations live and run, the part scripts/ needs too. No imports:
|
|
3
|
+
* scripts/validate-library loads this file as plain TypeScript to write the
|
|
4
|
+
* shell command of each tool a skill names.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Areas with operations today: each is one `summer <area> <action>` command
|
|
8
|
+
* (src/cli/commands/ops.ts). CLI command words stay out of this list.
|
|
9
|
+
*/
|
|
10
|
+
export const CLI_AREAS = [
|
|
11
|
+
"team", "profile", "docs", "assets", "makers", "jobs", "projects", "plans", "games", "store", "jams", "pricing",
|
|
12
|
+
"analytics", "experiments", "marketing", "content", "players", "economy", "inbox", "apps", "studio", "chats", "stories",
|
|
13
|
+
"plugins", "engine", "account",
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Operations that run in this package: everything in `engine`, the library
|
|
17
|
+
* (`docs`, apart from the Studio workflows, which are cloud), opening a
|
|
18
|
+
* page or an editor surface, docking an App in the editor, and uploading a
|
|
19
|
+
* local export. Everything else runs on the hosted server.
|
|
20
|
+
*/
|
|
21
|
+
const LOCAL_OPS = new Set(["docs.search", "docs.read", "docs.feedback", "docs.plan", "docs.engine_api", "studio.open", "apps.dock", "apps.publish_folder", "store.upload_file"]);
|
|
22
|
+
export function isLocalOp(op) {
|
|
23
|
+
return op.startsWith("engine.") || LOCAL_OPS.has(op);
|
|
24
|
+
}
|
|
@@ -18,6 +18,10 @@ export interface CatalogEntry {
|
|
|
18
18
|
legacy?: string[];
|
|
19
19
|
/** The exact input JSON Schema (search results and describe carry it). */
|
|
20
20
|
input?: Record<string, unknown>;
|
|
21
|
+
/** A cloud operation listed from the shipped catalog while no one is signed in: it runs after `summer login`. */
|
|
22
|
+
needsSignIn?: true;
|
|
23
|
+
/** Search words only, never printed: the library's topics for docs.search ("add multiplayer" is a how-to). */
|
|
24
|
+
topics?: string[];
|
|
21
25
|
}
|
|
22
26
|
/**
|
|
23
27
|
* The operations this package runs (engine and local), from the shipped
|
|
@@ -32,6 +36,13 @@ export declare function localInputSchema(op: string): Record<string, unknown> |
|
|
|
32
36
|
* A local operation in the contract's wire form (registry/schemas/operation.schema.json):
|
|
33
37
|
* what ops.describe answers and what the contract test validates.
|
|
34
38
|
*/
|
|
39
|
+
/**
|
|
40
|
+
* The operation when it is a real one (this package runs it, or the shipped
|
|
41
|
+
* catalog lists it), else null. Usage lines name an operation only through
|
|
42
|
+
* this, so a word someone typed (`summer engine my-secret-game`) never
|
|
43
|
+
* leaves the machine as an operation name.
|
|
44
|
+
*/
|
|
45
|
+
export declare function knownOp(op: string | null | undefined): string | null;
|
|
35
46
|
export declare function localWireForm(op: string): Record<string, unknown> | null;
|
|
36
47
|
/**
|
|
37
48
|
* The first problem a JSON Schema's top level finds in an input: a missing
|
package/dist/core/ops/catalog.js
CHANGED
|
@@ -5,6 +5,7 @@ import { loadLibraryIndex } from "../library-search.js";
|
|
|
5
5
|
import { PACKAGE_ROOT } from "../package-root.js";
|
|
6
6
|
import { CONTRACT_VERSION, isLocalOp, legacyNames, LOCAL_RUNNERS, mcpNameOf, MIN_APPROVAL } from "./contract.js";
|
|
7
7
|
import { ENGINE_SPLIT_OPS, engineOpDef, isSplitOp, splitInputSchema } from "./engine.js";
|
|
8
|
+
import { shippedTitle } from "./public-catalog.js";
|
|
8
9
|
/** A local tool's effect from its registry authority: scene edits and project files are writes. */
|
|
9
10
|
function effectOf(authority) {
|
|
10
11
|
if (authority?.publish)
|
|
@@ -26,7 +27,8 @@ function entryFor(op, toolName, tool, legacy) {
|
|
|
26
27
|
const summary = def?.summary ?? (tool.summary ?? "").slice(0, 300);
|
|
27
28
|
return {
|
|
28
29
|
name: op,
|
|
29
|
-
title:
|
|
30
|
+
// The hosted catalog's title when it has the op too (docs.search: "Search Summer docs", not "Search").
|
|
31
|
+
title: def?.title ?? shippedTitle(op) ?? titleOf(summary, op),
|
|
30
32
|
summary,
|
|
31
33
|
effect,
|
|
32
34
|
approval: MIN_APPROVAL[effect],
|
|
@@ -67,9 +69,19 @@ export function localEntries() {
|
|
|
67
69
|
continue;
|
|
68
70
|
out.set(row.op, entryFor(row.op, toolName, tool, name));
|
|
69
71
|
}
|
|
72
|
+
const docsSearch = out.get("docs.search");
|
|
73
|
+
if (docsSearch)
|
|
74
|
+
out.set("docs.search", { ...docsSearch, topics: libraryTopics() });
|
|
70
75
|
entriesCache = [...out.values()];
|
|
71
76
|
return entriesCache;
|
|
72
77
|
}
|
|
78
|
+
/** The words of every skill, template and example slug (multiplayer, fps, lighting...): what the library teaches. */
|
|
79
|
+
function libraryTopics() {
|
|
80
|
+
const slugs = loadLibraryIndex()
|
|
81
|
+
.filter((entry) => entry.kind !== "tool" && entry.kind !== "reference")
|
|
82
|
+
.flatMap((entry) => entry.id.replace(/^[a-z]+\//, "").split("-"));
|
|
83
|
+
return [...new Set(slugs)].filter((word) => word.length > 2 && !/^\d/.test(word));
|
|
84
|
+
}
|
|
73
85
|
function descriptorSchema(toolName) {
|
|
74
86
|
const record = loadLibraryIndex().find((candidate) => candidate.kind === "tool" && candidate.mcp_tool_name === toolName);
|
|
75
87
|
const slug = record?.id.replace(/^tool\//, "");
|
|
@@ -95,6 +107,17 @@ export function localInputSchema(op) {
|
|
|
95
107
|
* A local operation in the contract's wire form (registry/schemas/operation.schema.json):
|
|
96
108
|
* what ops.describe answers and what the contract test validates.
|
|
97
109
|
*/
|
|
110
|
+
/**
|
|
111
|
+
* The operation when it is a real one (this package runs it, or the shipped
|
|
112
|
+
* catalog lists it), else null. Usage lines name an operation only through
|
|
113
|
+
* this, so a word someone typed (`summer engine my-secret-game`) never
|
|
114
|
+
* leaves the machine as an operation name.
|
|
115
|
+
*/
|
|
116
|
+
export function knownOp(op) {
|
|
117
|
+
if (!op)
|
|
118
|
+
return null;
|
|
119
|
+
return localEntries().some((entry) => entry.name === op) || shippedTitle(op) !== undefined ? op : null;
|
|
120
|
+
}
|
|
98
121
|
export function localWireForm(op) {
|
|
99
122
|
const entry = localEntries().find((candidate) => candidate.name === op);
|
|
100
123
|
if (!entry)
|
package/dist/core/ops/cloud.d.ts
CHANGED
|
@@ -42,10 +42,18 @@ export declare function hostedCallFailure(error: unknown, call: {
|
|
|
42
42
|
export declare function answerOfHosted(result: Record<string, unknown>): Answer;
|
|
43
43
|
/** Runs a tool on the hosted v4 surface: the MCP's mounted client or the CLI's one-shot call. */
|
|
44
44
|
export type HostedCall = (name: string, args: Record<string, unknown>) => Promise<Record<string, unknown>>;
|
|
45
|
+
/**
|
|
46
|
+
* ops.describe of a cloud operation when Summer's server could not answer it
|
|
47
|
+
* (no sign-in, no network): the operation from the shipped catalog, with a
|
|
48
|
+
* warning. Null when the catalog has no such operation; the failure stands.
|
|
49
|
+
*/
|
|
50
|
+
export declare function describeFromShipped(name: string, failure: Answer): Answer | null;
|
|
45
51
|
/**
|
|
46
52
|
* One ranked list of local and cloud operations for a plain-words query.
|
|
47
|
-
*
|
|
48
|
-
*
|
|
53
|
+
* Every cloud operation comes from the shipped catalog (public-catalog.ts),
|
|
54
|
+
* so search finds it signed out, marked needsSignIn; signed in, the server's
|
|
55
|
+
* own search lays its live rows over the shipped ones (and adds newer
|
|
56
|
+
* operations). Local hits carry their input schema from the library descriptor.
|
|
49
57
|
*/
|
|
50
58
|
export declare function searchEverywhere(query: string, filters: {
|
|
51
59
|
area?: string;
|
package/dist/core/ops/cloud.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { defaultHostedConnectDependencies, hostedConnectFailure, HostedUnreachableError, httpStatusOf } from "../hosted-mcp.js";
|
|
2
2
|
import { OAuthError, resolveMcpResourceUrl } from "../oauth.js";
|
|
3
3
|
import { localEntries, localInputSchema } from "./catalog.js";
|
|
4
|
-
import { errorAnswer, isLocalOp } from "./contract.js";
|
|
4
|
+
import { errorAnswer, isLocalOp, resolveOpName } from "./contract.js";
|
|
5
|
+
import { shippedCloudEntries, shippedWireForm } from "./public-catalog.js";
|
|
5
6
|
import { withOutField } from "./save-files.js";
|
|
6
|
-
import {
|
|
7
|
+
import { searchEntries } from "./search.js";
|
|
7
8
|
/**
|
|
8
9
|
* The hosted Summer server's v4 surface: the same address with `?surface=v4`
|
|
9
10
|
* (it keeps serving 3.x tools to every request that does not ask). Cloud
|
|
@@ -139,37 +140,59 @@ export function answerOfHosted(result) {
|
|
|
139
140
|
}
|
|
140
141
|
return result.isError === true ? errorAnswer("unavailable", first.slice(0, 300) || "The Summer server did not answer.") : { ok: true, status: "done", result: { text: first } };
|
|
141
142
|
}
|
|
143
|
+
/** Failures that mean Summer's server did not describe the operation, so the shipped catalog may. */
|
|
144
|
+
const DID_NOT_ANSWER = new Set(["not_signed_in", "forbidden", "rate_limited", "unavailable"]);
|
|
145
|
+
/**
|
|
146
|
+
* ops.describe of a cloud operation when Summer's server could not answer it
|
|
147
|
+
* (no sign-in, no network): the operation from the shipped catalog, with a
|
|
148
|
+
* warning. Null when the catalog has no such operation; the failure stands.
|
|
149
|
+
*/
|
|
150
|
+
export function describeFromShipped(name, failure) {
|
|
151
|
+
// The server's own answer stands (not_found: it no longer has the operation).
|
|
152
|
+
if (failure.ok || !DID_NOT_ANSWER.has(failure.error.code))
|
|
153
|
+
return null;
|
|
154
|
+
const operation = shippedWireForm(resolveOpName(name));
|
|
155
|
+
if (!operation)
|
|
156
|
+
return null;
|
|
157
|
+
const warning = failure.error.code === "not_signed_in"
|
|
158
|
+
? "Not signed in: this is the catalog in this version; the operation runs after `summer login`."
|
|
159
|
+
: `Summer's server did not answer (${failure.error.message}); this is the catalog in this version.`;
|
|
160
|
+
return { ok: true, status: "done", result: { operation }, warnings: [warning] };
|
|
161
|
+
}
|
|
162
|
+
/** The warning when cloud operations come from the shipped catalog, and whether that is because no one is signed in. */
|
|
163
|
+
function shippedReason(answer) {
|
|
164
|
+
if (!answer.ok && answer.error.code === "not_signed_in") {
|
|
165
|
+
return { warning: "Not signed in: cloud operations are listed from the catalog in this version and run after `summer login` (needsSignIn).", signedOut: true };
|
|
166
|
+
}
|
|
167
|
+
return { warning: `Cloud operations are listed from the catalog in this version; Summer's server did not search: ${answer.ok ? "no answer" : answer.error.message}`, signedOut: false };
|
|
168
|
+
}
|
|
142
169
|
/**
|
|
143
170
|
* One ranked list of local and cloud operations for a plain-words query.
|
|
144
|
-
*
|
|
145
|
-
*
|
|
171
|
+
* Every cloud operation comes from the shipped catalog (public-catalog.ts),
|
|
172
|
+
* so search finds it signed out, marked needsSignIn; signed in, the server's
|
|
173
|
+
* own search lays its live rows over the shipped ones (and adds newer
|
|
174
|
+
* operations). Local hits carry their input schema from the library descriptor.
|
|
146
175
|
*/
|
|
147
176
|
export async function searchEverywhere(query, filters, call, isDirect = () => false) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
input: localInputSchema(entry.name) ?? { type: "object" },
|
|
151
|
-
mcpTool: entry.mcpTool && isDirect(entry.mcpTool) ? entry.mcpTool : undefined,
|
|
152
|
-
}));
|
|
153
|
-
let cloud = [];
|
|
154
|
-
let warning = null;
|
|
177
|
+
let live = [];
|
|
178
|
+
let reason = null;
|
|
155
179
|
try {
|
|
156
|
-
const answer = answerOfHosted(await call("summer_search", { query, ...(filters.area ? { area: filters.area } : {}), limit:
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
.map((entry) => (entry.input ? { ...entry, input: withOutField(entry.name, entry.input) } : entry));
|
|
162
|
-
}
|
|
163
|
-
else if (!answer.ok)
|
|
164
|
-
warning = `Cloud operations were not searched: ${answer.error.message}`;
|
|
180
|
+
const answer = answerOfHosted(await call("summer_search", { query, ...(filters.area ? { area: filters.area } : {}), limit: 20 }));
|
|
181
|
+
if (answer.ok && answer.status === "done")
|
|
182
|
+
live = (answer.result.items ?? []).filter((entry) => !isLocalOp(entry.name));
|
|
183
|
+
else
|
|
184
|
+
reason = shippedReason(answer);
|
|
165
185
|
}
|
|
166
186
|
catch (error) {
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
.
|
|
173
|
-
|
|
174
|
-
|
|
187
|
+
reason = shippedReason(hostedCallFailure(error, { op: "ops.search", read: true }));
|
|
188
|
+
}
|
|
189
|
+
const cloud = new Map(shippedCloudEntries().map((entry) => [entry.name, reason?.signedOut ? { ...entry, needsSignIn: true } : entry]));
|
|
190
|
+
// The operations that save files take `out` here (save-files.ts), so their input shows it.
|
|
191
|
+
for (const entry of live) {
|
|
192
|
+
cloud.set(entry.name, { ...cloud.get(entry.name), ...entry, ...(entry.input ? { input: withOutField(entry.name, entry.input) } : {}) });
|
|
193
|
+
}
|
|
194
|
+
const items = searchEntries([...localEntries(), ...cloud.values()], query, filters).map(({ topics: _topics, ...entry }) => isLocalOp(entry.name)
|
|
195
|
+
? { ...entry, input: localInputSchema(entry.name) ?? { type: "object" }, mcpTool: entry.mcpTool && isDirect(entry.mcpTool) ? entry.mcpTool : undefined }
|
|
196
|
+
: entry);
|
|
197
|
+
return { items, warning: reason?.warning ?? null };
|
|
175
198
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isLocalOp } from "./areas.js";
|
|
1
2
|
/**
|
|
2
3
|
* The Summer operation catalog, the part this package needs (contract 1).
|
|
3
4
|
* Every Summer operation has one name (`area.action`), one effect, one
|
|
@@ -100,7 +101,7 @@ export declare function resolveOpName(name: string): string;
|
|
|
100
101
|
* (apps.publish_folder reads a folder on disk; apps.publish takes files).
|
|
101
102
|
*/
|
|
102
103
|
export declare const LOCAL_RUNNERS: Readonly<Record<string, string>>;
|
|
103
|
-
export
|
|
104
|
+
export { isLocalOp };
|
|
104
105
|
/**
|
|
105
106
|
* The local 3.x tools that run an operation here, first choice first: the
|
|
106
107
|
* tool the op was renamed from before the tools merged into it.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { PACKAGE_ROOT } from "../package-root.js";
|
|
4
|
+
import { isLocalOp } from "./areas.js";
|
|
4
5
|
/**
|
|
5
6
|
* The Summer operation catalog, the part this package needs (contract 1).
|
|
6
7
|
* Every Summer operation has one name (`area.action`), one effect, one
|
|
@@ -65,22 +66,13 @@ export function resolveOpName(name) {
|
|
|
65
66
|
const trimmed = name.trim();
|
|
66
67
|
return legacyNames()[trimmed]?.op ?? trimmed;
|
|
67
68
|
}
|
|
68
|
-
/**
|
|
69
|
-
* Operations that run in this package: everything in `engine`, the library
|
|
70
|
-
* (`docs`, apart from the Studio workflows, which are cloud), opening a
|
|
71
|
-
* page or an editor surface, docking an App in the editor, and uploading a
|
|
72
|
-
* local export. Everything else runs on the hosted server.
|
|
73
|
-
*/
|
|
74
|
-
const LOCAL_OPS = new Set(["docs.search", "docs.read", "docs.feedback", "docs.plan", "docs.engine_api", "studio.open", "apps.dock", "apps.publish_folder", "store.upload_file"]);
|
|
75
69
|
/**
|
|
76
70
|
* Local operations a 3.x tool runs although legacy-names.json maps that
|
|
77
71
|
* tool to a cloud operation: the local-only input is its own operation
|
|
78
72
|
* (apps.publish_folder reads a folder on disk; apps.publish takes files).
|
|
79
73
|
*/
|
|
80
74
|
export const LOCAL_RUNNERS = { "apps.publish_folder": "summer_app_publish" };
|
|
81
|
-
export
|
|
82
|
-
return op.startsWith("engine.") || LOCAL_OPS.has(op);
|
|
83
|
-
}
|
|
75
|
+
export { isLocalOp };
|
|
84
76
|
/**
|
|
85
77
|
* The local 3.x tools that run an operation here, first choice first: the
|
|
86
78
|
* tool the op was renamed from before the tools merged into it.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { CatalogEntry } from "./catalog.js";
|
|
2
|
+
import { type Approval, type Effect } from "./contract.js";
|
|
3
|
+
export interface PublicOperation {
|
|
4
|
+
name: string;
|
|
5
|
+
title: string;
|
|
6
|
+
summary: string;
|
|
7
|
+
effect: Effect;
|
|
8
|
+
approval: Approval;
|
|
9
|
+
permission: string;
|
|
10
|
+
provider: "cloud";
|
|
11
|
+
auth: string;
|
|
12
|
+
status: "stable" | "preview" | "deprecated";
|
|
13
|
+
since: string;
|
|
14
|
+
mcpTool: string;
|
|
15
|
+
direct: string[];
|
|
16
|
+
idempotencyKey?: "required" | "optional";
|
|
17
|
+
job?: {
|
|
18
|
+
typicalSeconds: number;
|
|
19
|
+
};
|
|
20
|
+
input: Record<string, unknown>;
|
|
21
|
+
output: Record<string, unknown>;
|
|
22
|
+
legacy?: string[];
|
|
23
|
+
tags?: string[];
|
|
24
|
+
examples: Array<{
|
|
25
|
+
input: Record<string, unknown>;
|
|
26
|
+
note: string;
|
|
27
|
+
}>;
|
|
28
|
+
deprecated?: {
|
|
29
|
+
replacedBy: string;
|
|
30
|
+
after: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export interface PublicCatalog {
|
|
34
|
+
contract: number;
|
|
35
|
+
operations: PublicOperation[];
|
|
36
|
+
/** The operations the server leaves to this package (engine and local ones), with their 3.x names. */
|
|
37
|
+
localOperations: Array<{
|
|
38
|
+
name: string;
|
|
39
|
+
legacy: string[];
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
42
|
+
export declare function publicCatalog(): PublicCatalog;
|
|
43
|
+
/** The cloud operations as search rows; the ones that save files show `out` in their input. */
|
|
44
|
+
export declare function shippedCloudEntries(): CatalogEntry[];
|
|
45
|
+
/** The catalog's title of an operation, for the local ones it lists too. */
|
|
46
|
+
export declare function shippedTitle(op: string): string | undefined;
|
|
47
|
+
/** One cloud operation as ops.describe answers it, from the shipped catalog; null when it has no such row. */
|
|
48
|
+
export declare function shippedWireForm(op: string): Record<string, unknown> | null;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { PACKAGE_ROOT } from "../package-root.js";
|
|
4
|
+
import { CONTRACT_VERSION, isLocalOp } from "./contract.js";
|
|
5
|
+
import { withOutField } from "./save-files.js";
|
|
6
|
+
/**
|
|
7
|
+
* The hosted Summer server's public operation catalog, shipped in this
|
|
8
|
+
* package: registry/operations/public-catalog.json, a byte copy of the
|
|
9
|
+
* server's own file (`npm run sync:catalog`; `-- --check` fails when it is
|
|
10
|
+
* behind). Search and describe list every cloud operation from it with no
|
|
11
|
+
* sign-in; a signed-in search lays the server's live rows over it.
|
|
12
|
+
*/
|
|
13
|
+
const PUBLIC_CATALOG_FILE = join("registry", "operations", "public-catalog.json");
|
|
14
|
+
let catalogCache = null;
|
|
15
|
+
export function publicCatalog() {
|
|
16
|
+
if (catalogCache)
|
|
17
|
+
return catalogCache;
|
|
18
|
+
try {
|
|
19
|
+
catalogCache = JSON.parse(readFileSync(join(PACKAGE_ROOT, PUBLIC_CATALOG_FILE), "utf8"));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
catalogCache = { contract: CONTRACT_VERSION, operations: [], localOperations: [] };
|
|
23
|
+
}
|
|
24
|
+
return catalogCache;
|
|
25
|
+
}
|
|
26
|
+
/** The cloud operations as search rows; the ones that save files show `out` in their input. */
|
|
27
|
+
export function shippedCloudEntries() {
|
|
28
|
+
return publicCatalog()
|
|
29
|
+
.operations.filter((op) => !isLocalOp(op.name))
|
|
30
|
+
.map((op) => ({
|
|
31
|
+
name: op.name,
|
|
32
|
+
title: op.title,
|
|
33
|
+
summary: op.summary,
|
|
34
|
+
effect: op.effect,
|
|
35
|
+
approval: op.approval,
|
|
36
|
+
provider: "cloud",
|
|
37
|
+
status: op.status,
|
|
38
|
+
available: true,
|
|
39
|
+
...(op.tags?.length ? { tags: op.tags } : {}),
|
|
40
|
+
...(op.legacy?.length ? { legacy: op.legacy } : {}),
|
|
41
|
+
input: withOutField(op.name, op.input),
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
/** The catalog's title of an operation, for the local ones it lists too. */
|
|
45
|
+
export function shippedTitle(op) {
|
|
46
|
+
return publicCatalog().operations.find((candidate) => candidate.name === op)?.title;
|
|
47
|
+
}
|
|
48
|
+
/** One cloud operation as ops.describe answers it, from the shipped catalog; null when it has no such row. */
|
|
49
|
+
export function shippedWireForm(op) {
|
|
50
|
+
const found = publicCatalog().operations.find((candidate) => candidate.name === op);
|
|
51
|
+
if (!found || isLocalOp(op))
|
|
52
|
+
return null;
|
|
53
|
+
// `direct` names the hosted profiles that list it as a tool; it says nothing here.
|
|
54
|
+
const { direct: _direct, ...wire } = found;
|
|
55
|
+
return { contract: CONTRACT_VERSION, ...wire, input: withOutField(op, found.input), needsSignIn: true };
|
|
56
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { CatalogEntry } from "./catalog.js";
|
|
2
2
|
import type { Effect } from "./contract.js";
|
|
3
3
|
export declare function words(text: string): string[];
|
|
4
|
-
export declare function scoreEntry(entry: CatalogEntry, query: string): number;
|
|
5
4
|
export declare function searchEntries(entries: readonly CatalogEntry[], query: string, filters: {
|
|
6
5
|
area?: string;
|
|
7
6
|
effect?: Effect;
|