@agent-native/core 0.59.0 → 0.60.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/dist/a2a/index.d.ts +2 -0
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +1 -0
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/invoke.d.ts +63 -0
- package/dist/a2a/invoke.d.ts.map +1 -0
- package/dist/a2a/invoke.js +157 -0
- package/dist/a2a/invoke.js.map +1 -0
- package/dist/agent/run-store.d.ts +15 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +28 -0
- package/dist/agent/run-store.js.map +1 -1
- package/dist/chat-threads/store.d.ts +21 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +128 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/agent.d.ts +23 -0
- package/dist/cli/agent.d.ts.map +1 -0
- package/dist/cli/agent.js +300 -0
- package/dist/cli/agent.js.map +1 -0
- package/dist/cli/agents.d.ts +14 -0
- package/dist/cli/agents.d.ts.map +1 -0
- package/dist/cli/agents.js +95 -0
- package/dist/cli/agents.js.map +1 -0
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +264 -2
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/create.d.ts +3 -2
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +154 -83
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +50 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/invoke.d.ts +26 -0
- package/dist/cli/invoke.d.ts.map +1 -0
- package/dist/cli/invoke.js +227 -0
- package/dist/cli/invoke.js.map +1 -0
- package/dist/cli/templates-meta.d.ts +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +9 -8
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspacify.d.ts +1 -1
- package/dist/cli/workspacify.d.ts.map +1 -1
- package/dist/cli/workspacify.js +6 -6
- package/dist/cli/workspacify.js.map +1 -1
- package/dist/client/AgentPanel.js +1 -1
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +8 -2
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +5 -4
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +65 -12
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/blocks/library/diagram.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.js +23 -17
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/types.d.ts +2 -0
- package/dist/client/blocks/types.d.ts.map +1 -1
- package/dist/client/blocks/types.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +1 -1
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.d.ts +3 -1
- package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
- package/dist/client/notifications/NotificationsBell.js +7 -3
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts +13 -0
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +41 -0
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +2 -2
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +102 -0
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/org/auto-join-domain.d.ts +11 -3
- package/dist/org/auto-join-domain.d.ts.map +1 -1
- package/dist/org/auto-join-domain.js +7 -6
- package/dist/org/auto-join-domain.js.map +1 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +68 -32
- package/dist/org/context.js.map +1 -1
- package/dist/org/migrations.d.ts.map +1 -1
- package/dist/org/migrations.js +6 -0
- package/dist/org/migrations.js.map +1 -1
- package/dist/provider-api/actions/github-repo-files.d.ts +84 -0
- package/dist/provider-api/actions/github-repo-files.d.ts.map +1 -0
- package/dist/provider-api/actions/github-repo-files.js +213 -0
- package/dist/provider-api/actions/github-repo-files.js.map +1 -0
- package/dist/provider-api/github-repo.d.ts +11 -0
- package/dist/provider-api/github-repo.d.ts.map +1 -0
- package/dist/provider-api/github-repo.js +553 -0
- package/dist/provider-api/github-repo.js.map +1 -0
- package/dist/provider-api/index.d.ts +184 -11
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +519 -0
- package/dist/provider-api/index.js.map +1 -1
- package/dist/scripts/docs/search.d.ts.map +1 -1
- package/dist/scripts/docs/search.js +38 -13
- package/dist/scripts/docs/search.js.map +1 -1
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +11 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +32 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +297 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth-marketing.d.ts.map +1 -1
- package/dist/server/auth-marketing.js +17 -7
- package/dist/server/auth-marketing.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +6 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +18 -98
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/styles/blocks.css +30 -8
- package/dist/styles/rich-markdown-editor.css +10 -4
- package/dist/templates/{starter-shell-sync.spec.ts → chat-shell-sync.spec.ts} +21 -21
- package/dist/templates/default/.agents/skills/actions/SKILL.md +5 -5
- package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/dist/templates/default/AGENTS.md +22 -1
- package/dist/templates/default/actions/hello.ts +1 -1
- package/dist/templates/default/actions/navigate.ts +1 -1
- package/dist/templates/default/actions/view-screen.ts +1 -1
- package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/dist/templates/headless/.env.example +4 -0
- package/dist/templates/headless/.prettierrc +5 -0
- package/dist/templates/headless/AGENTS.md +58 -0
- package/dist/templates/headless/DEVELOPING.md +22 -0
- package/dist/templates/headless/_gitignore +36 -0
- package/dist/templates/headless/actions/hello.ts +14 -0
- package/dist/templates/headless/actions/run.ts +3 -0
- package/dist/templates/headless/package.json +22 -0
- package/dist/templates/headless/tsconfig.json +7 -0
- package/dist/templates/ui-primitives-sync.spec.ts +2 -2
- package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -5
- package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/dist/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +9 -0
- package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +93 -0
- package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +11 -1
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +1 -1
- package/dist/templates/workspace-core/AGENTS.md +20 -3
- package/dist/templates/workspace-core/src/server/index.ts +1 -1
- package/dist/templates/workspace-root/AGENTS.md +25 -5
- package/dist/templates/workspace-root/README.md +7 -7
- package/dist/triggers/dispatcher.d.ts +2 -3
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +2 -3
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/triggers/routes.d.ts +38 -0
- package/dist/triggers/routes.d.ts.map +1 -0
- package/dist/triggers/routes.js +202 -0
- package/dist/triggers/routes.js.map +1 -0
- package/dist/vite/client.d.ts +2 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +121 -2
- package/dist/vite/client.js.map +1 -1
- package/docs/AGENTS.md +57 -0
- package/docs/SKILL.md +40 -0
- package/docs/content/a2a-protocol.md +1 -1
- package/docs/content/actions.md +48 -8
- package/docs/content/agent-surfaces.md +76 -14
- package/docs/content/cli-adapters.md +1 -1
- package/docs/content/cloneable-saas.md +5 -4
- package/docs/content/code-agents-ui.md +1 -1
- package/docs/content/components.md +1 -1
- package/docs/content/context-awareness.md +15 -3
- package/docs/content/creating-templates.md +15 -7
- package/docs/content/drop-in-agent.md +1 -1
- package/docs/content/faq.md +6 -4
- package/docs/content/getting-started.md +63 -73
- package/docs/content/key-concepts.md +24 -24
- package/docs/content/native-chat-ui.md +4 -4
- package/docs/content/pure-agent-apps.md +34 -10
- package/docs/content/security.md +1 -1
- package/docs/content/server.md +1 -1
- package/docs/content/template-chat.md +85 -0
- package/docs/content/template-dispatch.md +1 -1
- package/docs/content/tracking.md +1 -1
- package/docs/content/what-is-agent-native.md +7 -6
- package/package.json +10 -1
- package/src/templates/{starter-shell-sync.spec.ts → chat-shell-sync.spec.ts} +21 -21
- package/src/templates/default/.agents/skills/actions/SKILL.md +5 -5
- package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/src/templates/default/AGENTS.md +22 -1
- package/src/templates/default/actions/hello.ts +1 -1
- package/src/templates/default/actions/navigate.ts +1 -1
- package/src/templates/default/actions/view-screen.ts +1 -1
- package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/src/templates/headless/.env.example +4 -0
- package/src/templates/headless/.prettierrc +5 -0
- package/src/templates/headless/AGENTS.md +58 -0
- package/src/templates/headless/DEVELOPING.md +22 -0
- package/src/templates/headless/_gitignore +36 -0
- package/src/templates/headless/actions/hello.ts +14 -0
- package/src/templates/headless/actions/run.ts +3 -0
- package/src/templates/headless/package.json +22 -0
- package/src/templates/headless/tsconfig.json +7 -0
- package/src/templates/ui-primitives-sync.spec.ts +2 -2
- package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -5
- package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/src/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +9 -0
- package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +93 -0
- package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +11 -1
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +1 -1
- package/src/templates/workspace-core/AGENTS.md +20 -3
- package/src/templates/workspace-core/src/server/index.ts +1 -1
- package/src/templates/workspace-root/AGENTS.md +25 -5
- package/src/templates/workspace-root/README.md +7 -7
- package/docs/content/template-starter.md +0 -78
|
@@ -801,6 +801,11 @@ export function createProviderApiRuntime(options) {
|
|
|
801
801
|
listCatalog: (provider) => listProviderApiCatalogWithCustom(provider, { providerIds }, runtimeOptions),
|
|
802
802
|
fetchDocs: (docsOptions) => fetchProviderApiDocs(docsOptions, runtimeOptions),
|
|
803
803
|
executeRequest: (args) => executeProviderApiRequest(args, runtimeOptions),
|
|
804
|
+
listGitHubRepositoryFiles: (args) => listGitHubRepositoryFiles(args, runtimeOptions),
|
|
805
|
+
searchGitHubRepositoryFiles: (args) => searchGitHubRepositoryFiles(args, runtimeOptions),
|
|
806
|
+
readGitHubRepositoryFile: (args) => readGitHubRepositoryFile(args, runtimeOptions),
|
|
807
|
+
writeGitHubRepositoryFile: (args) => writeGitHubRepositoryFile(args, runtimeOptions),
|
|
808
|
+
deleteGitHubRepositoryFile: (args) => deleteGitHubRepositoryFile(args, runtimeOptions),
|
|
804
809
|
};
|
|
805
810
|
}
|
|
806
811
|
export async function fetchProviderApiDocs(options, runtime = { appId: "app" }) {
|
|
@@ -1049,6 +1054,520 @@ export async function executeProviderApiRequest(args, runtime) {
|
|
|
1049
1054
|
guidance: "This was a raw provider API request. Use provider docs/spec URLs to choose endpoints and include method/path/status plus relevant filters in the methodology. Prefer this escape hatch whenever canned actions are too narrow.",
|
|
1050
1055
|
};
|
|
1051
1056
|
}
|
|
1057
|
+
const GITHUB_REPO_FILES_DEFAULT_MAX = 1_000;
|
|
1058
|
+
const GITHUB_REPO_FILES_MAX = 10_000;
|
|
1059
|
+
const GITHUB_CODE_SEARCH_DEFAULT_PER_PAGE = 30;
|
|
1060
|
+
const GITHUB_CODE_SEARCH_MAX_PER_PAGE = 100;
|
|
1061
|
+
export async function listGitHubRepositoryFiles(args, runtime) {
|
|
1062
|
+
const repository = normalizeGitHubRepository(args);
|
|
1063
|
+
const pathPrefix = normalizeGitHubFilePath(args.path);
|
|
1064
|
+
const maxFiles = clampPositiveInt(args.maxFiles, GITHUB_REPO_FILES_DEFAULT_MAX, GITHUB_REPO_FILES_MAX);
|
|
1065
|
+
if (args.recursive) {
|
|
1066
|
+
const ref = args.ref?.trim() || (await resolveGitHubDefaultBranch(args, runtime));
|
|
1067
|
+
const { json, response } = await executeGitHubJsonRequest({
|
|
1068
|
+
runtime,
|
|
1069
|
+
label: "list repository tree",
|
|
1070
|
+
args: {
|
|
1071
|
+
provider: "github",
|
|
1072
|
+
path: `${githubRepoApiPath(repository)}/git/trees/${encodeURIComponent(ref)}`,
|
|
1073
|
+
query: { recursive: "1" },
|
|
1074
|
+
connectionId: args.connectionId,
|
|
1075
|
+
timeoutMs: args.timeoutMs,
|
|
1076
|
+
maxBytes: args.maxBytes,
|
|
1077
|
+
},
|
|
1078
|
+
});
|
|
1079
|
+
const tree = asRecord(json);
|
|
1080
|
+
const rawEntries = Array.isArray(tree.tree) ? tree.tree : [];
|
|
1081
|
+
const entries = rawEntries
|
|
1082
|
+
.map((entry) => normalizeGitHubTreeEntry(entry, {
|
|
1083
|
+
owner: repository.owner,
|
|
1084
|
+
repo: repository.repo,
|
|
1085
|
+
ref,
|
|
1086
|
+
}))
|
|
1087
|
+
.filter((entry) => !!entry)
|
|
1088
|
+
.filter((entry) => args.includeDirectories || entry.type === "file")
|
|
1089
|
+
.filter((entry) => githubPathMatchesPrefix(entry.path, pathPrefix));
|
|
1090
|
+
const limitedEntries = entries.slice(0, maxFiles);
|
|
1091
|
+
return {
|
|
1092
|
+
repository,
|
|
1093
|
+
ref,
|
|
1094
|
+
path: pathPrefix,
|
|
1095
|
+
recursive: true,
|
|
1096
|
+
entries: limitedEntries,
|
|
1097
|
+
totalCount: entries.length,
|
|
1098
|
+
truncated: Boolean(tree.truncated) || entries.length > limitedEntries.length,
|
|
1099
|
+
providerTruncated: Boolean(tree.truncated),
|
|
1100
|
+
response: compactResponseStatus(response),
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
const { json, response } = await executeGitHubJsonRequest({
|
|
1104
|
+
runtime,
|
|
1105
|
+
label: "list repository contents",
|
|
1106
|
+
args: {
|
|
1107
|
+
provider: "github",
|
|
1108
|
+
path: githubContentsApiPath(repository, pathPrefix),
|
|
1109
|
+
query: args.ref ? { ref: args.ref } : undefined,
|
|
1110
|
+
connectionId: args.connectionId,
|
|
1111
|
+
timeoutMs: args.timeoutMs,
|
|
1112
|
+
maxBytes: args.maxBytes,
|
|
1113
|
+
},
|
|
1114
|
+
});
|
|
1115
|
+
const rawEntries = Array.isArray(json) ? json : [json];
|
|
1116
|
+
const entries = rawEntries
|
|
1117
|
+
.map(normalizeGitHubContentsEntry)
|
|
1118
|
+
.filter((entry) => !!entry)
|
|
1119
|
+
.filter((entry) => args.includeDirectories || entry.type === "file");
|
|
1120
|
+
const limitedEntries = entries.slice(0, maxFiles);
|
|
1121
|
+
return {
|
|
1122
|
+
repository,
|
|
1123
|
+
ref: args.ref?.trim() || null,
|
|
1124
|
+
path: pathPrefix,
|
|
1125
|
+
recursive: false,
|
|
1126
|
+
entries: limitedEntries,
|
|
1127
|
+
totalCount: entries.length,
|
|
1128
|
+
truncated: entries.length > limitedEntries.length,
|
|
1129
|
+
providerTruncated: false,
|
|
1130
|
+
response: compactResponseStatus(response),
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
export async function searchGitHubRepositoryFiles(args, runtime) {
|
|
1134
|
+
const repository = normalizeGitHubRepository(args);
|
|
1135
|
+
const query = args.query?.trim() ?? "";
|
|
1136
|
+
if (!query) {
|
|
1137
|
+
const listed = await listGitHubRepositoryFiles({
|
|
1138
|
+
owner: repository.owner,
|
|
1139
|
+
repo: repository.repo,
|
|
1140
|
+
path: args.path,
|
|
1141
|
+
ref: args.ref,
|
|
1142
|
+
recursive: true,
|
|
1143
|
+
includeDirectories: false,
|
|
1144
|
+
maxFiles: GITHUB_REPO_FILES_MAX,
|
|
1145
|
+
connectionId: args.connectionId,
|
|
1146
|
+
timeoutMs: args.timeoutMs,
|
|
1147
|
+
maxBytes: args.maxBytes,
|
|
1148
|
+
}, runtime);
|
|
1149
|
+
const filtered = listed.entries.filter((entry) => githubTreeEntryMatchesSearchFilters(entry, args));
|
|
1150
|
+
const maxFiles = clampPositiveInt(args.maxFiles, GITHUB_REPO_FILES_DEFAULT_MAX, GITHUB_REPO_FILES_MAX);
|
|
1151
|
+
const limitedItems = filtered.slice(0, maxFiles);
|
|
1152
|
+
return {
|
|
1153
|
+
repository,
|
|
1154
|
+
mode: "tree-filter",
|
|
1155
|
+
query: null,
|
|
1156
|
+
ref: listed.ref,
|
|
1157
|
+
items: limitedItems,
|
|
1158
|
+
totalCount: filtered.length,
|
|
1159
|
+
truncated: listed.truncated || filtered.length > limitedItems.length,
|
|
1160
|
+
incompleteResults: listed.providerTruncated,
|
|
1161
|
+
response: listed.response,
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
const perPage = clampPositiveInt(args.perPage, GITHUB_CODE_SEARCH_DEFAULT_PER_PAGE, GITHUB_CODE_SEARCH_MAX_PER_PAGE);
|
|
1165
|
+
const page = clampPositiveInt(args.page, 1, 100);
|
|
1166
|
+
const q = buildGitHubCodeSearchQuery(repository, args, query);
|
|
1167
|
+
const { json, response } = await executeGitHubJsonRequest({
|
|
1168
|
+
runtime,
|
|
1169
|
+
label: "search repository code",
|
|
1170
|
+
args: {
|
|
1171
|
+
provider: "github",
|
|
1172
|
+
path: "/search/code",
|
|
1173
|
+
query: { q, per_page: perPage, page },
|
|
1174
|
+
headers: args.includeTextMatches
|
|
1175
|
+
? { Accept: "application/vnd.github.text-match+json" }
|
|
1176
|
+
: undefined,
|
|
1177
|
+
connectionId: args.connectionId,
|
|
1178
|
+
timeoutMs: args.timeoutMs,
|
|
1179
|
+
maxBytes: args.maxBytes,
|
|
1180
|
+
},
|
|
1181
|
+
});
|
|
1182
|
+
const body = asRecord(json);
|
|
1183
|
+
const rawItems = Array.isArray(body.items) ? body.items : [];
|
|
1184
|
+
const items = rawItems
|
|
1185
|
+
.map(normalizeGitHubCodeSearchEntry)
|
|
1186
|
+
.filter((entry) => !!entry);
|
|
1187
|
+
return {
|
|
1188
|
+
repository,
|
|
1189
|
+
mode: "code-search",
|
|
1190
|
+
query: q,
|
|
1191
|
+
ref: null,
|
|
1192
|
+
items,
|
|
1193
|
+
totalCount: typeof body.total_count === "number" && Number.isFinite(body.total_count)
|
|
1194
|
+
? body.total_count
|
|
1195
|
+
: items.length,
|
|
1196
|
+
truncated: items.length >= perPage,
|
|
1197
|
+
incompleteResults: Boolean(body.incomplete_results),
|
|
1198
|
+
response: compactResponseStatus(response),
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
export async function readGitHubRepositoryFile(args, runtime) {
|
|
1202
|
+
const repository = normalizeGitHubRepository(args);
|
|
1203
|
+
const path = requireGitHubFilePath(args.path);
|
|
1204
|
+
const { json, response } = await executeGitHubJsonRequest({
|
|
1205
|
+
runtime,
|
|
1206
|
+
label: "read repository file",
|
|
1207
|
+
args: {
|
|
1208
|
+
provider: "github",
|
|
1209
|
+
path: githubContentsApiPath(repository, path),
|
|
1210
|
+
query: args.ref ? { ref: args.ref } : undefined,
|
|
1211
|
+
connectionId: args.connectionId,
|
|
1212
|
+
timeoutMs: args.timeoutMs,
|
|
1213
|
+
maxBytes: args.maxBytes,
|
|
1214
|
+
},
|
|
1215
|
+
});
|
|
1216
|
+
if (Array.isArray(json)) {
|
|
1217
|
+
throw new Error(`GitHub path "${path}" is a directory. Use listGitHubRepositoryFiles or the github-repo-files action with operation="list".`);
|
|
1218
|
+
}
|
|
1219
|
+
const file = asRecord(json);
|
|
1220
|
+
const encoding = typeof file.encoding === "string" ? file.encoding.toLowerCase() : null;
|
|
1221
|
+
const rawBase64 = encoding === "base64" && typeof file.content === "string"
|
|
1222
|
+
? file.content.replace(/\s+/g, "")
|
|
1223
|
+
: null;
|
|
1224
|
+
const content = rawBase64
|
|
1225
|
+
? Buffer.from(rawBase64, "base64").toString("utf8")
|
|
1226
|
+
: null;
|
|
1227
|
+
const sha = typeof file.sha === "string" ? file.sha : "";
|
|
1228
|
+
if (!sha)
|
|
1229
|
+
throw new Error(`GitHub read for "${path}" did not return a SHA.`);
|
|
1230
|
+
return {
|
|
1231
|
+
repository,
|
|
1232
|
+
path: typeof file.path === "string" ? file.path : path,
|
|
1233
|
+
ref: args.ref?.trim() || null,
|
|
1234
|
+
name: typeof file.name === "string" ? file.name : githubBasename(path),
|
|
1235
|
+
type: typeof file.type === "string" ? file.type : "file",
|
|
1236
|
+
sha,
|
|
1237
|
+
size: typeof file.size === "number" ? file.size : 0,
|
|
1238
|
+
encoding,
|
|
1239
|
+
content,
|
|
1240
|
+
contentBase64: rawBase64,
|
|
1241
|
+
url: typeof file.url === "string" ? file.url : null,
|
|
1242
|
+
htmlUrl: typeof file.html_url === "string" ? file.html_url : null,
|
|
1243
|
+
downloadUrl: typeof file.download_url === "string" ? file.download_url : null,
|
|
1244
|
+
response: compactResponseStatus(response),
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
export async function writeGitHubRepositoryFile(args, runtime) {
|
|
1248
|
+
const repository = normalizeGitHubRepository(args);
|
|
1249
|
+
const path = requireGitHubFilePath(args.path);
|
|
1250
|
+
const message = args.message.trim();
|
|
1251
|
+
if (!message)
|
|
1252
|
+
throw new Error("GitHub file write requires a commit message.");
|
|
1253
|
+
let sha = args.sha?.trim();
|
|
1254
|
+
if (!sha && args.overwriteExisting) {
|
|
1255
|
+
try {
|
|
1256
|
+
const existing = await readGitHubRepositoryFile({
|
|
1257
|
+
owner: repository.owner,
|
|
1258
|
+
repo: repository.repo,
|
|
1259
|
+
path,
|
|
1260
|
+
ref: args.branch,
|
|
1261
|
+
connectionId: args.connectionId,
|
|
1262
|
+
timeoutMs: args.timeoutMs,
|
|
1263
|
+
maxBytes: args.maxBytes,
|
|
1264
|
+
}, runtime);
|
|
1265
|
+
sha = existing.sha;
|
|
1266
|
+
}
|
|
1267
|
+
catch (error) {
|
|
1268
|
+
if (!isGitHubNotFoundError(error))
|
|
1269
|
+
throw error;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
const body = {
|
|
1273
|
+
message,
|
|
1274
|
+
content: Buffer.from(args.content, "utf8").toString("base64"),
|
|
1275
|
+
};
|
|
1276
|
+
if (sha)
|
|
1277
|
+
body.sha = sha;
|
|
1278
|
+
if (args.branch?.trim())
|
|
1279
|
+
body.branch = args.branch.trim();
|
|
1280
|
+
if (args.committer)
|
|
1281
|
+
body.committer = args.committer;
|
|
1282
|
+
if (args.author)
|
|
1283
|
+
body.author = args.author;
|
|
1284
|
+
const { json, response } = await executeGitHubJsonRequest({
|
|
1285
|
+
runtime,
|
|
1286
|
+
label: "write repository file",
|
|
1287
|
+
args: {
|
|
1288
|
+
provider: "github",
|
|
1289
|
+
method: "PUT",
|
|
1290
|
+
path: githubContentsApiPath(repository, path),
|
|
1291
|
+
body,
|
|
1292
|
+
connectionId: args.connectionId,
|
|
1293
|
+
timeoutMs: args.timeoutMs,
|
|
1294
|
+
maxBytes: args.maxBytes,
|
|
1295
|
+
},
|
|
1296
|
+
});
|
|
1297
|
+
const result = asRecord(json);
|
|
1298
|
+
const content = asRecord(result.content);
|
|
1299
|
+
const commit = asRecord(result.commit);
|
|
1300
|
+
return {
|
|
1301
|
+
repository,
|
|
1302
|
+
path,
|
|
1303
|
+
branch: args.branch?.trim() || null,
|
|
1304
|
+
content: {
|
|
1305
|
+
name: stringOrNull(content.name),
|
|
1306
|
+
path: stringOrNull(content.path),
|
|
1307
|
+
sha: stringOrNull(content.sha),
|
|
1308
|
+
url: stringOrNull(content.url),
|
|
1309
|
+
htmlUrl: stringOrNull(content.html_url),
|
|
1310
|
+
},
|
|
1311
|
+
commit: {
|
|
1312
|
+
sha: stringOrNull(commit.sha),
|
|
1313
|
+
url: stringOrNull(commit.url),
|
|
1314
|
+
htmlUrl: stringOrNull(commit.html_url),
|
|
1315
|
+
message: stringOrNull(commit.message),
|
|
1316
|
+
},
|
|
1317
|
+
response: compactResponseStatus(response),
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
export async function deleteGitHubRepositoryFile(args, runtime) {
|
|
1321
|
+
const repository = normalizeGitHubRepository(args);
|
|
1322
|
+
const path = requireGitHubFilePath(args.path);
|
|
1323
|
+
const message = args.message.trim();
|
|
1324
|
+
if (!message) {
|
|
1325
|
+
throw new Error("GitHub file delete requires a commit message.");
|
|
1326
|
+
}
|
|
1327
|
+
let sha = args.sha?.trim();
|
|
1328
|
+
if (!sha) {
|
|
1329
|
+
const existing = await readGitHubRepositoryFile({
|
|
1330
|
+
owner: repository.owner,
|
|
1331
|
+
repo: repository.repo,
|
|
1332
|
+
path,
|
|
1333
|
+
ref: args.branch,
|
|
1334
|
+
connectionId: args.connectionId,
|
|
1335
|
+
timeoutMs: args.timeoutMs,
|
|
1336
|
+
maxBytes: args.maxBytes,
|
|
1337
|
+
}, runtime);
|
|
1338
|
+
sha = existing.sha;
|
|
1339
|
+
}
|
|
1340
|
+
const body = { message, sha };
|
|
1341
|
+
if (args.branch?.trim())
|
|
1342
|
+
body.branch = args.branch.trim();
|
|
1343
|
+
if (args.committer)
|
|
1344
|
+
body.committer = args.committer;
|
|
1345
|
+
if (args.author)
|
|
1346
|
+
body.author = args.author;
|
|
1347
|
+
const { json, response } = await executeGitHubJsonRequest({
|
|
1348
|
+
runtime,
|
|
1349
|
+
label: "delete repository file",
|
|
1350
|
+
args: {
|
|
1351
|
+
provider: "github",
|
|
1352
|
+
method: "DELETE",
|
|
1353
|
+
path: githubContentsApiPath(repository, path),
|
|
1354
|
+
body,
|
|
1355
|
+
connectionId: args.connectionId,
|
|
1356
|
+
timeoutMs: args.timeoutMs,
|
|
1357
|
+
maxBytes: args.maxBytes,
|
|
1358
|
+
},
|
|
1359
|
+
});
|
|
1360
|
+
const result = asRecord(json);
|
|
1361
|
+
const commit = asRecord(result.commit);
|
|
1362
|
+
return {
|
|
1363
|
+
repository,
|
|
1364
|
+
path,
|
|
1365
|
+
branch: args.branch?.trim() || null,
|
|
1366
|
+
commit: {
|
|
1367
|
+
sha: stringOrNull(commit.sha),
|
|
1368
|
+
url: stringOrNull(commit.url),
|
|
1369
|
+
htmlUrl: stringOrNull(commit.html_url),
|
|
1370
|
+
message: stringOrNull(commit.message),
|
|
1371
|
+
},
|
|
1372
|
+
response: compactResponseStatus(response),
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
async function executeGitHubJsonRequest(options) {
|
|
1376
|
+
const result = (await executeProviderApiRequest({ provider: "github", ...options.args }, options.runtime));
|
|
1377
|
+
const response = result.response;
|
|
1378
|
+
if (!response) {
|
|
1379
|
+
throw new Error(`GitHub ${options.label} returned an unexpected result.`);
|
|
1380
|
+
}
|
|
1381
|
+
if (!response.ok) {
|
|
1382
|
+
throw new Error(`GitHub ${options.label} failed with HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}${providerResponseErrorDetail(response)}`);
|
|
1383
|
+
}
|
|
1384
|
+
return { json: response.json, response };
|
|
1385
|
+
}
|
|
1386
|
+
async function resolveGitHubDefaultBranch(args, runtime) {
|
|
1387
|
+
const repository = normalizeGitHubRepository(args);
|
|
1388
|
+
const { json } = await executeGitHubJsonRequest({
|
|
1389
|
+
runtime,
|
|
1390
|
+
label: "get repository metadata",
|
|
1391
|
+
args: {
|
|
1392
|
+
provider: "github",
|
|
1393
|
+
path: githubRepoApiPath(repository),
|
|
1394
|
+
connectionId: args.connectionId,
|
|
1395
|
+
timeoutMs: args.timeoutMs,
|
|
1396
|
+
maxBytes: args.maxBytes,
|
|
1397
|
+
},
|
|
1398
|
+
});
|
|
1399
|
+
const body = asRecord(json);
|
|
1400
|
+
const defaultBranch = stringOrNull(body.default_branch);
|
|
1401
|
+
if (!defaultBranch) {
|
|
1402
|
+
throw new Error(`GitHub repository ${repository.owner}/${repository.repo} did not return a default branch.`);
|
|
1403
|
+
}
|
|
1404
|
+
return defaultBranch;
|
|
1405
|
+
}
|
|
1406
|
+
function normalizeGitHubRepository(args) {
|
|
1407
|
+
const owner = args.owner.trim();
|
|
1408
|
+
const repo = args.repo.trim().replace(/\.git$/i, "");
|
|
1409
|
+
if (!owner)
|
|
1410
|
+
throw new Error("GitHub repository owner is required.");
|
|
1411
|
+
if (!repo)
|
|
1412
|
+
throw new Error("GitHub repository name is required.");
|
|
1413
|
+
return { owner, repo };
|
|
1414
|
+
}
|
|
1415
|
+
function githubRepoApiPath(repository) {
|
|
1416
|
+
return `/repos/${encodeURIComponent(repository.owner)}/${encodeURIComponent(repository.repo)}`;
|
|
1417
|
+
}
|
|
1418
|
+
function githubContentsApiPath(repository, filePath) {
|
|
1419
|
+
const encodedPath = encodeGitHubFilePath(filePath);
|
|
1420
|
+
return `${githubRepoApiPath(repository)}/contents${encodedPath ? `/${encodedPath}` : ""}`;
|
|
1421
|
+
}
|
|
1422
|
+
function encodeGitHubFilePath(filePath) {
|
|
1423
|
+
return normalizeGitHubFilePath(filePath)
|
|
1424
|
+
.split("/")
|
|
1425
|
+
.filter(Boolean)
|
|
1426
|
+
.map((part) => encodeURIComponent(part))
|
|
1427
|
+
.join("/");
|
|
1428
|
+
}
|
|
1429
|
+
function normalizeGitHubFilePath(filePath) {
|
|
1430
|
+
return (filePath ?? "").trim().replace(/^\/+|\/+$/g, "");
|
|
1431
|
+
}
|
|
1432
|
+
function requireGitHubFilePath(filePath) {
|
|
1433
|
+
const normalized = normalizeGitHubFilePath(filePath);
|
|
1434
|
+
if (!normalized)
|
|
1435
|
+
throw new Error("GitHub file path is required.");
|
|
1436
|
+
return normalized;
|
|
1437
|
+
}
|
|
1438
|
+
function githubBasename(filePath) {
|
|
1439
|
+
return filePath.split("/").filter(Boolean).pop() ?? filePath;
|
|
1440
|
+
}
|
|
1441
|
+
function githubPathMatchesPrefix(path, prefix) {
|
|
1442
|
+
if (!prefix)
|
|
1443
|
+
return true;
|
|
1444
|
+
return path === prefix || path.startsWith(`${prefix}/`);
|
|
1445
|
+
}
|
|
1446
|
+
function normalizeGitHubTreeEntry(value, options) {
|
|
1447
|
+
const entry = asRecord(value);
|
|
1448
|
+
const path = stringOrNull(entry.path);
|
|
1449
|
+
if (!path)
|
|
1450
|
+
return null;
|
|
1451
|
+
const type = stringOrNull(entry.type);
|
|
1452
|
+
const normalizedType = type === "blob"
|
|
1453
|
+
? "file"
|
|
1454
|
+
: type === "tree"
|
|
1455
|
+
? "dir"
|
|
1456
|
+
: type === "commit"
|
|
1457
|
+
? "submodule"
|
|
1458
|
+
: "unknown";
|
|
1459
|
+
return {
|
|
1460
|
+
name: githubBasename(path),
|
|
1461
|
+
path,
|
|
1462
|
+
type: normalizedType,
|
|
1463
|
+
sha: stringOrNull(entry.sha),
|
|
1464
|
+
size: numberOrNull(entry.size),
|
|
1465
|
+
url: stringOrNull(entry.url),
|
|
1466
|
+
htmlUrl: normalizedType === "file"
|
|
1467
|
+
? githubWebFileUrl(options, path)
|
|
1468
|
+
: normalizedType === "dir"
|
|
1469
|
+
? githubWebTreeUrl(options, path)
|
|
1470
|
+
: null,
|
|
1471
|
+
downloadUrl: null,
|
|
1472
|
+
};
|
|
1473
|
+
}
|
|
1474
|
+
function normalizeGitHubContentsEntry(value) {
|
|
1475
|
+
const entry = asRecord(value);
|
|
1476
|
+
const path = stringOrNull(entry.path);
|
|
1477
|
+
if (!path)
|
|
1478
|
+
return null;
|
|
1479
|
+
const type = stringOrNull(entry.type);
|
|
1480
|
+
return {
|
|
1481
|
+
name: stringOrNull(entry.name) ?? githubBasename(path),
|
|
1482
|
+
path,
|
|
1483
|
+
type: type === "file" ||
|
|
1484
|
+
type === "dir" ||
|
|
1485
|
+
type === "symlink" ||
|
|
1486
|
+
type === "submodule"
|
|
1487
|
+
? type
|
|
1488
|
+
: "unknown",
|
|
1489
|
+
sha: stringOrNull(entry.sha),
|
|
1490
|
+
size: numberOrNull(entry.size),
|
|
1491
|
+
url: stringOrNull(entry.url),
|
|
1492
|
+
htmlUrl: stringOrNull(entry.html_url),
|
|
1493
|
+
downloadUrl: stringOrNull(entry.download_url),
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
function normalizeGitHubCodeSearchEntry(value) {
|
|
1497
|
+
return normalizeGitHubContentsEntry({ ...asRecord(value), type: "file" });
|
|
1498
|
+
}
|
|
1499
|
+
function githubTreeEntryMatchesSearchFilters(entry, args) {
|
|
1500
|
+
const filename = args.filename?.trim();
|
|
1501
|
+
if (filename && entry.name !== filename)
|
|
1502
|
+
return false;
|
|
1503
|
+
const extension = args.extension?.trim().replace(/^\./, "");
|
|
1504
|
+
if (extension && !entry.path.endsWith(`.${extension}`))
|
|
1505
|
+
return false;
|
|
1506
|
+
const pathFilter = normalizeGitHubFilePath(args.path);
|
|
1507
|
+
if (pathFilter && !entry.path.includes(pathFilter))
|
|
1508
|
+
return false;
|
|
1509
|
+
return true;
|
|
1510
|
+
}
|
|
1511
|
+
function buildGitHubCodeSearchQuery(repository, args, query) {
|
|
1512
|
+
const qualifiers = [`repo:${repository.owner}/${repository.repo}`];
|
|
1513
|
+
const path = normalizeGitHubFilePath(args.path);
|
|
1514
|
+
if (path)
|
|
1515
|
+
qualifiers.push(`path:${quoteGitHubSearchQualifier(path)}`);
|
|
1516
|
+
if (args.filename?.trim()) {
|
|
1517
|
+
qualifiers.push(`filename:${quoteGitHubSearchQualifier(args.filename.trim())}`);
|
|
1518
|
+
}
|
|
1519
|
+
if (args.extension?.trim()) {
|
|
1520
|
+
qualifiers.push(`extension:${quoteGitHubSearchQualifier(args.extension.trim().replace(/^\./, ""))}`);
|
|
1521
|
+
}
|
|
1522
|
+
if (args.language?.trim()) {
|
|
1523
|
+
qualifiers.push(`language:${quoteGitHubSearchQualifier(args.language.trim())}`);
|
|
1524
|
+
}
|
|
1525
|
+
return [query, "in:file", ...qualifiers].join(" ");
|
|
1526
|
+
}
|
|
1527
|
+
function quoteGitHubSearchQualifier(value) {
|
|
1528
|
+
return /\s/.test(value) ? JSON.stringify(value) : value;
|
|
1529
|
+
}
|
|
1530
|
+
function githubWebFileUrl(options, filePath) {
|
|
1531
|
+
return `https://github.com/${encodeURIComponent(options.owner)}/${encodeURIComponent(options.repo)}/blob/${encodeURIComponent(options.ref)}/${encodeGitHubFilePath(filePath)}`;
|
|
1532
|
+
}
|
|
1533
|
+
function githubWebTreeUrl(options, filePath) {
|
|
1534
|
+
return `https://github.com/${encodeURIComponent(options.owner)}/${encodeURIComponent(options.repo)}/tree/${encodeURIComponent(options.ref)}/${encodeGitHubFilePath(filePath)}`;
|
|
1535
|
+
}
|
|
1536
|
+
function clampPositiveInt(value, defaultValue, maxValue) {
|
|
1537
|
+
if (!Number.isFinite(value) || value <= 0)
|
|
1538
|
+
return defaultValue;
|
|
1539
|
+
return Math.min(maxValue, Math.floor(value));
|
|
1540
|
+
}
|
|
1541
|
+
function compactResponseStatus(response) {
|
|
1542
|
+
return {
|
|
1543
|
+
status: response.status,
|
|
1544
|
+
statusText: response.statusText,
|
|
1545
|
+
ok: response.ok,
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1548
|
+
function providerResponseErrorDetail(response) {
|
|
1549
|
+
const body = asRecord(response.json);
|
|
1550
|
+
const message = stringOrNull(body.message);
|
|
1551
|
+
const detail = message ??
|
|
1552
|
+
(typeof response.text === "string"
|
|
1553
|
+
? response.text.replace(/\s+/g, " ").trim().slice(0, 500)
|
|
1554
|
+
: "");
|
|
1555
|
+
return detail ? `: ${detail}` : "";
|
|
1556
|
+
}
|
|
1557
|
+
function isGitHubNotFoundError(error) {
|
|
1558
|
+
return error instanceof Error && /\bHTTP 404\b/.test(error.message);
|
|
1559
|
+
}
|
|
1560
|
+
function asRecord(value) {
|
|
1561
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
1562
|
+
? value
|
|
1563
|
+
: {};
|
|
1564
|
+
}
|
|
1565
|
+
function stringOrNull(value) {
|
|
1566
|
+
return typeof value === "string" ? value : null;
|
|
1567
|
+
}
|
|
1568
|
+
function numberOrNull(value) {
|
|
1569
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1570
|
+
}
|
|
1052
1571
|
// ---------------------------------------------------------------------------
|
|
1053
1572
|
// Custom provider execution
|
|
1054
1573
|
// ---------------------------------------------------------------------------
|