@opvs-ai/cli 0.1.3 → 0.2.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.
@@ -1,39 +1,232 @@
1
1
  /**
2
2
  * Config file management: ~/.opvs/config.json
3
+ *
4
+ * v2 format supports multiple workspaces. v1 configs are auto-migrated.
3
5
  */
4
6
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
7
  import { homedir } from "node:os";
6
8
  import { join } from "node:path";
7
- import { DEFAULT_CONFIG } from "../types.js";
9
+ import { DEFAULT_CONFIG, DEFAULT_WORKSPACE, } from "../types.js";
8
10
  const CONFIG_DIR = join(homedir(), ".opvs");
9
11
  const CONFIG_FILE = join(CONFIG_DIR, "config.json");
10
12
  export function getConfigPath() {
11
13
  return CONFIG_FILE;
12
14
  }
13
- export function loadConfig() {
15
+ // ---------------------------------------------------------------------------
16
+ // Internal: read, migrate, write
17
+ // ---------------------------------------------------------------------------
18
+ function slugify(name) {
19
+ return name
20
+ .toLowerCase()
21
+ .replace(/[^a-z0-9]+/g, "-")
22
+ .replace(/^-|-$/g, "") || "default";
23
+ }
24
+ function migrateV1(v1) {
25
+ const slug = v1.brand_name ? slugify(v1.brand_name) : "default";
26
+ const config = {
27
+ version: 2,
28
+ current_workspace: v1.token ? slug : "",
29
+ format: v1.format || "yaml",
30
+ workspaces: {},
31
+ };
32
+ if (v1.token) {
33
+ config.workspaces[slug] = {
34
+ api_url: v1.api_url || DEFAULT_WORKSPACE.api_url,
35
+ token: v1.token,
36
+ brand_id: v1.brand_id,
37
+ brand_name: v1.brand_name,
38
+ };
39
+ }
40
+ return config;
41
+ }
42
+ function writeConfig(config) {
43
+ if (!existsSync(CONFIG_DIR)) {
44
+ mkdirSync(CONFIG_DIR, { recursive: true });
45
+ }
46
+ writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n");
47
+ }
48
+ /** Load the raw v2 config, auto-migrating from v1 if needed. */
49
+ export function loadRawConfig() {
14
50
  if (!existsSync(CONFIG_FILE)) {
15
- return { ...DEFAULT_CONFIG };
51
+ return { ...DEFAULT_CONFIG, workspaces: {} };
16
52
  }
17
53
  try {
18
- const raw = readFileSync(CONFIG_FILE, "utf-8");
19
- return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
54
+ const raw = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
55
+ if (raw.version === 2) {
56
+ return {
57
+ version: 2,
58
+ current_workspace: raw.current_workspace ?? "",
59
+ format: raw.format ?? "yaml",
60
+ workspaces: raw.workspaces ?? {},
61
+ };
62
+ }
63
+ // v1 migration
64
+ const migrated = migrateV1(raw);
65
+ writeConfig(migrated);
66
+ return migrated;
20
67
  }
21
68
  catch {
22
- return { ...DEFAULT_CONFIG };
69
+ return { ...DEFAULT_CONFIG, workspaces: {} };
23
70
  }
24
71
  }
25
- export function saveConfig(config) {
26
- const current = loadConfig();
27
- const merged = { ...current, ...config };
28
- if (!existsSync(CONFIG_DIR)) {
29
- mkdirSync(CONFIG_DIR, { recursive: true });
72
+ // ---------------------------------------------------------------------------
73
+ // Workspace resolution
74
+ // ---------------------------------------------------------------------------
75
+ /**
76
+ * Resolve which workspace to use. Priority:
77
+ * 1. Explicit flag (--workspace / -w)
78
+ * 2. OPVS_WORKSPACE env var
79
+ * 3. current_workspace in config
80
+ * 4. Implicit single workspace
81
+ * 5. Error
82
+ */
83
+ export function resolveWorkspace(config, flagSlug) {
84
+ const slug = flagSlug ||
85
+ process.env.OPVS_WORKSPACE ||
86
+ config.current_workspace ||
87
+ (Object.keys(config.workspaces).length === 1
88
+ ? Object.keys(config.workspaces)[0]
89
+ : "");
90
+ if (!slug) {
91
+ const available = Object.keys(config.workspaces);
92
+ if (available.length === 0) {
93
+ throw new Error('No workspaces configured. Run "opvs auth request -w <slug> -e <email>" to authenticate.');
94
+ }
95
+ throw new Error(`Multiple workspaces available: ${available.join(", ")}. Use "opvs workspace use <slug>" or "-w <slug>" to select one.`);
96
+ }
97
+ const workspace = config.workspaces[slug];
98
+ if (!workspace) {
99
+ const available = Object.keys(config.workspaces);
100
+ throw new Error(`Workspace "${slug}" not found. Available: ${available.length > 0 ? available.join(", ") : "(none)"}`);
101
+ }
102
+ return { slug, workspace };
103
+ }
104
+ // ---------------------------------------------------------------------------
105
+ // Public API — used by commands
106
+ // ---------------------------------------------------------------------------
107
+ /**
108
+ * Get the effective (resolved) config for the current command.
109
+ * Applies env var overrides on top of the resolved workspace.
110
+ */
111
+ export function getEffectiveConfig(flagSlug) {
112
+ const config = loadRawConfig();
113
+ const { slug, workspace } = resolveWorkspace(config, flagSlug);
114
+ return {
115
+ workspace_slug: slug,
116
+ api_url: process.env.OPVS_API_URL || workspace.api_url,
117
+ token: process.env.OPVS_TOKEN || workspace.token,
118
+ brand_id: workspace.brand_id,
119
+ brand_name: workspace.brand_name,
120
+ format: process.env.OPVS_FORMAT || config.format,
121
+ };
122
+ }
123
+ /** Get just the global format setting (no workspace resolution needed). */
124
+ export function getFormat() {
125
+ const config = loadRawConfig();
126
+ return process.env.OPVS_FORMAT || config.format;
127
+ }
128
+ /** Save or update a workspace entry. Also sets as current if no current is set. */
129
+ export function saveWorkspace(slug, data) {
130
+ const config = loadRawConfig();
131
+ const existing = config.workspaces[slug] || { ...DEFAULT_WORKSPACE };
132
+ config.workspaces[slug] = { ...existing, ...data };
133
+ if (!config.current_workspace) {
134
+ config.current_workspace = slug;
135
+ }
136
+ writeConfig(config);
137
+ }
138
+ /** Set the current workspace pointer. */
139
+ export function setCurrentWorkspace(slug) {
140
+ const config = loadRawConfig();
141
+ if (!config.workspaces[slug]) {
142
+ throw new Error(`Workspace "${slug}" does not exist.`);
143
+ }
144
+ config.current_workspace = slug;
145
+ writeConfig(config);
146
+ }
147
+ /** Remove a workspace. Updates current_workspace if needed. */
148
+ export function removeWorkspace(slug) {
149
+ const config = loadRawConfig();
150
+ if (!config.workspaces[slug]) {
151
+ throw new Error(`Workspace "${slug}" does not exist.`);
30
152
  }
31
- writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2) + "\n");
153
+ delete config.workspaces[slug];
154
+ if (config.current_workspace === slug) {
155
+ const remaining = Object.keys(config.workspaces);
156
+ config.current_workspace = remaining.length === 1 ? remaining[0] : "";
157
+ }
158
+ writeConfig(config);
159
+ }
160
+ /** List all workspaces with metadata. */
161
+ export function listWorkspaces() {
162
+ const config = loadRawConfig();
163
+ return Object.entries(config.workspaces).map(([slug, ws]) => ({
164
+ slug,
165
+ brand_name: ws.brand_name,
166
+ api_url: ws.api_url,
167
+ isCurrent: slug === config.current_workspace,
168
+ }));
32
169
  }
170
+ /** Update global settings (format). */
171
+ export function saveGlobal(data) {
172
+ const config = loadRawConfig();
173
+ if (data.format)
174
+ config.format = data.format;
175
+ writeConfig(config);
176
+ }
177
+ /** Reset config to empty v2 defaults. */
33
178
  export function resetConfig() {
34
- if (!existsSync(CONFIG_DIR)) {
35
- mkdirSync(CONFIG_DIR, { recursive: true });
179
+ writeConfig({ ...DEFAULT_CONFIG, workspaces: {} });
180
+ }
181
+ /**
182
+ * @deprecated Use getEffectiveConfig() instead. Kept for migration period.
183
+ * Returns a v1-shaped config from the current workspace for backwards compat.
184
+ */
185
+ export function loadConfig() {
186
+ try {
187
+ const eff = getEffectiveConfig();
188
+ return {
189
+ api_url: eff.api_url,
190
+ token: eff.token,
191
+ brand_id: eff.brand_id,
192
+ brand_name: eff.brand_name,
193
+ format: eff.format,
194
+ };
195
+ }
196
+ catch {
197
+ return {
198
+ api_url: DEFAULT_WORKSPACE.api_url,
199
+ token: "",
200
+ brand_id: null,
201
+ brand_name: "",
202
+ format: "yaml",
203
+ };
204
+ }
205
+ }
206
+ /**
207
+ * @deprecated Use saveWorkspace() or saveGlobal() instead.
208
+ * Kept for migration period — saves to current workspace.
209
+ */
210
+ export function saveConfig(data) {
211
+ const config = loadRawConfig();
212
+ const slug = config.current_workspace || "default";
213
+ // Separate global vs workspace fields
214
+ if (data.format) {
215
+ config.format = data.format;
216
+ }
217
+ const wsData = {};
218
+ if (data.api_url !== undefined)
219
+ wsData.api_url = data.api_url;
220
+ if (data.token !== undefined)
221
+ wsData.token = data.token;
222
+ if (data.brand_id !== undefined)
223
+ wsData.brand_id = data.brand_id;
224
+ if (data.brand_name !== undefined)
225
+ wsData.brand_name = data.brand_name;
226
+ if (Object.keys(wsData).length > 0) {
227
+ const existing = config.workspaces[slug] || { ...DEFAULT_WORKSPACE };
228
+ config.workspaces[slug] = { ...existing, ...wsData };
36
229
  }
37
- writeFileSync(CONFIG_FILE, JSON.stringify(DEFAULT_CONFIG, null, 2) + "\n");
230
+ writeConfig(config);
38
231
  }
39
232
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAa,cAAc,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAA0B;IACnD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAC7E,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,12 +1,32 @@
1
1
  /** Shared TypeScript interfaces for @opvs/cli */
2
- export interface CLIConfig {
2
+ export interface WorkspaceConfig {
3
+ api_url: string;
4
+ token: string;
5
+ brand_id: number | null;
6
+ brand_name: string;
7
+ }
8
+ export interface CLIConfigV2 {
9
+ version: 2;
10
+ current_workspace: string;
11
+ format: "yaml" | "json" | "md";
12
+ workspaces: Record<string, WorkspaceConfig>;
13
+ }
14
+ /** Flat effective config returned to commands after workspace resolution. */
15
+ export interface EffectiveConfig extends WorkspaceConfig {
16
+ workspace_slug: string;
17
+ format: "yaml" | "json" | "md";
18
+ }
19
+ export interface CLIConfigV1 {
3
20
  api_url: string;
4
21
  token: string;
5
22
  brand_id: number | null;
6
23
  brand_name: string;
7
24
  format: "yaml" | "json" | "md";
8
25
  }
9
- export declare const DEFAULT_CONFIG: CLIConfig;
26
+ /** @deprecated Use CLIConfigV2. Kept as alias for migration. */
27
+ export type CLIConfig = CLIConfigV1;
28
+ export declare const DEFAULT_CONFIG: CLIConfigV2;
29
+ export declare const DEFAULT_WORKSPACE: WorkspaceConfig;
10
30
  export interface PATRequestResponse {
11
31
  request_id: string;
12
32
  status: string;
package/dist/types.js CHANGED
@@ -1,9 +1,14 @@
1
1
  /** Shared TypeScript interfaces for @opvs/cli */
2
2
  export const DEFAULT_CONFIG = {
3
- api_url: "https://api.opvs.ai",
3
+ version: 2,
4
+ current_workspace: "",
5
+ format: "yaml",
6
+ workspaces: {},
7
+ };
8
+ export const DEFAULT_WORKSPACE = {
9
+ api_url: "https://app.opvs.ai",
4
10
  token: "",
5
11
  brand_id: null,
6
12
  brand_name: "",
7
- format: "yaml",
8
13
  };
9
14
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAUjD,MAAM,CAAC,MAAM,cAAc,GAAc;IACvC,OAAO,EAAE,qBAAqB;IAC9B,KAAK,EAAE,EAAE;IACT,QAAQ,EAAE,IAAI;IACd,UAAU,EAAE,EAAE;IACd,MAAM,EAAE,MAAM;CACf,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAqCjD,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,OAAO,EAAE,CAAC;IACV,iBAAiB,EAAE,EAAE;IACrB,MAAM,EAAE,MAAM;IACd,UAAU,EAAE,EAAE;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAoB;IAChD,OAAO,EAAE,qBAAqB;IAC9B,KAAK,EAAE,EAAE;IACT,QAAQ,EAAE,IAAI;IACd,UAAU,EAAE,EAAE;CACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opvs-ai/cli",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "OPVS CLI — Terminal access to AgentBoard + AgentDocs for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,8 @@
23
23
  "node": ">=18.0.0"
24
24
  },
25
25
  "files": [
26
- "dist"
26
+ "dist",
27
+ "README.md"
27
28
  ],
28
29
  "keywords": [
29
30
  "opvs",