@aligndottech/cli 0.25.0 → 0.26.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 (54) hide show
  1. package/dist/commands/default-action.d.ts.map +1 -1
  2. package/dist/commands/default-action.js +5 -0
  3. package/dist/commands/default-action.js.map +1 -1
  4. package/dist/commands/dev/index.d.ts.map +1 -1
  5. package/dist/commands/dev/index.js +2 -1
  6. package/dist/commands/dev/index.js.map +1 -1
  7. package/dist/commands/import/confluence.d.ts.map +1 -1
  8. package/dist/commands/import/confluence.js +2 -1
  9. package/dist/commands/import/confluence.js.map +1 -1
  10. package/dist/commands/import/git.d.ts.map +1 -1
  11. package/dist/commands/import/git.js +2 -1
  12. package/dist/commands/import/git.js.map +1 -1
  13. package/dist/commands/import/github.d.ts.map +1 -1
  14. package/dist/commands/import/github.js +2 -1
  15. package/dist/commands/import/github.js.map +1 -1
  16. package/dist/commands/import/gitlab.d.ts.map +1 -1
  17. package/dist/commands/import/gitlab.js +2 -1
  18. package/dist/commands/import/gitlab.js.map +1 -1
  19. package/dist/commands/import/jira.d.ts.map +1 -1
  20. package/dist/commands/import/jira.js +2 -1
  21. package/dist/commands/import/jira.js.map +1 -1
  22. package/dist/commands/import/linear.d.ts.map +1 -1
  23. package/dist/commands/import/linear.js +2 -1
  24. package/dist/commands/import/linear.js.map +1 -1
  25. package/dist/commands/import/notion.d.ts.map +1 -1
  26. package/dist/commands/import/notion.js +2 -1
  27. package/dist/commands/import/notion.js.map +1 -1
  28. package/dist/commands/import/slack.d.ts.map +1 -1
  29. package/dist/commands/import/slack.js +2 -1
  30. package/dist/commands/import/slack.js.map +1 -1
  31. package/dist/commands/import/teams.d.ts.map +1 -1
  32. package/dist/commands/import/teams.js +2 -1
  33. package/dist/commands/import/teams.js.map +1 -1
  34. package/dist/commands/import/zoom.d.ts.map +1 -1
  35. package/dist/commands/import/zoom.js +2 -1
  36. package/dist/commands/import/zoom.js.map +1 -1
  37. package/dist/commands/login.d.ts.map +1 -1
  38. package/dist/commands/login.js +2 -1
  39. package/dist/commands/login.js.map +1 -1
  40. package/dist/commands/mcp.d.ts.map +1 -1
  41. package/dist/commands/mcp.js +3 -2
  42. package/dist/commands/mcp.js.map +1 -1
  43. package/dist/commands/setup.d.ts.map +1 -1
  44. package/dist/commands/setup.js +159 -109
  45. package/dist/commands/setup.js.map +1 -1
  46. package/dist/lib/brand.d.ts +59 -0
  47. package/dist/lib/brand.d.ts.map +1 -0
  48. package/dist/lib/brand.js +197 -0
  49. package/dist/lib/brand.js.map +1 -0
  50. package/dist/lib/setup-ux.d.ts +38 -0
  51. package/dist/lib/setup-ux.d.ts.map +1 -0
  52. package/dist/lib/setup-ux.js +73 -0
  53. package/dist/lib/setup-ux.js.map +1 -0
  54. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brand.d.ts","sourceRoot":"","sources":["../../src/lib/brand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,KAAK;;;CAGR,CAAC;AAWX,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,SAAS,IAAI,CAAC;AAE3B;;;GAGG;AACH,eAAO,MAAM,aAAa,4EAGhB,CAAC;AAmBX;0EAC0E;AAC1E,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAanD,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iFAAiF;IACjF,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAuCD,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,IAAI,GAAE,aAAkB,GAAG,MAAM,EAAE,CAwC5D;AAED,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAkBlD;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,MAAM,CAK5E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAIxD"}
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Align brand rendering for the terminal.
3
+ *
4
+ * The mark is AUTHORED at terminal resolution, not downsampled from the vector logo.
5
+ * Resampling the detailed mark to this size was tried first and read as mud: the thin
6
+ * strokes and the inner triangle turn to noise below about 40 rows. So this is pixel
7
+ * art of the mark - chevron, inner triangle, the teal bar and the two feet - drawn to
8
+ * survive at 16x5 cells, packed two pixel rows per terminal row with half blocks.
9
+ *
10
+ * On a dark terminal the navy strokes are rendered WHITE, following the brand pack's
11
+ * own knockout variant (F 4 R): navy on a dark background is invisible, which is why
12
+ * that variant exists. The teal stays teal in both, as it does in the artwork.
13
+ */
14
+ export const BRAND = {
15
+ teal: '#43b6ac',
16
+ navy: '#022863',
17
+ };
18
+ const TEAL_RGB = [67, 182, 172];
19
+ const NAVY_RGB = [2, 40, 99];
20
+ const WHITE_RGB = [255, 255, 255];
21
+ // 256-colour approximations, for terminals that report colour but not truecolor.
22
+ const TEAL_256 = 79;
23
+ const NAVY_256 = 24;
24
+ const WHITE_256 = 231;
25
+ export const LOGO_WIDTH = 20;
26
+ export const LOGO_ROWS = 8;
27
+ /**
28
+ * The live positioning line, taken from align-frontend's hero (src/lib/seo.ts).
29
+ * 'Collaboration with clarity built in' is RETIRED - do not reintroduce it.
30
+ */
31
+ export const TAGLINE_LINES = [
32
+ 'Your AI agents know the code.',
33
+ "They don't know the company.",
34
+ ];
35
+ /**
36
+ * One character per terminal cell, encoding the two pixel rows it covers:
37
+ * ' ' both empty 'N' both mark 'T' both teal
38
+ * 'n' mark on top 'u' mark below 't' teal on top 'v' teal below
39
+ * 'x' mark over teal 'y' teal over mark
40
+ */
41
+ const SPRITE = [
42
+ ' unnu ',
43
+ ' NnuunN ',
44
+ ' NnunnunN ',
45
+ ' uNNuNuuNuNNuuuuu',
46
+ 'vvvvvvvvvvvvvvvvvv ',
47
+ ' vvvvv vvvvv ',
48
+ ' uu uu uu uu ',
49
+ ' NNuNN NNuNN ',
50
+ ];
51
+ const SPRITE_SOLID = [
52
+ ' uNNu ',
53
+ ' NNnnNN ',
54
+ ' NNnuunNN ',
55
+ ' uNNNuNNuNNNuuuuu',
56
+ 'vvvvvvvvvvvvvvvvvv ',
57
+ ' vvvvv vvvvv ',
58
+ ' uuu uuu uuu uuu ',
59
+ ' NNNuNNN NNNuNNN ',
60
+ ];
61
+ function resolveColor(o) {
62
+ if (typeof o.color === 'boolean')
63
+ return o.color;
64
+ // NO_COLOR is honoured whatever its value, per the no-color.org convention: the
65
+ // variable's PRESENCE is the signal, so `NO_COLOR=0` still disables colour.
66
+ if (process.env['NO_COLOR'] !== undefined)
67
+ return false;
68
+ return Boolean(process.stdout.isTTY);
69
+ }
70
+ function resolveTruecolor(o) {
71
+ if (typeof o.truecolor === 'boolean')
72
+ return o.truecolor;
73
+ const ct = process.env['COLORTERM'] ?? '';
74
+ return ct === 'truecolor' || ct === '24bit';
75
+ }
76
+ function resolveDark(o) {
77
+ if (typeof o.dark === 'boolean')
78
+ return o.dark;
79
+ // COLORFGBG is "fg;bg"; a bg of 0-6 or 8 means a dark background. Absent on most
80
+ // terminals, and dark is the safer default: a white mark on an unexpectedly light
81
+ // background is faint, whereas navy on an unexpectedly dark one is unreadable.
82
+ const fgbg = process.env['COLORFGBG'];
83
+ if (fgbg) {
84
+ const bg = Number(fgbg.split(';').pop());
85
+ if (Number.isFinite(bg))
86
+ return bg <= 6 || bg === 8;
87
+ }
88
+ return true;
89
+ }
90
+ function fg(rgb, c256, truecolor) {
91
+ return truecolor ? `\x1b[38;2;${rgb[0]};${rgb[1]};${rgb[2]}m` : `\x1b[38;5;${c256}m`;
92
+ }
93
+ function bg(rgb, c256, truecolor) {
94
+ return truecolor ? `\x1b[48;2;${rgb[0]};${rgb[1]};${rgb[2]}m` : `\x1b[48;5;${c256}m`;
95
+ }
96
+ const RESET = '\x1b[0m';
97
+ /** The mark, one string per terminal row, all exactly LOGO_WIDTH cells wide. */
98
+ export function logoLines(opts = {}) {
99
+ const color = resolveColor(opts);
100
+ const truecolor = resolveTruecolor(opts);
101
+ const markRgb = resolveDark(opts) ? WHITE_RGB : NAVY_RGB;
102
+ const mark256 = resolveDark(opts) ? WHITE_256 : NAVY_256;
103
+ const style = opts.style ?? 'white';
104
+ // 'teal' paints the strokes teal instead of the knockout white; 'solid' also swaps in
105
+ // the filled sprite, which reads bolder because the mass carries the colour rather
106
+ // than a one-cell outline.
107
+ const strokeRgb = style === 'white' ? markRgb : TEAL_RGB;
108
+ const stroke256 = style === 'white' ? mark256 : TEAL_256;
109
+ return (style === 'solid' ? SPRITE_SOLID : SPRITE).map((row) => {
110
+ let out = '';
111
+ for (const cell of row) {
112
+ // Plain mode still uses the blocks: the shape is the point, and stripping
113
+ // colour must not change the width or the silhouette.
114
+ if (!color) {
115
+ out += cell === ' ' ? ' '
116
+ : cell === 'N' || cell === 'T' ? '█'
117
+ : cell === 'n' || cell === 't' ? '▀'
118
+ : cell === 'u' || cell === 'v' ? '▄'
119
+ : '█';
120
+ continue;
121
+ }
122
+ switch (cell) {
123
+ case ' ':
124
+ out += ' ';
125
+ break;
126
+ case 'N':
127
+ out += `${fg(strokeRgb, stroke256, truecolor)}█${RESET}`;
128
+ break;
129
+ case 'T':
130
+ out += `${fg(TEAL_RGB, TEAL_256, truecolor)}█${RESET}`;
131
+ break;
132
+ case 'n':
133
+ out += `${fg(strokeRgb, stroke256, truecolor)}▀${RESET}`;
134
+ break;
135
+ case 'u':
136
+ out += `${fg(strokeRgb, stroke256, truecolor)}▄${RESET}`;
137
+ break;
138
+ case 't':
139
+ out += `${fg(TEAL_RGB, TEAL_256, truecolor)}▀${RESET}`;
140
+ break;
141
+ case 'v':
142
+ out += `${fg(TEAL_RGB, TEAL_256, truecolor)}▄${RESET}`;
143
+ break;
144
+ case 'x':
145
+ out += `${fg(strokeRgb, stroke256, truecolor) + bg(TEAL_RGB, TEAL_256, truecolor)}▀${RESET}`;
146
+ break;
147
+ case 'y':
148
+ out += `${fg(TEAL_RGB, TEAL_256, truecolor) + bg(strokeRgb, stroke256, truecolor)}▀${RESET}`;
149
+ break;
150
+ default: out += ' ';
151
+ }
152
+ }
153
+ return out;
154
+ });
155
+ }
156
+ /**
157
+ * The full lockup: the mark on the left, wordmark and tagline to its right, so the
158
+ * whole thing is only as tall as the mark (LOGO_ROWS) rather than stacking.
159
+ */
160
+ export function banner(opts) {
161
+ const color = resolveColor(opts);
162
+ const truecolor = resolveTruecolor(opts);
163
+ const dim = color ? '\x1b[2m' : '';
164
+ const bold = color ? '\x1b[1m' : '';
165
+ const tealFg = color ? fg(TEAL_RGB, TEAL_256, truecolor) : '';
166
+ const reset = color ? RESET : '';
167
+ const right = new Array(LOGO_ROWS).fill('');
168
+ // Registered, not TM: Align is a registered trademark.
169
+ right[1] = `${bold}ALIGN®${reset}`;
170
+ right[2] = `${tealFg}${TAGLINE_LINES[0]}${reset}`;
171
+ right[3] = `${tealFg}${TAGLINE_LINES[1]}${reset}`;
172
+ const meta = opts.context ? `v${opts.version} ${'\u00b7'} ${opts.context}` : `v${opts.version}`;
173
+ right[5] = `${dim}${meta}${reset}`;
174
+ const mark = logoLines(opts);
175
+ return mark.map((m, i) => (right[i] ? `${m} ${right[i]}` : m)).join('\n');
176
+ }
177
+ /** One consistent intro chip for every command, in brand teal. */
178
+ export function commandIntro(label, opts = {}) {
179
+ const color = resolveColor(opts);
180
+ if (!color)
181
+ return ` ${label} `;
182
+ const truecolor = resolveTruecolor(opts);
183
+ return `${bg(TEAL_RGB, TEAL_256, truecolor)}${fg(NAVY_RGB, NAVY_256, truecolor)} ${label} ${RESET}`;
184
+ }
185
+ /**
186
+ * Print the banner, but only when someone is actually looking at a terminal.
187
+ *
188
+ * Piped output (`align ask ... | jq`) and CI logs must stay clean, so this is a
189
+ * no-op off a TTY rather than a plain-text banner.
190
+ */
191
+ export function printBanner(opts) {
192
+ if (!process.stdout.isTTY)
193
+ return false;
194
+ process.stdout.write(`${banner(opts)}\n`);
195
+ return true;
196
+ }
197
+ //# sourceMappingURL=brand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brand.js","sourceRoot":"","sources":["../../src/lib/brand.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * How many options `@clack/prompts` may render at once.
3
+ *
4
+ * Without this, clack draws every option and its in-place redraw miscounts once
5
+ * the list is taller than the viewport, duplicating rows on screen. An outside
6
+ * tester hit exactly that on 2026-08-30: seven connectors, a screenful of git
7
+ * import output above them, and "Notion" painted three times.
8
+ */
9
+ export declare function pickerMaxItems(rows: number | undefined, optionCount: number): number;
10
+ /**
11
+ * Read an already-authenticated token out of a local CLI, so a user who has
12
+ * `gh` set up is not sent to a browser to mint a PAT by hand.
13
+ *
14
+ * Returns null for every failure - not installed, not logged in, or authenticated
15
+ * but printing nothing. Null means "ask the user normally", so a broken or absent
16
+ * CLI degrades to the flow that existed before rather than to an error.
17
+ */
18
+ export declare function detectCliToken(bin: string, args: string[]): Promise<string | null>;
19
+ /** Connectors whose token can be read from an already-authenticated local CLI. */
20
+ export declare const CLI_TOKEN_SOURCES: Record<string, {
21
+ bin: string;
22
+ args: string[];
23
+ label: string;
24
+ }>;
25
+ /**
26
+ * Whether to use a token found in a local CLI, ask first, or ignore it.
27
+ *
28
+ * Separate from the prompt chain on purpose. `--approve` is documented as "Skip
29
+ * confirmation prompts (for scripted use)", and this repo has already shipped one
30
+ * prompt that ignored it - setup.ts still carries the comment about `align setup
31
+ * --approve` hanging when two agents were installed. A rule buried in an async
32
+ * prompt chain is not testable; this is.
33
+ */
34
+ export declare function cliTokenDecision(o: {
35
+ token: string | null;
36
+ approve: boolean;
37
+ }): 'use' | 'ask' | 'skip';
38
+ //# sourceMappingURL=setup-ux.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-ux.d.ts","sourceRoot":"","sources":["../../src/lib/setup-ux.ts"],"names":[],"mappings":"AAsBA;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAIpF;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWxF;AAED,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAE5F,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAKtG"}
@@ -0,0 +1,73 @@
1
+ import { execa } from 'execa';
2
+ /**
3
+ * Sizing and credential-discovery helpers for `align setup`.
4
+ *
5
+ * Lives outside setup.ts deliberately: that file is 833 lines and the 900-line
6
+ * ratchet is real, but more importantly these two are pure enough to test
7
+ * directly, which the flow around them is not.
8
+ */
9
+ // Lines the prompt needs beyond the option rows themselves: the message, clack's
10
+ // top and bottom rules, the submit hint, and enough slack that the previous
11
+ // command's last line is not overwritten.
12
+ const RESERVED_ROWS = 8;
13
+ // Below this a paginated list is unusable, so we overflow slightly rather than
14
+ // render one option at a time. clack scrolls within maxItems, so a floor is safe.
15
+ const MIN_VISIBLE = 3;
16
+ // Used when stdout is not a TTY and reports no size. 24 is the classic default.
17
+ const ASSUMED_ROWS = 24;
18
+ /**
19
+ * How many options `@clack/prompts` may render at once.
20
+ *
21
+ * Without this, clack draws every option and its in-place redraw miscounts once
22
+ * the list is taller than the viewport, duplicating rows on screen. An outside
23
+ * tester hit exactly that on 2026-08-30: seven connectors, a screenful of git
24
+ * import output above them, and "Notion" painted three times.
25
+ */
26
+ export function pickerMaxItems(rows, optionCount) {
27
+ const height = typeof rows === 'number' && Number.isFinite(rows) && rows > 0 ? rows : ASSUMED_ROWS;
28
+ const usable = Math.max(MIN_VISIBLE, height - RESERVED_ROWS);
29
+ return Math.min(optionCount, usable);
30
+ }
31
+ /**
32
+ * Read an already-authenticated token out of a local CLI, so a user who has
33
+ * `gh` set up is not sent to a browser to mint a PAT by hand.
34
+ *
35
+ * Returns null for every failure - not installed, not logged in, or authenticated
36
+ * but printing nothing. Null means "ask the user normally", so a broken or absent
37
+ * CLI degrades to the flow that existed before rather than to an error.
38
+ */
39
+ export async function detectCliToken(bin, args) {
40
+ try {
41
+ // execa rejects on a non-zero exit, so the catch covers "not logged in"; the
42
+ // explicit check covers a runner configured with reject:false upstream.
43
+ const result = await execa(bin, args, { timeout: 5_000 });
44
+ if (typeof result?.exitCode === 'number' && result.exitCode !== 0)
45
+ return null;
46
+ const token = String(result?.stdout ?? '').trim();
47
+ return token.length > 0 ? token : null;
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ /** Connectors whose token can be read from an already-authenticated local CLI. */
54
+ export const CLI_TOKEN_SOURCES = {
55
+ github: { bin: 'gh', args: ['auth', 'token'], label: 'GitHub CLI (gh)' },
56
+ };
57
+ /**
58
+ * Whether to use a token found in a local CLI, ask first, or ignore it.
59
+ *
60
+ * Separate from the prompt chain on purpose. `--approve` is documented as "Skip
61
+ * confirmation prompts (for scripted use)", and this repo has already shipped one
62
+ * prompt that ignored it - setup.ts still carries the comment about `align setup
63
+ * --approve` hanging when two agents were installed. A rule buried in an async
64
+ * prompt chain is not testable; this is.
65
+ */
66
+ export function cliTokenDecision(o) {
67
+ if (!o.token)
68
+ return 'skip';
69
+ // --approve means the affirmative, not the absence of the step: skipping the
70
+ // connector would silently drop a source the user could have had.
71
+ return o.approve ? 'use' : 'ask';
72
+ }
73
+ //# sourceMappingURL=setup-ux.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-ux.js","sourceRoot":"","sources":["../../src/lib/setup-ux.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B;;;;;;GAMG;AAEH,iFAAiF;AACjF,4EAA4E;AAC5E,0CAA0C;AAC1C,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,+EAA+E;AAC/E,kFAAkF;AAClF,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB,gFAAgF;AAChF,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,IAAwB,EAAE,WAAmB;IAC1E,MAAM,MAAM,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC;IACnG,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC;IAC7D,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,IAAc;IAC9D,IAAI,CAAC;QACH,6EAA6E;QAC7E,wEAAwE;QACxE,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,IAAI,OAAO,MAAM,EAAE,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,iBAAiB,GAAmE;IAC/F,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE;CACzE,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAA6C;IAC5E,IAAI,CAAC,CAAC,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAC5B,6EAA6E;IAC7E,kEAAkE;IAClE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACnC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aligndottech/cli",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "mcpName": "io.github.aligndottech/cli",
5
5
  "type": "module",
6
6
  "description": "Align CLI - capture decisions, check alignment, and manage connectors",