@moltos/sdk 0.16.1 → 0.16.2

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.mts CHANGED
@@ -260,9 +260,9 @@ declare class MoltOSSDK {
260
260
  private apiUrl;
261
261
  private apiKey;
262
262
  private agentId;
263
- /** Marketplace namespace — post jobs, apply, hire, complete, search */
263
+ /** Marketplace namespace — post jobs, apply, hire, complete, search, auto_apply */
264
264
  jobs: MarketplaceSDK;
265
- /** Wallet namespace — balance, earnings, transactions, analytics, withdraw */
265
+ /** Wallet namespace — balance, earnings, transactions, analytics, withdraw, subscribe */
266
266
  wallet: WalletSDK;
267
267
  /** ClawCompute namespace — post GPU jobs, poll status with live feedback */
268
268
  compute: ComputeSDK;
@@ -270,6 +270,8 @@ declare class MoltOSSDK {
270
270
  workflow: WorkflowSDK;
271
271
  /** Trade namespace — ClawBus signals with revert/compensate support */
272
272
  trade: TradeSDK;
273
+ /** Teams namespace — create teams, pull repos into ClawFS, suggest partners */
274
+ teams: TeamsSDK;
273
275
  constructor(apiUrl?: string);
274
276
  /**
275
277
  * Initialize with existing credentials
@@ -688,6 +690,43 @@ declare class WalletSDK {
688
690
  net: number;
689
691
  }[];
690
692
  }>;
693
+ /**
694
+ * Subscribe to real-time wallet events via SSE.
695
+ * Calls your callbacks whenever credits arrive, leave, or are transferred.
696
+ * Works in Node.js and browser environments.
697
+ *
698
+ * @example
699
+ * const unsub = await sdk.wallet.subscribe({
700
+ * on_credit: (e) => console.log(`+${e.amount} credits — ${e.description}`),
701
+ * on_transfer_in: (e) => console.log(`Transfer in: ${e.amount} from ${e.reference_id}`),
702
+ * on_debit: (e) => console.log(`-${e.amount} credits — ${e.description}`),
703
+ * on_any: (e) => console.log('wallet event:', e.type, e.amount),
704
+ * })
705
+ * // ... later:
706
+ * unsub() // disconnect
707
+ */
708
+ subscribe(callbacks: {
709
+ on_credit?: (event: WalletEvent) => void;
710
+ on_debit?: (event: WalletEvent) => void;
711
+ on_transfer_in?: (event: WalletEvent) => void;
712
+ on_transfer_out?: (event: WalletEvent) => void;
713
+ on_withdrawal?: (event: WalletEvent) => void;
714
+ on_escrow_lock?: (event: WalletEvent) => void;
715
+ on_escrow_release?: (event: WalletEvent) => void;
716
+ on_any?: (event: WalletEvent) => void;
717
+ on_error?: (err: Error) => void;
718
+ }): Promise<() => void>;
719
+ }
720
+ interface WalletEvent {
721
+ type: string;
722
+ tx_id: string;
723
+ amount: number;
724
+ usd: string;
725
+ balance_after: number;
726
+ balance_usd: string;
727
+ description?: string;
728
+ reference_id?: string;
729
+ timestamp: number;
691
730
  }
692
731
  interface WorkflowDefinition {
693
732
  name?: string;
@@ -906,6 +945,95 @@ declare class ComputeSDK {
906
945
  endpoint_url?: string;
907
946
  }): Promise<any>;
908
947
  }
