@driftless-sh/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.
@@ -0,0 +1,9 @@
1
+ export declare const api: {
2
+ get: <T = unknown>(path: string) => Promise<T>;
3
+ post: <T = unknown>(path: string, body?: unknown) => Promise<T>;
4
+ put: <T = unknown>(path: string, body?: unknown) => Promise<T>;
5
+ delete: <T = unknown>(path: string) => Promise<T>;
6
+ };
7
+ export declare function getApiUrl(): string;
8
+ export declare function getApiKey(): string | null;
9
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAqFA,eAAO,MAAM,GAAG;UACR,CAAC,kBAAkB,MAAM,KAA6B,OAAO,CAAC,CAAC,CAAC;WAC/D,CAAC,kBAAkB,MAAM,SAAS,OAAO,KACf,OAAO,CAAC,CAAC,CAAC;UACrC,CAAC,kBAAkB,MAAM,SAAS,OAAO,KACf,OAAO,CAAC,CAAC,CAAC;aACjC,CAAC,kBAAkB,MAAM,KAAgC,OAAO,CAAC,CAAC,CAAC;CAC7E,CAAA;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAEzC"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.api = void 0;
4
+ exports.getApiUrl = getApiUrl;
5
+ exports.getApiKey = getApiKey;
6
+ const node_http_1 = require("node:http");
7
+ const node_https_1 = require("node:https");
8
+ const node_fs_1 = require("node:fs");
9
+ const node_path_1 = require("node:path");
10
+ const node_os_1 = require("node:os");
11
+ const CONFIG_PATH = (0, node_path_1.resolve)((0, node_os_1.homedir)(), '.driftless', 'config.json');
12
+ function loadApiKey() {
13
+ // 1. Env var
14
+ const envKey = process.env['DRIFTLESS_API_KEY'];
15
+ if (envKey)
16
+ return envKey;
17
+ // 2. Config file
18
+ try {
19
+ if ((0, node_fs_1.existsSync)(CONFIG_PATH)) {
20
+ const config = JSON.parse((0, node_fs_1.readFileSync)(CONFIG_PATH, 'utf8'));
21
+ return config.api_key || null;
22
+ }
23
+ }
24
+ catch {
25
+ // ignore
26
+ }
27
+ return null;
28
+ }
29
+ const DEFAULT_URL = 'http://localhost:3000/api/v1';
30
+ function getBaseUrl() {
31
+ const envUrl = process.env['DRIFTLESS_API_URL'];
32
+ if (envUrl) {
33
+ return envUrl.endsWith('/api/v1') ? envUrl : `${envUrl}/api/v1`;
34
+ }
35
+ // Try config file
36
+ try {
37
+ if ((0, node_fs_1.existsSync)(CONFIG_PATH)) {
38
+ const config = JSON.parse((0, node_fs_1.readFileSync)(CONFIG_PATH, 'utf8'));
39
+ return config.api_url || DEFAULT_URL;
40
+ }
41
+ }
42
+ catch {
43
+ // ignore
44
+ }
45
+ return DEFAULT_URL;
46
+ }
47
+ function request(method, path, body) {
48
+ return new Promise((resolve, reject) => {
49
+ const baseUrl = getBaseUrl();
50
+ const fullUrl = `${baseUrl}${path}`;
51
+ const url = new URL(fullUrl);
52
+ const isHttps = url.protocol === 'https:';
53
+ const fn = isHttps ? node_https_1.request : node_http_1.request;
54
+ const headers = {
55
+ 'Content-Type': 'application/json',
56
+ Accept: 'application/json',
57
+ };
58
+ const apiKey = loadApiKey();
59
+ if (apiKey) {
60
+ headers['X-API-Key'] = apiKey;
61
+ }
62
+ const req = fn(fullUrl, { method, headers }, (res) => {
63
+ let data = '';
64
+ res.on('data', (chunk) => (data += chunk.toString()));
65
+ res.on('end', () => {
66
+ try {
67
+ resolve(JSON.parse(data));
68
+ }
69
+ catch {
70
+ resolve(data);
71
+ }
72
+ });
73
+ });
74
+ req.on('error', reject);
75
+ if (body)
76
+ req.write(JSON.stringify(body));
77
+ req.end();
78
+ });
79
+ }
80
+ exports.api = {
81
+ get: (path) => request('GET', path),
82
+ post: (path, body) => request('POST', path, body),
83
+ put: (path, body) => request('PUT', path, body),
84
+ delete: (path) => request('DELETE', path),
85
+ };
86
+ function getApiUrl() {
87
+ return getBaseUrl();
88
+ }
89
+ function getApiKey() {
90
+ return loadApiKey();
91
+ }
92
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function contextCommand(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAGA,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmFlE"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.contextCommand = contextCommand;
4
+ const api_client_1 = require("../api-client");
5
+ const git_1 = require("../git");
6
+ async function contextCommand(args) {
7
+ if (!(0, git_1.isGitRepo)()) {
8
+ console.error('Error: not a git repository.');
9
+ process.exit(1);
10
+ }
11
+ const remote = (0, git_1.getGitRemote)();
12
+ if (!remote) {
13
+ console.error('Error: no git remote found.');
14
+ process.exit(1);
15
+ }
16
+ // Get workspace
17
+ let workspace;
18
+ try {
19
+ workspace = await api_client_1.api.get(`/workspaces/${remote.org}`);
20
+ }
21
+ catch {
22
+ console.error(`Workspace '${remote.org}' not found. Run 'driftless init' first.`);
23
+ process.exit(1);
24
+ }
25
+ const subCommand = args[0];
26
+ if (subCommand === 'list') {
27
+ try {
28
+ const watchers = (await api_client_1.api.get(`/workspaces/${remote.org}/watchers`));
29
+ if (watchers.length === 0) {
30
+ console.log('No watchers defined yet.');
31
+ console.log('Create one with: driftless context add "name" --what "..." --how "..." --where "..."');
32
+ }
33
+ else {
34
+ for (const w of watchers) {
35
+ console.log(` • ${w.slug} — ${w.name}`);
36
+ }
37
+ }
38
+ }
39
+ catch {
40
+ console.log('Watchers API not available yet (coming in M5).');
41
+ }
42
+ return;
43
+ }
44
+ if (subCommand === 'get') {
45
+ const slug = args[1];
46
+ if (!slug) {
47
+ console.error('Usage: driftless context get <name>');
48
+ process.exit(1);
49
+ }
50
+ try {
51
+ const watcher = await api_client_1.api.get(`/workspaces/${remote.org}/watchers/${slug}`);
52
+ console.log(`Name: ${watcher.name}`);
53
+ console.log(`What: ${watcher.what || 'N/A'}`);
54
+ console.log(`How: ${watcher.how || 'N/A'}`);
55
+ console.log(`Where: ${watcher.where_files?.join(', ') || 'N/A'}`);
56
+ console.log(`Used by: ${watcher.where_used_by?.join(', ') || 'N/A'}`);
57
+ console.log(`Updated: ${watcher.last_updated || 'never'}`);
58
+ }
59
+ catch {
60
+ console.log(`Watcher '${slug}' not found or API not available.`);
61
+ }
62
+ return;
63
+ }
64
+ if (subCommand === 'add') {
65
+ const name = args[1];
66
+ if (!name) {
67
+ console.error('Usage: driftless context add "name" --what "..." --how "..." --where "..."');
68
+ process.exit(1);
69
+ }
70
+ try {
71
+ await api_client_1.api.post(`/workspaces/${remote.org}/watchers`, {
72
+ name,
73
+ slug: name.toLowerCase().replace(/\s+/g, '-'),
74
+ });
75
+ console.log(`Watcher '${name}' created.`);
76
+ }
77
+ catch {
78
+ console.log('Watchers API not available yet (coming in M5).');
79
+ }
80
+ return;
81
+ }
82
+ console.log('Usage: driftless context <list|get|add> [args]');
83
+ }
84
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function initCommand(): Promise<void>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAGA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA8FjD"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initCommand = initCommand;
4
+ const api_client_1 = require("../api-client");
5
+ const git_1 = require("../git");
6
+ async function initCommand() {
7
+ console.log('Driftless — context integrity for engineering teams\n');
8
+ if (!(0, git_1.isGitRepo)()) {
9
+ console.error('Error: not a git repository. Run this command from the root of your repo.');
10
+ process.exit(1);
11
+ }
12
+ const remote = (0, git_1.getGitRemote)();
13
+ if (!remote) {
14
+ console.error('Error: no git remote found. Add a remote first with: git remote add origin <url>');
15
+ process.exit(1);
16
+ }
17
+ console.log(`Repository: ${remote.org}/${remote.repo}`);
18
+ // 1. Create workspace (or find existing)
19
+ let workspace;
20
+ try {
21
+ workspace = await api_client_1.api.get(`/workspaces/${remote.org}`);
22
+ console.log(`Workspace: ${remote.org} (existing)`);
23
+ }
24
+ catch {
25
+ workspace = await api_client_1.api.post('/workspaces', {
26
+ name: remote.org,
27
+ slug: remote.org,
28
+ });
29
+ console.log(`Workspace: ${remote.org} (created)`);
30
+ }
31
+ // 2. Connect repo (or find existing)
32
+ let repo;
33
+ try {
34
+ const repos = (await api_client_1.api.get(`/workspaces/${remote.org}/repos`));
35
+ repo = repos.find((r) => r.github_org === remote.org && r.github_repo === remote.repo);
36
+ if (repo) {
37
+ console.log(`Repo: ${remote.repo} (existing)`);
38
+ }
39
+ }
40
+ catch {
41
+ // ignore
42
+ }
43
+ if (!repo) {
44
+ repo = await api_client_1.api.post(`/workspaces/${remote.org}/repos`, {
45
+ github_org: remote.org,
46
+ github_repo: remote.repo,
47
+ });
48
+ console.log(`Repo: ${remote.repo} (connected)`);
49
+ }
50
+ // 3. Scan repo
51
+ console.log('\nScanning codebase...');
52
+ const scanResult = await api_client_1.api.post(`/workspaces/${remote.org}/repos/${repo.id}/scan`);
53
+ if (scanResult.status === 'error') {
54
+ console.error(`Scan failed: ${scanResult.error}`);
55
+ process.exit(1);
56
+ }
57
+ const { summary } = scanResult;
58
+ console.log(`\nResults:`);
59
+ console.log(` Framework: ${summary.framework}`);
60
+ console.log(` Type: ${summary.system_type}`);
61
+ console.log(` Auth: ${summary.auth_patterns?.join(', ') || 'none'}`);
62
+ console.log(` Endpoints: ${summary.endpoints}`);
63
+ console.log(` Guards: ${summary.guards}`);
64
+ console.log(` Services: ${summary.services}`);
65
+ console.log(` Modules: ${summary.modules}`);
66
+ // 4. Suggest rules
67
+ console.log('\nSuggested rules:');
68
+ const suggestions = [
69
+ ...(summary.auth_patterns?.includes('apikey')
70
+ ? ['Every B2B endpoint must use BusinessAccessGuard']
71
+ : []),
72
+ ...(summary.guards > 3 ? ['Services must not import controllers directly'] : []),
73
+ ...(summary.endpoints > 50
74
+ ? [`app.controller.ts should be split — over 50 endpoints detected`]
75
+ : []),
76
+ ];
77
+ if (suggestions.length === 0) {
78
+ console.log(' No automatic suggestions for this repo.');
79
+ }
80
+ else {
81
+ for (const s of suggestions) {
82
+ console.log(` • ${s}`);
83
+ }
84
+ console.log('\nAccept these suggestions? Run:');
85
+ console.log(` driftless rule accept --all`);
86
+ }
87
+ console.log(`\nDone! Run 'driftless scan --diff' before pushing to check for violations.`);
88
+ }
89
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function installSkillCommand(): void;
2
+ //# sourceMappingURL=install-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-skill.d.ts","sourceRoot":"","sources":["../../src/commands/install-skill.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,IAAI,IAAI,CA4C1C"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.installSkillCommand = installSkillCommand;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ function installSkillCommand() {
7
+ const cwd = process.cwd();
8
+ const agentsPath = (0, node_path_1.resolve)(cwd, 'AGENTS.md');
9
+ const template = `# Driftless — Team Codebase Memory
10
+
11
+ Driftless Cloud is the source of truth for this repo's architecture context.
12
+
13
+ Before touching backend architecture, auth, routes, guards, services, modules, or package boundaries, load relevant context:
14
+
15
+ \\\`\\\`\\\`bash
16
+ driftless context get <feature>
17
+ \\\`\\\`\\\`
18
+
19
+ Before completing work, verify the current diff:
20
+
21
+ \\\`\\\`\\\`bash
22
+ driftless scan --diff
23
+ \\\`\\\`\\\`
24
+
25
+ If Driftless reports violations, fix them before finishing.
26
+
27
+ If you discover durable context about the codebase, add it to the team memory:
28
+
29
+ \\\`\\\`\\\`bash
30
+ driftless context add "<name>" --what "..." --how "..." --where "..."
31
+ \\\`\\\`\\\`
32
+
33
+ Driftless is not local session memory. It is shared team context stored in Cloud and kept updated through scans, agent activity, and repo changes.
34
+ `;
35
+ if ((0, node_fs_1.existsSync)(agentsPath)) {
36
+ console.log('AGENTS.md already exists. Appending Driftless section...');
37
+ const existing = require('node:fs').readFileSync(agentsPath, 'utf8');
38
+ if (existing.includes('Driftless — Context & Integrity')) {
39
+ console.log('Driftless section already present.');
40
+ return;
41
+ }
42
+ (0, node_fs_1.writeFileSync)(agentsPath, existing + '\n---\n\n' + template);
43
+ }
44
+ else {
45
+ (0, node_fs_1.writeFileSync)(agentsPath, template);
46
+ }
47
+ console.log(`Driftless skill installed at ${agentsPath}`);
48
+ }
49
+ //# sourceMappingURL=install-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-skill.js","sourceRoot":"","sources":["../../src/commands/install-skill.ts"],"names":[],"mappings":";;AAGA,kDA4CC;AA/CD,qCAAmD;AACnD,yCAAmC;AAEnC,SAAgB,mBAAmB;IACjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,MAAM,UAAU,GAAG,IAAA,mBAAO,EAAC,GAAG,EAAE,WAAW,CAAC,CAAA;IAE5C,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;CAyBlB,CAAA;IAEC,IAAI,IAAA,oBAAU,EAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAA;QACvE,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;QACpE,IAAI,QAAQ,CAAC,QAAQ,CAAC,iCAAiC,CAAC,EAAE,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAA;YACjD,OAAM;QACR,CAAC;QACD,IAAA,uBAAa,EAAC,UAAU,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC,CAAA;IAC9D,CAAC;SAAM,CAAC;QACN,IAAA,uBAAa,EAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;IACrC,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gCAAgC,UAAU,EAAE,CAAC,CAAA;AAC3D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function loginCommand(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAeA,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+ChE"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loginCommand = loginCommand;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const node_readline_1 = require("node:readline");
7
+ const node_child_process_1 = require("node:child_process");
8
+ const node_os_1 = require("node:os");
9
+ const CONFIG_DIR = (0, node_path_1.resolve)((0, node_os_1.homedir)(), '.driftless');
10
+ const CONFIG_PATH = (0, node_path_1.resolve)(CONFIG_DIR, 'config.json');
11
+ function openBrowser(url) {
12
+ const cmd = process.platform === 'darwin' ? 'open' :
13
+ process.platform === 'win32' ? 'start' : 'xdg-open';
14
+ (0, node_child_process_1.exec)(`${cmd} ${url}`);
15
+ }
16
+ async function loginCommand(args) {
17
+ // --key flag for quick setup (CI, scripts)
18
+ const keyIndex = args.indexOf('--key');
19
+ if (keyIndex !== -1 && args[keyIndex + 1]) {
20
+ const apiKey = args[keyIndex + 1];
21
+ saveConfig(apiKey);
22
+ return;
23
+ }
24
+ const apiUrl = process.env['DRIFTLESS_API_URL'] || 'https://api.driftless.icu/api/v1';
25
+ const dashboardUrl = 'https://driftless.icu';
26
+ console.log('Opening Driftless Dashboard to get your API key...');
27
+ console.log();
28
+ // Open browser to dashboard API keys section
29
+ openBrowser(dashboardUrl);
30
+ console.log('If the browser doesn\'t open, visit:');
31
+ console.log(` ${dashboardUrl}`);
32
+ console.log();
33
+ console.log('1. Sign in with your account');
34
+ console.log('2. Go to Settings → API Keys');
35
+ console.log('3. Create a new API key');
36
+ console.log('4. Copy the key (starts with drift_)');
37
+ console.log();
38
+ // Interactive prompt
39
+ const rl = (0, node_readline_1.createInterface)({
40
+ input: process.stdin,
41
+ output: process.stdout,
42
+ });
43
+ const apiKey = await new Promise((resolve) => {
44
+ rl.question('Paste your API key: ', (answer) => {
45
+ rl.close();
46
+ resolve(answer.trim());
47
+ });
48
+ });
49
+ if (!apiKey.startsWith('drift_')) {
50
+ console.error('Error: API key must start with "drift_".');
51
+ console.error('Get a valid key from your Driftless Dashboard → Settings → API Keys.');
52
+ process.exit(1);
53
+ }
54
+ saveConfig(apiKey, apiUrl);
55
+ }
56
+ function saveConfig(apiKey, apiUrl) {
57
+ const url = apiUrl || 'https://api.driftless.icu/api/v1';
58
+ try {
59
+ if (!(0, node_fs_1.existsSync)(CONFIG_DIR)) {
60
+ (0, node_fs_1.mkdirSync)(CONFIG_DIR, { recursive: true });
61
+ }
62
+ (0, node_fs_1.writeFileSync)(CONFIG_PATH, JSON.stringify({ api_key: apiKey, api_url: url }, null, 2) + '\n');
63
+ console.log();
64
+ console.log('Logged in successfully.');
65
+ console.log(` Config: ${CONFIG_PATH}`);
66
+ console.log();
67
+ console.log('Try: driftless scan --diff');
68
+ }
69
+ catch (err) {
70
+ console.error('Failed to save config:', err);
71
+ process.exit(1);
72
+ }
73
+ }
74
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":";;AAeA,oCA+CC;AA9DD,qCAA4E;AAC5E,yCAAmC;AACnC,iDAA+C;AAC/C,2DAAyC;AACzC,qCAAiC;AAEjC,MAAM,UAAU,GAAG,IAAA,mBAAO,EAAC,IAAA,iBAAO,GAAE,EAAE,YAAY,CAAC,CAAA;AACnD,MAAM,WAAW,GAAG,IAAA,mBAAO,EAAC,UAAU,EAAE,aAAa,CAAC,CAAA;AAEtD,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAClD,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAA;IACrD,IAAA,yBAAI,EAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC,CAAA;AACvB,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,IAAc;IAC/C,2CAA2C;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IACtC,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAA;QACjC,UAAU,CAAC,MAAM,CAAC,CAAA;QAClB,OAAM;IACR,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,kCAAkC,CAAA;IACrF,MAAM,YAAY,GAAG,uBAAuB,CAAA;IAE5C,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAA;IACjE,OAAO,CAAC,GAAG,EAAE,CAAA;IAEb,6CAA6C;IAC7C,WAAW,CAAC,YAAY,CAAC,CAAA;IAEzB,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAA;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,YAAY,EAAE,CAAC,CAAA;IAChC,OAAO,CAAC,GAAG,EAAE,CAAA;IACb,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;IAC3C,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;IAC3C,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;IACtC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAA;IACnD,OAAO,CAAC,GAAG,EAAE,CAAA;IAEb,qBAAqB;IACrB,MAAM,EAAE,GAAG,IAAA,+BAAe,EAAC;QACzB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QACnD,EAAE,CAAC,QAAQ,CAAC,sBAAsB,EAAE,CAAC,MAAM,EAAE,EAAE;YAC7C,EAAE,CAAC,KAAK,EAAE,CAAA;YACV,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;QACxB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAA;QACzD,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAA;QACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAC5B,CAAC;AAED,SAAS,UAAU,CAAC,MAAc,EAAE,MAAe;IACjD,MAAM,GAAG,GAAG,MAAM,IAAI,kCAAkC,CAAA;IAExD,IAAI,CAAC;QACH,IAAI,CAAC,IAAA,oBAAU,EAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,IAAA,mBAAS,EAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC5C,CAAC;QACD,IAAA,uBAAa,EACX,WAAW,EACX,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAClE,CAAA;QACD,OAAO,CAAC,GAAG,EAAE,CAAA;QACb,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;QACtC,OAAO,CAAC,GAAG,CAAC,aAAa,WAAW,EAAE,CAAC,CAAA;QACvC,OAAO,CAAC,GAAG,EAAE,CAAA;QACb,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAA;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAA;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function scanCommand(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAGA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoF/D"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scanCommand = scanCommand;
4
+ const api_client_1 = require("../api-client");
5
+ const git_1 = require("../git");
6
+ async function scanCommand(args) {
7
+ if (!(0, git_1.isGitRepo)()) {
8
+ console.error('Error: not a git repository.');
9
+ process.exit(1);
10
+ }
11
+ const remote = (0, git_1.getGitRemote)();
12
+ if (!remote) {
13
+ console.error('Error: no git remote found.');
14
+ process.exit(1);
15
+ }
16
+ // Get workspace + repo
17
+ let workspace;
18
+ try {
19
+ workspace = await api_client_1.api.get(`/workspaces/${remote.org}`);
20
+ }
21
+ catch {
22
+ console.error(`Workspace '${remote.org}' not found. Run 'driftless init' first.`);
23
+ process.exit(1);
24
+ }
25
+ const repos = (await api_client_1.api.get(`/workspaces/${remote.org}/repos`));
26
+ const repo = repos.find((r) => r.github_org === remote.org && r.github_repo === remote.repo);
27
+ if (!repo) {
28
+ console.error(`Repo '${remote.repo}' not found. Run 'driftless init' first.`);
29
+ process.exit(1);
30
+ }
31
+ // Get diff
32
+ const onlyDiff = args.includes('--diff');
33
+ let diff = '';
34
+ let source = '';
35
+ if (onlyDiff) {
36
+ diff = (0, git_1.getUncommittedDiff)();
37
+ source = 'uncommitted changes';
38
+ if (!diff) {
39
+ console.log('No uncommitted changes. Clean.');
40
+ process.exit(0);
41
+ }
42
+ }
43
+ else {
44
+ const staged = (0, git_1.getStagedDiff)();
45
+ const unstaged = (0, git_1.getUncommittedDiff)();
46
+ diff = [staged, unstaged].filter(Boolean).join('\n');
47
+ source = staged && unstaged ? 'staged + unstaged' : staged ? 'staged' : 'unstaged';
48
+ if (!diff) {
49
+ console.log('No changes to scan. Clean.');
50
+ process.exit(0);
51
+ }
52
+ }
53
+ const commitHash = (0, git_1.getLastCommitHash)();
54
+ const author = (0, git_1.getAuthorName)();
55
+ console.log(`Scanning ${source}...`);
56
+ // Evaluate
57
+ const result = await api_client_1.api.post('/scan', {
58
+ workspace_id: workspace.id,
59
+ repo_id: repo.id,
60
+ diff,
61
+ commit_hash: commitHash,
62
+ author,
63
+ });
64
+ if (result.status === 'clean') {
65
+ console.log('Clean — no violations detected.');
66
+ process.exit(0);
67
+ }
68
+ console.log(`\n${result.violations.length} violation(s) found:\n`);
69
+ for (const v of result.violations) {
70
+ const severityColor = v.severity === 'critical' || v.severity === 'high' ? '\x1b[31m' : '\x1b[33m';
71
+ console.log(` ${severityColor}[${v.severity.toUpperCase()}]\x1b[0m ${v.rule_name}`);
72
+ console.log(` ${v.explanation}`);
73
+ console.log(` File: ${v.file_path}:${v.line_number}`);
74
+ console.log(` Code: ${v.diff_snippet}`);
75
+ console.log();
76
+ }
77
+ console.log('Fix these violations before pushing.');
78
+ process.exit(1);
79
+ }
80
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
package/dist/git.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ export declare function getGitRemote(): {
2
+ org: string;
3
+ repo: string;
4
+ } | null;
5
+ export declare function isGitRepo(): boolean;
6
+ export declare function getUncommittedDiff(): string;
7
+ export declare function getStagedDiff(): string;
8
+ export declare function getLastCommitHash(): string;
9
+ export declare function getAuthorName(): string;
10
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,IAAI;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAgBnE;AAED,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAM3C;AAED,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAM1C;AAED,wBAAgB,aAAa,IAAI,MAAM,CAMtC"}
package/dist/git.js ADDED
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getGitRemote = getGitRemote;
4
+ exports.isGitRepo = isGitRepo;
5
+ exports.getUncommittedDiff = getUncommittedDiff;
6
+ exports.getStagedDiff = getStagedDiff;
7
+ exports.getLastCommitHash = getLastCommitHash;
8
+ exports.getAuthorName = getAuthorName;
9
+ const node_child_process_1 = require("node:child_process");
10
+ const node_fs_1 = require("node:fs");
11
+ const node_path_1 = require("node:path");
12
+ function getGitRemote() {
13
+ try {
14
+ const url = (0, node_child_process_1.execSync)('git config --get remote.origin.url', {
15
+ encoding: 'utf8',
16
+ cwd: process.cwd(),
17
+ }).trim();
18
+ // git@github.com:org/repo.git or https://github.com/org/repo.git
19
+ const match = url.match(/[:/]([^/]+)\/([^/]+?)(?:\.git)?$/);
20
+ if (match) {
21
+ return { org: match[1], repo: match[2] };
22
+ }
23
+ return null;
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ function isGitRepo() {
30
+ return (0, node_fs_1.existsSync)((0, node_path_1.resolve)(process.cwd(), '.git'));
31
+ }
32
+ function getUncommittedDiff() {
33
+ try {
34
+ return (0, node_child_process_1.execSync)('git diff', { encoding: 'utf8', cwd: process.cwd() }).trim();
35
+ }
36
+ catch {
37
+ return '';
38
+ }
39
+ }
40
+ function getStagedDiff() {
41
+ try {
42
+ return (0, node_child_process_1.execSync)('git diff --staged', { encoding: 'utf8', cwd: process.cwd() }).trim();
43
+ }
44
+ catch {
45
+ return '';
46
+ }
47
+ }
48
+ function getLastCommitHash() {
49
+ try {
50
+ return (0, node_child_process_1.execSync)('git rev-parse HEAD', { encoding: 'utf8', cwd: process.cwd() }).trim();
51
+ }
52
+ catch {
53
+ return 'unknown';
54
+ }
55
+ }
56
+ function getAuthorName() {
57
+ try {
58
+ return (0, node_child_process_1.execSync)('git config user.name', { encoding: 'utf8', cwd: process.cwd() }).trim();
59
+ }
60
+ catch {
61
+ return 'unknown';
62
+ }
63
+ }
64
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":";;AAIA,oCAgBC;AAED,8BAEC;AAED,gDAMC;AAED,sCAMC;AAED,8CAMC;AAED,sCAMC;AAxDD,2DAA6C;AAC7C,qCAAoC;AACpC,yCAAmC;AAEnC,SAAgB,YAAY;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,6BAAQ,EAAC,oCAAoC,EAAE;YACzD,QAAQ,EAAE,MAAM;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;SACnB,CAAC,CAAC,IAAI,EAAE,CAAA;QAET,iEAAiE;QACjE,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAA;QAC3D,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;QAC1C,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,SAAgB,SAAS;IACvB,OAAO,IAAA,oBAAU,EAAC,IAAA,mBAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC,CAAA;AACnD,CAAC;AAED,SAAgB,kBAAkB;IAChC,IAAI,CAAC;QACH,OAAO,IAAA,6BAAQ,EAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,SAAgB,aAAa;IAC3B,IAAI,CAAC;QACH,OAAO,IAAA,6BAAQ,EAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACvF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,SAAgB,iBAAiB;IAC/B,IAAI,CAAC;QACH,OAAO,IAAA,6BAAQ,EAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACxF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,SAAgB,aAAa;IAC3B,IAAI,CAAC;QACH,OAAO,IAAA,6BAAQ,EAAC,sBAAsB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC1F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const init_1 = require("./commands/init");
5
+ const scan_1 = require("./commands/scan");
6
+ const context_1 = require("./commands/context");
7
+ const install_skill_1 = require("./commands/install-skill");
8
+ const login_1 = require("./commands/login");
9
+ async function main() {
10
+ const args = process.argv.slice(2);
11
+ const command = args[0];
12
+ switch (command) {
13
+ case 'init':
14
+ await (0, init_1.initCommand)();
15
+ break;
16
+ case 'scan':
17
+ await (0, scan_1.scanCommand)(args.slice(1));
18
+ break;
19
+ case 'context':
20
+ await (0, context_1.contextCommand)(args.slice(1));
21
+ break;
22
+ case 'install-skill':
23
+ (0, install_skill_1.installSkillCommand)();
24
+ break;
25
+ case 'login':
26
+ (0, login_1.loginCommand)(args.slice(1));
27
+ break;
28
+ case undefined:
29
+ case '--help':
30
+ case '-h':
31
+ console.log(`Driftless CLI v0.1.0
32
+
33
+ Usage:
34
+ driftless login --key <key> Authenticate with API key
35
+ driftless init Connect repo, scan, suggest rules
36
+ driftless scan Scan staged + uncommitted changes
37
+ driftless scan --diff Scan uncommitted changes only
38
+ driftless context list List all watchers
39
+ driftless context get <name> Get watcher context
40
+ driftless context add <name> Create new watcher
41
+ driftless install-skill Install AGENTS.md skill
42
+
43
+ Auth priority:
44
+ 1. DRIFTLESS_API_KEY env var
45
+ 2. ~/.driftless/config.json
46
+
47
+ Environment:
48
+ DRIFTLESS_API_URL API server URL (default: http://localhost:3000/api/v1)
49
+ `);
50
+ break;
51
+ default:
52
+ console.error(`Unknown command: ${command}`);
53
+ console.error('Run driftless --help for usage.');
54
+ process.exit(1);
55
+ }
56
+ }
57
+ main().catch((err) => {
58
+ console.error('Error:', err.message);
59
+ process.exit(1);
60
+ });
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,0CAA6C;AAC7C,0CAA6C;AAC7C,gDAAmD;AACnD,4DAA8D;AAC9D,4CAA+C;AAE/C,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;IAEvB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,MAAM,IAAA,kBAAW,GAAE,CAAA;YACnB,MAAK;QACP,KAAK,MAAM;YACT,MAAM,IAAA,kBAAW,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YAChC,MAAK;QACP,KAAK,SAAS;YACZ,MAAM,IAAA,wBAAc,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YACnC,MAAK;QACP,KAAK,eAAe;YAClB,IAAA,mCAAmB,GAAE,CAAA;YACrB,MAAK;QACP,KAAK,OAAO;YACV,IAAA,oBAAY,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YAC3B,MAAK;QACP,KAAK,SAAS,CAAC;QACf,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI;YACP,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;CAkBjB,CAAC,CAAA;YACI,MAAK;QACP;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAA;YAC5C,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAA;YAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@driftless-sh/cli",
3
+ "version": "0.1.0",
4
+ "description": "Driftless CLI — context integrity for AI engineering teams",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/driftless-sh/driftless-skill.git"
9
+ },
10
+ "bin": {
11
+ "driftless": "dist/index.js"
12
+ },
13
+ "files": [
14
+ "dist/"
15
+ ],
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "clean": "rm -rf dist"
22
+ },
23
+ "devDependencies": {
24
+ "typescript": "^5.8.3",
25
+ "@types/node": "^22.15.3"
26
+ }
27
+ }