trakt-tools 1.6.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
  "id": "trakt-tools",
3
3
  "name": "Trakt",
4
4
  "description": "Track movies and TV shows using trakt.tv",
5
- "version": "1.6.1",
5
+ "version": "1.8.0",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "properties": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trakt-tools",
3
- "version": "1.6.1",
3
+ "version": "1.8.0",
4
4
  "description": "OpenClaw plugin for Trakt.tv - track movies and TV shows",
5
5
  "type": "module",
6
6
  "openclaw": {
package/src/index.ts CHANGED
@@ -81,6 +81,24 @@ const TOOLS: ToolDef[] = [
81
81
  ),
82
82
  }),
83
83
  },
84
+ {
85
+ name: 'trakt_history_remove',
86
+ command: 'history',
87
+ subcommand: 'remove',
88
+ description:
89
+ 'Remove movies or shows from Trakt.tv watch history (undo a mark-as-watched). Searches by title; removing a show wipes ALL its episode plays, removing a movie wipes all its watches. There is no per-watch granular removal.',
90
+ parameters: Type.Object({
91
+ titles: Type.Array(Type.String(), {
92
+ description: 'Title(s) to remove from history',
93
+ minItems: 1,
94
+ }),
95
+ type: Type.Optional(
96
+ Type.Union([Type.Literal('movie'), Type.Literal('show')], {
97
+ description: 'Content type (default: show)',
98
+ })
99
+ ),
100
+ }),
101
+ },
84
102
  {
85
103
  name: 'trakt_watchlist',
86
104
  command: 'watchlist',
@@ -96,6 +114,61 @@ const TOOLS: ToolDef[] = [
96
114
  page: Type.Optional(Type.Number({ description: 'Page number' })),
97
115
  }),
98
116
  },
117
+ {
118
+ name: 'trakt_watchlist_add',
119
+ command: 'watchlist',
120
+ subcommand: 'add',
121
+ description:
122
+ 'Add movies or shows to the Trakt.tv watchlist. Searches by title and queues matches in one sync call. Accepts multiple titles. Items already on the list are reported under `existing_*` counts.',
123
+ parameters: Type.Object({
124
+ titles: Type.Array(Type.String(), {
125
+ description: 'Title(s) to add to the watchlist',
126
+ minItems: 1,
127
+ }),
128
+ type: Type.Optional(
129
+ Type.Union([Type.Literal('movie'), Type.Literal('show')], {
130
+ description: 'Content type (default: show)',
131
+ })
132
+ ),
133
+ }),
134
+ },
135
+ {
136
+ name: 'trakt_watchlist_remove',
137
+ command: 'watchlist',
138
+ subcommand: 'remove',
139
+ description:
140
+ 'Remove movies or shows from the Trakt.tv watchlist. Searches by title and removes matches in one sync call. Accepts multiple titles. Items that were not on the list are silent no-ops (deleted_*=0).',
141
+ parameters: Type.Object({
142
+ titles: Type.Array(Type.String(), {
143
+ description: 'Title(s) to remove from the watchlist',
144
+ minItems: 1,
145
+ }),
146
+ type: Type.Optional(
147
+ Type.Union([Type.Literal('movie'), Type.Literal('show')], {
148
+ description: 'Content type (default: show)',
149
+ })
150
+ ),
151
+ }),
152
+ },
153
+ {
154
+ name: 'trakt_calendar',
155
+ command: 'calendar',
156
+ description:
157
+ 'Show upcoming episodes of shows you watch. Returns forward-looking airings within a date window. Use for proactive "what airs next?" workflows — this is the only trakt tool that returns future data.',
158
+ parameters: Type.Object({
159
+ days: Type.Optional(
160
+ Type.Number({ description: 'Number of days to look ahead (default 7)' })
161
+ ),
162
+ start: Type.Optional(
163
+ Type.String({ description: 'Start date YYYY-MM-DD (defaults to today)' })
164
+ ),
165
+ new: Type.Optional(
166
+ Type.Boolean({
167
+ description: 'Only return series premieres (S01E01 airings)',
168
+ })
169
+ ),
170
+ }),
171
+ },
99
172
  {
100
173
  name: 'trakt_progress',
101
174
  command: 'progress',
@@ -208,6 +281,26 @@ function buildCliArgs(
208
281
  }
209
282
  }
210
283
 
284
+ // Title-array commands (watchlist add/remove, history remove) all share
285
+ // the same shape: search by title, POST the matches. Only `history add`
286
+ // needs special handling for --watched-at.
287
+ const titleArrayCommands: Array<[string, string]> = [
288
+ ['watchlist', 'add'],
289
+ ['watchlist', 'remove'],
290
+ ['history', 'remove'],
291
+ ];
292
+ if (titleArrayCommands.some(([c, s]) => c === command && s === subcommand)) {
293
+ const titles = params.titles as string[] | undefined;
294
+ if (titles) {
295
+ if (params.type) args.push('--type', String(params.type));
296
+ for (const title of titles) {
297
+ args.push(title);
298
+ }
299
+ args.push('--json');
300
+ return args;
301
+ }
302
+ }
303
+
211
304
  const skipKeys = new Set(['query', 'titles']);
212
305
  for (const [key, value] of Object.entries(params)) {
213
306
  if (skipKeys.has(key) || value === undefined || value === null || value === false) continue;