@revos/cli 0.2.1 → 0.2.3

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 (162) hide show
  1. package/README.md +289 -77
  2. package/dist/adapters/oclif/commands/action-runs/get.mjs +1 -1
  3. package/dist/adapters/oclif/commands/action-runs/list.mjs +8 -2
  4. package/dist/adapters/oclif/commands/actions/get-input-schema.mjs +2 -2
  5. package/dist/adapters/oclif/commands/actions/get-params-schema.mjs +2 -2
  6. package/dist/adapters/oclif/commands/actions/get.mjs +1 -1
  7. package/dist/adapters/oclif/commands/actions/list.mjs +8 -4
  8. package/dist/adapters/oclif/commands/ai-instructions/create.mjs +1 -1
  9. package/dist/adapters/oclif/commands/ai-instructions/delete.mjs +1 -1
  10. package/dist/adapters/oclif/commands/ai-instructions/get.mjs +1 -1
  11. package/dist/adapters/oclif/commands/ai-instructions/list.mjs +8 -2
  12. package/dist/adapters/oclif/commands/ai-instructions/update.mjs +1 -1
  13. package/dist/adapters/oclif/commands/api.d.mts +11 -0
  14. package/dist/adapters/oclif/commands/api.mjs +112 -0
  15. package/dist/adapters/oclif/commands/apply.d.mts +29 -0
  16. package/dist/adapters/oclif/commands/apply.mjs +77 -0
  17. package/dist/adapters/oclif/commands/auth/login.d.mts +6 -4
  18. package/dist/adapters/oclif/commands/auth/login.mjs +23 -11
  19. package/dist/adapters/oclif/commands/auth/logout.d.mts +2 -1
  20. package/dist/adapters/oclif/commands/auth/logout.mjs +3 -2
  21. package/dist/adapters/oclif/commands/auth/status.d.mts +4 -2
  22. package/dist/adapters/oclif/commands/auth/status.mjs +23 -3
  23. package/dist/adapters/oclif/commands/connections/create.d.mts +6 -0
  24. package/dist/adapters/oclif/commands/connections/create.mjs +8 -0
  25. package/dist/adapters/oclif/commands/connections/delete.d.mts +6 -0
  26. package/dist/adapters/oclif/commands/connections/delete.mjs +8 -0
  27. package/dist/adapters/oclif/commands/connections/get.d.mts +6 -0
  28. package/dist/adapters/oclif/commands/connections/get.mjs +8 -0
  29. package/dist/adapters/oclif/commands/connections/list.d.mts +6 -0
  30. package/dist/adapters/oclif/commands/connections/list.mjs +14 -0
  31. package/dist/adapters/oclif/commands/connections/update.d.mts +6 -0
  32. package/dist/adapters/oclif/commands/connections/update.mjs +8 -0
  33. package/dist/adapters/oclif/commands/cubes/create.d.mts +6 -0
  34. package/dist/adapters/oclif/commands/cubes/create.mjs +8 -0
  35. package/dist/adapters/oclif/commands/cubes/delete.d.mts +6 -0
  36. package/dist/adapters/oclif/commands/cubes/delete.mjs +8 -0
  37. package/dist/adapters/oclif/commands/cubes/get.d.mts +6 -0
  38. package/dist/adapters/oclif/commands/cubes/get.mjs +8 -0
  39. package/dist/adapters/oclif/commands/cubes/list.d.mts +6 -0
  40. package/dist/adapters/oclif/commands/cubes/list.mjs +13 -0
  41. package/dist/adapters/oclif/commands/cubes/update.d.mts +6 -0
  42. package/dist/adapters/oclif/commands/cubes/update.mjs +8 -0
  43. package/dist/adapters/oclif/commands/diff.d.mts +28 -0
  44. package/dist/adapters/oclif/commands/diff.mjs +66 -0
  45. package/dist/adapters/oclif/commands/gservice-account-keys/get.mjs +1 -1
  46. package/dist/adapters/oclif/commands/gservice-account-keys/reveal.mjs +2 -2
  47. package/dist/adapters/oclif/commands/gservice-accounts/create.mjs +1 -1
  48. package/dist/adapters/oclif/commands/gservice-accounts/delete.mjs +1 -1
  49. package/dist/adapters/oclif/commands/gservice-accounts/get.mjs +1 -1
  50. package/dist/adapters/oclif/commands/gservice-accounts/list.mjs +7 -2
  51. package/dist/adapters/oclif/commands/init.d.mts +3 -1
  52. package/dist/adapters/oclif/commands/init.mjs +27 -23
  53. package/dist/adapters/oclif/commands/org/create.mjs +3 -2
  54. package/dist/adapters/oclif/commands/org/current.d.mts +12 -3
  55. package/dist/adapters/oclif/commands/org/current.mjs +27 -2
  56. package/dist/adapters/oclif/commands/org/get.mjs +3 -2
  57. package/dist/adapters/oclif/commands/org/list.d.mts +3 -11
  58. package/dist/adapters/oclif/commands/org/list.mjs +35 -26
  59. package/dist/adapters/oclif/commands/org/switch.d.mts +4 -2
  60. package/dist/adapters/oclif/commands/org/switch.mjs +16 -3
  61. package/dist/adapters/oclif/commands/pull.d.mts +29 -0
  62. package/dist/adapters/oclif/commands/pull.mjs +88 -0
  63. package/dist/adapters/oclif/commands/score-groups/create.mjs +3 -2
  64. package/dist/adapters/oclif/commands/score-groups/delete.mjs +1 -1
  65. package/dist/adapters/oclif/commands/score-groups/get.mjs +1 -1
  66. package/dist/adapters/oclif/commands/score-groups/list.mjs +3 -2
  67. package/dist/adapters/oclif/commands/score-groups/update.mjs +1 -1
  68. package/dist/adapters/oclif/commands/scores/create.mjs +3 -2
  69. package/dist/adapters/oclif/commands/scores/delete.mjs +1 -1
  70. package/dist/adapters/oclif/commands/scores/list.mjs +3 -2
  71. package/dist/adapters/oclif/commands/scores/update.mjs +1 -1
  72. package/dist/adapters/oclif/commands/segments/create.mjs +1 -1
  73. package/dist/adapters/oclif/commands/segments/delete.mjs +1 -1
  74. package/dist/adapters/oclif/commands/segments/evaluate.mjs +2 -2
  75. package/dist/adapters/oclif/commands/segments/get-evaluation-history.mjs +2 -2
  76. package/dist/adapters/oclif/commands/segments/get-version.mjs +2 -2
  77. package/dist/adapters/oclif/commands/segments/get.mjs +1 -1
  78. package/dist/adapters/oclif/commands/segments/list-versions.mjs +16 -5
  79. package/dist/adapters/oclif/commands/segments/list.mjs +9 -2
  80. package/dist/adapters/oclif/commands/segments/restore-version.mjs +2 -2
  81. package/dist/adapters/oclif/commands/segments/update.mjs +1 -1
  82. package/dist/adapters/oclif/commands/sources/create.d.mts +11 -0
  83. package/dist/adapters/oclif/commands/sources/create.mjs +16 -0
  84. package/dist/adapters/oclif/commands/sources/delete.d.mts +6 -0
  85. package/dist/adapters/oclif/commands/sources/delete.mjs +8 -0
  86. package/dist/adapters/oclif/commands/sources/get.d.mts +6 -0
  87. package/dist/adapters/oclif/commands/sources/get.mjs +8 -0
  88. package/dist/adapters/oclif/commands/sources/list-streams.d.mts +6 -0
  89. package/dist/adapters/oclif/commands/sources/list-streams.mjs +31 -0
  90. package/dist/adapters/oclif/commands/sources/list.d.mts +6 -0
  91. package/dist/adapters/oclif/commands/sources/list.mjs +13 -0
  92. package/dist/adapters/oclif/commands/{integrations/get.d.mts → sources/update.d.mts} +4 -4
  93. package/dist/adapters/oclif/commands/sources/update.mjs +21 -0
  94. package/dist/adapters/oclif/commands/status.d.mts +27 -0
  95. package/dist/adapters/oclif/commands/status.mjs +77 -0
  96. package/dist/adapters/oclif/commands/table-views/create.mjs +3 -2
  97. package/dist/adapters/oclif/commands/table-views/delete.mjs +1 -1
  98. package/dist/adapters/oclif/commands/table-views/list.mjs +3 -2
  99. package/dist/adapters/oclif/commands/table-views/update.mjs +1 -1
  100. package/dist/adapters/oclif/commands/tables/create.mjs +1 -1
  101. package/dist/adapters/oclif/commands/tables/delete.mjs +1 -1
  102. package/dist/adapters/oclif/commands/tables/get.mjs +1 -1
  103. package/dist/adapters/oclif/commands/tables/list.mjs +3 -2
  104. package/dist/adapters/oclif/commands/tables/update.mjs +1 -1
  105. package/dist/{base.command-d7VW6WTp.d.mts → base.command-BmddDbHa.d.mts} +4 -1
  106. package/dist/base.command-D8taHOFF.mjs +83 -0
  107. package/dist/chunk-CfYAbeIz.mjs +13 -0
  108. package/dist/context-D5uelKLe.d.mts +62 -0
  109. package/dist/core-B-IdeRNl.mjs +2448 -0
  110. package/dist/{factory-BrFKT8t-.mjs → factory-CCcimDhl.mjs} +45 -10
  111. package/dist/iac-render-BSZZEP0n.mjs +17 -0
  112. package/dist/index-D0ax2I61.d.mts +581 -0
  113. package/dist/index.d.mts +4 -4
  114. package/dist/index.mjs +2 -2
  115. package/dist/{presets-D9b6IWKy.mjs → presets-Bb9gwgeh.mjs} +40 -8
  116. package/dist/templates/.claude/settings.json +39 -0
  117. package/dist/templates/.devcontainer/Dockerfile +9 -0
  118. package/dist/templates/.devcontainer/devcontainer.json +4 -1
  119. package/dist/templates/.devcontainer/setup.sh +3 -0
  120. package/dist/templates/AGENTS.md +33 -20
  121. package/dist/templates/dbt/dbt_project.yml +2 -2
  122. package/dist/templates/gitignore +3 -1
  123. package/dist/templates/skills/create-connections/SKILL.md +210 -0
  124. package/dist/templates/skills/create-connections/references/mappers.md +152 -0
  125. package/dist/templates/skills/{create-semantic-model → create-cubes}/SKILL.md +20 -18
  126. package/dist/templates/skills/create-cubes/references/bq-pk-fk-conventions.md +183 -0
  127. package/dist/templates/skills/{create-semantic-model → create-cubes}/references/cube-examples.md +2 -2
  128. package/dist/templates/skills/create-cubes/references/hubspot-entities.md +289 -0
  129. package/dist/templates/skills/create-cubes/references/jira-entities.md +201 -0
  130. package/dist/templates/skills/create-cubes/references/netsuite-entities.md +121 -0
  131. package/dist/templates/skills/create-cubes/references/stripe-entities.md +114 -0
  132. package/dist/templates/skills/create-dbt-transformations/SKILL.md +43 -22
  133. package/dist/templates/skills/create-dbt-transformations/references/edge-cases.md +20 -2
  134. package/dist/templates/skills/create-dbt-transformations/references/schema-conventions.md +21 -7
  135. package/dist/templates/skills/create-dbt-transformations/references/sql-templates.md +34 -20
  136. package/dist/templates/skills/explore-lakehouse/SKILL.md +3 -3
  137. package/dist/templates/skills/load-sample-data/SKILL.md +1 -1
  138. package/dist/templates/skills/visualize-semantic-model/SKILL.md +159 -0
  139. package/dist/templates/skills/visualize-semantic-model/scripts/render_graph.py +186 -0
  140. package/dist/{types-Y_ht_ja5.d.mts → types-Bk2Cb5yt.d.mts} +9 -0
  141. package/package.json +44 -7
  142. package/dist/adapters/oclif/commands/integrations/create.d.mts +0 -11
  143. package/dist/adapters/oclif/commands/integrations/create.mjs +0 -16
  144. package/dist/adapters/oclif/commands/integrations/get.mjs +0 -21
  145. package/dist/adapters/oclif/commands/integrations/list.d.mts +0 -11
  146. package/dist/adapters/oclif/commands/integrations/list.mjs +0 -16
  147. package/dist/adapters/oclif/commands/integrations/update.d.mts +0 -15
  148. package/dist/adapters/oclif/commands/integrations/update.mjs +0 -21
  149. package/dist/adapters/oclif/commands/overlays/diff.d.mts +0 -19
  150. package/dist/adapters/oclif/commands/overlays/diff.mjs +0 -80
  151. package/dist/adapters/oclif/commands/overlays/pull.d.mts +0 -15
  152. package/dist/adapters/oclif/commands/overlays/pull.mjs +0 -45
  153. package/dist/adapters/oclif/commands/overlays/push.d.mts +0 -18
  154. package/dist/adapters/oclif/commands/overlays/push.mjs +0 -59
  155. package/dist/adapters/oclif/commands/overlays/status.d.mts +0 -18
  156. package/dist/adapters/oclif/commands/overlays/status.mjs +0 -53
  157. package/dist/base.command-YiwlGlKs.mjs +0 -62
  158. package/dist/core-jpFPylBb.mjs +0 -997
  159. package/dist/index-DD2Vr-pu.d.mts +0 -193
  160. package/dist/types-C_p_6rkj.d.mts +0 -69
  161. /package/dist/templates/skills/{create-semantic-model → create-cubes}/references/key-patterns.md +0 -0
  162. /package/dist/templates/skills/{create-semantic-model → create-cubes}/references/validation-queries.md +0 -0
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env python3
2
+ """Render a Cube.dev semantic model graph to a PNG.
3
+
4
+ Reads a JSON spec from stdin (see SKILL.md for the schema) and writes a dark-themed
5
+ directed-graph PNG to --output. Layout is automatic: the fact spine sits centered;
6
+ dimensions are evenly distributed in a ring around it.
7
+ """
8
+
9
+ import argparse
10
+ import json
11
+ import math
12
+ import sys
13
+
14
+ import matplotlib
15
+
16
+ matplotlib.use("Agg")
17
+ import matplotlib.pyplot as plt
18
+ from matplotlib.patches import FancyBboxPatch
19
+
20
+ INDIGO = "#6366f1"
21
+ SKY = "#0ea5e9"
22
+ BG = "#0f1117"
23
+ NODE_FILL = "#1e293b"
24
+ TITLE_FG = "#f1f5f9"
25
+ SUB_FG = "#94a3b8"
26
+ LEGEND_FG = "#64748b"
27
+
28
+ W, H = 13.0, 7.0
29
+ SPINE_CENTER = (W / 2, H / 2)
30
+ DIM_RADIUS_X = 4.6
31
+ DIM_RADIUS_Y = 2.2
32
+
33
+
34
+ def draw_node(ax, cx, cy, w, h, title, subtitle_lines, tag, border, tag_color):
35
+ box = FancyBboxPatch(
36
+ (cx - w / 2, cy - h / 2), w, h,
37
+ boxstyle="round,pad=0.05", linewidth=2,
38
+ edgecolor=border, facecolor=NODE_FILL, zorder=3,
39
+ )
40
+ ax.add_patch(box)
41
+ ax.text(cx, cy + h / 2 - 0.28, tag, ha="center", va="top",
42
+ fontsize=7.5, fontweight="bold", color=tag_color,
43
+ fontfamily="monospace", zorder=4)
44
+ ax.text(cx, cy + 0.12, title, ha="center", va="center",
45
+ fontsize=9.5, fontweight="bold", color=TITLE_FG, zorder=4)
46
+ for i, line in enumerate(subtitle_lines):
47
+ ax.text(cx, cy - 0.32 - i * 0.32, line, ha="center", va="center",
48
+ fontsize=8, color=SUB_FG, zorder=4)
49
+
50
+
51
+ def draw_edge(ax, x1, y1, x2, y2, label, from_card, to_card, color):
52
+ ax.annotate(
53
+ "", xy=(x2, y2), xytext=(x1, y1),
54
+ arrowprops=dict(arrowstyle="->", color=color, lw=1.8,
55
+ connectionstyle="arc3,rad=0.0"),
56
+ zorder=2,
57
+ )
58
+ mx, my = (x1 + x2) / 2, (y1 + y2) / 2
59
+ dx, dy = x2 - x1, y2 - y1
60
+ length = math.hypot(-dy, dx) or 1.0
61
+ ox, oy = -dy / length * 0.22, dx / length * 0.22
62
+ ax.text(mx + ox, my + oy, label, ha="center", va="center",
63
+ fontsize=7.5, color=LEGEND_FG, zorder=4)
64
+ # cardinality markers near each endpoint
65
+ ax.text(x1 + dx * 0.08, y1 + dy * 0.08 + 0.18, from_card,
66
+ ha="center", va="center", fontsize=11, fontweight="bold",
67
+ color=SUB_FG, zorder=5)
68
+ ax.text(x2 - dx * 0.08, y2 - dy * 0.08 + 0.18, to_card,
69
+ ha="center", va="center", fontsize=11, fontweight="bold",
70
+ color=SUB_FG, zorder=5)
71
+
72
+
73
+ def fact_subtitle_lines(spine):
74
+ lines = [f"PK: {spine['pk']}"] if spine.get("pk") else []
75
+ fks = spine.get("fks") or []
76
+ # pack FKs two per line
77
+ for i in range(0, len(fks), 2):
78
+ chunk = fks[i:i + 2]
79
+ lines.append("FK: " + " · ".join(chunk))
80
+ return lines
81
+
82
+
83
+ def dim_subtitle_lines(dim):
84
+ lines = []
85
+ if dim.get("pk"):
86
+ lines.append(f"PK: {dim['pk']}")
87
+ if dim.get("extras"):
88
+ lines.append(" · ".join(dim["extras"]))
89
+ return lines
90
+
91
+
92
+ def dim_position(i, n):
93
+ # Distribute dims evenly around an ellipse centered on the spine.
94
+ # Start from the left (angle = π) and go clockwise so a single dim sits left.
95
+ angle = math.pi - (2 * math.pi * i / n)
96
+ cx = SPINE_CENTER[0] + DIM_RADIUS_X * math.cos(angle)
97
+ cy = SPINE_CENTER[1] + DIM_RADIUS_Y * math.sin(angle)
98
+ return cx, cy
99
+
100
+
101
+ def edge_endpoints(src, dst, src_w=3.0, src_h=1.6, dst_w=3.2, dst_h=2.0):
102
+ # Stop the arrow at the bounding boxes so it doesn't overlap node text.
103
+ sx, sy = src
104
+ dx, dy = dst
105
+ vx, vy = dx - sx, dy - sy
106
+ length = math.hypot(vx, vy) or 1.0
107
+ ux, uy = vx / length, vy / length
108
+ # rough rectangular inset — works fine for the box sizes we use
109
+ src_inset = max(src_w / 2 * abs(ux), src_h / 2 * abs(uy))
110
+ dst_inset = max(dst_w / 2 * abs(ux), dst_h / 2 * abs(uy))
111
+ return (sx + ux * src_inset, sy + uy * src_inset,
112
+ dx - ux * dst_inset, dy - uy * dst_inset)
113
+
114
+
115
+ def render(spec, output_path):
116
+ fig, ax = plt.subplots(figsize=(W, H))
117
+ fig.patch.set_facecolor(BG)
118
+ ax.set_facecolor(BG)
119
+ ax.set_xlim(0, W)
120
+ ax.set_ylim(0, H)
121
+ ax.axis("off")
122
+
123
+ spine = spec["fact_spine"]
124
+ dims = spec.get("dimensions", [])
125
+ edges = spec.get("edges", [])
126
+
127
+ # nodes
128
+ draw_node(ax, *SPINE_CENTER, 3.2, 2.0,
129
+ spine["name"], fact_subtitle_lines(spine),
130
+ "FACT SPINE", INDIGO, "#818cf8")
131
+
132
+ positions = {spine["name"]: SPINE_CENTER}
133
+ n = max(len(dims), 1)
134
+ for i, dim in enumerate(dims):
135
+ cx, cy = dim_position(i, n)
136
+ positions[dim["name"]] = (cx, cy)
137
+ draw_node(ax, cx, cy, 3.0, 1.6,
138
+ dim["name"], dim_subtitle_lines(dim),
139
+ "DIMENSION", SKY, "#38bdf8")
140
+
141
+ # edges
142
+ for e in edges:
143
+ src = positions.get(e["from"])
144
+ dst = positions.get(e["to"])
145
+ if not src or not dst:
146
+ continue
147
+ x1, y1, x2, y2 = edge_endpoints(src, dst)
148
+ draw_edge(ax, x1, y1, x2, y2,
149
+ e.get("label", ""),
150
+ e.get("from_card", "1"),
151
+ e.get("to_card", "∞"),
152
+ SKY)
153
+
154
+ # title
155
+ ax.text(W / 2, H - 0.3, spec.get("title", "Semantic Model"),
156
+ ha="center", va="center", fontsize=12,
157
+ fontweight="bold", color="#e2e8f0")
158
+
159
+ # legend
160
+ for i, (col, lbl) in enumerate([(INDIGO, "Fact spine"),
161
+ (SKY, "Dimension / edge")]):
162
+ lx = 4.0 + i * 2.8
163
+ ax.plot([lx, lx + 0.5], [0.35, 0.35], color=col, lw=2.5)
164
+ ax.text(lx + 0.65, 0.35, lbl, va="center", fontsize=8, color=LEGEND_FG)
165
+ ax.text(10.5, 0.35, "1 = one side ∞ = many side",
166
+ va="center", fontsize=8, color=LEGEND_FG)
167
+
168
+ plt.tight_layout(pad=0.3)
169
+ plt.savefig(output_path, dpi=160, bbox_inches="tight", facecolor=BG)
170
+ print(f"Saved: {output_path}")
171
+
172
+
173
+ def main():
174
+ parser = argparse.ArgumentParser(description=__doc__)
175
+ parser.add_argument("--output", required=True, help="Path to write the PNG.")
176
+ parser.add_argument("--input", default="-",
177
+ help="JSON spec path, or '-' for stdin (default).")
178
+ args = parser.parse_args()
179
+
180
+ raw = sys.stdin.read() if args.input == "-" else open(args.input).read()
181
+ spec = json.loads(raw)
182
+ render(spec, args.output)
183
+
184
+
185
+ if __name__ == "__main__":
186
+ main()
@@ -8,6 +8,9 @@ interface StoredCredentials {
8
8
  userId?: string;
9
9
  email?: string;
10
10
  organizationId?: string;
11
+ apiUrl?: string;
12
+ authUrl?: string;
13
+ authClientId?: string;
11
14
  }