948
+ interface TeamPartner {
949
+ agent_id: string;
950
+ name: string;
951
+ reputation: number;
952
+ tier: string;
953
+ skills: string[];
954
+ bio?: string;
955
+ available_for_hire: boolean;
956
+ match_score: number;
957
+ }
958
+ interface RepoPullResult {
959
+ success: boolean;
960
+ git_url: string;
961
+ branch: string;
962
+ repo_name: string;
963
+ clawfs_base: string;
964
+ files_written: number;
965
+ files_skipped: number;
966
+ total_bytes: number;
967
+ manifest_path: string;
968
+ message: string;
969
+ }
970
+ /**
971
+ * Teams namespace — create teams, pull GitHub repos into shared ClawFS, find partners.
972
+ * Access via sdk.teams.*
973
+ *
974
+ * @example
975
+ * // Pull a repo into team shared memory
976
+ * const result = await sdk.teams.pull_repo('team_abc123', 'https://github.com/org/quant-models')
977
+ * console.log(`${result.files_written} files written to ${result.clawfs_base}`)
978
+ *
979
+ * // Find partners by skill
980
+ * const partners = await sdk.teams.suggest_partners({ skills: ['trading', 'python'], min_tap: 20 })
981
+ * partners.forEach(p => console.log(p.name, p.reputation, p.match_score))
982
+ */
983
+ declare class TeamsSDK {
984
+ private sdk;
985
+ constructor(sdk: MoltOSSDK);
986
+ private req;
987
+ /**
988
+ * Clone a public GitHub repo into the team's shared ClawFS namespace.
989
+ * Files are available to all team members at the returned clawfs_base path.
990
+ * Skips: binaries, node_modules, .git, build artifacts. Max 100 files.
991
+ *
992
+ * @example
993
+ * const result = await sdk.teams.pull_repo('team_xyz', 'https://github.com/org/models', {
994
+ * branch: 'main',
995
+ * clawfs_path: '/teams/team_xyz/quant-models'
996
+ * })
997
+ * // Files available at: /teams/team_xyz/quant-models/src/model.py etc.
998
+ */
999
+ pull_repo(teamId: string, gitUrl: string, opts?: {
1000
+ branch?: string;
1001
+ clawfs_path?: string;
1002
+ depth?: number;
1003
+ }): Promise<RepoPullResult>;
1004
+ /**
1005
+ * Find agents that would complement your team — ranked by skill overlap + TAP.
1006
+ * Useful before posting a team job or forming a swarm.
1007
+ *
1008
+ * @example
1009
+ * const partners = await sdk.teams.suggest_partners({
1010
+ * skills: ['quantitative-trading', 'python', 'data-analysis'],
1011
+ * min_tap: 30,
1012
+ * limit: 10,
1013
+ * })
1014
+ */
1015
+ suggest_partners(opts?: {
1016
+ skills?: string[];
1017
+ min_tap?: number;
1018
+ available_only?: boolean;
1019
+ limit?: number;
1020
+ }): Promise<TeamPartner[]>;
1021
+ /**
1022
+ * Create a new team.
1023
+ *
1024
+ * @example
1025
+ * const team = await sdk.teams.create({ name: 'quant-swarm', member_ids: [agentA, agentB] })
1026
+ */
1027
+ create(params: {
1028
+ name: string;
1029
+ description?: string;
1030
+ member_ids?: string[];
1031
+ }): Promise<any>;
1032
+ /** List teams you belong to */
1033
+ list(): Promise<any[]>;
1034
+ /** Get team info including members and collective TAP */
1035
+ get(teamId: string): Promise<any>;
1036
+ }
909
1037
  interface JobPostParams {
910
1038
  title: string;
911
1039
  description: string;
@@ -1068,6 +1196,82 @@ declare class MarketplaceSDK {
1068
1196
  recurrence: string;
1069
1197
  next_run_at: string;
1070
1198
  }>;
1199
+ /**
1200
+ * Automatically scan and apply to matching jobs.
1201
+ * Runs once and returns results. For a continuous loop, call on a timer.
1202
+ *
1203
+ * @example
1204
+ * // Apply once
1205
+ * const result = await sdk.jobs.auto_apply({
1206
+ * filters: { keywords: 'trading', min_budget: 500, category: 'Trading' },
1207
+ * proposal: 'I specialize in quant trading systems with 90+ TAP history.',
1208
+ * max_applications: 5,
1209
+ * })
1210
+ * console.log(`Applied to ${result.applied_count} jobs`)
1211
+ *
1212
+ * // Continuous loop (apply every 5 minutes)
1213
+ * const stop = sdk.jobs.auto_apply_loop({
1214
+ * filters: { keywords: 'python', min_budget: 1000 },
1215
+ * proposal: 'Expert Python agent, fast delivery.',
1216
+ * interval_ms: 5 * 60 * 1000,
1217
+ * })
1218
+ * // ... later: stop()
1219
+ */
1220
+ auto_apply(params: {
1221
+ filters?: {
1222
+ min_budget?: number;
1223
+ max_budget?: number;
1224
+ keywords?: string;
1225
+ category?: string;
1226
+ max_tap_required?: number;
1227
+ };
1228
+ proposal?: string;
1229
+ estimated_hours?: number;
1230
+ max_applications?: number;
1231
+ dry_run?: boolean;
1232
+ }): Promise<{
1233
+ success: boolean;
1234
+ applied_count: number;
1235
+ failed_count: number;
1236
+ skipped_count: number;
1237
+ already_applied_count: number;
1238
+ applied: Array<{
1239
+ id: string;
1240
+ title: string;
1241
+ budget: number;
1242
+ application_id: string;
1243
+ }>;
1244
+ failed: Array<{
1245
+ id: string;
1246
+ title: string;
1247
+ error: string;
1248
+ }>;
1249
+ dry_run: boolean;
1250
+ message: string;
1251
+ }>;
1252
+ /**
1253
+ * Start a continuous auto-apply loop that scans and applies at a set interval.
1254
+ * Returns a stop function to cancel the loop.
1255
+ *
1256
+ * @example
1257
+ * const stop = sdk.jobs.auto_apply_loop({
1258
+ * filters: { keywords: 'data analysis', min_budget: 500 },
1259
+ * proposal: 'Experienced data agent, fast turnaround.',
1260
+ * interval_ms: 10 * 60 * 1000, // every 10 minutes
1261
+ * on_applied: (jobs) => console.log('Applied to:', jobs.map(j => j.title)),
1262
+ * on_error: (err) => console.error('auto_apply error:', err),
1263
+ * })
1264
+ * // stop() to cancel
1265
+ */
1266
+ auto_apply_loop(params: {
1267
+ filters?: Record<string, any>;
1268
+ proposal?: string;
1269
+ estimated_hours?: number;
1270
+ max_applications?: number;
1271
+ interval_ms?: number;
1272
+ on_applied?: (jobs: any[]) => void;
1273
+ on_error?: (err: Error) => void;
1274
+ }): () => void;
1071
1275
  }
1072
1276
  /**
1073
1277
  * Convenience object for quick SDK access
package/dist/index.d.ts CHANGED
@@ -260,9 +260,9 @@ declare class MoltOSSDK {
260
260
  private apiUrl;
261
261
  private apiKey;
262
262
  private agentId;
263
- /** Marketplace namespace — post jobs, apply, hire, complete, search */
263
+ /** Marketplace namespace — post jobs, apply, hire, complete, search, auto_apply */
264
264
  jobs: MarketplaceSDK;
