@socialseal/cli 0.1.11 → 0.1.12

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/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.1.12 - 2026-06-23
6
+
7
+ - Expose Asset Studio and video production tool surfaces through CLI discovery/schema output.
8
+ - Add category-filtered tool discovery for users and agents.
9
+
5
10
  ## 0.1.11 - 2026-06-12
6
11
 
7
12
  - Add ad hoc public video URL analysis parity for queue and extract workflows, including `--url` and `--allow-untracked` support.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@socialseal/cli",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "SocialSeal CLI (non-interactive)",
package/src/index.js CHANGED
@@ -146,6 +146,94 @@ const KNOWN_TOOLS = [
146
146
  knownLocalDevState: 'enabled',
147
147
  notes: 'Accepts videoId/videoUid/platformVideoId/searchResultId items and public URL items with allowUntracked=true; videoId means video_uid or platform-native video id, not a tracking item id.',
148
148
  },
149
+ {
150
+ name: 'vnext-clips-read',
151
+ category: 'asset-studio',
152
+ description: 'List workspace clip-library items and optionally sign selected source videos.',
153
+ objectType: 'workspace_clip',
154
+ transport: 'post_edge_function',
155
+ workspaceScoped: true,
156
+ knownLocalDevState: 'enabled',
157
+ },
158
+ {
159
+ name: 'vnext-clips-create',
160
+ category: 'asset-studio',
161
+ description: 'Create signed clip upload targets and finalize uploaded clip metadata.',
162
+ objectType: 'workspace_clip',
163
+ transport: 'post_edge_function',
164
+ workspaceScoped: true,
165
+ knownLocalDevState: 'enabled',
166
+ actionAliases: ['create', 'finalize'],
167
+ notes: 'The create action returns signed upload URLs; upload bytes to storage before calling finalize.',
168
+ },
169
+ {
170
+ name: 'vnext-clip-shot-mappings-read',
171
+ category: 'asset-studio',
172
+ description: 'Read clip-to-blueprint shot mappings for Asset Studio.',
173
+ objectType: 'clip_shot_mapping',
174
+ transport: 'post_edge_function',
175
+ workspaceScoped: true,
176
+ knownLocalDevState: 'enabled',
177
+ },
178
+ {
179
+ name: 'vnext-clip-shot-mappings-write',
180
+ category: 'asset-studio',
181
+ description: 'Upsert or delete clip-to-blueprint shot mappings for Asset Studio.',
182
+ objectType: 'clip_shot_mapping',
183
+ transport: 'post_edge_function',
184
+ workspaceScoped: true,
185
+ knownLocalDevState: 'enabled',
186
+ actionAliases: ['upsert', 'delete'],
187
+ },
188
+ {
189
+ name: 'vnext-generated-assets-read',
190
+ category: 'asset-studio',
191
+ description: 'List generated rough cuts for a blueprint or read one generated asset.',
192
+ objectType: 'generated_asset',
193
+ transport: 'post_edge_function',
194
+ workspaceScoped: true,
195
+ knownLocalDevState: 'enabled',
196
+ actionAliases: ['list', 'detail'],
197
+ },
198
+ {
199
+ name: 'vnext-generated-asset-create',
200
+ category: 'asset-studio',
201
+ description: 'Create a generated rough-cut asset from an edit spec.',
202
+ objectType: 'generated_asset',
203
+ transport: 'post_edge_function',
204
+ workspaceScoped: true,
205
+ knownLocalDevState: 'enabled',
206
+ },
207
+ {
208
+ name: 'vnext-generated-asset-optimize',
209
+ category: 'asset-studio',
210
+ description: 'Optimize a generated asset or create a new revision.',
211
+ objectType: 'generated_asset_revision',
212
+ transport: 'post_edge_function',
213
+ workspaceScoped: true,
214
+ knownLocalDevState: 'enabled',
215
+ actionAliases: ['optimize', 'create-revision'],
216
+ },
217
+ {
218
+ name: 'vnext-generated-asset-export',
219
+ category: 'asset-studio',
220
+ description: 'Export a generated rough cut as FCPXML.',
221
+ objectType: 'generated_asset_export',
222
+ transport: 'post_edge_function',
223
+ workspaceScoped: true,
224
+ knownLocalDevState: 'enabled',
225
+ },
226
+ {
227
+ name: 'vnext-generated-asset-share',
228
+ category: 'asset-studio',
229
+ description: 'Create, read, or revoke generated-asset share links.',
230
+ objectType: 'generated_asset_share',
231
+ transport: 'post_edge_function',
232
+ workspaceScoped: false,
233
+ knownLocalDevState: 'enabled',
234
+ actionAliases: ['create', 'read', 'revoke'],
235
+ notes: 'create/revoke require workspaceId in the body; read uses shareToken and does not require workspace scope.',
236
+ },
149
237
  { name: 'douyin-geo-api', category: 'search', description: 'Query Douyin search and geo data.' },
