spec-copy-selection 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.
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readFileRange = exports.parseArgs = void 0;
4
+ var parseArgs_js_1 = require("./parseArgs.js");
5
+ Object.defineProperty(exports, "parseArgs", { enumerable: true, get: function () { return parseArgs_js_1.parseArgs; } });
6
+ var readFileRange_js_1 = require("./readFileRange.js");
7
+ Object.defineProperty(exports, "readFileRange", { enumerable: true, get: function () { return readFileRange_js_1.readFileRange; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AAQA,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAClB,uDAAmD;AAA1C,iHAAA,aAAa,OAAA"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseArgs = parseArgs;
4
+ const USAGE = `Usage: spec-copy-selection <file-path>:<start-line>-<end-line>
5
+
6
+ Examples:
7
+ spec-copy-selection ./src/index.ts:1-10
8
+ spec-copy-selection src/utils.ts:25-50
9
+ spec-copy-selection D:\\projects\\file.ts:10-20 (Windows)
10
+
11
+ Options:
12
+ --help, -h Show this help message`;
13
+ function parseArgs(argv) {
14
+ if (argv.length === 0) {
15
+ throw new Error(USAGE);
16
+ }
17
+ if (argv[0] === '--help' || argv[0] === '-h') {
18
+ throw new Error(USAGE);
19
+ }
20
+ const input = argv[0];
21
+ const lineRangePattern = /:(\d+)-(\d+)$/;
22
+ const match = input.match(lineRangePattern);
23
+ if (!match) {
24
+ throw new Error('Invalid format. Usage: spec-copy-selection <file-path>:<start-line>-<end-line>');
25
+ }
26
+ const colonIndex = input.lastIndexOf(`:${match[1]}-${match[2]}`);
27
+ const filePath = input.substring(0, colonIndex);
28
+ const startLine = parseInt(match[1], 10);
29
+ const endLine = parseInt(match[2], 10);
30
+ if (!filePath) {
31
+ throw new Error('Invalid format. Usage: spec-copy-selection <file-path>:<start-line>-<end-line>');
32
+ }
33
+ if (startLine < 1) {
34
+ throw new Error('Invalid range: line numbers must be positive integers');
35
+ }
36
+ if (endLine < startLine) {
37
+ throw new Error(`Invalid range: start line (${startLine}) cannot be greater than end line (${endLine})`);
38
+ }
39
+ return {
40
+ filePath,
41
+ startLine,
42
+ endLine,
43
+ };
44
+ }
45
+ //# sourceMappingURL=parseArgs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseArgs.js","sourceRoot":"","sources":["../../src/cli/parseArgs.ts"],"names":[],"mappings":";;AA6BA,8BAoDC;AA1ED,MAAM,KAAK,GAAG;;;;;;;;uCAQyB,CAAC;AAcxC,SAAgB,SAAS,CAAC,IAAc;IAEtC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAGD,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAGtB,MAAM,gBAAgB,GAAG,eAAe,CAAC;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAE5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,gFAAgF,CACjF,CAAC;IACJ,CAAC;IAGD,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAGvC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,gFAAgF,CACjF,CAAC;IACJ,CAAC;IAGD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,OAAO,GAAG,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,8BAA8B,SAAS,sCAAsC,OAAO,GAAG,CACxF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ;QACR,SAAS;QACT,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.readFileRange = readFileRange;
7
+ const node_fs_1 = require("node:fs");
8
+ const promises_1 = require("node:fs/promises");
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const node_readline_1 = require("node:readline");
11
+ const FILE_SIZE_THRESHOLD = 10 * 1024 * 1024;
12
+ async function readFileRangeSmall(resolvedPath, filePath, startLine, endLine) {
13
+ let fileContent;
14
+ try {
15
+ fileContent = await (0, promises_1.readFile)(resolvedPath, 'utf-8');
16
+ }
17
+ catch (error) {
18
+ if (error instanceof Error) {
19
+ if (error.code === 'ENOENT') {
20
+ throw new Error(`File not found: ${filePath}`);
21
+ }
22
+ if (error.code === 'EACCES') {
23
+ throw new Error(`Permission denied: ${filePath}`);
24
+ }
25
+ throw new Error(`Failed to read file: ${error.message}`);
26
+ }
27
+ throw error;
28
+ }
29
+ const lines = fileContent.split('\n');
30
+ const totalLines = lines.length;
31
+ if (startLine > totalLines) {
32
+ throw new Error(`Invalid range: start line (${startLine}) exceeds file length (${totalLines} lines)`);
33
+ }
34
+ const actualEndLine = Math.min(endLine, totalLines);
35
+ const extractedLines = lines.slice(startLine - 1, actualEndLine);
36
+ return extractedLines.join('\n');
37
+ }
38
+ async function readFileRangeLarge(resolvedPath, filePath, startLine, endLine) {
39
+ return new Promise((resolve, reject) => {
40
+ const lines = [];
41
+ let currentLine = 0;
42
+ let streamClosed = false;
43
+ const fileStream = (0, node_fs_1.createReadStream)(resolvedPath, { encoding: 'utf-8' });
44
+ const rl = (0, node_readline_1.createInterface)({
45
+ input: fileStream,
46
+ crlfDelay: Infinity,
47
+ });
48
+ const cleanup = () => {
49
+ if (!streamClosed) {
50
+ streamClosed = true;
51
+ rl.close();
52
+ fileStream.destroy();
53
+ }
54
+ };
55
+ rl.on('line', (line) => {
56
+ currentLine++;
57
+ if (currentLine >= startLine && currentLine <= endLine) {
58
+ lines.push(line);
59
+ }
60
+ if (currentLine >= endLine) {
61
+ cleanup();
62
+ resolve(lines.join('\n'));
63
+ }
64
+ });
65
+ rl.on('close', () => {
66
+ if (!streamClosed) {
67
+ streamClosed = true;
68
+ if (currentLine < startLine) {
69
+ reject(new Error(`Invalid range: start line (${startLine}) exceeds file length (${currentLine} lines)`));
70
+ return;
71
+ }
72
+ resolve(lines.join('\n'));
73
+ }
74
+ });
75
+ rl.on('error', (error) => {
76
+ cleanup();
77
+ reject(error);
78
+ });
79
+ fileStream.on('error', (error) => {
80
+ cleanup();
81
+ if (error.code === 'ENOENT') {
82
+ reject(new Error(`File not found: ${filePath}`));
83
+ }
84
+ else if (error.code === 'EACCES') {
85
+ reject(new Error(`Permission denied: ${filePath}`));
86
+ }
87
+ else {
88
+ reject(new Error(`Failed to read file: ${error.message}`));
89
+ }
90
+ });
91
+ });
92
+ }
93
+ async function readFileRange(filePath, startLine, endLine) {
94
+ const resolvedPath = node_path_1.default.resolve(process.cwd(), filePath);
95
+ let fileSize = 0;
96
+ try {
97
+ const stats = await (0, promises_1.stat)(resolvedPath);
98
+ fileSize = stats.size;
99
+ }
100
+ catch (error) {
101
+ if (error.code === 'ENOENT') {
102
+ throw new Error(`File not found: ${filePath}`);
103
+ }
104
+ if (error.code === 'EACCES') {
105
+ throw new Error(`Permission denied: ${filePath}`);
106
+ }
107
+ }
108
+ if (fileSize >= FILE_SIZE_THRESHOLD) {
109
+ return readFileRangeLarge(resolvedPath, filePath, startLine, endLine);
110
+ }
111
+ return readFileRangeSmall(resolvedPath, filePath, startLine, endLine);
112
+ }
113
+ //# sourceMappingURL=readFileRange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readFileRange.js","sourceRoot":"","sources":["../../src/cli/readFileRange.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":""}
package/dist/index.js CHANGED
@@ -4,10 +4,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ const node_path_1 = __importDefault(require("node:path"));
7
8
  const clipboardy_1 = __importDefault(require("clipboardy"));
9
+ const index_js_1 = require("./cli/index.js");
10
+ const transform_1 = require("./transform");
8
11
  async function main() {
9
12
  try {
10
- await clipboardy_1.default.write('🦄');
13
+ const args = (0, index_js_1.parseArgs)(process.argv.slice(2));
14
+ const content = await (0, index_js_1.readFileRange)(args.filePath, args.startLine, args.endLine);
15
+ const resolvedPath = node_path_1.default.resolve(process.cwd(), args.filePath);
16
+ const metadata = {
17
+ filePath: resolvedPath,
18
+ fileName: node_path_1.default.basename(resolvedPath),
19
+ extension: node_path_1.default.extname(resolvedPath),
20
+ lineRange: `${args.startLine}-${args.endLine}`,
21
+ };
22
+ const transform = (0, transform_1.compose)(transform_1.formatOutput, transform_1.stripFrontmatter);
23
+ const transformed = transform(content, metadata);
24
+ await clipboardy_1.default.write(transformed);
25
+ console.log(`✓ Copied lines ${args.startLine}-${args.endLine} from ${metadata.fileName} to clipboard`);
11
26
  }
12
27
  catch (error) {
13
28
  console.error('Error:', error instanceof Error ? error.message : String(error));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AACA,4DAAmC;AAEnC,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,oBAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AACA,0DAA6B;AAC7B,4DAAmC;AACnC,6CAA0D;AAE1D,2CAAsE;AAEtE,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QAEH,MAAM,IAAI,GAAG,IAAA,oBAAS,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAG9C,MAAM,OAAO,GAAG,MAAM,IAAA,wBAAa,EAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAGjF,MAAM,YAAY,GAAG,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChE,MAAM,QAAQ,GAAiB;YAC7B,QAAQ,EAAE,YAAY;YACtB,QAAQ,EAAE,mBAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;YACrC,SAAS,EAAE,mBAAI,CAAC,OAAO,CAAC,YAAY,CAAC;YACrC,SAAS,EAAE,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE;SAC/C,CAAC;QAGF,MAAM,SAAS,GAAG,IAAA,mBAAO,EAAC,wBAAY,EAAE,4BAAgB,CAAC,CAAC;QAC1D,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAGjD,MAAM,oBAAS,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAGnC,OAAO,CAAC,GAAG,CACT,kBAAkB,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,SAAS,QAAQ,CAAC,QAAQ,eAAe,CAC1F,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compose = compose;
4
+ function compose(...fns) {
5
+ if (fns.length === 0) {
6
+ return (content) => content;
7
+ }
8
+ if (fns.length === 1) {
9
+ return fns[0];
10
+ }
11
+ return (content, metadata) => fns.reduceRight((result, fn) => fn(result, metadata), content);
12
+ }
13
+ //# sourceMappingURL=compose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../../src/transform/compose.ts"],"names":[],"mappings":";;AAwCA,0BAcC;AAdD,SAAgB,OAAO,CAAC,GAAG,GAAwB;IAEjD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,OAAe,EAAU,EAAE,CAAC,OAAO,CAAC;IAC9C,CAAC;IAGD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC;IAGD,OAAO,CAAC,OAAe,EAAE,QAAQ,EAAU,EAAE,CAC3C,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stripFrontmatter = exports.identity = exports.formatOutput = exports.addHeader = exports.compose = void 0;
4
+ var compose_1 = require("./compose");
5
+ Object.defineProperty(exports, "compose", { enumerable: true, get: function () { return compose_1.compose; } });
6
+ var addHeader_1 = require("./strategies/addHeader");
7
+ Object.defineProperty(exports, "addHeader", { enumerable: true, get: function () { return addHeader_1.addHeader; } });
8
+ var formatOutput_1 = require("./strategies/formatOutput");
9
+ Object.defineProperty(exports, "formatOutput", { enumerable: true, get: function () { return formatOutput_1.formatOutput; } });
10
+ var identity_1 = require("./strategies/identity");
11
+ Object.defineProperty(exports, "identity", { enumerable: true, get: function () { return identity_1.identity; } });
12
+ var stripFrontmatter_1 = require("./strategies/stripFrontmatter");
13
+ Object.defineProperty(exports, "stripFrontmatter", { enumerable: true, get: function () { return stripFrontmatter_1.stripFrontmatter; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transform/index.ts"],"names":[],"mappings":";;;AA2BA,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAChB,oDAAmD;AAA1C,sGAAA,SAAS,OAAA;AAGlB,0DAAyD;AAAhD,4GAAA,YAAY,OAAA;AACrB,kDAAiD;AAAxC,oGAAA,QAAQ,OAAA;AACjB,kEAAiE;AAAxD,oHAAA,gBAAgB,OAAA"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addHeader = void 0;
4
+ const addHeader = (content, metadata) => {
5
+ const header = `// File: ${metadata.filePath}\n// Lines: ${metadata.lineRange}\n`;
6
+ return content ? `${header}\n${content}` : header;
7
+ };
8
+ exports.addHeader = addHeader;
9
+ //# sourceMappingURL=addHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addHeader.js","sourceRoot":"","sources":["../../../src/transform/strategies/addHeader.ts"],"names":[],"mappings":";;;AAiDO,MAAM,SAAS,GAAsB,CAAC,OAAe,EAAE,QAAQ,EAAU,EAAE;IAChF,MAAM,MAAM,GAAG,YAAY,QAAQ,CAAC,QAAQ,eAAe,QAAQ,CAAC,SAAS,IAAI,CAAC;IAGlF,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACpD,CAAC,CAAC;AALW,QAAA,SAAS,aAKpB"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.formatOutput = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const formatOutput = (content, metadata) => {
9
+ const { filePath, lineRange } = metadata;
10
+ const relativePath = node_path_1.default.relative(process.cwd(), filePath).replace(/\\/g, '/');
11
+ const backlogPattern = /specs\/([^/]+)\/backlog\.md$/;
12
+ const match = relativePath.match(backlogPattern);
13
+ if (match) {
14
+ const featureName = match[1];
15
+ return `spec: ${featureName}\n${content} (this request was extracted from ${relativePath}:${lineRange})`;
16
+ }
17
+ return `${relativePath}:${lineRange}`;
18
+ };
19
+ exports.formatOutput = formatOutput;
20
+ //# sourceMappingURL=formatOutput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatOutput.js","sourceRoot":"","sources":["../../../src/transform/strategies/formatOutput.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAQtB,MAAM,YAAY,GAAsB,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;IACnE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IAGzC,MAAM,YAAY,GAAG,mBAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAGhF,MAAM,cAAc,GAAG,8BAA8B,CAAC;IACtD,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAEjD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7B,OAAO,SAAS,WAAW,KAAK,OAAO,qCAAqC,YAAY,IAAI,SAAS,GAAG,CAAC;IAC3G,CAAC;IAGD,OAAO,GAAG,YAAY,IAAI,SAAS,EAAE,CAAC;AACxC,CAAC,CAAC;AAjBW,QAAA,YAAY,gBAiBvB"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.identity = void 0;
4
+ const identity = (content) => {
5
+ return content;
6
+ };
7
+ exports.identity = identity;
8
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/transform/strategies/identity.ts"],"names":[],"mappings":";;;AAqBO,MAAM,QAAQ,GAAsB,CAAC,OAAe,EAAU,EAAE;IACrE,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAFW,QAAA,QAAQ,YAEnB"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stripFrontmatter = void 0;
4
+ const stripFrontmatter = (content) => {
5
+ const yamlPattern = /^---\n([\s\S]*?)\n---\n/;
6
+ const tomlPattern = /^\+\+\+\n([\s\S]*?)\n\+\+\+\n/;
7
+ const result = content.replace(yamlPattern, '').replace(tomlPattern, '');
8
+ return result !== content ? result.trimStart() : content;
9
+ };
10
+ exports.stripFrontmatter = stripFrontmatter;
11
+ //# sourceMappingURL=stripFrontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripFrontmatter.js","sourceRoot":"","sources":["../../../src/transform/strategies/stripFrontmatter.ts"],"names":[],"mappings":";;;AA8DO,MAAM,gBAAgB,GAAsB,CAAC,OAAe,EAAU,EAAE;IAE7E,MAAM,WAAW,GAAG,yBAAyB,CAAC;IAE9C,MAAM,WAAW,GAAG,+BAA+B,CAAC;IAGpD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAGzE,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AAC3D,CAAC,CAAC;AAXW,QAAA,gBAAgB,oBAW3B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transform/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-copy-selection",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A CLI utility for copying text to clipboard",
5
5
  "main": "./dist/index.js",
6
6
  "bin": {
@@ -18,11 +18,11 @@
18
18
  "paste",
19
19
  "utility"
20
20
  ],
21
- "author": "",
21
+ "author": "nullmastermind",
22
22
  "license": "MIT",
23
23
  "repository": {
24
24
  "type": "git",
25
- "url": "https://github.com/yourusername/spec-copy-selection.git"
25
+ "url": "https://github.com/nullmastermind/spec-copy-selection.git"
26
26
  },
27
27
  "engines": {
28
28
  "node": ">=18"
@@ -36,7 +36,7 @@
36
36
  "clipboardy": "^5.1.0"
37
37
  },
38
38
  "scripts": {
39
- "dev": "bun run src/index.ts",
39
+ "dev": "bun run src/index.ts specs/cli-file-operations/backlog.md:4-10",
40
40
  "build": "tsc",
41
41
  "prepublishOnly": "bun run check && bun run build",
42
42
  "lint": "biome lint .",