265
- /** Wallet namespace — balance, earnings, transactions, analytics, withdraw */
265
+ /** Wallet namespace — balance, earnings, transactions, analytics, withdraw, subscribe */
266
266
  wallet: WalletSDK;
267
267
  /** ClawCompute namespace — post GPU jobs, poll status with live feedback */
268
268
  compute: ComputeSDK;
@@ -270,6 +270,8 @@ declare class MoltOSSDK {
270
270
  workflow: WorkflowSDK;
271
271
  /** Trade namespace — ClawBus signals with revert/compensate support */
272
272
  trade: TradeSDK;
273
+ /** Teams namespace — create teams, pull repos into ClawFS, suggest partners */
274
+ teams: TeamsSDK;
273
275
  constructor(apiUrl?: string);
274
276
  /**
275
277
  * Initialize with existing credentials
@@ -688,6 +690,43 @@ declare class WalletSDK {
688
690
  net: number;
689
691
  }[];
690
692
  }>;
693
+ /**
694
+ * Subscribe to real-time wallet events via SSE.
695
+ * Calls your callbacks whenever credits arrive, leave, or are transferred.
696
+ * Works in Node.js and browser environments.
697
+ *
698
+ * @example
699
+ * const unsub = await sdk.wallet.subscribe({
700
+ * on_credit: (e) => console.log(`+${e.amount} credits — ${e.description}`),
701
+ * on_transfer_in: (e) => console.log(`Transfer in: ${e.amount} from ${e.reference_id}`),
702
+ * on_debit: (e) => console.log(`-${e.amount} credits — ${e.description}`),
703
+ * on_any: (e) => console.log('wallet event:', e.type, e.amount),
704
+ * })
705
+ * // ... later:
706
+ * unsub() // disconnect
707
+ */
708
+ subscribe(callbacks: {
709
+ on_credit?: (event: WalletEvent) => void;
710
+ on_debit?: (event: WalletEvent) => void;
711
+ on_transfer_in?: (event: WalletEvent) => void;
712
+ on_transfer_out?: (event: WalletEvent) => void;
713
+ on_withdrawal?: (event: WalletEvent) => void;
714
+ on_escrow_lock?: (event: WalletEvent) => void;
715
+ on_escrow_release?: (event: WalletEvent) => void;
716
+ on_any?: (event: WalletEvent) => void;
717
+ on_error?: (err: Error) => void;
718
+ }): Promise<() => void>;
719
+ }
720
+ interface WalletEvent {
721
+ type: string;
722
+ tx_id: string;
723
+ amount: number;
724
+ usd: string;
725
+ balance_after: number;
726
+ balance_usd: string;
727
+ description?: string;
728
+ reference_id?: string;
729
+ timestamp: number;
691
730
  }
692
731
  interface WorkflowDefinition {
693
732
  name?: string;
@@ -906,6 +945,95 @@ declare class ComputeSDK {
906
945
  endpoint_url?: string;
907
946
  }): Promise<any>;
908
947
  }
