@superblocksteam/vite-plugin-file-sync 2.0.149 → 2.0.150-next.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/ai-service/agent/prompts/api-prompts.js +1 -1
- package/dist/ai-service/agent/prompts/build-base-system-prompt.d.ts.map +1 -1
- package/dist/ai-service/agent/prompts/build-base-system-prompt.js +38 -10
- package/dist/ai-service/agent/prompts/build-base-system-prompt.js.map +1 -1
- package/dist/ai-service/agent/prompts/build-security-scan-prompt.d.ts.map +1 -1
- package/dist/ai-service/agent/prompts/build-security-scan-prompt.js +20 -4
- package/dist/ai-service/agent/prompts/build-security-scan-prompt.js.map +1 -1
- package/dist/ai-service/agent/subagents/testing/prompt-builder.js +1 -1
- package/dist/ai-service/agent/tools/apis/analysis.d.ts +6 -0
- package/dist/ai-service/agent/tools/apis/analysis.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/analysis.js +130 -26
- package/dist/ai-service/agent/tools/apis/analysis.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.js +2 -2
- package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/test-api.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/test-api.js +131 -31
- package/dist/ai-service/agent/tools/apis/test-api.js.map +1 -1
- package/dist/ai-service/agent/tools/build-delete-file.d.ts +2 -2
- package/dist/ai-service/agent/tools/build-delete-file.js +3 -3
- package/dist/ai-service/agent/tools/build-delete-file.js.map +1 -1
- package/dist/ai-service/agent/tools/build-install-packages.d.ts +41 -21
- package/dist/ai-service/agent/tools/build-install-packages.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-install-packages.js +299 -20
- package/dist/ai-service/agent/tools/build-install-packages.js.map +1 -1
- package/dist/ai-service/agent/tools/build-manage-checklist.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-manage-checklist.js +2 -1
- package/dist/ai-service/agent/tools/build-manage-checklist.js.map +1 -1
- package/dist/ai-service/agent/tools/databases/dev-database-tasks.d.ts +161 -24
- package/dist/ai-service/agent/tools/databases/dev-database-tasks.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/databases/dev-database-tasks.js +312 -55
- package/dist/ai-service/agent/tools/databases/dev-database-tasks.js.map +1 -1
- package/dist/ai-service/agent/tools/get-logs.d.ts +2 -2
- package/dist/ai-service/agent/tools/report-security-findings.d.ts +3 -3
- package/dist/ai-service/agent/tools.d.ts +10 -11
- package/dist/ai-service/agent/tools.d.ts.map +1 -1
- package/dist/ai-service/agent/tools.js +38 -19
- package/dist/ai-service/agent/tools.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js +9 -8
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/grep.js +1 -1
- package/dist/ai-service/agent/tools2/tools/index.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/index.js +2 -3
- package/dist/ai-service/agent/tools2/tools/index.js.map +1 -1
- package/dist/ai-service/app-interface/npm-package-lookup.d.ts +22 -0
- package/dist/ai-service/app-interface/npm-package-lookup.d.ts.map +1 -1
- package/dist/ai-service/app-interface/npm-package-lookup.js +111 -0
- package/dist/ai-service/app-interface/npm-package-lookup.js.map +1 -1
- package/dist/ai-service/app-interface/shell.d.ts +71 -3
- package/dist/ai-service/app-interface/shell.d.ts.map +1 -1
- package/dist/ai-service/app-interface/shell.js +575 -23
- package/dist/ai-service/app-interface/shell.js.map +1 -1
- package/dist/ai-service/app-interface/vulnerability-gate.d.ts +83 -0
- package/dist/ai-service/app-interface/vulnerability-gate.d.ts.map +1 -0
- package/dist/ai-service/app-interface/vulnerability-gate.js +543 -0
- package/dist/ai-service/app-interface/vulnerability-gate.js.map +1 -0
- package/dist/ai-service/dev-database-client.d.ts +14 -4
- package/dist/ai-service/dev-database-client.d.ts.map +1 -1
- package/dist/ai-service/dev-database-client.js +1 -24
- package/dist/ai-service/dev-database-client.js.map +1 -1
- package/dist/ai-service/features.d.ts +5 -0
- package/dist/ai-service/features.d.ts.map +1 -1
- package/dist/ai-service/features.js +5 -0
- package/dist/ai-service/features.js.map +1 -1
- package/dist/ai-service/index.d.ts +2 -0
- package/dist/ai-service/index.d.ts.map +1 -1
- package/dist/ai-service/index.js +30 -7
- package/dist/ai-service/index.js.map +1 -1
- package/dist/ai-service/integrations/store.d.ts +3 -0
- package/dist/ai-service/integrations/store.d.ts.map +1 -1
- package/dist/ai-service/integrations/store.js +2 -0
- package/dist/ai-service/integrations/store.js.map +1 -1
- package/dist/ai-service/managed-native-db-availability.d.ts +62 -0
- package/dist/ai-service/managed-native-db-availability.d.ts.map +1 -0
- package/dist/ai-service/managed-native-db-availability.js +37 -0
- package/dist/ai-service/managed-native-db-availability.js.map +1 -0
- package/dist/ai-service/security/vulnerability-triage.d.ts +90 -0
- package/dist/ai-service/security/vulnerability-triage.d.ts.map +1 -0
- package/dist/ai-service/security/vulnerability-triage.js +113 -0
- package/dist/ai-service/security/vulnerability-triage.js.map +1 -0
- package/dist/ai-service/skills/system/superblocks-frontend/skill.generated.d.ts +1 -1
- package/dist/ai-service/skills/system/superblocks-frontend/skill.generated.d.ts.map +1 -1
- package/dist/ai-service/skills/system/superblocks-frontend/skill.generated.js +13 -0
- package/dist/ai-service/skills/system/superblocks-frontend/skill.generated.js.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.d.ts +9 -0
- package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.js +4 -0
- package/dist/ai-service/state-machine/clark-fsm.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.js +2 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.js.map +1 -1
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.d.ts +11 -0
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.js +51 -4
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.js.map +1 -1
- package/dist/ai-service/tasks/factory.d.ts +2 -0
- package/dist/ai-service/tasks/factory.d.ts.map +1 -1
- package/dist/ai-service/tasks/factory.js +7 -0
- package/dist/ai-service/tasks/factory.js.map +1 -1
- package/dist/ai-service/types.d.ts +57 -3
- package/dist/ai-service/types.d.ts.map +1 -1
- package/dist/ai-service/types.js +20 -0
- package/dist/ai-service/types.js.map +1 -1
- package/dist/migration/restructure.js +1 -1
- package/dist/migration-templates/app-fullstack/client/pages/{Page1 → Home}/index.tsx +1 -1
- package/dist/migration-templates/app-fullstack/client/router.tsx +1 -1
- package/dist/migration-templates/app-fullstack/package.json +2 -2
- package/dist/npm/apply-package-json-substitutions.d.ts +19 -0
- package/dist/npm/apply-package-json-substitutions.d.ts.map +1 -0
- package/dist/npm/apply-package-json-substitutions.js +108 -0
- package/dist/npm/apply-package-json-substitutions.js.map +1 -0
- package/dist/policy-gate-callback-mapper.d.ts +1 -1
- package/dist/policy-gate-callback-mapper.d.ts.map +1 -1
- package/dist/policy-gate-callback-mapper.js.map +1 -1
- package/package.json +8 -8
|
@@ -325,7 +325,7 @@ When using integrations in SDK APIs:
|
|
|
325
325
|
1. **Use integration IDs** (UUIDs), not display names - IDs are stable identifiers that won't break if integrations are renamed
|
|
326
326
|
2. **Get the ID from the integrations panel** - each integration has a unique ID visible in its settings
|
|
327
327
|
3. **Store IDs in constants** with descriptive names at the top of the API file for clarity
|
|
328
|
-
4. **Choose a descriptive \`integrations\` map key** — a valid JS identifier derived from the integration's display name /
|
|
328
|
+
4. **Choose a descriptive \`integrations\` map key** — a valid JS identifier derived from the integration's display name / App Database \`logicalName\` (lowercase snake_case). Normalize: lowercase → replace non-alphanumeric with \`_\` → collapse \`_\` → if empty/starts with a digit/reserved word, prefix \`db_\`. Examples: \`pokemon_tracker\` → \`pokemon_tracker\`; \`Orders DB\` → \`orders_db\`; \`2024-orders\` → \`db_2024_orders\`. If two integrations would share a key, disambiguate (e.g. \`orders_db\` / \`orders_db_2\`). Do **not** use a generic placeholder like \`db\` when the integration already has a meaningful name — that key is what appears in generated code and TraceView. SDK README examples that use \`db\` are placeholders only.
|
|
329
329
|
|
|
330
330
|
Example:
|
|
331
331
|
\`\`\`typescript
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-base-system-prompt.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/agent/prompts/build-base-system-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"build-base-system-prompt.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/agent/prompts/build-base-system-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAQpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAStD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC7B,wBAAwB,EAAE,OAAO,CAAC;IAClC,MAAM,CAAC,EAAE,YAAY,GAAG,gBAAgB,GAAG,aAAa,CAAC;CAC1D;AAED,eAAO,MAAM,qBAAqB,GAChC,QAAQ,eAAe,EACvB,OAAO,MAAM,EACb,eAAe,MAAM,EACrB,sBAAsB,MAAM,EAC5B,yBAAyB,MAAM,EAC/B,iBAAiB,cAAc,EAC/B,mCAAiC,WA4WlC,CAAC"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { PROTECTED_CORE_PACKAGES } from "@superblocksteam/library-shared/types";
|
|
2
2
|
import { SUPERBLOCKS_LIVE_GIT_BRANCH } from "@superblocksteam/shared";
|
|
3
3
|
import { getErrorMeta, getPrefixedLogger } from "../../../util/logger.js";
|
|
4
|
+
import { isManagedNativeDbAvailableForClark } from "../../managed-native-db-availability.js";
|
|
4
5
|
import { buildSystemSkillExclusions } from "../../migration-prompt-gating.js";
|
|
5
6
|
import { generateSkillsXml } from "../../skills/index.js";
|
|
6
7
|
import { buildYamlApiSection, buildSdkApiSection, buildApiToolGuidance, } from "./api-prompts.js";
|
|
7
8
|
const logger = getPrefixedLogger("[build-base-system-prompt]");
|
|
8
9
|
export const buildBaseSystemPrompt = (config, mode, factsSection, appKnowledgeSection, onDemandKnowledgeIndex, registryPolicy, v2ToV3MigrationInProgress = false) => {
|
|
10
|
+
const managedNativeDbAvailable = isManagedNativeDbAvailableForClark(config);
|
|
9
11
|
const superblocksDocsGuidance = config.features.superblocksDocsMcpEnabled
|
|
10
12
|
? "For Superblocks product documentation, use the `search_superblocks_docs` tool first for setup, integration, and platform behavior questions. If the docs MCP result is missing or incomplete, then use `web_fetch` against `https://docs.superblocks.com` and, if needed, discover pages via `https://docs.superblocks.com/sitemap.xml`.\nWhen referring to Superblocks pages in your response, always include relative links: [Integrations](/integrations) for the integrations page, or [Integration Name](/integrations/{slug}) for a specific integration (e.g., [Salesforce](/integrations/salesforce), [PostgreSQL](/integrations/postgres))."
|
|
11
13
|
: "For Superblocks product documentation, prefer `https://docs.superblocks.com` as the primary source. If you need to discover the right page first, use the sitemap at `https://docs.superblocks.com/sitemap.xml`, then fetch the specific docs page you need.";
|
|
@@ -21,7 +23,7 @@ The current mode and plan approval status will be given to you in the <current_m
|
|
|
21
23
|
In 'Plan' mode, your goal is to help the user understand and interact with their application, and the data and integrations available to them.
|
|
22
24
|
|
|
23
25
|
**Plan Mode Behavior:**
|
|
24
|
-
- **Without approved plan**: You can use read-only tools freely, plus a small set of product-scoped tools — notably ${config.features.clarkAttachmentDownloadEnabled ? "`listAttachments` and `downloadAttachments` (which materialize uploaded attachments into a private scratch directory), " : ""}\`exitPlanMode\` (to propose a plan for approval)${
|
|
26
|
+
- **Without approved plan**: You can use read-only tools freely, plus a small set of product-scoped tools — notably ${config.features.clarkAttachmentDownloadEnabled ? "`listAttachments` and `downloadAttachments` (which materialize uploaded attachments into a private scratch directory), " : ""}\`exitPlanMode\` (to propose a plan for approval)${managedNativeDbAvailable ? ", and the read-only App Database background-task companions `checkTask` and `waitForTask` (so you can observe progress of any tasks the user started before entering Plan mode)" : ""}, and debug/interactive tools the UI may expose. You cannot otherwise make changes to the user's application files or production data${managedNativeDbAvailable ? " — including provisioning a dev database or applying SQL migrations, which require an approved plan" : ""}. Answer questions, provide suggestions, inspect attachments, and when appropriate, present plans using the exitPlanMode tool.
|
|
25
27
|
- **With approved plan**: When the user accepts one of your plans, you gain access to all tools and can execute the plan by making the necessary changes. You remain in Plan mode throughout execution.
|
|
26
28
|
|
|
27
29
|
**Integrations:**
|
|
@@ -52,12 +54,15 @@ Edits to unread files will be rejected.
|
|
|
52
54
|
**Remembering Application Knowledge:**
|
|
53
55
|
If the user says "/remember", "remember this", "always use X", "make sure you never Y", or otherwise asks you to save a persistent preference or rule about this application, first check existing knowledge entries via available read tools (\`build_readFile\` over \`skills/app/*\` and relevant on-demand knowledge files) and avoid drafting duplicates. Then call \`rememberKnowledge\` to draft entries for approval only when net-new or revised knowledge is needed.
|
|
54
56
|
|
|
55
|
-
${
|
|
57
|
+
${managedNativeDbAvailable
|
|
56
58
|
? `**Dev Database Lifecycle:**
|
|
57
59
|
You can provision and manage lifecycle-controlled dev databases for the application in Build mode (or in Plan mode with an approved plan). Side-effecting kickoff tools are off-limits in unapproved Plan mode, so when you are in Plan mode and the user needs a database, propose a plan that includes these steps.
|
|
58
|
-
|
|
60
|
+
You cannot delete App Database bindings. Explain that deletion is not supported here and direct the user to the Superblocks admin console or support; use the database lifecycle tools only to provision, migrate, or check a binding's status.
|
|
61
|
+
- \`provisionDatabase\` — Create or reuse a dev App Database binding on Amazon RDS. Returns a taskId IMMEDIATELY while RDS provisioning runs in the background.
|
|
59
62
|
- \`startApplyDevDatabaseMigrations\` — Run the binding's SQL migrations. Required after \`provisionDatabase\` if any application tables need to exist; provisioning only creates an empty RDS database.
|
|
60
63
|
- \`checkTask\` (read-only, instant) and \`waitForTask\` (read-only, blocking) — Observe progress. PREFER \`checkTask\` and keep working on unrelated steps while a task runs; only fall back to \`waitForTask\` when \`checkTask\` still reports \`state='running'\` AND you literally have no other useful work to do.
|
|
64
|
+
- After \`checkTask\` or \`waitForTask\` reports the provisioning task completed, use only the \`integrationId\` from that task result for this App Database.
|
|
65
|
+
- If \`provisionDatabase\` itself reports failure, or \`checkTask\` or \`waitForTask\` reports the provisioning task failed, report the error and stop all database-dependent work. This failure policy overrides the general integration guidance above: do not call \`searchIntegrations\` or \`openIntegrationSetup\`, and do not substitute an existing Postgres integration. Only if the user explicitly asks to use a different datasource may you use those tools or an existing integration to select or configure that requested alternative.
|
|
61
66
|
|
|
62
67
|
**SQL migration contents:**
|
|
63
68
|
- Migration \`.sql\` files (e.g. under \`db/migrations/\`) apply in **edit/preview and deployed** environments.
|
|
@@ -212,7 +217,7 @@ ${superblocksDocsGuidance}
|
|
|
212
217
|
|
|
213
218
|
**Before installing any package, check it with \`build_lookupNpmPackage\`** to verify it exists in the configured registry and that you are using a recent version.
|
|
214
219
|
|
|
215
|
-
${buildRegistryPolicyParagraph(registryPolicy)}
|
|
220
|
+
${buildRegistryPolicyParagraph(registryPolicy, config.features.packageInstallGateEnabled === true)}
|
|
216
221
|
<safety_guidance>
|
|
217
222
|
${safetyGuidance}
|
|
218
223
|
</safety_guidance>
|
|
@@ -237,7 +242,13 @@ ALWAYS read components using tools like \`grep\` and \`glob\` when you do not ha
|
|
|
237
242
|
- Leaving orphaned files is unprofessional and creates technical debt
|
|
238
243
|
- If unsure whether a file is used, check with grep/glob first, then delete if unused
|
|
239
244
|
- Always provide clear context in deletion requests (what's being deleted and why)
|
|
240
|
-
- Note: The tool will automatically prompt users for API and page deletions
|
|
245
|
+
- Note: The tool will automatically prompt users for API and page deletions, so be confident in your deletions
|
|
246
|
+
|
|
247
|
+
**Page names must DESCRIBE the page:**
|
|
248
|
+
- A new app starts with one empty page at \`pages/Home\` wired as the \`/\` index route — build the app's landing content there and keep it named \`Home\` unless the user asks for something else
|
|
249
|
+
- In a multi-page app, every page you add beyond that one gets a descriptive PascalCase name for what it shows (e.g. \`Dashboard\`, \`Inventory\`, \`TopBuilders\`) — page names are user-visible in the editor's page switcher, so name them the way you'd label a nav item
|
|
250
|
+
- Rename the starter page only if the app's landing route is really something other than a home page (e.g. \`Overview\`): \`build_renameFile\` every file under \`pages/Home/\` into the new directory, rename the page component to match, and update the import in \`router.tsx\`, keeping it as the \`/\` index route
|
|
251
|
+
- NEVER name a page \`Page1\` (or \`Page2\`, \`Page3\`, ...)
|
|
241
252
|
|
|
242
253
|
**Seeking user input is CRITICAL:**
|
|
243
254
|
- When dealing with a persistent error, before deciding to change approach (eg switch to mock data, simplify UI, etc), ALWAYS check in with the user first
|
|
@@ -288,7 +299,11 @@ Use \`build_manageChecklist\` to give the user real-time visibility into your pr
|
|
|
288
299
|
|
|
289
300
|
**How to manage checklist items:**
|
|
290
301
|
- Break complex tasks into specific, actionable items — not vague descriptions
|
|
291
|
-
- Mark an item \`in_progress\` BEFORE starting work on it
|
|
302
|
+
- Mark an item \`in_progress\` BEFORE starting work on it
|
|
303
|
+
- Keep one hands-on item \`in_progress\` at a time${managedNativeDbAvailable
|
|
304
|
+
? `
|
|
305
|
+
- An item waiting on a background task (e.g. \`provisionDatabase\`) is the exception: leave it \`in_progress\` while the task runs and mark the next hands-on item \`in_progress\` too, so the user sees both moving at once`
|
|
306
|
+
: ""}
|
|
292
307
|
- Mark items \`completed\` immediately after finishing — do not batch completions
|
|
293
308
|
- Only add items you intend to complete — unfinished items block \`build_finalize\`
|
|
294
309
|
- If a task cannot be completed, mark it \`failed\` with a \`failureReason\` — never leave items stuck as \`pending\` or \`in_progress\`
|
|
@@ -683,6 +698,7 @@ ${sdkApiEnabled ? "" : buildYamlApiSection()}
|
|
|
683
698
|
You **must** use \`react-router@7\` in data mode for routing. The framework and declarative modes are **not** supported.
|
|
684
699
|
Standard patterns apply: \`useNavigate()\`, \`useParams()\`, \`useSearchParams()\`.
|
|
685
700
|
If you add new pages or rename page files or export names, you **must** update the router.
|
|
701
|
+
The starter \`pages/Home\` page is bound to the \`/\` index route; keep an index route wired to whichever page is the app's landing page.
|
|
686
702
|
</navigation>
|
|
687
703
|
|
|
688
704
|
<component_usage_guidance>
|
|
@@ -930,9 +946,21 @@ You should always attempt to use an existing component before creating a new one
|
|
|
930
946
|
</design_system_guidance>
|
|
931
947
|
`;
|
|
932
948
|
}
|
|
933
|
-
function
|
|
949
|
+
function buildVulnerablePackageGuidance() {
|
|
950
|
+
return `If \`build_installPackages\` succeeds, treat its security decision as final. Do not volunteer vulnerability claims from your own knowledge; only communicate security findings explicitly returned by the tool.
|
|
951
|
+
If \`build_installPackages\` returns \`NpmInstallBlocked\` with reason \`vulnerable_package\`:
|
|
952
|
+
- Malware findings: never retry or override — choose a different reputable package.
|
|
953
|
+
- CVE findings: the tool may already have triaged exploitability. If install is still blocked, try at most a couple of different reputable replacements that serve the same purpose (prefer packages/versions older than 7 days), install each via \`build_installPackages\` (they are re-checked), and briefly mention any replacement you used in normal narration — do not over-explain security.
|
|
954
|
+
- If a replacement works and you still complete the user's request, do not surface the blocked package to the builder when they did not name it.
|
|
955
|
+
- If no replacement works and the builder did not name the package, explain only the capability that could not ship — no proceed option.
|
|
956
|
+
- If \`userRequested\` is true on the tool result (the package name appears in the user's triggering message), warn the builder, ask for a short reason if they still want it, then call \`build_installPackages\` again with the same packages and \`proceedWithReason\` set to that reason (this shows a confirmation prompt). Never invent a proceed reason.`;
|
|
957
|
+
}
|
|
958
|
+
function buildRegistryPolicyParagraph(registryPolicy, packageInstallGateEnabled) {
|
|
934
959
|
if (!registryPolicy)
|
|
935
960
|
return "";
|
|
961
|
+
const vulnerablePackageGuidance = packageInstallGateEnabled
|
|
962
|
+
? buildVulnerablePackageGuidance()
|
|
963
|
+
: "";
|
|
936
964
|
// Degraded branch: the registry-config service was unreachable when this
|
|
937
965
|
// turn started, so we genuinely do not know whether the org has a private
|
|
938
966
|
// registry. Tell Clark to avoid `npm install` if possible and to frame any
|
|
@@ -940,7 +968,7 @@ function buildRegistryPolicyParagraph(registryPolicy) {
|
|
|
940
968
|
// public-npm advice path, which would be wrong for a previously-configured
|
|
941
969
|
// org during a config-service outage.
|
|
942
970
|
if (registryPolicy.source === "unreachable") {
|
|
943
|
-
return `Your organization's npm registry configuration is temporarily unavailable. Avoid running \`npm install\` if possible; if the user insists, advise that installs may fail and the failure may be transient — do not retry aggressively, and do not tell the user the package is missing from a public or private registry on the basis of a single failure.
|
|
971
|
+
return `Your organization's npm registry configuration is temporarily unavailable. Avoid running \`npm install\` if possible; if the user insists, advise that installs may fail and the failure may be transient — do not retry aggressively, and do not tell the user the package is missing from a public or private registry on the basis of a single failure. ${vulnerablePackageGuidance}
|
|
944
972
|
|
|
945
973
|
`;
|
|
946
974
|
}
|
|
@@ -949,11 +977,11 @@ function buildRegistryPolicyParagraph(registryPolicy) {
|
|
|
949
977
|
// constant so the prompt can never drift from what the tool layer and
|
|
950
978
|
// the DevServerErrorOverlay enforce.
|
|
951
979
|
const protectedPackagesPhrase = PROTECTED_CORE_PACKAGES.map((name) => `\`${name}\``).join(", ");
|
|
952
|
-
return `Your organization uses a private npm registry. Only packages available in that registry can be installed. If \`build_installPackages\` returns \`NpmInstallBlocked\` with reason \`not_in_registry\`, do not retry — explain to the user that the package isn't available and suggest they ask their org admin to add it. Never suggest uninstalling, replacing, or refactoring the app away from core dependencies — any \`@superblocksteam/*\` package, plus ${protectedPackagesPhrase}. If a core dependency is unavailable in the registry, the only fix is for an org admin to make it available there.
|
|
980
|
+
return `Your organization uses a private npm registry. Only packages available in that registry can be installed. If \`build_installPackages\` returns \`NpmInstallBlocked\` with reason \`not_in_registry\`, do not retry — explain to the user that the package isn't available and suggest they ask their org admin to add it. Never suggest uninstalling, replacing, or refactoring the app away from core dependencies — any \`@superblocksteam/*\` package, plus ${protectedPackagesPhrase}. If a core dependency is unavailable in the registry, the only fix is for an org admin to make it available there. ${vulnerablePackageGuidance}
|
|
953
981
|
|
|
954
982
|
`;
|
|
955
983
|
}
|
|
956
|
-
return `Packages are installed from the public npm registry. If \`build_installPackages\` returns \`NpmInstallBlocked\` with reason \`registry_unreachable\`, do not retry — explain that npm is unreachable.
|
|
984
|
+
return `Packages are installed from the public npm registry. If \`build_installPackages\` returns \`NpmInstallBlocked\` with reason \`registry_unreachable\`, do not retry — explain that npm is unreachable. ${vulnerablePackageGuidance}
|
|
957
985
|
|
|
958
986
|
`;
|
|
959
987
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-base-system-prompt.js","sourceRoot":"","sources":["../../../../src/ai-service/agent/prompts/build-base-system-prompt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,MAAM,GAAG,iBAAiB,CAAC,4BAA4B,CAAC,CAAC;AAkB/D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,MAAuB,EACvB,IAAa,EACb,YAAqB,EACrB,mBAA4B,EAC5B,sBAA+B,EAC/B,cAA+B,EAC/B,yBAAyB,GAAG,KAAK,EACjC,EAAE;IACF,MAAM,uBAAuB,GAAG,MAAM,CAAC,QAAQ,CAAC,yBAAyB;QACvE,CAAC,CAAC,snBAAsnB;QACxnB,CAAC,CAAC,8PAA8P,CAAC;IAEnQ,IAAI,QAAQ,GAAG,EAAE,CAAC;IAElB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,QAAQ,GAAG;;;;;;;;;;sHAUuG,MAAM,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAC,CAAC,yHAAyH,CAAC,CAAC,CAAC,EAAE,oDAAoD,
|
|
1
|
+
{"version":3,"file":"build-base-system-prompt.js","sourceRoot":"","sources":["../../../../src/ai-service/agent/prompts/build-base-system-prompt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,kCAAkC,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,MAAM,GAAG,iBAAiB,CAAC,4BAA4B,CAAC,CAAC;AAkB/D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,MAAuB,EACvB,IAAa,EACb,YAAqB,EACrB,mBAA4B,EAC5B,sBAA+B,EAC/B,cAA+B,EAC/B,yBAAyB,GAAG,KAAK,EACjC,EAAE;IACF,MAAM,wBAAwB,GAAG,kCAAkC,CAAC,MAAM,CAAC,CAAC;IAC5E,MAAM,uBAAuB,GAAG,MAAM,CAAC,QAAQ,CAAC,yBAAyB;QACvE,CAAC,CAAC,snBAAsnB;QACxnB,CAAC,CAAC,8PAA8P,CAAC;IAEnQ,IAAI,QAAQ,GAAG,EAAE,CAAC;IAElB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,QAAQ,GAAG;;;;;;;;;;sHAUuG,MAAM,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAC,CAAC,yHAAyH,CAAC,CAAC,CAAC,EAAE,oDAAoD,wBAAwB,CAAC,CAAC,CAAC,iLAAiL,CAAC,CAAC,CAAC,EAAE,wIAAwI,wBAAwB,CAAC,CAAC,CAAC,qGAAqG,CAAC,CAAC,CAAC,EAAE;;;;;;;;EASrzB,MAAM,CAAC,QAAQ,CAAC,uBAAuB;YACrC,CAAC,CAAC;;;;;;;;;;;qLAW+K;YACjL,CAAC,CAAC,EACN;;;;;;;;;;EAWE,wBAAwB;YACtB,CAAC,CAAC;;;;;;;;;;;;;CAaL;YACG,CAAC,CAAC,EACN,GACM,MAAM,CAAC,QAAQ,CAAC,gBAAgB;YAC9B,CAAC,CAAC;;;;;;;sCAQE,MAAM,CAAC,QAAQ,CAAC,mBAAmB;gBACjC,CAAC,CAAC,oEAAoE;gBACtE,CAAC,CAAC,6BACN;uEAEE,MAAM,CAAC,QAAQ,CAAC,mBAAmB;gBACjC,CAAC,CAAC,uGAAuG;gBACzG,CAAC,CAAC,kFACN;2CAEE,MAAM,CAAC,QAAQ,CAAC,mBAAmB;gBACjC,CAAC,CAAC,2EAA2E;gBAC7E,CAAC,CAAC,uDACN;0lBAEE,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OACtD;;;EAIR,MAAM,CAAC,QAAQ,CAAC,mBAAmB;gBACjC,CAAC,CAAC;;;yFAGmF,2BAA2B;qEAC/C,2BAA2B;iJACiD,2BAA2B;;;wGAGpE,2BAA2B;;CAElI;gBACG,CAAC,CAAC;0PACoP,2BAA2B,sDAAsD,2BAA2B;CAEtW;CACC;YACO,CAAC,CAAC;;CAGN;;CAEH,CAAC;IACA,CAAC;IAED,MAAM,cAAc,GAClB,MAAM,CAAC,QAAQ,CAAC,oBAAoB,IAAI,uBAAuB,CAAC;IAElE,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,IAAI,KAAK,CAAC;IAC7D,MAAM,uBAAuB,GAC3B,MAAM,CAAC,QAAQ,CAAC,uBAAuB,IAAI,KAAK,CAAC;IAEnD,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;IAElD,8EAA8E;IAC9E,MAAM,cAAc,GAAG,SAAS;QAC9B,CAAC,CAAC,yBAAyB,CACvB,aAAa,EACb,uBAAuB,EACvB,yBAAyB,CAC1B;QACH,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,YAAY,GAAG,cAAc,KAAK,IAAI,CAAC;IAE7C,oFAAoF;IACpF,MAAM,gBAAgB,GAAG,YAAY;QACnC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,6BAA6B,CAAC,aAAa,CAAC,CAAC;IAEjD,uCAAuC;IACvC,MAAM,CAAC,IAAI,CAAC,gDAAgD,EAAE;QAC5D,oBAAoB,EAAE,CAAC,CAAC,YAAY;QACpC,uBAAuB,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;QAClD,oBAAoB,EAAE,CAAC,CAAC,sBAAsB;QAC9C,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,IAAI,CAAC;KAC7D,CAAC,CAAC;IAEH,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,IAAI,CAAC,gCAAgC,GAAG,YAAY,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,sBAAsB,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,8BAA8B,GAAG,sBAAsB,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,CACL,QAAQ;QACR,MAAM,CAAC;;WAEA,WAAW;;;;;;;;;;;;EAYpB,mBAAmB,CAAC,YAAY,EAAE,mBAAmB,CAAC;;;;;;EAOtD,MAAM,CAAC,QAAQ,CAAC,8BAA8B;YAC5C,CAAC,CAAC;;;;;;;;;;;;;;;;6JAiBE,uBAAuB;gBACrB,CAAC,CAAC;sUAC0T;gBAC5T,CAAC,CAAC,EACN;gIAC0H;YAC5H,CAAC,CAAC;;2FAGN;;;EAGE,cAAc,IAAI,EAAE;EACpB,sBAAsB,CAAC,CAAC,CAAC,8BAA8B,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BpF,uBAAuB;;;;EAIvB,4BAA4B,CAC5B,cAAc,EACd,MAAM,CAAC,QAAQ,CAAC,yBAAyB,KAAK,IAAI,CACnD;;EAEC,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oDAkFV,wBAAwB;YACtB,CAAC,CAAC;6NACmN;YACrN,CAAC,CAAC,EACN;;;;;;;;;;;;EAYF,gBAAgB;EAChB,aAAa,CAAC,CAAC,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;;;;;;EAMtE,oBAAoB,CAAC,aAAa,CAAC;;CAEpC,CACE,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAEvC;;;;;;;;;;;GAWG;AACH,SAAS,mBAAmB,CAC1B,YAAqB,EACrB,mBAA4B;IAE5B,MAAM,QAAQ,GAAG,CAAC,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC;IACxC,MAAM,eAAe,GAAG,CAAC,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC;IAEtD,IAAI,CAAC,QAAQ,IAAI,CAAC,eAAe,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,IAAI,CAAC,YAAa,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,eAAe,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,mBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAE7C,IAAI,KAAK,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;QAC3C,MAAM,CAAC,IAAI,CACT,kCAAkC,KAAK,CAAC,MAAM,OAAO,uBAAuB,aAAa,CAC1F,CAAC;QACF,MAAM,iBAAiB,GACrB,kGAAkG;YAClG,iGAAiG;YACjG,0GAA0G,CAAC;QAC7G,KAAK;YACH,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,GAAG,iBAAiB,CAAC,MAAM,CAAC;gBAClE,iBAAiB,CAAC;IACtB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,yBAAyB,CAChC,aAAsB,EACtB,uBAAgC,EAChC,yBAAkC;IAElC,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,0BAA0B,CAAC;YAC/C,aAAa;YACb,uBAAuB;YACvB,yBAAyB;SAC1B,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,iBAAiB,CACjC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,SAAS,CACzD,CAAC;QAEF,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CACT,oEAAoE,CACrE,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QAEjD,MAAM,gBAAgB,GAAG,aAAa;YACpC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,MAAM,CAAC;;;;;;;;;CASd,CAAC;QAEE,OAAO,MAAM,CAAC;;;;;;;EAOhB,SAAS;;;EAGT,gBAAgB;;;;;;;;;;;;;;;;CAgBjB,CAAC;IACA,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CACV,0EAA0E,EAC1E,YAAY,CAAC,KAAK,CAAC,CACpB,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,8BAA8B,CAAC,cAAsB;IAC5D,OAAO,MAAM,CAAC;;;;;;;;;EASd,cAAc;;;;;;;;CAQf,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,SAAS,6BAA6B,CAAC,aAAsB;IAC3D,OAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2Od,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4P3C,CAAC;AACF,CAAC;AAED,SAAS,8BAA8B;IACrC,OAAO;;;;;;gWAMuV,CAAC;AACjW,CAAC;AAED,SAAS,4BAA4B,CACnC,cAA0C,EAC1C,yBAAkC;IAElC,IAAI,CAAC,cAAc;QAAE,OAAO,EAAE,CAAC;IAC/B,MAAM,yBAAyB,GAAG,yBAAyB;QACzD,CAAC,CAAC,8BAA8B,EAAE;QAClC,CAAC,CAAC,EAAE,CAAC;IAEP,yEAAyE;IACzE,0EAA0E;IAC1E,2EAA2E;IAC3E,uEAAuE;IACvE,2EAA2E;IAC3E,sCAAsC;IACtC,IAAI,cAAc,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;QAC5C,OAAO,8VAA8V,yBAAyB;;CAEjY,CAAC;IACA,CAAC;IAED,IAAI,cAAc,CAAC,wBAAwB,EAAE,CAAC;QAC5C,yEAAyE;QACzE,sEAAsE;QACtE,qCAAqC;QACrC,MAAM,uBAAuB,GAAG,uBAAuB,CAAC,GAAG,CACzD,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,CACxB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,OAAO,kcAAkc,uBAAuB,uHAAuH,yBAAyB;;CAEnnB,CAAC;IACA,CAAC;IAED,OAAO,yMAAyM,yBAAyB;;CAE1O,CAAC;AACF,CAAC;AAED,MAAM,uBAAuB,GAAG,MAAM,CAAC;;;;;;;;CAQtC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-security-scan-prompt.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/agent/prompts/build-security-scan-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,KAAK,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ;
|
|
1
|
+
{"version":3,"file":"build-security-scan-prompt.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/agent/prompts/build-security-scan-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,KAAK,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ;AAsBD,wBAAgB,0BAA0B,IAAI,MAAM,CAsDnD;AA8JD,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,uBAAuB,EACnC,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAYR"}
|
|
@@ -5,9 +5,25 @@
|
|
|
5
5
|
* Layer 2: App Context — dynamic, per-app metadata to prevent false positives.
|
|
6
6
|
* Layer 3: Admin Policy Prompt — what to look for (from template or IT admin).
|
|
7
7
|
*/
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
|
|
8
|
+
// Policy of the Superblocks-managed security agent, used whenever a review carries no admin prompt.
|
|
9
|
+
// Admin-authored agents replace it with their own; keep this text in sync with the General Security
|
|
10
|
+
// Review starting template in review_policy_agent_template.
|
|
11
|
+
const DEFAULT_ADMIN_PROMPT = [
|
|
12
|
+
"Perform a comprehensive security review of this application.",
|
|
13
|
+
"Look for all common vulnerability categories including:",
|
|
14
|
+
"",
|
|
15
|
+
"- Hardcoded secrets, API keys, tokens, or passwords in source code",
|
|
16
|
+
"- SQL injection, code injection (eval, dynamic execution), command injection, SSRF, or template injection",
|
|
17
|
+
"- XSS via user-controlled data rendered as raw HTML without sanitization",
|
|
18
|
+
"- Missing or broken authentication and authorization checks",
|
|
19
|
+
"- Sensitive data (PII, credentials) logged, leaked in responses, or stored insecurely",
|
|
20
|
+
"- Weak or deprecated cryptographic algorithms",
|
|
21
|
+
"- Insecure network configuration (wildcard CORS, disabled TLS verification, open redirects)",
|
|
22
|
+
"- Insecure deserialization or unrestricted file uploads",
|
|
23
|
+
"- API endpoints that return excessive data or expose internal details",
|
|
24
|
+
"",
|
|
25
|
+
"Report any security concern you find, even if it doesn't fit neatly into these categories.",
|
|
26
|
+
].join("\n");
|
|
11
27
|
export function buildSecurityAgentSkeleton() {
|
|
12
28
|
const today = new Date().toISOString().split("T")[0];
|
|
13
29
|
return `## Role
|
|
@@ -209,7 +225,7 @@ whether they are safe platform conventions or genuine security concerns.`);
|
|
|
209
225
|
export function composeSecurityAgentPrompt(appContext, adminPrompt) {
|
|
210
226
|
const skeleton = buildSecurityAgentSkeleton();
|
|
211
227
|
const context = buildSecurityAgentAppContext(appContext);
|
|
212
|
-
const policy = adminPrompt
|
|
228
|
+
const policy = adminPrompt?.trim() ? adminPrompt : DEFAULT_ADMIN_PROMPT;
|
|
213
229
|
return `${skeleton}
|
|
214
230
|
|
|
215
231
|
${context}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-security-scan-prompt.js","sourceRoot":"","sources":["../../../../src/ai-service/agent/prompts/build-security-scan-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,+
|
|
1
|
+
{"version":3,"file":"build-security-scan-prompt.js","sourceRoot":"","sources":["../../../../src/ai-service/agent/prompts/build-security-scan-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,oGAAoG;AACpG,oGAAoG;AACpG,4DAA4D;AAC5D,MAAM,oBAAoB,GAAG;IAC3B,8DAA8D;IAC9D,yDAAyD;IACzD,EAAE;IACF,oEAAoE;IACpE,2GAA2G;IAC3G,0EAA0E;IAC1E,6DAA6D;IAC7D,uFAAuF;IACvF,+CAA+C;IAC/C,6FAA6F;IAC7F,yDAAyD;IACzD,uEAAuE;IACvE,EAAE;IACF,4FAA4F;CAC7F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,UAAU,0BAA0B;IACxC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAErD,OAAO;;;;;;WAME,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yIA4CyH,CAAC;AAC1I,CAAC;AAED,SAAS,4BAA4B,CACnC,OAAgC;IAEhC,MAAM,QAAQ,GAAa;QACzB;;;;;;;;;;;;;;;kBAec;KACf,CAAC;IAEF,QAAQ,CAAC,IAAI,CAAC;;;;;;;iGAOiF,CAAC,CAAC;IAEjG,QAAQ,CAAC,IAAI,CAAC;;;;;;;;;;iDAUiC,CAAC,CAAC;IAEjD,IAAI,OAAO,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,eAAe,GAAG,OAAO,CAAC,YAAY;aACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,UAAU,GAAG,CAAC;aAC/C,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,QAAQ,CAAC,IAAI,CAAC;;;;EAIhB,eAAe;;iFAEgE,CAAC,CAAC;IACjF,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFA4CkE,CAAC,CAAC;IAElF,QAAQ,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;4FAe4E,CAAC,CAAC;IAE5F,QAAQ,CAAC,IAAI,CAAC;;;;;;;;;;;;gFAYgE,CAAC,CAAC;IAEhF,QAAQ,CAAC,IAAI,CAAC;;;;;;mEAMmD,CAAC,CAAC;IAEnE,QAAQ,CAAC,IAAI,CAAC;;;;;;;;;;yEAUyD,CAAC,CAAC;IAEzE,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,UAAmC,EACnC,WAAoB;IAEpB,MAAM,QAAQ,GAAG,0BAA0B,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,4BAA4B,CAAC,UAAU,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,oBAAoB,CAAC;IAExE,OAAO,GAAG,QAAQ;;EAElB,OAAO;;;;EAIP,MAAM,EAAE,CAAC;AACX,CAAC"}
|
|
@@ -156,7 +156,7 @@ ${toolsSection}
|
|
|
156
156
|
|
|
157
157
|
## Embedded apps (embed hooks)
|
|
158
158
|
- First, quickly determine whether this app actually uses embed hooks:
|
|
159
|
-
- Use \`read\` to inspect the current page source (usually \`pages/Page1/index.tsx\`) and search for \`useEmitEmbedEvent\` / \`useEmbedEvent\` / \`useEmbedProperties\`.
|
|
159
|
+
- Use \`read\` to inspect the current page source (usually \`pages/Home/index.tsx\` or \`pages/Page1/index.tsx\`) and search for \`useEmitEmbedEvent\` / \`useEmbedEvent\` / \`useEmbedProperties\`.
|
|
160
160
|
- If neither hook exists, do not run embed-specific checks.
|
|
161
161
|
- If \`useEmitEmbedEvent\` exists:
|
|
162
162
|
- After an action that should emit (typically **submit**, **delete**, **clear**), immediately call \`browser_playwright_action\` with \`action: "getEmbedEvents"\`.
|
|
@@ -2,6 +2,12 @@ export interface MutationInfo {
|
|
|
2
2
|
type: string;
|
|
3
3
|
name: string;
|
|
4
4
|
details: string;
|
|
5
|
+
/**
|
|
6
|
+
* Integration UUID when the mutation site includes one — either a string
|
|
7
|
+
* literal (`postgres("…")` / `new PostgreSQL("step", "…", …)`) or a
|
|
8
|
+
* top-level `const ID = "…"` reference.
|
|
9
|
+
*/
|
|
10
|
+
integrationId?: string;
|
|
5
11
|
}
|
|
6
12
|
export declare const extractIntegrationIdsFromSource: (source: string) => string[];
|
|
7
13
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/agent/tools/apis/analysis.ts"],"names":[],"mappings":"AAkRA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/agent/tools/apis/analysis.ts"],"names":[],"mappings":"AAkRA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAKD,eAAO,MAAM,+BAA+B,GAAI,QAAQ,MAAM,KAAG,MAAM,EAiBtE,CAAC;AA6qBF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,GAClC,gBAAgB,MAAM,EACtB,YAAY,MAAM,KACjB;IAAE,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAoBtD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,MAAM,EACd,aAAa,MAAM,KAClB,YAAY,EA+bd,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,EACd,aAAa,MAAM,KAClB,OAMF,CAAC"}
|
|
@@ -306,6 +306,42 @@ const extractStringValue = (node) => {
|
|
|
306
306
|
}
|
|
307
307
|
return null;
|
|
308
308
|
};
|
|
309
|
+
/**
|
|
310
|
+
* Top-level `const ID = "uuid"` bindings. Same shape Clark / SDK APIs use so
|
|
311
|
+
* the UUID is not inlined at every call site. Only `const` is accepted —
|
|
312
|
+
* `let`/`var` can be reassigned and must not attribute mutations.
|
|
313
|
+
*/
|
|
314
|
+
const buildTopLevelStringLiteralMap = (programBody) => {
|
|
315
|
+
const literals = new Map();
|
|
316
|
+
for (const statement of programBody) {
|
|
317
|
+
if (!t.isVariableDeclaration(statement) || statement.kind !== "const") {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
for (const declaration of statement.declarations) {
|
|
321
|
+
if (!t.isIdentifier(declaration.id) || !declaration.init)
|
|
322
|
+
continue;
|
|
323
|
+
const value = extractStringValue(declaration.init);
|
|
324
|
+
if (value !== null) {
|
|
325
|
+
literals.set(declaration.id.name, value);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return literals;
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* Resolve an integration-id argument that is either a string literal or a
|
|
333
|
+
* reference to a top-level const string. Unresolvable identifiers stay
|
|
334
|
+
* undefined so auto-allow treats the mutation as unattributed.
|
|
335
|
+
*/
|
|
336
|
+
const resolveIntegrationIdArg = (node, stringLiterals) => {
|
|
337
|
+
const literal = extractStringValue(node);
|
|
338
|
+
if (literal !== null)
|
|
339
|
+
return literal;
|
|
340
|
+
if (t.isIdentifier(node)) {
|
|
341
|
+
return stringLiterals.get(node.name);
|
|
342
|
+
}
|
|
343
|
+
return undefined;
|
|
344
|
+
};
|
|
309
345
|
const extractPropertyValue = (configNode, propertyName) => {
|
|
310
346
|
if (!t.isObjectExpression(configNode))
|
|
311
347
|
return null;
|
|
@@ -316,6 +352,29 @@ const extractPropertyValue = (configNode, propertyName) => {
|
|
|
316
352
|
return null;
|
|
317
353
|
return extractStringValue(prop.value);
|
|
318
354
|
};
|
|
355
|
+
/**
|
|
356
|
+
* Distinguish a missing object property from one whose value is not a string
|
|
357
|
+
* literal (identifier, call, template, etc.). Auto-allow paths fail closed on
|
|
358
|
+
* unresolved write-relevant fields.
|
|
359
|
+
*/
|
|
360
|
+
const resolveObjectPropertyString = (configNode, propertyName) => {
|
|
361
|
+
if (!t.isObjectExpression(configNode))
|
|
362
|
+
return { kind: "missing" };
|
|
363
|
+
const prop = configNode.properties.find((p) => t.isObjectProperty(p) &&
|
|
364
|
+
t.isIdentifier(p.key) &&
|
|
365
|
+
p.key.name === propertyName);
|
|
366
|
+
if (!prop || !t.isObjectProperty(prop))
|
|
367
|
+
return { kind: "missing" };
|
|
368
|
+
// Only direct string/template literals count as resolved. Arrow functions
|
|
369
|
+
// and identifiers can evaluate to writes at runtime — treat as unresolved.
|
|
370
|
+
if (!t.isStringLiteral(prop.value) && !t.isTemplateLiteral(prop.value)) {
|
|
371
|
+
return { kind: "unresolved" };
|
|
372
|
+
}
|
|
373
|
+
const value = extractStringValue(prop.value);
|
|
374
|
+
if (value !== null)
|
|
375
|
+
return { kind: "literal", value };
|
|
376
|
+
return { kind: "unresolved" };
|
|
377
|
+
};
|
|
319
378
|
const getIntegrationTypeName = (node) => {
|
|
320
379
|
if (t.isIdentifier(node)) {
|
|
321
380
|
return node.name;
|
|
@@ -505,9 +564,15 @@ const detectSdkMutation = (className, runFn, source) => {
|
|
|
505
564
|
: null;
|
|
506
565
|
}
|
|
507
566
|
if (REST_INTEGRATION_TYPES.includes(className)) {
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
567
|
+
if (/method:\s*["'`](POST|PUT|DELETE|PATCH)["'`]/i.test(cleanBody)) {
|
|
568
|
+
return "HTTP mutation method detected";
|
|
569
|
+
}
|
|
570
|
+
// Fail closed: a method binding that isn't a clear safe literal may write.
|
|
571
|
+
if (/method:\s*/i.test(cleanBody) &&
|
|
572
|
+
!/method:\s*["'`](GET|HEAD|OPTIONS)["'`]/i.test(cleanBody)) {
|
|
573
|
+
return "HTTP method unresolved — treating as possible mutation";
|
|
574
|
+
}
|
|
575
|
+
return null;
|
|
511
576
|
}
|
|
512
577
|
if (className === "Redis") {
|
|
513
578
|
return REDIS_WRITE_COMMANDS.some((cmd) => new RegExp(`["'\`]\\s*${cmd}\\b`, "i").test(cleanBody))
|
|
@@ -550,13 +615,14 @@ const findRunFunction = (apiConfigNode) => {
|
|
|
550
615
|
}
|
|
551
616
|
return null;
|
|
552
617
|
};
|
|
553
|
-
const handleSdkIntegrationMutation = (className, integrationKey, apiConfigNode, source, mutations) => {
|
|
618
|
+
const handleSdkIntegrationMutation = (className, integrationKey, apiConfigNode, source, mutations, integrationId) => {
|
|
554
619
|
const runFn = findRunFunction(apiConfigNode);
|
|
555
620
|
if (!runFn) {
|
|
556
621
|
mutations.push({
|
|
557
622
|
type: className,
|
|
558
623
|
name: integrationKey,
|
|
559
624
|
details: `SDK API integration (${className}) may perform mutations`,
|
|
625
|
+
integrationId,
|
|
560
626
|
});
|
|
561
627
|
return;
|
|
562
628
|
}
|
|
@@ -566,9 +632,16 @@ const handleSdkIntegrationMutation = (className, integrationKey, apiConfigNode,
|
|
|
566
632
|
type: className,
|
|
567
633
|
name: integrationKey,
|
|
568
634
|
details,
|
|
635
|
+
integrationId,
|
|
569
636
|
});
|
|
570
637
|
}
|
|
571
638
|
};
|
|
639
|
+
const integrationIdFromPluginCall = (callNode, stringLiterals) => {
|
|
640
|
+
const firstArg = callNode.arguments[0];
|
|
641
|
+
if (!firstArg || !t.isExpression(firstArg))
|
|
642
|
+
return undefined;
|
|
643
|
+
return resolveIntegrationIdArg(firstArg, stringLiterals);
|
|
644
|
+
};
|
|
572
645
|
const extractStepNames = (source) => {
|
|
573
646
|
const stepNames = new Set();
|
|
574
647
|
const stepNameRegex = /new\s+(JavaScript|Python)\s*\(\s*["'`]([^"'`]+)["'`]/g;
|
|
@@ -585,6 +658,9 @@ const buildSdkPluginVariableMap = (ast) => {
|
|
|
585
658
|
const refs = new Map();
|
|
586
659
|
traverse(ast, {
|
|
587
660
|
VariableDeclarator(path) {
|
|
661
|
+
const declaration = path.parent;
|
|
662
|
+
if (!t.isVariableDeclaration(declaration))
|
|
663
|
+
return;
|
|
588
664
|
const id = path.node.id;
|
|
589
665
|
const init = path.node.init;
|
|
590
666
|
if (!t.isIdentifier(id))
|
|
@@ -597,7 +673,12 @@ const buildSdkPluginVariableMap = (ast) => {
|
|
|
597
673
|
const className = SDK_PLUGIN_TO_CLASS.get(pluginId);
|
|
598
674
|
if (!className)
|
|
599
675
|
return;
|
|
600
|
-
refs.set(id.name, {
|
|
676
|
+
refs.set(id.name, {
|
|
677
|
+
pluginId,
|
|
678
|
+
className,
|
|
679
|
+
callNode: init,
|
|
680
|
+
isConstBinding: declaration.kind === "const",
|
|
681
|
+
});
|
|
601
682
|
},
|
|
602
683
|
});
|
|
603
684
|
return refs;
|
|
@@ -744,6 +825,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
744
825
|
throw new Error("Failed to parse source code");
|
|
745
826
|
}
|
|
746
827
|
const sdkPluginVars = buildSdkPluginVariableMap(ast);
|
|
828
|
+
const stringLiterals = buildTopLevelStringLiteralMap(ast.program.body);
|
|
747
829
|
// Pre-check: detect if the target export exists in the file even if it has
|
|
748
830
|
// no integrations (an integration-less API cannot have mutations, so we must
|
|
749
831
|
// not fall back to unscoped analysis just because no integration handler ran).
|
|
@@ -788,6 +870,15 @@ export const extractMutations = (source, exportName) => {
|
|
|
788
870
|
const name = extractStringValue(args[0]);
|
|
789
871
|
if (!name)
|
|
790
872
|
return;
|
|
873
|
+
// `new Plugin("step", "<integrationId>", config)` — args[1] is an ID when
|
|
874
|
+
// it's a string literal or a top-level const string ref; object configs
|
|
875
|
+
// (JS/Python steps, RestApi without an ID) leave this undefined.
|
|
876
|
+
const integrationId = args[1] && t.isExpression(args[1])
|
|
877
|
+
? resolveIntegrationIdArg(args[1], stringLiterals)
|
|
878
|
+
: undefined;
|
|
879
|
+
const recordMutation = (info) => {
|
|
880
|
+
mutations.push(integrationId ? { ...info, integrationId } : { ...info });
|
|
881
|
+
};
|
|
791
882
|
if ((typeName === "JavaScript" || typeName === "Python") &&
|
|
792
883
|
jsStepNames.has(name)) {
|
|
793
884
|
const configArg = args[1];
|
|
@@ -813,7 +904,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
813
904
|
const statementValue = statementProp.value;
|
|
814
905
|
const statement = extractStringValue(statementValue);
|
|
815
906
|
if (statement && isSqlMutation(statement)) {
|
|
816
|
-
|
|
907
|
+
recordMutation({
|
|
817
908
|
type: typeName,
|
|
818
909
|
name,
|
|
819
910
|
details: `SQL mutation detected`,
|
|
@@ -823,7 +914,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
823
914
|
t.isFunctionExpression(statementValue)) {
|
|
824
915
|
// First check if the function body itself contains SQL mutations
|
|
825
916
|
if (scanJavaScriptForSqlMutations(statementValue, source)) {
|
|
826
|
-
|
|
917
|
+
recordMutation({
|
|
827
918
|
type: typeName,
|
|
828
919
|
name,
|
|
829
920
|
details: `SQL mutation detected`,
|
|
@@ -835,7 +926,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
835
926
|
for (const paramName of paramNames) {
|
|
836
927
|
const jsStep = jsSteps.get(paramName);
|
|
837
928
|
if (jsStep && scanJavaScriptForSqlMutations(jsStep, source)) {
|
|
838
|
-
|
|
929
|
+
recordMutation({
|
|
839
930
|
type: typeName,
|
|
840
931
|
name,
|
|
841
932
|
details: `SQL mutation detected (references ${paramName} which builds mutation query)`,
|
|
@@ -851,7 +942,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
851
942
|
if (statementValue.start && statementValue.end) {
|
|
852
943
|
const templateContent = source.slice(statementValue.start, statementValue.end);
|
|
853
944
|
if (isSqlMutation(templateContent)) {
|
|
854
|
-
|
|
945
|
+
recordMutation({
|
|
855
946
|
type: typeName,
|
|
856
947
|
name,
|
|
857
948
|
details: `SQL mutation detected`,
|
|
@@ -871,12 +962,23 @@ export const extractMutations = (source, exportName) => {
|
|
|
871
962
|
const configArg = args[2] || args[1];
|
|
872
963
|
if (!configArg)
|
|
873
964
|
return;
|
|
874
|
-
const method =
|
|
875
|
-
if (method
|
|
876
|
-
|
|
965
|
+
const method = resolveObjectPropertyString(configArg, "method");
|
|
966
|
+
if (method.kind === "unresolved") {
|
|
967
|
+
// Fail closed: a dynamic method (e.g. `method: HTTP_METHOD`) may be
|
|
968
|
+
// a write at runtime. Leave it unattributed only when the id itself
|
|
969
|
+
// is missing; otherwise keep the id so WRITE escalation still works.
|
|
970
|
+
recordMutation({
|
|
971
|
+
type: typeName,
|
|
972
|
+
name,
|
|
973
|
+
details: "HTTP method unresolved — treating as possible mutation",
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
else if (method.kind === "literal" &&
|
|
977
|
+
HTTP_MUTATION_METHODS.includes(method.value.toUpperCase())) {
|
|
978
|
+
recordMutation({
|
|
877
979
|
type: typeName,
|
|
878
980
|
name,
|
|
879
|
-
details: `HTTP ${method.toUpperCase()} mutation`,
|
|
981
|
+
details: `HTTP ${method.value.toUpperCase()} mutation`,
|
|
880
982
|
});
|
|
881
983
|
}
|
|
882
984
|
}
|
|
@@ -886,7 +988,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
886
988
|
return;
|
|
887
989
|
const action = extractPropertyValue(configArg, "action");
|
|
888
990
|
if (action && DYNAMODB_MUTATION_ACTIONS.includes(action)) {
|
|
889
|
-
|
|
991
|
+
recordMutation({
|
|
890
992
|
type: typeName,
|
|
891
993
|
name,
|
|
892
994
|
details: `DynamoDB ${action} mutation`,
|
|
@@ -906,7 +1008,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
906
1008
|
const actionField = extractPropertyValue(actionProp.value, "action");
|
|
907
1009
|
if (actionField &&
|
|
908
1010
|
SALESFORCE_MUTATION_ACTIONS.includes(actionField)) {
|
|
909
|
-
|
|
1011
|
+
recordMutation({
|
|
910
1012
|
type: typeName,
|
|
911
1013
|
name,
|
|
912
1014
|
details: `Salesforce ${actionField} mutation`,
|
|
@@ -915,7 +1017,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
915
1017
|
}
|
|
916
1018
|
}
|
|
917
1019
|
else if (typeName === "Email") {
|
|
918
|
-
|
|
1020
|
+
recordMutation({
|
|
919
1021
|
type: typeName,
|
|
920
1022
|
name,
|
|
921
1023
|
details: "Email send mutation",
|
|
@@ -927,7 +1029,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
927
1029
|
return;
|
|
928
1030
|
const query = extractPropertyValue(configArg, "query");
|
|
929
1031
|
if (query && /^\s*mutation\s/i.test(query)) {
|
|
930
|
-
|
|
1032
|
+
recordMutation({
|
|
931
1033
|
type: typeName,
|
|
932
1034
|
name,
|
|
933
1035
|
details: "GraphQL mutation",
|
|
@@ -940,7 +1042,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
940
1042
|
return;
|
|
941
1043
|
const operation = extractPropertyValue(configArg, "operation");
|
|
942
1044
|
if (operation && MONGODB_MUTATION_OPERATIONS.includes(operation)) {
|
|
943
|
-
|
|
1045
|
+
recordMutation({
|
|
944
1046
|
type: typeName,
|
|
945
1047
|
name,
|
|
946
1048
|
details: `MongoDB ${operation} mutation`,
|
|
@@ -953,7 +1055,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
953
1055
|
return;
|
|
954
1056
|
const action = extractPropertyValue(configArg, "action");
|
|
955
1057
|
if (action && S3_MUTATION_ACTIONS.includes(action)) {
|
|
956
|
-
|
|
1058
|
+
recordMutation({
|
|
957
1059
|
type: typeName,
|
|
958
1060
|
name,
|
|
959
1061
|
details: `S3 ${action} mutation`,
|
|
@@ -966,7 +1068,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
966
1068
|
return;
|
|
967
1069
|
const action = extractPropertyValue(configArg, "action");
|
|
968
1070
|
if (action && GCS_MUTATION_ACTIONS.includes(action)) {
|
|
969
|
-
|
|
1071
|
+
recordMutation({
|
|
970
1072
|
type: typeName,
|
|
971
1073
|
name,
|
|
972
1074
|
details: `GCS ${action} mutation`,
|
|
@@ -974,7 +1076,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
974
1076
|
}
|
|
975
1077
|
}
|
|
976
1078
|
else if (typeName === "SMTP") {
|
|
977
|
-
|
|
1079
|
+
recordMutation({
|
|
978
1080
|
type: typeName,
|
|
979
1081
|
name,
|
|
980
1082
|
details: "SMTP send mutation",
|
|
@@ -986,7 +1088,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
986
1088
|
return;
|
|
987
1089
|
const action = extractPropertyValue(configArg, "action");
|
|
988
1090
|
if (action && COUCHBASE_MUTATION_ACTIONS.includes(action)) {
|
|
989
|
-
|
|
1091
|
+
recordMutation({
|
|
990
1092
|
type: typeName,
|
|
991
1093
|
name,
|
|
992
1094
|
details: `Couchbase ${action} mutation`,
|
|
@@ -995,7 +1097,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
995
1097
|
else if (action === "runSql") {
|
|
996
1098
|
const sqlBody = extractPropertyValue(configArg, "sqlBody");
|
|
997
1099
|
if (sqlBody && isSqlMutation(sqlBody)) {
|
|
998
|
-
|
|
1100
|
+
recordMutation({
|
|
999
1101
|
type: typeName,
|
|
1000
1102
|
name,
|
|
1001
1103
|
details: `Couchbase SQL++ mutation: ${sqlBody.slice(0, 50)}`,
|
|
@@ -1012,7 +1114,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
1012
1114
|
const pointAction = extractPropertyValue(configArg, "pointAction");
|
|
1013
1115
|
if (pointAction &&
|
|
1014
1116
|
COSMOSDB_MUTATION_POINT_ACTIONS.includes(pointAction)) {
|
|
1015
|
-
|
|
1117
|
+
recordMutation({
|
|
1016
1118
|
type: typeName,
|
|
1017
1119
|
name,
|
|
1018
1120
|
details: `CosmosDB ${pointAction} mutation`,
|
|
@@ -1057,7 +1159,7 @@ export const extractMutations = (source, exportName) => {
|
|
|
1057
1159
|
enclosingExport !== undefined &&
|
|
1058
1160
|
enclosingExport !== exportName)
|
|
1059
1161
|
return;
|
|
1060
|
-
handleSdkIntegrationMutation(className, integrationKey, apiConfigNode, source, mutations);
|
|
1162
|
+
handleSdkIntegrationMutation(className, integrationKey, apiConfigNode, source, mutations, integrationIdFromPluginCall(path.node, stringLiterals));
|
|
1061
1163
|
},
|
|
1062
1164
|
Identifier(path) {
|
|
1063
1165
|
const varInfo = sdkPluginVars.get(path.node.name);
|
|
@@ -1091,7 +1193,9 @@ export const extractMutations = (source, exportName) => {
|
|
|
1091
1193
|
enclosingExport !== undefined &&
|
|
1092
1194
|
enclosingExport !== exportName)
|
|
1093
1195
|
return;
|
|
1094
|
-
handleSdkIntegrationMutation(varInfo.className, integrationKey, apiConfigNode, source, mutations
|
|
1196
|
+
handleSdkIntegrationMutation(varInfo.className, integrationKey, apiConfigNode, source, mutations, varInfo.isConstBinding
|
|
1197
|
+
? integrationIdFromPluginCall(varInfo.callNode, stringLiterals)
|
|
1198
|
+
: undefined);
|
|
1095
1199
|
},
|
|
1096
1200
|
});
|
|
1097
1201
|
// If exportName was requested but not found in the file (e.g. stale registry),
|