@sprigr/apps-app-sdk 0.8.5 → 0.8.6

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/index.d.ts CHANGED
@@ -1424,6 +1424,71 @@ interface OfferUndoArgs {
1424
1424
  */
1425
1425
  declare function offerUndo(args: OfferUndoArgs): Promise<AppUndoEnvelope | undefined>;
1426
1426
 
1427
+ /**
1428
+ * Apply confirmation policies to a parsed `sprigr-app.json`, for an app's
1429
+ * `gen:confirmation` script and its drift-guard test.
1430
+ *
1431
+ * Pure: takes the parsed manifest, mutates it in place, returns what it
1432
+ * touched. The script owns the two lines of file I/O around it, so this
1433
+ * module stays free of `node:fs` and safe to bundle into a Worker.
1434
+ *
1435
+ * Besides writing each policy, it retires the two mechanisms a policy
1436
+ * supersedes: the legacy `confirmation_required` flag (a bare
1437
+ * `{ always: true }` with no describe) and any app-declared `confirm` input
1438
+ * (the platform injects its own top-level `confirm` wherever a policy is
1439
+ * present). Both are stripped from EVERY tool, not only the gated ones,
1440
+ * because a stray copy on an ungated tool is how a handler ends up reading
1441
+ * a flag nothing enforces.
1442
+ */
1443
+
1444
+ interface ManifestDispatchBlock {
1445
+ actionField: string;
1446
+ actions: string[];
1447
+ actionInputs?: Record<string, {
1448
+ accepts: string[];
1449
+ required?: string[];
1450
+ }>;
1451
+ }
1452
+ interface ManifestToolLike {
1453
+ name: string;
1454
+ input_schema?: {
1455
+ properties?: Record<string, unknown>;
1456
+ required?: string[];
1457
+ [k: string]: unknown;
1458
+ };
1459
+ confirmation?: unknown;
1460
+ confirmation_required?: boolean;
1461
+ dispatch?: unknown;
1462
+ [k: string]: unknown;
1463
+ }
1464
+ interface ManifestLike {
1465
+ tools?: ManifestToolLike[];
1466
+ [k: string]: unknown;
1467
+ }
1468
+ interface ApplyPoliciesOptions {
1469
+ /** Tool name -> its policy: a tool-level rule, or `{ actions }` for a dispatcher. */
1470
+ policies: Readonly<Record<string, ConfirmationPolicy>>;
1471
+ /** Tool name -> dispatch block to write alongside (dispatchers only). */
1472
+ dispatch?: Readonly<Record<string, ManifestDispatchBlock>>;
1473
+ /** Delete `confirmation_required` from every tool. Default true. */
1474
+ stripLegacyFlag?: boolean;
1475
+ /** Delete an app-declared `confirm` input (property + required entry) from every tool. Default true. */
1476
+ dropConfirmParam?: boolean;
1477
+ }
1478
+ /**
1479
+ * Write the policies (and dispatch blocks) onto the named tools in place.
1480
+ * Throws when a policy names a tool the manifest does not have, so a
1481
+ * renamed tool cannot silently lose its gate. Returns the tool names touched.
1482
+ */
1483
+ declare function applyConfirmationPolicies(manifest: ManifestLike, opts: ApplyPoliciesOptions): string[];
1484
+ /**
1485
+ * True when applying the policies to a copy of the manifest changes nothing:
1486
+ * the committed file is a fresh generation. The drift-guard test's one call.
1487
+ */
1488
+ declare function manifestIsFresh(manifest: ManifestLike, opts: ApplyPoliciesOptions): boolean;
1489
+ /** The manifest, serialised the way the repo commits it (2-space, trailing newline). */
1490
+ declare function serializeManifest(manifest: ManifestLike): string;
1491
+
1427
1492
  /**
1428
1493
  * @sprigr/apps-app-sdk
1429
1494
  *
@@ -1824,4 +1889,4 @@ interface ExecutionContextLike {
1824
1889
  }
1825
1890
  type HandlerFn<TArgs, TResult> = (args: TArgs, env: Record<string, unknown>, ctx?: ExecutionContextLike) => Promise<TResult>;
1826
1891
 
1827
- export { APPROVAL_GRANTED_KEY, type Actor, type AppApprovalEnvelope, type AppFileListItem, type AppFileUrlArgs, type AppFileUrlResult, type AppFilesEnv, type AppUndoEnvelope, type ApprovalGateOptions, type ApprovalSpec, type ArchiveOfferOptions, type ArchiveOfferRefusal, type CaptureJournal, type ConfirmCondition, type ConfirmRule, type ConfirmationPolicy, type D1Like, type D1PreparedStatementLike, DEFAULT_EMIT_TIMEOUT_MS, DEFAULT_MAX_FILE_BYTES, DEFAULT_MONEY_FIELDS, DEFAULT_WRITE_PREFIXES, type DispatcherApprovalGate, type DispatcherApprovalOptions, type EmitMarketplaceEventOptions, type EmitResult, type EmitTransport, type EventArgs, type ExecutionContextLike, type FetchFileResult, type FetchWithRetryOptions, type GetAppFileResult, type HandlerFn, type InboxOwner, type InstallBridge, InvalidUndoEnvelopeError, type JournalRowLike, type MarketplaceEventEmitOpts, type MarketplaceEventSourceIntegration, NotConnectedError, type OAuthBouncerSignals, type OAuthState, type OfferUndoArgs, type PlatformHostEnv, type PolicyCheckInput, type PolicySource, type PutAppFileArgs, type PutAppFileResult, type PutAppFileStreamArgs, type RequireApprovalOptions, type RestoreResult, type RestoreSpec, type ScheduleArgs, type SprigrDataAggregationCell, type SprigrDataAggregationResult, type SprigrDataAggregationSpec, type SprigrDataApi, type SprigrDataIndexOpts, type SprigrDataSearchOpts, type SprigrDataSearchResult, type SprigrFilesApi, type SprigrFilesApiWithEdit, type SprigrFilesCreateInput, type SprigrFilesCreateResult, type SprigrFilesEditInput, type SprigrFilesEditResult, type SprigrFilesJobResult, type ToolArgs, type ToolHandler, type ToolResult, type ToolWrapperOptions, UNIT_SEP, type UndoApplyOptions, type UndoApplyResult, type UndoCaptureSpec, type UndoFidelity, type WebhookArgs, type WfpBridgeEnv, type WfpEmitReply, actorKey, actorTool, appFileUrl, approvalHash, archiveOfferRefusal, base64ToBytes, buildConfirmationPolicy, buildMarketplaceWebhookUrl, bytesToBase64, canEmit, checkConfirmationPolicy, constantTimeEqual, createMarketplaceEmitter, createToolWrappers, decodeState, deleteAppFile, describeMissingBridge, dispatcherApproval, emitMarketplaceEvent, encodeState, fetchFileAsBase64, fetchFileBytes, fetchWithRetry, fullWarning, getAppFile, hmacSha256Hex, installTokenPost, isNotConnectedError, isStagingHost, listAppFiles, offerUndo, overlaySprigr, ownerFromActorKey, parseActor, putAppFile, putAppFileStream, randomHex, recreatedWarning, refuseWithoutForce, requireApproval, resolveInstallBridge, resolveOAuthBouncerBase, resolveOAuthBouncerCallbackUrl, resolvePlatformWebhookBase, runUndoApply, safeCapture, seq, set, tool, undoEnvelope, withSprigrEmitFallback };
1892
+ export { APPROVAL_GRANTED_KEY, type Actor, type AppApprovalEnvelope, type AppFileListItem, type AppFileUrlArgs, type AppFileUrlResult, type AppFilesEnv, type AppUndoEnvelope, type ApplyPoliciesOptions, type ApprovalGateOptions, type ApprovalSpec, type ArchiveOfferOptions, type ArchiveOfferRefusal, type CaptureJournal, type ConfirmCondition, type ConfirmRule, type ConfirmationPolicy, type D1Like, type D1PreparedStatementLike, DEFAULT_EMIT_TIMEOUT_MS, DEFAULT_MAX_FILE_BYTES, DEFAULT_MONEY_FIELDS, DEFAULT_WRITE_PREFIXES, type DispatcherApprovalGate, type DispatcherApprovalOptions, type EmitMarketplaceEventOptions, type EmitResult, type EmitTransport, type EventArgs, type ExecutionContextLike, type FetchFileResult, type FetchWithRetryOptions, type GetAppFileResult, type HandlerFn, type InboxOwner, type InstallBridge, InvalidUndoEnvelopeError, type JournalRowLike, type ManifestDispatchBlock, type ManifestLike, type ManifestToolLike, type MarketplaceEventEmitOpts, type MarketplaceEventSourceIntegration, NotConnectedError, type OAuthBouncerSignals, type OAuthState, type OfferUndoArgs, type PlatformHostEnv, type PolicyCheckInput, type PolicySource, type PutAppFileArgs, type PutAppFileResult, type PutAppFileStreamArgs, type RequireApprovalOptions, type RestoreResult, type RestoreSpec, type ScheduleArgs, type SprigrDataAggregationCell, type SprigrDataAggregationResult, type SprigrDataAggregationSpec, type SprigrDataApi, type SprigrDataIndexOpts, type SprigrDataSearchOpts, type SprigrDataSearchResult, type SprigrFilesApi, type SprigrFilesApiWithEdit, type SprigrFilesCreateInput, type SprigrFilesCreateResult, type SprigrFilesEditInput, type SprigrFilesEditResult, type SprigrFilesJobResult, type ToolArgs, type ToolHandler, type ToolResult, type ToolWrapperOptions, UNIT_SEP, type UndoApplyOptions, type UndoApplyResult, type UndoCaptureSpec, type UndoFidelity, type WebhookArgs, type WfpBridgeEnv, type WfpEmitReply, actorKey, actorTool, appFileUrl, applyConfirmationPolicies, approvalHash, archiveOfferRefusal, base64ToBytes, buildConfirmationPolicy, buildMarketplaceWebhookUrl, bytesToBase64, canEmit, checkConfirmationPolicy, constantTimeEqual, createMarketplaceEmitter, createToolWrappers, decodeState, deleteAppFile, describeMissingBridge, dispatcherApproval, emitMarketplaceEvent, encodeState, fetchFileAsBase64, fetchFileBytes, fetchWithRetry, fullWarning, getAppFile, hmacSha256Hex, installTokenPost, isNotConnectedError, isStagingHost, listAppFiles, manifestIsFresh, offerUndo, overlaySprigr, ownerFromActorKey, parseActor, putAppFile, putAppFileStream, randomHex, recreatedWarning, refuseWithoutForce, requireApproval, resolveInstallBridge, resolveOAuthBouncerBase, resolveOAuthBouncerCallbackUrl, resolvePlatformWebhookBase, runUndoApply, safeCapture, seq, serializeManifest, set, tool, undoEnvelope, withSprigrEmitFallback };
package/dist/index.js CHANGED
@@ -940,6 +940,48 @@ function checkConfirmationPolicy(input) {
940
940
  }
941
941
  return out.sort();
942
942
  }
943
+
944
+ // src/write-protection/manifest.ts
945
+ function applyConfirmationPolicies(manifest, opts) {
946
+ const tools = manifest.tools ?? [];
947
+ const byName = new Map(tools.map((t) => [t.name, t]));
948
+ const touched = [];
949
+ for (const [name, policy] of Object.entries(opts.policies)) {
950
+ const tool2 = byName.get(name);
951
+ if (!tool2) throw new Error(`applyConfirmationPolicies: no tool named '${name}' in the manifest`);
952
+ tool2.confirmation = policy;
953
+ touched.push(name);
954
+ }
955
+ for (const [name, block] of Object.entries(opts.dispatch ?? {})) {
956
+ const tool2 = byName.get(name);
957
+ if (!tool2) throw new Error(`applyConfirmationPolicies: no tool named '${name}' in the manifest (dispatch)`);
958
+ tool2.dispatch = block;
959
+ if (!touched.includes(name)) touched.push(name);
960
+ }
961
+ const stripLegacy = opts.stripLegacyFlag ?? true;
962
+ const dropConfirm = opts.dropConfirmParam ?? true;
963
+ for (const tool2 of tools) {
964
+ if (stripLegacy) delete tool2.confirmation_required;
965
+ if (dropConfirm) {
966
+ const schema = tool2.input_schema;
967
+ if (schema?.properties && "confirm" in schema.properties) delete schema.properties.confirm;
968
+ if (schema?.required?.includes("confirm")) {
969
+ schema.required = schema.required.filter((k) => k !== "confirm");
970
+ if (schema.required.length === 0) delete schema.required;
971
+ }
972
+ }
973
+ }
974
+ return touched;
975
+ }
976
+ function manifestIsFresh(manifest, opts) {
977
+ const copy = JSON.parse(JSON.stringify(manifest));
978
+ applyConfirmationPolicies(copy, opts);
979
+ return JSON.stringify(copy) === JSON.stringify(manifest);
980
+ }
981
+ function serializeManifest(manifest) {
982
+ return `${JSON.stringify(manifest, null, 2)}
983
+ `;
984
+ }
943
985
  export {
944
986
  APPROVAL_GRANTED_KEY,
945
987
  DEFAULT_EMIT_TIMEOUT_MS,
@@ -952,6 +994,7 @@ export {
952
994
  actorKey,
953
995
  actorTool,
954
996
  appFileUrl,
997
+ applyConfirmationPolicies,
955
998
  approvalHash,
956
999
  archiveOfferRefusal,
957
1000
  base64ToBytes,
@@ -979,6 +1022,7 @@ export {
979
1022
  isNotConnectedError,
980
1023
  isStagingHost,
981
1024
  listAppFiles,
1025
+ manifestIsFresh,
982
1026
  offerUndo,
983
1027
  overlaySprigr,
984
1028
  ownerFromActorKey,
@@ -996,6 +1040,7 @@ export {
996
1040
  runUndoApply,
997
1041
  safeCapture,
998
1042
  seq,
1043
+ serializeManifest,
999
1044
  set,
1000
1045
  tool,
1001
1046
  undoEnvelope,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sprigr/apps-app-sdk",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",