12
15
  interface AuthResult {
13
16
  success: boolean;
@@ -24,6 +27,12 @@ interface AuthStatusInfo {
24
27
  credentialsPath?: string;
25
28
  organizationId?: string;
26
29
  organizationName?: string;
30
+ project?: {
31
+ name?: string;
32
+ path: string;
33
+ orgId: string;
34
+ inSyncWithGlobal: boolean;
35
+ };
27
36
  }
28
37
  type OrganizationInfo = OrganizationResponseDto["data"];
29
38
  interface OrgListResult {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revos/cli",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "RevOS CLI for managing RevOS platform resources",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,11 +30,44 @@
30
30
  "org": {
31
31
  "description": "Organization management commands"
32
32
  },
33
- "overlays": {
34
- "description": "Manage Cube overlays"
33
+ "sources": {
34
+ "description": "Manage data sources (list/get/delete via API; create/update open RevOS UI)"
35
35
  },
36
- "integrations": {
37
- "description": "Manage integrations (opens RevOS UI)"
36
+ "tables": {
37
+ "description": "Manage tables (scoring models)"
38
+ },
39
+ "table-views": {
40
+ "description": "Manage table views"
41
+ },
42
+ "cubes": {
43
+ "description": "Manage Cube.dev semantic models"
44
+ },
45
+ "connections": {
46
+ "description": "Manage Connections (syncs from Sources to BigQuery)"
47
+ },
48
+ "scores": {
49
+ "description": "Manage scores attached to a scoring model"
50
+ },
51
+ "score-groups": {
52
+ "description": "Manage score groups"
53
+ },
54
+ "segments": {
55
+ "description": "Manage segments and their evaluation history"
56
+ },
57
+ "actions": {
58
+ "description": "Inspect actions and their input/params schemas"
59
+ },
60
+ "action-runs": {
61
+ "description": "Inspect action run history"
62
+ },
63
+ "ai-instructions": {
64
+ "description": "Manage AI instructions"
65
+ },
66
+ "gservice-accounts": {
67
+ "description": "Manage Google service accounts"
68
+ },
69
+ "gservice-account-keys": {
70
+ "description": "Manage Google service account keys"
38
71
  }
39
72
  }
40
73
  },
@@ -44,15 +77,19 @@
44
77
  "LICENSE"
45
78
  ],
46
79
  "dependencies": {
80
+ "@dagrejs/graphlib": "^2.2.4",
47
81
  "@inquirer/search": "^4.1.7",
48
82
  "@inquirer/select": "^4.4.2",
49
83
  "@oclif/core": "^4.2.10",
50
84
  "@oclif/plugin-warn-if-update-available": "^3.1.61",
51
85
  "@oclif/table": "^0.5.4",
52
86
  "chalk": "^4.1.2",
87
+ "microdiff": "^1.5.0",
53
88
  "open": "^10.1.0",
54
89
  "yaml": "^2.8.3",
55
- "@revos/api-client": "0.1.0"
90
+ "zod": "^4.3.5",
91
+ "zod-validation-error": "^4.0.1",
92
+ "@revos/api-client": "0.1.1"
56
93
  },
57
94
  "devDependencies": {
58
95
  "@swc/core": "^1.7.26",
@@ -61,7 +98,7 @@
61
98
  "@types/node": "^22.5.4",
62
99
  "jest": "^29.7.0",
63
100
  "tsdown": "^0.21.9",
64
- "typescript": "^5.7.2",
101
+ "typescript": "^5.9.0",
65
102
  "@revos/config-eslint": "0.0.0"
66
103
  },
67
104
  "publishConfig": {
@@ -1,11 +0,0 @@
1
- import { t as BaseCommand } from "../../../../base.command-d7VW6WTp.mjs";
2
-
3
- //#region src/adapters/oclif/commands/integrations/create.d.ts
4
- declare class IntegrationsCreate extends BaseCommand<typeof IntegrationsCreate> {
5
- static description: string;
6
- run(): Promise<{
7
- url: string;
8
- }>;
9
- }
10
- //#endregion
11
- export { IntegrationsCreate as default };
@@ -1,16 +0,0 @@
1
- import { b as getConfig, h as resolveAppUrl } from "../../../../core-jpFPylBb.mjs";
2
- import { t as BaseCommand } from "../../../../base.command-YiwlGlKs.mjs";
3
- import chalk from "chalk";
4
- import open from "open";
5
- //#region src/adapters/oclif/commands/integrations/create.ts
6
- var IntegrationsCreate = class extends BaseCommand {
7
- static description = "Open the RevOS UI to create a new integration (data source)";
8
- async run() {
9
- const url = `${resolveAppUrl((await getConfig()).apiUrl)}/integrations?action=new`;
10
- if (!this.jsonEnabled()) this.log(`Opening ${chalk.bold(url)} in your browser...`);
11
- await open(url);
12
- return { url };
13
- }
14
- };
15
- //#endregion
16
- export { IntegrationsCreate as default };
@@ -1,21 +0,0 @@
1
- import { b as getConfig, h as resolveAppUrl } from "../../../../core-jpFPylBb.mjs";
2
- import { t as BaseCommand } from "../../../../base.command-YiwlGlKs.mjs";
3
- import chalk from "chalk";
4
- import { Args } from "@oclif/core";
5
- import open from "open";
6
- //#region src/adapters/oclif/commands/integrations/get.ts
7
- var IntegrationsGet = class extends BaseCommand {
8
- static description = "Open a specific integration in the RevOS UI";
9
- static args = { id: Args.string({
10
- description: "Integration ID",
11
- required: true
12
- }) };
13
- async run() {
14
- const url = `${resolveAppUrl((await getConfig()).apiUrl)}/integrations/${this.args.id}`;
15
- if (!this.jsonEnabled()) this.log(`Opening ${chalk.bold(url)} in your browser...`);
16
- await open(url);
17
- return { url };
18
- }
19
- };
20
- //#endregion
21
- export { IntegrationsGet as default };
@@ -1,11 +0,0 @@
1
- import { t as BaseCommand } from "../../../../base.command-d7VW6WTp.mjs";
2
-
3
- //#region src/adapters/oclif/commands/integrations/list.d.ts
4
- declare class IntegrationsList extends BaseCommand<typeof IntegrationsList> {
5
- static description: string;
6
- run(): Promise<{
7
- url: string;
8
- }>;
9
- }
10
- //#endregion
11
- export { IntegrationsList as default };
@@ -1,16 +0,0 @@
1
- import { b as getConfig, h as resolveAppUrl } from "../../../../core-jpFPylBb.mjs";
2
- import { t as BaseCommand } from "../../../../base.command-YiwlGlKs.mjs";
3
- import chalk from "chalk";
4
- import open from "open";
5
- //#region src/adapters/oclif/commands/integrations/list.ts
6
- var IntegrationsList = class extends BaseCommand {
7
- static description = "Open the integrations page in the RevOS UI";
8
- async run() {
9
- const url = `${resolveAppUrl((await getConfig()).apiUrl)}/integrations`;
10
- if (!this.jsonEnabled()) this.log(`Opening ${chalk.bold(url)} in your browser...`);
11
- await open(url);
12
- return { url };
13
- }
14
- };
15
- //#endregion
16
- export { IntegrationsList as default };
@@ -1,15 +0,0 @@
1
- import { t as BaseCommand } from "../../../../base.command-d7VW6WTp.mjs";
2
- import * as _$_oclif_core_interfaces0 from "@oclif/core/interfaces";
3
-
4
- //#region src/adapters/oclif/commands/integrations/update.d.ts
5
- declare class IntegrationsUpdate extends BaseCommand<typeof IntegrationsUpdate> {
6
- static description: string;
7
- static args: {
8
- id: _$_oclif_core_interfaces0.Arg<string, Record<string, unknown>>;
9
- };
10
- run(): Promise<{
11
- url: string;
12
- }>;
13
- }
14
- //#endregion
15
- export { IntegrationsUpdate as default };
@@ -1,21 +0,0 @@
1
- import { b as getConfig, h as resolveAppUrl } from "../../../../core-jpFPylBb.mjs";
2
- import { t as BaseCommand } from "../../../../base.command-YiwlGlKs.mjs";
3
- import chalk from "chalk";
4
- import { Args } from "@oclif/core";
5
- import open from "open";
6
- //#region src/adapters/oclif/commands/integrations/update.ts
7
- var IntegrationsUpdate = class extends BaseCommand {
8
- static description = "Open the RevOS UI to edit an existing integration";
9
- static args = { id: Args.string({
10
- description: "Integration ID",
11
- required: true
12
- }) };
13
- async run() {
14
- const url = `${resolveAppUrl((await getConfig()).apiUrl)}/integrations?action=edit&id=${this.args.id}`;
15
- if (!this.jsonEnabled()) this.log(`Opening ${chalk.bold(url)} in your browser...`);
16
- await open(url);
17
- return { url };
18
- }
19
- };
20
- //#endregion
21
- export { IntegrationsUpdate as default };
@@ -1,19 +0,0 @@
1
- import { o as DiffResult } from "../../../../types-C_p_6rkj.mjs";
2
- import { t as BaseCommand } from "../../../../base.command-d7VW6WTp.mjs";
3
- import * as _$_oclif_core_interfaces0 from "@oclif/core/interfaces";
4
-
5
- //#region src/adapters/oclif/commands/overlays/diff.d.ts
6
- declare class OverlaysDiff extends BaseCommand<typeof OverlaysDiff> {
7
- static description: string;
8
- static flags: {
9
- dir: _$_oclif_core_interfaces0.OptionFlag<string, _$_oclif_core_interfaces0.CustomOptions>;
10
- };
11
- static args: {
12
- files: _$_oclif_core_interfaces0.Arg<string[] | undefined, Record<string, unknown>>;
13
- };
14
- run(): Promise<DiffResult>;
15
- private renderEntry;
16
- private renderDataDiff;
17
- }
18
- //#endregion
19
- export { OverlaysDiff as default };
@@ -1,80 +0,0 @@
1
- import { b as getConfig, p as createApiClient, r as DiffService } from "../../../../core-jpFPylBb.mjs";
2
- import { t as BaseCommand } from "../../../../base.command-YiwlGlKs.mjs";
3
- import chalk from "chalk";
4
- import { Args, Flags } from "@oclif/core";
5
- //#region src/adapters/oclif/commands/overlays/diff.ts
6
- var OverlaysDiff = class extends BaseCommand {
7
- static description = "Show differences between local files and remote overlays";
8
- static flags = { dir: Flags.string({
9
- char: "d",
10
- description: "Directory containing overlay files",
11
- default: "./semantic"
12
- }) };
13
- static args = { files: Args.string({
14
- description: "Specific files to diff (optional)",
15
- required: false,
16
- multiple: true
17
- }) };
18
- async run() {
19
- const { flags, args } = this;
20
- const files = args.files ?? [];
21
- const result = await new DiffService({ api: createApiClient(await getConfig()) }).execute({
22
- dir: flags.dir,
23
- files: files.length > 0 ? files : void 0
24
- });
25
- if (!this.jsonEnabled()) {
26
- if (result.entries.length === 0) {
27
- this.warn("No overlay files found.");
28
- return result;
29
- }
30
- for (const entry of result.entries) this.renderEntry(entry);
31
- this.log("");
32
- }
33
- return result;
34
- }
35
- renderEntry(entry) {
36
- this.log(chalk.bold(`\n${entry.name}:`));
37
- if (entry.isRemoteOnly) {
38
- this.log(chalk.red(" - Exists only on remote (not in local files)"));
39
- return;
40
- }
41
- if (entry.isSynced) {
42
- this.log(chalk.gray(" No changes"));
43
- return;
44
- }
45
- if (entry.isNew) {
46
- this.log(chalk.green("+ New overlay (will be created)"));
47
- for (const change of entry.changes) if (change.field === "data") {
48
- this.log(chalk.green(` ${change.field}:`));
49
- for (const line of (change.newValue ?? "").split(/\r?\n/)) this.log(chalk.green(` ${line}`));
50
- } else this.log(chalk.green(` ${change.field}: ${change.newValue}`));
51
- return;
52
- }
53
- for (const change of entry.changes) if (change.field === "data") {
54
- this.log(chalk.yellow(" ~ data: (modified)"));
55
- this.renderDataDiff(change.oldValue ?? "", change.newValue ?? "");
56
- } else {
57
- this.log(chalk.red(` - ${change.field}: ${change.oldValue}`));
58
- this.log(chalk.green(` + ${change.field}: ${change.newValue}`));
59
- }
60
- }
61
- renderDataDiff(oldValue, newValue) {
62
- const oldLines = oldValue.split(/\r?\n/);
63
- const newLines = newValue.split(/\r?\n/);
64
- const maxLines = Math.max(oldLines.length, newLines.length);
65
- const maxDiffLines = 20;
66
- let diffCount = 0;
67
- for (let i = 0; i < maxLines && diffCount < maxDiffLines; i++) {
68
- const oldLine = oldLines[i] ?? "";
69
- const newLine = newLines[i] ?? "";
70
- if (oldLine !== newLine) {
71
- if (oldLine) this.log(chalk.red(` - ${oldLine}`));
72
- if (newLine) this.log(chalk.green(` + ${newLine}`));
73
- diffCount++;
74
- }
75
- }
76
- if (diffCount >= maxDiffLines) this.log(chalk.gray(` ... (${maxLines - maxDiffLines} more lines)`));
77
- }
78
- };
79
- //#endregion
80
- export { OverlaysDiff as default };
@@ -1,15 +0,0 @@
1
- import { u as PullResult } from "../../../../types-C_p_6rkj.mjs";
2
- import { t as BaseCommand } from "../../../../base.command-d7VW6WTp.mjs";
3
- import * as _$_oclif_core_interfaces0 from "@oclif/core/interfaces";
4
-
5
- //#region src/adapters/oclif/commands/overlays/pull.d.ts
6
- declare class OverlaysPull extends BaseCommand<typeof OverlaysPull> {
7
- static description: string;
8
- static flags: {
9
- dir: _$_oclif_core_interfaces0.OptionFlag<string, _$_oclif_core_interfaces0.CustomOptions>;
10
- name: _$_oclif_core_interfaces0.OptionFlag<string[] | undefined, _$_oclif_core_interfaces0.CustomOptions>;
11
- };
12
- run(): Promise<PullResult>;
13
- }
14
- //#endregion
15
- export { OverlaysPull as default };
@@ -1,45 +0,0 @@
1
- import { a as PullService, b as getConfig, p as createApiClient } from "../../../../core-jpFPylBb.mjs";
2
- import { t as BaseCommand } from "../../../../base.command-YiwlGlKs.mjs";
3
- import * as os from "os";
4
- import chalk from "chalk";
5
- import { Flags } from "@oclif/core";
6
- //#region src/adapters/oclif/commands/overlays/pull.ts
7
- var OverlaysPull = class extends BaseCommand {
8
- static description = "Pull overlays from RevOS API to local files";
9
- static flags = {
10
- dir: Flags.string({
11
- char: "d",
12
- description: "Directory to save overlay files",
13
- default: "./semantic"
14
- }),
15
- name: Flags.string({
16
- char: "n",
17
- description: "Specific overlay names to pull",
18
- multiple: true
19
- })
20
- };
21
- async run() {
22
- const { flags } = this;
23
- const result = await new PullService({ api: createApiClient(await getConfig()) }).execute({
24
- dir: flags.dir,
25
- names: flags.name
26
- });
27
- if (!this.jsonEnabled()) {
28
- if (result.pulled.length === 0 && result.notFound.length === 0) {
29
- this.warn("No overlays to pull.");
30
- return result;
31
- }
32
- if (result.notFound.length > 0) this.warn(`The following overlays were not found:${os.EOL}${result.notFound.map((n) => ` - ${n}`).join(os.EOL)}`);
33
- for (const item of result.pulled) this.log(chalk.green(`↓ Pulled: ${item.name} → ${item.filePath}`));
34
- for (const e of result.errors) this.log(chalk.red(`✗ Error saving ${e.name}: ${e.error}`));
35
- this.log("");
36
- this.log(chalk.bold("Summary:"));
37
- this.log(chalk.green(` Pulled: ${result.pulled.length}`));
38
- if (result.errors.length > 0) this.log(chalk.red(` Errors: ${result.errors.length}`));
39
- }
40
- if (result.errors.length > 0) this.exit(1);
41
- return result;
42
- }
43
- };
44
- //#endregion
45
- export { OverlaysPull as default };
@@ -1,18 +0,0 @@
1
- import { d as PushResult } from "../../../../types-C_p_6rkj.mjs";
2
- import { t as BaseCommand } from "../../../../base.command-d7VW6WTp.mjs";
3
- import * as _$_oclif_core_interfaces0 from "@oclif/core/interfaces";
4
-
5
- //#region src/adapters/oclif/commands/overlays/push.d.ts
6
- declare class OverlaysPush extends BaseCommand<typeof OverlaysPush> {
7
- static description: string;
8
- static flags: {
9
- dir: _$_oclif_core_interfaces0.OptionFlag<string, _$_oclif_core_interfaces0.CustomOptions>;
10
- force: _$_oclif_core_interfaces0.BooleanFlag<boolean>;
11
- };
12
- static args: {
13
- files: _$_oclif_core_interfaces0.Arg<string[] | undefined, Record<string, unknown>>;
14
- };
15
- run(): Promise<PushResult>;
16
- }
17
- //#endregion
18
- export { OverlaysPush as default };
@@ -1,59 +0,0 @@
1
- import { b as getConfig, o as PushService, p as createApiClient } from "../../../../core-jpFPylBb.mjs";
2
- import { t as BaseCommand } from "../../../../base.command-YiwlGlKs.mjs";
3
- import chalk from "chalk";
4
- import { Args, Flags } from "@oclif/core";
5
- //#region src/adapters/oclif/commands/overlays/push.ts
6
- var OverlaysPush = class extends BaseCommand {
7
- static description = "Push overlay files to RevOS API";
8
- static flags = {
9
- dir: Flags.string({
10
- char: "d",
11
- description: "Directory containing overlay files",
12
- default: "./semantic"
13
- }),
14
- force: Flags.boolean({
15
- char: "f",
16
- description: "Force push even if remote is newer",
17
- default: false
18
- })
19
- };
20
- static args = { files: Args.string({
21
- description: "Specific files to push (optional)",
22
- required: false,
23
- multiple: true
24
- }) };
25
- async run() {
26
- const { flags, args } = this;
27
- const files = args.files ?? [];
28
- const result = await new PushService({ api: createApiClient(await getConfig()) }).execute({
29
- dir: flags.dir,
30
- force: flags.force,
31
- files: files.length > 0 ? files : void 0
32
- });
33
- if (!this.jsonEnabled()) {
34
- if (result.created.length === 0 && result.updated.length === 0 && result.conflicts.length === 0 && result.errors.length === 0) {
35
- this.warn("No overlay files found.");
36
- return result;
37
- }
38
- const remoteOnlyConflicts = result.conflicts.filter((c) => c.reason === "exists remotely but not locally");
39
- if (remoteOnlyConflicts.length > 0) {
40
- for (const c of remoteOnlyConflicts) this.log(chalk.red(` - ${c.name}`));
41
- this.error("The following overlays exist remotely but not locally. Run 'revos overlays pull' first.", { exit: 1 });
42
- }
43
- for (const name of result.created) this.log(chalk.green(`+ Created: ${name}`));
44
- for (const name of result.updated) this.log(chalk.blue(`~ Updated: ${name}`));
45
- for (const c of result.conflicts) this.log(chalk.yellow(`! Conflict: ${c.name} - ${c.reason}`));
46
- for (const e of result.errors) this.log(chalk.red(`✗ Error: ${e.name} - ${e.error}`));
47
- this.log("");
48
- this.log(chalk.bold("Summary:"));
49
- if (result.created.length > 0) this.log(chalk.green(` Created: ${result.created.length}`));
50
- if (result.updated.length > 0) this.log(chalk.blue(` Updated: ${result.updated.length}`));
51
- if (result.conflicts.length > 0) this.log(chalk.yellow(` Conflicts: ${result.conflicts.length}`));
52
- if (result.errors.length > 0) this.log(chalk.red(` Errors: ${result.errors.length}`));
53
- }
54
- if (result.errors.length > 0 || result.conflicts.length > 0) this.exit(1);
55
- return result;
56
- }
57
- };
58
- //#endregion
59
- export { OverlaysPush as default };