@ssobig/writer-cli 0.2.2 → 0.3.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.
Files changed (28) hide show
  1. package/README.md +12 -0
  2. package/config.js +2 -1
  3. package/package.json +1 -1
  4. package/templates/mystery-v1/authoring-view-preference.js +22 -5
  5. package/templates/mystery-v1/character-perspective-preview.js +3 -3
  6. package/templates/mystery-v1/codemirror6-runtime.min.js +28 -0
  7. package/templates/mystery-v1/component-asset-operations.js +5 -4
  8. package/templates/mystery-v1/component-catalog-contract.js +26 -35
  9. package/templates/mystery-v1/component-draft-operations.js +19 -8
  10. package/templates/mystery-v1/component-field-contracts.js +29 -49
  11. package/templates/mystery-v1/component-id-policy.js +1 -1
  12. package/templates/mystery-v1/component-manager.js +21 -11
  13. package/templates/mystery-v1/component-navigation-counts.js +3 -8
  14. package/templates/mystery-v1/component-registry.js +11 -5
  15. package/templates/mystery-v1/component-renderers.js +12 -8
  16. package/templates/mystery-v1/markdown-live-editor.js +350 -0
  17. package/templates/mystery-v1/page-header.js +2 -1
  18. package/tools/writer-cli/package-lock.json +2 -2
  19. package/tools/writer-cli/package.json +1 -1
  20. package/tools/writer-cli/skills/ssobig-writer-cli/SKILL.md +1 -1
  21. package/tools/writer-cli/skills/ssobig-writer-cli/references/projects-components.md +1 -1
  22. package/tools/writer-cli/src/agent-service.cjs +3 -1
  23. package/tools/writer-cli/src/command-registry.cjs +3 -0
  24. package/tools/writer-cli/src/commands.cjs +85 -3
  25. package/tools/writer-cli/src/domain.cjs +250 -1
  26. package/tools/writer-cli/src/gateway.cjs +14 -0
  27. package/tools/writer-cli/src/mutations.cjs +167 -1
  28. package/tools/writer-cli/src/project-import.cjs +12 -21
package/README.md CHANGED
@@ -17,6 +17,18 @@ ssobig-writer project list
17
17
 
18
18
  CLI는 stdout에 JSON 문서 하나를 출력한다. 원고 변경은 `plan -> 사람 검토 -> apply -> authoritative read-back` 절차만 사용하며, 범용 SQL이나 직접 table update를 제공하지 않는다.
19
19
 
20
+ 작품 구성 화면의 등록된 선택 Component 추가·사용 여부와 선택 속성도 같은 절차로 변경할 수 있다.
21
+
22
+ ```bash
23
+ ssobig-writer component plan-add --project <slug> --template ssobig.timeline --out component-add.plan.json
24
+ ssobig-writer apply component-add.plan.json --receipt component-add.receipt.json
25
+
26
+ ssobig-writer component plan-set-active --project <slug> --instance timeline --active false --out component-archive.plan.json
27
+ ssobig-writer component plan-set-field --project <slug> --instance clues --field image --enabled false --out field.plan.json
28
+ ```
29
+
30
+ plan에서 대상, 보존할 data, 생성·제거될 View·binding 또는 `enabledOptionalFields` 변경을 먼저 검토해야 한다. 사용 안 함은 data를 삭제하지 않고 보관하며, 필수·내부·미등록 Component와 필수·미등록 속성 및 임의 구성 변경은 허용하지 않는다.
31
+
20
32
  ## 업데이트와 제거
21
33
 
