@arka-labs/nemesis 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +668 -0
  3. package/lib/core/agent-launcher.js +193 -0
  4. package/lib/core/audit.js +210 -0
  5. package/lib/core/connexions.js +80 -0
  6. package/lib/core/flowmap/api.js +111 -0
  7. package/lib/core/flowmap/cli-helpers.js +80 -0
  8. package/lib/core/flowmap/machine.js +281 -0
  9. package/lib/core/flowmap/persistence.js +83 -0
  10. package/lib/core/generators.js +183 -0
  11. package/lib/core/inbox.js +275 -0
  12. package/lib/core/logger.js +20 -0
  13. package/lib/core/mission.js +109 -0
  14. package/lib/core/notewriter/config.js +36 -0
  15. package/lib/core/notewriter/cr.js +237 -0
  16. package/lib/core/notewriter/log.js +112 -0
  17. package/lib/core/notewriter/notes.js +168 -0
  18. package/lib/core/notewriter/paths.js +45 -0
  19. package/lib/core/notewriter/reader.js +121 -0
  20. package/lib/core/notewriter/registry.js +80 -0
  21. package/lib/core/odm.js +191 -0
  22. package/lib/core/profile-picker.js +323 -0
  23. package/lib/core/project.js +287 -0
  24. package/lib/core/registry.js +129 -0
  25. package/lib/core/secrets.js +137 -0
  26. package/lib/core/services.js +45 -0
  27. package/lib/core/team.js +287 -0
  28. package/lib/core/templates.js +80 -0
  29. package/lib/kairos/agent-runner.js +261 -0
  30. package/lib/kairos/claude-invoker.js +90 -0
  31. package/lib/kairos/context-injector.js +331 -0
  32. package/lib/kairos/context-loader.js +108 -0
  33. package/lib/kairos/context-writer.js +45 -0
  34. package/lib/kairos/dispatcher-router.js +173 -0
  35. package/lib/kairos/dispatcher.js +139 -0
  36. package/lib/kairos/event-bus.js +287 -0
  37. package/lib/kairos/event-router.js +131 -0
  38. package/lib/kairos/flowmap-bridge.js +120 -0
  39. package/lib/kairos/hook-handlers.js +351 -0
  40. package/lib/kairos/hook-installer.js +207 -0
  41. package/lib/kairos/hook-prompts.js +54 -0
  42. package/lib/kairos/leader-rules.js +94 -0
  43. package/lib/kairos/pid-checker.js +108 -0
  44. package/lib/kairos/situation-detector.js +123 -0
  45. package/lib/sync/fallback-engine.js +97 -0
  46. package/lib/sync/hcm-client.js +170 -0
  47. package/lib/sync/health.js +47 -0
  48. package/lib/sync/llm-client.js +387 -0
  49. package/lib/sync/nemesis-client.js +379 -0
  50. package/lib/sync/service-session.js +74 -0
  51. package/lib/sync/sync-engine.js +178 -0
  52. package/lib/ui/box.js +104 -0
  53. package/lib/ui/brand.js +42 -0
  54. package/lib/ui/colors.js +57 -0
  55. package/lib/ui/dashboard.js +580 -0
  56. package/lib/ui/error-hints.js +49 -0
  57. package/lib/ui/format.js +61 -0
  58. package/lib/ui/menu.js +306 -0
  59. package/lib/ui/note-card.js +198 -0
  60. package/lib/ui/note-colors.js +26 -0
  61. package/lib/ui/note-detail.js +297 -0
  62. package/lib/ui/note-filters.js +252 -0
  63. package/lib/ui/note-views.js +283 -0
  64. package/lib/ui/prompt.js +81 -0
  65. package/lib/ui/spinner.js +139 -0
  66. package/lib/ui/streambox.js +46 -0
  67. package/lib/ui/table.js +42 -0
  68. package/lib/ui/tree.js +33 -0
  69. package/package.json +53 -0
  70. package/src/cli.js +457 -0
  71. package/src/commands/_helpers.js +119 -0
  72. package/src/commands/audit.js +187 -0
  73. package/src/commands/auth.js +316 -0
  74. package/src/commands/doctor.js +243 -0
  75. package/src/commands/hcm.js +147 -0
  76. package/src/commands/inbox.js +333 -0
  77. package/src/commands/init.js +160 -0
  78. package/src/commands/kairos.js +216 -0
  79. package/src/commands/kars.js +134 -0
  80. package/src/commands/mission.js +275 -0
  81. package/src/commands/notes.js +316 -0
  82. package/src/commands/notewriter.js +296 -0
  83. package/src/commands/odm.js +329 -0
  84. package/src/commands/orch.js +68 -0
  85. package/src/commands/project.js +123 -0
  86. package/src/commands/run.js +123 -0
  87. package/src/commands/services.js +705 -0
  88. package/src/commands/status.js +231 -0
  89. package/src/commands/team.js +572 -0
  90. package/src/config.js +84 -0
  91. package/src/index.js +5 -0
  92. package/templates/project-context.json +10 -0
  93. package/templates/template_CONTRIB-NAME.json +22 -0
  94. package/templates/template_CR-ODM-NAME-000.exemple.json +32 -0
  95. package/templates/template_DEC-NAME-000.json +18 -0
  96. package/templates/template_INTV-NAME-000.json +15 -0
  97. package/templates/template_MISSION_CONTRACT.json +46 -0
  98. package/templates/template_ODM-NAME-000.json +89 -0
  99. package/templates/template_REGISTRY-PROJECT.json +26 -0
  100. package/templates/template_TXN-NAME-000.json +24 -0