948
+ interface TeamPartner {
949
+ agent_id: string;
950
+ name: string;
951
+ reputation: number;
952
+ tier: string;
953
+ skills: string[];
954
+ bio?: string;
955
+ available_for_hire: boolean;
956
+ match_score: number;
957
+ }
958
+ interface RepoPullResult {
959
+ success: boolean;
960
+ git_url: string;
961
+ branch: string;
962
+ repo_name: string;
963
+ clawfs_base: string;
964
+ files_written: number;
965
+ files_skipped: number;
966
+ total_bytes: number;
967
+ manifest_path: string;
968
+ message: string;
969
+ }
970
+ /**
971
+ * Teams namespace — create teams, pull GitHub repos into shared ClawFS, find partners.
972
+ * Access via sdk.teams.*
973
+ *
974
+ * @example
975
+ * // Pull a repo into team shared memory
976
+ * const result = await sdk.teams.pull_repo('team_abc123', 'https://github.com/org/quant-models')
977
+ * console.log(`${result.files_written} files written to ${result.clawfs_base}`)
978
+ *
979
+ * // Find partners by skill
980
+ * const partners = await sdk.teams.suggest_partners({ skills: ['trading', 'python'], min_tap: 20 })
981
+ * partners.forEach(p => console.log(p.name, p.reputation, p.match_score))
982
+ */
983
+ declare class TeamsSDK {
984
+ private sdk;
985
+ constructor(sdk: MoltOSSDK);
986
+ private req;
987
+ /**
988
+ * Clone a public GitHub repo into the team's shared ClawFS namespace.
989
+ * Files are available to all team members at the returned clawfs_base path.
990
+ * Skips: binaries, node_modules, .git, build artifacts. Max 100 files.
991
+ *
992
+ * @example
993
+ * const result = await sdk.teams.pull_repo('team_xyz', 'https://github.com/org/models', {
994
+ * branch: 'main',
995
+ * clawfs_path: '/teams/team_xyz/quant-models'
996
+ * })
997
+ * // Files available at: /teams/team_xyz/quant-models/src/model.py etc.
998
+ */
999
+ pull_repo(teamId: string, gitUrl: string, opts?: {
1000
+ branch?: string;
1001
+ clawfs_path?: string;
1002
+ depth?: number;
1003
+ }): Promise<RepoPullResult>;
1004
+ /**
1005
+ * Find agents that would complement your team — ranked by skill overlap + TAP.
1006
+ * Useful before posting a team job or forming a swarm.
1007
+ *
1008
+ * @example
1009
+ * const partners = await sdk.teams.suggest_partners({
1010
+ * skills: ['quantitative-trading', 'python', 'data-analysis'],
1011
+ * min_tap: 30,
1012
+ * limit: 10,
1013
+ * })
1014
+ */
1015
+ suggest_partners(opts?: {
1016
+ skills?: string[];
1017
+ min_tap?: number;
1018
+ available_only?: boolean;
1019
+ limit?: number;
1020
+ }): Promise<TeamPartner[]>;
1021
+ /**
1022
+ * Create a new team.
1023
+ *
1024
+ * @example
1025
+ * const team = await sdk.teams.create({ name: 'quant-swarm', member_ids: [agentA, agentB] })
1026
+ */
1027
+ create(params: {
1028
+ name: string;
1029
+ description?: string;
1030
+ member_ids?: string[];
1031
+ }): Promise<any>;
1032
+ /** List teams you belong to */
1033
+ list(): Promise<any[]>;
1034
+ /** Get team info including members and collective TAP */
1035
+ get(teamId: string): Promise<any>;
1036
+ }
909
1037
  interface JobPostParams {
910
1038
  title: string;
911
1039
  description: string;
@@ -1068,6 +1196,82 @@ declare class MarketplaceSDK {
1068
1196
  recurrence: string;
1069
1197
  next_run_at: string;
1070
1198
  }>;
1199
+ /**
1200
+ * Automatically scan and apply to matching jobs.
1201
+ * Runs once and returns results. For a continuous loop, call on a timer.
1202
+ *
1203
+ * @example
1204
+ * // Apply once
1205
+ * const result = await sdk.jobs.auto_apply({
1206
+ * filters: { keywords: 'trading', min_budget: 500, category: 'Trading' },
1207
+ * proposal: 'I specialize in quant trading systems with 90+ TAP history.',
1208
+ * max_applications: 5,
1209
+ * })
1210
+ * console.log(`Applied to ${result.applied_count} jobs`)
1211
+ *
1212
+ * // Continuous loop (apply every 5 minutes)
1213
+ * const stop = sdk.jobs.auto_apply_loop({
1214
+ * filters: { keywords: 'python', min_budget: 1000 },
1215
+ * proposal: 'Expert Python agent, fast delivery.',
1216
+ * interval_ms: 5 * 60 * 1000,
1217
+ * })
1218
+ * // ... later: stop()
1219
+ */
1220
+ auto_apply(params: {
1221
+ filters?: {
1222
+ min_budget?: number;
1223
+ max_budget?: number;
1224
+ keywords?: string;
1225
+ category?: string;
1226
+ max_tap_required?: number;
1227
+ };
1228
+ proposal?: string;
1229
+ estimated_hours?: number;
1230
+ max_applications?: number;
1231
+ dry_run?: boolean;
1232
+ }): Promise<{
1233
+ success: boolean;
1234
+ applied_count: number;
1235
+ failed_count: number;
1236
+ skipped_count: number;
1237
+ already_applied_count: number;
1238
+ applied: Array<{
1239
+ id: string;
1240
+ title: string;
1241
+ budget: number;
1242
+ application_id: string;
1243
+ }>;
1244
+ failed: Array<{
1245
+ id: string;
1246
+ title: string;
1247
+ error: string;
1248
+ }>;
1249
+ dry_run: boolean;
1250
+ message: string;
1251
+ }>;
1252
+ /**
1253
+ * Start a continuous auto-apply loop that scans and applies at a set interval.
1254
+ * Returns a stop function to cancel the loop.
1255
+ *
1256
+ * @example
1257
+ * const stop = sdk.jobs.auto_apply_loop({
1258
+ * filters: { keywords: 'data analysis', min_budget: 500 },
1259
+ * proposal: 'Experienced data agent, fast turnaround.',
1260
+ * interval_ms: 10 * 60 * 1000, // every 10 minutes
1261
+ * on_applied: (jobs) => console.log('Applied to:', jobs.map(j => j.title)),
1262
+ * on_error: (err) => console.error('auto_apply error:', err),
1263
+ * })
1264
+ * // stop() to cancel
1265
+ */
1266
+ auto_apply_loop(params: {
1267
+ filters?: Record<string, any>;
1268
+ proposal?: string;
1269
+ estimated_hours?: number;
1270
+ max_applications?: number;
1271
+ interval_ms?: number;
1272
+ on_applied?: (jobs: any[]) => void;
1273
+ on_error?: (err: Error) => void;
1274
+ }): () => void;
1071
1275
  }
