@revos/cli 0.2.3 → 0.3.1
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.
- package/README.md +42 -4
- package/dist/adapters/oclif/commands/action-runs/get.mjs +1 -1
- package/dist/adapters/oclif/commands/action-runs/list.mjs +1 -1
- package/dist/adapters/oclif/commands/actions/get-input-schema.mjs +2 -2
- package/dist/adapters/oclif/commands/actions/get-params-schema.mjs +2 -2
- package/dist/adapters/oclif/commands/actions/get.mjs +1 -1
- package/dist/adapters/oclif/commands/actions/list.mjs +2 -2
- package/dist/adapters/oclif/commands/ai-instructions/create.mjs +1 -1
- package/dist/adapters/oclif/commands/ai-instructions/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/ai-instructions/get.mjs +1 -1
- package/dist/adapters/oclif/commands/ai-instructions/list.mjs +1 -1
- package/dist/adapters/oclif/commands/ai-instructions/update.mjs +1 -1
- package/dist/adapters/oclif/commands/api.mjs +2 -2
- package/dist/adapters/oclif/commands/apply.d.mts +1 -1
- package/dist/adapters/oclif/commands/apply.mjs +2 -2
- package/dist/adapters/oclif/commands/auth/login.mjs +13 -28
- package/dist/adapters/oclif/commands/auth/logout.mjs +2 -2
- package/dist/adapters/oclif/commands/auth/status.mjs +2 -2
- package/dist/adapters/oclif/commands/connections/create.mjs +1 -1
- package/dist/adapters/oclif/commands/connections/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/connections/get.mjs +1 -1
- package/dist/adapters/oclif/commands/connections/list.mjs +1 -1
- package/dist/adapters/oclif/commands/connections/update.mjs +1 -1
- package/dist/adapters/oclif/commands/cubes/create.mjs +1 -1
- package/dist/adapters/oclif/commands/cubes/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/cubes/get.mjs +1 -1
- package/dist/adapters/oclif/commands/cubes/list.mjs +1 -1
- package/dist/adapters/oclif/commands/cubes/meta.d.mts +6 -0
- package/dist/adapters/oclif/commands/cubes/meta.mjs +45 -0
- package/dist/adapters/oclif/commands/cubes/query.d.mts +6 -0
- package/dist/adapters/oclif/commands/cubes/query.mjs +51 -0
- package/dist/adapters/oclif/commands/cubes/update.mjs +1 -1
- package/dist/adapters/oclif/commands/diff.d.mts +1 -1
- package/dist/adapters/oclif/commands/diff.mjs +2 -2
- package/dist/adapters/oclif/commands/gservice-account-keys/get.mjs +1 -1
- package/dist/adapters/oclif/commands/gservice-account-keys/reveal.mjs +2 -2
- package/dist/adapters/oclif/commands/gservice-accounts/create.mjs +1 -1
- package/dist/adapters/oclif/commands/gservice-accounts/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/gservice-accounts/get.mjs +1 -1
- package/dist/adapters/oclif/commands/gservice-accounts/list.mjs +1 -1
- package/dist/adapters/oclif/commands/init.d.mts +2 -0
- package/dist/adapters/oclif/commands/init.mjs +92 -4
- package/dist/adapters/oclif/commands/org/create.mjs +1 -1
- package/dist/adapters/oclif/commands/org/current.mjs +2 -2
- package/dist/adapters/oclif/commands/org/get.mjs +1 -1
- package/dist/adapters/oclif/commands/org/list.mjs +2 -2
- package/dist/adapters/oclif/commands/org/switch.mjs +2 -2
- package/dist/adapters/oclif/commands/pull.d.mts +1 -1
- package/dist/adapters/oclif/commands/pull.mjs +2 -2
- package/dist/adapters/oclif/commands/score-groups/create.mjs +1 -1
- package/dist/adapters/oclif/commands/score-groups/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/score-groups/get.mjs +1 -1
- package/dist/adapters/oclif/commands/score-groups/list.mjs +1 -1
- package/dist/adapters/oclif/commands/score-groups/update.mjs +1 -1
- package/dist/adapters/oclif/commands/scores/create.mjs +1 -1
- package/dist/adapters/oclif/commands/scores/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/scores/list.mjs +1 -1
- package/dist/adapters/oclif/commands/scores/update.mjs +1 -1
- package/dist/adapters/oclif/commands/segments/create.mjs +1 -1
- package/dist/adapters/oclif/commands/segments/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/segments/evaluate.mjs +2 -2
- package/dist/adapters/oclif/commands/segments/get-evaluation-history.mjs +2 -2
- package/dist/adapters/oclif/commands/segments/get-version.mjs +2 -2
- package/dist/adapters/oclif/commands/segments/get.mjs +1 -1
- package/dist/adapters/oclif/commands/segments/list-versions.mjs +2 -2
- package/dist/adapters/oclif/commands/segments/list.mjs +1 -1
- package/dist/adapters/oclif/commands/segments/restore-version.mjs +2 -2
- package/dist/adapters/oclif/commands/segments/update.mjs +1 -1
- package/dist/adapters/oclif/commands/sources/create.mjs +2 -2
- package/dist/adapters/oclif/commands/sources/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/sources/get.mjs +1 -1
- package/dist/adapters/oclif/commands/sources/list-streams.mjs +2 -2
- package/dist/adapters/oclif/commands/sources/list.mjs +1 -1
- package/dist/adapters/oclif/commands/sources/update.mjs +2 -2
- package/dist/adapters/oclif/commands/status.d.mts +1 -1
- package/dist/adapters/oclif/commands/status.mjs +3 -3
- package/dist/adapters/oclif/commands/table-views/create.mjs +1 -1
- package/dist/adapters/oclif/commands/table-views/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/table-views/list.mjs +1 -1
- package/dist/adapters/oclif/commands/table-views/update.mjs +1 -1
- package/dist/adapters/oclif/commands/tables/create.mjs +1 -1
- package/dist/adapters/oclif/commands/tables/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/tables/get.mjs +1 -1
- package/dist/adapters/oclif/commands/tables/list.mjs +1 -1
- package/dist/adapters/oclif/commands/tables/update.mjs +1 -1
- package/dist/{base.command-D8taHOFF.mjs → base.command-CnVb4RG6.mjs} +1 -1
- package/dist/{core-B-IdeRNl.mjs → core-CY9pC37x.mjs} +68 -5
- package/dist/{factory-CCcimDhl.mjs → factory-DTqayaCF.mjs} +2 -2
- package/dist/{index-D0ax2I61.d.mts → index-Cbb9pLt6.d.mts} +26 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{presets-Bb9gwgeh.mjs → presets-mJzFGMhG.mjs} +2 -2
- package/dist/templates/.devcontainer/Dockerfile +8 -0
- package/dist/templates/.devcontainer/devcontainer.json +10 -9
- package/dist/templates/.devcontainer/post-create.sh +46 -0
- package/dist/templates/.devcontainer/post-start.sh +61 -0
- package/dist/templates/.devcontainer/welcome.sh +26 -0
- package/dist/templates/README.md +80 -12
- package/package.json +1 -1
- package/dist/templates/.devcontainer/setup.sh +0 -35
|
@@ -25,6 +25,7 @@ declare class ApiError extends Error {
|
|
|
25
25
|
//#endregion
|
|
26
26
|
//#region src/core/config.d.ts
|
|
27
27
|
declare const DEFAULT_API_URL = "https://api.revos.ai";
|
|
28
|
+
declare function resolveApiUrl(): string;
|
|
28
29
|
declare function getConfig(): Promise<Config>;
|
|
29
30
|
//#endregion
|
|
30
31
|
//#region src/core/auth/credentials-store.d.ts
|
|
@@ -78,6 +79,18 @@ declare function getUserInfo(accessToken: string): Promise<ClerkUserInfo>;
|
|
|
78
79
|
declare function tokenResponseToCredentials(tokenResponse: TokenResponse, userInfo: ClerkUserInfo): StoredCredentials;
|
|
79
80
|
declare function refreshAccessToken(refreshToken: string): Promise<TokenResponse>;
|
|
80
81
|
//#endregion
|
|
82
|
+
//#region src/core/auth/oauth-flow.d.ts
|
|
83
|
+
interface PerformOAuthLoginOptions {
|
|
84
|
+
apiUrl: string;
|
|
85
|
+
organizationId?: string;
|
|
86
|
+
log?: (msg: string) => void;
|
|
87
|
+
}
|
|
88
|
+
interface PerformOAuthLoginResult {
|
|
89
|
+
credentials: StoredCredentials;
|
|
90
|
+
userInfo: ClerkUserInfo;
|
|
91
|
+
}
|
|
92
|
+
declare function performOAuthLogin(opts: PerformOAuthLoginOptions): Promise<PerformOAuthLoginResult>;
|
|
93
|
+
//#endregion
|
|
81
94
|
//#region src/core/utils.d.ts
|
|
82
95
|
declare function formatError(error: unknown): string;
|
|
83
96
|
declare function sanitizeFileName(name: string): string;
|
|
@@ -559,6 +572,16 @@ interface InitResult {
|
|
|
559
572
|
createdFiles: string[];
|
|
560
573
|
pulledIac: PullResult;
|
|
561
574
|
}
|
|
575
|
+
interface EnsureGcpKeyOptions {
|
|
576
|
+
apiUrl: string;
|
|
577
|
+
token: string;
|
|
578
|
+
organization: OrganizationInfo;
|
|
579
|
+
projectSlug: string;
|
|
580
|
+
}
|
|
581
|
+
interface EnsureGcpKeyResult {
|
|
582
|
+
keyPath: string;
|
|
583
|
+
status: "exists" | "created";
|
|
584
|
+
}
|
|
562
585
|
declare class InitService {
|
|
563
586
|
private readonly templatesDir;
|
|
564
587
|
private static readonly PROJECT_DIRS;
|
|
@@ -567,6 +590,8 @@ declare class InitService {
|
|
|
567
590
|
run(options: InitOptions): Promise<InitResult>;
|
|
568
591
|
private pullIacResources;
|
|
569
592
|
resolveOrganization(apiUrl: string, token: string, organizationId?: string): Promise<OrganizationInfo>;
|
|
593
|
+
static gcpKeyPath(projectSlug: string): string;
|
|
594
|
+
ensureGcpKey(options: EnsureGcpKeyOptions): Promise<EnsureGcpKeyResult>;
|
|
570
595
|
private downloadGcpKey;
|
|
571
596
|
dryRun(projectDir: string): {
|
|
572
597
|
projectDir: string;
|
|
@@ -578,4 +603,4 @@ declare class InitService {
|
|
|
578
603
|
private renderTemplate;
|
|
579
604
|
}
|
|
580
605
|
//#endregion
|
|
581
|
-
export {
|
|
606
|
+
export { getUserInfo as A, loadCredentials as B, AuthConfig as C, exchangeCodeForTokens as D, buildAuthorizationUrl as E, OAuthServerResult as F, ApiError as G, DEFAULT_API_URL as H, startOAuthServer as I, Config as K, deleteCredentials as L, setAuthConfig as M, setAuthEnv as N, generatePKCEChallenge as O, tokenResponseToCredentials as P, getCredentialsPath as R, AUTH_ENVS as S, PKCEChallenge as T, getConfig as U, saveCredentials as V, resolveApiUrl as W, formatError as _, formatEnvMismatchError as a, PerformOAuthLoginResult as b, renderProjectContextLine as c, PulledResource as d, AppliedResource as f, resolveAppUrl as g, unwrap as h, formatCredentialsMismatchWarning as i, refreshAccessToken as j, getActiveAuthConfig as k, index_d_exports as l, createApiClient as m, InitResult as n, formatInProjectSwitchWarning as o, ApiClient as p, InitService as r, formatProjectOrgFlagError as s, InitOptions as t, ResourceStatus as u, sanitizeFileName as v, AuthEnv as w, performOAuthLogin as x, PerformOAuthLoginOptions as y, isTokenExpired as z };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as getUserInfo, B as loadCredentials, C as AuthConfig, D as exchangeCodeForTokens, E as buildAuthorizationUrl, F as OAuthServerResult, G as ApiError, H as DEFAULT_API_URL, I as startOAuthServer, K as Config, L as deleteCredentials, M as setAuthConfig, N as setAuthEnv, O as generatePKCEChallenge, P as tokenResponseToCredentials, R as getCredentialsPath, S as AUTH_ENVS, T as PKCEChallenge, U as getConfig, V as saveCredentials, W as resolveApiUrl, _ as formatError, a as formatEnvMismatchError, b as PerformOAuthLoginResult, c as renderProjectContextLine, g as resolveAppUrl, h as unwrap, i as formatCredentialsMismatchWarning, j as refreshAccessToken, k as getActiveAuthConfig, l as index_d_exports, m as createApiClient, n as InitResult, o as formatInProjectSwitchWarning, p as ApiClient, r as InitService, s as formatProjectOrgFlagError, t as InitOptions, v as sanitizeFileName, w as AuthEnv, x as performOAuthLogin, y as PerformOAuthLoginOptions, z as isTokenExpired } from "./index-Cbb9pLt6.mjs";
|
|
2
2
|
import { a as OrgListResult, c as StoredCredentials, i as OAuthCallbackResult, l as TokenResponse, n as AuthStatusInfo, o as OrgSwitchResult, r as ClerkUserInfo, s as OrganizationInfo, t as AuthResult } from "./types-Bk2Cb5yt.mjs";
|
|
3
3
|
import { a as validateEnvAgainstProject, i as resolveProjectContext, n as ProjectContext, r as isInsideProject, t as EnvMismatch } from "./context-D5uelKLe.mjs";
|
|
4
|
-
export { AUTH_ENVS, ApiClient, ApiError, AuthConfig, AuthEnv, AuthResult, AuthStatusInfo, ClerkUserInfo, Config, DEFAULT_API_URL, EnvMismatch, InitOptions, InitResult, InitService, OAuthCallbackResult, OAuthServerResult, OrgListResult, OrgSwitchResult, OrganizationInfo, PKCEChallenge, ProjectContext, StoredCredentials, TokenResponse, buildAuthorizationUrl, createApiClient, deleteCredentials, exchangeCodeForTokens, formatCredentialsMismatchWarning, formatEnvMismatchError, formatError, formatInProjectSwitchWarning, formatProjectOrgFlagError, generatePKCEChallenge, getActiveAuthConfig, getConfig, getCredentialsPath, getUserInfo, index_d_exports as iac, isInsideProject, isTokenExpired, loadCredentials, refreshAccessToken, renderProjectContextLine, resolveAppUrl, resolveProjectContext, sanitizeFileName, saveCredentials, setAuthConfig, setAuthEnv, startOAuthServer, tokenResponseToCredentials, unwrap, validateEnvAgainstProject };
|
|
4
|
+
export { AUTH_ENVS, ApiClient, ApiError, AuthConfig, AuthEnv, AuthResult, AuthStatusInfo, ClerkUserInfo, Config, DEFAULT_API_URL, EnvMismatch, InitOptions, InitResult, InitService, OAuthCallbackResult, OAuthServerResult, OrgListResult, OrgSwitchResult, OrganizationInfo, PKCEChallenge, PerformOAuthLoginOptions, PerformOAuthLoginResult, ProjectContext, StoredCredentials, TokenResponse, buildAuthorizationUrl, createApiClient, deleteCredentials, exchangeCodeForTokens, formatCredentialsMismatchWarning, formatEnvMismatchError, formatError, formatInProjectSwitchWarning, formatProjectOrgFlagError, generatePKCEChallenge, getActiveAuthConfig, getConfig, getCredentialsPath, getUserInfo, index_d_exports as iac, isInsideProject, isTokenExpired, loadCredentials, performOAuthLogin, refreshAccessToken, renderProjectContextLine, resolveApiUrl, resolveAppUrl, resolveProjectContext, sanitizeFileName, saveCredentials, setAuthConfig, setAuthEnv, startOAuthServer, tokenResponseToCredentials, unwrap, validateEnvAgainstProject };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { AUTH_ENVS, ApiError, DEFAULT_API_URL, InitService, buildAuthorizationUrl, createApiClient, deleteCredentials, exchangeCodeForTokens, formatCredentialsMismatchWarning, formatEnvMismatchError, formatError, formatInProjectSwitchWarning, formatProjectOrgFlagError, generatePKCEChallenge, getActiveAuthConfig, getConfig, getCredentialsPath, getUserInfo, iac_exports as iac, isInsideProject, isTokenExpired, loadCredentials, refreshAccessToken, renderProjectContextLine, resolveAppUrl, resolveProjectContext, sanitizeFileName, saveCredentials, setAuthConfig, setAuthEnv, startOAuthServer, tokenResponseToCredentials, unwrap, validateEnvAgainstProject };
|
|
1
|
+
import { A as buildAuthorizationUrl, B as deleteCredentials, C as formatError, D as resolveApiUrl, E as getConfig, F as refreshAccessToken, G as ApiError, H as isTokenExpired, I as setAuthConfig, L as setAuthEnv, M as generatePKCEChallenge, N as getActiveAuthConfig, O as performOAuthLogin, P as getUserInfo, R as tokenResponseToCredentials, S as resolveAppUrl, T as DEFAULT_API_URL, U as loadCredentials, V as getCredentialsPath, W as saveCredentials, a as formatInProjectSwitchWarning, b as createApiClient, c as isInsideProject, d as iac_exports, i as formatEnvMismatchError, j as exchangeCodeForTokens, k as AUTH_ENVS, l as resolveProjectContext, o as formatProjectOrgFlagError, r as formatCredentialsMismatchWarning, s as renderProjectContextLine, t as InitService, u as validateEnvAgainstProject, w as sanitizeFileName, x as unwrap, z as startOAuthServer } from "./core-CY9pC37x.mjs";
|
|
2
|
+
export { AUTH_ENVS, ApiError, DEFAULT_API_URL, InitService, buildAuthorizationUrl, createApiClient, deleteCredentials, exchangeCodeForTokens, formatCredentialsMismatchWarning, formatEnvMismatchError, formatError, formatInProjectSwitchWarning, formatProjectOrgFlagError, generatePKCEChallenge, getActiveAuthConfig, getConfig, getCredentialsPath, getUserInfo, iac_exports as iac, isInsideProject, isTokenExpired, loadCredentials, performOAuthLogin, refreshAccessToken, renderProjectContextLine, resolveApiUrl, resolveAppUrl, resolveProjectContext, sanitizeFileName, saveCredentials, setAuthConfig, setAuthEnv, startOAuthServer, tokenResponseToCredentials, unwrap, validateEnvAgainstProject };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { x as unwrap } from "./core-
|
|
2
|
-
import { n as createListRender, r as defineApiCommand, t as bodyFlag } from "./factory-
|
|
1
|
+
import { x as unwrap } from "./core-CY9pC37x.mjs";
|
|
2
|
+
import { n as createListRender, r as defineApiCommand, t as bodyFlag } from "./factory-DTqayaCF.mjs";
|
|
3
3
|
import { Args, Flags } from "@oclif/core";
|
|
4
4
|
//#region src/adapters/oclif/presets.ts
|
|
5
5
|
function camelToKebab(s) {
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
FROM mcr.microsoft.com/devcontainers/python:3.13
|
|
2
2
|
|
|
3
|
+
# jq is used by .devcontainer/welcome.sh + post-start.sh to parse
|
|
4
|
+
# `revos auth status --json`.
|
|
5
|
+
# It usually ships in the base image via common-debian.sh, but install
|
|
6
|
+
# explicitly so this gate doesn't silently break on a future base bump.
|
|
7
|
+
RUN apt-get update -q \
|
|
8
|
+
&& apt-get install -y --no-install-recommends jq \
|
|
9
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
10
|
+
|
|
3
11
|
# Pre-install dbt so it's available before VS Code extensions activate
|
|
4
12
|
# (cryptography<47 avoids Illegal instruction on ARM)
|
|
5
13
|
RUN pip install --quiet dbt-bigquery "cryptography<47"
|
|
@@ -14,25 +14,26 @@
|
|
|
14
14
|
},
|
|
15
15
|
"containerEnv": {
|
|
16
16
|
"DBT_PROJECT_DIR": "${containerWorkspaceFolder}/dbt",
|
|
17
|
-
"GOOGLE_APPLICATION_CREDENTIALS": "/home/vscode/.revos
|
|
17
|
+
"GOOGLE_APPLICATION_CREDENTIALS": "/home/vscode/.revos/<%=projectSlug%>-gsa-creds.json",
|
|
18
18
|
"GOOGLE_CLOUD_PROJECT": "<%=bqProjectId%>",
|
|
19
19
|
"REVOS_BQ_DATASET": "<%=bqDataset%>",
|
|
20
20
|
"REVOS_ORG_ID": "<%=organizationId%>"
|
|
21
21
|
},
|
|
22
|
-
"postCreateCommand": "bash .devcontainer/
|
|
22
|
+
"postCreateCommand": "bash .devcontainer/post-create.sh",
|
|
23
|
+
"postStartCommand": "bash .devcontainer/post-start.sh",
|
|
23
24
|
"mounts": [
|
|
24
25
|
{
|
|
25
|
-
"source": "
|
|
26
|
-
"target": "/
|
|
27
|
-
"type": "
|
|
26
|
+
"source": "revos-<%=projectSlug%>-credentials",
|
|
27
|
+
"target": "/home/vscode/.revos",
|
|
28
|
+
"type": "volume"
|
|
28
29
|
},
|
|
29
30
|
{
|
|
30
|
-
"source": "
|
|
31
|
-
"target": "/
|
|
32
|
-
"type": "
|
|
31
|
+
"source": "revos-<%=projectSlug%>-gcloud",
|
|
32
|
+
"target": "/home/vscode/.config/gcloud",
|
|
33
|
+
"type": "volume"
|
|
33
34
|
},
|
|
34
35
|
{
|
|
35
|
-
"source": "claude
|
|
36
|
+
"source": "revos-<%=projectSlug%>-claude",
|
|
36
37
|
"target": "/home/vscode/.claude",
|
|
37
38
|
"type": "volume"
|
|
38
39
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Named volumes mount as root-owned by default. We use three per-project
|
|
5
|
+
# volumes (~/.revos, ~/.config/gcloud, ~/.claude) instead of one whole-home
|
|
6
|
+
# volume because VS Code's server install writes to ~/.vscode-server before
|
|
7
|
+
# postCreateCommand runs, and there's no clean lifecycle hook to fix
|
|
8
|
+
# ownership early enough for a whole-home mount.
|
|
9
|
+
sudo chown -R vscode:vscode /home/vscode/.revos 2>/dev/null || true
|
|
10
|
+
sudo chown -R vscode:vscode /home/vscode/.config/gcloud 2>/dev/null || true
|
|
11
|
+
sudo chown -R vscode:vscode /home/vscode/.claude 2>/dev/null || true
|
|
12
|
+
mkdir -p "$HOME/.revos" "$HOME/.config/gcloud"
|
|
13
|
+
|
|
14
|
+
# Install RevOS CLI
|
|
15
|
+
npm install -g @revos/cli
|
|
16
|
+
|
|
17
|
+
# Best-effort gcloud activation. Usually a no-op on first container create
|
|
18
|
+
# (user hasn't run `revos init` yet, no key file), but covers the case
|
|
19
|
+
# where the credentials volume was preserved across a recreate. After this,
|
|
20
|
+
# the gcloud auth state lives in the persisted ~/.config/gcloud volume, so
|
|
21
|
+
# subsequent rebuilds don't need re-activation. `revos init` itself also
|
|
22
|
+
# activates when it provisions a new key.
|
|
23
|
+
KEY="${GOOGLE_APPLICATION_CREDENTIALS:-}"
|
|
24
|
+
if [ -n "$KEY" ] && [ -s "$KEY" ]; then
|
|
25
|
+
gcloud auth activate-service-account --key-file="$KEY" >/dev/null 2>&1 || true
|
|
26
|
+
if [ -n "${GOOGLE_CLOUD_PROJECT:-}" ]; then
|
|
27
|
+
gcloud config set project "$GOOGLE_CLOUD_PROJECT" >/dev/null 2>&1 || true
|
|
28
|
+
fi
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Symlink dbt profiles so `dbt run` works without --profiles-dir
|
|
32
|
+
mkdir -p "$HOME/.dbt"
|
|
33
|
+
ln -sf "$(pwd)/dbt/profiles.yml" "$HOME/.dbt/profiles.yml"
|
|
34
|
+
|
|
35
|
+
# Install the onboarding-banner welcome check. We copy it into ~/.revos so
|
|
36
|
+
# it survives outside the workspace mount, and source it from ~/.bashrc so
|
|
37
|
+
# it prints at the top of every interactive terminal — instead of being
|
|
38
|
+
# buried under postStartCommand logs in the "Dev Containers" output panel.
|
|
39
|
+
# The script self-clears once auth + key exist.
|
|
40
|
+
cp .devcontainer/welcome.sh "$HOME/.revos/welcome.sh"
|
|
41
|
+
|
|
42
|
+
if ! grep -qF 'source ~/.revos/welcome.sh' "$HOME/.bashrc" 2>/dev/null; then
|
|
43
|
+
echo '' >> "$HOME/.bashrc"
|
|
44
|
+
echo '# RevOS dev-container onboarding banner (auto-clears once set up)' >> "$HOME/.bashrc"
|
|
45
|
+
echo 'source ~/.revos/welcome.sh' >> "$HOME/.bashrc"
|
|
46
|
+
fi
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Runs on every container start (postStartCommand). Pure information —
|
|
5
|
+
# either SETUP REQUIRED (with next steps) or READY (with environment debug
|
|
6
|
+
# info). Important for users who open Claude Code directly and never touch
|
|
7
|
+
# a terminal where welcome.sh would otherwise print the gate.
|
|
8
|
+
#
|
|
9
|
+
# gcloud activation lives in post-create.sh (one-time) and inside `revos
|
|
10
|
+
# init` (when a new key is provisioned). The persisted ~/.config/gcloud
|
|
11
|
+
# named volume keeps the activation state across rebuilds, so this script
|
|
12
|
+
# doesn't need to re-activate on every start.
|
|
13
|
+
|
|
14
|
+
need_setup=false
|
|
15
|
+
|
|
16
|
+
if command -v revos >/dev/null 2>&1; then
|
|
17
|
+
if ! revos auth status --json 2>/dev/null | jq -e '.authenticated' >/dev/null 2>&1; then
|
|
18
|
+
need_setup=true
|
|
19
|
+
fi
|
|
20
|
+
if [ ! -s "$HOME/.revos/<%=projectSlug%>-gsa-creds.json" ]; then
|
|
21
|
+
need_setup=true
|
|
22
|
+
fi
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if $need_setup; then
|
|
26
|
+
echo ""
|
|
27
|
+
echo "████████████████████████████████████████████████████████████████████████"
|
|
28
|
+
echo "█ █"
|
|
29
|
+
echo "█ ⚠ REVOS DEV CONTAINER — SETUP REQUIRED █"
|
|
30
|
+
echo "█ █"
|
|
31
|
+
echo "█ Open a terminal and run: █"
|
|
32
|
+
echo "█ █"
|
|
33
|
+
echo "█ revos init █"
|
|
34
|
+
echo "█ █"
|
|
35
|
+
echo "████████████████████████████████████████████████████████████████████████"
|
|
36
|
+
echo ""
|
|
37
|
+
else
|
|
38
|
+
# Setup is complete — print a confirmation banner with environment debug
|
|
39
|
+
# info. Useful for users who never open a terminal, and as a quick
|
|
40
|
+
# reference when troubleshooting "is my container looking at the right
|
|
41
|
+
# project / dataset / org?".
|
|
42
|
+
user_email=$(revos auth status --json 2>/dev/null | jq -r '.email // "(unknown)"')
|
|
43
|
+
gcloud_account=$(gcloud config get-value account 2>/dev/null || true)
|
|
44
|
+
gcloud_account=${gcloud_account:-(none)}
|
|
45
|
+
gcloud_project=$(gcloud config get-value project 2>/dev/null || true)
|
|
46
|
+
gcloud_project=${gcloud_project:-${GOOGLE_CLOUD_PROJECT:-(none)}}
|
|
47
|
+
|
|
48
|
+
echo ""
|
|
49
|
+
echo "████████████████████████████████████████████████████████████████████████"
|
|
50
|
+
echo "█ █"
|
|
51
|
+
echo "█ ✓ REVOS DEV CONTAINER — READY █"
|
|
52
|
+
echo "█ █"
|
|
53
|
+
printf "█ RevOS user: %-51s █\n" "${user_email:0:51}"
|
|
54
|
+
printf "█ GCP account: %-51s █\n" "${gcloud_account:0:51}"
|
|
55
|
+
printf "█ GCP project: %-51s █\n" "${gcloud_project:0:51}"
|
|
56
|
+
printf "█ BQ dataset: %-51s █\n" "${REVOS_BQ_DATASET:-(unset)}"
|
|
57
|
+
printf "█ Org ID: %-51s █\n" "${REVOS_ORG_ID:-(unset)}"
|
|
58
|
+
echo "█ █"
|
|
59
|
+
echo "████████████████████████████████████████████████████████████████████████"
|
|
60
|
+
echo ""
|
|
61
|
+
fi
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# RevOS dev-container welcome check. Sourced from ~/.bashrc on every
|
|
2
|
+
# interactive shell. Silent once `revos auth status` is authenticated and
|
|
3
|
+
# the GSA key file is present. `revos init` handles both — it signs you in
|
|
4
|
+
# via the browser if needed, then provisions the GSA key.
|
|
5
|
+
__revos_need_setup=false
|
|
6
|
+
|
|
7
|
+
if ! command -v revos >/dev/null 2>&1; then
|
|
8
|
+
return 0
|
|
9
|
+
fi
|
|
10
|
+
if ! revos auth status --json 2>/dev/null | jq -e '.authenticated' >/dev/null 2>&1; then
|
|
11
|
+
__revos_need_setup=true
|
|
12
|
+
fi
|
|
13
|
+
if [ ! -s "$HOME/.revos/<%=projectSlug%>-gsa-creds.json" ]; then
|
|
14
|
+
__revos_need_setup=true
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
if $__revos_need_setup; then
|
|
18
|
+
echo ""
|
|
19
|
+
echo "============================================================"
|
|
20
|
+
echo " Welcome to <%=projectName%> dev container!"
|
|
21
|
+
echo " To finish setup, run:"
|
|
22
|
+
echo " revos init"
|
|
23
|
+
echo "============================================================"
|
|
24
|
+
echo ""
|
|
25
|
+
fi
|
|
26
|
+
unset __revos_need_setup
|
package/dist/templates/README.md
CHANGED
|
@@ -1,23 +1,91 @@
|
|
|
1
1
|
# <%=projectName%>
|
|
2
2
|
|
|
3
|
-
RevOS data engineering project for **<%=orgName
|
|
3
|
+
RevOS data engineering project for **<%=orgName%>**.
|
|
4
|
+
|
|
5
|
+
This project is designed to be opened in a Dev Container. All tooling — Python, Node, dbt, the Google Cloud CLI, the RevOS CLI, GitHub CLI, and Claude Code — comes pre-installed. The container is the supported development environment; you should rarely need to install anything on your host.
|
|
4
6
|
|
|
5
7
|
## Getting started
|
|
6
8
|
|
|
7
|
-
1. Open
|
|
8
|
-
|
|
9
|
+
1. **Open in VS Code** and click **Reopen in Container** when prompted. First open builds the image (~1–2 min); subsequent opens are instant.
|
|
10
|
+
|
|
11
|
+
2. **One-time setup inside the container.** Open a terminal and run:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
revos init # signs you in via browser (if needed), then provisions the BigQuery service account key
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`revos init` detects it's running inside an existing project, skips the org prompt and scaffolding, and just fills in the missing GCP key. If you aren't authenticated yet, it opens the browser for sign-in first — the org is taken from `revos.yaml`.
|
|
18
|
+
|
|
19
|
+
**You won't need to repeat this.** Credentials persist in per-project Docker volumes, so every future `Rebuild Container`, restart, or VS Code reopen lands in a fully-authenticated state — the container will print `REVOS DEV CONTAINER — READY` on every start.
|
|
20
|
+
|
|
21
|
+
3. **Verify everything is wired up.** Either look at the banner the container prints on every start (`REVOS DEV CONTAINER — READY` with your auth + GCP details), or run:
|
|
22
|
+
|
|
9
23
|
```bash
|
|
10
|
-
|
|
11
|
-
|
|
24
|
+
bq ls $REVOS_BQ_DATASET # list tables in your BigQuery dataset
|
|
25
|
+
dbt debug # confirm dbt connection
|
|
26
|
+
revos status # list local Connections/Cubes vs. the API
|
|
12
27
|
```
|
|
13
28
|
|
|
14
|
-
## Project
|
|
29
|
+
## Project layout
|
|
15
30
|
|
|
16
31
|
```
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
32
|
+
.
|
|
33
|
+
├── revos.yaml # binds this project to your RevOS org (do not edit)
|
|
34
|
+
├── connections/ # sync pipelines (RevOS-managed; one YAML per Connection)
|
|
35
|
+
├── cubes/ # Cube.dev semantic model definitions (one YAML per Cube)
|
|
36
|
+
├── dbt/
|
|
37
|
+
│ ├── dbt_project.yml
|
|
38
|
+
│ ├── profiles.yml # pre-configured for BigQuery via $GOOGLE_APPLICATION_CREDENTIALS
|
|
39
|
+
│ └── models/
|
|
40
|
+
│ ├── bronze/ # raw ingested data — declared as dbt sources in schema.yml
|
|
41
|
+
│ ├── silver/ # cleaned & conformed
|
|
42
|
+
│ └── gold/ # business-ready marts
|
|
43
|
+
├── .claude/ # AI companion config + pre-installed skills
|
|
44
|
+
├── .devcontainer/ # Dev Container definition
|
|
45
|
+
├── AGENTS.md # context for AI coding agents
|
|
46
|
+
└── CLAUDE.md # imports AGENTS.md
|
|
23
47
|
```
|
|
48
|
+
|
|
49
|
+
## Common workflows
|
|
50
|
+
|
|
51
|
+
| Task | Command |
|
|
52
|
+
| --------------------------------------------- | ------------------------------------ |
|
|
53
|
+
| List data sources available on RevOS | `revos sources list` |
|
|
54
|
+
| Add a new data source (opens RevOS UI) | `revos sources create` |
|
|
55
|
+
| Pull current Connections & Cubes from the API | `revos pull` |
|
|
56
|
+
| Push local YAML changes back to the API | `revos apply` |
|
|
57
|
+
| Preview drift before applying | `revos diff` |
|
|
58
|
+
| Run all dbt models | `dbt run` |
|
|
59
|
+
| Run dbt tests | `dbt test` |
|
|
60
|
+
| Inspect a BigQuery table | `bq head -n 5 $REVOS_BQ_DATASET.<t>` |
|
|
61
|
+
| Show all `revos` commands | `revos --help` |
|
|
62
|
+
|
|
63
|
+
## Working with Claude Code
|
|
64
|
+
|
|
65
|
+
This project ships pre-installed Claude skills under `.claude/skills/` for the common tasks:
|
|
66
|
+
|
|
67
|
+
- **`explore-lakehouse`** — survey your BigQuery datasets and tables.
|
|
68
|
+
- **`create-connections`** — author a Connection YAML from a Source's available streams.
|
|
69
|
+
- **`create-cubes`** — build Cube.dev semantic models from gold-layer tables.
|
|
70
|
+
- **`create-dbt-transformations`** — write bronze→silver→gold dbt models.
|
|
71
|
+
- **`load-sample-data`** — seed BigQuery with example data when the warehouse is empty.
|
|
72
|
+
- **`visualize-semantic-model`** — render the cube graph as an image.
|
|
73
|
+
|
|
74
|
+
Inside the container, ask Claude things like _"create a Connection for our Stripe source"_ or _"build a silver model for the orders table"_ and it will use the matching skill.
|
|
75
|
+
|
|
76
|
+
## Troubleshooting
|
|
77
|
+
|
|
78
|
+
- **Container shows `SETUP REQUIRED` banner.** Run `revos init` in the container terminal — it handles login automatically.
|
|
79
|
+
- **`bq` or `dbt` fails with auth errors.** Container's gcloud is not activated. Rebuild the container, or run `bash .devcontainer/post-start.sh` to re-activate.
|
|
80
|
+
- **Start from a clean slate.** Wipe the per-project Docker volumes from your host:
|
|
81
|
+
```bash
|
|
82
|
+
docker volume rm revos-<%=projectSlug%>-credentials \
|
|
83
|
+
revos-<%=projectSlug%>-gcloud \
|
|
84
|
+
revos-<%=projectSlug%>-claude
|
|
85
|
+
```
|
|
86
|
+
Then `Rebuild Container` and rerun step 2.
|
|
87
|
+
|
|
88
|
+
## Further reading
|
|
89
|
+
|
|
90
|
+
- RevOS CLI reference: <https://cli.revos.dev>
|
|
91
|
+
- This project's AI guidance: [`AGENTS.md`](./AGENTS.md)
|
package/package.json
CHANGED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
|
|
4
|
-
# Copy mounted GCP service account key to vscode user's home
|
|
5
|
-
if [ -f /tmp/.revos-gsa-creds.json ]; then
|
|
6
|
-
mkdir -p "$HOME/.revos"
|
|
7
|
-
cp /tmp/.revos-gsa-creds.json "$HOME/.revos/gsa-creds.json"
|
|
8
|
-
chmod 600 "$HOME/.revos/gsa-creds.json"
|
|
9
|
-
fi
|
|
10
|
-
|
|
11
|
-
# Copy mounted RevOS CLI credentials so revos commands work without re-login
|
|
12
|
-
if [ -f /tmp/.revos-credentials.json ]; then
|
|
13
|
-
mkdir -p "$HOME/.revos"
|
|
14
|
-
cp /tmp/.revos-credentials.json "$HOME/.revos/credentials.json"
|
|
15
|
-
chmod 600 "$HOME/.revos/credentials.json"
|
|
16
|
-
fi
|
|
17
|
-
|
|
18
|
-
# Configure gcloud with service account and project
|
|
19
|
-
GCP_KEY="$HOME/.revos/gsa-creds.json"
|
|
20
|
-
if [ -f "$GCP_KEY" ]; then
|
|
21
|
-
gcloud auth activate-service-account --key-file="$GCP_KEY"
|
|
22
|
-
fi
|
|
23
|
-
if [ -n "${GOOGLE_CLOUD_PROJECT:-}" ]; then
|
|
24
|
-
gcloud config set project "$GOOGLE_CLOUD_PROJECT"
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
# Fix Claude Code credentials permissions (volume is created as root)
|
|
28
|
-
sudo chown -R vscode:vscode /home/vscode/.claude 2>/dev/null || true
|
|
29
|
-
|
|
30
|
-
# Install RevOS CLI
|
|
31
|
-
npm install -g @revos/cli
|
|
32
|
-
|
|
33
|
-
# Symlink dbt profiles so `dbt run` works without --profiles-dir
|
|
34
|
-
mkdir -p "$HOME/.dbt"
|
|
35
|
-
ln -sf "$(pwd)/dbt/profiles.yml" "$HOME/.dbt/profiles.yml"
|