package/lib/ui/box.js ADDED
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Emoji-aware box drawing — zero deps.
3
+ * Adapted from arka-labs-cli/lib/box.js.
4
+ */
5
+
6
+ import { stripAnsi } from './colors.js';
7
+
8
+ const isMark = (value) => /^\p{Mark}$/u.test(value);
9
+
10
+ export function isWideCodePoint(codePoint) {
11
+ if (codePoint >= 0x1f300 && codePoint <= 0x1faff) return true; // emoji blocks
12
+ if (codePoint >= 0x2600 && codePoint <= 0x27bf) return true; // misc symbols dingbats
13
+ if (codePoint >= 0x1100 && codePoint <= 0x115f) return true;
14
+ if (codePoint === 0x2329 || codePoint === 0x232a) return true;
15
+ if (codePoint >= 0x2e80 && codePoint <= 0xa4cf && codePoint !== 0x303f) return true;
16
+ if (codePoint >= 0xac00 && codePoint <= 0xd7a3) return true;
17
+ if (codePoint >= 0xf900 && codePoint <= 0xfaff) return true;
18
+ if (codePoint >= 0xfe10 && codePoint <= 0xfe19) return true;
19
+ if (codePoint >= 0xfe30 && codePoint <= 0xfe6f) return true;
20
+ if (codePoint >= 0xff00 && codePoint <= 0xff60) return true;
21
+ if (codePoint >= 0xffe0 && codePoint <= 0xffe6) return true;
22
+ if (codePoint >= 0x20000 && codePoint <= 0x3fffd) return true;
23
+ return false;
24
+ }
25
+
26
+ export function stringWidth(value) {
27
+ const plain = stripAnsi(value);
28
+ let width = 0;
29
+
30
+ for (const ch of plain) {
31
+ if (ch === '\uFE0E' || ch === '\uFE0F') continue; // variation selectors
32
+ if (isMark(ch)) continue; // combining marks
33
+
34
+ const codePoint = ch.codePointAt(0) ?? 0;
35
+ width += isWideCodePoint(codePoint) ? 2 : 1;
36
+ }
37
+
38
+ return width;
39
+ }
40
+
41
+ export function padEndVisible(value, width) {
42
+ const missing = Math.max(0, width - stringWidth(value));
43
+ return `${value}${' '.repeat(missing)}`;
44
+ }
45
+
46
+ export function box(lines, options = {}) {
47
+ const paddingX = options.paddingX ?? 2;
48
+ const paddingY = options.paddingY ?? 0;
49
+ const border = typeof options.border === 'function' ? options.border : (v) => v;
50
+
51
+ const contentWidth = Math.max(0, ...lines.map((line) => stringWidth(line)));
52
+ const innerWidth = contentWidth + paddingX * 2;
53
+
54
+ const top = `${border('\u250c')}${border('\u2500'.repeat(innerWidth))}${border('\u2510')}`;
55
+ const bottom = `${border('\u2514')}${border('\u2500'.repeat(innerWidth))}${border('\u2518')}`;
56
+ const empty = `${border('\u2502')}${' '.repeat(innerWidth)}${border('\u2502')}`;
57
+
58
+ const out = [top];
59
+ for (let i = 0; i < paddingY; i++) out.push(empty);
60
+
61
+ for (const line of lines) {
62
+ out.push(
63
+ `${border('\u2502')}${' '.repeat(paddingX)}${padEndVisible(line, contentWidth)}${' '.repeat(paddingX)}${border('\u2502')}`,
64
+ );
65
+ }
66
+
67
+ for (let i = 0; i < paddingY; i++) out.push(empty);
68
+ out.push(bottom);
69
+ return out.join('\n');
70
+ }
71
+
72
+ export function titledBox(title, lines, options = {}) {
73
+ const paddingX = options.paddingX ?? 2;
74
+ const paddingY = options.paddingY ?? 0;
75
+ const border = typeof options.border === 'function' ? options.border : (v) => v;
76
+
77
+ const contentWidth = Math.max(0, ...lines.map((line) => stringWidth(line)));
78
+ const innerWidthFromContent = contentWidth + paddingX * 2;
79
+
80
+ const titlePrefixRaw = `\u2500 ${title} `;
81
+ const titleWidth = stringWidth(titlePrefixRaw);
82
+ const innerWidth = Math.max(innerWidthFromContent, titleWidth);
83
+
84
+ const titlePrefix = `${border('\u2500')} ${title} `;
85
+ const remainingTop = Math.max(0, innerWidth - stringWidth(titlePrefixRaw));
86
+ const top = `${border('\u250c')}${titlePrefix}${border('\u2500'.repeat(remainingTop))}${border('\u2510')}`;
87
+ const bottom = `${border('\u2514')}${border('\u2500'.repeat(innerWidth))}${border('\u2518')}`;
88
+ const empty = `${border('\u2502')}${' '.repeat(innerWidth)}${border('\u2502')}`;
89
+
90
+ const contentAreaWidth = innerWidth - paddingX * 2;
91
+
92
+ const out = [top];
93
+ for (let i = 0; i < paddingY; i++) out.push(empty);
94
+
95
+ for (const line of lines) {
96
+ out.push(
97
+ `${border('\u2502')}${' '.repeat(paddingX)}${padEndVisible(line, contentAreaWidth)}${' '.repeat(paddingX)}${border('\u2502')}`,
98
+ );
99
+ }
100
+
101
+ for (let i = 0; i < paddingY; i++) out.push(empty);
102
+ out.push(bottom);
103
+ return out.join('\n');
104
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * ARKA LABS CLI branding — logo + header.
3
+ * Recovered from arka-labs-cli/src/brand.js.
4
+ */
5
+
6
+ import { style } from './colors.js';
7
+
8
+ export const LOGO = [
9
+ ' █████╗ ██████╗ ██╗ ██╗ █████╗ ██╗ █████╗ ██████╗ ███████╗',
10
+ ' ██╔══██╗██╔══██╗██║ ██╔╝██╔══██╗██║ ██╔══██╗██╔══██╗██╔════╝',
11
+ ' ███████║██████╔╝█████╔╝ ███████║██║ ███████║██████╔╝███████╗',
12
+ ' ██╔══██║██╔══██╗██╔═██╗ ██╔══██║██║ ██╔══██║██╔══██╗╚════██║',
13
+ ' ██║ ██║██║ ██║██║ ██╗██║ ██║███████╗██║ ██║██████╔╝███████║',
14
+ ' ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚══════╝',
15
+ ].join('\n');
16
+
17
+ export const PRODUCT_NAME = 'ARKA Labs CLI';
18
+
19
+ export function renderBrandHeader({ version, tagline = 'Gouvernance souveraine' } = {}) {
20
+ const safeVersion = typeof version === 'string' ? version : '1.0.0';
21
+ return [
22
+ style.arkaRed(LOGO),
23
+ '',
24
+ `${style.dim('arkalabs')} ${style.dim('-')} ${style.bold('nemesis')} ${style.gray(`v${safeVersion}`)} ${style.dim('-')} ${style.nemesisAccent('Kairos router')} ${style.gray('v2.0.0')}`,
25
+ style.gray(tagline),
26
+ '',
27
+ ];
28
+ }
29
+
30
+ /**
31
+ * Compact one-line brand banner for secondary screens.
32
+ * @param {object} opts
33
+ * @param {string} opts.version
34
+ * @param {string} [opts.section] — current section name (e.g. "team", "odm")
35
+ */
36
+ export function renderBrandBanner({ version, section } = {}) {
37
+ const safeVersion = typeof version === 'string' ? version : '1.0.0';
38
+ const sectionPart = section ? ` ${style.dim('>')} ${style.bold(section)}` : '';
39
+ const line = ` ${style.dim('arkalabs')} ${style.dim('-')} ${style.bold('nemesis')} ${style.gray(`v${safeVersion}`)}${sectionPart}`;
40
+ const rule = ` ${style.dim('\u2500'.repeat(40))}`;
41
+ return `${line}\n${rule}\n`;
42
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * ANSI color system — zero deps.
3
+ * Adapted from arka-labs-cli/lib/ansi.js with Nemesis identity.
4
+ * Respects NO_COLOR env var and TTY detection.
5
+ */
6
+
7
+ const ANSI_RE = /\u001b\[[0-9;]*m/g;
8
+
9
+ export function isColorEnabled() {
10
+ if (process.env.NEMESIS_COLOR === '0') return false;
11
+ if (process.env.NEMESIS_COLOR === '1') return true;
12
+ if (process.env.FORCE_COLOR) return true;
13
+ if (process.env.NO_COLOR) return false;
14
+ return Boolean(process.stdout.isTTY);
15
+ }
16
+
17
+ export function stripAnsi(value) {
18
+ return value.replace(ANSI_RE, '');
19
+ }
20
+
21
+ function wrap(open, close, value) {
22
+ if (!isColorEnabled()) return value;
23
+ return `${open}${value}${close}`;
24
+ }
25
+
26
+ export function rgb(r, g, b, value) {
27
+ return wrap(`\u001b[38;2;${r};${g};${b}m`, '\u001b[39m', value);
28
+ }
29
+
30
+ export function bgRgb(r, g, b, value) {
31
+ return wrap(`\u001b[48;2;${r};${g};${b}m`, '\u001b[49m', value);
32
+ }
33
+
34
+ export const style = {
35
+ // Formatting
36
+ bold: (value) => wrap('\u001b[1m', '\u001b[22m', value),
37
+ dim: (value) => wrap('\u001b[2m', '\u001b[22m', value),
38
+ italic: (value) => wrap('\u001b[3m', '\u001b[23m', value),
39
+ underline: (value) => wrap('\u001b[4m', '\u001b[24m', value),
40
+
41
+ // Standard colors
42
+ red: (value) => wrap('\u001b[31m', '\u001b[39m', value),
43
+ green: (value) => wrap('\u001b[32m', '\u001b[39m', value),
44
+ yellow: (value) => wrap('\u001b[33m', '\u001b[39m', value),
45
+ blue: (value) => wrap('\u001b[34m', '\u001b[39m', value),
46
+ gray: (value) => rgb(106, 114, 130, value),
47
+
48
+ // ARKA primary — legacy red #c71244
49
+ arkaRed: (value) => rgb(199, 18, 68, value),
50
+
51
+ // Nemesis accent — blue-violet
52
+ nemesisAccent: (value) => rgb(99, 102, 241, value),
53
+
54
+ // Custom RGB
55
+ rgb: (r, g, b, value) => rgb(r, g, b, value),
56
+ bgRgb: (r, g, b, value) => bgRgb(r, g, b, value),
57
+ };