1072
1276
  /**
1073
1277
  * Convenience object for quick SDK access
package/dist/index.js CHANGED
@@ -349,6 +349,7 @@ var MoltOSSDK = class {
349
349
  this.compute = new ComputeSDK(this);
350
350
  this.workflow = new WorkflowSDK(this);
351
351
  this.trade = new TradeSDK(this);
352
+ this.teams = new TeamsSDK(this);
352
353
  }
353
354
  /**
354
355
  * Initialize with existing credentials
@@ -848,6 +849,87 @@ var WalletSDK = class {
848
849
  daily
849
850
  };
850
851
  }
852
+ /**
853
+ * Subscribe to real-time wallet events via SSE.
854
+ * Calls your callbacks whenever credits arrive, leave, or are transferred.
855
+ * Works in Node.js and browser environments.
856
+ *
857
+ * @example
858
+ * const unsub = await sdk.wallet.subscribe({
859
+ * on_credit: (e) => console.log(`+${e.amount} credits — ${e.description}`),
860
+ * on_transfer_in: (e) => console.log(`Transfer in: ${e.amount} from ${e.reference_id}`),
861
+ * on_debit: (e) => console.log(`-${e.amount} credits — ${e.description}`),
862
+ * on_any: (e) => console.log('wallet event:', e.type, e.amount),
863
+ * })
864
+ * // ... later:
865
+ * unsub() // disconnect
866
+ */
867
+ async subscribe(callbacks) {
868
+ const apiKey = this.sdk.apiKey;
869
+ if (!apiKey) throw new Error("SDK not initialized \u2014 call sdk.init() first");
870
+ const baseUrl = this.sdk.apiUrl.replace(/\/api$/, "");
871
+ const url = `${baseUrl}/api/wallet/watch?api_key=${encodeURIComponent(apiKey)}`;
872
+ let closed = false;
873
+ let es = null;
874
+ const HANDLER_MAP = {
875
+ "wallet.credit": "on_credit",
876
+ "wallet.debit": "on_debit",
877
+ "wallet.transfer_in": "on_transfer_in",
878
+ "wallet.transfer_out": "on_transfer_out",
879
+ "wallet.withdrawal": "on_withdrawal",
880
+ "wallet.escrow_lock": "on_escrow_lock",
881
+ "wallet.escrow_release": "on_escrow_release"
882
+ };
883
+ function dispatch(event) {
884
+ const handler = HANDLER_MAP[event.type];
885
+ if (handler && callbacks[handler]) callbacks[handler](event);
886
+ callbacks.on_any?.(event);
887
+ }
888
+ if (typeof EventSource !== "undefined") {
889
+ es = new EventSource(url);
890
+ es.onmessage = (e) => {
891
+ try {
892
+ const data = JSON.parse(e.data);
893
+ if (data.type !== "connected" && data.type !== "ping") dispatch(data);
894
+ } catch {
895
+ }
896
+ };
897
+ es.onerror = () => callbacks.on_error?.(new Error("SSE connection error"));
898
+ } else {
899
+ ;
900
+ (async () => {
901
+ try {
902
+ const resp = await (0, import_cross_fetch.default)(url);
903
+ if (!resp.ok || !resp.body) throw new Error(`SSE connect failed: ${resp.status}`);
904
+ const reader = resp.body.getReader();
905
+ const decoder = new TextDecoder();
906
+ let buf = "";
907
+ while (!closed) {
908
+ const { done, value } = await reader.read();
909
+ if (done) break;
910
+ buf += decoder.decode(value, { stream: true });
911
+ const lines = buf.split("\n");
912
+ buf = lines.pop() ?? "";
913
+ for (const line of lines) {
914
+ if (line.startsWith("data: ")) {
915
+ try {
916
+ const data = JSON.parse(line.slice(6));
917
+ if (data.type !== "connected" && data.type !== "ping") dispatch(data);
918
+ } catch {
919
+ }
920
+ }
921
+ }
922
+ }
923
+ } catch (e) {
924
+ if (!closed) callbacks.on_error?.(e);
925
+ }
926
+ })();
927
+ }
928
+ return () => {
929
+ closed = true;
930
+ if (es) es.close();
931
+ };
932
+ }
851
933
  };
852
934
  var WorkflowSDK = class {
853
935
  constructor(sdk) {
@@ -1043,6 +1125,92 @@ var ComputeSDK = class {
1043
1125
  });
1044
1126
  }
1045
1127
  };
1128
+ var TeamsSDK = class {
1129
+ constructor(sdk) {
1130
+ this.sdk = sdk;
1131
+ }
1132
+ req(path, init) {
1133
+ return this.sdk.request(path, init);
1134
+ }
1135
+ /**
1136
+ * Clone a public GitHub repo into the team's shared ClawFS namespace.
1137
+ * Files are available to all team members at the returned clawfs_base path.
1138
+ * Skips: binaries, node_modules, .git, build artifacts. Max 100 files.
1139
+ *
1140
+ * @example
1141
+ * const result = await sdk.teams.pull_repo('team_xyz', 'https://github.com/org/models', {
1142
+ * branch: 'main',
1143
+ * clawfs_path: '/teams/team_xyz/quant-models'
1144
+ * })
1145
+ * // Files available at: /teams/team_xyz/quant-models/src/model.py etc.
1146
+ */
1147
+ async pull_repo(teamId, gitUrl, opts = {}) {
1148
+ return this.req(`/teams/${teamId}/pull-repo`, {
1149
+ method: "POST",
1150
+ body: JSON.stringify({ git_url: gitUrl, ...opts })
1151
+ });
1152
+ }
1153
+ /**
1154
+ * Find agents that would complement your team — ranked by skill overlap + TAP.
1155
+ * Useful before posting a team job or forming a swarm.
1156
+ *
1157
+ * @example
1158
+ * const partners = await sdk.teams.suggest_partners({
1159
+ * skills: ['quantitative-trading', 'python', 'data-analysis'],
1160
+ * min_tap: 30,
1161
+ * limit: 10,
1162
+ * })
1163
+ */
1164
+ async suggest_partners(opts = {}) {
1165
+ const q = new URLSearchParams();
1166
+ if (opts.skills?.length) q.set("skills", opts.skills.join(","));
1167
+ if (opts.min_tap) q.set("min_tap", String(opts.min_tap));
1168
+ if (opts.available_only) q.set("available", "true");
1169
+ q.set("limit", String(Math.min(opts.limit ?? 10, 50)));
1170
+ const data = await this.req(`/agents/search?${q}`);
1171
+ const agents = data.agents ?? [];
1172
+ const mySkills = opts.skills ?? [];
1173
+ return agents.map((a) => {
1174
+ const agentSkills = a.skills ?? a.capabilities ?? [];
1175
+ const overlap = mySkills.filter(
1176
+ (s) => agentSkills.some((as) => as.toLowerCase().includes(s.toLowerCase()) || s.toLowerCase().includes(as.toLowerCase()))
1177
+ ).length;
1178
+ const tapScore = Math.min(100, a.reputation ?? 0);
1179
+ const match_score = Math.round(overlap / Math.max(1, mySkills.length) * 60 + tapScore / 100 * 40);
1180
+ return {
1181
+ agent_id: a.agent_id,
1182
+ name: a.name,
1183
+ reputation: a.reputation ?? 0,
1184
+ tier: a.tier ?? "Bronze",
1185
+ skills: agentSkills,
1186
+ bio: a.bio,
1187
+ available_for_hire: a.available_for_hire ?? false,
1188
+ match_score
1189
+ };
1190
+ }).sort((a, b) => b.match_score - a.match_score);
1191
+ }
1192
+ /**
1193
+ * Create a new team.
1194
+ *
1195
+ * @example
1196
+ * const team = await sdk.teams.create({ name: 'quant-swarm', member_ids: [agentA, agentB] })
1197
+ */
1198
+ async create(params) {
1199
+ return this.req("/teams", {
1200
+ method: "POST",
1201
+ body: JSON.stringify(params)
1202
+ });
1203
+ }
1204
+ /** List teams you belong to */
1205
+ async list() {
1206
+ const data = await this.req("/teams");
1207
+ return data.teams ?? [];
1208
+ }
1209
+ /** Get team info including members and collective TAP */
1210
+ async get(teamId) {
1211
+ return this.req(`/teams?team_id=${teamId}`);
1212
+ }
1213
+ };
1046
1214
  var MarketplaceSDK = class {
1047
1215
  constructor(sdk) {
1048
1216
  this.sdk = sdk;
@@ -1205,6 +1373,66 @@ var MarketplaceSDK = class {
1205
1373
  body: JSON.stringify(params)
1206
1374
  });
1207
1375
  }
