democut 0.6.15 → 0.6.19

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.
Files changed (2) hide show
  1. package/dist/cli.js +452 -22
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -6916,7 +6916,7 @@ import { realpathSync } from "fs";
6916
6916
  import { fileURLToPath } from "url";
6917
6917
 
6918
6918
  // src/version.ts
6919
- var VERSION = "0.6.15";
6919
+ var VERSION = "0.6.19";
6920
6920
 
6921
6921
  // src/device-flow.ts
6922
6922
  var DeviceFlowError = class extends Error {
@@ -16295,6 +16295,21 @@ var GENERATED_TOOLS = [
16295
16295
  "title": "Image Prompt",
16296
16296
  "type": "string"
16297
16297
  },
16298
+ "provider": {
16299
+ "anyOf": [
16300
+ {
16301
+ "maxLength": 32,
16302
+ "minLength": 1,
16303
+ "type": "string"
16304
+ },
16305
+ {
16306
+ "type": "null"
16307
+ }
16308
+ ],
16309
+ "default": null,
16310
+ "description": "\uC601\uC0C1 \uC0DD\uC131 \uACF5\uAE09\uC790(\uC608: minimax). \uBE44\uC6B0\uBA74 \uC11C\uBC84 \uAE30\uBCF8\uAC12 \u2014 \uC4F8 \uC218 \uC788\uB294 \uBAA9\uB85D\uC740 GET \u2026/options \uC758 videogen_providers",
16311
+ "title": "Provider"
16312
+ },
16298
16313
  "seed": {
16299
16314
  "anyOf": [
16300
16315
  {
@@ -17129,6 +17144,21 @@ var GENERATED_TOOLS = [
17129
17144
  "title": "Image Prompt",
17130
17145
  "type": "string"
17131
17146
  },
17147
+ "provider": {
17148
+ "anyOf": [
17149
+ {
17150
+ "maxLength": 32,
17151
+ "minLength": 1,
17152
+ "type": "string"
17153
+ },
17154
+ {
17155
+ "type": "null"
17156
+ }
17157
+ ],
17158
+ "default": null,
17159
+ "description": "\uC601\uC0C1 \uC0DD\uC131 \uACF5\uAE09\uC790(\uC608: minimax). \uBE44\uC6B0\uBA74 \uC11C\uBC84 \uAE30\uBCF8\uAC12 \u2014 \uC4F8 \uC218 \uC788\uB294 \uBAA9\uB85D\uC740 GET \u2026/options \uC758 videogen_providers",
17160
+ "title": "Provider"
17161
+ },
17132
17162
  "seed": {
17133
17163
  "anyOf": [
17134
17164
  {
@@ -18136,6 +18166,251 @@ var GENERATED_TOOLS = [
18136
18166
  "idempotentHint": true,
18137
18167
  "openWorldHint": false
18138
18168
  }
18169
+ },
18170
+ {
18171
+ "name": "democut_list_characters",
18172
+ "description": "\uC544\uBC14\uD0C0 \uBAA9\uB85D.",
18173
+ "inputSchema": {
18174
+ "type": "object",
18175
+ "properties": {},
18176
+ "required": [],
18177
+ "additionalProperties": false
18178
+ },
18179
+ "annotations": {
18180
+ "readOnlyHint": true,
18181
+ "destructiveHint": false,
18182
+ "idempotentHint": true,
18183
+ "openWorldHint": false
18184
+ }
18185
+ },
18186
+ {
18187
+ "name": "democut_create_character",
18188
+ "description": "\uC544\uBC14\uD0C0\uB97C \uB9CC\uB4E0\uB2E4(0\uC6D0).",
18189
+ "inputSchema": {
18190
+ "type": "object",
18191
+ "properties": {
18192
+ "name": {
18193
+ "maxLength": 100,
18194
+ "minLength": 1,
18195
+ "title": "Name",
18196
+ "type": "string"
18197
+ },
18198
+ "role": {
18199
+ "default": "",
18200
+ "title": "Role",
18201
+ "type": "string"
18202
+ },
18203
+ "voice_id": {
18204
+ "anyOf": [
18205
+ {
18206
+ "type": "string"
18207
+ },
18208
+ {
18209
+ "type": "null"
18210
+ }
18211
+ ],
18212
+ "default": null,
18213
+ "title": "Voice Id"
18214
+ },
18215
+ "persona_text": {
18216
+ "default": "",
18217
+ "title": "Persona Text",
18218
+ "type": "string"
18219
+ },
18220
+ "look_text": {
18221
+ "default": "",
18222
+ "title": "Look Text",
18223
+ "type": "string"
18224
+ }
18225
+ },
18226
+ "required": [
18227
+ "name"
18228
+ ],
18229
+ "additionalProperties": false
18230
+ },
18231
+ "annotations": {
18232
+ "readOnlyHint": false,
18233
+ "destructiveHint": false,
18234
+ "idempotentHint": false,
18235
+ "openWorldHint": false
18236
+ }
18237
+ },
18238
+ {
18239
+ "name": "democut_get_character",
18240
+ "description": "\uC544\uBC14\uD0C0 \uD558\uB098(\uC0AC\uC9C4 \uD310).",
18241
+ "inputSchema": {
18242
+ "type": "object",
18243
+ "properties": {
18244
+ "character_id": {
18245
+ "type": "string",
18246
+ "description": "\uC544\uBC14\uD0C0 id(chr_\u2026)"
18247
+ }
18248
+ },
18249
+ "required": [
18250
+ "character_id"
18251
+ ],
18252
+ "additionalProperties": false
18253
+ },
18254
+ "annotations": {
18255
+ "readOnlyHint": true,
18256
+ "destructiveHint": false,
18257
+ "idempotentHint": true,
18258
+ "openWorldHint": false
18259
+ }
18260
+ },
18261
+ {
18262
+ "name": "democut_put_character",
18263
+ "description": "\uC544\uBC14\uD0C0\uB97C \uC804\uCCB4 \uAD50\uCCB4\uD55C\uB2E4(If-Match rev). democut_get_character \uC758 rev \uB97C \uADF8\uB300\uB85C \uB123\uC5B4\uB77C \u2014 \uADF8 \uC0AC\uC774 \uB204\uAC00 \uBC14\uAFE8\uC73C\uBA74 409 \uC774\uACE0 \uBCD1\uD569\uD558\uC9C0 \uC54A\uB294\uB2E4.",
18264
+ "inputSchema": {
18265
+ "type": "object",
18266
+ "properties": {
18267
+ "character_id": {
18268
+ "type": "string",
18269
+ "description": "\uC544\uBC14\uD0C0 id(chr_\u2026)"
18270
+ },
18271
+ "name": {
18272
+ "maxLength": 100,
18273
+ "minLength": 1,
18274
+ "title": "Name",
18275
+ "type": "string"
18276
+ },
18277
+ "role": {
18278
+ "default": "",
18279
+ "title": "Role",
18280
+ "type": "string"
18281
+ },
18282
+ "voice_id": {
18283
+ "anyOf": [
18284
+ {
18285
+ "type": "string"
18286
+ },
18287
+ {
18288
+ "type": "null"
18289
+ }
18290
+ ],
18291
+ "default": null,
18292
+ "title": "Voice Id"
18293
+ },
18294
+ "persona_text": {
18295
+ "default": "",
18296
+ "title": "Persona Text",
18297
+ "type": "string"
18298
+ },
18299
+ "look_text": {
18300
+ "default": "",
18301
+ "title": "Look Text",
18302
+ "type": "string"
18303
+ },
18304
+ "rev": {
18305
+ "type": "integer",
18306
+ "minimum": 0,
18307
+ "description": "\uD604\uC7AC rev(get_character \uC758 \uAC12 \uADF8\uB300\uB85C). \uADF8 \uC0AC\uC774 \uBC14\uB00C\uC5C8\uC73C\uBA74 409 REV_MISMATCH"
18308
+ }
18309
+ },
18310
+ "required": [
18311
+ "character_id",
18312
+ "name",
18313
+ "rev"
18314
+ ],
18315
+ "additionalProperties": false
18316
+ },
18317
+ "annotations": {
18318
+ "readOnlyHint": false,
18319
+ "destructiveHint": false,
18320
+ "idempotentHint": true,
18321
+ "openWorldHint": false
18322
+ }
18323
+ },
18324
+ {
18325
+ "name": "democut_delete_character",
18326
+ "description": "\uC544\uBC14\uD0C0\uB97C \uC9C0\uC6B4\uB2E4.",
18327
+ "inputSchema": {
18328
+ "type": "object",
18329
+ "properties": {
18330
+ "character_id": {
18331
+ "type": "string",
18332
+ "description": "\uC544\uBC14\uD0C0 id(chr_\u2026)"
18333
+ }
18334
+ },
18335
+ "required": [
18336
+ "character_id"
18337
+ ],
18338
+ "additionalProperties": false
18339
+ },
18340
+ "annotations": {
18341
+ "readOnlyHint": false,
18342
+ "destructiveHint": true,
18343
+ "idempotentHint": true,
18344
+ "openWorldHint": false
18345
+ }
18346
+ },
18347
+ {
18348
+ "name": "democut_add_character_photo",
18349
+ "description": "\uC62C\uB9B0 \uC774\uBBF8\uC9C0\uB97C \uC0AC\uC9C4 \uD310\uC73C\uB85C \uCD94\uAC00\uD55C\uB2E4(0\uC6D0). \uC18C\uAE09 \uC5C6\uC74C.",
18350
+ "inputSchema": {
18351
+ "type": "object",
18352
+ "properties": {
18353
+ "character_id": {
18354
+ "type": "string",
18355
+ "description": "\uC544\uBC14\uD0C0 id(chr_\u2026)"
18356
+ },
18357
+ "asset_id": {
18358
+ "title": "Asset Id",
18359
+ "type": "string"
18360
+ },
18361
+ "note": {
18362
+ "anyOf": [
18363
+ {
18364
+ "type": "string"
18365
+ },
18366
+ {
18367
+ "type": "null"
18368
+ }
18369
+ ],
18370
+ "default": null,
18371
+ "title": "Note"
18372
+ }
18373
+ },
18374
+ "required": [
18375
+ "character_id",
18376
+ "asset_id"
18377
+ ],
18378
+ "additionalProperties": false
18379
+ },
18380
+ "annotations": {
18381
+ "readOnlyHint": false,
18382
+ "destructiveHint": false,
18383
+ "idempotentHint": false,
18384
+ "openWorldHint": false
18385
+ }
18386
+ },
18387
+ {
18388
+ "name": "democut_select_character_photo",
18389
+ "description": "\uB300\uD45C \uC0AC\uC9C4\uC744 \uACE0\uB978\uB2E4(\uC774\uBBF8 \uB9CC\uB4E0 \uCEF7\uC5D0\uB294 \uC18C\uAE09\uD558\uC9C0 \uC54A\uB294\uB2E4).",
18390
+ "inputSchema": {
18391
+ "type": "object",
18392
+ "properties": {
18393
+ "character_id": {
18394
+ "type": "string",
18395
+ "description": "\uC544\uBC14\uD0C0 id(chr_\u2026)"
18396
+ },
18397
+ "photo_id": {
18398
+ "title": "Photo Id",
18399
+ "type": "string"
18400
+ }
18401
+ },
18402
+ "required": [
18403
+ "character_id",
18404
+ "photo_id"
18405
+ ],
18406
+ "additionalProperties": false
18407
+ },
18408
+ "annotations": {
18409
+ "readOnlyHint": false,
18410
+ "destructiveHint": false,
18411
+ "idempotentHint": true,
18412
+ "openWorldHint": false
18413
+ }
18139
18414
  }
18140
18415
  ];
18141
18416
 
@@ -18321,6 +18596,7 @@ async function apiRequest(baseUrl, path, init = {}, deps = {}) {
18321
18596
  const fetchImpl = deps.fetchImpl ?? fetch;
18322
18597
  const token = await getValidAccessToken(baseUrl, deps);
18323
18598
  const headers = {
18599
+ ...init.headers ?? {},
18324
18600
  Authorization: `Bearer ${token}`,
18325
18601
  "User-Agent": `democut/${VERSION}`
18326
18602
  };
@@ -18617,19 +18893,6 @@ function listProjects(a = {}, deps = {}) {
18617
18893
  return { text: lines.join("\n") };
18618
18894
  });
18619
18895
  }
18620
- var PROJECT_FIELD_DEFAULTS = {
18621
- ratio: "16:9",
18622
- resolution: "1080p",
18623
- folder_id: null,
18624
- defaults: null
18625
- };
18626
- function unsupportedProjectFields(a) {
18627
- const given = a;
18628
- return Object.keys(PROJECT_FIELD_DEFAULTS).filter((key) => {
18629
- const v = given[key];
18630
- return v !== void 0 && v !== null && v !== PROJECT_FIELD_DEFAULTS[key];
18631
- });
18632
- }
18633
18896
  function createProject(a = {}, deps = {}) {
18634
18897
  return guarded(READ_ONLY, async () => {
18635
18898
  const title = (a.title ?? "").trim();
@@ -18639,24 +18902,38 @@ function createProject(a = {}, deps = {}) {
18639
18902
  text: "title \uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 \uC54C\uC544\uBCFC \uC218 \uC788\uB294 \uD504\uB85C\uC81D\uD2B8 \uC774\uB984\uC744 \uB123\uC5B4 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694."
18640
18903
  };
18641
18904
  }
18642
- const unsupported = unsupportedProjectFields(a);
18643
- if (unsupported.length > 0) {
18644
- return {
18645
- isError: true,
18646
- text: `${unsupported.join(", ")} \uC740 \uC544\uC9C1 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uAE30\uBCF8\uAC12\uB9CC \uAC00\uB2A5). \uADF8 \uC778\uC790\uB97C \uBE7C\uACE0 \uB2E4\uC2DC \uD638\uCD9C\uD558\uBA74 ${PROJECT_FIELD_DEFAULTS.ratio}\xB7${PROJECT_FIELD_DEFAULTS.resolution} \uB85C \uB9CC\uB4E4\uC5B4\uC9D1\uB2C8\uB2E4.`
18647
- };
18648
- }
18649
18905
  const base = resolveBaseUrl(deps.baseUrl);
18650
18906
  const voiceId = await defaultVoiceId(base, deps);
18651
18907
  const p = await create(
18652
18908
  base,
18653
- { title, voice_id: voiceId, external_ref: `mcp:project:${title}` },
18909
+ {
18910
+ title,
18911
+ voice_id: voiceId,
18912
+ external_ref: `mcp:project:${title}`,
18913
+ ...a.ratio !== void 0 ? { ratio: a.ratio } : {},
18914
+ ...a.resolution !== void 0 ? { resolution: a.resolution } : {},
18915
+ ...a.folder_id !== void 0 ? { folder_id: a.folder_id } : {},
18916
+ ...a.defaults !== void 0 ? { defaults: a.defaults } : {}
18917
+ },
18654
18918
  deps
18655
18919
  );
18920
+ const asked = a.ratio;
18921
+ const mismatch = asked && p.ratio && p.ratio !== asked;
18656
18922
  return {
18657
18923
  text: [
18658
18924
  `\uD504\uB85C\uC81D\uD2B8 \uC900\uBE44\uB428 \u2014 slug: ${p.slug}`,
18659
18925
  `\uC81C\uBAA9: ${p.title}`,
18926
+ // ⚠️ 롤링 중 옛 api 는 이 둘을 내지 않는다 — 없으면 **말하지 않는다**(undefined 를 찍으면
18927
+ // 모델이 그것을 사실로 읽는다).
18928
+ ...p.ratio && p.resolution ? [
18929
+ `\uBE44\uC728\xB7\uD574\uC0C1\uB3C4: ${p.ratio} \xB7 ${p.resolution}` + (p.ratio !== "16:9" ? " (\uBE44\uC728\uC740 \uC774\uD6C4 \uBC14\uAFC0 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4)" : "")
18930
+ ] : [],
18931
+ ...mismatch ? [
18932
+ `\u26A0\uFE0F ${asked} \uB85C \uC694\uCCAD\uD588\uC9C0\uB9CC ${p.ratio} \uB85C \uB9CC\uB4E4\uC5B4\uC84C\uC2B5\uB2C8\uB2E4 \u2014 \uC11C\uBC84\uAC00 \uC544\uC9C1 \uC774 \uC635\uC158\uC744 \uBC1B\uC9C0 \uC54A\uB294 \uBC84\uC804\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uBE44\uC728\uC740 \uBC14\uAFC0 \uC218 \uC5C6\uC73C\uB2C8, ${asked} \uAC00 \uD544\uC694\uD558\uBA74 \uC774 \uD504\uB85C\uC81D\uD2B8\uB97C \uC4F0\uC9C0 \uB9D0\uACE0 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC54C\uB9B0 \uB4A4 \uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uB9CC\uB4DC\uC138\uC694.`
18933
+ ] : [],
18934
+ ...asked && !p.ratio ? [
18935
+ `\u26A0\uFE0F \uC11C\uBC84\uAC00 \uBE44\uC728\uC744 \uC54C\uB824\uC8FC\uC9C0 \uC54A\uC544 ${asked} \uB85C \uB9CC\uB4E4\uC5B4\uC84C\uB294\uC9C0 \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (\uC61B \uBC84\uC804\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4). democut_get_options \uB85C \uD655\uC778\uD558\uC138\uC694.`
18936
+ ] : [],
18660
18937
  "",
18661
18938
  "\uD504\uB85C\uC81D\uD2B8\uB97C \uC694\uAD6C\uD558\uB294 \uB3C4\uAD6C\uC758 project_slug \uC5D0 \uC704 slug \uB97C \uADF8\uB300\uB85C \uB123\uC73C\uC138\uC694.",
18662
18939
  "\uAC19\uC740 \uC81C\uBAA9\uC73C\uB85C \uC774 \uB3C4\uAD6C\uB97C \uB2E4\uC2DC \uBD88\uB7EC\uB3C4 \uC0C8\uB85C \uB9CC\uB4E4\uC9C0 \uC54A\uACE0 \uC774 \uD504\uB85C\uC81D\uD2B8\uAC00 \uB098\uC635\uB2C8\uB2E4."
@@ -18960,6 +19237,144 @@ function cancelJob(a = {}, deps = {}) {
18960
19237
  return { text: lines.join("\n") };
18961
19238
  });
18962
19239
  }
19240
+ function characterLine(c) {
19241
+ const photos = c.photos?.length ? `\uC0AC\uC9C4 ${c.photos.length}\uC7A5` : "\uC0AC\uC9C4 \uC5C6\uC74C";
19242
+ return `${c.name} [${c.id}] rev=${c.rev} \xB7 ${photos}${c.current_photo_id ? " (\uB300\uD45C \uC788\uC74C)" : ""}`;
19243
+ }
19244
+ function listCharacters(_a3 = {}, deps = {}) {
19245
+ return guarded(READ_ONLY, async () => {
19246
+ const base = resolveBaseUrl(deps.baseUrl);
19247
+ const out2 = await apiRequest(base, "/api/characters", {}, deps);
19248
+ if (!out2.characters?.length) {
19249
+ return { text: "\uC544\uBC14\uD0C0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. democut_create_character \uB85C \uB9CC\uB4DC\uC138\uC694." };
19250
+ }
19251
+ return {
19252
+ text: [`\uC544\uBC14\uD0C0 ${out2.characters.length}\uAC1C:`, ...out2.characters.map((c) => ` ${characterLine(c)}`)].join("\n")
19253
+ };
19254
+ });
19255
+ }
19256
+ function characterBody(a) {
19257
+ return {
19258
+ name: a.name,
19259
+ role: a.role ?? "",
19260
+ voice_id: a.voice_id ?? null,
19261
+ persona_text: a.persona_text ?? "",
19262
+ look_text: a.look_text ?? ""
19263
+ };
19264
+ }
19265
+ function createCharacter(a = {}, deps = {}) {
19266
+ return guarded(READ_ONLY, async () => {
19267
+ if (!(a.name ?? "").trim()) return { isError: true, text: "name \uC774 \uD544\uC694\uD569\uB2C8\uB2E4." };
19268
+ const base = resolveBaseUrl(deps.baseUrl);
19269
+ const out2 = await apiRequest(
19270
+ base,
19271
+ "/api/characters",
19272
+ { method: "POST", body: characterBody(a) },
19273
+ deps
19274
+ );
19275
+ return {
19276
+ text: [
19277
+ `\uC544\uBC14\uD0C0\uB97C \uB9CC\uB4E4\uC5C8\uC2B5\uB2C8\uB2E4: ${characterLine(out2)}`,
19278
+ `\uCEF7\uC5D0\uC11C \uC4F0\uB824\uBA74 spec.pip.avatar_id \uC5D0 ${out2.id} \uB97C \uB123\uC73C\uC138\uC694.`
19279
+ ].join("\n")
19280
+ };
19281
+ });
19282
+ }
19283
+ function getCharacter(a = {}, deps = {}) {
19284
+ return guarded(READ_ONLY, async () => {
19285
+ const id = (a.character_id ?? "").trim();
19286
+ if (!id) return { isError: true, text: "character_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
19287
+ const base = resolveBaseUrl(deps.baseUrl);
19288
+ const out2 = await apiRequest(base, `/api/characters/${encodeURIComponent(id)}`, {}, deps);
19289
+ const lines = [characterLine(out2)];
19290
+ if (out2.role) lines.push(` \uC5ED\uD560: ${out2.role}`);
19291
+ if (out2.voice_id) lines.push(` \uBCF4\uC774\uC2A4: ${out2.voice_id}`);
19292
+ for (const p of out2.photos ?? []) {
19293
+ lines.push(` \uC0AC\uC9C4 ${p.seq}: ${p.asset_id} (${p.source})${p.id === out2.current_photo_id ? " \u2190 \uB300\uD45C" : ""}`);
19294
+ }
19295
+ return { text: lines.join("\n") };
19296
+ });
19297
+ }
19298
+ function putCharacter(a = {}, deps = {}) {
19299
+ return guarded(READ_ONLY, async () => {
19300
+ const id = (a.character_id ?? "").trim();
19301
+ if (!id) return { isError: true, text: "character_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
19302
+ if (!(a.name ?? "").trim()) return { isError: true, text: "name \uC774 \uD544\uC694\uD569\uB2C8\uB2E4(\uC804\uCCB4 \uAD50\uCCB4\uC785\uB2C8\uB2E4)." };
19303
+ if (a.rev === void 0 || a.rev === null) {
19304
+ return { isError: true, text: "rev \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 \u2014 democut_get_character \uB85C \uD604\uC7AC rev \uB97C \uC77D\uC5B4 \uADF8\uB300\uB85C \uB123\uC73C\uC138\uC694." };
19305
+ }
19306
+ const base = resolveBaseUrl(deps.baseUrl);
19307
+ const out2 = await apiRequest(
19308
+ base,
19309
+ `/api/characters/${encodeURIComponent(id)}`,
19310
+ { method: "PUT", body: characterBody(a), headers: { "If-Match": String(a.rev) } },
19311
+ deps
19312
+ );
19313
+ return { text: `\uC544\uBC14\uD0C0\uB97C \uBC14\uAFE8\uC2B5\uB2C8\uB2E4: ${characterLine(out2)}` };
19314
+ });
19315
+ }
19316
+ function addCharacterPhoto(a = {}, deps = {}) {
19317
+ return guarded(READ_ONLY, async () => {
19318
+ const id = (a.character_id ?? "").trim();
19319
+ if (!id) return { isError: true, text: "character_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
19320
+ const assetId = (a.asset_id ?? "").trim();
19321
+ if (!assetId) {
19322
+ return {
19323
+ isError: true,
19324
+ text: "asset_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 \u2014 democut_upload_asset \uC73C\uB85C \uC774\uBBF8\uC9C0\uB97C \uBA3C\uC800 \uC62C\uB9AC\uC138\uC694."
19325
+ };
19326
+ }
19327
+ const base = resolveBaseUrl(deps.baseUrl);
19328
+ const out2 = await apiRequest(
19329
+ base,
19330
+ `/api/characters/${encodeURIComponent(id)}/photos`,
19331
+ { method: "POST", body: { asset_id: assetId, ...a.note ? { note: a.note } : {} } },
19332
+ deps
19333
+ );
19334
+ const added = out2.photos?.[out2.photos.length - 1];
19335
+ const tail = added && out2.current_photo_id === added.id ? " \uCCAB \uC0AC\uC9C4\uC774\uB77C \uB300\uD45C\uB85C \uC815\uD588\uC2B5\uB2C8\uB2E4." : "";
19336
+ return { text: `\uC0AC\uC9C4\uC744 \uCD94\uAC00\uD588\uC2B5\uB2C8\uB2E4: ${characterLine(out2)}${tail}` };
19337
+ });
19338
+ }
19339
+ function selectCharacterPhoto(a = {}, deps = {}) {
19340
+ return guarded(READ_ONLY, async () => {
19341
+ const id = (a.character_id ?? "").trim();
19342
+ if (!id) return { isError: true, text: "character_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
19343
+ const photoId = (a.photo_id ?? "").trim();
19344
+ if (!photoId) {
19345
+ return {
19346
+ isError: true,
19347
+ text: "photo_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 \u2014 democut_get_character \uC758 photos[].id \uB97C \uC4F0\uC138\uC694."
19348
+ };
19349
+ }
19350
+ const base = resolveBaseUrl(deps.baseUrl);
19351
+ const out2 = await apiRequest(
19352
+ base,
19353
+ `/api/characters/${encodeURIComponent(id)}/photos/current`,
19354
+ { method: "PUT", body: { photo_id: photoId } },
19355
+ deps
19356
+ );
19357
+ return {
19358
+ text: `\uB300\uD45C \uC0AC\uC9C4\uC744 \uBC14\uAFE8\uC2B5\uB2C8\uB2E4: ${characterLine(out2)} \u2014 \uC774\uBBF8 \uB9CC\uB4E0 \uCEF7\uC740 \uADF8\uB300\uB85C\uC785\uB2C8\uB2E4.`
19359
+ };
19360
+ });
19361
+ }
19362
+ function deleteCharacter(a = {}, deps = {}) {
19363
+ return guarded(READ_ONLY, async () => {
19364
+ const id = (a.character_id ?? "").trim();
19365
+ if (!id) return { isError: true, text: "character_id \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
19366
+ const base = resolveBaseUrl(deps.baseUrl);
19367
+ await apiRequest(
19368
+ base,
19369
+ `/api/characters/${encodeURIComponent(id)}`,
19370
+ { method: "DELETE" },
19371
+ deps
19372
+ );
19373
+ return {
19374
+ text: `\uC544\uBC14\uD0C0 ${id} \uB97C \uC9C0\uC6E0\uC2B5\uB2C8\uB2E4. \uC774\uBBF8 \uB9CC\uB4E0 \uCEF7\uC740 \uADF8\uB300\uB85C\uC785\uB2C8\uB2E4(\uADF8\uB54C \uC4F4 \uC790\uC0B0\uC744 \uC790\uAE30 \uD589\uC5D0 \uAC16\uACE0 \uC788\uC2B5\uB2C8\uB2E4).`
19375
+ };
19376
+ });
19377
+ }
18963
19378
 
18964
19379
  // src/mcp/server.ts
18965
19380
  var TOOLS = GENERATED_TOOLS;
@@ -18993,6 +19408,21 @@ function dispatch(name, args, deps = {}) {
18993
19408
  return importCut(args, deps);
18994
19409
  case "democut_cancel_job":
18995
19410
  return cancelJob(args, deps);
19411
+ // ── 아바타(캐릭터) CRUD (MR 19a) ──
19412
+ case "democut_list_characters":
19413
+ return listCharacters(args, deps);
19414
+ case "democut_create_character":
19415
+ return createCharacter(args, deps);
19416
+ case "democut_get_character":
19417
+ return getCharacter(args, deps);
19418
+ case "democut_put_character":
19419
+ return putCharacter(args, deps);
19420
+ case "democut_add_character_photo":
19421
+ return addCharacterPhoto(args, deps);
19422
+ case "democut_select_character_photo":
19423
+ return selectCharacterPhoto(args, deps);
19424
+ case "democut_delete_character":
19425
+ return deleteCharacter(args, deps);
18996
19426
  default:
18997
19427
  return Promise.resolve({ isError: true, text: `\uC54C \uC218 \uC5C6\uB294 \uB3C4\uAD6C: ${name}` });
18998
19428
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "democut",
3
- "version": "0.6.15",
3
+ "version": "0.6.19",
4
4
  "description": "DemoCut 에이전트 CLI — device flow 로그인(RFC 8628) + 영상 생성",
5
5
  "license": "MIT",
6
6
  "author": "InfoGrab",