@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.
Files changed (129) hide show
  1. package/dist/agents/catalog.d.ts +19 -0
  2. package/dist/agents/catalog.d.ts.map +1 -0
  3. package/dist/agents/catalog.js +45 -0
  4. package/dist/agents/catalog.js.map +1 -0
  5. package/dist/agents/configuration.d.ts +1 -0
  6. package/dist/agents/configuration.d.ts.map +1 -1
  7. package/dist/agents/configuration.js +36 -0
  8. package/dist/agents/configuration.js.map +1 -1
  9. package/dist/agents/configuration.test.d.ts +2 -0
  10. package/dist/agents/configuration.test.d.ts.map +1 -0
  11. package/dist/agents/configuration.test.js +32 -0
  12. package/dist/agents/configuration.test.js.map +1 -0
  13. package/dist/commands/capture.d.ts +19 -0
  14. package/dist/commands/capture.d.ts.map +1 -0
  15. package/dist/commands/capture.js +105 -0
  16. package/dist/commands/capture.js.map +1 -0
  17. package/dist/commands/init.d.ts.map +1 -1
  18. package/dist/commands/init.js +11 -30
  19. package/dist/commands/init.js.map +1 -1
  20. package/dist/commands/install.d.ts +2 -0
  21. package/dist/commands/install.d.ts.map +1 -1
  22. package/dist/commands/install.js +86 -15
  23. package/dist/commands/install.js.map +1 -1
  24. package/dist/commands/login.d.ts +8 -1
  25. package/dist/commands/login.d.ts.map +1 -1
  26. package/dist/commands/login.js +169 -80
  27. package/dist/commands/login.js.map +1 -1
  28. package/dist/commands/push-learnings.d.ts.map +1 -1
  29. package/dist/commands/push-learnings.js +95 -63
  30. package/dist/commands/push-learnings.js.map +1 -1
  31. package/dist/commands/sync.d.ts +4 -0
  32. package/dist/commands/sync.d.ts.map +1 -1
  33. package/dist/commands/sync.js +120 -64
  34. package/dist/commands/sync.js.map +1 -1
  35. package/dist/commands/up.d.ts +23 -0
  36. package/dist/commands/up.d.ts.map +1 -0
  37. package/dist/commands/up.js +263 -0
  38. package/dist/commands/up.js.map +1 -0
  39. package/dist/enrichment/workflow.d.ts +1 -0
  40. package/dist/enrichment/workflow.d.ts.map +1 -1
  41. package/dist/enrichment/workflow.js +13 -0
  42. package/dist/enrichment/workflow.js.map +1 -1
  43. package/dist/generator/preview.d.ts +13 -0
  44. package/dist/generator/preview.d.ts.map +1 -0
  45. package/dist/generator/preview.js +242 -0
  46. package/dist/generator/preview.js.map +1 -0
  47. package/dist/generator/preview.test.d.ts +19 -0
  48. package/dist/generator/preview.test.d.ts.map +1 -0
  49. package/dist/generator/preview.test.js +289 -0
  50. package/dist/generator/preview.test.js.map +1 -0
  51. package/dist/generator/render.d.ts +2 -2
  52. package/dist/generator/render.d.ts.map +1 -1
  53. package/dist/generator/render.js +37 -18
  54. package/dist/generator/render.js.map +1 -1
  55. package/dist/generator/writer.d.ts +15 -1
  56. package/dist/generator/writer.d.ts.map +1 -1
  57. package/dist/generator/writer.js +41 -3
  58. package/dist/generator/writer.js.map +1 -1
  59. package/dist/hooks/capture-hooks.d.ts +9 -0
  60. package/dist/hooks/capture-hooks.d.ts.map +1 -0
  61. package/dist/hooks/capture-hooks.js +100 -0
  62. package/dist/hooks/capture-hooks.js.map +1 -0
  63. package/dist/hooks/capture-hooks.test.d.ts +2 -0
  64. package/dist/hooks/capture-hooks.test.d.ts.map +1 -0
  65. package/dist/hooks/capture-hooks.test.js +50 -0
  66. package/dist/hooks/capture-hooks.test.js.map +1 -0
  67. package/dist/index.js +26 -3
  68. package/dist/index.js.map +1 -1
  69. package/dist/learnings/yaml-learnings.d.ts +16 -2
  70. package/dist/learnings/yaml-learnings.d.ts.map +1 -1
  71. package/dist/learnings/yaml-learnings.js +43 -8
  72. package/dist/learnings/yaml-learnings.js.map +1 -1
  73. package/dist/learnings/yaml-learnings.test.d.ts +2 -0
  74. package/dist/learnings/yaml-learnings.test.d.ts.map +1 -0
  75. package/dist/learnings/yaml-learnings.test.js +39 -0
  76. package/dist/learnings/yaml-learnings.test.js.map +1 -0
  77. package/dist/licensing/installer.d.ts +2 -2
  78. package/dist/licensing/installer.d.ts.map +1 -1
  79. package/dist/licensing/installer.js +3 -1
  80. package/dist/licensing/installer.js.map +1 -1
  81. package/dist/licensing/template-fetch.d.ts +2 -2
  82. package/dist/licensing/template-fetch.d.ts.map +1 -1
  83. package/dist/licensing/template-fetch.js +4 -1
  84. package/dist/licensing/template-fetch.js.map +1 -1
  85. package/dist/mcp/config-generator.d.ts +42 -0
  86. package/dist/mcp/config-generator.d.ts.map +1 -0
  87. package/dist/mcp/config-generator.js +55 -0
  88. package/dist/mcp/config-generator.js.map +1 -0
  89. package/dist/mcp/config-generator.test.d.ts +7 -0
  90. package/dist/mcp/config-generator.test.d.ts.map +1 -0
  91. package/dist/mcp/config-generator.test.js +79 -0
  92. package/dist/mcp/config-generator.test.js.map +1 -0
  93. package/dist/ruflo/config-generator.d.ts +22 -0
  94. package/dist/ruflo/config-generator.d.ts.map +1 -0
  95. package/dist/ruflo/config-generator.js +89 -0
  96. package/dist/ruflo/config-generator.js.map +1 -0
  97. package/dist/ruflo/config-generator.test.d.ts +2 -0
  98. package/dist/ruflo/config-generator.test.d.ts.map +1 -0
  99. package/dist/ruflo/config-generator.test.js +18 -0
  100. package/dist/ruflo/config-generator.test.js.map +1 -0
  101. package/dist/ruflo/detect.d.ts +11 -0
  102. package/dist/ruflo/detect.d.ts.map +1 -0
  103. package/dist/ruflo/detect.js +30 -0
  104. package/dist/ruflo/detect.js.map +1 -0
  105. package/dist/ruflo/index.d.ts +3 -0
  106. package/dist/ruflo/index.d.ts.map +1 -0
  107. package/dist/ruflo/index.js +3 -0
  108. package/dist/ruflo/index.js.map +1 -0
  109. package/dist/security/index.d.ts +1 -1
  110. package/dist/security/index.d.ts.map +1 -1
  111. package/dist/security/index.js +1 -1
  112. package/dist/security/index.js.map +1 -1
  113. package/dist/security/integrity.d.ts +8 -0
  114. package/dist/security/integrity.d.ts.map +1 -1
  115. package/dist/security/integrity.js +28 -0
  116. package/dist/security/integrity.js.map +1 -1
  117. package/package.json +5 -3
  118. package/dist/generator/package-renderer.d.ts +0 -38
  119. package/dist/generator/package-renderer.d.ts.map +0 -1
  120. package/dist/generator/package-renderer.js +0 -181
  121. package/dist/generator/package-renderer.js.map +0 -1
  122. package/dist/generator/provider-transform.d.ts +0 -15
  123. package/dist/generator/provider-transform.d.ts.map +0 -1
  124. package/dist/generator/provider-transform.js +0 -163
  125. package/dist/generator/provider-transform.js.map +0 -1
  126. package/dist/licensing/fingerprint.test.d.ts +0 -2
  127. package/dist/licensing/fingerprint.test.d.ts.map +0 -1
  128. package/dist/licensing/fingerprint.test.js +0 -41
  129. package/dist/licensing/fingerprint.test.js.map +0 -1