150
238
  {
151
239
  name: 'google-ai-search',
@@ -218,7 +306,34 @@ const KNOWN_TOOLS = [
218
306
  { name: 'vnext-blueprints-create', category: 'vnext', description: 'Create a vNext blueprint from grounded evidence.' },
219
307
  { name: 'vnext-blueprints-generate', category: 'vnext', description: 'Generate a vNext blueprint from workspace opportunity data.' },
220
308
  { name: 'vnext-blueprints-read', category: 'vnext', description: 'Read vNext blueprint history and specific versions.' },
309
+ {
310
+ name: 'vnext-blueprints-shots-read',
311
+ category: 'video-production',
312
+ description: 'Read shot-lift and pinned shot assets for a blueprint.',
313
+ objectType: 'blueprint_shot_asset',
314
+ transport: 'post_edge_function',
315
+ workspaceScoped: true,
316
+ knownLocalDevState: 'enabled',
317
+ },
318
+ {
319
+ name: 'vnext-blueprints-shots-refresh',
320
+ category: 'video-production',
321
+ description: 'Queue a refresh for blueprint shot assets.',
322
+ objectType: 'blueprint_shots_job',
323
+ transport: 'post_edge_function',
324
+ workspaceScoped: true,
325
+ knownLocalDevState: 'enabled',
326
+ },
221
327
  { name: 'vnext-briefs-create', category: 'vnext', description: 'Create a vNext brief record.' },
328
+ {
329
+ name: 'vnext-briefs-export',
330
+ category: 'video-production',
331
+ description: 'Export a generated vNext brief as markdown.',
332
+ objectType: 'vnext_brief_export',
333
+ transport: 'post_edge_function',
334
+ workspaceScoped: true,
335
+ knownLocalDevState: 'enabled',
336
+ },
222
337
  { name: 'vnext-briefs-generate', category: 'vnext', description: 'Generate a vNext brief from a blueprint or opportunity.' },
223
338
  { name: 'vnext-briefs-read', category: 'vnext', description: 'Read generated vNext briefs and version history.' },
224
339
  { name: 'vnext-intents', category: 'vnext', description: 'List, create, update, or delete vNext intents.' },
@@ -451,6 +566,311 @@ const TOOL_SCHEMA_HINTS = {
451
566
  'socialseal tools call --function tracked-video-extract --workspace-id <workspace-uuid> --body \'{"allowUntracked":true,"items":[{"url":"https://www.instagram.com/reel/SHORTCODE/"}]}\'',
452
567
  ],
453
568
  },
569
+ 'vnext-clips-read': {
570
+ summary: 'List Asset Studio clip-library items and optionally sign selected video URLs.',
571
+ operations: [
572
+ {
573
+ action: 'list',
574
+ required: ['workspaceId or --workspace-id'],
575
+ optional: ['videoClipIds[] to include signed source video URLs'],
576
+ example: {
577
+ workspaceId: '00000000-0000-4000-8000-000000000000',
578
+ videoClipIds: ['11111111-1111-4111-8111-111111111111'],
579
+ },
580
+ },
581
+ ],
582
+ cliExamples: [
583
+ 'socialseal tools call --function vnext-clips-read --workspace-id <workspace-uuid> --body \'{"videoClipIds":["<clip-uuid>"]}\'',
584
+ ],
585
+ },
586
+ 'vnext-clips-create': {
587
+ summary: 'Create signed upload targets for clips and finalize uploaded clip metadata.',
588
+ operations: [
589
+ {
590
+ action: 'create',
591
+ required: ['action=create', 'workspaceId or --workspace-id', 'fileName', 'mimeType'],
592
+ optional: [],
593
+ example: {
594
+ action: 'create',
595
+ workspaceId: '00000000-0000-4000-8000-000000000000',
596
+ fileName: 'hero-shot.mp4',
597
+ mimeType: 'video/mp4',
598
+ },
599
+ },
600
+ {
601
+ action: 'finalize',
602
+ required: ['action=finalize', 'workspaceId or --workspace-id', 'clipId', 'fileName', 'storagePath', 'mimeType', 'sizeBytes', 'rightsAttested=true'],
603
+ optional: ['durationSeconds', 'width', 'height', 'posterPath'],
604
+ example: {
605
+ action: 'finalize',
606
+ workspaceId: '00000000-0000-4000-8000-000000000000',
607
+ clipId: '11111111-1111-4111-8111-111111111111',
608
+ fileName: 'hero-shot.mp4',
609
+ storagePath: 'workspace-00000000-0000-4000-8000-000000000000/11111111-1111-4111-8111-111111111111.mp4',
610
+ mimeType: 'video/mp4',
611
+ sizeBytes: 1048576,
612
+ rightsAttested: true,
613
+ },
614
+ },
615
+ ],
616
+ cliExamples: [
617
+ 'socialseal tools call --function vnext-clips-create --workspace-id <workspace-uuid> --body \'{"action":"create","fileName":"hero-shot.mp4","mimeType":"video/mp4"}\'',
618
+ 'socialseal tools call --function vnext-clips-create --workspace-id <workspace-uuid> --body @clip-finalize.json',
619
+ ],
620
+ },
621
+ 'vnext-clip-shot-mappings-read': {
622
+ summary: 'Read Asset Studio clip-to-shot mappings for a blueprint.',
623
+ operations: [
624
+ {
625
+ action: 'read',
626
+ required: ['workspaceId or --workspace-id', 'blueprintId'],
627
+ optional: [],
628
+ example: {
629
+ workspaceId: '00000000-0000-4000-8000-000000000000',
630
+ blueprintId: '22222222-2222-4222-8222-222222222222',
631
+ },
632
+ },
633
+ ],
634
+ cliExamples: [
635
+ 'socialseal tools call --function vnext-clip-shot-mappings-read --workspace-id <workspace-uuid> --body \'{"blueprintId":"<blueprint-uuid>"}\'',
636
+ ],
637
+ },
638
+ 'vnext-clip-shot-mappings-write': {
639
+ summary: 'Upsert or delete Asset Studio clip-to-shot mappings.',
640
+ operations: [
641
+ {
642
+ action: 'upsert',
643
+ required: ['action=upsert', 'workspaceId or --workspace-id', 'blueprintId', 'panelId', 'clipId'],
644
+ optional: ['source (suggested|override)', 'score'],
645
+ example: {
646
+ action: 'upsert',
647
+ workspaceId: '00000000-0000-4000-8000-000000000000',
648
+ blueprintId: '22222222-2222-4222-8222-222222222222',
649
+ panelId: 'panel-1',
650
+ clipId: '11111111-1111-4111-8111-111111111111',
651
+ source: 'override',
652
+ },
653
+ },
654
+ {
655
+ action: 'delete',
656
+ required: ['action=delete', 'workspaceId or --workspace-id', 'blueprintId', 'panelId'],
657
+ optional: [],
658
+ example: {
659
+ action: 'delete',
660
+ workspaceId: '00000000-0000-4000-8000-000000000000',
661
+ blueprintId: '22222222-2222-4222-8222-222222222222',
662
+ panelId: 'panel-1',
663
+ },
664
+ },
665
+ ],
666
+ cliExamples: [
667
+ 'socialseal tools call --function vnext-clip-shot-mappings-write --workspace-id <workspace-uuid> --body \'{"action":"upsert","blueprintId":"<blueprint-uuid>","panelId":"panel-1","clipId":"<clip-uuid>"}\'',
668
+ ],
669
+ },
670
+ 'vnext-generated-assets-read': {
671
+ summary: 'List generated rough cuts for a blueprint or read one generated asset.',
672
+ operations: [
673
+ {
674
+ action: 'list',
675
+ required: ['action=list', 'workspaceId or --workspace-id', 'blueprintId'],
676
+ optional: [],
677
+ example: {
678
+ action: 'list',
679
+ workspaceId: '00000000-0000-4000-8000-000000000000',
680
+ blueprintId: '22222222-2222-4222-8222-222222222222',
681
+ },
682
+ },
683
+ {
684
+ action: 'detail',
685
+ required: ['action=detail', 'workspaceId or --workspace-id', 'assetId'],
686
+ optional: [],
687
+ example: {
688
+ action: 'detail',
689
+ workspaceId: '00000000-0000-4000-8000-000000000000',
690
+ assetId: '33333333-3333-4333-8333-333333333333',
691
+ },
692
+ },
693
+ ],
694
+ cliExamples: [
695
+ 'socialseal tools call --function vnext-generated-assets-read --workspace-id <workspace-uuid> --body \'{"action":"list","blueprintId":"<blueprint-uuid>"}\'',
696
+ 'socialseal tools call --function vnext-generated-assets-read --workspace-id <workspace-uuid> --body \'{"action":"detail","assetId":"<asset-uuid>"}\'',
697
+ ],
698
+ },
699
+ 'vnext-generated-asset-create': {
700
+ summary: 'Create a generated rough cut from an Asset Studio edit spec.',
701
+ operations: [
702
+ {
703
+ action: 'create',
704
+ required: ['workspaceId or --workspace-id', 'blueprintId', 'title', 'editSpec'],
705
+ optional: [],
706
+ example: {
707
+ workspaceId: '00000000-0000-4000-8000-000000000000',
708
+ blueprintId: '22222222-2222-4222-8222-222222222222',
709
+ title: 'Homepage rough cut',
710
+ editSpec: {
711
+ version: 1,
712
+ fps: 30,
713
+ width: 1080,
714
+ height: 1920,
715
+ totalDurationSeconds: 3,
716
+ shots: [
717
+ {
718
+ panelId: 'panel-1',
719
+ clipId: '11111111-1111-4111-8111-111111111111',
720
+ title: 'Opening hook',
721
+ kind: 'hook',
722
+ shotLabel: 'Hero exterior',
723
+ sourceStartSeconds: 0,
724
+ durationSeconds: 3,
725
+ evidenceIds: [],
726
+ },
727
+ ],
728
+ },
729
+ },
730
+ },
731
+ ],
732
+ cliExamples: [
733
+ 'socialseal tools call --function vnext-generated-asset-create --workspace-id <workspace-uuid> --body @edit-spec.json',
734
+ ],
735
+ },
736
+ 'vnext-generated-asset-optimize': {
737
+ summary: 'Optimize a generated asset or create a new revision.',
738
+ operations: [
739
+ {
740
+ action: 'optimize',
741
+ required: ['action=optimize', 'workspaceId or --workspace-id', 'assetId'],
742
+ optional: [],
743
+ example: {
744
+ action: 'optimize',
745
+ workspaceId: '00000000-0000-4000-8000-000000000000',
746
+ assetId: '33333333-3333-4333-8333-333333333333',
747
+ },
748
+ },
749
+ {
750
+ action: 'create-revision',
751
+ required: ['action=create-revision', 'workspaceId or --workspace-id', 'assetId'],
752
+ optional: [],
753
+ example: {
754
+ action: 'create-revision',
755
+ workspaceId: '00000000-0000-4000-8000-000000000000',
756
+ assetId: '33333333-3333-4333-8333-333333333333',
757
+ },
758
+ },
759
+ ],
760
+ cliExamples: [
761
+ 'socialseal tools call --function vnext-generated-asset-optimize --workspace-id <workspace-uuid> --body \'{"action":"optimize","assetId":"<asset-uuid>"}\'',
762
+ ],
763
+ },
764
+ 'vnext-generated-asset-export': {
765
+ summary: 'Export a generated rough cut as FCPXML.',
766
+ operations: [
767
+ {
768
+ action: 'export',
769
+ required: ['workspaceId or --workspace-id', 'assetId'],
770
+ optional: ['format=fcpxml'],
771
+ example: {
772
+ workspaceId: '00000000-0000-4000-8000-000000000000',
773
+ assetId: '33333333-3333-4333-8333-333333333333',
774
+ format: 'fcpxml',
775
+ },
776
+ },
777
+ ],
778
+ cliExamples: [
779
+ 'socialseal tools call --function vnext-generated-asset-export --workspace-id <workspace-uuid> --body \'{"assetId":"<asset-uuid>","format":"fcpxml"}\'',
780
+ ],
781
+ },
782
+ 'vnext-generated-asset-share': {
783
+ summary: 'Create, read, or revoke generated rough-cut share links.',
784
+ operations: [
785
+ {
786
+ action: 'create',
787
+ required: ['action=create', 'workspaceId', 'assetId'],
788
+ optional: ['ttlSeconds', 'shareBaseUrl'],
789
+ example: {
790
+ action: 'create',
791
+ workspaceId: '00000000-0000-4000-8000-000000000000',
792
+ assetId: '33333333-3333-4333-8333-333333333333',
793
+ ttlSeconds: 604800,
794
+ },
795
+ },
796
+ {
797
+ action: 'read',
798
+ required: ['action=read', 'shareToken'],
799
+ optional: [],
800
+ example: {
801
+ action: 'read',
802
+ shareToken: '0123456789abcdef0123456789abcdef',
803
+ },
804
+ },
805
+ {
806
+ action: 'revoke',
807
+ required: ['action=revoke', 'workspaceId', 'shareLinkId'],
808
+ optional: [],
809
+ example: {
810
+ action: 'revoke',
811
+ workspaceId: '00000000-0000-4000-8000-000000000000',
812
+ shareLinkId: '44444444-4444-4444-8444-444444444444',
813
+ },
814
+ },
815
+ ],
816
+ cliExamples: [
817
+ 'socialseal tools call --function vnext-generated-asset-share --body \'{"action":"create","workspaceId":"<workspace-uuid>","assetId":"<asset-uuid>"}\'',
818
+ 'socialseal tools call --function vnext-generated-asset-share --body \'{"action":"read","shareToken":"<share-token>"}\'',
819
+ ],
820
+ },
821
+ 'vnext-blueprints-shots-read': {
822
+ summary: 'Read blueprint shot-lift rows and pinned shot assets with signed URLs.',
823
+ operations: [
824
+ {
825
+ action: 'read',
826
+ required: ['workspaceId or --workspace-id', 'blueprintId'],
827
+ optional: ['signedUrlSeconds'],
828
+ example: {
829
+ workspaceId: '00000000-0000-4000-8000-000000000000',
830
+ blueprintId: '22222222-2222-4222-8222-222222222222',
831
+ signedUrlSeconds: 3600,
832
+ },
833
+ },
834
+ ],
835
+ cliExamples: [
836
+ 'socialseal tools call --function vnext-blueprints-shots-read --workspace-id <workspace-uuid> --body \'{"blueprintId":"<blueprint-uuid>"}\'',
837
+ ],
838
+ },
839
+ 'vnext-blueprints-shots-refresh': {
840
+ summary: 'Queue a refresh for blueprint shot assets.',
841
+ operations: [
842
+ {
843
+ action: 'refresh',
844
+ required: ['workspaceId or --workspace-id', 'blueprintId'],
845
+ optional: [],
846
+ example: {
847
+ workspaceId: '00000000-0000-4000-8000-000000000000',
848
+ blueprintId: '22222222-2222-4222-8222-222222222222',
849
+ },
850
+ },
851
+ ],
852
+ cliExamples: [
853
+ 'socialseal tools call --function vnext-blueprints-shots-refresh --workspace-id <workspace-uuid> --body \'{"blueprintId":"<blueprint-uuid>"}\'',
854
+ ],
855
+ },
856
+ 'vnext-briefs-export': {
857
+ summary: 'Export the latest or selected generated vNext brief as markdown.',
858
+ operations: [
859
+ {
860
+ action: 'export',
861
+ required: ['workspaceId or --workspace-id', 'opportunityKey'],
862
+ optional: ['version'],
863
+ example: {
864
+ workspaceId: '00000000-0000-4000-8000-000000000000',
865
+ opportunityKey: 'opportunity-key',
866
+ version: 1,
867
+ },
868
+ },
869
+ ],
870
+ cliExamples: [
871
+ 'socialseal tools call --function vnext-briefs-export --workspace-id <workspace-uuid> --body \'{"opportunityKey":"<opportunity-key>"}\'',
872
+ ],
873
+ },
454
874
  'group-management': {
455
875
  summary: 'Manage single-platform tracking groups and memberships.',
456
876
  operations: [
@@ -544,6 +964,18 @@ function buildToolRegistry() {
544
964
  });
545
965
  }
546
966
 
967
+ function filterToolRegistry(tools, category) {
968
+ const normalizedCategory = trimString(category).toLowerCase();
969
+ const filtered = normalizedCategory
970
+ ? tools.filter((tool) => trimString(tool.category).toLowerCase() === normalizedCategory)
971
+ : tools;
972
+ return [...filtered].sort((a, b) => {
973
+ const categoryCompare = trimString(a.category).localeCompare(trimString(b.category));
974
+ if (categoryCompare !== 0) return categoryCompare;
975
+ return trimString(a.name).localeCompare(trimString(b.name));
976
+ });
977
+ }
978
+
547
979
  function getConfigPath() {
548
980
  return process.env.SOCIALSEAL_CONFIG || DEFAULT_CONFIG_PATH;
549
981
  }
@@ -1164,6 +1596,23 @@ function resolvePayloadWorkspaceId(payload, fallbackWorkspaceId) {
1164
1596
  return fallbackWorkspaceId || null;
1165
1597
  }
1166
1598
 
1599
+ function isGeneratedAssetShareScopedAction(functionName, payload) {
1600
+ if (functionName !== 'vnext-generated-asset-share' || !isJsonObject(payload)) {
1601
+ return false;
1602
+ }
1603
+ const action = trimString(payload.action).toLowerCase();
1604
+ return action === 'create' || action === 'revoke';
1605
+ }
1606
+
1607
+ function shouldRequireToolWorkspace(functionName, payload) {
1608
+ const tool = getKnownTool(functionName);
1609
+ const category = trimString(tool?.category).toLowerCase();
1610
+ return (
1611
+ Boolean(tool?.workspaceScoped) &&
1612
+ (category === 'asset-studio' || category === 'video-production')
1613
+ ) || isGeneratedAssetShareScopedAction(functionName, payload);
1614
+ }
1615
+
1167
1616
  function isUuidLike(value) {
1168
1617
  return typeof value === 'string' && /^[0-9a-f]{8}-[0-9a-f-]{27}$/i.test(value.trim());
1169
1618
  }
@@ -3756,6 +4205,26 @@ async function handleToolsCall(opts) {
3756
4205
  });
