@nepopsx/cli 0.0.19 → 0.0.21
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/agents/catalog.d.ts +19 -0
- package/dist/agents/catalog.d.ts.map +1 -0
- package/dist/agents/catalog.js +45 -0
- package/dist/agents/catalog.js.map +1 -0
- package/dist/agents/configuration.d.ts +1 -0
- package/dist/agents/configuration.d.ts.map +1 -1
- package/dist/agents/configuration.js +36 -0
- package/dist/agents/configuration.js.map +1 -1
- package/dist/agents/configuration.test.d.ts +2 -0
- package/dist/agents/configuration.test.d.ts.map +1 -0
- package/dist/agents/configuration.test.js +32 -0
- package/dist/agents/configuration.test.js.map +1 -0
- package/dist/commands/capture.d.ts +19 -0
- package/dist/commands/capture.d.ts.map +1 -0
- package/dist/commands/capture.js +105 -0
- package/dist/commands/capture.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +11 -30
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.d.ts +2 -0
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +86 -15
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/login.d.ts +8 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +169 -80
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/push-learnings.d.ts.map +1 -1
- package/dist/commands/push-learnings.js +95 -63
- package/dist/commands/push-learnings.js.map +1 -1
- package/dist/commands/sync.d.ts +4 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +120 -64
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/up.d.ts +23 -0
- package/dist/commands/up.d.ts.map +1 -0
- package/dist/commands/up.js +263 -0
- package/dist/commands/up.js.map +1 -0
- package/dist/enrichment/workflow.d.ts +1 -0
- package/dist/enrichment/workflow.d.ts.map +1 -1
- package/dist/enrichment/workflow.js +13 -0
- package/dist/enrichment/workflow.js.map +1 -1
- package/dist/generator/preview.d.ts +13 -0
- package/dist/generator/preview.d.ts.map +1 -0
- package/dist/generator/preview.js +242 -0
- package/dist/generator/preview.js.map +1 -0
- package/dist/generator/preview.test.d.ts +19 -0
- package/dist/generator/preview.test.d.ts.map +1 -0
- package/dist/generator/preview.test.js +289 -0
- package/dist/generator/preview.test.js.map +1 -0
- package/dist/generator/render.d.ts +2 -2
- package/dist/generator/render.d.ts.map +1 -1
- package/dist/generator/render.js +37 -18
- package/dist/generator/render.js.map +1 -1
- package/dist/generator/writer.d.ts +15 -1
- package/dist/generator/writer.d.ts.map +1 -1
- package/dist/generator/writer.js +41 -3
- package/dist/generator/writer.js.map +1 -1
- package/dist/hooks/capture-hooks.d.ts +9 -0
- package/dist/hooks/capture-hooks.d.ts.map +1 -0
- package/dist/hooks/capture-hooks.js +100 -0
- package/dist/hooks/capture-hooks.js.map +1 -0
- package/dist/hooks/capture-hooks.test.d.ts +2 -0
- package/dist/hooks/capture-hooks.test.d.ts.map +1 -0
- package/dist/hooks/capture-hooks.test.js +50 -0
- package/dist/hooks/capture-hooks.test.js.map +1 -0
- package/dist/index.js +26 -3
- package/dist/index.js.map +1 -1
- package/dist/learnings/yaml-learnings.d.ts +16 -2
- package/dist/learnings/yaml-learnings.d.ts.map +1 -1
- package/dist/learnings/yaml-learnings.js +43 -8
- package/dist/learnings/yaml-learnings.js.map +1 -1
- package/dist/learnings/yaml-learnings.test.d.ts +2 -0
- package/dist/learnings/yaml-learnings.test.d.ts.map +1 -0
- package/dist/learnings/yaml-learnings.test.js +39 -0
- package/dist/learnings/yaml-learnings.test.js.map +1 -0
- package/dist/licensing/installer.d.ts +2 -2
- package/dist/licensing/installer.d.ts.map +1 -1
- package/dist/licensing/installer.js +3 -1
- package/dist/licensing/installer.js.map +1 -1
- package/dist/licensing/template-fetch.d.ts +2 -2
- package/dist/licensing/template-fetch.d.ts.map +1 -1
- package/dist/licensing/template-fetch.js +4 -1
- package/dist/licensing/template-fetch.js.map +1 -1
- package/dist/mcp/config-generator.d.ts +42 -0
- package/dist/mcp/config-generator.d.ts.map +1 -0
- package/dist/mcp/config-generator.js +55 -0
- package/dist/mcp/config-generator.js.map +1 -0
- package/dist/mcp/config-generator.test.d.ts +7 -0
- package/dist/mcp/config-generator.test.d.ts.map +1 -0
- package/dist/mcp/config-generator.test.js +79 -0
- package/dist/mcp/config-generator.test.js.map +1 -0
- package/dist/ruflo/config-generator.d.ts +22 -0
- package/dist/ruflo/config-generator.d.ts.map +1 -0
- package/dist/ruflo/config-generator.js +89 -0
- package/dist/ruflo/config-generator.js.map +1 -0
- package/dist/ruflo/config-generator.test.d.ts +2 -0
- package/dist/ruflo/config-generator.test.d.ts.map +1 -0
- package/dist/ruflo/config-generator.test.js +18 -0
- package/dist/ruflo/config-generator.test.js.map +1 -0
- package/dist/ruflo/detect.d.ts +11 -0
- package/dist/ruflo/detect.d.ts.map +1 -0
- package/dist/ruflo/detect.js +30 -0
- package/dist/ruflo/detect.js.map +1 -0
- package/dist/ruflo/index.d.ts +3 -0
- package/dist/ruflo/index.d.ts.map +1 -0
- package/dist/ruflo/index.js +3 -0
- package/dist/ruflo/index.js.map +1 -0
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/index.js.map +1 -1
- package/dist/security/integrity.d.ts +8 -0
- package/dist/security/integrity.d.ts.map +1 -1
- package/dist/security/integrity.js +28 -0
- package/dist/security/integrity.js.map +1 -1
- package/package.json +5 -3
- package/dist/generator/package-renderer.d.ts +0 -38
- package/dist/generator/package-renderer.d.ts.map +0 -1
- package/dist/generator/package-renderer.js +0 -181
- package/dist/generator/package-renderer.js.map +0 -1
- package/dist/generator/provider-transform.d.ts +0 -15
- package/dist/generator/provider-transform.d.ts.map +0 -1
- package/dist/generator/provider-transform.js +0 -163
- package/dist/generator/provider-transform.js.map +0 -1
- package/dist/licensing/fingerprint.test.d.ts +0 -2
- package/dist/licensing/fingerprint.test.d.ts.map +0 -1
- package/dist/licensing/fingerprint.test.js +0 -41
- package/dist/licensing/fingerprint.test.js.map +0 -1
package/dist/generator/render.js
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* - renderTemplateFile (reads template from disk)
|
|
6
6
|
* - applyLicenseWatermark (steganographic fingerprint)
|
|
7
7
|
*/
|
|
8
|
-
import Handlebars from
|
|
9
|
-
import { existsSync, readFileSync, readdirSync } from
|
|
10
|
-
import { extname, join } from
|
|
11
|
-
import { generateWatermark, renderTemplate, registerAgentPartialsFromMap, clearPartialNames, renderTemplateMap, setPhilosophyBlock, setCustomInstructions, } from
|
|
12
|
-
import { applySteganography } from
|
|
8
|
+
import Handlebars from "handlebars";
|
|
9
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
10
|
+
import { extname, join } from "node:path";
|
|
11
|
+
import { generateWatermark, renderTemplate, registerAgentPartialsFromMap, clearPartialNames, renderTemplateMap, setPhilosophyBlock, setCustomInstructions, } from "@nepopsx/core";
|
|
12
|
+
import { applySteganography } from "../licensing/fingerprint.js";
|
|
13
13
|
// Re-export core renderer API so callers only need to import from this module
|
|
14
14
|
export { renderTemplate, registerAgentPartialsFromMap, clearPartialNames, renderTemplateMap, setPhilosophyBlock, setCustomInstructions, };
|
|
15
15
|
// ─── Disk-based partial helpers ─────────────────────────────
|
|
@@ -21,13 +21,13 @@ export function registerAgentPartials(partialsDir, config, agentMeta) {
|
|
|
21
21
|
return;
|
|
22
22
|
for (const file of readdirSync(partialsDir)) {
|
|
23
23
|
const fullPath = join(partialsDir, file);
|
|
24
|
-
const raw = readFileSync(fullPath,
|
|
24
|
+
const raw = readFileSync(fullPath, "utf-8");
|
|
25
25
|
let partialName = file;
|
|
26
|
-
if (partialName.endsWith(
|
|
26
|
+
if (partialName.endsWith(".hbs"))
|
|
27
27
|
partialName = partialName.slice(0, -4);
|
|
28
|
-
if (partialName.endsWith(
|
|
28
|
+
if (partialName.endsWith(".md"))
|
|
29
29
|
partialName = partialName.slice(0, -3);
|
|
30
|
-
if (file.endsWith(
|
|
30
|
+
if (file.endsWith(".hbs")) {
|
|
31
31
|
Handlebars.registerPartial(partialName, renderTemplate(raw, config, agentMeta));
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
@@ -43,9 +43,9 @@ export function clearPartials(partialsDir) {
|
|
|
43
43
|
return;
|
|
44
44
|
for (const file of readdirSync(partialsDir)) {
|
|
45
45
|
let partialName = file;
|
|
46
|
-
if (partialName.endsWith(
|
|
46
|
+
if (partialName.endsWith(".hbs"))
|
|
47
47
|
partialName = partialName.slice(0, -4);
|
|
48
|
-
if (partialName.endsWith(
|
|
48
|
+
if (partialName.endsWith(".md"))
|
|
49
49
|
partialName = partialName.slice(0, -3);
|
|
50
50
|
Handlebars.unregisterPartial(partialName);
|
|
51
51
|
}
|
|
@@ -54,29 +54,48 @@ export function clearPartials(partialsDir) {
|
|
|
54
54
|
* Render a template file from disk.
|
|
55
55
|
*/
|
|
56
56
|
export function renderTemplateFile(templatePath, config, agentMeta) {
|
|
57
|
-
const source = readFileSync(templatePath,
|
|
57
|
+
const source = readFileSync(templatePath, "utf-8");
|
|
58
58
|
return renderTemplate(source, config, agentMeta);
|
|
59
59
|
}
|
|
60
60
|
// ─── Watermark + fingerprint post-processing ────────────────
|
|
61
61
|
let _watermarkData = null;
|
|
62
|
+
const LEADING_FRONTMATTER_RE = /^(\uFEFF?---\r?\n[\s\S]*?\r?\n---)(\r?\n[\s\S]*)?$/;
|
|
62
63
|
export function setWatermarkData(data) {
|
|
63
64
|
_watermarkData = data;
|
|
64
65
|
}
|
|
65
66
|
function detectWatermarkCommentStyle(outputPath) {
|
|
66
67
|
if (!outputPath) {
|
|
67
|
-
return
|
|
68
|
+
return "html";
|
|
68
69
|
}
|
|
69
70
|
const extension = extname(outputPath).toLowerCase();
|
|
70
|
-
if (extension ===
|
|
71
|
-
|
|
71
|
+
if (extension === ".yaml" ||
|
|
72
|
+
extension === ".yml" ||
|
|
73
|
+
extension === ".toml" ||
|
|
74
|
+
extension === ".env") {
|
|
75
|
+
return "hash";
|
|
72
76
|
}
|
|
73
|
-
return
|
|
77
|
+
return "html";
|
|
78
|
+
}
|
|
79
|
+
function insertWatermark(content, watermarkLine, style) {
|
|
80
|
+
if (content.includes(watermarkLine)) {
|
|
81
|
+
return content;
|
|
82
|
+
}
|
|
83
|
+
if (style !== "html") {
|
|
84
|
+
return `${watermarkLine}\n${content}`;
|
|
85
|
+
}
|
|
86
|
+
const frontmatterMatch = content.match(LEADING_FRONTMATTER_RE);
|
|
87
|
+
if (!frontmatterMatch) {
|
|
88
|
+
return `${watermarkLine}\n${content}`;
|
|
89
|
+
}
|
|
90
|
+
const [, frontmatter, rest = ""] = frontmatterMatch;
|
|
91
|
+
return `${frontmatter}\n${watermarkLine}${rest}`;
|
|
74
92
|
}
|
|
75
93
|
export function applyLicenseWatermark(content, outputPath) {
|
|
76
94
|
if (!_watermarkData)
|
|
77
95
|
return content;
|
|
78
|
-
const
|
|
79
|
-
|
|
96
|
+
const style = detectWatermarkCommentStyle(outputPath);
|
|
97
|
+
const watermarkLine = generateWatermark(_watermarkData, style);
|
|
98
|
+
let result = insertWatermark(content, watermarkLine, style);
|
|
80
99
|
result = applySteganography(result, _watermarkData.fingerprint);
|
|
81
100
|
return result;
|
|
82
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/generator/render.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,4BAA4B,EAC5B,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,GAKtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,8EAA8E;AAC9E,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,GAItB,CAAC;AAEF,+DAA+D;AAE/D;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,WAAmB,EACnB,MAAuB,EACvB,SAA8B;IAE9B,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO;IAErC,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE5C,IAAI,WAAW,GAAG,IAAI,CAAC;QACvB,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzE,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAExE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,UAAU,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/generator/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,11 +7,25 @@ export interface WriteResult {
|
|
|
7
7
|
created: string[];
|
|
8
8
|
updated: string[];
|
|
9
9
|
unchanged: string[];
|
|
10
|
+
/** Files whose local hand-edits were backed up before overwriting. */
|
|
11
|
+
backedUp: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface WriteOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Protect local hand-edits: before overwriting an existing file whose
|
|
16
|
+
* on-disk content differs from what NEPOPSX last wrote (per the manifest),
|
|
17
|
+
* save the local copy to `<path>.local` and warn. No-op on the first sync
|
|
18
|
+
* (no manifest yet) and for files already at their last-synced state.
|
|
19
|
+
*/
|
|
20
|
+
protect?: boolean;
|
|
21
|
+
/** Skip the local-edit backup and overwrite directly. */
|
|
22
|
+
force?: boolean;
|
|
10
23
|
}
|
|
11
24
|
/**
|
|
12
25
|
* Write generated files to disk. Diff-aware: only writes if content changed.
|
|
26
|
+
* With `protect`, never silently clobbers a hand-edited file — backs it up first.
|
|
13
27
|
*/
|
|
14
|
-
export declare function writeGeneratedFiles(rootDir: string, operations: WriteOperation[], dryRun: boolean): WriteResult;
|
|
28
|
+
export declare function writeGeneratedFiles(rootDir: string, operations: WriteOperation[], dryRun: boolean, options?: WriteOptions): WriteResult;
|
|
15
29
|
/**
|
|
16
30
|
* Print write results to console.
|
|
17
31
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/generator/writer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/generator/writer.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,cAAc,EAAE,EAC5B,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,YAAiB,GACzB,WAAW,CA6Cb;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CA6B3E"}
|
package/dist/generator/writer.js
CHANGED
|
@@ -1,12 +1,33 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { dirname, join } from 'node:path';
|
|
3
|
+
import { dirname, join, resolve, relative, isAbsolute } from 'node:path';
|
|
3
4
|
import chalk from 'chalk';
|
|
5
|
+
import { readManifest } from '../security/integrity.js';
|
|
6
|
+
function sha256(content) {
|
|
7
|
+
return createHash('sha256').update(content, 'utf-8').digest('hex');
|
|
8
|
+
}
|
|
9
|
+
/** A generated path must stay inside the workspace root (defense against a buggy/
|
|
10
|
+
* malicious bundle path with '..' or an absolute path escaping the workspace). */
|
|
11
|
+
function isInsideRoot(rootDir, opPath) {
|
|
12
|
+
if (isAbsolute(opPath))
|
|
13
|
+
return false;
|
|
14
|
+
const rel = relative(resolve(rootDir), resolve(rootDir, opPath));
|
|
15
|
+
return rel.length > 0 && !rel.startsWith('..') && !isAbsolute(rel);
|
|
16
|
+
}
|
|
4
17
|
/**
|
|
5
18
|
* Write generated files to disk. Diff-aware: only writes if content changed.
|
|
19
|
+
* With `protect`, never silently clobbers a hand-edited file — backs it up first.
|
|
6
20
|
*/
|
|
7
|
-
export function writeGeneratedFiles(rootDir, operations, dryRun) {
|
|
8
|
-
const result = { created: [], updated: [], unchanged: [] };
|
|
21
|
+
export function writeGeneratedFiles(rootDir, operations, dryRun, options = {}) {
|
|
22
|
+
const result = { created: [], updated: [], unchanged: [], backedUp: [] };
|
|
23
|
+
// Only protect once a manifest exists (i.e. NEPOPSX has written here before).
|
|
24
|
+
const manifest = options.protect && !options.force ? readManifest(rootDir) : null;
|
|
25
|
+
const protect = manifest !== null && manifest.size > 0;
|
|
9
26
|
for (const op of operations) {
|
|
27
|
+
if (!isInsideRoot(rootDir, op.path)) {
|
|
28
|
+
console.warn(chalk.yellow(`⚠ Skipping write to "${op.path}" — path escapes the workspace root.`));
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
10
31
|
const fullPath = join(rootDir, op.path);
|
|
11
32
|
const dir = dirname(fullPath);
|
|
12
33
|
if (existsSync(fullPath)) {
|
|
@@ -15,6 +36,17 @@ export function writeGeneratedFiles(rootDir, operations, dryRun) {
|
|
|
15
36
|
result.unchanged.push(op.path);
|
|
16
37
|
continue;
|
|
17
38
|
}
|
|
39
|
+
// The content will change. If the on-disk copy isn't what NEPOPSX last
|
|
40
|
+
// wrote, it's a local hand-edit — preserve it before overwriting.
|
|
41
|
+
if (protect && !dryRun) {
|
|
42
|
+
const lastWritten = manifest.get(op.path);
|
|
43
|
+
const isLocalEdit = lastWritten === undefined || lastWritten !== sha256(existing);
|
|
44
|
+
if (isLocalEdit) {
|
|
45
|
+
const backupPath = `${fullPath}.local`;
|
|
46
|
+
writeFileSync(backupPath, existing, 'utf-8');
|
|
47
|
+
result.backedUp.push(op.path);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
18
50
|
if (!dryRun) {
|
|
19
51
|
writeFileSync(fullPath, op.content, 'utf-8');
|
|
20
52
|
}
|
|
@@ -48,6 +80,12 @@ export function printWriteResult(result, dryRun) {
|
|
|
48
80
|
if (result.unchanged.length > 0) {
|
|
49
81
|
console.log(`\n${prefix}${chalk.dim(`Unchanged: ${result.unchanged.length} file(s)`)}`);
|
|
50
82
|
}
|
|
83
|
+
if (result.backedUp.length > 0) {
|
|
84
|
+
console.log(`\n${prefix}${chalk.yellow('Local edits preserved (backed up to <file>.local before overwriting):')}`);
|
|
85
|
+
for (const f of result.backedUp)
|
|
86
|
+
console.log(` ${chalk.yellow('⚠')} ${f} ${chalk.dim('→')} ${f}.local`);
|
|
87
|
+
console.log(chalk.dim(' Re-apply your changes from the .local copies, or re-run with --force to skip backups.'));
|
|
88
|
+
}
|
|
51
89
|
const total = result.created.length + result.updated.length;
|
|
52
90
|
if (total === 0) {
|
|
53
91
|
console.log(chalk.dim('\nNo changes needed.'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/generator/writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/generator/writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { OutputProvider } from "@nepopsx/core";
|
|
2
|
+
/**
|
|
3
|
+
* Generate/merge session-end "capture" hooks for the active providers, so each
|
|
4
|
+
* session automatically ships its reflector learnings to the backend
|
|
5
|
+
* (`nepopsx capture` → POST /learnings/auto). Idempotent and merge-safe — never
|
|
6
|
+
* clobbers an existing hooks file. Returns the relative paths written/updated.
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateCaptureHooks(rootDir: string, providers: OutputProvider[]): string[];
|
|
9
|
+
//# sourceMappingURL=capture-hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-hooks.d.ts","sourceRoot":"","sources":["../../src/hooks/capture-hooks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAuFpD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAW3F"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
// Command a session-end hook runs to ship reflector learnings to the backend.
|
|
4
|
+
// `npx --yes @nepopsx/cli capture` resolves a local install first, else fetches
|
|
5
|
+
// the published package — and `capture` itself soft-fails, so it can never
|
|
6
|
+
// crash the session even if offline / unlicensed.
|
|
7
|
+
const CAPTURE_CMD = "npx --yes @nepopsx/cli capture";
|
|
8
|
+
function readJsonObject(path) {
|
|
9
|
+
if (!existsSync(path))
|
|
10
|
+
return {};
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
13
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
14
|
+
? parsed
|
|
15
|
+
: {};
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function writeJsonObject(path, data) {
|
|
22
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
23
|
+
writeFileSync(path, `${JSON.stringify(data, null, 2)}\n`, "utf-8");
|
|
24
|
+
}
|
|
25
|
+
function asObject(value) {
|
|
26
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
27
|
+
? value
|
|
28
|
+
: {};
|
|
29
|
+
}
|
|
30
|
+
function mentionsCapture(value) {
|
|
31
|
+
return typeof value === "string" && value.includes("nepopsx") && value.includes("capture");
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Merge a session-end capture hook into GitHub Copilot's `.github/hooks/hooks.json`.
|
|
35
|
+
* Idempotent + preserves any existing hooks. Returns the path if written, else null.
|
|
36
|
+
*/
|
|
37
|
+
function ensureCopilotHook(rootDir) {
|
|
38
|
+
const rel = ".github/hooks/hooks.json";
|
|
39
|
+
const path = join(rootDir, rel);
|
|
40
|
+
const cfg = readJsonObject(path);
|
|
41
|
+
if (typeof cfg.version !== "number")
|
|
42
|
+
cfg.version = 1;
|
|
43
|
+
const hooks = asObject(cfg.hooks);
|
|
44
|
+
const sessionEnd = Array.isArray(hooks.sessionEnd) ? hooks.sessionEnd : [];
|
|
45
|
+
const already = sessionEnd.some((h) => {
|
|
46
|
+
const handler = asObject(h);
|
|
47
|
+
return mentionsCapture(handler.bash) || mentionsCapture(handler.powershell);
|
|
48
|
+
});
|
|
49
|
+
if (already)
|
|
50
|
+
return null;
|
|
51
|
+
sessionEnd.push({ type: "command", bash: CAPTURE_CMD, powershell: CAPTURE_CMD, timeoutSec: 60 });
|
|
52
|
+
hooks.sessionEnd = sessionEnd;
|
|
53
|
+
cfg.hooks = hooks;
|
|
54
|
+
writeJsonObject(path, cfg);
|
|
55
|
+
return rel;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Merge a SessionEnd capture hook into Claude Code's `.claude/settings.json`.
|
|
59
|
+
* Idempotent + preserves all other settings/hooks. Returns the path if written, else null.
|
|
60
|
+
*/
|
|
61
|
+
function ensureClaudeHook(rootDir) {
|
|
62
|
+
const rel = ".claude/settings.json";
|
|
63
|
+
const path = join(rootDir, rel);
|
|
64
|
+
const cfg = readJsonObject(path);
|
|
65
|
+
const hooks = asObject(cfg.hooks);
|
|
66
|
+
const sessionEnd = Array.isArray(hooks.SessionEnd) ? hooks.SessionEnd : [];
|
|
67
|
+
const already = sessionEnd.some((group) => {
|
|
68
|
+
const handlers = asObject(group).hooks;
|
|
69
|
+
return (Array.isArray(handlers) &&
|
|
70
|
+
handlers.some((h) => mentionsCapture(asObject(h).command)));
|
|
71
|
+
});
|
|
72
|
+
if (already)
|
|
73
|
+
return null;
|
|
74
|
+
sessionEnd.push({ matcher: "*", hooks: [{ type: "command", command: CAPTURE_CMD }] });
|
|
75
|
+
hooks.SessionEnd = sessionEnd;
|
|
76
|
+
cfg.hooks = hooks;
|
|
77
|
+
writeJsonObject(path, cfg);
|
|
78
|
+
return rel;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Generate/merge session-end "capture" hooks for the active providers, so each
|
|
82
|
+
* session automatically ships its reflector learnings to the backend
|
|
83
|
+
* (`nepopsx capture` → POST /learnings/auto). Idempotent and merge-safe — never
|
|
84
|
+
* clobbers an existing hooks file. Returns the relative paths written/updated.
|
|
85
|
+
*/
|
|
86
|
+
export function generateCaptureHooks(rootDir, providers) {
|
|
87
|
+
const written = [];
|
|
88
|
+
if (providers.includes("github-copilot")) {
|
|
89
|
+
const p = ensureCopilotHook(rootDir);
|
|
90
|
+
if (p)
|
|
91
|
+
written.push(p);
|
|
92
|
+
}
|
|
93
|
+
if (providers.includes("claude-code")) {
|
|
94
|
+
const p = ensureClaudeHook(rootDir);
|
|
95
|
+
if (p)
|
|
96
|
+
written.push(p);
|
|
97
|
+
}
|
|
98
|
+
return written;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=capture-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-hooks.js","sourceRoot":"","sources":["../../src/hooks/capture-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,8EAA8E;AAC9E,gFAAgF;AAChF,2EAA2E;AAC3E,kDAAkD;AAClD,MAAM,WAAW,GAAG,gCAAgC,CAAC;AAErD,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QAChE,OAAO,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACnE,CAAC,CAAE,MAAkC;YACrC,CAAC,CAAC,EAAE,CAAC;IACT,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,IAAa;IAClD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAChE,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC7F,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,OAAe;IACxC,MAAM,GAAG,GAAG,0BAA0B,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAAE,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAE,KAAK,CAAC,UAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1F,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,OAAO,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IACH,IAAI,OAAO;QAAE,OAAO,IAAI,CAAC;IAEzB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IACjG,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9B,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;IAClB,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC3B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,GAAG,GAAG,uBAAuB,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAE,KAAK,CAAC,UAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1F,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QACxC,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;QACvC,OAAO,CACL,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAC3D,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,IAAI,OAAO;QAAE,OAAO,IAAI,CAAC;IAEzB,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;IACtF,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9B,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;IAClB,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC3B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe,EAAE,SAA2B;IAC/E,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-hooks.test.d.ts","sourceRoot":"","sources":["../../src/hooks/capture-hooks.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// @nepopsx/cli — capture-hooks merge-safety + idempotency tests
|
|
2
|
+
import { strict as assert } from 'node:assert';
|
|
3
|
+
import { mkdtempSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'node:fs';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { after, describe, it } from 'node:test';
|
|
7
|
+
import { generateCaptureHooks } from './capture-hooks.js';
|
|
8
|
+
describe('generateCaptureHooks', () => {
|
|
9
|
+
it('creates Copilot + Claude session-end hooks that call capture', () => {
|
|
10
|
+
const dir = mkdtempSync(join(tmpdir(), 'nepopsx-hooks-'));
|
|
11
|
+
after(() => rmSync(dir, { recursive: true, force: true }));
|
|
12
|
+
const written = generateCaptureHooks(dir, ['github-copilot', 'claude-code']);
|
|
13
|
+
assert.deepEqual(written.sort(), ['.claude/settings.json', '.github/hooks/hooks.json']);
|
|
14
|
+
const copilot = JSON.parse(readFileSync(join(dir, '.github/hooks/hooks.json'), 'utf-8'));
|
|
15
|
+
assert.equal(copilot.version, 1);
|
|
16
|
+
assert.match(copilot.hooks.sessionEnd[0].bash, /capture/);
|
|
17
|
+
const claude = JSON.parse(readFileSync(join(dir, '.claude/settings.json'), 'utf-8'));
|
|
18
|
+
assert.match(claude.hooks.SessionEnd[0].hooks[0].command, /capture/);
|
|
19
|
+
});
|
|
20
|
+
it('is idempotent — no duplicate hooks on re-run', () => {
|
|
21
|
+
const dir = mkdtempSync(join(tmpdir(), 'nepopsx-hooks-'));
|
|
22
|
+
after(() => rmSync(dir, { recursive: true, force: true }));
|
|
23
|
+
generateCaptureHooks(dir, ['github-copilot', 'claude-code']);
|
|
24
|
+
const second = generateCaptureHooks(dir, ['github-copilot', 'claude-code']);
|
|
25
|
+
assert.deepEqual(second, []);
|
|
26
|
+
const claude = JSON.parse(readFileSync(join(dir, '.claude/settings.json'), 'utf-8'));
|
|
27
|
+
assert.equal(claude.hooks.SessionEnd.length, 1);
|
|
28
|
+
});
|
|
29
|
+
it('preserves existing settings + hooks when merging the Claude hook', () => {
|
|
30
|
+
const dir = mkdtempSync(join(tmpdir(), 'nepopsx-hooks-'));
|
|
31
|
+
after(() => rmSync(dir, { recursive: true, force: true }));
|
|
32
|
+
mkdirSync(join(dir, '.claude'), { recursive: true });
|
|
33
|
+
writeFileSync(join(dir, '.claude/settings.json'), JSON.stringify({
|
|
34
|
+
permissions: { allow: ['Bash'] },
|
|
35
|
+
hooks: { PreToolUse: [{ matcher: 'Bash', hooks: [] }] },
|
|
36
|
+
}));
|
|
37
|
+
generateCaptureHooks(dir, ['claude-code']);
|
|
38
|
+
const claude = JSON.parse(readFileSync(join(dir, '.claude/settings.json'), 'utf-8'));
|
|
39
|
+
assert.deepEqual(claude.permissions, { allow: ['Bash'] });
|
|
40
|
+
assert.ok(Array.isArray(claude.hooks.PreToolUse));
|
|
41
|
+
assert.equal(claude.hooks.SessionEnd.length, 1);
|
|
42
|
+
});
|
|
43
|
+
it('only writes hooks for the requested providers', () => {
|
|
44
|
+
const dir = mkdtempSync(join(tmpdir(), 'nepopsx-hooks-'));
|
|
45
|
+
after(() => rmSync(dir, { recursive: true, force: true }));
|
|
46
|
+
const written = generateCaptureHooks(dir, ['github-copilot']);
|
|
47
|
+
assert.deepEqual(written, ['.github/hooks/hooks.json']);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=capture-hooks.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-hooks.test.js","sourceRoot":"","sources":["../../src/hooks/capture-hooks.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { initCommand } from './commands/init.js';
|
|
3
|
+
import { upCommand } from './commands/up.js';
|
|
3
4
|
import { syncCommand } from './commands/sync.js';
|
|
4
5
|
import { doctorCommand } from './commands/doctor.js';
|
|
5
6
|
import { installCommand } from './commands/install.js';
|
|
@@ -8,12 +9,22 @@ import { decodeCommand } from './commands/decode.js';
|
|
|
8
9
|
import { loginCommand } from './commands/login.js';
|
|
9
10
|
import { scanCommand } from './commands/scan.js';
|
|
10
11
|
import { pushLearningsCommand } from './commands/push-learnings.js';
|
|
12
|
+
import { captureCommand } from './commands/capture.js';
|
|
11
13
|
import { serverClearCommand, serverSetCommand, serverShowCommand, } from './commands/server.js';
|
|
12
14
|
const program = new Command();
|
|
13
15
|
program
|
|
14
16
|
.name('nepopsx')
|
|
15
17
|
.description('NEPOPSX — AI Agent Platform for Engineering Teams')
|
|
16
18
|
.version('0.0.19');
|
|
19
|
+
program
|
|
20
|
+
.command('up')
|
|
21
|
+
.description('Guided onboarding: scaffold + resolve the entitled agent + tailor it via your own Copilot/Claude (no API keys) + render. Resumable — safe to re-run.')
|
|
22
|
+
.option('-c, --config <path>', 'Path to workspace.yaml', '.nepopsx/workspace.yaml')
|
|
23
|
+
.option('--agent <name>', 'Agent to set up (default: resolve from your plan)')
|
|
24
|
+
.option('--providers <providers...>', 'Editor providers to render for (default: github-copilot claude-code)')
|
|
25
|
+
.option('--system', 'CI escape hatch: install a GENERIC (untailored) agent — no IDE round-trip')
|
|
26
|
+
.option('-y, --yes', 'Non-interactive: fail with guidance instead of prompting when a choice is needed')
|
|
27
|
+
.action(upCommand);
|
|
17
28
|
program
|
|
18
29
|
.command('init')
|
|
19
30
|
.description('Initialize a new NEPOPSX workspace (interactive setup)')
|
|
@@ -25,8 +36,11 @@ program
|
|
|
25
36
|
.option('-c, --config <path>', 'Path to workspace.yaml', '.nepopsx/workspace.yaml')
|
|
26
37
|
.option('--remote', 'Fetch workspace config from backend API instead of local file')
|
|
27
38
|
.option('--workspace <slug>', 'Workspace slug to fetch (used with --remote)')
|
|
28
|
-
.option('--dry-run', '
|
|
39
|
+
.option('--dry-run', '(deprecated) alias of --preview')
|
|
40
|
+
.option('--preview', 'Show colored diff of pending changes; write nothing')
|
|
41
|
+
.option('--exit-on-changes', 'Exit non-zero when --preview detects changes (CI use)')
|
|
29
42
|
.option('--dev', 'Dev mode — bypass license checks (for NEPOPSX agent developers)')
|
|
43
|
+
.option('--force', 'Overwrite hand-edited files without backing them up to <file>.local first')
|
|
30
44
|
.action(syncCommand);
|
|
31
45
|
program
|
|
32
46
|
.command('install <agent>')
|
|
@@ -35,6 +49,7 @@ program
|
|
|
35
49
|
.option('--agent', 'Agent-assisted mode (generate prompt files for Copilot/Claude)')
|
|
36
50
|
.option('--apply <path>', 'Apply a JSON response file from agent-assisted install mode')
|
|
37
51
|
.option('-y, --yes', 'Skip confirmations when auto-enriching agent config')
|
|
52
|
+
.option('--system', 'Install with the agent default config (no LLM enrichment, no prompts)')
|
|
38
53
|
.option('--providers <providers...>', 'AI editor providers to generate output for (e.g., github-copilot claude-code)')
|
|
39
54
|
.action(installCommand);
|
|
40
55
|
program
|
|
@@ -53,8 +68,9 @@ program
|
|
|
53
68
|
.action(decodeCommand);
|
|
54
69
|
program
|
|
55
70
|
.command('login')
|
|
56
|
-
.description('Log in
|
|
57
|
-
.option('--
|
|
71
|
+
.description('Log in via your browser (device authorization) — provisions your org license, no key to copy-paste')
|
|
72
|
+
.option('-c, --config <path>', 'Path to workspace.yaml', '.nepopsx/workspace.yaml')
|
|
73
|
+
.option('--no-browser', "Don't auto-open the browser; just print the URL + code")
|
|
58
74
|
.action(loginCommand);
|
|
59
75
|
const serverProgram = program
|
|
60
76
|
.command('server')
|
|
@@ -82,6 +98,13 @@ program
|
|
|
82
98
|
.option('--agent <name>', 'Only push learnings for a specific agent')
|
|
83
99
|
.option('-y, --yes', 'Skip confirmations')
|
|
84
100
|
.action(pushLearningsCommand);
|
|
101
|
+
program
|
|
102
|
+
.command('capture')
|
|
103
|
+
.description('Auto-ingest local reflector learnings to the backend (for session-end hooks / CI; non-interactive, soft-fails)')
|
|
104
|
+
.option('-c, --config <path>', 'Path to workspace.yaml', '.nepopsx/workspace.yaml')
|
|
105
|
+
.option('--workspace <slug>', 'Workspace slug')
|
|
106
|
+
.option('--agent <name>', 'Only capture learnings for a specific agent')
|
|
107
|
+
.action(captureCommand);
|
|
85
108
|
program
|
|
86
109
|
.command('scan')
|
|
87
110
|
.description('LLM-powered analysis — enrich workspace.yaml and installed agent configs')
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,mDAAmD,CAAC;KAChE,OAAO,CAAC,QAAQ,CAAC,CAAC;AAErB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wDAAwD,CAAC;KACrE,MAAM,CAAC,mBAAmB,EAAE,0CAA0C,CAAC;KACvE,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,6EAA6E,CAAC;KAC1F,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,EAAE,yBAAyB,CAAC;KAClF,MAAM,CAAC,UAAU,EAAE,+DAA+D,CAAC;KACnF,MAAM,CAAC,oBAAoB,EAAE,8CAA8C,CAAC;KAC5E,MAAM,CAAC,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,11 +5,25 @@
|
|
|
5
5
|
* These are the canonical local store for reflector-produced learnings.
|
|
6
6
|
*/
|
|
7
7
|
import type { LearningYaml } from '@nepopsx/core';
|
|
8
|
+
/** A parsed learning paired with the file it came from. */
|
|
9
|
+
export interface LearningFile {
|
|
10
|
+
learning: LearningYaml;
|
|
11
|
+
filePath: string;
|
|
12
|
+
}
|
|
8
13
|
/**
|
|
9
|
-
* Load all YAML learning files from a directory.
|
|
10
|
-
* Recursively scans local subdirectories, excluding server-owned
|
|
14
|
+
* Load all YAML learning files from a directory, keeping each file's path.
|
|
15
|
+
* Recursively scans local subdirectories, excluding the server-owned `team/`
|
|
16
|
+
* folder (pulled team learnings, never re-pushed).
|
|
11
17
|
*/
|
|
18
|
+
export declare function loadLearningFiles(learningsDir: string, agentFilter?: string): LearningFile[];
|
|
19
|
+
/** Load learnings without their paths (back-compat wrapper). */
|
|
12
20
|
export declare function loadYamlLearnings(learningsDir: string, agentFilter?: string): LearningYaml[];
|
|
21
|
+
/**
|
|
22
|
+
* Update just the `status` field of a learning file in place, preserving its
|
|
23
|
+
* location and all other fields. Best-effort — used after a successful push so
|
|
24
|
+
* locally-authored learnings aren't re-pushed (which would inflate occurrences).
|
|
25
|
+
*/
|
|
26
|
+
export declare function setLearningStatus(filePath: string, status: LearningYaml['status']): void;
|
|
13
27
|
/**
|
|
14
28
|
* Parse a single YAML learning file. Returns null if invalid.
|
|
15
29
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml-learnings.d.ts","sourceRoot":"","sources":["../../src/learnings/yaml-learnings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAMlD
|
|
1
|
+
{"version":3,"file":"yaml-learnings.d.ts","sourceRoot":"","sources":["../../src/learnings/yaml-learnings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAMlD,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAM5F;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAE5F;AAqBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAkBxF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAqCvE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,MAAM,CA2B7E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1E,YAAY,CAed"}
|