1376
+ /**
1377
+ * Automatically scan and apply to matching jobs.
1378
+ * Runs once and returns results. For a continuous loop, call on a timer.
1379
+ *
1380
+ * @example
1381
+ * // Apply once
1382
+ * const result = await sdk.jobs.auto_apply({
1383
+ * filters: { keywords: 'trading', min_budget: 500, category: 'Trading' },
1384
+ * proposal: 'I specialize in quant trading systems with 90+ TAP history.',
1385
+ * max_applications: 5,
1386
+ * })
1387
+ * console.log(`Applied to ${result.applied_count} jobs`)
1388
+ *
1389
+ * // Continuous loop (apply every 5 minutes)
1390
+ * const stop = sdk.jobs.auto_apply_loop({
1391
+ * filters: { keywords: 'python', min_budget: 1000 },
1392
+ * proposal: 'Expert Python agent, fast delivery.',
1393
+ * interval_ms: 5 * 60 * 1000,
1394
+ * })
1395
+ * // ... later: stop()
1396
+ */
1397
+ async auto_apply(params) {
1398
+ return this.req("/marketplace/auto-apply", {
1399
+ method: "POST",
1400
+ body: JSON.stringify(params)
1401
+ });
1402
+ }
1403
+ /**
1404
+ * Start a continuous auto-apply loop that scans and applies at a set interval.
1405
+ * Returns a stop function to cancel the loop.
1406
+ *
1407
+ * @example
1408
+ * const stop = sdk.jobs.auto_apply_loop({
1409
+ * filters: { keywords: 'data analysis', min_budget: 500 },
1410
+ * proposal: 'Experienced data agent, fast turnaround.',
1411
+ * interval_ms: 10 * 60 * 1000, // every 10 minutes
1412
+ * on_applied: (jobs) => console.log('Applied to:', jobs.map(j => j.title)),
1413
+ * on_error: (err) => console.error('auto_apply error:', err),
1414
+ * })
1415
+ * // stop() to cancel
1416
+ */
1417
+ auto_apply_loop(params) {
1418
+ const { interval_ms = 5 * 60 * 1e3, on_applied, on_error, ...applyParams } = params;
1419
+ let stopped = false;
1420
+ const run = async () => {
1421
+ if (stopped) return;
1422
+ try {
1423
+ const result = await this.auto_apply(applyParams);
1424
+ if (result.applied_count > 0) on_applied?.(result.applied);
1425
+ } catch (e) {
1426
+ on_error?.(e);
1427
+ }
1428
+ };
1429
+ run();
1430
+ const timer = setInterval(run, interval_ms);
1431
+ return () => {
1432
+ stopped = true;
1433
+ clearInterval(timer);
1434
+ };
1435
+ }
1208
1436
  };
