@agent-native/core 0.148.0 → 0.149.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/corpus/README.md +1 -1
- package/corpus/templates/analytics/changelog/2026-08-10-wide-tables-in-analytics-chat-now-scroll-horizontally-within.md +6 -0
- package/corpus/templates/calendar/app/components/calendar/DayView.tsx +13 -53
- package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +11 -70
- package/corpus/templates/calendar/app/lib/event-layout.ts +122 -0
- package/corpus/templates/calendar/app/routes/_app.availability.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-08-10-opening-availability-settings-from-the-agent-lands-on-the-av.md +6 -0
- package/corpus/templates/calendar/vitest.config.ts +6 -1
- package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +3 -1
- package/corpus/templates/clips/app/components/player/video-player.tsx +44 -4
- package/corpus/templates/clips/changelog/2026-08-10-fixed-transcription-failures-for-recordings-without-captured.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-10-mobile-clips-can-now-enter-fullscreen-on-iphone-safari.md +6 -0
- package/corpus/templates/content/actions/_property-utils.ts +11 -1
- package/corpus/templates/content/actions/view-screen.ts +62 -12
- package/corpus/templates/content/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/design/.agents/skills/design-templates/SKILL.md +22 -0
- package/corpus/templates/design/AGENTS.md +3 -0
- package/corpus/templates/design/actions/create-design-from-template.ts +19 -0
- package/corpus/templates/design/actions/get-design-snapshot.ts +18 -0
- package/corpus/templates/design/actions/get-design-template.ts +178 -0
- package/corpus/templates/design/actions/list-designs.ts +3 -1
- package/corpus/templates/design/actions/view-screen.ts +31 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +225 -214
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +3 -0
- package/corpus/templates/design/app/i18n-data.ts +78 -0
- package/corpus/templates/design/app/lib/design-authors.ts +64 -0
- package/corpus/templates/design/app/pages/Index.tsx +114 -4
- package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +1 -0
- package/corpus/templates/design/changelog/2026-08-07-alt-dragging-an-element-to-copy-it-now-keeps-the-copy-visibl.md +6 -0
- package/corpus/templates/design/changelog/2026-08-07-design-cards-now-show-who-created-each-design-with-a-filter-.md +6 -0
- package/corpus/templates/design/changelog/2026-08-07-drawing-a-shape-on-the-overview-canvas-now-keeps-the-shape-s.md +6 -0
- package/corpus/templates/design/changelog/2026-08-07-hold-option-alt-while-dragging-a-frame-on-the-overview-canva.md +6 -0
- package/corpus/templates/design/server/lib/design-template-data.ts +143 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/forms/AGENTS.md +2 -2
- package/corpus/templates/forms/actions/create-form.ts +1 -1
- package/corpus/templates/forms/actions/update-form.ts +5 -5
- package/corpus/templates/forms/changelog/2026-08-10-forms-now-keep-agent-applied-field-changes-visible-after-an-.md +6 -0
- package/corpus/templates/forms/changelog/2026-08-10-published-form-links-always-use-the-working-public-form-url.md +6 -0
- package/corpus/templates/forms/server/plugins/agent-chat.ts +2 -2
- package/corpus/templates/slides/AGENTS.md +4 -3
- package/corpus/templates/slides/actions/import-google-slides-reference.ts +56 -10
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +12 -74
- package/corpus/templates/slides/app/components/editor/GeneratingSlidePreview.tsx +5 -1
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +15 -4
- package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +116 -55
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1 -0
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +143 -18
- package/corpus/templates/slides/app/i18n/en-US.ts +6 -0
- package/corpus/templates/slides/app/lib/generation-state.ts +7 -1
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +32 -14
- package/corpus/templates/slides/app/pages/Index.tsx +110 -128
- package/corpus/templates/slides/changelog/2026-08-10-imported-reference-decks-now-show-clear-success-and-stay-sel.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-10-pasted-google-slides-links-import-after-reconnecting-google-.md +6 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +4 -0
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +13 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +1 -1
- package/dist/agent/engine/registry.d.ts +8 -2
- package/dist/agent/engine/registry.js +63 -29
- package/dist/agent/production-agent.js +7 -0
- package/dist/agent/run-manager.d.ts +5 -4
- package/dist/agent/run-manager.js +6 -5
- package/dist/cli/claude-code-participant.d.ts +2 -1
- package/dist/cli/claude-code-participant.js +19 -0
- package/dist/cli/code-agent-executor.js +223 -0
- package/dist/cli/create-workspace.js +3 -3
- package/dist/cli/create.d.ts +3 -2
- package/dist/cli/create.js +20 -24
- package/dist/client/AgentPanel.js +8 -4
- package/dist/client/AssistantChat.js +34 -1
- package/dist/client/agent-chat-adapter.d.ts +1 -0
- package/dist/client/agent-chat-adapter.js +10 -2
- package/dist/client/blocks/library/diagram.js +1 -1
- package/dist/client/blocks/library/sanitize-html.js +66 -2
- package/dist/client/blocks/library/wireframe-kit.js +69 -0
- package/dist/client/chat/markdown-renderer.d.ts +1 -0
- package/dist/client/chat/markdown-renderer.js +4 -0
- package/dist/client/chat/message-components.d.ts +1 -0
- package/dist/client/chat/message-components.js +9 -1
- package/dist/client/chat/tool-call-display.d.ts +8 -0
- package/dist/client/chat/tool-call-display.js +30 -21
- package/dist/client/chat-first/app-pane.js +1 -1
- package/dist/client/chat-first/apps-rail.d.ts +1 -1
- package/dist/client/chat-first/apps-rail.js +12 -12
- package/dist/client/chat-first/chat-history.d.ts +1 -1
- package/dist/client/chat-first/chat-history.js +2 -0
- package/dist/client/chat-first/copy.js +1 -0
- package/dist/client/chat-first/primary-nav.js +1 -1
- package/dist/client/chat-first/types.d.ts +1 -0
- package/dist/client/resources/McpConnectionSuggestion.js +2 -2
- package/dist/client/settings/SettingsTabsPage.d.ts +3 -1
- package/dist/client/settings/SettingsTabsPage.js +2 -2
- package/dist/client/sse-event-processor.d.ts +8 -0
- package/dist/client/sse-event-processor.js +13 -6
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.d.ts +5 -7
- package/dist/deploy/build.js +19 -12
- package/dist/localization/default-messages.js +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/provider-api/actions/provider-api.d.ts +2 -2
- package/dist/scripts/call-agent.js +3 -3
- package/dist/scripts/describe-workspace-apps.js +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-capabilities.js +0 -0
- package/dist/server/agent-chat/context-tools.js +1 -1
- package/dist/server/agent-chat/prompt-resources.js +1 -1
- package/dist/server/agent-chat-plugin.js +1 -1
- package/dist/server/auth.js +190 -42
- package/dist/server/better-auth-migrations.js +53 -0
- package/dist/server/http-response-telemetry.js +7 -1
- package/dist/server/onboarding-html.js +119 -33
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/password-policy.d.ts +2 -1
- package/dist/shared/password-policy.js +2 -1
- package/dist/styles/agent-conversation.css +20 -3
- package/dist/styles/agent-native.css +14 -2
- package/dist/styles/blocks.css +132 -0
- package/dist/templates/default/app/i18n/ar-SA.ts +1 -1
- package/dist/templates/default/app/i18n/de-DE.ts +1 -1
- package/dist/templates/default/app/i18n/en-US.ts +1 -1
- package/dist/templates/default/app/i18n/es-ES.ts +1 -1
- package/dist/templates/default/app/i18n/fr-FR.ts +1 -1
- package/dist/templates/default/app/i18n/hi-IN.ts +1 -1
- package/dist/templates/default/app/i18n/ja-JP.ts +1 -1
- package/dist/templates/default/app/i18n/ko-KR.ts +1 -1
- package/dist/templates/default/app/i18n/pt-BR.ts +1 -1
- package/dist/templates/default/app/i18n/zh-CN.ts +1 -1
- package/dist/templates/default/app/i18n/zh-TW.ts +1 -1
- package/dist/templates/default/pnpm-workspace.yaml +1 -0
- package/dist/templates/workspace-root/pnpm-workspace.yaml +2 -0
- package/docs/content/actions.mdx +4 -1
- package/docs/content/agent-surfaces.mdx +8 -6
- package/docs/content/automations.mdx +1 -1
- package/docs/content/cloneable-saas.mdx +6 -6
- package/docs/content/database.mdx +6 -1
- package/docs/content/deployment.mdx +10 -8
- package/docs/content/docs-components.mdx +22 -14
- package/docs/content/drop-in-agent.mdx +1 -1
- package/docs/content/environment-variables.mdx +4 -3
- package/docs/content/getting-started-actions.mdx +5 -4
- package/docs/content/getting-started-pages.mdx +7 -6
- package/docs/content/getting-started.mdx +4 -3
- package/docs/content/notifications.mdx +6 -6
- package/docs/content/progress.mdx +5 -5
- package/docs/content/routing.mdx +3 -1
- package/docs/content/server-database.mdx +13 -4
- package/docs/content/server-overview.mdx +9 -9
- package/docs/content/server-plugins.mdx +10 -4
- package/docs/content/server-routes.mdx +7 -2
- package/docs/content/tracking.mdx +4 -4
- package/docs/content/what-is-agent-native.mdx +4 -4
- package/package.json +2 -2
- package/src/templates/default/app/i18n/ar-SA.ts +1 -1
- package/src/templates/default/app/i18n/de-DE.ts +1 -1
- package/src/templates/default/app/i18n/en-US.ts +1 -1
- package/src/templates/default/app/i18n/es-ES.ts +1 -1
- package/src/templates/default/app/i18n/fr-FR.ts +1 -1
- package/src/templates/default/app/i18n/hi-IN.ts +1 -1
- package/src/templates/default/app/i18n/ja-JP.ts +1 -1
- package/src/templates/default/app/i18n/ko-KR.ts +1 -1
- package/src/templates/default/app/i18n/pt-BR.ts +1 -1
- package/src/templates/default/app/i18n/zh-CN.ts +1 -1
- package/src/templates/default/app/i18n/zh-TW.ts +1 -1
- package/src/templates/default/pnpm-workspace.yaml +1 -0
- package/src/templates/workspace-root/pnpm-workspace.yaml +2 -0
|
@@ -401,20 +401,26 @@ function shouldTraceEngineDetection() {
|
|
|
401
401
|
* `/builder/status` resolves them via the same request org context, and the
|
|
402
402
|
* chat engine picker must not disagree with that card.
|
|
403
403
|
*/
|
|
404
|
-
export async function detectEngineFromUserSecrets() {
|
|
404
|
+
export async function detectEngineFromUserSecrets(identity) {
|
|
405
405
|
const traceLookup = shouldTraceEngineDetection();
|
|
406
|
-
let email;
|
|
407
|
-
let orgId;
|
|
406
|
+
let email = identity?.userEmail?.trim() || undefined;
|
|
407
|
+
let orgId = identity?.orgId;
|
|
408
408
|
try {
|
|
409
409
|
const { getRequestUserEmail, getRequestOrgId } = await import("../../server/request-context.js");
|
|
410
|
-
email
|
|
411
|
-
orgId
|
|
410
|
+
email ??= getRequestUserEmail();
|
|
411
|
+
if (orgId === undefined)
|
|
412
|
+
orgId = getRequestOrgId();
|
|
412
413
|
}
|
|
413
414
|
catch {
|
|
415
|
+
if (!email) {
|
|
416
|
+
if (traceLookup) {
|
|
417
|
+
console.log(`[engine-detect] result=null reason=no-request-context email=(unknown) orgId=(unknown)`);
|
|
418
|
+
}
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
414
421
|
if (traceLookup) {
|
|
415
|
-
console.log(`[engine-detect]
|
|
422
|
+
console.log(`[engine-detect] request context unavailable; using explicit identity email=${email} orgId=${orgId ?? "(none)"}`);
|
|
416
423
|
}
|
|
417
|
-
return null;
|
|
418
424
|
}
|
|
419
425
|
if (!email) {
|
|
420
426
|
if (traceLookup) {
|
|
@@ -427,8 +433,9 @@ export async function detectEngineFromUserSecrets() {
|
|
|
427
433
|
return false;
|
|
428
434
|
if (entry.requiredEnvVars.length === 0)
|
|
429
435
|
return false;
|
|
430
|
-
if (entry.name === "builder")
|
|
431
|
-
return hasUsableBuilderConnection();
|
|
436
|
+
if (entry.name === "builder") {
|
|
437
|
+
return hasUsableBuilderConnection(identity);
|
|
438
|
+
}
|
|
432
439
|
for (const key of entry.requiredEnvVars) {
|
|
433
440
|
// A throw here means the credential store could not be read. Let it
|
|
434
441
|
// propagate: swallowing it reports "no provider connected" to a user
|
|
@@ -520,8 +527,8 @@ async function resolveProviderBaseUrl(envVar) {
|
|
|
520
527
|
* keeps that distinction instead of reporting "connect a provider" to a user
|
|
521
528
|
* whose org-shared keys exist but were unreadable.
|
|
522
529
|
*/
|
|
523
|
-
async function hasUsableBuilderConnection() {
|
|
524
|
-
const creds = await resolveBuilderCredentialsDetailed();
|
|
530
|
+
async function hasUsableBuilderConnection(identity) {
|
|
531
|
+
const creds = await resolveBuilderCredentialsDetailed(identity);
|
|
525
532
|
assertCredentialStoreReadable(creds);
|
|
526
533
|
return Boolean(creds.privateKey && creds.publicKey);
|
|
527
534
|
}
|
|
@@ -567,7 +574,7 @@ async function apiKeyBelongsToDifferentProvider(apiKey, selectedEntry) {
|
|
|
567
574
|
}
|
|
568
575
|
return false;
|
|
569
576
|
}
|
|
570
|
-
async function engineCreateConfigForEntry(entry, apiKey, extra, preferResolvedCredential = false, apiKeyEnvVar) {
|
|
577
|
+
async function engineCreateConfigForEntry(entry, apiKey, extra, preferResolvedCredential = false, apiKeyEnvVar, credentialIdentity) {
|
|
571
578
|
const safeExtra = { ...(extra ?? {}) };
|
|
572
579
|
let matchingApiKey = apiKey;
|
|
573
580
|
// A declared provenance settles the question without inspecting values: a
|
|
@@ -632,6 +639,25 @@ async function engineCreateConfigForEntry(entry, apiKey, extra, preferResolvedCr
|
|
|
632
639
|
safeExtra.baseUrl = baseUrl;
|
|
633
640
|
}
|
|
634
641
|
}
|
|
642
|
+
if (entry.name === "builder" &&
|
|
643
|
+
(credentialIdentity !== undefined || safeExtra.credentials == null)) {
|
|
644
|
+
// Builder authentication is a private/public key pair, not the single
|
|
645
|
+
// provider key carried by ResolveEngineConfig. Capture the scoped pair
|
|
646
|
+
// while the verified request identity is available so a later stream or
|
|
647
|
+
// detached run cannot resolve credentials from the wrong ambient context.
|
|
648
|
+
const creds = await resolveBuilderCredentialsDetailed(credentialIdentity);
|
|
649
|
+
assertCredentialStoreReadable(creds);
|
|
650
|
+
if (credentialIdentity !== undefined ||
|
|
651
|
+
creds.source !== null ||
|
|
652
|
+
creds.lookupFailed) {
|
|
653
|
+
safeExtra.credentials = {
|
|
654
|
+
privateKey: creds.privateKey,
|
|
655
|
+
publicKey: creds.publicKey,
|
|
656
|
+
userId: creds.userId,
|
|
657
|
+
orgName: creds.orgName,
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
}
|
|
635
661
|
return engineCreateConfig(entry, matchingApiKey, safeExtra);
|
|
636
662
|
}
|
|
637
663
|
/**
|
|
@@ -661,15 +687,16 @@ export function isStoredEngineUsable(stored, entry) {
|
|
|
661
687
|
* deploy env vars; this async helper is what request-time routes should use
|
|
662
688
|
* when deciding whether a stored engine can actually run for the current user.
|
|
663
689
|
*/
|
|
664
|
-
export async function isStoredEngineUsableForRequest(stored, entry) {
|
|
690
|
+
export async function isStoredEngineUsableForRequest(stored, entry, options = {}) {
|
|
665
691
|
if (!isAgentEnginePackageInstalled(entry))
|
|
666
692
|
return false;
|
|
667
693
|
if (isAgentEngineSettingConfigured(stored))
|
|
668
694
|
return true;
|
|
669
695
|
if (entry.requiredEnvVars.length === 0)
|
|
670
696
|
return true;
|
|
671
|
-
if (entry.name === "builder")
|
|
672
|
-
return hasUsableBuilderConnection();
|
|
697
|
+
if (entry.name === "builder") {
|
|
698
|
+
return hasUsableBuilderConnection(options.credentialIdentity);
|
|
699
|
+
}
|
|
673
700
|
for (const key of entry.requiredEnvVars) {
|
|
674
701
|
if (!(await resolveUsableProviderSecret(key)))
|
|
675
702
|
return false;
|
|
@@ -692,8 +719,9 @@ export async function isResolvedEngineUsableForRequest(engine, options = {}) {
|
|
|
692
719
|
return false;
|
|
693
720
|
if (entry.requiredEnvVars.length === 0)
|
|
694
721
|
return true;
|
|
695
|
-
if (entry.name === "builder")
|
|
696
|
-
return hasUsableBuilderConnection();
|
|
722
|
+
if (entry.name === "builder") {
|
|
723
|
+
return hasUsableBuilderConnection(options.credentialIdentity);
|
|
724
|
+
}
|
|
697
725
|
if (options.apiKey?.trim()) {
|
|
698
726
|
const key = entry.requiredEnvVars[0];
|
|
699
727
|
if (!key)
|
|
@@ -776,7 +804,7 @@ export async function getConfiguredEngineNameForRequest(options = {}) {
|
|
|
776
804
|
* 7. Default "anthropic" (requires ANTHROPIC_API_KEY)
|
|
777
805
|
*/
|
|
778
806
|
export async function resolveEngine(config) {
|
|
779
|
-
const { engineOption, apiKey, apiKeyEnvVar, model: _model, appId } = config;
|
|
807
|
+
const { engineOption, apiKey, apiKeyEnvVar, model: _model, appId, credentialIdentity, } = config;
|
|
780
808
|
// 1. Explicit instance passed directly
|
|
781
809
|
if (engineOption &&
|
|
782
810
|
typeof engineOption === "object" &&
|
|
@@ -792,7 +820,7 @@ export async function resolveEngine(config) {
|
|
|
792
820
|
if (!entry)
|
|
793
821
|
throw new Error(`[agent-engine] Unknown engine: "${name}". Registered: ${[..._registry.keys()].join(", ")}`);
|
|
794
822
|
assertAgentEnginePackageInstalled(entry);
|
|
795
|
-
return entry.create(await engineCreateConfigForEntry(entry, apiKey, engineConfig, false, apiKeyEnvVar));
|
|
823
|
+
return entry.create(await engineCreateConfigForEntry(entry, apiKey, engineConfig, false, apiKeyEnvVar, credentialIdentity));
|
|
796
824
|
}
|
|
797
825
|
// 3. Explicit string name from options
|
|
798
826
|
if (typeof engineOption === "string") {
|
|
@@ -800,7 +828,7 @@ export async function resolveEngine(config) {
|
|
|
800
828
|
if (!entry)
|
|
801
829
|
throw new Error(`[agent-engine] Unknown engine: "${engineOption}". Registered: ${[..._registry.keys()].join(", ")}`);
|
|
802
830
|
assertAgentEnginePackageInstalled(entry);
|
|
803
|
-
return entry.create(await engineCreateConfigForEntry(entry, apiKey, undefined, false, apiKeyEnvVar));
|
|
831
|
+
return entry.create(await engineCreateConfigForEntry(entry, apiKey, undefined, false, apiKeyEnvVar, credentialIdentity));
|
|
804
832
|
}
|
|
805
833
|
// 4. Env var — explicit engine name override
|
|
806
834
|
const envEngine = process.env.AGENT_ENGINE;
|
|
@@ -808,14 +836,17 @@ export async function resolveEngine(config) {
|
|
|
808
836
|
const entry = _registry.get(envEngine);
|
|
809
837
|
if (entry) {
|
|
810
838
|
assertAgentEnginePackageInstalled(entry);
|
|
811
|
-
return entry.create(await engineCreateConfigForEntry(entry, apiKey, undefined, true, apiKeyEnvVar));
|
|
839
|
+
return entry.create(await engineCreateConfigForEntry(entry, apiKey, undefined, true, apiKeyEnvVar, credentialIdentity));
|
|
812
840
|
}
|
|
813
841
|
}
|
|
814
842
|
const appDefault = await getAgentAppModelDefaultForCurrentRequest(appId);
|
|
815
843
|
if (appDefault?.engine) {
|
|
816
844
|
const entry = _registry.get(appDefault.engine);
|
|
817
|
-
if (entry &&
|
|
818
|
-
|
|
845
|
+
if (entry &&
|
|
846
|
+
(await isStoredEngineUsableForRequest(appDefault, entry, {
|
|
847
|
+
credentialIdentity,
|
|
848
|
+
}))) {
|
|
849
|
+
return entry.create(await engineCreateConfigForEntry(entry, apiKey, undefined, true, apiKeyEnvVar, credentialIdentity));
|
|
819
850
|
}
|
|
820
851
|
}
|
|
821
852
|
let stored = null;
|
|
@@ -829,7 +860,7 @@ export async function resolveEngine(config) {
|
|
|
829
860
|
// (Builder OAuth callback + "paste your own key" settings flow write here,
|
|
830
861
|
// not env). Stored/app defaults are checked first so an explicit provider
|
|
831
862
|
// selection can override a connected Builder account.
|
|
832
|
-
const detectedFromUser = await detectEngineFromUserSecrets();
|
|
863
|
+
const detectedFromUser = await detectEngineFromUserSecrets(credentialIdentity);
|
|
833
864
|
// 6. Settings store — only when the stored row's API key is reachable.
|
|
834
865
|
// This explicit selection beats automatic Builder detection so users can
|
|
835
866
|
// switch away from Builder credits by saving/applying their own provider key.
|
|
@@ -838,26 +869,29 @@ export async function resolveEngine(config) {
|
|
|
838
869
|
const storedConfig = storedRaw?.config;
|
|
839
870
|
if (storedRaw && typeof storedEngine === "string") {
|
|
840
871
|
const entry = _registry.get(storedEngine);
|
|
841
|
-
if (entry &&
|
|
842
|
-
|
|
872
|
+
if (entry &&
|
|
873
|
+
(await isStoredEngineUsableForRequest(storedRaw, entry, {
|
|
874
|
+
credentialIdentity,
|
|
875
|
+
}))) {
|
|
876
|
+
return entry.create(await engineCreateConfigForEntry(entry, apiKey, stripInlineApiKeyConfig(storedConfig), true, apiKeyEnvVar, credentialIdentity));
|
|
843
877
|
}
|
|
844
878
|
}
|
|
845
879
|
if (detectedFromUser) {
|
|
846
|
-
return detectedFromUser.create(await engineCreateConfigForEntry(detectedFromUser, apiKey, undefined, true, apiKeyEnvVar));
|
|
880
|
+
return detectedFromUser.create(await engineCreateConfigForEntry(detectedFromUser, apiKey, undefined, true, apiKeyEnvVar, credentialIdentity));
|
|
847
881
|
}
|
|
848
882
|
// 8. Auto-detect from any provider env var — so just dropping a key in
|
|
849
883
|
// .env works without also setting AGENT_ENGINE. Skip keys with active
|
|
850
884
|
// auth-failure markers so a rejected deploy key cannot permanently win.
|
|
851
885
|
const detected = await detectEngineFromEnvForRequest();
|
|
852
886
|
if (detected) {
|
|
853
|
-
return detected.create(await engineCreateConfigForEntry(detected, apiKey, undefined, true, apiKeyEnvVar));
|
|
887
|
+
return detected.create(await engineCreateConfigForEntry(detected, apiKey, undefined, true, apiKeyEnvVar, credentialIdentity));
|
|
854
888
|
}
|
|
855
889
|
// 9. Default: anthropic
|
|
856
890
|
const anthropicEntry = _registry.get("anthropic");
|
|
857
891
|
if (!anthropicEntry) {
|
|
858
892
|
throw new Error("[agent-engine] Default Anthropic engine is not registered. Did builtin.ts fail to load?");
|
|
859
893
|
}
|
|
860
|
-
return anthropicEntry.create(await engineCreateConfigForEntry(anthropicEntry, apiKey, undefined, true, apiKeyEnvVar));
|
|
894
|
+
return anthropicEntry.create(await engineCreateConfigForEntry(anthropicEntry, apiKey, undefined, true, apiKeyEnvVar, credentialIdentity));
|
|
861
895
|
}
|
|
862
896
|
/**
|
|
863
897
|
* Read the user-selected model for an engine from the `agent-engine` setting.
|
|
@@ -5978,6 +5978,10 @@ export function createProductionAgentHandler(options) {
|
|
|
5978
5978
|
// DIAGNOSTIC-ONLY: bracket engine resolution (Builder credential / app-default
|
|
5979
5979
|
// settings reads inside resolveEngine).
|
|
5980
5980
|
workerStep("engine_start");
|
|
5981
|
+
const credentialIdentity = {
|
|
5982
|
+
userEmail: ownerEmail,
|
|
5983
|
+
orgId: getRequestOrgId(),
|
|
5984
|
+
};
|
|
5981
5985
|
let engine;
|
|
5982
5986
|
try {
|
|
5983
5987
|
engine = await resolveEngine({
|
|
@@ -5986,6 +5990,7 @@ export function createProductionAgentHandler(options) {
|
|
|
5986
5990
|
apiKeyEnvVar: effectiveApiKeyEnvVar,
|
|
5987
5991
|
model: configuredModel,
|
|
5988
5992
|
appId: options.appId,
|
|
5993
|
+
credentialIdentity,
|
|
5989
5994
|
});
|
|
5990
5995
|
}
|
|
5991
5996
|
catch {
|
|
@@ -5993,6 +5998,7 @@ export function createProductionAgentHandler(options) {
|
|
|
5993
5998
|
apiKey: effectiveApiKey,
|
|
5994
5999
|
apiKeyEnvVar: effectiveApiKeyEnvVar,
|
|
5995
6000
|
appId: options.appId,
|
|
6001
|
+
credentialIdentity,
|
|
5996
6002
|
});
|
|
5997
6003
|
}
|
|
5998
6004
|
// DIAGNOSTIC-ONLY: engine resolution finished.
|
|
@@ -6056,6 +6062,7 @@ export function createProductionAgentHandler(options) {
|
|
|
6056
6062
|
console.log(`[agent-chat] resolved engine=${engine.name} model=${effectiveModel} requestModel=${requestModel ?? "(none)"} requestEngine=${requestEngine ?? "(none)"} modelSource=${modelSelectionSource} turnId=${requestTurnId ?? "(none)"}`);
|
|
6057
6063
|
if (!(await isResolvedEngineUsableForRequest(engine, {
|
|
6058
6064
|
apiKey: effectiveApiKey,
|
|
6065
|
+
credentialIdentity,
|
|
6059
6066
|
}))) {
|
|
6060
6067
|
setResponseHeader(event, "Content-Type", "text/event-stream");
|
|
6061
6068
|
setResponseHeader(event, "Cache-Control", "no-cache");
|
|
@@ -164,10 +164,11 @@ export declare const DEFAULT_COMPLETED_RUN_RETENTION_MS: number;
|
|
|
164
164
|
*/
|
|
165
165
|
export declare const DEFAULT_ERRORED_RUN_RETENTION_MS: number;
|
|
166
166
|
/**
|
|
167
|
-
* How recently a terminal run must have
|
|
168
|
-
* it.
|
|
169
|
-
*
|
|
170
|
-
*
|
|
167
|
+
* How recently a terminal run must have completed for `/runs/active` to surface
|
|
168
|
+
* it. This must outlast the durable browser watchdog (13 minutes) and the
|
|
169
|
+
* in-flight reader watchdog (15 minutes) so a quiet event stream can detach
|
|
170
|
+
* and still replay a run that completed while the browser was waiting.
|
|
171
|
+
* Reconnect after this window won't replay the run.
|
|
171
172
|
*/
|
|
172
173
|
export declare const TERMINAL_RUN_RECONNECT_WINDOW_MS: number;
|
|
173
174
|
/** Fast poll cadence while a SQL-backed SSE subscription is actively receiving rows. */
|
|
@@ -180,12 +180,13 @@ export const DEFAULT_COMPLETED_RUN_RETENTION_MS = 24 * 60 * 60 * 1000;
|
|
|
180
180
|
*/
|
|
181
181
|
export const DEFAULT_ERRORED_RUN_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;
|
|
182
182
|
/**
|
|
183
|
-
* How recently a terminal run must have
|
|
184
|
-
* it.
|
|
185
|
-
*
|
|
186
|
-
*
|
|
183
|
+
* How recently a terminal run must have completed for `/runs/active` to surface
|
|
184
|
+
* it. This must outlast the durable browser watchdog (13 minutes) and the
|
|
185
|
+
* in-flight reader watchdog (15 minutes) so a quiet event stream can detach
|
|
186
|
+
* and still replay a run that completed while the browser was waiting.
|
|
187
|
+
* Reconnect after this window won't replay the run.
|
|
187
188
|
*/
|
|
188
|
-
export const TERMINAL_RUN_RECONNECT_WINDOW_MS =
|
|
189
|
+
export const TERMINAL_RUN_RECONNECT_WINDOW_MS = 20 * 60 * 1000;
|
|
189
190
|
/** Fast poll cadence while a SQL-backed SSE subscription is actively receiving rows. */
|
|
190
191
|
export const SQL_SUBSCRIPTION_ACTIVE_POLL_MS = 125;
|
|
191
192
|
/** Baseline SQL-backed SSE poll cadence when the run is idle. */
|
|
@@ -42,6 +42,7 @@ export interface RunClaudeCodeParticipantOptions {
|
|
|
42
42
|
prompt: string;
|
|
43
43
|
cwd: string;
|
|
44
44
|
model?: string;
|
|
45
|
+
effort?: string;
|
|
45
46
|
session?: ClaudeCodeParticipantSession;
|
|
46
47
|
/** Either the fixed CLI name or an absolute executable path for packaged apps. */
|
|
47
48
|
command?: string;
|
|
@@ -71,6 +72,6 @@ export interface ClaudeCodeSubscriptionStatusOptions {
|
|
|
71
72
|
}
|
|
72
73
|
export declare function readClaudeCodeSubscriptionStatus(options?: ClaudeCodeSubscriptionStatusOptions): Promise<ClaudeCodeSubscriptionStatus>;
|
|
73
74
|
export declare function runClaudeCodeParticipant(options: RunClaudeCodeParticipantOptions): Promise<ClaudeCodeParticipantResult>;
|
|
74
|
-
export declare function buildClaudeCodeParticipantArgs(options: Pick<RunClaudeCodeParticipantOptions, "role" | "model" | "session">): string[];
|
|
75
|
+
export declare function buildClaudeCodeParticipantArgs(options: Pick<RunClaudeCodeParticipantOptions, "role" | "model" | "effort" | "session">): string[];
|
|
75
76
|
export declare const CLAUDE_CODE_PARTICIPANT_TESTED_VERSION = "2.1.208";
|
|
76
77
|
export {};
|
|
@@ -102,6 +102,9 @@ export function buildClaudeCodeParticipantArgs(options) {
|
|
|
102
102
|
const model = readString(options.model);
|
|
103
103
|
if (model)
|
|
104
104
|
args.push("--model", model);
|
|
105
|
+
const effort = normalizeClaudeEffort(options.effort);
|
|
106
|
+
if (effort)
|
|
107
|
+
args.push("--effort", effort);
|
|
105
108
|
const sessionId = readString(options.session?.sessionId);
|
|
106
109
|
const resumeSessionId = readString(options.session?.resumeSessionId);
|
|
107
110
|
if (sessionId)
|
|
@@ -112,6 +115,22 @@ export function buildClaudeCodeParticipantArgs(options) {
|
|
|
112
115
|
args.push("--no-session-persistence");
|
|
113
116
|
return args;
|
|
114
117
|
}
|
|
118
|
+
function normalizeClaudeEffort(effort) {
|
|
119
|
+
switch (effort) {
|
|
120
|
+
case "low":
|
|
121
|
+
case "medium":
|
|
122
|
+
case "high":
|
|
123
|
+
case "max":
|
|
124
|
+
return effort;
|
|
125
|
+
case "minimal":
|
|
126
|
+
case "none":
|
|
127
|
+
return "low";
|
|
128
|
+
case "xhigh":
|
|
129
|
+
return "high";
|
|
130
|
+
default:
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
115
134
|
function collectClaudeCodeParticipantResult(child, options) {
|
|
116
135
|
const maxEvents = boundedLimit(options.maxEvents, DEFAULT_MAX_EVENTS);
|
|
117
136
|
const maxStreamBytes = boundedLimit(options.maxStreamBytes, DEFAULT_MAX_STREAM_BYTES);
|
|
@@ -14,6 +14,7 @@ import { readAgentsBundleFromFs, generateDevelopmentSkillsPromptBlock, } from ".
|
|
|
14
14
|
import { getAmbientOrgId, getAmbientUserEmail, runWithRequestContext, } from "../server/request-context.js";
|
|
15
15
|
import { isReasoningEffort, } from "../shared/reasoning-effort.js";
|
|
16
16
|
import { createAgentNativeConfigContext, loadResolvedAgentNativeConfig, } from "../vite/agent-native-config-loader.js";
|
|
17
|
+
import { runClaudeCodeParticipant, } from "./claude-code-participant.js";
|
|
17
18
|
import { codexMcpConfigArgs, mergeCodeAgentMcpConfig, restrictCodeAgentMcpConfig, } from "./code-agent-mcp-config.js";
|
|
18
19
|
import { createCodeAgentOutputSmoother } from "./code-agent-output-smoother.js";
|
|
19
20
|
import { addCodeAgentCommandToAllowlist, appendCodeAgentTranscriptEvent, dequeueCodeAgentFollowUp, getCodeAgentRunRecord, isCodeAgentCommandAllowed, listCodeAgentTranscriptEvents, updateCodeAgentRunRecord, } from "./code-agent-runs.js";
|
|
@@ -21,6 +22,8 @@ const DEFAULT_COMMAND_TIMEOUT_MS = 120_000;
|
|
|
21
22
|
const MAX_TOOL_OUTPUT_CHARS = 50_000;
|
|
22
23
|
const MAX_FILE_READ_CHARS = 120_000;
|
|
23
24
|
const CODEX_CLI_ENGINE_NAME = "codex-cli";
|
|
25
|
+
const CLAUDE_CLI_ENGINE_NAME = "claude-cli";
|
|
26
|
+
const CLAUDE_CLI_DEFAULT_MODEL = "claude-sonnet-5";
|
|
24
27
|
const RECAP_SOURCE_TOOL_PROFILE = "recap-source";
|
|
25
28
|
const RECAP_SOURCE_OUTPUT_FILE = "recap-source.json";
|
|
26
29
|
/**
|
|
@@ -110,6 +113,18 @@ export async function executeCodeAgentRun(options) {
|
|
|
110
113
|
signal: options.signal,
|
|
111
114
|
});
|
|
112
115
|
}
|
|
116
|
+
if (requestedEngine === CLAUDE_CLI_ENGINE_NAME) {
|
|
117
|
+
return executeClaudeCliRun({
|
|
118
|
+
run: existing,
|
|
119
|
+
prompt: executionPrompt,
|
|
120
|
+
model: options.model ?? metadataString(existing, "model"),
|
|
121
|
+
reasoningEffort: options.reasoningEffort ?? metadataReasoningEffort(existing),
|
|
122
|
+
permissionMode: existing.permissionMode ?? "full-auto",
|
|
123
|
+
stdout: options.stdout,
|
|
124
|
+
streamToolOutputToStdout,
|
|
125
|
+
signal: options.signal,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
113
128
|
const engine = options.engine ?? (await resolveExecutorEngine(requestedEngine));
|
|
114
129
|
if (!engine) {
|
|
115
130
|
const message = "No LLM provider key was found. Set ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, another supported provider key, or run `codex login` to use Codex CLI.";
|
|
@@ -437,6 +452,214 @@ export function codeAgentMcpInvocationPolicy(permissionMode) {
|
|
|
437
452
|
mode: permissionMode === "read-only" ? "read-only" : "allow-all",
|
|
438
453
|
};
|
|
439
454
|
}
|
|
455
|
+
async function executeClaudeCliRun(options) {
|
|
456
|
+
const cwd = options.run.cwd || process.cwd();
|
|
457
|
+
const model = normalizeClaudeCliModel(options.model);
|
|
458
|
+
const reasoningEffort = normalizeClaudeCliEffort(options.reasoningEffort);
|
|
459
|
+
const streamToolOutputToStdout = options.streamToolOutputToStdout ??
|
|
460
|
+
process.env.AGENT_NATIVE_CODE_AGENT_STRUCTURED_STDOUT !== "1";
|
|
461
|
+
const assistantText = [];
|
|
462
|
+
appendCodeAgentTranscriptEvent({
|
|
463
|
+
runId: options.run.id,
|
|
464
|
+
kind: "status",
|
|
465
|
+
message: "Starting Claude Code with local Claude authentication.",
|
|
466
|
+
metadata: {
|
|
467
|
+
status: "running",
|
|
468
|
+
phase: "executing",
|
|
469
|
+
engine: CLAUDE_CLI_ENGINE_NAME,
|
|
470
|
+
},
|
|
471
|
+
});
|
|
472
|
+
try {
|
|
473
|
+
const result = await runClaudeCodeParticipant({
|
|
474
|
+
role: options.permissionMode === "full-auto" ? "driver" : "watchdog",
|
|
475
|
+
prompt: buildClaudeCliPrompt(options.run, options.prompt),
|
|
476
|
+
cwd,
|
|
477
|
+
model,
|
|
478
|
+
effort: reasoningEffort,
|
|
479
|
+
signal: options.signal,
|
|
480
|
+
onEvent: (event) => {
|
|
481
|
+
const text = readClaudeParticipantAssistantText(event);
|
|
482
|
+
if (!text)
|
|
483
|
+
return;
|
|
484
|
+
assistantText.push(text);
|
|
485
|
+
if (streamToolOutputToStdout)
|
|
486
|
+
options.stdout?.write(text);
|
|
487
|
+
},
|
|
488
|
+
});
|
|
489
|
+
const finalMessage = readClaudeParticipantResultText(result.events) ??
|
|
490
|
+
(assistantText.join("\n\n").trim() || "Claude Code run completed.");
|
|
491
|
+
appendCodeAgentTranscriptEvent({
|
|
492
|
+
runId: options.run.id,
|
|
493
|
+
kind: "system",
|
|
494
|
+
message: finalMessage,
|
|
495
|
+
metadata: {
|
|
496
|
+
role: "assistant",
|
|
497
|
+
engine: CLAUDE_CLI_ENGINE_NAME,
|
|
498
|
+
model,
|
|
499
|
+
...(reasoningEffort ? { reasoningEffort } : {}),
|
|
500
|
+
},
|
|
501
|
+
});
|
|
502
|
+
const pendingFollowUp = dequeueCodeAgentFollowUp(options.run.id);
|
|
503
|
+
if (pendingFollowUp) {
|
|
504
|
+
const message = pendingFollowUp.mode === "queued"
|
|
505
|
+
? "Claude Code run completed; running queued follow-up."
|
|
506
|
+
: "Claude Code run completed; applying steering follow-up.";
|
|
507
|
+
appendCodeAgentTranscriptEvent({
|
|
508
|
+
runId: options.run.id,
|
|
509
|
+
kind: "status",
|
|
510
|
+
message,
|
|
511
|
+
metadata: {
|
|
512
|
+
status: "running",
|
|
513
|
+
phase: "follow-up",
|
|
514
|
+
followUpId: pendingFollowUp.id,
|
|
515
|
+
followUpMode: pendingFollowUp.mode,
|
|
516
|
+
engine: CLAUDE_CLI_ENGINE_NAME,
|
|
517
|
+
},
|
|
518
|
+
});
|
|
519
|
+
if (pendingFollowUp.permissionMode) {
|
|
520
|
+
updateCodeAgentRunRecord(options.run.id, {
|
|
521
|
+
permissionMode: pendingFollowUp.permissionMode,
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
return executeCodeAgentRun({
|
|
525
|
+
runId: options.run.id,
|
|
526
|
+
prompt: pendingFollowUp.prompt,
|
|
527
|
+
attachments: pendingFollowUp.attachments ??
|
|
528
|
+
userPromptAttachmentsForEvent(options.run.id, pendingFollowUp.eventId),
|
|
529
|
+
appendUserEvent: false,
|
|
530
|
+
stdout: options.stdout,
|
|
531
|
+
streamToolOutputToStdout: options.streamToolOutputToStdout,
|
|
532
|
+
signal: options.signal,
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
appendCodeAgentTranscriptEvent({
|
|
536
|
+
runId: options.run.id,
|
|
537
|
+
kind: "status",
|
|
538
|
+
message: "Claude Code run completed.",
|
|
539
|
+
metadata: {
|
|
540
|
+
status: "completed",
|
|
541
|
+
phase: "complete",
|
|
542
|
+
engine: CLAUDE_CLI_ENGINE_NAME,
|
|
543
|
+
},
|
|
544
|
+
});
|
|
545
|
+
return updateCodeAgentRunRecord(options.run.id, {
|
|
546
|
+
status: "completed",
|
|
547
|
+
phase: "complete",
|
|
548
|
+
needsApproval: false,
|
|
549
|
+
progress: {
|
|
550
|
+
label: "Complete",
|
|
551
|
+
completed: 1,
|
|
552
|
+
total: 1,
|
|
553
|
+
percent: 100,
|
|
554
|
+
},
|
|
555
|
+
metadata: {
|
|
556
|
+
executionCompletedAt: new Date().toISOString(),
|
|
557
|
+
engine: CLAUDE_CLI_ENGINE_NAME,
|
|
558
|
+
model,
|
|
559
|
+
...(reasoningEffort ? { reasoningEffort } : {}),
|
|
560
|
+
permissionMode: options.permissionMode,
|
|
561
|
+
},
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
const interrupted = options.signal?.aborted === true;
|
|
566
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
567
|
+
const summary = interrupted
|
|
568
|
+
? "Claude Code run paused."
|
|
569
|
+
: `Claude Code run failed: ${message}`;
|
|
570
|
+
if (streamToolOutputToStdout)
|
|
571
|
+
options.stdout?.write(`\n${summary}\n`);
|
|
572
|
+
appendCodeAgentTranscriptEvent({
|
|
573
|
+
runId: options.run.id,
|
|
574
|
+
kind: "status",
|
|
575
|
+
message: summary,
|
|
576
|
+
metadata: {
|
|
577
|
+
status: interrupted ? "paused" : "errored",
|
|
578
|
+
phase: interrupted ? "paused" : "error",
|
|
579
|
+
engine: CLAUDE_CLI_ENGINE_NAME,
|
|
580
|
+
},
|
|
581
|
+
});
|
|
582
|
+
return updateCodeAgentRunRecord(options.run.id, {
|
|
583
|
+
status: interrupted ? "paused" : "errored",
|
|
584
|
+
phase: interrupted ? "paused" : "error",
|
|
585
|
+
progress: {
|
|
586
|
+
label: interrupted ? "Paused" : "Error",
|
|
587
|
+
completed: 0,
|
|
588
|
+
total: 1,
|
|
589
|
+
failed: interrupted ? 0 : 1,
|
|
590
|
+
percent: 0,
|
|
591
|
+
},
|
|
592
|
+
metadata: {
|
|
593
|
+
...(interrupted
|
|
594
|
+
? { executionPausedAt: new Date().toISOString() }
|
|
595
|
+
: {
|
|
596
|
+
executionError: message,
|
|
597
|
+
executionErroredAt: new Date().toISOString(),
|
|
598
|
+
}),
|
|
599
|
+
engine: CLAUDE_CLI_ENGINE_NAME,
|
|
600
|
+
model,
|
|
601
|
+
},
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
function buildClaudeCliPrompt(run, prompt) {
|
|
606
|
+
const permissionMode = run.permissionMode ?? "full-auto";
|
|
607
|
+
const mode = permissionMode === "full-auto" ? "Auto" : "Plan";
|
|
608
|
+
const modeInstruction = mode === "Plan"
|
|
609
|
+
? "Inspect and explain only. Do not edit files or run mutating commands."
|
|
610
|
+
: "Edit and verify as needed. Do not create, switch, reset, rebase, or stash git branches.";
|
|
611
|
+
const additionalSkillsRoot = process.env.AGENT_NATIVE_CODE_AGENT_SKILLS_ROOT?.trim();
|
|
612
|
+
return [
|
|
613
|
+
`You are running from Agent-Native Code in ${run.cwd || process.cwd()}.`,
|
|
614
|
+
"Follow the repository AGENTS.md and any relevant skill instructions.",
|
|
615
|
+
...(additionalSkillsRoot
|
|
616
|
+
? [
|
|
617
|
+
`Additional installed Agent Plugin skills are available under ${additionalSkillsRoot}. Read any relevant SKILL.md files before acting.`,
|
|
618
|
+
]
|
|
619
|
+
: []),
|
|
620
|
+
`Run mode: ${mode} (${permissionMode}). ${modeInstruction}`,
|
|
621
|
+
"",
|
|
622
|
+
"# User request",
|
|
623
|
+
prompt,
|
|
624
|
+
].join("\n");
|
|
625
|
+
}
|
|
626
|
+
function normalizeClaudeCliModel(model) {
|
|
627
|
+
const trimmed = model?.trim();
|
|
628
|
+
return !trimmed || trimmed === "auto" || trimmed === CLAUDE_CLI_ENGINE_NAME
|
|
629
|
+
? CLAUDE_CLI_DEFAULT_MODEL
|
|
630
|
+
: trimmed;
|
|
631
|
+
}
|
|
632
|
+
function normalizeClaudeCliEffort(effort) {
|
|
633
|
+
return effort && effort !== "auto" ? effort : undefined;
|
|
634
|
+
}
|
|
635
|
+
function readClaudeParticipantAssistantText(event) {
|
|
636
|
+
if (event.type !== "assistant")
|
|
637
|
+
return null;
|
|
638
|
+
const message = asRecordValue(event.message);
|
|
639
|
+
const content = message?.content;
|
|
640
|
+
if (!Array.isArray(content))
|
|
641
|
+
return null;
|
|
642
|
+
const text = content
|
|
643
|
+
.filter((part) => isRecordValue(part))
|
|
644
|
+
.map((part) => (typeof part.text === "string" ? part.text : ""))
|
|
645
|
+
.filter(Boolean)
|
|
646
|
+
.join("");
|
|
647
|
+
return text.trim() || null;
|
|
648
|
+
}
|
|
649
|
+
function readClaudeParticipantResultText(events) {
|
|
650
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
651
|
+
const result = events[index]?.result;
|
|
652
|
+
if (typeof result === "string" && result.trim())
|
|
653
|
+
return result.trim();
|
|
654
|
+
}
|
|
655
|
+
return null;
|
|
656
|
+
}
|
|
657
|
+
function isRecordValue(value) {
|
|
658
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
659
|
+
}
|
|
660
|
+
function asRecordValue(value) {
|
|
661
|
+
return isRecordValue(value) ? value : null;
|
|
662
|
+
}
|
|
440
663
|
async function executeCodexCliRun(options) {
|
|
441
664
|
const cwd = options.run.cwd || process.cwd();
|
|
442
665
|
const outputDir = fs.mkdtempSync(path.join(os.tmpdir(), "agent-native-code-codex-"));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @deprecated `create-workspace` is now an alias for `create`. In current
|
|
3
|
-
* versions, `agent-native create <name>`
|
|
4
|
-
*
|
|
5
|
-
* standalone scaffold.
|
|
3
|
+
* versions, `agent-native create <name>` asks for a starting shape and its
|
|
4
|
+
* Chat/first-party template paths scaffold a workspace. Use `--standalone`
|
|
5
|
+
* for a single-app standalone scaffold.
|
|
6
6
|
*
|
|
7
7
|
* This module is kept for backwards compatibility with older docs and
|
|
8
8
|
* scripts that still invoke `agent-native create-workspace`.
|
package/dist/cli/create.d.ts
CHANGED
|
@@ -32,8 +32,9 @@ export interface CreateAppOptions {
|
|
|
32
32
|
/**
|
|
33
33
|
* Main entry for `agent-native create [name]`.
|
|
34
34
|
*
|
|
35
|
-
* Default behavior:
|
|
36
|
-
*
|
|
35
|
+
* Default behavior: ask for a starting shape, with Chat and first-party
|
|
36
|
+
* templates creating a workspace at <name>/. Use --standalone for the
|
|
37
|
+
* single-app standalone flow.
|
|
37
38
|
*
|
|
38
39
|
* If run *inside* an existing workspace, falls through to the add-app
|
|
39
40
|
* flow that scaffolds one new app under apps/<name>/.
|