@devcortex/cli 1.3.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/dist/commands/export.d.ts +9 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +49 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/import.d.ts +21 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +237 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/init.d.ts +22 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +225 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/issue.d.ts +8 -0
- package/dist/commands/issue.d.ts.map +1 -0
- package/dist/commands/issue.js +42 -0
- package/dist/commands/issue.js.map +1 -0
- package/dist/commands/keys.d.ts +23 -0
- package/dist/commands/keys.d.ts.map +1 -0
- package/dist/commands/keys.js +133 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/list.d.ts +20 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +163 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +9 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +91 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logs.d.ts +22 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +172 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/start.d.ts +9 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +88 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +22 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +179 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/test-mcp.d.ts +7 -0
- package/dist/commands/test-mcp.d.ts.map +1 -0
- package/dist/commands/test-mcp.js +115 -0
- package/dist/commands/test-mcp.js.map +1 -0
- package/dist/commands/update.d.ts +9 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +124 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +8 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +30 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth.d.ts +20 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +16 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/config.d.ts +16 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +29 -0
- package/dist/lib/config.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
export interface ExportOptions {
|
|
3
|
+
csv?: boolean;
|
|
4
|
+
out?: string;
|
|
5
|
+
apiUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function runExportCsv(opts: ExportOptions, cwd?: string): Promise<void>;
|
|
8
|
+
export declare function registerExport(program: Command): void;
|
|
9
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,SAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB1F;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgBrD"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// REQ-079: dcx export — CSV export of requirements.
|
|
2
|
+
import { writeFileSync } from 'node:fs';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { readLinkFile } from './init.js';
|
|
5
|
+
import { apiRequest } from '../lib/api.js';
|
|
6
|
+
import { getToken } from '../lib/config.js';
|
|
7
|
+
export async function runExportCsv(opts, cwd = process.cwd()) {
|
|
8
|
+
const link = readLinkFile(cwd);
|
|
9
|
+
if (!link) {
|
|
10
|
+
console.error('✗ No project linked. Run dcx init first.');
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
const apiUrl = opts.apiUrl ?? link.apiUrl;
|
|
14
|
+
const res = await apiRequest(`/organisations/${link.orgSlug}/projects/${link.projectId}/requirements/export/csv`, {}, apiUrl);
|
|
15
|
+
if (!res.ok) {
|
|
16
|
+
console.error(`✗ Export failed: HTTP ${res.status}`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const csv = await res.text();
|
|
20
|
+
if (opts.out) {
|
|
21
|
+
const outPath = resolve(cwd, opts.out);
|
|
22
|
+
writeFileSync(outPath, csv, 'utf-8');
|
|
23
|
+
console.log(`✓ Exported to ${outPath}`);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
process.stdout.write(csv);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function registerExport(program) {
|
|
30
|
+
program
|
|
31
|
+
.command('export')
|
|
32
|
+
.description('Export project data')
|
|
33
|
+
.option('--csv', 'Export requirements as CSV')
|
|
34
|
+
.option('--out <file>', 'Write output to file instead of stdout')
|
|
35
|
+
.option('--api-url <url>', 'API URL override')
|
|
36
|
+
.action(async (opts) => {
|
|
37
|
+
const token = getToken();
|
|
38
|
+
if (!token) {
|
|
39
|
+
console.error('✗ Not logged in — run dcx login first');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
if (!opts.csv) {
|
|
43
|
+
console.error('✗ Specify --csv to export requirements');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
await runExportCsv(opts);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAQ5C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAmB,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IACzE,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,CAAC;QAAC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IAE1F,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;IAC1C,MAAM,GAAG,GAAG,MAAM,UAAU,CAC1B,kBAAkB,IAAI,CAAC,OAAO,aAAa,IAAI,CAAC,SAAS,0BAA0B,EACnF,EAAE,EACF,MAAM,CACP,CAAC;IAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,yBAAyB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACvC,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;IAC1C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,qBAAqB,CAAC;SAClC,MAAM,CAAC,OAAO,EAAE,4BAA4B,CAAC;SAC7C,MAAM,CAAC,cAAc,EAAE,wCAAwC,CAAC;SAChE,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;SAC7C,MAAM,CAAC,KAAK,EAAE,IAAmB,EAAE,EAAE;QACpC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,KAAK,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QACxF,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
export interface ImportOptions {
|
|
3
|
+
csv?: string;
|
|
4
|
+
dryRun?: boolean;
|
|
5
|
+
apiUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
type MatchType = 'exact' | 'alias' | 'fuzzy' | 'unknown';
|
|
8
|
+
export interface ColumnMatch {
|
|
9
|
+
original: string;
|
|
10
|
+
canonical: string | null;
|
|
11
|
+
matchType: MatchType;
|
|
12
|
+
}
|
|
13
|
+
export declare function resolveColumn(header: string): ColumnMatch;
|
|
14
|
+
export declare function parseCSV(raw: string): {
|
|
15
|
+
headers: string[];
|
|
16
|
+
rows: Record<string, string>[];
|
|
17
|
+
};
|
|
18
|
+
export declare function runImportCsv(opts: ImportOptions, cwd?: string): Promise<void>;
|
|
19
|
+
export declare function registerImport(program: Command): void;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,KAAK,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,SAAS,CAAC;CACtB;AAmCD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CA6BzD;AAwBD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;CAAE,CAW3F;AAoGD,wBAAsB,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,SAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C1F;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAYrD"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// REQ-080 / REQ-105: dcx import — CSV import with dry-run and column validation
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { basename, resolve } from 'node:path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { readLinkFile } from './init.js';
|
|
6
|
+
import { apiJson } from '../lib/api.js';
|
|
7
|
+
import { getToken } from '../lib/config.js';
|
|
8
|
+
// ─── Column alias map ─────────────────────────────────────────────────────────
|
|
9
|
+
// All alias values stored lowercase — comparison is always lower-cased input vs these.
|
|
10
|
+
const FIELD_ALIASES = {
|
|
11
|
+
title: ['title', 'name'],
|
|
12
|
+
userStory: ['userstory', 'user_story', 'user story'],
|
|
13
|
+
acceptanceCriteria: ['acceptancecriteria', 'acceptance_criteria', 'acs'],
|
|
14
|
+
description: ['description'],
|
|
15
|
+
priority: ['priority'],
|
|
16
|
+
sprint: ['sprint', 'sprintnumber', 'sprint_number'],
|
|
17
|
+
};
|
|
18
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
19
|
+
function levenshtein(a, b) {
|
|
20
|
+
const m = a.length;
|
|
21
|
+
const n = b.length;
|
|
22
|
+
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
23
|
+
for (let i = 0; i <= m; i++)
|
|
24
|
+
dp[i][0] = i;
|
|
25
|
+
for (let j = 0; j <= n; j++)
|
|
26
|
+
dp[0][j] = j;
|
|
27
|
+
for (let i = 1; i <= m; i++) {
|
|
28
|
+
for (let j = 1; j <= n; j++) {
|
|
29
|
+
dp[i][j] =
|
|
30
|
+
a[i - 1] === b[j - 1]
|
|
31
|
+
? dp[i - 1][j - 1]
|
|
32
|
+
: 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return dp[m][n];
|
|
36
|
+
}
|
|
37
|
+
export function resolveColumn(header) {
|
|
38
|
+
const lower = header.toLowerCase();
|
|
39
|
+
for (const [canonical, aliases] of Object.entries(FIELD_ALIASES)) {
|
|
40
|
+
if (lower === canonical.toLowerCase()) {
|
|
41
|
+
return { original: header, canonical, matchType: 'exact' };
|
|
42
|
+
}
|
|
43
|
+
if (aliases.includes(lower)) {
|
|
44
|
+
return { original: header, canonical, matchType: 'alias' };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Fuzzy: closest canonical name or alias within edit distance ≤ 2
|
|
48
|
+
let bestDist = Infinity;
|
|
49
|
+
let bestCanonical = null;
|
|
50
|
+
for (const [canonical, aliases] of Object.entries(FIELD_ALIASES)) {
|
|
51
|
+
for (const candidate of [canonical.toLowerCase(), ...aliases]) {
|
|
52
|
+
const d = levenshtein(lower, candidate);
|
|
53
|
+
if (d < bestDist) {
|
|
54
|
+
bestDist = d;
|
|
55
|
+
bestCanonical = canonical;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (bestDist <= 2 && bestCanonical !== null) {
|
|
60
|
+
return { original: header, canonical: bestCanonical, matchType: 'fuzzy' };
|
|
61
|
+
}
|
|
62
|
+
return { original: header, canonical: null, matchType: 'unknown' };
|
|
63
|
+
}
|
|
64
|
+
// ─── CSV parser ───────────────────────────────────────────────────────────────
|
|
65
|
+
function parseCSVLine(line) {
|
|
66
|
+
const fields = [];
|
|
67
|
+
let current = '';
|
|
68
|
+
let inQuotes = false;
|
|
69
|
+
for (let i = 0; i < line.length; i++) {
|
|
70
|
+
const ch = line[i];
|
|
71
|
+
if (ch === '"') {
|
|
72
|
+
if (inQuotes && line[i + 1] === '"') {
|
|
73
|
+
current += '"';
|
|
74
|
+
i++;
|
|
75
|
+
}
|
|
76
|
+
else
|
|
77
|
+
inQuotes = !inQuotes;
|
|
78
|
+
}
|
|
79
|
+
else if (ch === ',' && !inQuotes) {
|
|
80
|
+
fields.push(current.trim());
|
|
81
|
+
current = '';
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
current += ch;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
fields.push(current.trim());
|
|
88
|
+
return fields;
|
|
89
|
+
}
|
|
90
|
+
export function parseCSV(raw) {
|
|
91
|
+
const lines = raw.split(/\r?\n/).filter(l => l.trim().length > 0);
|
|
92
|
+
if (lines.length === 0)
|
|
93
|
+
return { headers: [], rows: [] };
|
|
94
|
+
const headers = parseCSVLine(lines[0]);
|
|
95
|
+
const rows = lines.slice(1).map(line => {
|
|
96
|
+
const values = parseCSVLine(line);
|
|
97
|
+
const row = {};
|
|
98
|
+
headers.forEach((h, i) => { row[h] = values[i] ?? ''; });
|
|
99
|
+
return row;
|
|
100
|
+
});
|
|
101
|
+
return { headers, rows };
|
|
102
|
+
}
|
|
103
|
+
function countPipeValues(value) {
|
|
104
|
+
if (!value.trim())
|
|
105
|
+
return 0;
|
|
106
|
+
return value.split('|').filter(v => v.trim().length > 0).length;
|
|
107
|
+
}
|
|
108
|
+
// ─── Dry-run output ───────────────────────────────────────────────────────────
|
|
109
|
+
function printDryRunBox(filename, rows, acs) {
|
|
110
|
+
const title = 'DCX Import Dry Run';
|
|
111
|
+
const contentLines = [
|
|
112
|
+
`File: ${filename}`,
|
|
113
|
+
`Rows detected: ${rows}`,
|
|
114
|
+
`Estimated ACs: ${acs}`,
|
|
115
|
+
];
|
|
116
|
+
const innerWidth = Math.max(title.length + 6, ...contentLines.map(l => l.length + 4));
|
|
117
|
+
console.log(`┌─ ${title} ${'─'.repeat(innerWidth - title.length - 2)}┐`);
|
|
118
|
+
for (const line of contentLines) {
|
|
119
|
+
console.log(`│ ${line.padEnd(innerWidth - 2)}│`);
|
|
120
|
+
}
|
|
121
|
+
console.log(`└${'─'.repeat(innerWidth)}┘`);
|
|
122
|
+
}
|
|
123
|
+
function formatColumnLine(match) {
|
|
124
|
+
const { original, canonical, matchType } = match;
|
|
125
|
+
const origPadded = original.padEnd(14);
|
|
126
|
+
if (matchType === 'exact') {
|
|
127
|
+
return chalk.green(`✓ ${origPadded} → ${canonical}`);
|
|
128
|
+
}
|
|
129
|
+
if (matchType === 'alias') {
|
|
130
|
+
return chalk.green(`✓ ${origPadded} → ${canonical}`) + chalk.dim(' (alias matched)');
|
|
131
|
+
}
|
|
132
|
+
if (matchType === 'fuzzy') {
|
|
133
|
+
return chalk.yellow(`⚠ ${origPadded} → ${canonical}`) + chalk.dim(' (possible typo? matched fuzzy)');
|
|
134
|
+
}
|
|
135
|
+
return chalk.red(`✗ ${origPadded} → NOT RECOGNISED (will be ignored)`);
|
|
136
|
+
}
|
|
137
|
+
function printDryRunReport(filename, headers, rows, matches) {
|
|
138
|
+
const acMatch = matches.find(m => m.canonical === 'acceptanceCriteria');
|
|
139
|
+
const totalAcs = acMatch
|
|
140
|
+
? rows.reduce((sum, row) => sum + countPipeValues(row[acMatch.original] ?? ''), 0)
|
|
141
|
+
: 0;
|
|
142
|
+
printDryRunBox(filename, rows.length, totalAcs);
|
|
143
|
+
console.log('\nColumn mapping detected:');
|
|
144
|
+
for (const match of matches) {
|
|
145
|
+
console.log(formatColumnLine(match));
|
|
146
|
+
}
|
|
147
|
+
// Warn on missing important columns (AC-4)
|
|
148
|
+
const found = new Set(matches.map(m => m.canonical).filter(Boolean));
|
|
149
|
+
for (const field of ['title', 'userStory', 'priority']) {
|
|
150
|
+
if (!found.has(field)) {
|
|
151
|
+
console.log(chalk.yellow(`⚠ ${'(missing)'.padEnd(14)} → ${field} column not found in CSV`));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Preview first 3 rows (AC-5)
|
|
155
|
+
if (rows.length > 0) {
|
|
156
|
+
const titleMatch = matches.find(m => m.canonical === 'title');
|
|
157
|
+
const priorityMatch = matches.find(m => m.canonical === 'priority');
|
|
158
|
+
const idField = headers.find(h => ['reqid', 'req_id', 'id'].includes(h.toLowerCase()));
|
|
159
|
+
console.log('\nPreview (first 3 rows):');
|
|
160
|
+
rows.slice(0, 3).forEach((row, i) => {
|
|
161
|
+
const id = idField ? (row[idField] ?? `Row ${i + 1}`) : `Row ${i + 1}`;
|
|
162
|
+
const title = titleMatch ? (row[titleMatch.original] ?? '—') : '—';
|
|
163
|
+
const priority = priorityMatch ? (row[priorityMatch.original] ?? '—') : '—';
|
|
164
|
+
const acCount = acMatch ? countPipeValues(row[acMatch.original] ?? '') : 0;
|
|
165
|
+
console.log(` Row ${i + 1}: ${id} | "${title}" | ${priority} | ${acCount} ACs`);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
console.log(chalk.dim('\n Run without --dry-run to import.'));
|
|
169
|
+
}
|
|
170
|
+
// ─── CSV normalisation for live import ───────────────────────────────────────
|
|
171
|
+
function normalizeCSVHeaders(raw, matches) {
|
|
172
|
+
const firstNewline = raw.indexOf('\n');
|
|
173
|
+
const rest = firstNewline >= 0 ? raw.slice(firstNewline) : '';
|
|
174
|
+
const normalizedHeaders = matches
|
|
175
|
+
.map(m => {
|
|
176
|
+
const h = m.canonical ?? m.original;
|
|
177
|
+
return h.includes(',') ? `"${h}"` : h;
|
|
178
|
+
})
|
|
179
|
+
.join(',');
|
|
180
|
+
return normalizedHeaders + rest;
|
|
181
|
+
}
|
|
182
|
+
// ─── Main command ─────────────────────────────────────────────────────────────
|
|
183
|
+
export async function runImportCsv(opts, cwd = process.cwd()) {
|
|
184
|
+
const link = readLinkFile(cwd);
|
|
185
|
+
if (!link) {
|
|
186
|
+
console.error('✗ No project linked. Run dcx init first.');
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
if (!opts.csv) {
|
|
190
|
+
console.error('✗ Specify --csv <filepath>');
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
const filePath = resolve(cwd, opts.csv);
|
|
194
|
+
let csv;
|
|
195
|
+
try {
|
|
196
|
+
csv = readFileSync(filePath, 'utf-8');
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
console.error(`✗ Could not read file: ${filePath}`);
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
202
|
+
const { headers, rows } = parseCSV(csv);
|
|
203
|
+
if (headers.length === 0) {
|
|
204
|
+
console.error('✗ CSV file is empty or has no headers');
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
const matches = headers.map(resolveColumn);
|
|
208
|
+
if (opts.dryRun) {
|
|
209
|
+
printDryRunReport(basename(filePath), headers, rows, matches);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
// Live import: normalise headers client-side before sending (AC-7)
|
|
213
|
+
const normalizedCsv = normalizeCSVHeaders(csv, matches);
|
|
214
|
+
const apiUrl = opts.apiUrl ?? link.apiUrl;
|
|
215
|
+
const base = `/organisations/${link.orgSlug}/projects/${link.projectId}/requirements`;
|
|
216
|
+
const result = await apiJson(`${base}/import/csv`, { method: 'POST', body: JSON.stringify({ csv: normalizedCsv }) }, apiUrl);
|
|
217
|
+
console.log(`\n✓ Import complete for ${link.projectName}:`);
|
|
218
|
+
console.log(` Created: ${result.created}`);
|
|
219
|
+
console.log(` Skipped: ${result.skipped}`);
|
|
220
|
+
}
|
|
221
|
+
export function registerImport(program) {
|
|
222
|
+
program
|
|
223
|
+
.command('import')
|
|
224
|
+
.description('Import project data')
|
|
225
|
+
.option('--csv <filepath>', 'Import requirements from CSV file')
|
|
226
|
+
.option('--dry-run', 'Preview column mappings and first 3 rows without importing')
|
|
227
|
+
.option('--api-url <url>', 'API URL override')
|
|
228
|
+
.action(async (opts) => {
|
|
229
|
+
const token = getToken();
|
|
230
|
+
if (!token) {
|
|
231
|
+
console.error('✗ Not logged in — run dcx login first');
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
await runImportCsv(opts);
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
type Stack = 'pnpm' | 'yarn' | 'npm' | 'python' | 'rust' | 'go';
|
|
3
|
+
export declare function detectStack(cwd: string): Stack;
|
|
4
|
+
export declare function substituteStackCommands(content: string, stack: Stack): string;
|
|
5
|
+
export interface InitOptions {
|
|
6
|
+
project?: string;
|
|
7
|
+
agent?: string;
|
|
8
|
+
force?: boolean;
|
|
9
|
+
apiUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface LinkFile {
|
|
12
|
+
orgSlug: string;
|
|
13
|
+
projectId: string;
|
|
14
|
+
projectName: string;
|
|
15
|
+
apiUrl: string;
|
|
16
|
+
linkedAt: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function runInit(opts: InitOptions, cwd?: string): Promise<void>;
|
|
19
|
+
export declare function registerInit(program: Command): void;
|
|
20
|
+
export declare function readLinkFile(cwd?: string): LinkFile | null;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,KAAK,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;AAEhE,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAQ9C;AAWD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAM7E;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAgCD,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,SAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoMnF;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAYnD;AAED,wBAAgB,YAAY,CAAC,GAAG,SAAgB,GAAG,QAAQ,GAAG,IAAI,CAQjE"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import * as clack from '@clack/prompts';
|
|
2
|
+
import { writeFileSync, existsSync, readFileSync, appendFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { config, getApiUrl, getToken } from '../lib/config.js';
|
|
5
|
+
import { apiJson } from '../lib/api.js';
|
|
6
|
+
export function detectStack(cwd) {
|
|
7
|
+
if (existsSync(join(cwd, 'pnpm-lock.yaml')))
|
|
8
|
+
return 'pnpm';
|
|
9
|
+
if (existsSync(join(cwd, 'yarn.lock')))
|
|
10
|
+
return 'yarn';
|
|
11
|
+
if (existsSync(join(cwd, 'package-lock.json')) || existsSync(join(cwd, 'package.json')))
|
|
12
|
+
return 'npm';
|
|
13
|
+
if (existsSync(join(cwd, 'pyproject.toml')) || existsSync(join(cwd, 'requirements.txt')))
|
|
14
|
+
return 'python';
|
|
15
|
+
if (existsSync(join(cwd, 'Cargo.toml')))
|
|
16
|
+
return 'rust';
|
|
17
|
+
if (existsSync(join(cwd, 'go.mod')))
|
|
18
|
+
return 'go';
|
|
19
|
+
return 'npm';
|
|
20
|
+
}
|
|
21
|
+
const STACK_COMMANDS = {
|
|
22
|
+
pnpm: { typecheck: 'pnpm typecheck', lint: 'pnpm lint', test: 'pnpm test' },
|
|
23
|
+
yarn: { typecheck: 'yarn typecheck', lint: 'yarn lint', test: 'yarn test' },
|
|
24
|
+
npm: { typecheck: 'npm run typecheck', lint: 'npm run lint', test: 'npm test' },
|
|
25
|
+
python: { typecheck: 'mypy .', lint: 'ruff check .', test: 'pytest' },
|
|
26
|
+
rust: { typecheck: 'cargo check', lint: 'cargo clippy', test: 'cargo test' },
|
|
27
|
+
go: { typecheck: 'go build ./...', lint: 'golangci-lint run', test: 'go test ./...' },
|
|
28
|
+
};
|
|
29
|
+
export function substituteStackCommands(content, stack) {
|
|
30
|
+
const cmds = STACK_COMMANDS[stack];
|
|
31
|
+
return content
|
|
32
|
+
.replace('npm run typecheck', cmds.typecheck)
|
|
33
|
+
.replace('npm run lint', cmds.lint)
|
|
34
|
+
.replace('npm test', cmds.test);
|
|
35
|
+
}
|
|
36
|
+
export async function runInit(opts, cwd = process.cwd()) {
|
|
37
|
+
// AC-1: Check login
|
|
38
|
+
const token = getToken();
|
|
39
|
+
if (!token) {
|
|
40
|
+
console.error('✗ Not logged in — run dcx login first');
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
// REQ-102: Warn before overwriting an existing project link file (AC-1 through AC-6)
|
|
44
|
+
const existingLink = readLinkFile(cwd);
|
|
45
|
+
if (existingLink && !opts.force) {
|
|
46
|
+
const linkedDate = new Date(existingLink.linkedAt).toLocaleDateString();
|
|
47
|
+
clack.note(`Current project link: ${existingLink.orgSlug} / ${existingLink.projectName} (linked ${linkedDate})`);
|
|
48
|
+
clack.log.warn('This will overwrite your existing project link.');
|
|
49
|
+
const confirmOverwrite = await clack.confirm({
|
|
50
|
+
message: 'Continue and overwrite?',
|
|
51
|
+
initialValue: false,
|
|
52
|
+
});
|
|
53
|
+
if (clack.isCancel(confirmOverwrite) || !confirmOverwrite) {
|
|
54
|
+
clack.cancel('Aborted. Your existing project link has not been changed.');
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// REQ-102: Read apiUrl from existing link file before falling back to global config
|
|
59
|
+
const apiUrl = getApiUrl(opts.apiUrl ?? existingLink?.apiUrl);
|
|
60
|
+
// AC-8: Overwrite confirmation for existing .mcp.json
|
|
61
|
+
const mcpPath = join(cwd, '.mcp.json');
|
|
62
|
+
if (existsSync(mcpPath) && !opts.force) {
|
|
63
|
+
const confirm = await clack.confirm({
|
|
64
|
+
message: '.mcp.json already exists. Overwrite?',
|
|
65
|
+
});
|
|
66
|
+
if (clack.isCancel(confirm) || !confirm) {
|
|
67
|
+
clack.cancel('Cancelled');
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const s = clack.spinner();
|
|
72
|
+
s.start('Loading projects...');
|
|
73
|
+
let projects = [];
|
|
74
|
+
// BUG 2 fix: fall back to .devcortex-link.json when config.json is missing
|
|
75
|
+
let orgSlug = config.get('defaultOrgSlug');
|
|
76
|
+
if (!orgSlug && existingLink) {
|
|
77
|
+
orgSlug = existingLink.orgSlug;
|
|
78
|
+
}
|
|
79
|
+
if (!orgSlug) {
|
|
80
|
+
s.stop('');
|
|
81
|
+
console.error('✗ Not logged in — run dcx login first');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const res = await apiJson(`/organisations/${orgSlug}/projects`, {}, opts.apiUrl);
|
|
86
|
+
projects = res.data;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
s.stop('');
|
|
90
|
+
console.error(`✗ API unreachable at ${apiUrl} — is pnpm dev running?`);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
s.stop('');
|
|
94
|
+
// AC-2: Project selection
|
|
95
|
+
let selectedProject;
|
|
96
|
+
if (opts.project) {
|
|
97
|
+
selectedProject = projects.find((p) => p.id === opts.project);
|
|
98
|
+
}
|
|
99
|
+
else if (projects.length === 1) {
|
|
100
|
+
selectedProject = projects[0];
|
|
101
|
+
}
|
|
102
|
+
else if (projects.length > 1) {
|
|
103
|
+
const choice = await clack.select({
|
|
104
|
+
message: 'Select project',
|
|
105
|
+
options: projects.map((p) => ({ value: p.id, label: p.name })),
|
|
106
|
+
});
|
|
107
|
+
if (clack.isCancel(choice)) {
|
|
108
|
+
clack.cancel('Cancelled');
|
|
109
|
+
process.exit(0);
|
|
110
|
+
}
|
|
111
|
+
selectedProject = projects.find((p) => p.id === choice);
|
|
112
|
+
}
|
|
113
|
+
if (!selectedProject) {
|
|
114
|
+
console.error('✗ No project found');
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
const resolvedOrgSlug = selectedProject.orgSlug ?? orgSlug;
|
|
118
|
+
// AC-3: Generate API key — revoke old dcx CLI keys first to stay under the 10-key limit
|
|
119
|
+
const date = new Date().toISOString().slice(0, 10).replace(/-/g, '');
|
|
120
|
+
const keyName = `dcx-${date}`;
|
|
121
|
+
const s2 = clack.spinner();
|
|
122
|
+
s2.start('Rotating API key...');
|
|
123
|
+
try {
|
|
124
|
+
const existing = await apiJson(`/organisations/${resolvedOrgSlug}/projects/${selectedProject.id}/api-keys`, {}, opts.apiUrl);
|
|
125
|
+
const staleKeys = existing.data.filter((k) => k.revokedAt === null && k.name.startsWith('dcx-'));
|
|
126
|
+
for (const k of staleKeys) {
|
|
127
|
+
await apiJson(`/organisations/${resolvedOrgSlug}/projects/${selectedProject.id}/api-keys/${k.id}`, { method: 'DELETE' }, opts.apiUrl);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// non-fatal — proceed and let the create call surface any real limit errors
|
|
132
|
+
}
|
|
133
|
+
let newKey;
|
|
134
|
+
try {
|
|
135
|
+
newKey = await apiJson(`/organisations/${resolvedOrgSlug}/projects/${selectedProject.id}/api-keys`, { method: 'POST', body: JSON.stringify({ name: keyName }) }, opts.apiUrl);
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
s2.stop('');
|
|
139
|
+
console.error(`✗ Failed to generate API key: ${err.message}`);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
// AC-4: Write .mcp.json
|
|
143
|
+
const mcpContent = JSON.stringify({
|
|
144
|
+
mcpServers: {
|
|
145
|
+
devcortex: {
|
|
146
|
+
type: 'http',
|
|
147
|
+
url: `${apiUrl}/mcp`,
|
|
148
|
+
headers: { 'x-api-key': newKey.key },
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
}, null, 2);
|
|
152
|
+
writeFileSync(mcpPath, mcpContent);
|
|
153
|
+
// AC-5: Fetch and write constitution
|
|
154
|
+
let constitution = '';
|
|
155
|
+
try {
|
|
156
|
+
const res = await apiJson(`/organisations/${resolvedOrgSlug}/projects/${selectedProject.id}/constitution`, {}, opts.apiUrl);
|
|
157
|
+
constitution = res.content;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// non-fatal
|
|
161
|
+
}
|
|
162
|
+
const agentFile = opts.agent === 'opencode' ? 'AGENTS.md' : 'CLAUDE.md';
|
|
163
|
+
const stack = detectStack(cwd);
|
|
164
|
+
writeFileSync(join(cwd, agentFile), substituteStackCommands(constitution, stack));
|
|
165
|
+
// AC-6: Write .devcortex-link.json
|
|
166
|
+
const link = {
|
|
167
|
+
orgSlug: resolvedOrgSlug,
|
|
168
|
+
projectId: selectedProject.id,
|
|
169
|
+
projectName: selectedProject.name,
|
|
170
|
+
apiUrl,
|
|
171
|
+
linkedAt: new Date().toISOString(),
|
|
172
|
+
};
|
|
173
|
+
writeFileSync(join(cwd, '.devcortex-link.json'), JSON.stringify(link, null, 2));
|
|
174
|
+
// AC-7: Add .mcp.json to .gitignore
|
|
175
|
+
const gitignorePath = join(cwd, '.gitignore');
|
|
176
|
+
const gitignoreContent = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf8') : '';
|
|
177
|
+
if (!gitignoreContent.includes('.mcp.json')) {
|
|
178
|
+
appendFileSync(gitignorePath, '\n# DevCortex CLI\n.mcp.json\n');
|
|
179
|
+
}
|
|
180
|
+
s2.stop('Rotating API key...');
|
|
181
|
+
// DEF-010: Ask about auto-update watch mode preference
|
|
182
|
+
const watchEnabled = await clack.confirm({
|
|
183
|
+
message: `Enable auto-update? (dcx update --watch will keep ${agentFile} in sync)`,
|
|
184
|
+
});
|
|
185
|
+
if (!clack.isCancel(watchEnabled)) {
|
|
186
|
+
config.set('watchEnabled', watchEnabled);
|
|
187
|
+
}
|
|
188
|
+
// AC-9: Completion summary
|
|
189
|
+
const watchNote = !clack.isCancel(watchEnabled) && watchEnabled
|
|
190
|
+
? `→ Auto-update enabled — run: dcx update --watch`
|
|
191
|
+
: `→ Run dcx start to launch Claude Code`;
|
|
192
|
+
clack.note([
|
|
193
|
+
`✔ API key generated: ${keyName}`,
|
|
194
|
+
`✔ .mcp.json written`,
|
|
195
|
+
`✔ ${agentFile} written`,
|
|
196
|
+
`✔ .devcortex-link.json written`,
|
|
197
|
+
`✔ .gitignore updated`,
|
|
198
|
+
watchNote,
|
|
199
|
+
].join('\n'));
|
|
200
|
+
}
|
|
201
|
+
export function registerInit(program) {
|
|
202
|
+
program
|
|
203
|
+
.command('init')
|
|
204
|
+
.description('Link current directory to a DevCortex project')
|
|
205
|
+
.option('--project <id>', 'Project ID (skip selection)')
|
|
206
|
+
.option('--agent <name>', 'Agent type: claude (default) | opencode')
|
|
207
|
+
.option('--force', 'Overwrite existing .mcp.json and CLAUDE.md')
|
|
208
|
+
.option('--api-url <url>', 'API URL override')
|
|
209
|
+
.action(async (opts) => {
|
|
210
|
+
clack.intro('DevCortex Init');
|
|
211
|
+
await runInit(opts);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
export function readLinkFile(cwd = process.cwd()) {
|
|
215
|
+
const p = join(cwd, '.devcortex-link.json');
|
|
216
|
+
if (!existsSync(p))
|
|
217
|
+
return null;
|
|
218
|
+
try {
|
|
219
|
+
return JSON.parse(readFileSync(p, 'utf8'));
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAKxC,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC3D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACtD,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACtG,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC1G,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACvD,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,cAAc,GAAqE;IACvF,IAAI,EAAI,EAAE,SAAS,EAAE,gBAAgB,EAAM,IAAI,EAAE,WAAW,EAAS,IAAI,EAAE,WAAW,EAAE;IACxF,IAAI,EAAI,EAAE,SAAS,EAAE,gBAAgB,EAAM,IAAI,EAAE,WAAW,EAAS,IAAI,EAAE,WAAW,EAAE;IACxF,GAAG,EAAK,EAAE,SAAS,EAAE,mBAAmB,EAAG,IAAI,EAAE,cAAc,EAAM,IAAI,EAAE,UAAU,EAAE;IACvF,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAa,IAAI,EAAE,cAAc,EAAM,IAAI,EAAE,QAAQ,EAAE;IACpF,IAAI,EAAI,EAAE,SAAS,EAAE,aAAa,EAAQ,IAAI,EAAE,cAAc,EAAM,IAAI,EAAE,YAAY,EAAE;IACxF,EAAE,EAAM,EAAE,SAAS,EAAE,gBAAgB,EAAK,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,eAAe,EAAE;CAC7F,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,OAAe,EAAE,KAAY;IACnE,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,OAAO;SACX,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC,SAAS,CAAC;SAC5C,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC;SAClC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AA+CD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAiB,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAClE,oBAAoB;IACpB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,qFAAqF;IACrF,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,YAAY,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,kBAAkB,EAAE,CAAC;QACxE,KAAK,CAAC,IAAI,CACR,yBAAyB,YAAY,CAAC,OAAO,MAAM,YAAY,CAAC,WAAW,YAAY,UAAU,GAAG,CACrG,CAAC;QACF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;QAClE,MAAM,gBAAgB,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;YAC3C,OAAO,EAAE,yBAAyB;YAClC,YAAY,EAAE,KAAK;SACpB,CAAC,CAAC;QACH,IAAI,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1D,KAAK,CAAC,MAAM,CAAC,2DAA2D,CAAC,CAAC;YAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,oFAAoF;IACpF,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,IAAI,YAAY,EAAE,MAAM,CAAC,CAAC;IAE9D,sDAAsD;IACtD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACvC,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;YAClC,OAAO,EAAE,sCAAsC;SAChD,CAAC,CAAC;QACH,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACxC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAE/B,IAAI,QAAQ,GAAc,EAAE,CAAC;IAC7B,2EAA2E;IAC3E,IAAI,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAuB,CAAC;IACjE,IAAI,CAAC,OAAO,IAAI,YAAY,EAAE,CAAC;QAC7B,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC;IACjC,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAmB,kBAAkB,OAAO,WAAW,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACnG,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,wBAAwB,MAAM,yBAAyB,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEX,0BAA0B;IAC1B,IAAI,eAAoC,CAAC;IACzC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC;IAChE,CAAC;SAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,eAAe,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;SAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC;YAChC,OAAO,EAAE,gBAAgB;YACzB,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;SAC/D,CAAC,CAAC;QACH,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QAC3E,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,eAAe,GAAG,eAAe,CAAC,OAAO,IAAI,OAAO,CAAC;IAE3D,wFAAwF;IACxF,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;IAC9B,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAC3B,EAAE,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,kBAAkB,eAAe,aAAa,eAAe,CAAC,EAAE,WAAW,EAC3E,EAAE,EACF,IAAI,CAAC,MAAM,CACZ,CAAC;QACF,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CACzD,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,MAAM,OAAO,CACX,kBAAkB,eAAe,aAAa,eAAe,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,EAAE,EACnF,EAAE,MAAM,EAAE,QAAQ,EAAE,EACpB,IAAI,CAAC,MAAM,CACZ,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;IAC9E,CAAC;IAED,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,OAAO,CACpB,kBAAkB,eAAe,aAAa,eAAe,CAAC,EAAE,WAAW,EAC3E,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,EAC3D,IAAI,CAAC,MAAM,CACZ,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,iCAAkC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,wBAAwB;IACxB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,UAAU,EAAE;YACV,SAAS,EAAE;gBACT,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,GAAG,MAAM,MAAM;gBACpB,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,GAAG,EAAE;aACrC;SACF;KACF,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACZ,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAEnC,qCAAqC;IACrC,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CACvB,kBAAkB,eAAe,aAAa,eAAe,CAAC,EAAE,eAAe,EAC/E,EAAE,EACF,IAAI,CAAC,MAAM,CACZ,CAAC;QACF,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;IACxE,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,uBAAuB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;IAElF,mCAAmC;IACnC,MAAM,IAAI,GAAa;QACrB,OAAO,EAAE,eAAe;QACxB,SAAS,EAAE,eAAe,CAAC,EAAE;QAC7B,WAAW,EAAE,eAAe,CAAC,IAAI;QACjC,MAAM;QACN,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACnC,CAAC;IACF,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAEhF,oCAAoC;IACpC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC9C,MAAM,gBAAgB,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5C,cAAc,CAAC,aAAa,EAAE,gCAAgC,CAAC,CAAC;IAClE,CAAC;IAED,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAE/B,uDAAuD;IACvD,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;QACvC,OAAO,EAAE,qDAAqD,SAAS,WAAW;KACnF,CAAC,CAAC;IACH,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAC3C,CAAC;IAED,2BAA2B;IAC3B,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,YAAY;QAC7D,CAAC,CAAC,iDAAiD;QACnD,CAAC,CAAC,uCAAuC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC;QACT,wBAAwB,OAAO,EAAE;QACjC,qBAAqB;QACrB,KAAK,SAAS,UAAU;QACxB,gCAAgC;QAChC,sBAAsB;QACtB,SAAS;KACV,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,+CAA+C,CAAC;SAC5D,MAAM,CAAC,gBAAgB,EAAE,6BAA6B,CAAC;SACvD,MAAM,CAAC,gBAAgB,EAAE,yCAAyC,CAAC;SACnE,MAAM,CAAC,SAAS,EAAE,4CAA4C,CAAC;SAC/D,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;SAC7C,MAAM,CAAC,KAAK,EAAE,IAAiB,EAAE,EAAE;QAClC,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC9B,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAa,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
export interface IssueCloseOptions {
|
|
3
|
+
reason?: string;
|
|
4
|
+
apiUrl?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function runIssueClose(issueId: string, opts: IssueCloseOptions, cwd?: string): Promise<void>;
|
|
7
|
+
export declare function registerIssue(program: Command): void;
|
|
8
|
+
//# sourceMappingURL=issue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../src/commands/issue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAUD,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,iBAAiB,EACvB,GAAG,SAAgB,GAClB,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAepD"}
|