@@ -5,11 +5,11 @@
5
5
  * - renderTemplateFile (reads template from disk)
6
6
  * - applyLicenseWatermark (steganographic fingerprint)
7
7
  */
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';
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, 'utf-8');
24
+ const raw = readFileSync(fullPath, "utf-8");
25
25
  let partialName = file;
26
- if (partialName.endsWith('.hbs'))
26
+ if (partialName.endsWith(".hbs"))
27
27
  partialName = partialName.slice(0, -4);
28
- if (partialName.endsWith('.md'))
28
+ if (partialName.endsWith(".md"))
29
29
  partialName = partialName.slice(0, -3);
30
- if (file.endsWith('.hbs')) {
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('.hbs'))
46
+ if (partialName.endsWith(".hbs"))
47
47
  partialName = partialName.slice(0, -4);
48
- if (partialName.endsWith('.md'))
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, 'utf-8');
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 'html';
68
+ return "html";
68
69
  }
69
70
  const extension = extname(outputPath).toLowerCase();
70
- if (extension === '.yaml' || extension === '.yml' || extension === '.toml' || extension === '.env') {
71
- return 'hash';
71
+ if (extension === ".yaml" ||
72
+ extension === ".yml" ||
73
+ extension === ".toml" ||
74
+ extension === ".env") {
75
+ return "hash";
72
76
  }
73
- return 'html';
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 watermarkLine = generateWatermark(_watermarkData, detectWatermarkCommentStyle(outputPath));
79
- let result = watermarkLine + '\n' + content;
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,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QAClF,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,eAAe,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO;IACrC,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5C,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;QACxE,UAAU,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAAoB,EACpB,MAAuB,EACvB,SAA8B;IAE9B,MAAM,MAAM,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACnD,OAAO,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AACnD,CAAC;AAED,+DAA+D;AAE/D,IAAI,cAAc,GAAyB,IAAI,CAAC;AAEhD,MAAM,UAAU,gBAAgB,CAAC,IAA0B;IACzD,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC;AAED,SAAS,2BAA2B,CAAC,UAAmB;IACtD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IACpD,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACnG,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAe,EAAE,UAAmB;IACxE,IAAI,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC;IACpC,MAAM,aAAa,GAAG,iBAAiB,CAAC,cAAc,EAAE,2BAA2B,CAAC,UAAU,CAAC,CAAC,CAAC;IACjG,IAAI,MAAM,GAAG,aAAa,GAAG,IAAI,GAAG,OAAO,CAAC;IAC5C,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC;AAChB,CAAC"}
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":"AAIA,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;CACrB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,OAAO,GAAG,WAAW,CA2B/G;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAuB3E"}
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"}
@@ -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":"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"}
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":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=capture-hooks.test.d.ts.map
@@ -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', 'Preview changes without writing files')
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 to NEPOPSX and save credentials to .nepopsx/config.json')
57
- .option('--email <email>', 'Your NEPOPSX account email')
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":"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"}
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 folders.
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;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAM5F;AAqBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAoCvE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,MAAM,CAuB7E;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"}
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"}