odoo-forge 0.1.5 → 0.1.6

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/package.json +2 -2
  2. package/src/codex.js +98 -12
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "odoo-forge",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "CLI installer and updater for Odoo Forge internal 1.0.",
5
5
  "type": "module",
6
6
  "dependencies": {
7
- "odoo-forge-bundle": "0.1.5"
7
+ "odoo-forge-bundle": "0.1.6"
8
8
  },
9
9
  "bin": {
10
10
  "odoo-forge": "bin/odoo-forge.js"
package/src/codex.js CHANGED
@@ -12,25 +12,112 @@ export function buildCodexManagedBlock({ token }) {
12
12
  type = "stdio"
13
13
  command = "npx"
14
14
  args = ["-y", "flowus-mcp-server@latest"]
15
- env = { FLOWUS_TOKEN = "${token}" }
15
+
16
+ [mcp_servers.flowus.env]
17
+ FLOWUS_TOKEN = "${token}"
16
18
  ${CODEX_END_MARKER}`;
17
19
  }
18
20
 
19
- export function upsertManagedBlock({
21
+ function stripManagedBlock({
20
22
  originalContent,
21
23
  startMarker,
22
24
  endMarker,
23
- block,
24
25
  }) {
25
26
  const startIndex = originalContent.indexOf(startMarker);
26
27
  const endIndex = originalContent.indexOf(endMarker);
27
28
 
28
- if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
29
- const blockEnd = endIndex + endMarker.length;
30
- return `${originalContent.slice(0, startIndex)}${block}${originalContent.slice(blockEnd)}`;
29
+ if (startIndex === -1 || endIndex === -1 || endIndex <= startIndex) {
30
+ return originalContent;
31
+ }
32
+
33
+ const blockEnd = endIndex + endMarker.length;
34
+ return `${originalContent.slice(0, startIndex)}${originalContent.slice(blockEnd)}`;
35
+ }
36
+
37
+ function isFlowusSectionHeader(headerName) {
38
+ return headerName === "mcp_servers.flowus" || headerName.startsWith("mcp_servers.flowus.");
39
+ }
40
+
41
+ function removeFlowusSections(originalContent) {
42
+ const lines = originalContent.split("\n");
43
+ const keptLines = [];
44
+ let skipCurrentSection = false;
45
+
46
+ for (const line of lines) {
47
+ const sectionMatch = line.match(/^\s*\[([^\]]+)\]\s*$/);
48
+ if (sectionMatch) {
49
+ skipCurrentSection = isFlowusSectionHeader(sectionMatch[1]);
50
+ }
51
+
52
+ if (!skipCurrentSection) {
53
+ keptLines.push(line);
54
+ }
55
+ }
56
+
57
+ return keptLines.join("\n");
58
+ }
59
+
60
+ function readSectionContent({ originalContent, sectionName }) {
61
+ const lines = originalContent.split("\n");
62
+ const collected = [];
63
+ let inSection = false;
64
+
65
+ for (const line of lines) {
66
+ const sectionMatch = line.match(/^\s*\[([^\]]+)\]\s*$/);
67
+ if (sectionMatch) {
68
+ if (inSection) {
69
+ break;
70
+ }
71
+ inSection = sectionMatch[1] === sectionName;
72
+ continue;
73
+ }
74
+
75
+ if (inSection) {
76
+ collected.push(line);
77
+ }
31
78
  }
32
79
 
33
- const trimmed = originalContent.trimEnd();
80
+ return inSection ? collected.join("\n") : null;
81
+ }
82
+
83
+ function extractTokenFromContent(originalContent) {
84
+ const flowusSection = readSectionContent({
85
+ originalContent,
86
+ sectionName: "mcp_servers.flowus",
87
+ });
88
+ const envSection = readSectionContent({
89
+ originalContent,
90
+ sectionName: "mcp_servers.flowus.env",
91
+ });
92
+
93
+ const candidates = [envSection, flowusSection, originalContent];
94
+ for (const candidate of candidates) {
95
+ if (!candidate) {
96
+ continue;
97
+ }
98
+
99
+ const inlineMatch = candidate.match(/FLOWUS_TOKEN\s*=\s*"([^"]+)"/);
100
+ if (inlineMatch) {
101
+ return inlineMatch[1];
102
+ }
103
+ }
104
+
105
+ return null;
106
+ }
107
+
108
+ export function upsertManagedBlock({
109
+ originalContent,
110
+ startMarker,
111
+ endMarker,
112
+ block,
113
+ }) {
114
+ const withoutManagedBlock = stripManagedBlock({
115
+ originalContent,
116
+ startMarker,
117
+ endMarker,
118
+ });
119
+ const withoutFlowusSections = removeFlowusSections(withoutManagedBlock);
120
+ const trimmed = withoutFlowusSections.trimEnd();
34
121
  return trimmed ? `${trimmed}\n\n${block}\n` : `${block}\n`;
35
122
  }
36
123
 
@@ -43,13 +130,12 @@ export function readCodexManagedToken({ homeDir }) {
43
130
  const content = fs.readFileSync(configPath, "utf8");
44
131
  const startIndex = content.indexOf(CODEX_START_MARKER);
45
132
  const endIndex = content.indexOf(CODEX_END_MARKER);
46
- if (startIndex === -1 || endIndex === -1 || endIndex <= startIndex) {
47
- return null;
133
+ if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
134
+ const managedBlock = content.slice(startIndex, endIndex + CODEX_END_MARKER.length);
135
+ return extractTokenFromContent(managedBlock);
48
136
  }
49
137
 
50
- const managedBlock = content.slice(startIndex, endIndex + CODEX_END_MARKER.length);
51
- const match = managedBlock.match(/FLOWUS_TOKEN\s*=\s*"([^"]+)"/);
52
- return match?.[1] ?? null;
138
+ return extractTokenFromContent(content);
53
139
  }
54
140
 
55
141
  export function installCodexWiring({ homeDir, token }) {