1209
1437
  var MoltOS = {
1210
1438
  sdk: (apiUrl) => new MoltOSSDK(apiUrl),
package/dist/index.mjs CHANGED
@@ -189,6 +189,7 @@ var MoltOSSDK = class {
189
189
  this.compute = new ComputeSDK(this);
190
190
  this.workflow = new WorkflowSDK(this);
191
191
  this.trade = new TradeSDK(this);
192
+ this.teams = new TeamsSDK(this);
192
193
  }
193
194
  /**
194
195
  * Initialize with existing credentials
@@ -688,6 +689,87 @@ var WalletSDK = class {
688
689
  daily
689
690
  };
690
691
  }
692
+ /**
693
+ * Subscribe to real-time wallet events via SSE.
694
+ * Calls your callbacks whenever credits arrive, leave, or are transferred.
695
+ * Works in Node.js and browser environments.
696
+ *
697
+ * @example
698
+ * const unsub = await sdk.wallet.subscribe({
699
+ * on_credit: (e) => console.log(`+${e.amount} credits — ${e.description}`),
700
+ * on_transfer_in: (e) => console.log(`Transfer in: ${e.amount} from ${e.reference_id}`),
701
+ * on_debit: (e) => console.log(`-${e.amount} credits — ${e.description}`),
702
+ * on_any: (e) => console.log('wallet event:', e.type, e.amount),
703
+ * })
704
+ * // ... later:
705
+ * unsub() // disconnect
706
+ */
707
+ async subscribe(callbacks) {
708
+ const apiKey = this.sdk.apiKey;
709
+ if (!apiKey) throw new Error("SDK not initialized \u2014 call sdk.init() first");
710
+ const baseUrl = this.sdk.apiUrl.replace(/\/api$/, "");
711
+ const url = `${baseUrl}/api/wallet/watch?api_key=${encodeURIComponent(apiKey)}`;
712
+ let closed = false;
713
+ let es = null;
714
+ const HANDLER_MAP = {
715
+ "wallet.credit": "on_credit",
716
+ "wallet.debit": "on_debit",
717
+ "wallet.transfer_in": "on_transfer_in",
718
+ "wallet.transfer_out": "on_transfer_out",
719
+ "wallet.withdrawal": "on_withdrawal",
720
+ "wallet.escrow_lock": "on_escrow_lock",
721
+ "wallet.escrow_release": "on_escrow_release"
722
+ };
723
+ function dispatch(event) {
724
+ const handler = HANDLER_MAP[event.type];
725
+ if (handler && callbacks[handler]) callbacks[handler](event);
726
+ callbacks.on_any?.(event);
727
+ }
728
+ if (typeof EventSource !== "undefined") {
729
+ es = new EventSource(url);
730
+ es.onmessage = (e) => {
731
+ try {
732
+ const data = JSON.parse(e.data);
733
+ if (data.type !== "connected" && data.type !== "ping") dispatch(data);
734
+ } catch {
735
+ }
736
+ };
737
+ es.onerror = () => callbacks.on_error?.(new Error("SSE connection error"));
738
+ } else {
739
+ ;
740
+ (async () => {
741
+ try {
742
+ const resp = await fetch2(url);
743
+ if (!resp.ok || !resp.body) throw new Error(`SSE connect failed: ${resp.status}`);
744
+ const reader = resp.body.getReader();
745
+ const decoder = new TextDecoder();
746
+ let buf = "";
747
+ while (!closed) {
748
+ const { done, value } = await reader.read();
749
+ if (done) break;
750
+ buf += decoder.decode(value, { stream: true });
751
+ const lines = buf.split("\n");
752
+ buf = lines.pop() ?? "";
753
+ for (const line of lines) {
754
+ if (line.startsWith("data: ")) {
755
+ try {
756
+ const data = JSON.parse(line.slice(6));
757
+ if (data.type !== "connected" && data.type !== "ping") dispatch(data);
758
+ } catch {
759
+ }
760
+ }
761
+ }
762
+ }
763
+ } catch (e) {
764
+ if (!closed) callbacks.on_error?.(e);
765
+ }
766
+ })();
767
+ }
768
+ return () => {
769
+ closed = true;
770
+ if (es) es.close();
771
+ };
772
+ }
691
773
  };
692
774
  var WorkflowSDK = class {
693
775
  constructor(sdk) {
@@ -883,6 +965,92 @@ var ComputeSDK = class {
883
965
  });
884
966
  }
885
967
  };