22
34
  ```bash
package/config.js CHANGED
@@ -9,6 +9,7 @@
9
9
  supabaseUrl: "https://tlyioijsopxeegzfjlqe.supabase.co",
10
10
  supabaseKey: "sb_publishable_AdEHgXPGJ2gKGVAjb7RYSg_YzUuT6jB",
11
11
  assetBucket: "ssobig-writer-assets",
12
- staffDomain: "ssobig.com"
12
+ staffDomain: "ssobig.com",
13
+ sentryDsn: "https://d9d4a549fafe2f35be1827e5097ea7e8@o4505765760204800.ingest.us.sentry.io/4511998281449472"
13
14
  });
14
15
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ssobig/writer-cli",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Official agent CLI for SSOBIG WRITER",
5
5
  "type": "commonjs",
6
6
  "license": "UNLICENSED",
@@ -8,6 +8,7 @@
8
8
  const STORAGE_KEY = "somi-workbench-authoring-view";
9
9
  const DEFAULT_VIEW = "preview";
10
10
  const VIEWS = Object.freeze(["input", "preview"]);
11
+ const STORAGE_VERSION = 1;
11
12
 
12
13
  function normalize(value) {
13
14
  return VIEWS.includes(value) ? value : DEFAULT_VIEW;
@@ -18,17 +19,33 @@
18
19
  catch (_) { return null; }
19
20
  }
20
21
 
21
- function read(storage = deviceStorage()) {
22
- try { return normalize(storage?.getItem(STORAGE_KEY)); }
22
+ function parseStoredValue(value) {
23
+ if (VIEWS.includes(value)) return { fallback: value, views: {} };
24
+ try {
25
+ const parsed = JSON.parse(value || "null");
26
+ if (parsed?.version !== STORAGE_VERSION || !parsed.views || typeof parsed.views !== "object" || Array.isArray(parsed.views)) return { fallback: DEFAULT_VIEW, views: {} };
27
+ return { fallback: normalize(parsed.fallback), views: { ...parsed.views } };
28
+ } catch (_) { return { fallback: DEFAULT_VIEW, views: {} }; }
29
+ }
30
+
31
+ function read(scope, storage = deviceStorage()) {
32
+ try {
33
+ const stored = parseStoredValue(storage?.getItem(STORAGE_KEY));
34
+ return normalize(stored.views[String(scope || "")] || stored.fallback);
35
+ }
23
36
  catch (_) { return DEFAULT_VIEW; }
24
37
  }
25
38
 
26
- function write(view, storage = deviceStorage()) {
39
+ function write(scope, view, storage = deviceStorage()) {
27
40
  const normalized = normalize(view);
28
- try { storage?.setItem(STORAGE_KEY, normalized); }
41
+ try {
42
+ const stored = parseStoredValue(storage?.getItem(STORAGE_KEY));
43
+ stored.views[String(scope || "")] = normalized;
44
+ storage?.setItem(STORAGE_KEY, JSON.stringify({ version: STORAGE_VERSION, fallback: stored.fallback, views: stored.views }));
45
+ }
29
46
  catch (_) { /* 기기 저장소를 사용할 수 없어도 현재 화면 전환은 유지한다. */ }
30
47
  return normalized;
31
48
  }
32
49
 
33
- return Object.freeze({ STORAGE_KEY, DEFAULT_VIEW, VIEWS, normalize, read, write });
50
+ return Object.freeze({ STORAGE_KEY, STORAGE_VERSION, DEFAULT_VIEW, VIEWS, normalize, read, write });
34
51
  });
@@ -6,9 +6,9 @@
6
6
  "use strict";
7
7
 
8
8
  const CARD_ORDER = Object.freeze([
9
- Object.freeze({ key: "progress", label: "진행", templateId: "ssobig.progress" }),
10
- Object.freeze({ key: "common", label: "공통정보", templateId: "ssobig.common" }),
11
- Object.freeze({ key: "character", label: "캐릭터", templateId: "ssobig.character" })
9
+ Object.freeze({ key: "progress", label: "진행 순서", templateId: "ssobig.progress" }),
10
+ Object.freeze({ key: "common", label: "공통 문서", templateId: "ssobig.common" }),
11
+ Object.freeze({ key: "character", label: "캐릭터별 문서", templateId: "ssobig.character" })
12
12
  ]);
13
13
 
14
14
  function characters(instance, data) {