3757
4206
  }
3758
4207
 
4208
+ const scopedPayload = isJsonObject(translated.normalizedPayload)
4209
+ ? translated.normalizedPayload
4210
+ : (isJsonObject(translated.body) ? translated.body : payload);
4211
+ const hasSpecialWorkspaceHandling = new Set([
4212
+ 'group-management',
4213
+ 'export_tracking_data',
4214
+ 'tracked-video-extract',
4215
+ ]).has(opts.function);
4216
+ if (!hasSpecialWorkspaceHandling && shouldRequireToolWorkspace(opts.function, scopedPayload)) {
4217
+ requireWorkspaceSelection(effectiveWorkspaceId, {
4218
+ label: opts.function,
4219
+ hint: 'Pass --workspace-id, set SOCIALSEAL_WORKSPACE_ID, include workspaceId in the body, or configure a default workspace.',
4220
+ });
4221
+ emitWorkspaceSelectionNotice(opts, {
4222
+ workspaceId: effectiveWorkspaceId,
4223
+ source: effectiveWorkspaceSource,
4224
+ label: opts.function,
4225
+ });
4226
+ }
4227
+
3759
4228
  emitTrackingCreateScopeWarning(
3760
4229
  isJsonObject(translated.normalizedPayload) ? trimString(translated.normalizedPayload.action).toLowerCase() : '',
3761
4230
  effectiveWorkspaceId,
@@ -3854,9 +4323,10 @@ async function handleToolsCall(opts) {
3854
4323
  }
3855
4324
 
3856
4325
  function handleToolsList(opts) {
3857
- const tools = buildToolRegistry();
4326
+ const tools = filterToolRegistry(buildToolRegistry(), opts.category);
3858
4327
  const payload = {
3859
4328
  discovery: 'built_in_registry',
4329
+ category: trimString(opts.category) || null,
3860
4330
  tools,
3861
4331
  note: STATIC_TOOL_REGISTRY_NOTE,
3862
4332
  schemaNote: STATIC_TOOL_SCHEMA_NOTE,
@@ -3868,6 +4338,9 @@ function handleToolsList(opts) {
3868
4338
  }
3869
4339
 
3870
4340
  process.stdout.write('[socialseal] Built-in tool registry\n');
4341
+ if (payload.category) {
4342
+ process.stdout.write(`[socialseal] Category filter: ${payload.category}\n`);
4343
+ }
3871
4344
  process.stdout.write(`[socialseal] ${payload.note}\n`);
3872
4345
  process.stdout.write(`[socialseal] ${payload.schemaNote}\n`);
3873
4346
 
@@ -4983,6 +5456,7 @@ const tools = program.command('tools').description('Call edge functions directly
4983
5456
  tools
4984
5457
  .command('list')
4985
5458
  .description('List built-in tool registry entries')
5459
+ .option('--category <name>', 'Filter tools by category')
4986
5460
  .option('--json', 'Emit machine-readable output')
4987
5461
  .option('--pretty', 'Pretty-print JSON')
4988
5462
  .option('--verbose', 'Show error details')