@agent-native/core 0.227.0 → 0.228.0-nightly-20261111004142
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/action.d.ts +6 -2
- package/dist/agent/engine/builder-engine.js +6 -1
- package/dist/agent/engine/tool-call-journal-seed.d.ts +2 -0
- package/dist/agent/engine/tool-call-journal-seed.js +14 -0
- package/dist/agent/harness/store.js +14 -0
- package/dist/agent/production-agent.js +257 -17
- package/dist/agent/reaped-run-thread.js +6 -0
- package/dist/agent/run-manager.js +6 -0
- package/dist/agent/tool-call-journal.d.ts +4 -0
- package/dist/agent/tool-call-journal.js +12 -0
- package/dist/agent/types.d.ts +7 -1
- package/dist/app-config/agent.d.ts +3 -0
- package/dist/app-config/agent.js +7 -0
- package/dist/app-config/schema.d.ts +3 -0
- package/dist/application-state/handlers.d.ts +3 -3
- package/dist/application-state/handlers.js +6 -1
- package/dist/application-state/index.d.ts +3 -2
- package/dist/application-state/index.js +3 -2
- package/dist/application-state/last-used-tab.d.ts +11 -0
- package/dist/application-state/last-used-tab.js +43 -0
- package/dist/application-state/script-helpers.d.ts +26 -0
- package/dist/application-state/script-helpers.js +83 -15
- package/dist/application-state/store.d.ts +8 -0
- package/dist/application-state/store.js +16 -0
- package/dist/cli/agent.js +7 -3
- package/dist/cli/code-agent-executor.d.ts +1 -0
- package/dist/cli/code-agent-executor.js +37 -2
- package/dist/cli/code.js +3 -1
- package/dist/client/agent-sidebar-state.d.ts +2 -0
- package/dist/client/browser-tab-use.d.ts +9 -0
- package/dist/client/browser-tab-use.js +112 -0
- package/dist/client/chat/runtime.js +3 -1
- package/dist/client/error-capture.js +33 -1
- package/dist/client/navigation/index.d.ts +1 -0
- package/dist/client/navigation/index.js +1 -0
- package/dist/client/resources/mcp-integration-logos.js +16 -0
- package/dist/client/review/use-review.d.ts +28 -0
- package/dist/client/review/use-review.js +41 -12
- package/dist/client/route-state.js +2 -0
- package/dist/client/sse-event-processor.d.ts +1 -0
- package/dist/client/sse-event-processor.js +7 -1
- package/dist/client/use-db-sync.d.ts +8 -1
- package/dist/client/use-db-sync.js +6 -5
- package/dist/coding-tools/run-code.js +12 -2
- package/dist/coding-tools/sandbox/executions-store.d.ts +1 -1
- package/dist/coding-tools/sandbox/executions-store.js +9 -3
- package/dist/collab/routes.d.ts +1 -1
- package/dist/data-programs/execute.js +1 -1
- package/dist/db/schema-snapshot.generated.js +17 -3
- package/dist/extensions/url-safety.d.ts +1 -3
- package/dist/extensions/url-safety.js +23 -23
- package/dist/file-upload/actions/upload-image.d.ts +5 -5
- package/dist/file-upload/index.d.ts +1 -1
- package/dist/file-upload/index.js +1 -1
- package/dist/file-upload/s3-client.d.ts +1 -0
- package/dist/file-upload/s3-client.js +70 -13
- package/dist/file-upload/s3.d.ts +9 -0
- package/dist/file-upload/s3.js +14 -1
- package/dist/framework-package-versions.json +8 -8
- package/dist/jobs/run-history.js +10 -3
- package/dist/jobs/scheduler.js +5 -36
- package/dist/localization/core-messages/supplemental/ar-SA.js +35 -0
- package/dist/localization/core-messages/supplemental/de-DE.js +35 -0
- package/dist/localization/core-messages/supplemental/en-US.js +35 -0
- package/dist/localization/core-messages/supplemental/es-ES.js +35 -0
- package/dist/localization/core-messages/supplemental/fr-FR.js +35 -0
- package/dist/localization/core-messages/supplemental/hi-IN.js +35 -0
- package/dist/localization/core-messages/supplemental/ja-JP.js +35 -0
- package/dist/localization/core-messages/supplemental/ko-KR.js +35 -0
- package/dist/localization/core-messages/supplemental/pt-BR.js +35 -0
- package/dist/localization/core-messages/supplemental/zh-CN.js +35 -0
- package/dist/localization/core-messages/supplemental/zh-TW.js +35 -0
- package/dist/localization/default-messages.d.ts +35 -0
- package/dist/localization/default-messages.js +35 -0
- package/dist/localization/mcp-settings-messages.d.ts +35 -0
- package/dist/mcp/actions/list-mcp-client-connections.d.ts +8 -0
- package/dist/mcp/actions/list-mcp-client-connections.js +39 -0
- package/dist/mcp/browser-tab-target.d.ts +16 -0
- package/dist/mcp/browser-tab-target.js +58 -0
- package/dist/mcp/build-server.d.ts +1 -0
- package/dist/mcp/build-server.js +38 -7
- package/dist/mcp/call-attribution.d.ts +4 -1
- package/dist/mcp/call-attribution.js +3 -1
- package/dist/mcp/client-connections.d.ts +6 -0
- package/dist/mcp/client-connections.js +91 -0
- package/dist/mcp/connect-route.js +12 -2
- package/dist/mcp/connect-store.d.ts +3 -0
- package/dist/mcp/connect-store.js +10 -1
- package/dist/mcp/direct-action-call.js +1 -0
- package/dist/mcp/oauth-store.d.ts +6 -0
- package/dist/mcp/oauth-store.js +23 -0
- package/dist/mcp/oauth-token.d.ts +1 -0
- package/dist/mcp/oauth-token.js +1 -0
- package/dist/mcp/server.js +9 -20
- package/dist/mcp-client/config.d.ts +2 -0
- package/dist/mcp-client/manager.js +23 -0
- package/dist/mcp-client/workspace-servers.js +42 -10
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/org/handlers.d.ts +1 -1
- package/dist/org/handlers.js +21 -17
- package/dist/provider-api/actions/custom-provider-registration.d.ts +12 -12
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.js +17 -36
- package/dist/review/actions/create-review-comment.d.ts +7 -0
- package/dist/review/actions/create-review-comment.js +29 -3
- package/dist/review/actions/delete-review-comment.js +2 -2
- package/dist/review/actions/list-review-comments.d.ts +3 -0
- package/dist/review/actions/list-review-comments.js +41 -17
- package/dist/review/actions/react-to-review-comment.js +2 -2
- package/dist/review/actions/reply-review-comment.d.ts +4 -0
- package/dist/review/actions/reply-review-comment.js +15 -6
- package/dist/review/actions/update-review-comment-anchor.d.ts +6 -0
- package/dist/review/actions/update-review-comment-anchor.js +39 -10
- package/dist/review/actions/update-review-comment.d.ts +3 -0
- package/dist/review/actions/update-review-comment.js +28 -3
- package/dist/review/errors.d.ts +33 -0
- package/dist/review/errors.js +51 -0
- package/dist/review/index.d.ts +5 -4
- package/dist/review/index.js +3 -2
- package/dist/review/registry.d.ts +51 -1
- package/dist/review/registry.js +117 -0
- package/dist/review/store.d.ts +59 -14
- package/dist/review/store.js +622 -101
- package/dist/review/suggestions/actions.js +65 -10
- package/dist/review/suggestions/actor-kind.d.ts +5 -0
- package/dist/review/suggestions/actor-kind.js +20 -0
- package/dist/review/suggestions/store.js +16 -2
- package/dist/review/suggestions/types.d.ts +13 -0
- package/dist/review/types.d.ts +89 -0
- package/dist/scripts/db/dev-query-proxy.d.ts +2 -0
- package/dist/scripts/db/dev-query-proxy.js +4 -1
- package/dist/scripts/db/query.js +3 -0
- package/dist/scripts/dev/shell.js +4 -0
- package/dist/scripts/dev-session.d.ts +31 -0
- package/dist/scripts/dev-session.js +58 -0
- package/dist/scripts/resources/list.js +53 -4
- package/dist/scripts/runner.js +22 -4
- package/dist/search/query.d.ts +11 -5
- package/dist/search/query.js +52 -15
- package/dist/search/tokenize.d.ts +1 -0
- package/dist/search/tokenize.js +3 -0
- package/dist/secrets/api-keys.d.ts +4 -0
- package/dist/secrets/api-keys.js +5 -0
- package/dist/secrets/register.d.ts +2 -0
- package/dist/secrets/routes.d.ts +2 -2
- package/dist/secrets/routes.js +85 -6
- package/dist/secrets/storage.d.ts +2 -0
- package/dist/secrets/storage.js +34 -9
- package/dist/secrets/substitution.d.ts +3 -2
- package/dist/secrets/substitution.js +56 -7
- package/dist/server/action-discovery.js +5 -0
- package/dist/server/action-routes.js +8 -6
- package/dist/server/agent-chat/prompt-resources.js +117 -79
- package/dist/server/agent-chat/script-entries.js +15 -8
- package/dist/server/agent-chat-plugin.js +9 -4
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/agents-bundle.d.ts +3 -1
- package/dist/server/agents-bundle.js +4 -4
- package/dist/server/csrf.js +1 -0
- package/dist/server/dev-action-bridge.d.ts +2 -0
- package/dist/server/dev-action-bridge.js +34 -5
- package/dist/server/first-touch-route.d.ts +1 -1
- package/dist/server/http-response-telemetry.js +4 -0
- package/dist/server/loopback.js +3 -1
- package/dist/server/request-context.d.ts +26 -0
- package/dist/shared/app-state-routes.d.ts +7 -0
- package/dist/shared/app-state-routes.js +7 -0
- package/dist/shared/mcp-client-connections.d.ts +41 -0
- package/dist/shared/mcp-client-connections.js +18 -0
- package/dist/shared/mcp-connect-content.d.ts +18 -0
- package/dist/shared/mcp-connect-content.js +200 -172
- package/dist/shared/runtime-config.js +5 -1
- package/dist/templates/chat/.agents/skills/context-awareness/SKILL.md +13 -0
- package/dist/templates/default/.agents/skills/context-awareness/SKILL.md +13 -0
- package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +13 -0
- package/dist/tracking/providers.d.ts +7 -0
- package/dist/tracking/providers.js +39 -17
- package/dist/triggers/condition-evaluator.d.ts +2 -0
- package/dist/triggers/condition-evaluator.js +93 -3
- package/dist/triggers/dispatcher.js +24 -6
- package/docs/AGENTS.md +16 -16
- package/docs/content/create-with-an-agent.mdx +10 -4
- package/docs/content/durable-resume.mdx +11 -2
- package/docs/content/toolkit-comments-review.mdx +54 -1
- package/package.json +5 -4
- package/src/templates/chat/.agents/skills/context-awareness/SKILL.md +13 -0
- package/src/templates/default/.agents/skills/context-awareness/SKILL.md +13 -0
- package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +13 -0
|
@@ -3,6 +3,7 @@ import { isArtifactReceipt, } from "../artifacts/detect.js";
|
|
|
3
3
|
import { stripInlineBytes } from "../shared/inline-bytes.js";
|
|
4
4
|
import { toolCallInputSignature as inputSignature } from "./tool-call-input-signature.js";
|
|
5
5
|
import { isUnknownWriteCause } from "./types.js";
|
|
6
|
+
import { readWriteReceipt } from "./write-receipts.js";
|
|
6
7
|
export function toolCallIdentityKey(id, executionStepId) {
|
|
7
8
|
if (executionStepId !== undefined)
|
|
8
9
|
return JSON.stringify(["step", executionStepId]);
|
|
@@ -241,6 +242,9 @@ function replayOutcomeIdentity(entry) {
|
|
|
241
242
|
entry.result,
|
|
242
243
|
entry.isError,
|
|
243
244
|
entry.errorCode,
|
|
245
|
+
entry.receipt,
|
|
246
|
+
entry.actionSettled,
|
|
247
|
+
entry.settledOnCleanToolStop,
|
|
244
248
|
entry.committed,
|
|
245
249
|
entry.outcomeUnknown,
|
|
246
250
|
entry.artifacts,
|
|
@@ -339,6 +343,14 @@ export function classifyToolCallJournal(events) {
|
|
|
339
343
|
entry.isError = true;
|
|
340
344
|
if (event.errorCode)
|
|
341
345
|
entry.errorCode = event.errorCode;
|
|
346
|
+
const receipt = readWriteReceipt({ _receipt: event.receipt });
|
|
347
|
+
if (receipt)
|
|
348
|
+
entry.receipt = receipt;
|
|
349
|
+
if (event.actionSettled === true && event.isError !== true) {
|
|
350
|
+
entry.actionSettled = true;
|
|
351
|
+
if (event.settledOnCleanToolStop === true)
|
|
352
|
+
entry.settledOnCleanToolStop = true;
|
|
353
|
+
}
|
|
342
354
|
if (event.completedSideEffect === true)
|
|
343
355
|
entry.committed = true;
|
|
344
356
|
if (event.argumentsHash)
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -317,6 +317,12 @@ type AgentChatEventPayload = {
|
|
|
317
317
|
notExecuted?: true;
|
|
318
318
|
/** Compact action write evidence retained even when `result` is truncated. */
|
|
319
319
|
receipt?: WriteReceipt;
|
|
320
|
+
/** A successful invocation explicitly settled its work. */
|
|
321
|
+
actionSettled?: true;
|
|
322
|
+
/** The model completed the tool-call round before the action ran. */
|
|
323
|
+
settledOnCleanToolStop?: true;
|
|
324
|
+
/** The action emitted warnings the model must reconcile. */
|
|
325
|
+
hasAgentWarnings?: true;
|
|
320
326
|
/**
|
|
321
327
|
* Exact identity of the arguments the call ran with, defaults applied. A
|
|
322
328
|
* continued turn replays a committed call only for the same identity.
|
|
@@ -405,7 +411,7 @@ type AgentChatEventPayload = {
|
|
|
405
411
|
summary: string;
|
|
406
412
|
} | {
|
|
407
413
|
type: "done";
|
|
408
|
-
reason?: "user" | "loop_breaker";
|
|
414
|
+
reason?: "user" | "loop_breaker" | "action_settled";
|
|
409
415
|
message?: string;
|
|
410
416
|
} | {
|
|
411
417
|
type: "error";
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const agentConfig: z.ZodObject<{
|
|
3
|
+
promptSkills: z.ZodPrefault<z.ZodObject<{
|
|
4
|
+
includeSupportingFiles: z.ZodDefault<z.ZodBoolean>;
|
|
5
|
+
}, z.core.$strip>>;
|
|
3
6
|
engine: z.ZodOptional<z.ZodString>;
|
|
4
7
|
model: z.ZodOptional<z.ZodString>;
|
|
5
8
|
questionIntake: z.ZodOptional<z.ZodObject<{
|
package/dist/app-config/agent.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export const agentConfig = z.object({
|
|
3
|
+
promptSkills: z
|
|
4
|
+
.object({
|
|
5
|
+
includeSupportingFiles: z.boolean().default(true).meta({
|
|
6
|
+
doc: "Include supporting files, such as references and scripts, when presenting skills to the agent.",
|
|
7
|
+
}),
|
|
8
|
+
})
|
|
9
|
+
.prefault({}),
|
|
3
10
|
engine: z
|
|
4
11
|
.string()
|
|
5
12
|
.min(1)
|
|
@@ -86,6 +86,9 @@ export declare const appConfigSchema: z.ZodObject<{
|
|
|
86
86
|
}, z.core.$strip>>;
|
|
87
87
|
}, z.core.$strip>>;
|
|
88
88
|
agent: z.ZodPrefault<z.ZodObject<{
|
|
89
|
+
promptSkills: z.ZodPrefault<z.ZodObject<{
|
|
90
|
+
includeSupportingFiles: z.ZodDefault<z.ZodBoolean>;
|
|
91
|
+
}, z.core.$strip>>;
|
|
89
92
|
engine: z.ZodOptional<z.ZodString>;
|
|
90
93
|
model: z.ZodOptional<z.ZodString>;
|
|
91
94
|
questionIntake: z.ZodOptional<z.ZodObject<{
|
|
@@ -36,18 +36,18 @@ export declare const listComposeDrafts: import("h3").EventHandlerWithFetch<impor
|
|
|
36
36
|
export declare const getComposeDraft: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<Record<string, unknown> | null>>;
|
|
37
37
|
export declare const putComposeDraft: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<any>>;
|
|
38
38
|
export declare const saveComposeDraft: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
39
|
-
errorCode?: undefined;
|
|
40
|
-
error: string;
|
|
41
39
|
value?: undefined;
|
|
40
|
+
error: string;
|
|
42
41
|
revision?: undefined;
|
|
42
|
+
errorCode?: undefined;
|
|
43
43
|
details?: undefined;
|
|
44
44
|
} | {
|
|
45
|
-
errorCode?: undefined;
|
|
46
45
|
error?: undefined;
|
|
47
46
|
value: {
|
|
48
47
|
id: string;
|
|
49
48
|
};
|
|
50
49
|
revision: string;
|
|
50
|
+
errorCode?: undefined;
|
|
51
51
|
details?: undefined;
|
|
52
52
|
} | {
|
|
53
53
|
value?: undefined;
|
|
@@ -2,7 +2,8 @@ import { createError, defineEventHandler, getRouterParam, getHeader, getQuery, s
|
|
|
2
2
|
import { isSaveConflict, saveRevisionOf } from "../save-conflict/index.js";
|
|
3
3
|
import { readBrowserTabIdHeader } from "../server/agent-run-context.js";
|
|
4
4
|
import { readBody } from "../server/h3-helpers.js";
|
|
5
|
-
import { APP_STATE_BATCH_ROUTE_HEADER, APP_STATE_SEQ_HEADER, APP_STATE_WRITER_HEADER, TAB_SCOPED_APP_STATE_KEYS, } from "../shared/app-state-routes.js";
|
|
5
|
+
import { APP_STATE_BATCH_ROUTE_HEADER, APP_STATE_SEQ_HEADER, APP_STATE_WRITER_HEADER, BROWSER_TAB_USED_APP_STATE_KEY, TAB_SCOPED_APP_STATE_KEYS, } from "../shared/app-state-routes.js";
|
|
6
|
+
import { browserTabUsedKey } from "./last-used-tab.js";
|
|
6
7
|
import { appStateSaveIfCurrent } from "./save-if-current.js";
|
|
7
8
|
import { appStateKeyForBrowserTab } from "./script-helpers.js";
|
|
8
9
|
import { appStateGet, appStateGetManyEntries, appStatePut, appStateCompareAndSet, appStateDelete, appStateList, appStateDeleteByPrefix, } from "./store.js";
|
|
@@ -54,6 +55,10 @@ function headerSeq(event) {
|
|
|
54
55
|
return seq !== undefined && /^[0-9]{1,16}$/.test(seq) ? Number(seq) : seq;
|
|
55
56
|
}
|
|
56
57
|
function requestScopedKey(key, event) {
|
|
58
|
+
if (key === BROWSER_TAB_USED_APP_STATE_KEY) {
|
|
59
|
+
const browserTabId = readBrowserTabIdHeader(event);
|
|
60
|
+
return browserTabId ? browserTabUsedKey(browserTabId) : key;
|
|
61
|
+
}
|
|
57
62
|
return TAB_SCOPED_APP_STATE_KEYS.has(key)
|
|
58
63
|
? appStateKeyForBrowserTab(key, readBrowserTabIdHeader(event))
|
|
59
64
|
: key;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { appStateGet, appStateGetMany, appStateGetManyEntries, appStatePut, appStateDelete, appStateCompareAndSet, appStateCompareAndSetMany, appStateList, appStateDeleteByPrefix, type AppStateCompareAndSetOperation, } from "./store.js";
|
|
1
|
+
export { appStateGet, appStateGetMany, appStateGetManyEntries, appStatePut, appStateDelete, appStateCompareAndSet, appStateCompareAndSetMany, appStateList, appStateListUpdatedAt, appStateDeleteByPrefix, type AppStateCompareAndSetOperation, } from "./store.js";
|
|
2
|
+
export { browserTabUsedKey, findLastUsedBrowserTab, LAST_USED_BROWSER_TAB_MAX_AGE_MS, } from "./last-used-tab.js";
|
|
2
3
|
export { getAppStateEmitter, emitAppStateChange, emitAppStateDelete, type AppStateEvent, } from "./emitter.js";
|
|
3
4
|
export { getState, getStateMany, MAX_APP_STATE_BATCH_KEYS, MAX_APP_STATE_BATCH_WRITES, putState, putStateMany, deleteState, listComposeDrafts, getComposeDraft, putComposeDraft, deleteComposeDraft, deleteAllComposeDrafts, } from "./handlers.js";
|
|
4
|
-
export { readAppState, writeAppState, deleteAppState, compareAndSetAppState, compareAndSetManyAppState, listAppState, deleteAppStateByPrefix, readAppStateForCurrentTab, writeAppStateForCurrentTab, appStateKeyForBrowserTab, getCurrentRequestBrowserTabId, } from "./script-helpers.js";
|
|
5
|
+
export { readAppState, writeAppState, deleteAppState, compareAndSetAppState, compareAndSetManyAppState, listAppState, deleteAppStateByPrefix, readAppStateForCurrentTab, writeAppStateForCurrentTab, appStateKeyForBrowserTab, getCurrentRequestBrowserTabId, resolveCurrentRequestStateTab, } from "./script-helpers.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { appStateGet, appStateGetMany, appStateGetManyEntries, appStatePut, appStateDelete, appStateCompareAndSet, appStateCompareAndSetMany, appStateList, appStateDeleteByPrefix, } from "./store.js";
|
|
1
|
+
export { appStateGet, appStateGetMany, appStateGetManyEntries, appStatePut, appStateDelete, appStateCompareAndSet, appStateCompareAndSetMany, appStateList, appStateListUpdatedAt, appStateDeleteByPrefix, } from "./store.js";
|
|
2
|
+
export { browserTabUsedKey, findLastUsedBrowserTab, LAST_USED_BROWSER_TAB_MAX_AGE_MS, } from "./last-used-tab.js";
|
|
2
3
|
export { getAppStateEmitter, emitAppStateChange, emitAppStateDelete, } from "./emitter.js";
|
|
3
4
|
export { getState, getStateMany, MAX_APP_STATE_BATCH_KEYS, MAX_APP_STATE_BATCH_WRITES, putState, putStateMany, deleteState, listComposeDrafts, getComposeDraft, putComposeDraft, deleteComposeDraft, deleteAllComposeDrafts, } from "./handlers.js";
|
|
4
|
-
export { readAppState, writeAppState, deleteAppState, compareAndSetAppState, compareAndSetManyAppState, listAppState, deleteAppStateByPrefix, readAppStateForCurrentTab, writeAppStateForCurrentTab, appStateKeyForBrowserTab, getCurrentRequestBrowserTabId, } from "./script-helpers.js";
|
|
5
|
+
export { readAppState, writeAppState, deleteAppState, compareAndSetAppState, compareAndSetManyAppState, listAppState, deleteAppStateByPrefix, readAppStateForCurrentTab, writeAppStateForCurrentTab, appStateKeyForBrowserTab, getCurrentRequestBrowserTabId, resolveCurrentRequestStateTab, } from "./script-helpers.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BrowserTabTarget } from "../server/request-context.js";
|
|
2
|
+
/** How long after its last use a tab still counts as the one to act on. */
|
|
3
|
+
export declare const LAST_USED_BROWSER_TAB_MAX_AGE_MS: number;
|
|
4
|
+
/** The row that records a tab's last use: one per app and tab. */
|
|
5
|
+
export declare function browserTabUsedKey(browserTabId: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* The tab of this app the user used last, if one was used within
|
|
8
|
+
* LAST_USED_BROWSER_TAB_MAX_AGE_MS. Tabs are ordered by when the server
|
|
9
|
+
* stored their use, so browser clocks don't matter.
|
|
10
|
+
*/
|
|
11
|
+
export declare function findLastUsedBrowserTab(sessionId: string, now?: number): Promise<BrowserTabTarget>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getAppConfig } from "../app-config/index.js";
|
|
2
|
+
import { BROWSER_TAB_USED_APP_STATE_KEY } from "../shared/app-state-routes.js";
|
|
3
|
+
import { appStateListUpdatedAt } from "./store.js";
|
|
4
|
+
/** How long after its last use a tab still counts as the one to act on. */
|
|
5
|
+
export const LAST_USED_BROWSER_TAB_MAX_AGE_MS = 12 * 60 * 60 * 1000;
|
|
6
|
+
const SAFE_TAB_ID_RE = /^[A-Za-z0-9_-]{1,96}$/;
|
|
7
|
+
// Several apps can share one database (Design and Slides do), so each app
|
|
8
|
+
// keeps its tabs' records under its own name. The browser's write and the
|
|
9
|
+
// MCP lookup both run in this app's server, so they name it the same way.
|
|
10
|
+
// Encoding keeps distinct names distinct and keeps ":" out of the name.
|
|
11
|
+
function appScope() {
|
|
12
|
+
const app = getAppConfig().app;
|
|
13
|
+
const name = app.workspaceId ?? app.id ?? app.slug ?? app.packageName ?? app.name;
|
|
14
|
+
return name ? encodeURIComponent(name) : "app";
|
|
15
|
+
}
|
|
16
|
+
function browserTabUsedKeyPrefix() {
|
|
17
|
+
return `${BROWSER_TAB_USED_APP_STATE_KEY}:${appScope()}:`;
|
|
18
|
+
}
|
|
19
|
+
/** The row that records a tab's last use: one per app and tab. */
|
|
20
|
+
export function browserTabUsedKey(browserTabId) {
|
|
21
|
+
return `${browserTabUsedKeyPrefix()}${browserTabId}`;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The tab of this app the user used last, if one was used within
|
|
25
|
+
* LAST_USED_BROWSER_TAB_MAX_AGE_MS. Tabs are ordered by when the server
|
|
26
|
+
* stored their use, so browser clocks don't matter.
|
|
27
|
+
*/
|
|
28
|
+
export async function findLastUsedBrowserTab(sessionId, now = Date.now()) {
|
|
29
|
+
const prefix = browserTabUsedKeyPrefix();
|
|
30
|
+
let best;
|
|
31
|
+
for (const { key, updatedAt } of await appStateListUpdatedAt(sessionId, prefix, now - LAST_USED_BROWSER_TAB_MAX_AGE_MS)) {
|
|
32
|
+
const tabId = key.slice(prefix.length);
|
|
33
|
+
if (!SAFE_TAB_ID_RE.test(tabId))
|
|
34
|
+
continue;
|
|
35
|
+
if (!Number.isFinite(updatedAt))
|
|
36
|
+
continue;
|
|
37
|
+
if (now - updatedAt > LAST_USED_BROWSER_TAB_MAX_AGE_MS)
|
|
38
|
+
continue;
|
|
39
|
+
if (!best || updatedAt > best.usedAt)
|
|
40
|
+
best = { tabId, usedAt: updatedAt };
|
|
41
|
+
}
|
|
42
|
+
return best ? { kind: "last-used", ...best } : { kind: "unavailable" };
|
|
43
|
+
}
|
|
@@ -10,9 +10,35 @@ export declare function listAppState(prefix: string): Promise<Array<{
|
|
|
10
10
|
}>>;
|
|
11
11
|
export declare function deleteAppStateByPrefix(prefix: string): Promise<number>;
|
|
12
12
|
export declare function normalizeBrowserTabId(value: unknown): string | null;
|
|
13
|
+
/** The browser tab the current request came from, if any. */
|
|
13
14
|
export declare function getCurrentRequestBrowserTabId(): string | null;
|
|
15
|
+
/**
|
|
16
|
+
* The tab whose tab-scoped app state the current request reads and writes:
|
|
17
|
+
* the tab it came from or, for an MCP call from no tab, the tab of this app
|
|
18
|
+
* the user used last. `unavailable` when the call looked for a tab and none
|
|
19
|
+
* was used recently. Requests that have neither (scripts, jobs, the CLI) get
|
|
20
|
+
* no tab and keep the account-wide rows.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveCurrentRequestStateTab(): Promise<{
|
|
23
|
+
tabId: string | null;
|
|
24
|
+
unavailable: boolean;
|
|
25
|
+
}>;
|
|
14
26
|
export declare function appStateKeyForBrowserTab(key: string, browserTabId: unknown): string;
|
|
27
|
+
/**
|
|
28
|
+
* Reads `key` for the current request's tab (see
|
|
29
|
+
* resolveCurrentRequestStateTab), falling back to the account-wide row only
|
|
30
|
+
* when `fallbackToGlobal` is true. A request with no tab at all reads the
|
|
31
|
+
* account-wide row. An MCP call that found no recently used tab reads it
|
|
32
|
+
* only when it opted in, and never for the ambient keys: no tab keeps those
|
|
33
|
+
* rows current.
|
|
34
|
+
*/
|
|
15
35
|
export declare function readAppStateForCurrentTab(key: string, options?: {
|
|
16
36
|
fallbackToGlobal?: boolean;
|
|
17
37
|
}): Promise<Record<string, unknown> | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Writes `key` for the current request's tab (see
|
|
40
|
+
* resolveCurrentRequestStateTab). With no tab, it writes the account-wide
|
|
41
|
+
* row, as it always has: an MCP caller learns from the call's result that no
|
|
42
|
+
* tab was found.
|
|
43
|
+
*/
|
|
18
44
|
export declare function writeAppStateForCurrentTab(key: string, value: Record<string, unknown>): Promise<void>;
|
|
@@ -19,30 +19,43 @@ async function resolveSessionId() {
|
|
|
19
19
|
throw new Error("Application state access requires an authenticated request context or AGENT_USER_EMAIL env var");
|
|
20
20
|
}
|
|
21
21
|
export async function readAppState(key) {
|
|
22
|
-
|
|
22
|
+
const scoped = await requestScopedAppStateKey(key);
|
|
23
|
+
// No tab to read from: a call that asked for one gets nothing rather than
|
|
24
|
+
// the account-wide row, which no tab keeps current.
|
|
25
|
+
if (scoped.unavailable)
|
|
26
|
+
return null;
|
|
27
|
+
return readUnscopedAppState(scoped.key);
|
|
23
28
|
}
|
|
24
29
|
export async function writeAppState(key, value) {
|
|
25
30
|
const sessionId = await resolveSessionId();
|
|
26
|
-
|
|
31
|
+
const { key: scopedKey } = await requestScopedAppStateKey(key);
|
|
32
|
+
return appStatePut(sessionId, scopedKey, value, {
|
|
27
33
|
requestSource: "agent",
|
|
28
34
|
});
|
|
29
35
|
}
|
|
30
36
|
export async function deleteAppState(key) {
|
|
31
37
|
const sessionId = await resolveSessionId();
|
|
32
|
-
|
|
38
|
+
const { key: scopedKey } = await requestScopedAppStateKey(key);
|
|
39
|
+
return appStateDelete(sessionId, scopedKey, {
|
|
33
40
|
requestSource: "agent",
|
|
34
41
|
});
|
|
35
42
|
}
|
|
36
43
|
export async function compareAndSetAppState(key, expectedValue, nextValue) {
|
|
37
44
|
const sessionId = await resolveSessionId();
|
|
38
|
-
|
|
45
|
+
const { key: scopedKey } = await requestScopedAppStateKey(key);
|
|
46
|
+
return appStateCompareAndSet(sessionId, scopedKey, expectedValue, nextValue, {
|
|
47
|
+
requestSource: "agent",
|
|
48
|
+
});
|
|
39
49
|
}
|
|
40
50
|
export async function compareAndSetManyAppState(operations) {
|
|
41
51
|
const sessionId = await resolveSessionId();
|
|
42
|
-
|
|
52
|
+
const scopedOperations = await Promise.all(operations.map(async (operation) => ({
|
|
43
53
|
...operation,
|
|
44
|
-
key: requestScopedAppStateKey(operation.key),
|
|
45
|
-
}))
|
|
54
|
+
key: (await requestScopedAppStateKey(operation.key)).key,
|
|
55
|
+
})));
|
|
56
|
+
return appStateCompareAndSetMany(sessionId, scopedOperations, {
|
|
57
|
+
requestSource: "agent",
|
|
58
|
+
});
|
|
46
59
|
}
|
|
47
60
|
export async function listAppState(prefix) {
|
|
48
61
|
const sessionId = await resolveSessionId();
|
|
@@ -69,6 +82,7 @@ export function normalizeBrowserTabId(value) {
|
|
|
69
82
|
const trimmed = value.trim();
|
|
70
83
|
return SAFE_TAB_ID_RE.test(trimmed) ? trimmed : null;
|
|
71
84
|
}
|
|
85
|
+
/** The browser tab the current request came from, if any. */
|
|
72
86
|
export function getCurrentRequestBrowserTabId() {
|
|
73
87
|
try {
|
|
74
88
|
return normalizeBrowserTabId(getRequestRunContext()?.browserTabId);
|
|
@@ -77,32 +91,86 @@ export function getCurrentRequestBrowserTabId() {
|
|
|
77
91
|
return null;
|
|
78
92
|
}
|
|
79
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* The tab whose tab-scoped app state the current request reads and writes:
|
|
96
|
+
* the tab it came from or, for an MCP call from no tab, the tab of this app
|
|
97
|
+
* the user used last. `unavailable` when the call looked for a tab and none
|
|
98
|
+
* was used recently. Requests that have neither (scripts, jobs, the CLI) get
|
|
99
|
+
* no tab and keep the account-wide rows.
|
|
100
|
+
*/
|
|
101
|
+
export async function resolveCurrentRequestStateTab() {
|
|
102
|
+
const browserTabId = getCurrentRequestBrowserTabId();
|
|
103
|
+
if (browserTabId)
|
|
104
|
+
return { tabId: browserTabId, unavailable: false };
|
|
105
|
+
let slot;
|
|
106
|
+
try {
|
|
107
|
+
slot = getRequestRunContext()?.browserTabTarget;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
slot = undefined;
|
|
111
|
+
}
|
|
112
|
+
if (!slot)
|
|
113
|
+
return { tabId: null, unavailable: false };
|
|
114
|
+
const target = await slot.resolve();
|
|
115
|
+
if (target.kind === "last-used") {
|
|
116
|
+
const tabId = normalizeBrowserTabId(target.tabId);
|
|
117
|
+
if (tabId)
|
|
118
|
+
return { tabId, unavailable: false };
|
|
119
|
+
}
|
|
120
|
+
return { tabId: null, unavailable: true };
|
|
121
|
+
}
|
|
80
122
|
export function appStateKeyForBrowserTab(key, browserTabId) {
|
|
81
123
|
const normalized = normalizeBrowserTabId(browserTabId);
|
|
82
124
|
return normalized ? `${key}:${normalized}` : key;
|
|
83
125
|
}
|
|
84
|
-
function requestScopedAppStateKey(key) {
|
|
126
|
+
async function requestScopedAppStateKey(key) {
|
|
85
127
|
if (!TAB_SCOPED_AMBIENT_KEYS.has(key))
|
|
86
|
-
return key;
|
|
87
|
-
|
|
128
|
+
return { key, unavailable: false };
|
|
129
|
+
const tab = await resolveCurrentRequestStateTab();
|
|
130
|
+
return {
|
|
131
|
+
key: appStateKeyForBrowserTab(key, tab.tabId),
|
|
132
|
+
unavailable: tab.unavailable,
|
|
133
|
+
};
|
|
88
134
|
}
|
|
89
135
|
async function readUnscopedAppState(key) {
|
|
90
136
|
const sessionId = await resolveSessionId();
|
|
91
137
|
return appStateGet(sessionId, key);
|
|
92
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Reads `key` for the current request's tab (see
|
|
141
|
+
* resolveCurrentRequestStateTab), falling back to the account-wide row only
|
|
142
|
+
* when `fallbackToGlobal` is true. A request with no tab at all reads the
|
|
143
|
+
* account-wide row. An MCP call that found no recently used tab reads it
|
|
144
|
+
* only when it opted in, and never for the ambient keys: no tab keeps those
|
|
145
|
+
* rows current.
|
|
146
|
+
*/
|
|
93
147
|
export async function readAppStateForCurrentTab(key, options) {
|
|
94
|
-
const
|
|
95
|
-
const tabKey = appStateKeyForBrowserTab(key,
|
|
148
|
+
const tab = await resolveCurrentRequestStateTab();
|
|
149
|
+
const tabKey = appStateKeyForBrowserTab(key, tab.tabId);
|
|
150
|
+
const fallbackToGlobal = options?.fallbackToGlobal === true;
|
|
96
151
|
if (tabKey !== key) {
|
|
97
152
|
const scoped = await readAppState(tabKey);
|
|
98
153
|
if (scoped)
|
|
99
154
|
return scoped;
|
|
100
|
-
if (
|
|
155
|
+
if (!fallbackToGlobal)
|
|
101
156
|
return null;
|
|
102
157
|
}
|
|
158
|
+
if (tab.unavailable &&
|
|
159
|
+
(!fallbackToGlobal || TAB_SCOPED_AMBIENT_KEYS.has(key)))
|
|
160
|
+
return null;
|
|
103
161
|
return readUnscopedAppState(key);
|
|
104
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Writes `key` for the current request's tab (see
|
|
165
|
+
* resolveCurrentRequestStateTab). With no tab, it writes the account-wide
|
|
166
|
+
* row, as it always has: an MCP caller learns from the call's result that no
|
|
167
|
+
* tab was found.
|
|
168
|
+
*/
|
|
105
169
|
export async function writeAppStateForCurrentTab(key, value) {
|
|
106
|
-
const
|
|
107
|
-
|
|
170
|
+
const tab = await resolveCurrentRequestStateTab();
|
|
171
|
+
const tabKey = appStateKeyForBrowserTab(key, tab.tabId);
|
|
172
|
+
if (tabKey !== key)
|
|
173
|
+
return writeAppState(tabKey, value);
|
|
174
|
+
const sessionId = await resolveSessionId();
|
|
175
|
+
return appStatePut(sessionId, key, value, { requestSource: "agent" });
|
|
108
176
|
}
|
|
@@ -46,6 +46,14 @@ export declare function appStateList(sessionId: string, keyPrefix: string): Prom
|
|
|
46
46
|
key: string;
|
|
47
47
|
value: Record<string, unknown>;
|
|
48
48
|
}>>;
|
|
49
|
+
/**
|
|
50
|
+
* Lists the keys under `keyPrefix` with when the server last wrote each,
|
|
51
|
+
* leaving out any written before `writtenSince`.
|
|
52
|
+
*/
|
|
53
|
+
export declare function appStateListUpdatedAt(sessionId: string, keyPrefix: string, writtenSince?: number): Promise<Array<{
|
|
54
|
+
key: string;
|
|
55
|
+
updatedAt: number;
|
|
56
|
+
}>>;
|
|
49
57
|
export declare function appStateListByKeyPrefix(keyPrefix: string, limit?: number): Promise<Array<{
|
|
50
58
|
sessionId: string;
|
|
51
59
|
key: string;
|
|
@@ -253,6 +253,22 @@ export async function appStateList(sessionId, keyPrefix) {
|
|
|
253
253
|
value: JSON.parse(row.value),
|
|
254
254
|
}));
|
|
255
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* Lists the keys under `keyPrefix` with when the server last wrote each,
|
|
258
|
+
* leaving out any written before `writtenSince`.
|
|
259
|
+
*/
|
|
260
|
+
export async function appStateListUpdatedAt(sessionId, keyPrefix, writtenSince = 0) {
|
|
261
|
+
await ensureTable();
|
|
262
|
+
const client = getDbExec();
|
|
263
|
+
const { rows } = await client.execute({
|
|
264
|
+
sql: `SELECT key, updated_at FROM application_state WHERE session_id = ? AND key LIKE ? ESCAPE '!' AND updated_at >= ?`,
|
|
265
|
+
args: [sessionId, escapeLike(keyPrefix) + "%", writtenSince],
|
|
266
|
+
});
|
|
267
|
+
return rows.map((row) => ({
|
|
268
|
+
key: row.key,
|
|
269
|
+
updatedAt: Number(row.updated_at),
|
|
270
|
+
}));
|
|
271
|
+
}
|
|
256
272
|
export async function appStateListByKeyPrefix(keyPrefix, limit = 100) {
|
|
257
273
|
await ensureTable();
|
|
258
274
|
const client = getDbExec();
|
package/dist/cli/agent.js
CHANGED
|
@@ -8,7 +8,7 @@ import { runAgentLoopDirectWithSoftTimeout } from "../agent/run-loop-with-resume
|
|
|
8
8
|
import { getAppConfig } from "../app-config/index.js";
|
|
9
9
|
import { createGitHubRepoToolEntries } from "../provider-api/github-repo.js";
|
|
10
10
|
import { loadCliBootstrap } from "../scripts/cli-bootstrap.js";
|
|
11
|
-
import { resolveDevUserEmail } from "../scripts/dev-session.js";
|
|
11
|
+
import { devOrgChoiceFromEnv, resolveDevOrgScope, resolveDevUserEmail, } from "../scripts/dev-session.js";
|
|
12
12
|
import { loadEnv, serializeCliArgs } from "../scripts/utils.js";
|
|
13
13
|
import { autoDiscoverActions } from "../server/action-discovery.js";
|
|
14
14
|
import { captureCliOutput } from "../server/cli-capture.js";
|
|
@@ -134,9 +134,13 @@ export async function runAgent(args, io = {}) {
|
|
|
134
134
|
return 1;
|
|
135
135
|
}
|
|
136
136
|
const ownerEmail = parsed.userEmail ?? env.AGENT_USER_EMAIL ?? (await resolveDevUserEmail());
|
|
137
|
-
const
|
|
137
|
+
const envChoice = devOrgChoiceFromEnv(env);
|
|
138
|
+
const orgScope = await resolveDevOrgScope(ownerEmail, {
|
|
139
|
+
orgId: parsed.orgId ?? envChoice.orgId,
|
|
140
|
+
personal: envChoice.personal,
|
|
141
|
+
});
|
|
138
142
|
try {
|
|
139
|
-
const result = await runWithRequestContext({ userEmail: ownerEmail,
|
|
143
|
+
const result = await runWithRequestContext({ ...(ownerEmail ? { userEmail: ownerEmail } : {}), ...orgScope }, () => runLocalAgentLoop(parsed));
|
|
140
144
|
if (parsed.json) {
|
|
141
145
|
stdout(JSON.stringify(result, null, 2));
|
|
142
146
|
return result.failure ? 1 : 0;
|
|
@@ -21,6 +21,7 @@ interface CodeAgentApprovalExecutionOptions {
|
|
|
21
21
|
streamToolOutputToStdout?: boolean;
|
|
22
22
|
signal?: AbortSignal;
|
|
23
23
|
}
|
|
24
|
+
export declare const RECAP_SOURCE_TOOL_PROFILE = "recap-source";
|
|
24
25
|
export declare function executeCodeAgentRun(options: ExecuteCodeAgentRunOptions): Promise<CodeAgentRunRecord | null>;
|
|
25
26
|
export declare function codeAgentMcpInvocationPolicy(permissionMode: CodeAgentPermissionMode): McpToolInvocationPolicy;
|
|
26
27
|
export declare function executeExistingCodeAgentRun(runId: string, options?: Omit<ExecuteCodeAgentRunOptions, "runId">): Promise<CodeAgentRunRecord | null>;
|
|
@@ -31,8 +31,18 @@ const MCP_CONFIG_REMOVE_ATTEMPTS = 3;
|
|
|
31
31
|
const PI_CLI_ENGINE_NAME = "pi-cli";
|
|
32
32
|
const OPENCODE_CLI_ENGINE_NAME = "opencode-cli";
|
|
33
33
|
const CLAUDE_CLI_DEFAULT_MODEL = "claude-sonnet-5-5";
|
|
34
|
-
const RECAP_SOURCE_TOOL_PROFILE = "recap-source";
|
|
34
|
+
export const RECAP_SOURCE_TOOL_PROFILE = "recap-source";
|
|
35
35
|
const RECAP_SOURCE_OUTPUT_FILE = "recap-source.json";
|
|
36
|
+
const RECAP_SOURCE_INPUT_FILES = new Set([
|
|
37
|
+
"recap.diff",
|
|
38
|
+
"recap.stat",
|
|
39
|
+
"recap-blocks.md",
|
|
40
|
+
"recap-prompt.md",
|
|
41
|
+
"recap-source.initial.json",
|
|
42
|
+
"recap-source.json",
|
|
43
|
+
"recap-url-reason.txt",
|
|
44
|
+
"recap-repair-prompt.md",
|
|
45
|
+
]);
|
|
36
46
|
const STRUCTURED_HISTORY_RECENT_EVENTS = 40;
|
|
37
47
|
const STRUCTURED_HISTORY_RESULT_CAP = MAX_TOOL_OUTPUT_CHARS;
|
|
38
48
|
export async function executeCodeAgentRun(options) {
|
|
@@ -2268,8 +2278,28 @@ function createLocalCodeAgentActions(cwd, permissionMode, runId, onToolMetadata,
|
|
|
2268
2278
|
if (toolProfile === RECAP_SOURCE_TOOL_PROFILE) {
|
|
2269
2279
|
const allowedOutput = path.resolve(cwd, RECAP_SOURCE_OUTPUT_FILE);
|
|
2270
2280
|
const writeAction = actions.write;
|
|
2281
|
+
const readAction = actions.read;
|
|
2271
2282
|
return {
|
|
2272
|
-
read:
|
|
2283
|
+
read: {
|
|
2284
|
+
...readAction,
|
|
2285
|
+
run: async (args, context) => {
|
|
2286
|
+
const requestedPath = args && typeof args.path === "string" ? args.path : "";
|
|
2287
|
+
try {
|
|
2288
|
+
const resolved = path.resolve(cwd, requestedPath);
|
|
2289
|
+
const name = path.basename(resolved);
|
|
2290
|
+
if (!RECAP_SOURCE_INPUT_FILES.has(name) ||
|
|
2291
|
+
resolved !== path.join(cwd, name) ||
|
|
2292
|
+
fs.lstatSync(resolved).isSymbolicLink() ||
|
|
2293
|
+
path.dirname(fs.realpathSync(resolved)) !== fs.realpathSync(cwd)) {
|
|
2294
|
+
return "Error: recap source reads are limited to generated recap inputs.";
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
catch {
|
|
2298
|
+
return "Error: recap source reads are limited to generated recap inputs.";
|
|
2299
|
+
}
|
|
2300
|
+
return readAction.run(args, context);
|
|
2301
|
+
},
|
|
2302
|
+
},
|
|
2273
2303
|
write: {
|
|
2274
2304
|
...writeAction,
|
|
2275
2305
|
run: async (args, context) => {
|
|
@@ -2277,6 +2307,11 @@ function createLocalCodeAgentActions(cwd, permissionMode, runId, onToolMetadata,
|
|
|
2277
2307
|
if (path.resolve(cwd, requestedPath) !== allowedOutput) {
|
|
2278
2308
|
return `Error: only ${RECAP_SOURCE_OUTPUT_FILE} may be written in the recap-source tool profile.`;
|
|
2279
2309
|
}
|
|
2310
|
+
if (fs
|
|
2311
|
+
.lstatSync(allowedOutput, { throwIfNoEntry: false })
|
|
2312
|
+
?.isSymbolicLink()) {
|
|
2313
|
+
return `Error: ${RECAP_SOURCE_OUTPUT_FILE} cannot be a symbolic link.`;
|
|
2314
|
+
}
|
|
2280
2315
|
return writeAction.run(args, context);
|
|
2281
2316
|
},
|
|
2282
2317
|
},
|
package/dist/cli/code.js
CHANGED
|
@@ -4,7 +4,7 @@ import { createInterface } from "node:readline";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { runAuditAgentWeb } from "./audit-agent-web.js";
|
|
6
6
|
import { findProjectSlashCommand, listProjectSlashCommands, renderProjectSlashCommandPrompt, } from "./code-agent-commands.js";
|
|
7
|
-
import { executeApproveAlwaysCodeAgentApproval, executeCodeAgentRun, executeDenyCodeAgentApproval, executeExistingCodeAgentRun, executePendingCodeAgentApproval, } from "./code-agent-executor.js";
|
|
7
|
+
import { RECAP_SOURCE_TOOL_PROFILE, executeApproveAlwaysCodeAgentApproval, executeCodeAgentRun, executeDenyCodeAgentApproval, executeExistingCodeAgentRun, executePendingCodeAgentApproval, } from "./code-agent-executor.js";
|
|
8
8
|
import { CODE_AGENT_PERMISSION_MODES, appendCodeAgentTranscriptEvent, createCodeAgentRunRecord, getCodeAgentRunRecord, getLastCodeAgentRunRecord, isActiveCodeAgentRun, listCodeAgentRunRecords, listCodeAgentTranscriptEvents, normalizeCodeAgentPermissionMode, queueCodeAgentFollowUp, updateCodeAgentRunRecord, } from "./code-agent-runs.js";
|
|
9
9
|
import { runMigrate } from "./migrate.js";
|
|
10
10
|
export const CODE_AGENT_CLI_GOALS = [
|
|
@@ -325,6 +325,8 @@ Usage:
|
|
|
325
325
|
agent-native code run <runId>
|
|
326
326
|
agent-native code goals
|
|
327
327
|
|
|
328
|
+
Restricted tool profile: ${RECAP_SOURCE_TOOL_PROFILE}
|
|
329
|
+
|
|
328
330
|
Interactive shell:
|
|
329
331
|
/help Show shell commands
|
|
330
332
|
/goals List available coding-agent goals
|
|
@@ -13,6 +13,8 @@ export interface AgentSidebarStateChangeDetail {
|
|
|
13
13
|
open: boolean;
|
|
14
14
|
source: AgentSidebarStateSource;
|
|
15
15
|
mode: AgentSidebarStateMode;
|
|
16
|
+
/** The panel draws inside the app's `panelHost`, not beside the page. */
|
|
17
|
+
hosted?: boolean;
|
|
16
18
|
}
|
|
17
19
|
export declare function snapAgentSidebarWidth(width: number): number;
|
|
18
20
|
export declare function getAgentSidebarWideWidth(viewportWidth?: number): number;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Records when someone uses this browser tab (it gains focus, or its route
|
|
3
|
+
* changes while focused) and forgets the tab when the page goes away. An MCP
|
|
4
|
+
* tool call comes from no tab, so the server points its tab-scoped app
|
|
5
|
+
* state (navigation, navigate commands, selection) at the tab of this app
|
|
6
|
+
* used last. `useAgentRouteState` calls it; an app with its own navigation
|
|
7
|
+
* sync calls it once with its current route.
|
|
8
|
+
*/
|
|
9
|
+
export declare function useBrowserTabUse(route: string, enabled?: boolean): void;
|