@team-semicolon/semo-cli 4.0.3 → 4.0.4

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.
@@ -53,6 +53,14 @@ const kb_1 = require("../kb");
53
53
  // Memory file mapping
54
54
  // ============================================================
55
55
  const MEMORY_DIR = ".claude/memory";
56
+ // --out-dir 로 override 가능 (OpenClaw 봇 workspace 경로 지원)
57
+ function resolveMemoryDir(outDir) {
58
+ if (outDir) {
59
+ // 절대경로 또는 ~ 경로 처리
60
+ return outDir.replace(/^~/, require("os").homedir());
61
+ }
62
+ return path.join(process.cwd(), MEMORY_DIR);
63
+ }
56
64
  const KB_DOMAIN_MAP = {
57
65
  team: "team.md",
58
66
  project: "projects.md",
@@ -63,10 +71,9 @@ const KB_DOMAIN_MAP = {
63
71
  // ============================================================
64
72
  // Helpers
65
73
  // ============================================================
66
- function ensureMemoryDir(cwd) {
67
- const memDir = path.join(cwd, MEMORY_DIR);
68
- fs.mkdirSync(memDir, { recursive: true });
69
- return memDir;
74
+ function ensureMemoryDir(resolvedDir) {
75
+ fs.mkdirSync(resolvedDir, { recursive: true });
76
+ return resolvedDir;
70
77
  }
71
78
  function kbEntriesToMarkdown(domain, entries) {
72
79
  if (entries.length === 0) {
@@ -176,8 +183,8 @@ function registerContextCommands(program) {
176
183
  .option("--domain <name>", "특정 KB 도메인만")
177
184
  .option("--no-bots", "bot_status 동기화 건너뜀")
178
185
  .option("--no-ontology", "ontology 동기화 건너뜀")
186
+ .option("--out-dir <path>", "메모리 파일 출력 경로 (기본: .claude/memory/). OpenClaw 봇 workspace 지원용")
179
187
  .action(async (options) => {
180
- const cwd = process.cwd();
181
188
  const spinner = (0, ora_1.default)("context sync 시작...").start();
182
189
  const connected = await (0, database_1.isDbConnected)();
183
190
  if (!connected) {
@@ -186,7 +193,7 @@ function registerContextCommands(program) {
186
193
  return;
187
194
  }
188
195
  const pool = (0, database_1.getPool)();
189
- const memDir = ensureMemoryDir(cwd);
196
+ const memDir = ensureMemoryDir(resolveMemoryDir(options.outDir));
190
197
  let written = 0;
191
198
  try {
192
199
  // 1. KB domains → memory/*.md
@@ -221,7 +228,7 @@ function registerContextCommands(program) {
221
228
  written++;
222
229
  }
223
230
  spinner.succeed(`context sync 완료 — ${written}개 파일 업데이트`);
224
- console.log(chalk_1.default.gray(` 저장 위치: ${MEMORY_DIR}/`));
231
+ console.log(chalk_1.default.gray(` 저장 위치: ${memDir}`));
225
232
  }
226
233
  catch (err) {
227
234
  spinner.fail(`context sync 실패: ${err}`);
@@ -236,9 +243,9 @@ function registerContextCommands(program) {
236
243
  .description(".claude/memory/decisions.md → Core DB (semo.knowledge_base)")
237
244
  .option("--domain <name>", "push할 도메인 (기본: decision)", "decision")
238
245
  .option("--dry-run", "실제 push 없이 변경사항만 미리보기")
246
+ .option("--out-dir <path>", "메모리 파일 경로 (기본: .claude/memory/). OpenClaw 봇 workspace 지원용")
239
247
  .action(async (options) => {
240
- const cwd = process.cwd();
241
- const memDir = path.join(cwd, MEMORY_DIR);
248
+ const memDir = resolveMemoryDir(options.outDir);
242
249
  const filename = KB_DOMAIN_MAP[options.domain] || `${options.domain}.md`;
243
250
  const filePath = path.join(memDir, filename);
244
251
  if (!fs.existsSync(filePath)) {
package/dist/database.js CHANGED
@@ -9,6 +9,39 @@
9
9
  * - semo-system 의존성 제거
10
10
  * - 문서 내용을 DB에서 직접 조회
11
11
  */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
12
45
  Object.defineProperty(exports, "__esModule", { value: true });
13
46
  exports.getPool = getPool;
14
47
  exports.getActiveSkills = getActiveSkills;
@@ -20,6 +53,40 @@ exports.getSkillCountByCategory = getSkillCountByCategory;
20
53
  exports.closeConnection = closeConnection;
21
54
  exports.isDbConnected = isDbConnected;
22
55
  const pg_1 = require("pg");
56
+ const fs = __importStar(require("fs"));
57
+ const os = __importStar(require("os"));
58
+ const path = __importStar(require("path"));
59
+ // ~/.semo.env 자동 로드 — LaunchAgent / Claude Code 앱 / cron 등
60
+ // 인터랙티브 쉘이 아닌 환경에서 환경변수를 공급한다.
61
+ // 이미 설정된 환경변수는 덮어쓰지 않는다 (env var > file).
62
+ function loadSemoEnv() {
63
+ const envFile = path.join(os.homedir(), ".semo.env");
64
+ if (!fs.existsSync(envFile))
65
+ return;
66
+ try {
67
+ const lines = fs.readFileSync(envFile, "utf8").split("\n");
68
+ for (const raw of lines) {
69
+ const line = raw.trim().replace(/^export\s+/, "");
70
+ if (!line || line.startsWith("#"))
71
+ continue;
72
+ const eqIdx = line.indexOf("=");
73
+ if (eqIdx === -1)
74
+ continue;
75
+ const key = line.slice(0, eqIdx).trim();
76
+ let val = line.slice(eqIdx + 1).trim();
77
+ if ((val.startsWith("'") && val.endsWith("'")) || (val.startsWith('"') && val.endsWith('"'))) {
78
+ val = val.slice(1, -1);
79
+ }
80
+ if (key && !process.env[key])
81
+ process.env[key] = val;
82
+ }
83
+ }
84
+ catch {
85
+ // 파일 읽기 실패 시 무시 — 환경변수가 없으면 이후 buildDbConfig에서 에러
86
+ }
87
+ }
88
+ // 최초 import 시 즉시 실행
89
+ loadSemoEnv();
23
90
  // PostgreSQL 연결 정보 (팀 코어)
24
91
  // DATABASE_URL 우선, 없으면 개별 SEMO_DB_* 변수 사용
25
92
  function buildDbConfig() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-semicolon/semo-cli",
3
- "version": "4.0.3",
3
+ "version": "4.0.4",
4
4
  "description": "SEMO CLI - AI Agent Orchestration Framework Installer",
5
5
  "main": "dist/index.js",
6
6
  "bin": {