@cliperhq/cliper 1.0.0 → 1.0.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/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +74 -0
- package/dist/commands/push.d.ts +2 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +85 -0
- package/dist/commands/view.d.ts +2 -0
- package/dist/commands/view.d.ts.map +1 -0
- package/dist/commands/view.js +60 -0
- package/dist/index.js +15 -0
- package/package.json +2 -1
- package/src/commands/auth.ts +35 -0
- package/src/commands/push.ts +54 -0
- package/src/commands/view.ts +27 -0
- package/src/index.ts +19 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AASA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAejD;AAED,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAQ5C"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.authCommand = authCommand;
|
|
40
|
+
exports.getAuthToken = getAuthToken;
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
45
|
+
const readline = __importStar(require("readline"));
|
|
46
|
+
const AUTH_FILE = path.join(os.homedir(), ".cliper", "auth");
|
|
47
|
+
const AUTH_URL = "https://cliperhq.vercel.app/auth/cli";
|
|
48
|
+
async function authCommand() {
|
|
49
|
+
console.log(chalk_1.default.bold.cyan("\n cliper auth\n"));
|
|
50
|
+
console.log(chalk_1.default.gray(" Opening browser to authenticate...\n"));
|
|
51
|
+
const { default: open } = await Promise.resolve().then(() => __importStar(require("open")));
|
|
52
|
+
await open(AUTH_URL);
|
|
53
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
54
|
+
rl.question(chalk_1.default.white(" Paste your token here: "), (token) => {
|
|
55
|
+
rl.close();
|
|
56
|
+
const dir = path.dirname(AUTH_FILE);
|
|
57
|
+
if (!fs.existsSync(dir))
|
|
58
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
59
|
+
fs.writeFileSync(AUTH_FILE, JSON.stringify({ token: token.trim() }), { mode: 0o600 });
|
|
60
|
+
console.log(chalk_1.default.green("\n ✓ Authenticated. You can now use cliper push and cliper view.\n"));
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function getAuthToken() {
|
|
64
|
+
try {
|
|
65
|
+
if (!fs.existsSync(AUTH_FILE))
|
|
66
|
+
return null;
|
|
67
|
+
const data = JSON.parse(fs.readFileSync(AUTH_FILE, "utf-8"));
|
|
68
|
+
return data.token ?? null;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AASA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA4CjD"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.pushCommand = pushCommand;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
43
|
+
const ora_1 = __importDefault(require("ora"));
|
|
44
|
+
const config_1 = require("../scope/config");
|
|
45
|
+
const auth_1 = require("./auth");
|
|
46
|
+
const API_URL = "https://cliperhq.vercel.app/api/push";
|
|
47
|
+
async function pushCommand() {
|
|
48
|
+
const projectRoot = process.cwd();
|
|
49
|
+
const contextPath = path.join((0, config_1.getCliperDir)(projectRoot), "context.md");
|
|
50
|
+
if (!fs.existsSync(contextPath)) {
|
|
51
|
+
console.error(chalk_1.default.red("\n No context doc found. Run cliper init first.\n"));
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
const token = (0, auth_1.getAuthToken)();
|
|
55
|
+
if (!token) {
|
|
56
|
+
console.error(chalk_1.default.red("\n Not authenticated. Run cliper auth first.\n"));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
const content = fs.readFileSync(contextPath, "utf-8");
|
|
60
|
+
const projectName = path.basename(projectRoot);
|
|
61
|
+
const spinner = (0, ora_1.default)("Pushing context to dashboard...").start();
|
|
62
|
+
try {
|
|
63
|
+
const { default: fetch } = await Promise.resolve().then(() => __importStar(require("node-fetch")));
|
|
64
|
+
const res = await fetch(API_URL, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
headers: {
|
|
67
|
+
"Content-Type": "application/json",
|
|
68
|
+
"Authorization": `Bearer ${token}`,
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify({ projectName, content }),
|
|
71
|
+
});
|
|
72
|
+
const data = await res.json();
|
|
73
|
+
if (!res.ok) {
|
|
74
|
+
spinner.fail(chalk_1.default.red(`Push failed: ${data.error}`));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
spinner.succeed(chalk_1.default.green("Context pushed successfully"));
|
|
78
|
+
console.log(chalk_1.default.gray(`\n Dashboard: ${data.dashboardUrl}\n`));
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
spinner.fail(chalk_1.default.red(`Push failed: ${err.message}`));
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/commands/view.ts"],"names":[],"mappings":"AAOA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBjD"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.viewCommand = viewCommand;
|
|
40
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
41
|
+
const auth_1 = require("./auth");
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const push_1 = require("./push");
|
|
44
|
+
const DASHBOARD_URL = "https://cliperhq.vercel.app/dashboard";
|
|
45
|
+
async function viewCommand() {
|
|
46
|
+
const token = (0, auth_1.getAuthToken)();
|
|
47
|
+
if (!token) {
|
|
48
|
+
console.error(chalk_1.default.red("\n Not authenticated. Run cliper auth first.\n"));
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
console.log(chalk_1.default.bold.cyan("\n cliper view\n"));
|
|
52
|
+
// Push latest context first
|
|
53
|
+
await (0, push_1.pushCommand)();
|
|
54
|
+
const projectName = path.basename(process.cwd());
|
|
55
|
+
const { default: open } = await Promise.resolve().then(() => __importStar(require("open")));
|
|
56
|
+
const url = `${DASHBOARD_URL}?project=${encodeURIComponent(projectName)}`;
|
|
57
|
+
console.log(chalk_1.default.gray(` Opening: ${url}\n`));
|
|
58
|
+
await open(url);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=view.js.map
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,9 @@ const scope_1 = require("./commands/scope");
|
|
|
8
8
|
const status_1 = require("./commands/status");
|
|
9
9
|
const export_1 = require("./commands/export");
|
|
10
10
|
const analyze_1 = require("./commands/analyze");
|
|
11
|
+
const auth_1 = require("./commands/auth");
|
|
12
|
+
const push_1 = require("./commands/push");
|
|
13
|
+
const view_1 = require("./commands/view");
|
|
11
14
|
const { version } = require("../package.json");
|
|
12
15
|
commander_1.program
|
|
13
16
|
.name("cliper")
|
|
@@ -44,5 +47,17 @@ commander_1.program
|
|
|
44
47
|
.description("Analyze context doc and generate optimized AI prompt")
|
|
45
48
|
.requiredOption("--model <model>", "Target model: claude or chatgpt")
|
|
46
49
|
.action(analyze_1.analyzeCommand);
|
|
50
|
+
commander_1.program
|
|
51
|
+
.command("auth")
|
|
52
|
+
.description("Authenticate with Cliper dashboard")
|
|
53
|
+
.action(auth_1.authCommand);
|
|
54
|
+
commander_1.program
|
|
55
|
+
.command("push")
|
|
56
|
+
.description("Push context doc to Cliper dashboard")
|
|
57
|
+
.action(push_1.pushCommand);
|
|
58
|
+
commander_1.program
|
|
59
|
+
.command("view")
|
|
60
|
+
.description("Open project dashboard in browser")
|
|
61
|
+
.action(view_1.viewCommand);
|
|
47
62
|
commander_1.program.parse(process.argv);
|
|
48
63
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cliperhq/cliper",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Generate rich, AI-ready context documents from your codebase. Always fresh, always scoped — for Claude, ChatGPT, and beyond.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"ignore": "^5.3.1",
|
|
22
22
|
"marked": "^12.0.0",
|
|
23
23
|
"node-fetch": "^3.3.2",
|
|
24
|
+
"open": "^11.0.0",
|
|
24
25
|
"ora": "^8.0.1",
|
|
25
26
|
"simple-git": "^3.22.0"
|
|
26
27
|
},
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as os from "os";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import * as readline from "readline";
|
|
6
|
+
|
|
7
|
+
const AUTH_FILE = path.join(os.homedir(), ".cliper", "auth");
|
|
8
|
+
const AUTH_URL = "https://cliperhq.vercel.app/auth/cli";
|
|
9
|
+
|
|
10
|
+
export async function authCommand(): Promise<void> {
|
|
11
|
+
console.log(chalk.bold.cyan("\n cliper auth\n"));
|
|
12
|
+
console.log(chalk.gray(" Opening browser to authenticate...\n"));
|
|
13
|
+
|
|
14
|
+
const { default: open } = await import("open");
|
|
15
|
+
await open(AUTH_URL);
|
|
16
|
+
|
|
17
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
18
|
+
rl.question(chalk.white(" Paste your token here: "), (token) => {
|
|
19
|
+
rl.close();
|
|
20
|
+
const dir = path.dirname(AUTH_FILE);
|
|
21
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
22
|
+
fs.writeFileSync(AUTH_FILE, JSON.stringify({ token: token.trim() }), { mode: 0o600 });
|
|
23
|
+
console.log(chalk.green("\n ✓ Authenticated. You can now use cliper push and cliper view.\n"));
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getAuthToken(): string | null {
|
|
28
|
+
try {
|
|
29
|
+
if (!fs.existsSync(AUTH_FILE)) return null;
|
|
30
|
+
const data = JSON.parse(fs.readFileSync(AUTH_FILE, "utf-8"));
|
|
31
|
+
return data.token ?? null;
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import { getCliperDir } from "../scope/config";
|
|
6
|
+
import { getAuthToken } from "./auth";
|
|
7
|
+
|
|
8
|
+
const API_URL = "https://cliperhq.vercel.app/api/push";
|
|
9
|
+
|
|
10
|
+
export async function pushCommand(): Promise<void> {
|
|
11
|
+
const projectRoot = process.cwd();
|
|
12
|
+
const contextPath = path.join(getCliperDir(projectRoot), "context.md");
|
|
13
|
+
|
|
14
|
+
if (!fs.existsSync(contextPath)) {
|
|
15
|
+
console.error(chalk.red("\n No context doc found. Run cliper init first.\n"));
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const token = getAuthToken();
|
|
20
|
+
if (!token) {
|
|
21
|
+
console.error(chalk.red("\n Not authenticated. Run cliper auth first.\n"));
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const content = fs.readFileSync(contextPath, "utf-8");
|
|
26
|
+
const projectName = path.basename(projectRoot);
|
|
27
|
+
|
|
28
|
+
const spinner = ora("Pushing context to dashboard...").start();
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const { default: fetch } = await import("node-fetch");
|
|
32
|
+
const res = await fetch(API_URL, {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: {
|
|
35
|
+
"Content-Type": "application/json",
|
|
36
|
+
"Authorization": `Bearer ${token}`,
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify({ projectName, content }),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const data = await res.json() as any;
|
|
42
|
+
|
|
43
|
+
if (!res.ok) {
|
|
44
|
+
spinner.fail(chalk.red(`Push failed: ${data.error}`));
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
spinner.succeed(chalk.green("Context pushed successfully"));
|
|
49
|
+
console.log(chalk.gray(`\n Dashboard: ${data.dashboardUrl}\n`));
|
|
50
|
+
} catch (err: any) {
|
|
51
|
+
spinner.fail(chalk.red(`Push failed: ${err.message}`));
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { getAuthToken } from "./auth";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { pushCommand } from "./push";
|
|
5
|
+
|
|
6
|
+
const DASHBOARD_URL = "https://cliperhq.vercel.app/dashboard";
|
|
7
|
+
|
|
8
|
+
export async function viewCommand(): Promise<void> {
|
|
9
|
+
const token = getAuthToken();
|
|
10
|
+
|
|
11
|
+
if (!token) {
|
|
12
|
+
console.error(chalk.red("\n Not authenticated. Run cliper auth first.\n"));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
console.log(chalk.bold.cyan("\n cliper view\n"));
|
|
17
|
+
|
|
18
|
+
// Push latest context first
|
|
19
|
+
await pushCommand();
|
|
20
|
+
|
|
21
|
+
const projectName = path.basename(process.cwd());
|
|
22
|
+
const { default: open } = await import("open");
|
|
23
|
+
const url = `${DASHBOARD_URL}?project=${encodeURIComponent(projectName)}`;
|
|
24
|
+
|
|
25
|
+
console.log(chalk.gray(` Opening: ${url}\n`));
|
|
26
|
+
await open(url);
|
|
27
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,10 @@ import { scopeCommand } from "./commands/scope";
|
|
|
7
7
|
import { statusCommand } from "./commands/status";
|
|
8
8
|
import { exportCommand } from "./commands/export";
|
|
9
9
|
import { analyzeCommand } from "./commands/analyze";
|
|
10
|
+
import { authCommand } from "./commands/auth";
|
|
11
|
+
import { pushCommand } from "./commands/push";
|
|
12
|
+
import { viewCommand } from "./commands/view";
|
|
13
|
+
|
|
10
14
|
const { version } = require("../package.json");
|
|
11
15
|
|
|
12
16
|
program
|
|
@@ -51,4 +55,19 @@ program
|
|
|
51
55
|
.requiredOption("--model <model>", "Target model: claude or chatgpt")
|
|
52
56
|
.action(analyzeCommand);
|
|
53
57
|
|
|
58
|
+
program
|
|
59
|
+
.command("auth")
|
|
60
|
+
.description("Authenticate with Cliper dashboard")
|
|
61
|
+
.action(authCommand);
|
|
62
|
+
|
|
63
|
+
program
|
|
64
|
+
.command("push")
|
|
65
|
+
.description("Push context doc to Cliper dashboard")
|
|
66
|
+
.action(pushCommand);
|
|
67
|
+
|
|
68
|
+
program
|
|
69
|
+
.command("view")
|
|
70
|
+
.description("Open project dashboard in browser")
|
|
71
|
+
.action(viewCommand);
|
|
72
|
+
|
|
54
73
|
program.parse(process.argv);
|