@vectorplane/ctrl-cli 0.1.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.
- package/LICENSE +21 -0
- package/README.md +167 -0
- package/bin/vp.js +12 -0
- package/dist/commands/bootstrap.d.ts +1 -0
- package/dist/commands/bootstrap.js +40 -0
- package/dist/commands/config.d.ts +1 -0
- package/dist/commands/config.js +96 -0
- package/dist/commands/context.d.ts +1 -0
- package/dist/commands/context.js +46 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +69 -0
- package/dist/commands/event.d.ts +1 -0
- package/dist/commands/event.js +65 -0
- package/dist/commands/login.d.ts +1 -0
- package/dist/commands/login.js +39 -0
- package/dist/commands/session.d.ts +1 -0
- package/dist/commands/session.js +110 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +46 -0
- package/dist/commands/sync.d.ts +1 -0
- package/dist/commands/sync.js +108 -0
- package/dist/commands/whoami.d.ts +1 -0
- package/dist/commands/whoami.js +32 -0
- package/dist/commands/workspace.d.ts +1 -0
- package/dist/commands/workspace.js +66 -0
- package/dist/core/api.d.ts +24 -0
- package/dist/core/api.js +190 -0
- package/dist/core/auth.d.ts +16 -0
- package/dist/core/auth.js +71 -0
- package/dist/core/cli.d.ts +9 -0
- package/dist/core/cli.js +66 -0
- package/dist/core/config.d.ts +31 -0
- package/dist/core/config.js +263 -0
- package/dist/core/constants.d.ts +22 -0
- package/dist/core/constants.js +78 -0
- package/dist/core/env.d.ts +2 -0
- package/dist/core/env.js +10 -0
- package/dist/core/errors.d.ts +18 -0
- package/dist/core/errors.js +37 -0
- package/dist/core/git.d.ts +2 -0
- package/dist/core/git.js +66 -0
- package/dist/core/logger.d.ts +8 -0
- package/dist/core/logger.js +52 -0
- package/dist/core/machine.d.ts +4 -0
- package/dist/core/machine.js +87 -0
- package/dist/core/queue.d.ts +14 -0
- package/dist/core/queue.js +62 -0
- package/dist/core/runtime.d.ts +13 -0
- package/dist/core/runtime.js +16 -0
- package/dist/core/serializer.d.ts +7 -0
- package/dist/core/serializer.js +31 -0
- package/dist/core/server.d.ts +10 -0
- package/dist/core/server.js +84 -0
- package/dist/core/session.d.ts +16 -0
- package/dist/core/session.js +35 -0
- package/dist/core/workspace-binding.d.ts +15 -0
- package/dist/core/workspace-binding.js +41 -0
- package/dist/core/workspace.d.ts +2 -0
- package/dist/core/workspace.js +121 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +97 -0
- package/dist/types/api.d.ts +61 -0
- package/dist/types/api.js +2 -0
- package/dist/types/auth.d.ts +36 -0
- package/dist/types/auth.js +2 -0
- package/dist/types/config.d.ts +58 -0
- package/dist/types/config.js +2 -0
- package/dist/types/machine.d.ts +49 -0
- package/dist/types/machine.js +2 -0
- package/dist/types/snapshot.d.ts +15 -0
- package/dist/types/snapshot.js +2 -0
- package/dist/types/workspace.d.ts +44 -0
- package/dist/types/workspace.js +2 -0
- package/package.json +61 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { access, readFile, readdir } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { constants as fsConstants } from "node:fs";
|
|
4
|
+
import { createStableHash } from "./serializer.js";
|
|
5
|
+
async function exists(filePath) {
|
|
6
|
+
try {
|
|
7
|
+
await access(filePath, fsConstants.F_OK);
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async function safeRead(filePath) {
|
|
15
|
+
try {
|
|
16
|
+
return await readFile(filePath, "utf8");
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return "";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function detectMonorepo(rootPath, packageJsonRaw) {
|
|
23
|
+
if (packageJsonRaw) {
|
|
24
|
+
try {
|
|
25
|
+
const pkg = JSON.parse(packageJsonRaw);
|
|
26
|
+
if (Array.isArray(pkg.workspaces) || (pkg.workspaces && typeof pkg.workspaces === "object")) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const topLevel = await readdir(rootPath, { withFileTypes: true });
|
|
35
|
+
return topLevel.some((entry) => entry.isDirectory() && ["packages", "apps", "libs"].includes(entry.name));
|
|
36
|
+
}
|
|
37
|
+
function deriveSignals(content) {
|
|
38
|
+
const combined = `${content.packageJsonRaw}\n${content.tsconfigRaw}\n${content.wranglerRaw}\n${content.readmeRaw}\n${content.docsRaw}`.toLowerCase();
|
|
39
|
+
return {
|
|
40
|
+
hasCloudflareWorkers: combined.includes("wrangler") || combined.includes("durable object") || combined.includes("cloudflare worker"),
|
|
41
|
+
hasTypeScript: combined.includes("typescript") || combined.includes("\"tsc\""),
|
|
42
|
+
hasNode: combined.includes("\"node\"") || combined.includes("package.json"),
|
|
43
|
+
suggestsControlPlane: combined.includes("control plane") || combined.includes("governança") || combined.includes("orquestração"),
|
|
44
|
+
usesQueues: combined.includes("queue"),
|
|
45
|
+
usesDurableObjects: combined.includes("durable object"),
|
|
46
|
+
usesD1: combined.includes("d1"),
|
|
47
|
+
usesKv: combined.includes("kv"),
|
|
48
|
+
usesR2: combined.includes("r2"),
|
|
49
|
+
usesRestApi: combined.includes("rest"),
|
|
50
|
+
usesMcp: combined.includes("mcp"),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export async function collectWorkspaceContext(cwd, git) {
|
|
54
|
+
const rootPath = git.rootPath ?? cwd;
|
|
55
|
+
const packageJsonPath = path.join(rootPath, "package.json");
|
|
56
|
+
const tsconfigPath = path.join(rootPath, "tsconfig.json");
|
|
57
|
+
const wranglerPath = path.join(rootPath, "wrangler.toml");
|
|
58
|
+
const readmePath = path.join(rootPath, "README.md");
|
|
59
|
+
const docsPath = path.join(rootPath, "docs");
|
|
60
|
+
const [packageJsonRaw, tsconfigRaw, wranglerRaw, readmeRaw] = await Promise.all([
|
|
61
|
+
safeRead(packageJsonPath),
|
|
62
|
+
safeRead(tsconfigPath),
|
|
63
|
+
safeRead(wranglerPath),
|
|
64
|
+
safeRead(readmePath),
|
|
65
|
+
]);
|
|
66
|
+
const docsEntries = await (async () => {
|
|
67
|
+
try {
|
|
68
|
+
const entries = await readdir(docsPath, { withFileTypes: true });
|
|
69
|
+
return entries.filter((entry) => entry.isFile()).map((entry) => entry.name).slice(0, 20).join("\n");
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return "";
|
|
73
|
+
}
|
|
74
|
+
})();
|
|
75
|
+
const filePresence = {
|
|
76
|
+
AGENT_MD: await exists(path.join(rootPath, "AGENT.md")) || await exists(path.join(rootPath, "AGENTS.md")),
|
|
77
|
+
CLAUDE_MD: await exists(path.join(rootPath, "CLAUDE.md")),
|
|
78
|
+
README_MD: await exists(readmePath),
|
|
79
|
+
PACKAGE_JSON: await exists(packageJsonPath),
|
|
80
|
+
TSCONFIG_JSON: await exists(tsconfigPath),
|
|
81
|
+
WRANGLER_TOML: await exists(wranglerPath),
|
|
82
|
+
DOCKER_COMPOSE_YML: await exists(path.join(rootPath, "docker-compose.yml")),
|
|
83
|
+
ENV_EXAMPLE: await exists(path.join(rootPath, ".env.example")),
|
|
84
|
+
};
|
|
85
|
+
const derived = deriveSignals({ packageJsonRaw, tsconfigRaw, wranglerRaw, readmeRaw, docsRaw: docsEntries });
|
|
86
|
+
const isMonorepo = await detectMonorepo(rootPath, packageJsonRaw);
|
|
87
|
+
const importantFiles = [
|
|
88
|
+
{ file: "README.md", present: filePresence.README_MD },
|
|
89
|
+
{ file: "package.json", present: filePresence.PACKAGE_JSON },
|
|
90
|
+
{ file: "tsconfig.json", present: filePresence.TSCONFIG_JSON },
|
|
91
|
+
{ file: "wrangler.toml", present: filePresence.WRANGLER_TOML },
|
|
92
|
+
{ file: "AGENT.md", present: filePresence.AGENT_MD },
|
|
93
|
+
{ file: "AGENTS.md", present: filePresence.AGENT_MD },
|
|
94
|
+
{ file: "CLAUDE.md", present: filePresence.CLAUDE_MD },
|
|
95
|
+
{ file: "docker-compose.yml", present: filePresence.DOCKER_COMPOSE_YML },
|
|
96
|
+
{ file: ".env.example", present: filePresence.ENV_EXAMPLE },
|
|
97
|
+
]
|
|
98
|
+
.filter((entry) => entry.present)
|
|
99
|
+
.map((entry) => entry.file)
|
|
100
|
+
.slice(0, 12);
|
|
101
|
+
const snapshotHash = createStableHash({
|
|
102
|
+
rootPath,
|
|
103
|
+
filePresence,
|
|
104
|
+
signals: { ...derived, isGitRepository: git.isRepository, isMonorepo },
|
|
105
|
+
git,
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
rootPath,
|
|
109
|
+
rootName: path.basename(rootPath),
|
|
110
|
+
collectedAt: new Date().toISOString(),
|
|
111
|
+
filePresence,
|
|
112
|
+
importantFiles,
|
|
113
|
+
signals: {
|
|
114
|
+
...derived,
|
|
115
|
+
isGitRepository: git.isRepository,
|
|
116
|
+
isMonorepo,
|
|
117
|
+
},
|
|
118
|
+
snapshotHash,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=workspace.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runCli(args: string[]): Promise<number>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
|
+
import { runBootstrapCommand } from "./commands/bootstrap.js";
|
|
5
|
+
import { runConfigCommand } from "./commands/config.js";
|
|
6
|
+
import { runContextCommand } from "./commands/context.js";
|
|
7
|
+
import { runDoctorCommand } from "./commands/doctor.js";
|
|
8
|
+
import { runEventCommand } from "./commands/event.js";
|
|
9
|
+
import { runLoginCommand } from "./commands/login.js";
|
|
10
|
+
import { runSessionCommand } from "./commands/session.js";
|
|
11
|
+
import { runStatusCommand } from "./commands/status.js";
|
|
12
|
+
import { runSyncCommand } from "./commands/sync.js";
|
|
13
|
+
import { runWhoAmICommand } from "./commands/whoami.js";
|
|
14
|
+
import { runWorkspaceCommand } from "./commands/workspace.js";
|
|
15
|
+
import { CLIError } from "./core/errors.js";
|
|
16
|
+
async function getCliVersion() {
|
|
17
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
18
|
+
const packagePath = path.resolve(path.dirname(currentFile), "../package.json");
|
|
19
|
+
const raw = await readFile(packagePath, "utf8");
|
|
20
|
+
const parsed = JSON.parse(raw);
|
|
21
|
+
return parsed.version ?? "0.0.0";
|
|
22
|
+
}
|
|
23
|
+
function printHelp() {
|
|
24
|
+
process.stdout.write("VectorPlane Ctrl CLI\n");
|
|
25
|
+
process.stdout.write("Uso: vp <comando>\n");
|
|
26
|
+
process.stdout.write("\n");
|
|
27
|
+
process.stdout.write("Comandos principais:\n");
|
|
28
|
+
process.stdout.write(" login\n");
|
|
29
|
+
process.stdout.write(" sync [--force]\n");
|
|
30
|
+
process.stdout.write(" status\n");
|
|
31
|
+
process.stdout.write(" whoami\n");
|
|
32
|
+
process.stdout.write(" doctor\n");
|
|
33
|
+
process.stdout.write(" config <profile|get|set>\n");
|
|
34
|
+
process.stdout.write(" workspace <current|use|resolve|clear>\n");
|
|
35
|
+
process.stdout.write(" session <check-in|heartbeat|check-out>\n");
|
|
36
|
+
process.stdout.write(" context [--snapshot|--delivery]\n");
|
|
37
|
+
process.stdout.write(" bootstrap\n");
|
|
38
|
+
process.stdout.write(" event send <name> [--payload '{...}']\n");
|
|
39
|
+
}
|
|
40
|
+
export async function runCli(args) {
|
|
41
|
+
const [command, ...rest] = args;
|
|
42
|
+
if (!command || command === "--help" || command === "-h") {
|
|
43
|
+
printHelp();
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
const cliVersion = await getCliVersion();
|
|
47
|
+
try {
|
|
48
|
+
switch (command) {
|
|
49
|
+
case "login":
|
|
50
|
+
return runLoginCommand(cliVersion, rest);
|
|
51
|
+
case "sync":
|
|
52
|
+
return runSyncCommand(cliVersion, rest);
|
|
53
|
+
case "status":
|
|
54
|
+
return runStatusCommand();
|
|
55
|
+
case "whoami":
|
|
56
|
+
return runWhoAmICommand(cliVersion);
|
|
57
|
+
case "doctor":
|
|
58
|
+
return runDoctorCommand(cliVersion);
|
|
59
|
+
case "config":
|
|
60
|
+
return runConfigCommand(rest);
|
|
61
|
+
case "workspace":
|
|
62
|
+
return runWorkspaceCommand(rest);
|
|
63
|
+
case "session":
|
|
64
|
+
return runSessionCommand(cliVersion, rest);
|
|
65
|
+
case "context":
|
|
66
|
+
return runContextCommand(cliVersion, rest);
|
|
67
|
+
case "bootstrap":
|
|
68
|
+
return runBootstrapCommand(cliVersion, rest);
|
|
69
|
+
case "event":
|
|
70
|
+
return runEventCommand(cliVersion, rest);
|
|
71
|
+
default:
|
|
72
|
+
throw new CLIError(`Comando desconhecido: ${command}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (error instanceof CLIError) {
|
|
77
|
+
process.stderr.write(`VectorPlane: ${error.message}\n`);
|
|
78
|
+
return 1;
|
|
79
|
+
}
|
|
80
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
81
|
+
process.stderr.write(`VectorPlane: ${message}\n`);
|
|
82
|
+
return 1;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const entryArg = process.argv[1];
|
|
86
|
+
if (entryArg && import.meta.url === pathToFileURL(entryArg).href) {
|
|
87
|
+
runCli(process.argv.slice(2))
|
|
88
|
+
.then((exitCode) => {
|
|
89
|
+
process.exitCode = exitCode;
|
|
90
|
+
})
|
|
91
|
+
.catch((error) => {
|
|
92
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
93
|
+
process.stderr.write(`VectorPlane: ${message}\n`);
|
|
94
|
+
process.exitCode = 1;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { SnapshotPayload } from "./snapshot.js";
|
|
2
|
+
export interface SyncRequest {
|
|
3
|
+
workspace: string;
|
|
4
|
+
command: "sync";
|
|
5
|
+
snapshot: SnapshotPayload;
|
|
6
|
+
hash: string;
|
|
7
|
+
sent_at: string;
|
|
8
|
+
}
|
|
9
|
+
export interface SyncResponse {
|
|
10
|
+
ok?: boolean;
|
|
11
|
+
workspace?: string;
|
|
12
|
+
received_at?: string;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface EventRequest {
|
|
16
|
+
workspace: string;
|
|
17
|
+
event: string;
|
|
18
|
+
payload: Record<string, unknown>;
|
|
19
|
+
sent_at: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ResolveWorkspaceRequest {
|
|
22
|
+
repoUrl: string;
|
|
23
|
+
orgId?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ResolveWorkspaceResponse {
|
|
26
|
+
id?: string;
|
|
27
|
+
workspaceId?: string;
|
|
28
|
+
slug?: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
repoUrl?: string | null;
|
|
31
|
+
[key: string]: unknown;
|
|
32
|
+
}
|
|
33
|
+
export interface AgentSessionRequest {
|
|
34
|
+
workspaceId: string;
|
|
35
|
+
agentName: string;
|
|
36
|
+
agentType: string;
|
|
37
|
+
clientName: string;
|
|
38
|
+
clientInstanceId: string;
|
|
39
|
+
repoUrl?: string;
|
|
40
|
+
branch?: string | null;
|
|
41
|
+
commitSha?: string | null;
|
|
42
|
+
metadata?: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
export interface AgentHeartbeatRequest {
|
|
45
|
+
sessionId: string;
|
|
46
|
+
clientInstanceId: string;
|
|
47
|
+
branch?: string | null;
|
|
48
|
+
commitSha?: string | null;
|
|
49
|
+
metadata?: Record<string, unknown>;
|
|
50
|
+
}
|
|
51
|
+
export interface AgentCheckoutRequest {
|
|
52
|
+
sessionId: string;
|
|
53
|
+
metadata?: Record<string, unknown>;
|
|
54
|
+
}
|
|
55
|
+
export interface AgentSessionResponse {
|
|
56
|
+
id?: string;
|
|
57
|
+
sessionId?: string;
|
|
58
|
+
status?: string;
|
|
59
|
+
workspaceId?: string;
|
|
60
|
+
[key: string]: unknown;
|
|
61
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { MachineContext, RuntimeContext } from "./machine.js";
|
|
2
|
+
export interface AuthCodeExchangeRequest {
|
|
3
|
+
code: string;
|
|
4
|
+
client: "vp-cli";
|
|
5
|
+
device: MachineContext;
|
|
6
|
+
runtime: RuntimeContext;
|
|
7
|
+
}
|
|
8
|
+
export interface AuthTokenExchangeResponse {
|
|
9
|
+
access_token: string;
|
|
10
|
+
refresh_token: string;
|
|
11
|
+
workspace: string;
|
|
12
|
+
expires_in: number;
|
|
13
|
+
token_type: string;
|
|
14
|
+
}
|
|
15
|
+
export interface RefreshTokenRequest {
|
|
16
|
+
refresh_token: string;
|
|
17
|
+
client: "vp-cli";
|
|
18
|
+
}
|
|
19
|
+
export interface CurrentUserResponse {
|
|
20
|
+
id: string;
|
|
21
|
+
type: string;
|
|
22
|
+
email: string | null;
|
|
23
|
+
name: string | null;
|
|
24
|
+
orgIds: string[];
|
|
25
|
+
capabilities: string[];
|
|
26
|
+
isPlatformAdmin?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface AuthSession {
|
|
29
|
+
accessToken: string;
|
|
30
|
+
refreshToken: string;
|
|
31
|
+
workspace: string;
|
|
32
|
+
tokenType: string;
|
|
33
|
+
expiresIn: number;
|
|
34
|
+
obtainedAt: string;
|
|
35
|
+
expiresAt: string;
|
|
36
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export type VectorPlaneEnvironment = "production" | "preview" | "self-hosted";
|
|
2
|
+
export interface CliProfileConfig {
|
|
3
|
+
name: string;
|
|
4
|
+
apiBaseUrl: string;
|
|
5
|
+
appBaseUrl: string;
|
|
6
|
+
workspace: string | null;
|
|
7
|
+
orgId: string | null;
|
|
8
|
+
environment: VectorPlaneEnvironment;
|
|
9
|
+
}
|
|
10
|
+
export interface CliConfig {
|
|
11
|
+
activeProfile: string;
|
|
12
|
+
profiles: Record<string, CliProfileConfig>;
|
|
13
|
+
callbackHost: string;
|
|
14
|
+
callbackPort: number;
|
|
15
|
+
callbackPath: string;
|
|
16
|
+
requestTimeoutMs: number;
|
|
17
|
+
publicIpLookupTimeoutMs: number;
|
|
18
|
+
debug: boolean;
|
|
19
|
+
telemetryEnabled: boolean;
|
|
20
|
+
queueMaxRetries: number;
|
|
21
|
+
snapshotStoreLimit: number;
|
|
22
|
+
}
|
|
23
|
+
export interface CliProfileState {
|
|
24
|
+
lastSyncAt: string | null;
|
|
25
|
+
lastWorkspace: string | null;
|
|
26
|
+
lastCommand: string | null;
|
|
27
|
+
lastSyncHash: string | null;
|
|
28
|
+
lastSyncStatus: "success" | "queued" | "failed" | null;
|
|
29
|
+
lastError: string | null;
|
|
30
|
+
lastSnapshotPath: string | null;
|
|
31
|
+
lastSessionId: string | null;
|
|
32
|
+
}
|
|
33
|
+
export interface CliState {
|
|
34
|
+
activeProfile: string;
|
|
35
|
+
profiles: Record<string, CliProfileState>;
|
|
36
|
+
}
|
|
37
|
+
export interface WorkspaceBinding {
|
|
38
|
+
rootPath: string;
|
|
39
|
+
workspace: string;
|
|
40
|
+
repoUrl: string | null;
|
|
41
|
+
resolvedAt: string;
|
|
42
|
+
source: "manual" | "api-resolve" | "session";
|
|
43
|
+
}
|
|
44
|
+
export interface WorkspaceBindingStore {
|
|
45
|
+
bindings: Record<string, WorkspaceBinding>;
|
|
46
|
+
}
|
|
47
|
+
export interface PendingQueueItem {
|
|
48
|
+
id: string;
|
|
49
|
+
profile: string;
|
|
50
|
+
kind: "sync" | "event";
|
|
51
|
+
createdAt: string;
|
|
52
|
+
attempts: number;
|
|
53
|
+
lastError: string | null;
|
|
54
|
+
payload: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
export interface QueueStore {
|
|
57
|
+
items: PendingQueueItem[];
|
|
58
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface SafeEnvironmentVariable {
|
|
2
|
+
key: string;
|
|
3
|
+
value: string;
|
|
4
|
+
}
|
|
5
|
+
export interface NetworkInterfaceContext {
|
|
6
|
+
name: string;
|
|
7
|
+
family: string;
|
|
8
|
+
mac: string;
|
|
9
|
+
address: string;
|
|
10
|
+
internal: boolean;
|
|
11
|
+
cidr: string | null;
|
|
12
|
+
}
|
|
13
|
+
export interface RuntimeContext {
|
|
14
|
+
nodeVersion: string;
|
|
15
|
+
npmVersion: string | null;
|
|
16
|
+
cliVersion: string;
|
|
17
|
+
pid: number;
|
|
18
|
+
command: string;
|
|
19
|
+
args: string[];
|
|
20
|
+
shell: string | null;
|
|
21
|
+
safeEnv: SafeEnvironmentVariable[];
|
|
22
|
+
}
|
|
23
|
+
export interface DeviceIdentity {
|
|
24
|
+
machineId: string;
|
|
25
|
+
firstSeenAt: string;
|
|
26
|
+
lastSeenAt: string;
|
|
27
|
+
}
|
|
28
|
+
export interface MachineContext {
|
|
29
|
+
machineId: string;
|
|
30
|
+
hostname: string;
|
|
31
|
+
platform: NodeJS.Platform;
|
|
32
|
+
osRelease: string;
|
|
33
|
+
architecture: string;
|
|
34
|
+
kernelVersion: string;
|
|
35
|
+
username: string;
|
|
36
|
+
timezone: string;
|
|
37
|
+
locale: string;
|
|
38
|
+
shell: string | null;
|
|
39
|
+
currentDirectory: string;
|
|
40
|
+
homeDirectory: string;
|
|
41
|
+
cpuModel: string | null;
|
|
42
|
+
cpuCount: number;
|
|
43
|
+
loadAverage: number[];
|
|
44
|
+
memoryTotal: number;
|
|
45
|
+
memoryFree: number;
|
|
46
|
+
uptimeSeconds: number;
|
|
47
|
+
networkInterfaces: NetworkInterfaceContext[];
|
|
48
|
+
publicIp: string | null;
|
|
49
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { GitContext, WorkspaceContext } from "./workspace.js";
|
|
2
|
+
import type { MachineContext, RuntimeContext } from "./machine.js";
|
|
3
|
+
export interface CommandMetadata {
|
|
4
|
+
name: string;
|
|
5
|
+
startedAt: string;
|
|
6
|
+
cwd: string;
|
|
7
|
+
}
|
|
8
|
+
export interface SnapshotPayload {
|
|
9
|
+
machine: MachineContext;
|
|
10
|
+
runtime: RuntimeContext;
|
|
11
|
+
workspace: WorkspaceContext;
|
|
12
|
+
git: GitContext;
|
|
13
|
+
command: CommandMetadata;
|
|
14
|
+
timestamp: string;
|
|
15
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface WorkspaceFilePresence {
|
|
2
|
+
AGENT_MD: boolean;
|
|
3
|
+
CLAUDE_MD: boolean;
|
|
4
|
+
README_MD: boolean;
|
|
5
|
+
PACKAGE_JSON: boolean;
|
|
6
|
+
TSCONFIG_JSON: boolean;
|
|
7
|
+
WRANGLER_TOML: boolean;
|
|
8
|
+
DOCKER_COMPOSE_YML: boolean;
|
|
9
|
+
ENV_EXAMPLE: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface WorkspaceSignals {
|
|
12
|
+
isGitRepository: boolean;
|
|
13
|
+
hasCloudflareWorkers: boolean;
|
|
14
|
+
hasTypeScript: boolean;
|
|
15
|
+
hasNode: boolean;
|
|
16
|
+
isMonorepo: boolean;
|
|
17
|
+
suggestsControlPlane: boolean;
|
|
18
|
+
usesQueues: boolean;
|
|
19
|
+
usesDurableObjects: boolean;
|
|
20
|
+
usesD1: boolean;
|
|
21
|
+
usesKv: boolean;
|
|
22
|
+
usesR2: boolean;
|
|
23
|
+
usesRestApi: boolean;
|
|
24
|
+
usesMcp: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface WorkspaceContext {
|
|
27
|
+
rootPath: string;
|
|
28
|
+
rootName: string;
|
|
29
|
+
collectedAt: string;
|
|
30
|
+
filePresence: WorkspaceFilePresence;
|
|
31
|
+
importantFiles: string[];
|
|
32
|
+
signals: WorkspaceSignals;
|
|
33
|
+
snapshotHash: string;
|
|
34
|
+
}
|
|
35
|
+
export interface GitContext {
|
|
36
|
+
isRepository: boolean;
|
|
37
|
+
rootPath: string | null;
|
|
38
|
+
branch: string | null;
|
|
39
|
+
commitHash: string | null;
|
|
40
|
+
remoteOrigin: string | null;
|
|
41
|
+
repositoryName: string | null;
|
|
42
|
+
hasLocalChanges: boolean;
|
|
43
|
+
statusSummary: string[];
|
|
44
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vectorplane/ctrl-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official VectorPlane CLI for secure local auth, workspace sync, agent sessions, and control plane operations.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"vp": "./bin/vp.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin/vp.js",
|
|
16
|
+
"dist/**/*.js",
|
|
17
|
+
"dist/**/*.d.ts",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://gitlab.com/vector-plane/vectorplane-ctrl-cli.git"
|
|
27
|
+
},
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://gitlab.com/vector-plane/vectorplane-ctrl-cli/-/issues"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://gitlab.com/vector-plane/vectorplane-ctrl-cli#readme",
|
|
32
|
+
"funding": {
|
|
33
|
+
"type": "individual",
|
|
34
|
+
"url": "https://vectorplane.ai"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20.10.0"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsc -p tsconfig.json",
|
|
41
|
+
"check": "tsc --noEmit -p tsconfig.json",
|
|
42
|
+
"dev": "node --enable-source-maps ./dist/index.js",
|
|
43
|
+
"pack:dry-run": "npm pack --dry-run",
|
|
44
|
+
"release:check": "npm run check && npm run build && npm run pack:dry-run",
|
|
45
|
+
"prepublishOnly": "npm run release:check",
|
|
46
|
+
"start": "node ./dist/index.js"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"vectorplane",
|
|
50
|
+
"cli",
|
|
51
|
+
"control-plane",
|
|
52
|
+
"developer-tools",
|
|
53
|
+
"agents"
|
|
54
|
+
],
|
|
55
|
+
"author": "VectorPlane",
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/node": "^24.5.2",
|
|
59
|
+
"typescript": "^5.9.2"
|
|
60
|
+
}
|
|
61
|
+
}
|