@agent-native/core 0.153.10 → 0.154.1
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/AGENTS.md +20 -30
- package/corpus/templates/analytics/actions/search-dashboard-references.ts +58 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/analytics/app/lib/utils.ts +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewSqlPopover.tsx +1 -1
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -0
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +366 -3
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +3 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +6 -2
- package/corpus/templates/calendar/app/components/calendar/EventDialog.tsx +1 -1
- package/corpus/templates/calendar/app/lib/utils.ts +1 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +32 -5
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +15 -15
- package/corpus/templates/clips/app/i18n/en-US.ts +3 -3
- package/corpus/templates/clips/app/lib/utils.ts +5 -6
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +43 -8
- package/corpus/templates/clips/desktop/src/app.tsx +26 -12
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +23 -9
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +261 -11
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +21 -3
- package/corpus/templates/clips/shared/mic-audio-cleanup.ts +350 -0
- package/corpus/templates/content/actions/resolve-content-landing.ts +162 -32
- package/corpus/templates/content/app/i18n-data.ts +10 -10
- package/corpus/templates/content/scripts/check-native-deps.mjs +181 -15
- package/corpus/templates/content/shared/content-landing.ts +5 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +79 -7
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +14 -2
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +2 -2
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +35 -11
- package/corpus/templates/design/actions/get-design-system.ts +103 -3
- package/corpus/templates/design/actions/import-design-tokens.ts +37 -8
- package/corpus/templates/design/actions/import-github.ts +32 -138
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +49 -16
- package/corpus/templates/design/actions/present-design-variants.ts +93 -4
- package/corpus/templates/design/actions/run-design-audit.ts +229 -0
- package/corpus/templates/design/actions/sync-design-system-with-builder.ts +64 -0
- package/corpus/templates/design/app/components/design/code-workbench/commands.ts +2 -2
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +17 -4
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +5 -1
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +5 -1
- package/corpus/templates/design/app/hooks/use-question-flow.ts +81 -5
- package/corpus/templates/design/app/i18n/en-US.ts +1 -1
- package/corpus/templates/design/app/i18n-data.ts +32 -1
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +10 -10
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +83 -11
- package/corpus/templates/design/app/pages/DesignSystems.tsx +14 -0
- package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +22 -0
- package/corpus/templates/design/changelog/2026-08-13-a-screen-that-would-render-behind-an-invisible-alpine-overla.md +6 -0
- package/corpus/templates/design/changelog/2026-08-13-attach-a-ui-screenshot-and-the-design-is-reproduced-not-rein.md +6 -0
- package/corpus/templates/design/changelog/2026-08-13-linking-a-design-system-means-you-never-get-generic-directio.md +6 -0
- package/corpus/templates/design/changelog/2026-08-13-the-design-audit-now-reports-when-a-screen-ignores-its-linke.md +6 -0
- package/corpus/templates/design/changelog/2026-08-13-the-design-system-preview-now-shows-how-many-named-tokens-we.md +6 -0
- package/corpus/templates/design/changelog/2026-08-13-your-design-system-prompt-and-reference-screenshots-now-reac.md +6 -0
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +18 -2
- package/corpus/templates/design/shared/design-review.ts +1 -0
- package/corpus/templates/design/shared/html-integrity.ts +171 -0
- package/corpus/templates/mail/app/lib/utils.ts +1 -1
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +10 -6
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +41 -3
- package/corpus/templates/slides/actions/patch-deck.ts +12 -3
- package/corpus/templates/slides/actions/sync-design-system-with-builder.ts +64 -0
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -1
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +193 -20
- package/corpus/templates/slides/app/components/editor/EditorActionCluster.tsx +73 -1
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +64 -34
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +34 -41
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +119 -91
- package/corpus/templates/slides/app/components/editor/ImageOverlay.tsx +16 -0
- package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +15 -0
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +158 -31
- package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +30 -14
- package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +2 -2
- package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +4 -1
- package/corpus/templates/slides/app/components/editor/rich-text-selection.ts +14 -0
- package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +24 -0
- package/corpus/templates/slides/app/context/DeckContext.tsx +19 -31
- package/corpus/templates/slides/app/global.css +24 -0
- package/corpus/templates/slides/app/hooks/use-navigation-state.ts +20 -17
- package/corpus/templates/slides/app/i18n/en-US.ts +19 -10
- package/corpus/templates/slides/app/lib/deck-filter.ts +47 -0
- package/corpus/templates/slides/app/lib/export-google-slides-client.ts +15 -4
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +637 -1
- package/corpus/templates/slides/app/lib/image-download.ts +84 -0
- package/corpus/templates/slides/app/lib/utils.ts +1 -1
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +9 -0
- package/corpus/templates/slides/app/pages/Index.tsx +25 -9
- package/corpus/templates/slides/changelog/2026-08-13-clicking-a-slide-thumbnail-now-focuses-it-so-the-slide-shortc.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-13-duplicating-or-restoring-a-slide-now-keeps-its-transition-ani.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-13-opening-presentation-mode-from-the-agent-now-starts-on-the-re.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-13-slide-transitions-can-be-set-from-a-visible-control-in-the-sl.md +6 -0
- package/corpus/templates/slides/netlify.toml +1 -0
- package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +14 -2
- package/dist/a2a/audience.d.ts +2 -0
- package/dist/a2a/audience.js +23 -0
- package/dist/a2a/client.d.ts +4 -0
- package/dist/a2a/client.js +32 -14
- package/dist/a2a/server.d.ts +9 -4
- package/dist/a2a/server.js +52 -25
- package/dist/a2a/types.d.ts +4 -4
- package/dist/agent/production-agent.js +1 -1
- package/dist/brand-kit/types.d.ts +10 -2
- package/dist/cli/code.js +1 -1
- package/dist/cli/index.js +30 -1
- package/dist/cli/native-dependencies.d.ts +24 -0
- package/dist/cli/native-dependencies.js +264 -0
- package/dist/cli/plan-local.js +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.js +2 -2
- package/dist/cli/visualize-repo.js +1 -1
- package/dist/client/FeedbackButton.js +12 -12
- package/dist/client/agent-chat-adapter.js +3 -4
- package/dist/client/assistant-ui-recovery.d.ts +1 -1
- package/dist/client/assistant-ui-recovery.js +4 -0
- package/dist/client/chat/message-components.d.ts +11 -3
- package/dist/client/chat/message-components.js +31 -5
- package/dist/client/chat/tool-call-display.d.ts +2 -1
- package/dist/client/chat/tool-call-display.js +33 -15
- package/dist/client/db-admin/SqlEditor.js +1 -1
- package/dist/client/dev-overlay/DevOverlay.js +2 -2
- package/dist/client/extensions/portable-extension.js +4 -0
- package/dist/client/guided-questions.d.ts +8 -0
- package/dist/client/guided-questions.js +12 -3
- package/dist/client/sharing/ShareButton.js +16 -24
- package/dist/client/sse-event-processor.js +35 -15
- package/dist/client/tool-display.d.ts +9 -0
- package/dist/client/tool-display.js +39 -0
- package/dist/client/vite-dev-recovery-script.js +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/extensions/html-shell.js +5 -0
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/provider-api/actions/custom-provider-registration.d.ts +2 -2
- package/dist/server/agent-capabilities.js +0 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts +14 -13
- package/dist/server/agent-chat/action-filters-a2a.js +59 -23
- package/dist/server/agent-chat/prompt-resources.js +17 -16
- package/dist/server/agent-chat-plugin.d.ts +9 -0
- package/dist/server/agent-chat-plugin.js +29 -7
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/builder-design-systems.d.ts +33 -1
- package/dist/server/builder-design-systems.js +293 -11
- package/dist/server/design-token-utils.d.ts +11 -0
- package/dist/server/design-token-utils.js +68 -16
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/package.json +2 -2
|
@@ -39,6 +39,8 @@ export interface BuilderDesignSystemProxyFieldsOptions {
|
|
|
39
39
|
description?: string;
|
|
40
40
|
surface: "design" | "slides";
|
|
41
41
|
sourceKind?: BuilderDesignSystemSourceKind;
|
|
42
|
+
githubSources?: BuilderDesignSystemGitHubSource[];
|
|
43
|
+
syncedAt?: string;
|
|
42
44
|
}
|
|
43
45
|
export type BuilderDesignSystemSourceKind = "figma" | "code" | "github" | "mixed";
|
|
44
46
|
export interface BuilderDesignSystemProxyFields {
|
|
@@ -55,6 +57,8 @@ export interface BuilderDesignSystemProxyReference {
|
|
|
55
57
|
builderProjectId?: string;
|
|
56
58
|
builderUrl?: string;
|
|
57
59
|
builderStatus?: string;
|
|
60
|
+
githubSources?: BuilderDesignSystemGitHubSource[];
|
|
61
|
+
syncedAt?: string;
|
|
58
62
|
}
|
|
59
63
|
export interface BuilderDesignSystemDocsOptions {
|
|
60
64
|
page?: number;
|
|
@@ -82,11 +86,20 @@ export interface BuilderDesignSystemIndexOptions {
|
|
|
82
86
|
projectName?: string;
|
|
83
87
|
description?: string;
|
|
84
88
|
githubRepoUrl?: string;
|
|
89
|
+
githubRepos?: BuilderDesignSystemGitHubSource[];
|
|
85
90
|
connectedProjectId?: string;
|
|
86
91
|
files?: BuilderDesignSystemIndexFile[];
|
|
87
92
|
selection?: Record<string, string[]>;
|
|
88
93
|
devToolsVersion?: string;
|
|
89
94
|
}
|
|
95
|
+
/** A durable, replayable GitHub source configuration for a Builder DSI kit. */
|
|
96
|
+
export interface BuilderDesignSystemGitHubSource {
|
|
97
|
+
repoUrl: string;
|
|
98
|
+
ref?: string;
|
|
99
|
+
include?: string[];
|
|
100
|
+
exclude?: string[];
|
|
101
|
+
instructions?: string;
|
|
102
|
+
}
|
|
90
103
|
export interface BuilderDesignSystemIndexResult {
|
|
91
104
|
ok: true;
|
|
92
105
|
source: "builder";
|
|
@@ -124,6 +137,25 @@ export interface BuilderDesignSystemDecodeJobStatus {
|
|
|
124
137
|
createdAt: number;
|
|
125
138
|
updatedAt: number;
|
|
126
139
|
}
|
|
140
|
+
export interface BuilderDesignSystemGitHubFile {
|
|
141
|
+
path: string;
|
|
142
|
+
content: string;
|
|
143
|
+
}
|
|
144
|
+
export interface BuilderDesignSystemGitHubFileCollection {
|
|
145
|
+
source: BuilderDesignSystemGitHubSource;
|
|
146
|
+
owner: string;
|
|
147
|
+
repo: string;
|
|
148
|
+
ref?: string;
|
|
149
|
+
files: BuilderDesignSystemGitHubFile[];
|
|
150
|
+
totalBytes: number;
|
|
151
|
+
truncated: boolean;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Resolve an explicitly scoped/ref'd GitHub source into bounded file uploads.
|
|
155
|
+
* Native Builder public-repo sources are preferred for unscoped public repos;
|
|
156
|
+
* this path exists so branch, folder, and private-repo imports are replayable.
|
|
157
|
+
*/
|
|
158
|
+
export declare function collectBuilderDesignSystemGitHubFiles(input: BuilderDesignSystemGitHubSource): Promise<BuilderDesignSystemGitHubFileCollection>;
|
|
127
159
|
export declare function fetchBuilderDesignSystemDecodeJobStatus(jobId: string): Promise<BuilderDesignSystemDecodeJobStatus>;
|
|
128
160
|
export declare function getBuilderDesignSystemsBaseUrl(): string;
|
|
129
161
|
export declare function mimeTypeForBuilderDesignSystemFilename(filename: string, explicit?: string): string;
|
|
@@ -131,7 +163,7 @@ export declare function buildBuilderDesignSystemIndexFiles({ codeFiles, designMd
|
|
|
131
163
|
export declare function builderDesignSystemUrl(designSystemId?: string | null): string;
|
|
132
164
|
export declare function builderProjectBranchUrl(projectId?: string | null, branchName?: string | null): string | undefined;
|
|
133
165
|
export declare function localBuilderDesignSystemId(builderDesignSystemId: string): string;
|
|
134
|
-
export declare function createBuilderDesignSystemProxyFields({ result, projectName, description, surface, sourceKind, }: BuilderDesignSystemProxyFieldsOptions): BuilderDesignSystemProxyFields;
|
|
166
|
+
export declare function createBuilderDesignSystemProxyFields({ result, projectName, description, surface, sourceKind, githubSources, syncedAt, }: BuilderDesignSystemProxyFieldsOptions): BuilderDesignSystemProxyFields;
|
|
135
167
|
export declare function parseBuilderDesignSystemProxyReference(data: unknown): BuilderDesignSystemProxyReference | null;
|
|
136
168
|
export declare function fetchBuilderDesignSystemDocs(designSystemId: string, options?: BuilderDesignSystemDocsOptions): Promise<BuilderDesignSystemDocument[]>;
|
|
137
169
|
export declare function hydrateBuilderDesignSystemReference(reference: BuilderDesignSystemProxyReference, options?: BuilderDesignSystemDocsOptions): Promise<BuilderDesignSystemHydratedReference>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { withBuilderUtmTrackingParams } from "../shared/builder-link-tracking.js";
|
|
2
2
|
import { FeatureNotConfiguredError } from "./credential-provider.js";
|
|
3
|
-
import { getBuilderProxyOrigin, resolveBuilderCredentials, } from "./credential-provider.js";
|
|
3
|
+
import { getBuilderProxyOrigin, resolveSecret, resolveBuilderCredentials, } from "./credential-provider.js";
|
|
4
|
+
import { canonicalGitHubRepoUrl, fetchGitHubJsonResult, fetchGitHubRaw, parseGitHubRepoReference, } from "./design-token-utils.js";
|
|
4
5
|
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
5
6
|
// GCS resumable uploads require every chunk except the last to be a multiple
|
|
6
7
|
// of 256 KiB. 16 MiB is the recommended default and keeps very large `.fig`
|
|
@@ -10,6 +11,186 @@ const MAX_CHUNK_RETRIES = 5;
|
|
|
10
11
|
const DEFAULT_MAX_CODE_FILES = 50;
|
|
11
12
|
const DEFAULT_MAX_TOTAL_CODE_BYTES = 2 * 1024 * 1024;
|
|
12
13
|
const MAX_DOC_CONTENT_CHARS = 4_000;
|
|
14
|
+
const MAX_GITHUB_FILES = 50;
|
|
15
|
+
const MAX_GITHUB_TOTAL_BYTES = 2 * 1024 * 1024;
|
|
16
|
+
const MAX_GITHUB_FILE_BYTES = 512 * 1024;
|
|
17
|
+
const MAX_GITHUB_DIRECTORIES = 250;
|
|
18
|
+
const SKIPPED_GITHUB_DIRECTORIES = new Set([
|
|
19
|
+
".git",
|
|
20
|
+
".next",
|
|
21
|
+
".turbo",
|
|
22
|
+
".cache",
|
|
23
|
+
"build",
|
|
24
|
+
"coverage",
|
|
25
|
+
"dist",
|
|
26
|
+
"node_modules",
|
|
27
|
+
"vendor",
|
|
28
|
+
]);
|
|
29
|
+
function normalizeGitHubPath(value) {
|
|
30
|
+
const normalized = value.trim().replace(/^\/+|\/+$/g, "");
|
|
31
|
+
if (normalized.split("/").some((segment) => segment === "." || segment === "..")) {
|
|
32
|
+
throw new Error("GitHub file and folder scopes cannot contain . or .. segments.");
|
|
33
|
+
}
|
|
34
|
+
return normalized;
|
|
35
|
+
}
|
|
36
|
+
function pathMatchesScope(path, scope) {
|
|
37
|
+
const normalizedPath = normalizeGitHubPath(path);
|
|
38
|
+
const normalizedScope = normalizeGitHubPath(scope);
|
|
39
|
+
return (normalizedPath === normalizedScope ||
|
|
40
|
+
normalizedPath.startsWith(`${normalizedScope}/`));
|
|
41
|
+
}
|
|
42
|
+
function pathIsExcluded(path, excludes) {
|
|
43
|
+
return excludes.some((scope) => pathMatchesScope(path, scope));
|
|
44
|
+
}
|
|
45
|
+
function isIndexableGitHubFile(path) {
|
|
46
|
+
const name = path.split("/").pop()?.toLowerCase() ?? path.toLowerCase();
|
|
47
|
+
return (name === "package.json" ||
|
|
48
|
+
/\.(css|scss|sass|less|ts|tsx|js|jsx|json|html|svg|xml|md|markdown|mdx|txt)$/.test(name) ||
|
|
49
|
+
/(?:tailwind|postcss|theme|tokens|design)\.config\.[^/]+$/.test(name));
|
|
50
|
+
}
|
|
51
|
+
function isSkippedGitHubDirectory(path) {
|
|
52
|
+
const name = path.split("/").pop()?.toLowerCase() ?? "";
|
|
53
|
+
return SKIPPED_GITHUB_DIRECTORIES.has(name);
|
|
54
|
+
}
|
|
55
|
+
function githubSourceAccessError(owner, repo, status, hasToken, message) {
|
|
56
|
+
const suffix = message ? ` GitHub said: ${message}` : "";
|
|
57
|
+
if (!hasToken && (status === 401 || status === 403 || status === 404)) {
|
|
58
|
+
return new Error(`Could not access ${owner}/${repo}. Public repositories work without setup; private repositories require a fine-grained GitHub personal access token saved as GITHUB_TOKEN in Settings > Secrets with Repository permissions > Contents: Read-only.${suffix}`);
|
|
59
|
+
}
|
|
60
|
+
if (hasToken && (status === 401 || status === 403 || status === 404)) {
|
|
61
|
+
return new Error(`Could not access ${owner}/${repo} with the saved GITHUB_TOKEN. Check that the token is valid, the repository is selected, organization SSO/approval is complete, and Contents is Read-only.${suffix}`);
|
|
62
|
+
}
|
|
63
|
+
if (status === 429) {
|
|
64
|
+
return new Error(`GitHub rate-limited requests for ${owner}/${repo}. Save a GITHUB_TOKEN in Settings > Secrets or try again after the rate limit resets.${suffix}`);
|
|
65
|
+
}
|
|
66
|
+
return new Error(`Could not read ${owner}/${repo} from GitHub (status ${status || "unknown"}).${suffix}`);
|
|
67
|
+
}
|
|
68
|
+
function normalizedGitHubSource(source) {
|
|
69
|
+
const reference = parseGitHubRepoReference(source.repoUrl);
|
|
70
|
+
const ref = source.ref?.trim() || reference.ref;
|
|
71
|
+
const impliedPath = reference.subpath ? [reference.subpath] : [];
|
|
72
|
+
const include = [
|
|
73
|
+
...impliedPath,
|
|
74
|
+
...(source.include ?? []).map(normalizeGitHubPath).filter(Boolean),
|
|
75
|
+
];
|
|
76
|
+
const uniqueInclude = [...new Set(include)];
|
|
77
|
+
const exclude = [
|
|
78
|
+
...(source.exclude ?? []).map(normalizeGitHubPath).filter(Boolean),
|
|
79
|
+
];
|
|
80
|
+
const normalized = {
|
|
81
|
+
repoUrl: canonicalGitHubRepoUrl(source.repoUrl),
|
|
82
|
+
...(ref ? { ref } : {}),
|
|
83
|
+
...(uniqueInclude.length > 0 ? { include: uniqueInclude } : {}),
|
|
84
|
+
...(exclude.length > 0 ? { exclude: [...new Set(exclude)] } : {}),
|
|
85
|
+
...(source.instructions?.trim()
|
|
86
|
+
? { instructions: source.instructions.trim() }
|
|
87
|
+
: {}),
|
|
88
|
+
};
|
|
89
|
+
return { source: normalized, reference: { ...reference, ref } };
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Resolve an explicitly scoped/ref'd GitHub source into bounded file uploads.
|
|
93
|
+
* Native Builder public-repo sources are preferred for unscoped public repos;
|
|
94
|
+
* this path exists so branch, folder, and private-repo imports are replayable.
|
|
95
|
+
*/
|
|
96
|
+
export async function collectBuilderDesignSystemGitHubFiles(input) {
|
|
97
|
+
const { source, reference } = normalizedGitHubSource(input);
|
|
98
|
+
const githubToken = await resolveSecret("GITHUB_TOKEN");
|
|
99
|
+
const include = source.include ?? [];
|
|
100
|
+
const explicitScope = include.length > 0 || Boolean(source.ref);
|
|
101
|
+
const queue = [...(include.length > 0 ? include : [""])];
|
|
102
|
+
const visited = new Set();
|
|
103
|
+
const files = [];
|
|
104
|
+
let totalBytes = 0;
|
|
105
|
+
let directoriesVisited = 0;
|
|
106
|
+
let truncated = false;
|
|
107
|
+
while (queue.length > 0) {
|
|
108
|
+
const path = normalizeGitHubPath(queue.shift() ?? "");
|
|
109
|
+
if (visited.has(path) || pathIsExcluded(path, source.exclude ?? [])) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
visited.add(path);
|
|
113
|
+
directoriesVisited++;
|
|
114
|
+
if (directoriesVisited > MAX_GITHUB_DIRECTORIES) {
|
|
115
|
+
truncated = true;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
const result = await fetchGitHubJsonResult(reference.owner, reference.repo, path, {
|
|
119
|
+
token: githubToken,
|
|
120
|
+
ref: reference.ref,
|
|
121
|
+
});
|
|
122
|
+
if (!result.ok) {
|
|
123
|
+
throw githubSourceAccessError(reference.owner, reference.repo, result.status, Boolean(githubToken), result.message);
|
|
124
|
+
}
|
|
125
|
+
const entries = Array.isArray(result.data)
|
|
126
|
+
? result.data
|
|
127
|
+
: result.data
|
|
128
|
+
? [result.data]
|
|
129
|
+
: [];
|
|
130
|
+
for (const entry of entries) {
|
|
131
|
+
const entryPath = normalizeGitHubPath(entry?.path ?? entry?.name ?? "");
|
|
132
|
+
if (!entryPath || pathIsExcluded(entryPath, source.exclude ?? [])) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (entry.type === "dir") {
|
|
136
|
+
if (isSkippedGitHubDirectory(entryPath))
|
|
137
|
+
continue;
|
|
138
|
+
queue.push(entryPath);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (entry.type !== "file")
|
|
142
|
+
continue;
|
|
143
|
+
if (include.length > 0 &&
|
|
144
|
+
!include.some((scope) => pathMatchesScope(entryPath, scope))) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (!explicitScope && !isIndexableGitHubFile(entryPath))
|
|
148
|
+
continue;
|
|
149
|
+
if (files.length >= MAX_GITHUB_FILES) {
|
|
150
|
+
truncated = true;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
if ((entry.size ?? 0) > MAX_GITHUB_FILE_BYTES)
|
|
154
|
+
continue;
|
|
155
|
+
const content = await fetchGitHubRaw(reference.owner, reference.repo, entryPath, { token: githubToken, ref: reference.ref });
|
|
156
|
+
if (content === null) {
|
|
157
|
+
throw new Error(`Could not read ${entryPath} from ${reference.owner}/${reference.repo}${source.ref ? ` at ref ${source.ref}` : ""}. Check the repository Contents permission and file size.`);
|
|
158
|
+
}
|
|
159
|
+
const bytes = new TextEncoder().encode(content).byteLength;
|
|
160
|
+
if (totalBytes + bytes > MAX_GITHUB_TOTAL_BYTES) {
|
|
161
|
+
truncated = true;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
files.push({ path: entryPath, content });
|
|
165
|
+
totalBytes += bytes;
|
|
166
|
+
}
|
|
167
|
+
if (truncated)
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
if (files.length === 0) {
|
|
171
|
+
throw new Error(`No readable design-system files were found in ${reference.owner}/${reference.repo}${source.ref ? ` at ref ${source.ref}` : ""}. Select a folder or file that contains code, styles, tokens, or design.md.`);
|
|
172
|
+
}
|
|
173
|
+
if (truncated) {
|
|
174
|
+
throw new Error(`The selected GitHub source ${reference.owner}/${reference.repo} is larger than the safe inline indexing limit. Select a narrower folder or file set and try again.`);
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
source,
|
|
178
|
+
owner: reference.owner,
|
|
179
|
+
repo: reference.repo,
|
|
180
|
+
...(reference.ref ? { ref: reference.ref } : {}),
|
|
181
|
+
files,
|
|
182
|
+
totalBytes,
|
|
183
|
+
truncated,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
async function isPublicGitHubSource(reference) {
|
|
187
|
+
const result = await fetchGitHubJsonResult(reference.owner, reference.repo, "", {
|
|
188
|
+
ref: reference.ref,
|
|
189
|
+
});
|
|
190
|
+
return result.ok
|
|
191
|
+
? { ok: true }
|
|
192
|
+
: { ok: false, status: result.status, message: result.message };
|
|
193
|
+
}
|
|
13
194
|
export async function fetchBuilderDesignSystemDecodeJobStatus(jobId) {
|
|
14
195
|
const credentials = await resolveBuilderDesignSystemCredentials();
|
|
15
196
|
const url = makeBuilderDesignSystemUrl("decode-jobs/" + encodeURIComponent(jobId), credentials);
|
|
@@ -287,14 +468,19 @@ export function localBuilderDesignSystemId(builderDesignSystemId) {
|
|
|
287
468
|
.slice(0, 96);
|
|
288
469
|
return `builder-${slug || "design-system"}`;
|
|
289
470
|
}
|
|
290
|
-
export function createBuilderDesignSystemProxyFields({ result, projectName, description, surface, sourceKind, }) {
|
|
471
|
+
export function createBuilderDesignSystemProxyFields({ result, projectName, description, surface, sourceKind, githubSources, syncedAt, }) {
|
|
291
472
|
const title = projectName?.trim() || "Builder indexed design system";
|
|
473
|
+
const normalizedGithubSources = githubSources?.map((source) => normalizedGitHubSource(source).source);
|
|
292
474
|
const fallbackDescription = description ?? `Builder indexed design system ${result.designSystemId}`;
|
|
293
475
|
const surfaceNoun = surface === "slides" ? "slides" : "designs";
|
|
294
476
|
const spacingKey = surface === "slides" ? "slidePadding" : "pagePadding";
|
|
295
477
|
const data = JSON.stringify({
|
|
296
478
|
source: "builder",
|
|
297
479
|
...(sourceKind ? { sourceKind } : {}),
|
|
480
|
+
...(normalizedGithubSources?.length
|
|
481
|
+
? { githubSources: normalizedGithubSources }
|
|
482
|
+
: {}),
|
|
483
|
+
...(syncedAt ? { syncedAt } : {}),
|
|
298
484
|
builderDesignSystemId: result.designSystemId,
|
|
299
485
|
builderJobId: result.jobId,
|
|
300
486
|
builderProjectId: result.projectId,
|
|
@@ -328,6 +514,9 @@ export function createBuilderDesignSystemProxyFields({ result, projectName, desc
|
|
|
328
514
|
projectName ? `Requested name: ${projectName}` : "",
|
|
329
515
|
description ? `Context: ${description}` : "",
|
|
330
516
|
"Builder Design System Intelligence is the source of truth for indexed tokens, components, assets, and usage guidance.",
|
|
517
|
+
normalizedGithubSources?.length
|
|
518
|
+
? "GitHub source scope is persisted so this design system can be synced without reconfiguring it."
|
|
519
|
+
: "",
|
|
331
520
|
]
|
|
332
521
|
.filter(Boolean)
|
|
333
522
|
.join("\n"),
|
|
@@ -340,6 +529,9 @@ export function createBuilderDesignSystemProxyFields({ result, projectName, desc
|
|
|
340
529
|
`Builder URL: ${result.builderUrl}`,
|
|
341
530
|
`When generating ${surfaceNoun}, treat Builder DSI as the source of truth for indexed tokens, components, assets, and usage guidance.`,
|
|
342
531
|
"Call get-design-system for this local id before generation and use the returned builder docs and token values when available.",
|
|
532
|
+
normalizedGithubSources?.length
|
|
533
|
+
? "Use sync-design-system-with-builder to refresh the persisted GitHub source scope before generating when the repository changed."
|
|
534
|
+
: "",
|
|
343
535
|
].join("\n");
|
|
344
536
|
return {
|
|
345
537
|
title,
|
|
@@ -375,6 +567,48 @@ export function parseBuilderDesignSystemProxyReference(data) {
|
|
|
375
567
|
sourceKind !== "mixed") {
|
|
376
568
|
return null;
|
|
377
569
|
}
|
|
570
|
+
let invalidGithubSource = false;
|
|
571
|
+
const githubSources = Array.isArray(value.githubSources)
|
|
572
|
+
? value.githubSources.flatMap((source) => {
|
|
573
|
+
if (!source || typeof source !== "object") {
|
|
574
|
+
invalidGithubSource = true;
|
|
575
|
+
return [];
|
|
576
|
+
}
|
|
577
|
+
const candidate = source;
|
|
578
|
+
if (typeof candidate.repoUrl !== "string") {
|
|
579
|
+
invalidGithubSource = true;
|
|
580
|
+
return [];
|
|
581
|
+
}
|
|
582
|
+
try {
|
|
583
|
+
const normalized = normalizedGitHubSource({
|
|
584
|
+
repoUrl: candidate.repoUrl,
|
|
585
|
+
...(typeof candidate.ref === "string"
|
|
586
|
+
? { ref: candidate.ref }
|
|
587
|
+
: {}),
|
|
588
|
+
...(Array.isArray(candidate.include)
|
|
589
|
+
? {
|
|
590
|
+
include: candidate.include.filter((path) => typeof path === "string"),
|
|
591
|
+
}
|
|
592
|
+
: {}),
|
|
593
|
+
...(Array.isArray(candidate.exclude)
|
|
594
|
+
? {
|
|
595
|
+
exclude: candidate.exclude.filter((path) => typeof path === "string"),
|
|
596
|
+
}
|
|
597
|
+
: {}),
|
|
598
|
+
...(typeof candidate.instructions === "string"
|
|
599
|
+
? { instructions: candidate.instructions }
|
|
600
|
+
: {}),
|
|
601
|
+
});
|
|
602
|
+
return [normalized.source];
|
|
603
|
+
}
|
|
604
|
+
catch {
|
|
605
|
+
invalidGithubSource = true;
|
|
606
|
+
return [];
|
|
607
|
+
}
|
|
608
|
+
})
|
|
609
|
+
: undefined;
|
|
610
|
+
if (invalidGithubSource)
|
|
611
|
+
return null;
|
|
378
612
|
return {
|
|
379
613
|
source: "builder",
|
|
380
614
|
...(sourceKind ? { sourceKind } : {}),
|
|
@@ -385,6 +619,8 @@ export function parseBuilderDesignSystemProxyReference(data) {
|
|
|
385
619
|
: undefined,
|
|
386
620
|
builderUrl: typeof value.builderUrl === "string" ? value.builderUrl : undefined,
|
|
387
621
|
builderStatus: typeof value.builderStatus === "string" ? value.builderStatus : undefined,
|
|
622
|
+
...(githubSources?.length ? { githubSources } : {}),
|
|
623
|
+
...(typeof value.syncedAt === "string" ? { syncedAt: value.syncedAt } : {}),
|
|
388
624
|
};
|
|
389
625
|
}
|
|
390
626
|
function truncateDocContent(content) {
|
|
@@ -435,8 +671,9 @@ export async function fetchBuilderDesignSystemDocs(designSystemId, options = {})
|
|
|
435
671
|
});
|
|
436
672
|
await assertOk(response, "Builder design-system docs fetch failed");
|
|
437
673
|
const json = (await response.json());
|
|
438
|
-
if (!Array.isArray(json))
|
|
439
|
-
|
|
674
|
+
if (!Array.isArray(json)) {
|
|
675
|
+
throw new Error("Builder design-system docs fetch returned an invalid response.");
|
|
676
|
+
}
|
|
440
677
|
return json.map(normalizeBuilderDesignSystemDocument);
|
|
441
678
|
}
|
|
442
679
|
export async function hydrateBuilderDesignSystemReference(reference, options = { page: 0, pageSize: 40 }) {
|
|
@@ -555,10 +792,56 @@ export async function startBuilderDesignSystemIndex(options) {
|
|
|
555
792
|
}
|
|
556
793
|
if (files.length === 0 &&
|
|
557
794
|
!options.githubRepoUrl &&
|
|
795
|
+
!(options.githubRepos && options.githubRepos.length > 0) &&
|
|
558
796
|
!options.connectedProjectId) {
|
|
559
797
|
throw new Error("Provide at least one .fig/code/text file or a GitHub repository URL to index with Builder.");
|
|
560
798
|
}
|
|
561
799
|
const sources = [];
|
|
800
|
+
const fileInstructions = new Map();
|
|
801
|
+
function appendGitHubCollection(collection) {
|
|
802
|
+
for (const file of collection.files) {
|
|
803
|
+
const name = `github/${collection.owner}/${collection.repo}/${file.path}`;
|
|
804
|
+
files.push({
|
|
805
|
+
name,
|
|
806
|
+
data: new TextEncoder().encode(file.content),
|
|
807
|
+
mimeType: mimeTypeForBuilderDesignSystemFilename(file.path),
|
|
808
|
+
});
|
|
809
|
+
if (collection.source.instructions) {
|
|
810
|
+
fileInstructions.set(name, collection.source.instructions);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
const githubSources = options.githubRepos?.length
|
|
815
|
+
? options.githubRepos
|
|
816
|
+
: options.githubRepoUrl?.trim()
|
|
817
|
+
? [{ repoUrl: options.githubRepoUrl.trim() }]
|
|
818
|
+
: [];
|
|
819
|
+
for (const input of githubSources) {
|
|
820
|
+
const { source, reference } = normalizedGitHubSource(input);
|
|
821
|
+
const hasExplicitScope = Boolean(source.ref) ||
|
|
822
|
+
Boolean(source.include?.length) ||
|
|
823
|
+
Boolean(source.exclude?.length);
|
|
824
|
+
if (hasExplicitScope) {
|
|
825
|
+
const collection = await collectBuilderDesignSystemGitHubFiles(source);
|
|
826
|
+
appendGitHubCollection(collection);
|
|
827
|
+
continue;
|
|
828
|
+
}
|
|
829
|
+
const publicAccess = await isPublicGitHubSource(reference);
|
|
830
|
+
if (publicAccess.ok) {
|
|
831
|
+
sources.push({
|
|
832
|
+
kind: "public-repo",
|
|
833
|
+
repoUrl: source.repoUrl,
|
|
834
|
+
...(source.instructions ? { instructions: source.instructions } : {}),
|
|
835
|
+
});
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
838
|
+
if (await resolveSecret("GITHUB_TOKEN")) {
|
|
839
|
+
const collection = await collectBuilderDesignSystemGitHubFiles(source);
|
|
840
|
+
appendGitHubCollection(collection);
|
|
841
|
+
continue;
|
|
842
|
+
}
|
|
843
|
+
throw githubSourceAccessError(reference.owner, reference.repo, publicAccess.status, false, publicAccess.message);
|
|
844
|
+
}
|
|
562
845
|
if (files.length > 0) {
|
|
563
846
|
const slots = await startBuilderDesignSystemUpload(files.map((file) => ({
|
|
564
847
|
name: file.name,
|
|
@@ -568,23 +851,22 @@ export async function startBuilderDesignSystemIndex(options) {
|
|
|
568
851
|
for (let i = 0; i < slots.length; i++) {
|
|
569
852
|
await uploadToResumableUrl(slots[i], files[i]);
|
|
570
853
|
}
|
|
854
|
+
const fileSources = [];
|
|
571
855
|
for (let i = 0; i < slots.length; i++) {
|
|
572
856
|
const name = files[i].name;
|
|
573
857
|
const fileSelection = options.selection?.[name];
|
|
574
|
-
|
|
858
|
+
fileSources.push({
|
|
575
859
|
kind: "file",
|
|
576
860
|
uploadToken: slots[i].uploadToken,
|
|
861
|
+
...(fileInstructions.get(name)
|
|
862
|
+
? { instructions: fileInstructions.get(name) }
|
|
863
|
+
: {}),
|
|
577
864
|
...(fileSelection && fileSelection.length > 0
|
|
578
865
|
? { selection: { [name]: fileSelection } }
|
|
579
866
|
: {}),
|
|
580
867
|
});
|
|
581
868
|
}
|
|
582
|
-
|
|
583
|
-
if (options.githubRepoUrl?.trim()) {
|
|
584
|
-
sources.push({
|
|
585
|
-
kind: "public-repo",
|
|
586
|
-
repoUrl: options.githubRepoUrl.trim(),
|
|
587
|
-
});
|
|
869
|
+
sources.unshift(...fileSources);
|
|
588
870
|
}
|
|
589
871
|
if (options.connectedProjectId?.trim()) {
|
|
590
872
|
sources.push({
|
|
@@ -101,6 +101,14 @@ export interface UrlExtractionResult {
|
|
|
101
101
|
}
|
|
102
102
|
export interface GitHubFetchOptions {
|
|
103
103
|
token?: string | null;
|
|
104
|
+
/** Branch, tag, or commit to read from. */
|
|
105
|
+
ref?: string;
|
|
106
|
+
}
|
|
107
|
+
export interface GitHubRepoReference {
|
|
108
|
+
owner: string;
|
|
109
|
+
repo: string;
|
|
110
|
+
ref?: string;
|
|
111
|
+
subpath?: string;
|
|
104
112
|
}
|
|
105
113
|
export interface GitHubJsonResult<T = unknown> {
|
|
106
114
|
ok: boolean;
|
|
@@ -117,11 +125,14 @@ export interface GitHubJsonResult<T = unknown> {
|
|
|
117
125
|
* clear early error for literal private hosts, ssrfSafeFetch is the backstop.
|
|
118
126
|
*/
|
|
119
127
|
export declare function validateUrl(url: string): void;
|
|
128
|
+
/** Parse a GitHub URL or "org/repo" shorthand, retaining an optional ref/path. */
|
|
129
|
+
export declare function parseGitHubRepoReference(raw: string): GitHubRepoReference;
|
|
120
130
|
/** Parse a GitHub URL or "org/repo" shorthand into owner + repo. */
|
|
121
131
|
export declare function parseOwnerRepo(raw: string): {
|
|
122
132
|
owner: string;
|
|
123
133
|
repo: string;
|
|
124
134
|
};
|
|
135
|
+
export declare function canonicalGitHubRepoUrl(raw: string): string;
|
|
125
136
|
/** Fetch a path from the GitHub Contents API as JSON with status details. */
|
|
126
137
|
export declare function fetchGitHubJsonResult<T = unknown>(owner: string, repo: string, path: string, options?: GitHubFetchOptions): Promise<GitHubJsonResult<T>>;
|
|
127
138
|
/** Fetch a path from the GitHub Contents API as JSON. Returns null on error. */
|
|
@@ -108,26 +108,78 @@ export function validateUrl(url) {
|
|
|
108
108
|
// ---------------------------------------------------------------------------
|
|
109
109
|
// GitHub helpers
|
|
110
110
|
// ---------------------------------------------------------------------------
|
|
111
|
-
/** Parse a GitHub URL or "org/repo" shorthand
|
|
112
|
-
export function
|
|
111
|
+
/** Parse a GitHub URL or "org/repo" shorthand, retaining an optional ref/path. */
|
|
112
|
+
export function parseGitHubRepoReference(raw) {
|
|
113
113
|
const cleaned = raw
|
|
114
114
|
.trim()
|
|
115
115
|
.replace(/[?#].*$/, "")
|
|
116
116
|
.replace(/\/+$/, "");
|
|
117
|
+
if (!cleaned)
|
|
118
|
+
throw new Error("GitHub repository reference cannot be empty.");
|
|
117
119
|
const sshMatch = cleaned.match(/^(?:ssh:\/\/)?git@github\.com[:/]([^/]+)\/([^/]+?)(?:\.git)?$/);
|
|
118
|
-
if (sshMatch)
|
|
120
|
+
if (sshMatch)
|
|
119
121
|
return { owner: sshMatch[1], repo: sshMatch[2] };
|
|
120
|
-
}
|
|
121
122
|
const shorthand = cleaned.match(/^([^/\s]+)\/([^/\s]+?)(?:\.git)?$/);
|
|
122
|
-
if (shorthand)
|
|
123
|
+
if (shorthand)
|
|
123
124
|
return { owner: shorthand[1], repo: shorthand[2] };
|
|
125
|
+
let parsed;
|
|
126
|
+
try {
|
|
127
|
+
parsed = new URL(cleaned);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
throw new Error("Could not parse GitHub owner/repo from URL. " +
|
|
131
|
+
'Expected format: "https://github.com/org/repo", "org/repo", or "git@github.com:org/repo.git"');
|
|
132
|
+
}
|
|
133
|
+
if (parsed.hostname.toLowerCase() !== "github.com") {
|
|
134
|
+
throw new Error("GitHub repository URL must use github.com.");
|
|
124
135
|
}
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
136
|
+
const parts = parsed.pathname
|
|
137
|
+
.split("/")
|
|
138
|
+
.filter(Boolean)
|
|
139
|
+
.map((part) => {
|
|
140
|
+
try {
|
|
141
|
+
return decodeURIComponent(part);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return part;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
const owner = parts[0];
|
|
148
|
+
const repo = parts[1]?.replace(/\.git$/, "");
|
|
149
|
+
if (!owner || !repo) {
|
|
150
|
+
throw new Error("Could not parse GitHub owner/repo from URL. " +
|
|
151
|
+
'Expected format: "https://github.com/org/repo", "org/repo", or "git@github.com:org/repo.git"');
|
|
152
|
+
}
|
|
153
|
+
const kind = parts[2];
|
|
154
|
+
if ((kind === "tree" || kind === "blob") && parts[3]) {
|
|
155
|
+
return {
|
|
156
|
+
owner,
|
|
157
|
+
repo,
|
|
158
|
+
ref: parts[3],
|
|
159
|
+
...(parts.length > 4 ? { subpath: parts.slice(4).join("/") } : {}),
|
|
160
|
+
};
|
|
128
161
|
}
|
|
129
|
-
|
|
130
|
-
|
|
162
|
+
return { owner, repo };
|
|
163
|
+
}
|
|
164
|
+
/** Parse a GitHub URL or "org/repo" shorthand into owner + repo. */
|
|
165
|
+
export function parseOwnerRepo(raw) {
|
|
166
|
+
const { owner, repo } = parseGitHubRepoReference(raw);
|
|
167
|
+
return { owner, repo };
|
|
168
|
+
}
|
|
169
|
+
export function canonicalGitHubRepoUrl(raw) {
|
|
170
|
+
const { owner, repo } = parseGitHubRepoReference(raw);
|
|
171
|
+
return `https://github.com/${owner}/${repo}`;
|
|
172
|
+
}
|
|
173
|
+
function githubContentsUrl(owner, repo, path, ref) {
|
|
174
|
+
const encodedPath = path
|
|
175
|
+
.split("/")
|
|
176
|
+
.filter(Boolean)
|
|
177
|
+
.map((segment) => encodeURIComponent(segment))
|
|
178
|
+
.join("/");
|
|
179
|
+
const url = new URL(`https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/contents/${encodedPath}`);
|
|
180
|
+
if (ref?.trim())
|
|
181
|
+
url.searchParams.set("ref", ref.trim());
|
|
182
|
+
return url;
|
|
131
183
|
}
|
|
132
184
|
/** Fetch a path from the GitHub Contents API as JSON. Returns null on error. */
|
|
133
185
|
function githubHeaders(accept, options = {}) {
|
|
@@ -139,9 +191,9 @@ function githubHeaders(accept, options = {}) {
|
|
|
139
191
|
}
|
|
140
192
|
/** Fetch a path from the GitHub Contents API as JSON with status details. */
|
|
141
193
|
export async function fetchGitHubJsonResult(owner, repo, path, options = {}) {
|
|
142
|
-
const url =
|
|
143
|
-
validateUrl(url);
|
|
144
|
-
const res = await ssrfSafeFetch(url, {
|
|
194
|
+
const url = githubContentsUrl(owner, repo, path, options.ref);
|
|
195
|
+
validateUrl(url.toString());
|
|
196
|
+
const res = await ssrfSafeFetch(url.toString(), {
|
|
145
197
|
headers: githubHeaders("application/vnd.github.v3+json", options),
|
|
146
198
|
signal: AbortSignal.timeout(FETCH_TIMEOUT),
|
|
147
199
|
});
|
|
@@ -173,9 +225,9 @@ export async function fetchGitHubJson(owner, repo, path, options = {}) {
|
|
|
173
225
|
}
|
|
174
226
|
/** Fetch raw file content from the GitHub Contents API. Returns null on error or oversize. */
|
|
175
227
|
export async function fetchGitHubRaw(owner, repo, path, options = {}) {
|
|
176
|
-
const url =
|
|
177
|
-
validateUrl(url);
|
|
178
|
-
const res = await ssrfSafeFetch(url, {
|
|
228
|
+
const url = githubContentsUrl(owner, repo, path, options.ref);
|
|
229
|
+
validateUrl(url.toString());
|
|
230
|
+
const res = await ssrfSafeFetch(url.toString(), {
|
|
179
231
|
headers: githubHeaders("application/vnd.github.v3.raw", options),
|
|
180
232
|
signal: AbortSignal.timeout(FETCH_TIMEOUT),
|
|
181
233
|
});
|
package/dist/server/index.d.ts
CHANGED
|
@@ -69,7 +69,7 @@ export { createIntegrationsPlugin, defaultIntegrationsPlugin, enqueueRemoteComma
|
|
|
69
69
|
export { isElectron, isMobile, getOrigin, getAppBasePath, getAppUrl, resolveOAuthRedirectUri, isAllowedOAuthRedirectUri, encodeOAuthState, decodeOAuthState, resolveOAuthOwner, createOAuthSession, oauthCallbackResponse, oauthErrorPage, oauthDesktopExchangePage, type OAuthStatePayload, type OAuthOwnerResult, type OAuthSessionResult, } from "./google-oauth.js";
|
|
70
70
|
export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, type GenericWorkspaceOAuthProvider, type WorkspaceProviderOAuthFlow, } from "./workspace-provider-oauth.js";
|
|
71
71
|
export { FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed, resolveBuilderCredentialSource, resolveBuilderCredential, readDeployCredentialEnv, writeBuilderCredentials, deleteBuilderCredentials, resolveSecret, type BuilderCredentialsDetailed, } from "./credential-provider.js";
|
|
72
|
-
export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSystemIndexFiles, createBuilderDesignSystemProxyFields, fetchBuilderDesignSystemDecodeJobStatus, fetchBuilderDesignSystemDocs, getBuilderDesignSystemsBaseUrl, hydrateBuilderDesignSystemReference, indexBuilderDesignSystem, localBuilderDesignSystemId, mimeTypeForBuilderDesignSystemFilename, parseBuilderDesignSystemProxyReference, startBuilderDesignSystemIndex, startBuilderDesignSystemUpload, type BuildBuilderDesignSystemIndexFilesOptions, type BuilderDesignSystemCodeFileInput, type BuilderDesignSystemDecodeJobStatus, type BuilderDesignSystemDocsOptions, type BuilderDesignSystemDocument, type BuilderDesignSystemHydratedReference, type BuilderDesignSystemIndexFile, type BuilderDesignSystemIndexFromSourcesOptions, type BuilderDesignSystemIndexOptions, type BuilderDesignSystemIndexResult, type BuilderDesignSystemUploadAttachment, type BuilderDesignSystemUploadSlot, type BuilderDesignSystemProxyFields, type BuilderDesignSystemProxyFieldsOptions, type BuilderDesignSystemProxyReference, type BuilderDesignSystemSourceKind, } from "./builder-design-systems.js";
|
|
72
|
+
export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSystemIndexFiles, collectBuilderDesignSystemGitHubFiles, createBuilderDesignSystemProxyFields, fetchBuilderDesignSystemDecodeJobStatus, fetchBuilderDesignSystemDocs, getBuilderDesignSystemsBaseUrl, hydrateBuilderDesignSystemReference, indexBuilderDesignSystem, localBuilderDesignSystemId, mimeTypeForBuilderDesignSystemFilename, parseBuilderDesignSystemProxyReference, startBuilderDesignSystemIndex, startBuilderDesignSystemUpload, type BuildBuilderDesignSystemIndexFilesOptions, type BuilderDesignSystemCodeFileInput, type BuilderDesignSystemDecodeJobStatus, type BuilderDesignSystemDocsOptions, type BuilderDesignSystemDocument, type BuilderDesignSystemHydratedReference, type BuilderDesignSystemIndexFile, type BuilderDesignSystemIndexFromSourcesOptions, type BuilderDesignSystemIndexOptions, type BuilderDesignSystemIndexResult, type BuilderDesignSystemGitHubFile, type BuilderDesignSystemGitHubFileCollection, type BuilderDesignSystemGitHubSource, type BuilderDesignSystemUploadAttachment, type BuilderDesignSystemUploadSlot, type BuilderDesignSystemProxyFields, type BuilderDesignSystemProxyFieldsOptions, type BuilderDesignSystemProxyReference, type BuilderDesignSystemSourceKind, } from "./builder-design-systems.js";
|
|
73
73
|
export { createBuilderProject, ensureBuilderProject, findBuilderProjectForRepo, getBuilderBranchProjectId, isBuilderBranchingEnabled, requestBuilderBrowserConnection, resolveBuilderBranchProjectId, resolveIsBuilderBranchingEnabled, runBuilderAgent, type BuilderProjectResult, type RunBuilderAgentResult, } from "./builder-browser.js";
|
|
74
74
|
export { ensureFusionContainer, sendFusionBranchMessage, pushFusionBranch, reserveFusionHostingSlug, deployFusionProject, getFusionDeploys, getFusionBranchEditorUrl, getFusionHostingUrl, type FusionBranchRef, type EnsureFusionContainerResult, type SendFusionMessageResult, } from "./fusion-app.js";
|
|
75
75
|
export { sendEmail, isEmailConfigured, getEmailReadiness, getEmailProvider, type EmailAttachment, type EmailReadiness, type EmailProvider, type SendEmailArgs, } from "./email.js";
|
package/dist/server/index.js
CHANGED
|
@@ -74,7 +74,7 @@ export { createIntegrationsPlugin, defaultIntegrationsPlugin, enqueueRemoteComma
|
|
|
74
74
|
export { isElectron, isMobile, getOrigin, getAppBasePath, getAppUrl, resolveOAuthRedirectUri, isAllowedOAuthRedirectUri, encodeOAuthState, decodeOAuthState, resolveOAuthOwner, createOAuthSession, oauthCallbackResponse, oauthErrorPage, oauthDesktopExchangePage, } from "./google-oauth.js";
|
|
75
75
|
export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, } from "./workspace-provider-oauth.js";
|
|
76
76
|
export { FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed, resolveBuilderCredentialSource, resolveBuilderCredential, readDeployCredentialEnv, writeBuilderCredentials, deleteBuilderCredentials, resolveSecret, } from "./credential-provider.js";
|
|
77
|
-
export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSystemIndexFiles, createBuilderDesignSystemProxyFields, fetchBuilderDesignSystemDecodeJobStatus, fetchBuilderDesignSystemDocs, getBuilderDesignSystemsBaseUrl, hydrateBuilderDesignSystemReference, indexBuilderDesignSystem, localBuilderDesignSystemId, mimeTypeForBuilderDesignSystemFilename, parseBuilderDesignSystemProxyReference, startBuilderDesignSystemIndex, startBuilderDesignSystemUpload, } from "./builder-design-systems.js";
|
|
77
|
+
export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSystemIndexFiles, collectBuilderDesignSystemGitHubFiles, createBuilderDesignSystemProxyFields, fetchBuilderDesignSystemDecodeJobStatus, fetchBuilderDesignSystemDocs, getBuilderDesignSystemsBaseUrl, hydrateBuilderDesignSystemReference, indexBuilderDesignSystem, localBuilderDesignSystemId, mimeTypeForBuilderDesignSystemFilename, parseBuilderDesignSystemProxyReference, startBuilderDesignSystemIndex, startBuilderDesignSystemUpload, } from "./builder-design-systems.js";
|
|
78
78
|
export { createBuilderProject, ensureBuilderProject, findBuilderProjectForRepo, getBuilderBranchProjectId, isBuilderBranchingEnabled, requestBuilderBrowserConnection, resolveBuilderBranchProjectId, resolveIsBuilderBranchingEnabled, runBuilderAgent, } from "./builder-browser.js";
|
|
79
79
|
export { ensureFusionContainer, sendFusionBranchMessage, pushFusionBranch, reserveFusionHostingSlug, deployFusionProject, getFusionDeploys, getFusionBranchEditorUrl, getFusionHostingUrl, } from "./fusion-app.js";
|
|
80
80
|
export { sendEmail, isEmailConfigured, getEmailReadiness, getEmailProvider, } from "./email.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.154.1",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -421,7 +421,7 @@
|
|
|
421
421
|
"y-protocols": "^1.0.7",
|
|
422
422
|
"yjs": "^13.6.31",
|
|
423
423
|
"zod": "^4.3.6",
|
|
424
|
-
"@agent-native/toolkit": "^0.14.
|
|
424
|
+
"@agent-native/toolkit": "^0.14.2",
|
|
425
425
|
"@agent-native/recap-cli": "0.5.4"
|
|
426
426
|
},
|
|
427
427
|
"devDependencies": {
|