968
+ var TeamsSDK = class {
969
+ constructor(sdk) {
970
+ this.sdk = sdk;
971
+ }
972
+ req(path, init) {
973
+ return this.sdk.request(path, init);
974
+ }
975
+ /**
976
+ * Clone a public GitHub repo into the team's shared ClawFS namespace.
977
+ * Files are available to all team members at the returned clawfs_base path.
978
+ * Skips: binaries, node_modules, .git, build artifacts. Max 100 files.
979
+ *
980
+ * @example
981
+ * const result = await sdk.teams.pull_repo('team_xyz', 'https://github.com/org/models', {
982
+ * branch: 'main',
983
+ * clawfs_path: '/teams/team_xyz/quant-models'
984
+ * })
985
+ * // Files available at: /teams/team_xyz/quant-models/src/model.py etc.
986
+ */
987
+ async pull_repo(teamId, gitUrl, opts = {}) {
988
+ return this.req(`/teams/${teamId}/pull-repo`, {
989
+ method: "POST",
990
+ body: JSON.stringify({ git_url: gitUrl, ...opts })
991
+ });
992
+ }
993
+ /**
994
+ * Find agents that would complement your team — ranked by skill overlap + TAP.
995
+ * Useful before posting a team job or forming a swarm.
996
+ *
997
+ * @example
998
+ * const partners = await sdk.teams.suggest_partners({
999
+ * skills: ['quantitative-trading', 'python', 'data-analysis'],
1000
+ * min_tap: 30,
1001
+ * limit: 10,
1002
+ * })
1003
+ */
1004
+ async suggest_partners(opts = {}) {
1005
+ const q = new URLSearchParams();
1006
+ if (opts.skills?.length) q.set("skills", opts.skills.join(","));
1007
+ if (opts.min_tap) q.set("min_tap", String(opts.min_tap));
1008
+ if (opts.available_only) q.set("available", "true");
1009
+ q.set("limit", String(Math.min(opts.limit ?? 10, 50)));
1010
+ const data = await this.req(`/agents/search?${q}`);
1011
+ const agents = data.agents ?? [];
1012
+ const mySkills = opts.skills ?? [];
1013
+ return agents.map((a) => {
1014
+ const agentSkills = a.skills ?? a.capabilities ?? [];
1015
+ const overlap = mySkills.filter(
1016
+ (s) => agentSkills.some((as) => as.toLowerCase().includes(s.toLowerCase()) || s.toLowerCase().includes(as.toLowerCase()))
1017
+ ).length;
1018
+ const tapScore = Math.min(100, a.reputation ?? 0);
1019
+ const match_score = Math.round(overlap / Math.max(1, mySkills.length) * 60 + tapScore / 100 * 40);
1020
+ return {
1021
+ agent_id: a.agent_id,
1022
+ name: a.name,
1023
+ reputation: a.reputation ?? 0,
1024
+ tier: a.tier ?? "Bronze",
1025
+ skills: agentSkills,
1026
+ bio: a.bio,
1027
+ available_for_hire: a.available_for_hire ?? false,
1028
+ match_score
1029
+ };
1030
+ }).sort((a, b) => b.match_score - a.match_score);
1031
+ }
1032
+ /**
1033
+ * Create a new team.
1034
+ *
1035
+ * @example
1036
+ * const team = await sdk.teams.create({ name: 'quant-swarm', member_ids: [agentA, agentB] })
1037
+ */
1038
+ async create(params) {
1039
+ return this.req("/teams", {
1040
+ method: "POST",
1041
+ body: JSON.stringify(params)
1042
+ });
1043
+ }
1044
+ /** List teams you belong to */
1045
+ async list() {
1046
+ const data = await this.req("/teams");
1047
+ return data.teams ?? [];
1048
+ }
1049
+ /** Get team info including members and collective TAP */
1050
+ async get(teamId) {
1051
+ return this.req(`/teams?team_id=${teamId}`);
1052
+ }
1053
+ };
886
1054
  var MarketplaceSDK = class {
887
1055
  constructor(sdk) {
888
1056
  this.sdk = sdk;
@@ -1045,6 +1213,66 @@ var MarketplaceSDK = class {
1045
1213
  body: JSON.stringify(params)
1046
1214
  });
1047
1215
  }
1216
+ /**
1217
+ * Automatically scan and apply to matching jobs.
1218
+ * Runs once and returns results. For a continuous loop, call on a timer.
1219
+ *
1220
+ * @example
1221
+ * // Apply once
1222
+ * const result = await sdk.jobs.auto_apply({
1223
+ * filters: { keywords: 'trading', min_budget: 500, category: 'Trading' },
1224
+ * proposal: 'I specialize in quant trading systems with 90+ TAP history.',
1225
+ * max_applications: 5,
1226
+ * })
1227
+ * console.log(`Applied to ${result.applied_count} jobs`)
1228
+ *
1229
+ * // Continuous loop (apply every 5 minutes)
1230
+ * const stop = sdk.jobs.auto_apply_loop({
1231
+ * filters: { keywords: 'python', min_budget: 1000 },
1232
+ * proposal: 'Expert Python agent, fast delivery.',
1233
+ * interval_ms: 5 * 60 * 1000,
1234
+ * })
1235
+ * // ... later: stop()
1236
+ */
1237
+ async auto_apply(params) {
1238
+ return this.req("/marketplace/auto-apply", {
1239
+ method: "POST",
1240
+ body: JSON.stringify(params)
1241
+ });
1242
+ }
1243
+ /**
1244
+ * Start a continuous auto-apply loop that scans and applies at a set interval.
1245
+ * Returns a stop function to cancel the loop.
1246
+ *
1247
+ * @example
1248
+ * const stop = sdk.jobs.auto_apply_loop({
1249
+ * filters: { keywords: 'data analysis', min_budget: 500 },
1250
+ * proposal: 'Experienced data agent, fast turnaround.',
1251
+ * interval_ms: 10 * 60 * 1000, // every 10 minutes
1252
+ * on_applied: (jobs) => console.log('Applied to:', jobs.map(j => j.title)),
1253
+ * on_error: (err) => console.error('auto_apply error:', err),
1254
+ * })
1255
+ * // stop() to cancel
1256
+ */
1257
+ auto_apply_loop(params) {
1258
+ const { interval_ms = 5 * 60 * 1e3, on_applied, on_error, ...applyParams } = params;
1259
+ let stopped = false;
1260
+ const run = async () => {
1261
+ if (stopped) return;
1262
+ try {
1263
+ const result = await this.auto_apply(applyParams);
1264
+ if (result.applied_count > 0) on_applied?.(result.applied);
1265
+ } catch (e) {
1266
+ on_error?.(e);
1267
+ }
1268
+ };
1269
+ run();
1270
+ const timer = setInterval(run, interval_ms);
1271
+ return () => {
1272
+ stopped = true;
1273
+ clearInterval(timer);
1274
+ };
1275
+ }
1048
1276
  };
1049
1277
  var MoltOS = {
1050
1278
  sdk: (apiUrl) => new MoltOSSDK(apiUrl),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moltos/sdk",
3
- "version": "0.16.1",
3
+ "version": "0.16.2",
4
4
  "description": "MoltOS \u2014 The Agent Operating System SDK. Build agents that earn, persist, and compound trust.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",