@inkeep/agents-cli 0.59.4 → 0.61.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 (28) hide show
  1. package/dist/agents-cli/package.js +1 -1
  2. package/dist/api.js +74 -2
  3. package/dist/api.js.map +1 -1
  4. package/dist/commands/pull-v4/generators/agent-generator.js +2 -2
  5. package/dist/commands/pull-v4/generators/agent-generator.js.map +1 -1
  6. package/dist/commands/pull-v4/generators/context-config-generator.js.map +1 -1
  7. package/dist/commands/pull-v4/introspect/index.js +70 -17
  8. package/dist/commands/pull-v4/introspect/index.js.map +1 -1
  9. package/dist/commands/pull-v4/merge-conflicts.js +37 -0
  10. package/dist/commands/pull-v4/merge-conflicts.js.map +1 -0
  11. package/dist/commands/pull-v4/merge-ui/column-row.js +63 -0
  12. package/dist/commands/pull-v4/merge-ui/column-row.js.map +1 -0
  13. package/dist/commands/pull-v4/merge-ui/conflict-view.js +135 -0
  14. package/dist/commands/pull-v4/merge-ui/conflict-view.js.map +1 -0
  15. package/dist/commands/pull-v4/merge-ui/help-bar.js +79 -0
  16. package/dist/commands/pull-v4/merge-ui/help-bar.js.map +1 -0
  17. package/dist/commands/pull-v4/merge-ui/merge-app.js +239 -0
  18. package/dist/commands/pull-v4/merge-ui/merge-app.js.map +1 -0
  19. package/dist/commands/pull-v4/merge-ui/resolution-summary.js +106 -0
  20. package/dist/commands/pull-v4/merge-ui/resolution-summary.js.map +1 -0
  21. package/dist/commands/pull-v4/merge-ui/types.js +1 -0
  22. package/dist/commands/pull-v4/merge-ui/utils.js +43 -0
  23. package/dist/commands/pull-v4/merge-ui/utils.js.map +1 -0
  24. package/dist/index.js +2 -2
  25. package/dist/index.js.map +1 -1
  26. package/dist/utils/state.js +46 -0
  27. package/dist/utils/state.js.map +1 -0
  28. package/package.json +7 -4
@@ -0,0 +1,79 @@
1
+ import { Box, Text } from "ink";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+
4
+ //#region src/commands/pull-v4/merge-ui/help-bar.tsx
5
+ function Key({ label, action }) {
6
+ return /* @__PURE__ */ jsxs(Box, {
7
+ marginRight: 2,
8
+ children: [/* @__PURE__ */ jsx(Text, {
9
+ bold: true,
10
+ color: "yellow",
11
+ children: label
12
+ }), /* @__PURE__ */ jsxs(Text, {
13
+ dimColor: true,
14
+ children: [" ", action]
15
+ })]
16
+ });
17
+ }
18
+ function HelpBar({ phase }) {
19
+ if (phase === "summary") return /* @__PURE__ */ jsxs(Box, {
20
+ borderStyle: "single",
21
+ borderTop: true,
22
+ borderBottom: false,
23
+ borderLeft: false,
24
+ borderRight: false,
25
+ paddingX: 1,
26
+ children: [
27
+ /* @__PURE__ */ jsx(Key, {
28
+ label: "Enter",
29
+ action: "confirm"
30
+ }),
31
+ /* @__PURE__ */ jsx(Key, {
32
+ label: "b",
33
+ action: "back"
34
+ }),
35
+ /* @__PURE__ */ jsx(Key, {
36
+ label: "Esc/q",
37
+ action: "cancel"
38
+ })
39
+ ]
40
+ });
41
+ return /* @__PURE__ */ jsxs(Box, {
42
+ borderStyle: "single",
43
+ borderTop: true,
44
+ borderBottom: false,
45
+ borderLeft: false,
46
+ borderRight: false,
47
+ paddingX: 1,
48
+ children: [
49
+ /* @__PURE__ */ jsx(Key, {
50
+ label: "↑↓/jk",
51
+ action: "navigate"
52
+ }),
53
+ /* @__PURE__ */ jsx(Key, {
54
+ label: "←/1",
55
+ action: "ours"
56
+ }),
57
+ /* @__PURE__ */ jsx(Key, {
58
+ label: "→/2",
59
+ action: "theirs"
60
+ }),
61
+ /* @__PURE__ */ jsx(Key, {
62
+ label: "Enter/n",
63
+ action: "next"
64
+ }),
65
+ /* @__PURE__ */ jsx(Key, {
66
+ label: "p",
67
+ action: "prev"
68
+ }),
69
+ /* @__PURE__ */ jsx(Key, {
70
+ label: "Esc/q",
71
+ action: "cancel"
72
+ })
73
+ ]
74
+ });
75
+ }
76
+
77
+ //#endregion
78
+ export { HelpBar };
79
+ //# sourceMappingURL=help-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help-bar.js","names":[],"sources":["../../../../src/commands/pull-v4/merge-ui/help-bar.tsx"],"sourcesContent":["import { Box, Text } from 'ink';\n\ninterface HelpBarProps {\n phase: 'resolving' | 'summary';\n}\n\nfunction Key({ label, action }: { label: string; action: string }) {\n return (\n <Box marginRight={2}>\n <Text bold color=\"yellow\">\n {label}\n </Text>\n <Text dimColor> {action}</Text>\n </Box>\n );\n}\n\nexport function HelpBar({ phase }: HelpBarProps) {\n if (phase === 'summary') {\n return (\n <Box\n borderStyle=\"single\"\n borderTop\n borderBottom={false}\n borderLeft={false}\n borderRight={false}\n paddingX={1}\n >\n <Key label=\"Enter\" action=\"confirm\" />\n <Key label=\"b\" action=\"back\" />\n <Key label=\"Esc/q\" action=\"cancel\" />\n </Box>\n );\n }\n\n return (\n <Box\n borderStyle=\"single\"\n borderTop\n borderBottom={false}\n borderLeft={false}\n borderRight={false}\n paddingX={1}\n >\n <Key label=\"↑↓/jk\" action=\"navigate\" />\n <Key label=\"←/1\" action=\"ours\" />\n <Key label=\"→/2\" action=\"theirs\" />\n <Key label=\"Enter/n\" action=\"next\" />\n <Key label=\"p\" action=\"prev\" />\n <Key label=\"Esc/q\" action=\"cancel\" />\n </Box>\n );\n}\n"],"mappings":";;;;AAMA,SAAS,IAAI,EAAE,OAAO,UAA6C;AACjE,QACE,qBAAC;EAAI,aAAa;aAChB,oBAAC;GAAK;GAAK,OAAM;aACd;IACI,EACP,qBAAC;GAAK;cAAS,KAAE;IAAc;GAC3B;;AAIV,SAAgB,QAAQ,EAAE,SAAuB;AAC/C,KAAI,UAAU,UACZ,QACE,qBAAC;EACC,aAAY;EACZ;EACA,cAAc;EACd,YAAY;EACZ,aAAa;EACb,UAAU;;GAEV,oBAAC;IAAI,OAAM;IAAQ,QAAO;KAAY;GACtC,oBAAC;IAAI,OAAM;IAAI,QAAO;KAAS;GAC/B,oBAAC;IAAI,OAAM;IAAQ,QAAO;KAAW;;GACjC;AAIV,QACE,qBAAC;EACC,aAAY;EACZ;EACA,cAAc;EACd,YAAY;EACZ,aAAa;EACb,UAAU;;GAEV,oBAAC;IAAI,OAAM;IAAQ,QAAO;KAAa;GACvC,oBAAC;IAAI,OAAM;IAAM,QAAO;KAAS;GACjC,oBAAC;IAAI,OAAM;IAAM,QAAO;KAAW;GACnC,oBAAC;IAAI,OAAM;IAAU,QAAO;KAAS;GACrC,oBAAC;IAAI,OAAM;IAAI,QAAO;KAAS;GAC/B,oBAAC;IAAI,OAAM;IAAQ,QAAO;KAAW;;GACjC"}
@@ -0,0 +1,239 @@
1
+ import { diffTypeColor, formatDiffType, formatEntityId, getChangedColumns } from "./utils.js";
2
+ import { ConflictView } from "./conflict-view.js";
3
+ import { HelpBar } from "./help-bar.js";
4
+ import { ResolutionSummary } from "./resolution-summary.js";
5
+ import { Box, Text, useApp, useInput } from "ink";
6
+ import { useEffect, useMemo, useReducer } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+
9
+ //#region src/commands/pull-v4/merge-ui/merge-app.tsx
10
+ function createInitialState(conflicts) {
11
+ return {
12
+ phase: "resolving",
13
+ currentConflictIndex: 0,
14
+ focusedColumnIndex: -1,
15
+ resolutions: conflicts.map(() => ({
16
+ rowDefaultPick: "ours",
17
+ columnOverrides: {}
18
+ }))
19
+ };
20
+ }
21
+ function mergeReducer(state, action) {
22
+ switch (action.type) {
23
+ case "SET_ROW_DEFAULT": {
24
+ const resolutions = [...state.resolutions];
25
+ resolutions[state.currentConflictIndex] = {
26
+ rowDefaultPick: action.side,
27
+ columnOverrides: {}
28
+ };
29
+ return {
30
+ ...state,
31
+ resolutions
32
+ };
33
+ }
34
+ case "SET_COLUMN_PICK": {
35
+ const resolutions = [...state.resolutions];
36
+ const current = resolutions[state.currentConflictIndex];
37
+ resolutions[state.currentConflictIndex] = {
38
+ ...current,
39
+ columnOverrides: {
40
+ ...current.columnOverrides,
41
+ [action.column]: action.side
42
+ }
43
+ };
44
+ return {
45
+ ...state,
46
+ resolutions
47
+ };
48
+ }
49
+ case "FOCUS_UP": return {
50
+ ...state,
51
+ focusedColumnIndex: state.focusedColumnIndex - 1
52
+ };
53
+ case "FOCUS_DOWN": return {
54
+ ...state,
55
+ focusedColumnIndex: state.focusedColumnIndex + 1
56
+ };
57
+ case "NEXT_CONFLICT": {
58
+ const nextIndex = state.currentConflictIndex + 1;
59
+ if (nextIndex >= action.totalConflicts) return {
60
+ ...state,
61
+ phase: "summary"
62
+ };
63
+ return {
64
+ ...state,
65
+ currentConflictIndex: nextIndex,
66
+ focusedColumnIndex: -1
67
+ };
68
+ }
69
+ case "PREV_CONFLICT":
70
+ if (state.currentConflictIndex <= 0) return state;
71
+ return {
72
+ ...state,
73
+ currentConflictIndex: state.currentConflictIndex - 1,
74
+ focusedColumnIndex: -1
75
+ };
76
+ case "GO_BACK_TO_RESOLVING": return {
77
+ ...state,
78
+ phase: "resolving",
79
+ currentConflictIndex: action.lastConflictIndex,
80
+ focusedColumnIndex: -1
81
+ };
82
+ case "CONFIRM": return {
83
+ ...state,
84
+ phase: "confirmed"
85
+ };
86
+ case "CANCEL": return {
87
+ ...state,
88
+ phase: "cancelled"
89
+ };
90
+ }
91
+ }
92
+ function buildResolutions(conflicts, resolutions, allChangedColumns) {
93
+ return conflicts.map((conflict, i) => {
94
+ const res = resolutions[i];
95
+ const changedCols = allChangedColumns[i];
96
+ const columns = {};
97
+ for (const col of changedCols) columns[col] = res.columnOverrides[col] ?? res.rowDefaultPick;
98
+ return {
99
+ table: conflict.table,
100
+ primaryKey: conflict.primaryKey,
101
+ rowDefaultPick: res.rowDefaultPick,
102
+ columns
103
+ };
104
+ });
105
+ }
106
+ function MergeApp({ conflicts }) {
107
+ const { exit } = useApp();
108
+ const [state, dispatch] = useReducer(mergeReducer, conflicts, createInitialState);
109
+ const isEmpty = conflicts.length === 0;
110
+ const allChangedColumns = useMemo(() => conflicts.map(getChangedColumns), [conflicts]);
111
+ const currentConflict = isEmpty ? void 0 : conflicts[state.currentConflictIndex];
112
+ const isRowLevelOnly = currentConflict?.ours === null || currentConflict?.theirs === null;
113
+ const currentChangedColumns = allChangedColumns[state.currentConflictIndex] ?? [];
114
+ const maxColumnIndex = currentChangedColumns.length - 1;
115
+ useEffect(() => {
116
+ if (isEmpty) {
117
+ exit([]);
118
+ return;
119
+ }
120
+ if (state.phase === "confirmed") exit(buildResolutions(conflicts, state.resolutions, allChangedColumns));
121
+ else if (state.phase === "cancelled") exit(null);
122
+ }, [
123
+ isEmpty,
124
+ state.phase,
125
+ conflicts,
126
+ state.resolutions,
127
+ allChangedColumns,
128
+ exit
129
+ ]);
130
+ useInput((input, key) => {
131
+ if (isEmpty) return;
132
+ if (key.escape || input === "q") {
133
+ dispatch({ type: "CANCEL" });
134
+ return;
135
+ }
136
+ if (state.phase === "summary") {
137
+ if (key.return) dispatch({ type: "CONFIRM" });
138
+ if (input === "b" || input === "p") dispatch({
139
+ type: "GO_BACK_TO_RESOLVING",
140
+ lastConflictIndex: conflicts.length - 1
141
+ });
142
+ return;
143
+ }
144
+ if (state.phase !== "resolving") return;
145
+ if (!isRowLevelOnly) {
146
+ if (key.upArrow || input === "k") {
147
+ if (state.focusedColumnIndex > -1) dispatch({ type: "FOCUS_UP" });
148
+ }
149
+ if (key.downArrow || input === "j") {
150
+ if (state.focusedColumnIndex < maxColumnIndex) dispatch({ type: "FOCUS_DOWN" });
151
+ }
152
+ }
153
+ if (input === "1" || input === "l" || key.leftArrow) if (isRowLevelOnly || state.focusedColumnIndex === -1) dispatch({
154
+ type: "SET_ROW_DEFAULT",
155
+ side: "ours"
156
+ });
157
+ else dispatch({
158
+ type: "SET_COLUMN_PICK",
159
+ column: currentChangedColumns[state.focusedColumnIndex],
160
+ side: "ours"
161
+ });
162
+ if (input === "2" || input === "r" || key.rightArrow) if (isRowLevelOnly || state.focusedColumnIndex === -1) dispatch({
163
+ type: "SET_ROW_DEFAULT",
164
+ side: "theirs"
165
+ });
166
+ else dispatch({
167
+ type: "SET_COLUMN_PICK",
168
+ column: currentChangedColumns[state.focusedColumnIndex],
169
+ side: "theirs"
170
+ });
171
+ if (key.return || input === "n") dispatch({
172
+ type: "NEXT_CONFLICT",
173
+ totalConflicts: conflicts.length
174
+ });
175
+ if (input === "p") dispatch({ type: "PREV_CONFLICT" });
176
+ });
177
+ if (isEmpty) return null;
178
+ const conflictListHeader = /* @__PURE__ */ jsxs(Box, {
179
+ flexDirection: "column",
180
+ marginBottom: 1,
181
+ children: [/* @__PURE__ */ jsxs(Text, {
182
+ color: "yellow",
183
+ children: [conflicts.length, " conflict(s) found:"]
184
+ }), conflicts.map((c, i) => {
185
+ const entity = formatEntityId(c.primaryKey);
186
+ return /* @__PURE__ */ jsxs(Text, { children: [
187
+ " ",
188
+ i + 1,
189
+ ". ",
190
+ /* @__PURE__ */ jsx(Text, {
191
+ color: "cyan",
192
+ children: c.table
193
+ }),
194
+ " ",
195
+ /* @__PURE__ */ jsx(Text, {
196
+ bold: true,
197
+ children: entity
198
+ }),
199
+ " local: ",
200
+ /* @__PURE__ */ jsx(Text, {
201
+ color: diffTypeColor(c.ourDiffType),
202
+ children: formatDiffType(c.ourDiffType)
203
+ }),
204
+ " | remote: ",
205
+ /* @__PURE__ */ jsx(Text, {
206
+ color: diffTypeColor(c.theirDiffType),
207
+ children: formatDiffType(c.theirDiffType)
208
+ })
209
+ ] }, `${c.table}-${entity}`);
210
+ })]
211
+ });
212
+ if (state.phase === "summary") return /* @__PURE__ */ jsxs(Box, {
213
+ flexDirection: "column",
214
+ children: [conflictListHeader, /* @__PURE__ */ jsx(ResolutionSummary, {
215
+ conflicts,
216
+ resolutions: state.resolutions,
217
+ allChangedColumns
218
+ })]
219
+ });
220
+ return /* @__PURE__ */ jsxs(Box, {
221
+ flexDirection: "column",
222
+ children: [
223
+ conflictListHeader,
224
+ /* @__PURE__ */ jsx(ConflictView, {
225
+ conflict: conflicts[state.currentConflictIndex],
226
+ resolution: state.resolutions[state.currentConflictIndex],
227
+ changedColumns: currentChangedColumns,
228
+ focusedColumnIndex: state.focusedColumnIndex,
229
+ conflictIndex: state.currentConflictIndex,
230
+ totalConflicts: conflicts.length
231
+ }),
232
+ /* @__PURE__ */ jsx(HelpBar, { phase: "resolving" })
233
+ ]
234
+ });
235
+ }
236
+
237
+ //#endregion
238
+ export { MergeApp };
239
+ //# sourceMappingURL=merge-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-app.js","names":[],"sources":["../../../../src/commands/pull-v4/merge-ui/merge-app.tsx"],"sourcesContent":["import type { ConflictItem, ConflictResolution } from '@inkeep/agents-core';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport { useEffect, useMemo, useReducer } from 'react';\nimport { ConflictView } from './conflict-view';\nimport { HelpBar } from './help-bar';\nimport { ResolutionSummary } from './resolution-summary';\nimport type { ConflictResolutionState, MergeAction, MergeState, Side } from './types';\nimport { diffTypeColor, formatDiffType, formatEntityId, getChangedColumns } from './utils';\n\nfunction createInitialState(conflicts: ConflictItem[]): MergeState {\n return {\n phase: 'resolving',\n currentConflictIndex: 0,\n focusedColumnIndex: -1,\n resolutions: conflicts.map(\n (): ConflictResolutionState => ({\n rowDefaultPick: 'ours',\n columnOverrides: {},\n })\n ),\n };\n}\n\nfunction mergeReducer(state: MergeState, action: MergeAction): MergeState {\n switch (action.type) {\n case 'SET_ROW_DEFAULT': {\n const resolutions = [...state.resolutions];\n resolutions[state.currentConflictIndex] = {\n rowDefaultPick: action.side,\n columnOverrides: {},\n };\n return { ...state, resolutions };\n }\n case 'SET_COLUMN_PICK': {\n const resolutions = [...state.resolutions];\n const current = resolutions[state.currentConflictIndex];\n resolutions[state.currentConflictIndex] = {\n ...current,\n columnOverrides: {\n ...current.columnOverrides,\n [action.column]: action.side,\n },\n };\n return { ...state, resolutions };\n }\n case 'FOCUS_UP':\n return { ...state, focusedColumnIndex: state.focusedColumnIndex - 1 };\n case 'FOCUS_DOWN':\n return { ...state, focusedColumnIndex: state.focusedColumnIndex + 1 };\n case 'NEXT_CONFLICT': {\n const nextIndex = state.currentConflictIndex + 1;\n if (nextIndex >= action.totalConflicts) {\n return { ...state, phase: 'summary' };\n }\n return { ...state, currentConflictIndex: nextIndex, focusedColumnIndex: -1 };\n }\n case 'PREV_CONFLICT': {\n if (state.currentConflictIndex <= 0) return state;\n return {\n ...state,\n currentConflictIndex: state.currentConflictIndex - 1,\n focusedColumnIndex: -1,\n };\n }\n case 'GO_BACK_TO_RESOLVING':\n return {\n ...state,\n phase: 'resolving',\n currentConflictIndex: action.lastConflictIndex,\n focusedColumnIndex: -1,\n };\n case 'CONFIRM':\n return { ...state, phase: 'confirmed' };\n case 'CANCEL':\n return { ...state, phase: 'cancelled' };\n }\n}\n\nfunction buildResolutions(\n conflicts: ConflictItem[],\n resolutions: ConflictResolutionState[],\n allChangedColumns: string[][]\n): ConflictResolution[] {\n return conflicts.map((conflict, i) => {\n const res = resolutions[i];\n const changedCols = allChangedColumns[i];\n const columns: Record<string, Side> = {};\n for (const col of changedCols) {\n columns[col] = res.columnOverrides[col] ?? res.rowDefaultPick;\n }\n return {\n table: conflict.table,\n primaryKey: conflict.primaryKey,\n rowDefaultPick: res.rowDefaultPick,\n columns,\n };\n });\n}\n\ninterface MergeAppProps {\n conflicts: ConflictItem[];\n}\n\nexport function MergeApp({ conflicts }: MergeAppProps) {\n const { exit } = useApp();\n const [state, dispatch] = useReducer(mergeReducer, conflicts, createInitialState);\n const isEmpty = conflicts.length === 0;\n\n const allChangedColumns = useMemo(() => conflicts.map(getChangedColumns), [conflicts]);\n\n const currentConflict = isEmpty ? undefined : conflicts[state.currentConflictIndex];\n const isRowLevelOnly = currentConflict?.ours === null || currentConflict?.theirs === null;\n const currentChangedColumns = allChangedColumns[state.currentConflictIndex] ?? [];\n const maxColumnIndex = currentChangedColumns.length - 1;\n\n useEffect(() => {\n if (isEmpty) {\n exit([]);\n return;\n }\n if (state.phase === 'confirmed') {\n exit(buildResolutions(conflicts, state.resolutions, allChangedColumns));\n } else if (state.phase === 'cancelled') {\n exit(null);\n }\n }, [isEmpty, state.phase, conflicts, state.resolutions, allChangedColumns, exit]);\n\n useInput((input, key) => {\n if (isEmpty) return;\n\n if (key.escape || input === 'q') {\n dispatch({ type: 'CANCEL' });\n return;\n }\n\n if (state.phase === 'summary') {\n if (key.return) {\n dispatch({ type: 'CONFIRM' });\n }\n if (input === 'b' || input === 'p') {\n dispatch({ type: 'GO_BACK_TO_RESOLVING', lastConflictIndex: conflicts.length - 1 });\n }\n return;\n }\n\n if (state.phase !== 'resolving') return;\n\n if (!isRowLevelOnly) {\n if (key.upArrow || input === 'k') {\n if (state.focusedColumnIndex > -1) {\n dispatch({ type: 'FOCUS_UP' });\n }\n }\n if (key.downArrow || input === 'j') {\n if (state.focusedColumnIndex < maxColumnIndex) {\n dispatch({ type: 'FOCUS_DOWN' });\n }\n }\n }\n\n if (input === '1' || input === 'l' || key.leftArrow) {\n if (isRowLevelOnly || state.focusedColumnIndex === -1) {\n dispatch({ type: 'SET_ROW_DEFAULT', side: 'ours' });\n } else {\n dispatch({\n type: 'SET_COLUMN_PICK',\n column: currentChangedColumns[state.focusedColumnIndex],\n side: 'ours',\n });\n }\n }\n if (input === '2' || input === 'r' || key.rightArrow) {\n if (isRowLevelOnly || state.focusedColumnIndex === -1) {\n dispatch({ type: 'SET_ROW_DEFAULT', side: 'theirs' });\n } else {\n dispatch({\n type: 'SET_COLUMN_PICK',\n column: currentChangedColumns[state.focusedColumnIndex],\n side: 'theirs',\n });\n }\n }\n\n if (key.return || input === 'n') {\n dispatch({ type: 'NEXT_CONFLICT', totalConflicts: conflicts.length });\n }\n if (input === 'p') {\n dispatch({ type: 'PREV_CONFLICT' });\n }\n });\n\n if (isEmpty) return null;\n\n const conflictListHeader = (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"yellow\">{conflicts.length} conflict(s) found:</Text>\n {conflicts.map((c, i) => {\n const entity = formatEntityId(c.primaryKey);\n return (\n <Text key={`${c.table}-${entity}`}>\n {' '}\n {i + 1}. <Text color=\"cyan\">{c.table}</Text> <Text bold>{entity}</Text>\n {' local: '}\n <Text color={diffTypeColor(c.ourDiffType)}>{formatDiffType(c.ourDiffType)}</Text>\n {' | remote: '}\n <Text color={diffTypeColor(c.theirDiffType)}>{formatDiffType(c.theirDiffType)}</Text>\n </Text>\n );\n })}\n </Box>\n );\n\n if (state.phase === 'summary') {\n return (\n <Box flexDirection=\"column\">\n {conflictListHeader}\n <ResolutionSummary\n conflicts={conflicts}\n resolutions={state.resolutions}\n allChangedColumns={allChangedColumns}\n />\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n {conflictListHeader}\n <ConflictView\n conflict={conflicts[state.currentConflictIndex]}\n resolution={state.resolutions[state.currentConflictIndex]}\n changedColumns={currentChangedColumns}\n focusedColumnIndex={state.focusedColumnIndex}\n conflictIndex={state.currentConflictIndex}\n totalConflicts={conflicts.length}\n />\n <HelpBar phase=\"resolving\" />\n </Box>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ import { formatEntityId } from "./utils.js";
2
+ import { Box, Text } from "ink";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+
5
+ //#region src/commands/pull-v4/merge-ui/resolution-summary.tsx
6
+ function ResolutionSummary({ conflicts, resolutions, allChangedColumns }) {
7
+ return /* @__PURE__ */ jsx(Box, {
8
+ flexDirection: "column",
9
+ children: /* @__PURE__ */ jsxs(Box, {
10
+ borderStyle: "round",
11
+ borderColor: "cyan",
12
+ paddingX: 1,
13
+ flexDirection: "column",
14
+ children: [
15
+ /* @__PURE__ */ jsx(Text, {
16
+ bold: true,
17
+ color: "cyan",
18
+ children: "Resolution Summary"
19
+ }),
20
+ /* @__PURE__ */ jsx(Text, {
21
+ dimColor: true,
22
+ children: "─".repeat(50)
23
+ }),
24
+ conflicts.map((conflict, i) => {
25
+ const resolution = resolutions[i];
26
+ const changedCols = allChangedColumns[i];
27
+ const entityId = formatEntityId(conflict.primaryKey);
28
+ const hasOverrides = Object.keys(resolution.columnOverrides).length > 0;
29
+ return /* @__PURE__ */ jsxs(Box, {
30
+ flexDirection: "column",
31
+ marginY: 0,
32
+ children: [/* @__PURE__ */ jsxs(Box, { children: [
33
+ /* @__PURE__ */ jsx(Text, {
34
+ color: "cyan",
35
+ children: conflict.table
36
+ }),
37
+ /* @__PURE__ */ jsxs(Text, {
38
+ bold: true,
39
+ children: [
40
+ " \"",
41
+ entityId,
42
+ "\""
43
+ ]
44
+ }),
45
+ /* @__PURE__ */ jsx(Text, { children: " → default: " }),
46
+ /* @__PURE__ */ jsx(Text, {
47
+ color: resolution.rowDefaultPick === "ours" ? "blue" : "magenta",
48
+ children: resolution.rowDefaultPick === "ours" ? "local" : "remote"
49
+ })
50
+ ] }), hasOverrides && /* @__PURE__ */ jsx(Box, {
51
+ flexDirection: "column",
52
+ marginLeft: 2,
53
+ children: changedCols.map((col) => {
54
+ const pick = resolution.columnOverrides[col] ?? resolution.rowDefaultPick;
55
+ if (!(col in resolution.columnOverrides)) return null;
56
+ return /* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsxs(Text, {
57
+ dimColor: true,
58
+ children: [
59
+ " ↳ ",
60
+ col,
61
+ ": "
62
+ ]
63
+ }), /* @__PURE__ */ jsx(Text, {
64
+ color: pick === "ours" ? "blue" : "magenta",
65
+ children: pick === "ours" ? "local" : "remote"
66
+ })] }, col);
67
+ })
68
+ })]
69
+ }, `${conflict.table}-${entityId}`);
70
+ }),
71
+ /* @__PURE__ */ jsx(Box, {
72
+ marginTop: 1,
73
+ children: /* @__PURE__ */ jsx(Text, {
74
+ dimColor: true,
75
+ children: "─".repeat(50)
76
+ })
77
+ }),
78
+ /* @__PURE__ */ jsxs(Box, { children: [
79
+ /* @__PURE__ */ jsx(Text, { children: "Press " }),
80
+ /* @__PURE__ */ jsx(Text, {
81
+ bold: true,
82
+ color: "yellow",
83
+ children: "Enter"
84
+ }),
85
+ /* @__PURE__ */ jsx(Text, { children: " to apply, " }),
86
+ /* @__PURE__ */ jsx(Text, {
87
+ bold: true,
88
+ color: "yellow",
89
+ children: "b"
90
+ }),
91
+ /* @__PURE__ */ jsx(Text, { children: " to go back, " }),
92
+ /* @__PURE__ */ jsx(Text, {
93
+ bold: true,
94
+ color: "yellow",
95
+ children: "Esc/q"
96
+ }),
97
+ /* @__PURE__ */ jsx(Text, { children: " to cancel" })
98
+ ] })
99
+ ]
100
+ })
101
+ });
102
+ }
103
+
104
+ //#endregion
105
+ export { ResolutionSummary };
106
+ //# sourceMappingURL=resolution-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution-summary.js","names":[],"sources":["../../../../src/commands/pull-v4/merge-ui/resolution-summary.tsx"],"sourcesContent":["import type { ConflictItem } from '@inkeep/agents-core';\nimport { Box, Text } from 'ink';\nimport type { ConflictResolutionState, Side } from './types';\nimport { formatEntityId } from './utils';\n\ninterface ResolutionSummaryProps {\n conflicts: ConflictItem[];\n resolutions: ConflictResolutionState[];\n allChangedColumns: string[][];\n}\n\nexport function ResolutionSummary({\n conflicts,\n resolutions,\n allChangedColumns,\n}: ResolutionSummaryProps) {\n return (\n <Box flexDirection=\"column\">\n <Box borderStyle=\"round\" borderColor=\"cyan\" paddingX={1} flexDirection=\"column\">\n <Text bold color=\"cyan\">\n Resolution Summary\n </Text>\n <Text dimColor>{'─'.repeat(50)}</Text>\n\n {conflicts.map((conflict, i) => {\n const resolution = resolutions[i];\n const changedCols = allChangedColumns[i];\n const entityId = formatEntityId(conflict.primaryKey);\n const hasOverrides = Object.keys(resolution.columnOverrides).length > 0;\n\n return (\n <Box key={`${conflict.table}-${entityId}`} flexDirection=\"column\" marginY={0}>\n <Box>\n <Text color=\"cyan\">{conflict.table}</Text>\n <Text bold> &quot;{entityId}&quot;</Text>\n <Text> → default: </Text>\n <Text color={resolution.rowDefaultPick === 'ours' ? 'blue' : 'magenta'}>\n {resolution.rowDefaultPick === 'ours' ? 'local' : 'remote'}\n </Text>\n </Box>\n {hasOverrides && (\n <Box flexDirection=\"column\" marginLeft={2}>\n {changedCols.map((col) => {\n const pick: Side = resolution.columnOverrides[col] ?? resolution.rowDefaultPick;\n const isOverride = col in resolution.columnOverrides;\n if (!isOverride) return null;\n return (\n <Box key={col}>\n <Text dimColor> ↳ {col}: </Text>\n <Text color={pick === 'ours' ? 'blue' : 'magenta'}>\n {pick === 'ours' ? 'local' : 'remote'}\n </Text>\n </Box>\n );\n })}\n </Box>\n )}\n </Box>\n );\n })}\n\n <Box marginTop={1}>\n <Text dimColor>{'─'.repeat(50)}</Text>\n </Box>\n <Box>\n <Text>Press </Text>\n <Text bold color=\"yellow\">\n Enter\n </Text>\n <Text> to apply, </Text>\n <Text bold color=\"yellow\">\n b\n </Text>\n <Text> to go back, </Text>\n <Text bold color=\"yellow\">\n Esc/q\n </Text>\n <Text> to cancel</Text>\n </Box>\n </Box>\n </Box>\n );\n}\n"],"mappings":";;;;;AAWA,SAAgB,kBAAkB,EAChC,WACA,aACA,qBACyB;AACzB,QACE,oBAAC;EAAI,eAAc;YACjB,qBAAC;GAAI,aAAY;GAAQ,aAAY;GAAO,UAAU;GAAG,eAAc;;IACrE,oBAAC;KAAK;KAAK,OAAM;eAAO;MAEjB;IACP,oBAAC;KAAK;eAAU,IAAI,OAAO,GAAG;MAAQ;IAErC,UAAU,KAAK,UAAU,MAAM;KAC9B,MAAM,aAAa,YAAY;KAC/B,MAAM,cAAc,kBAAkB;KACtC,MAAM,WAAW,eAAe,SAAS,WAAW;KACpD,MAAM,eAAe,OAAO,KAAK,WAAW,gBAAgB,CAAC,SAAS;AAEtE,YACE,qBAAC;MAA0C,eAAc;MAAS,SAAS;iBACzE,qBAAC;OACC,oBAAC;QAAK,OAAM;kBAAQ,SAAS;SAAa;OAC1C,qBAAC;QAAK;;SAAK;SAAQ;SAAS;;SAAa;OACzC,oBAAC,kBAAK,iBAAmB;OACzB,oBAAC;QAAK,OAAO,WAAW,mBAAmB,SAAS,SAAS;kBAC1D,WAAW,mBAAmB,SAAS,UAAU;SAC7C;UACH,EACL,gBACC,oBAAC;OAAI,eAAc;OAAS,YAAY;iBACrC,YAAY,KAAK,QAAQ;QACxB,MAAM,OAAa,WAAW,gBAAgB,QAAQ,WAAW;AAEjE,YAAI,EADe,OAAO,WAAW,iBACpB,QAAO;AACxB,eACE,qBAAC,kBACC,qBAAC;SAAK;;UAAS;UAAI;UAAI;;UAAS,EAChC,oBAAC;SAAK,OAAO,SAAS,SAAS,SAAS;mBACrC,SAAS,SAAS,UAAU;UACxB,KAJC,IAKJ;SAER;QACE;QAxBA,GAAG,SAAS,MAAM,GAAG,WA0BzB;MAER;IAEF,oBAAC;KAAI,WAAW;eACd,oBAAC;MAAK;gBAAU,IAAI,OAAO,GAAG;OAAQ;MAClC;IACN,qBAAC;KACC,oBAAC,kBAAK,WAAa;KACnB,oBAAC;MAAK;MAAK,OAAM;gBAAS;OAEnB;KACP,oBAAC,kBAAK,gBAAkB;KACxB,oBAAC;MAAK;MAAK,OAAM;gBAAS;OAEnB;KACP,oBAAC,kBAAK,kBAAoB;KAC1B,oBAAC;MAAK;MAAK,OAAM;gBAAS;OAEnB;KACP,oBAAC,kBAAK,eAAiB;QACnB;;IACF;GACF"}
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,43 @@
1
+ //#region src/commands/pull-v4/merge-ui/utils.ts
2
+ const SKIP_COLUMNS = new Set(["created_at", "updated_at"]);
3
+ function getChangedColumns(conflict) {
4
+ const ours = conflict.ours ?? {};
5
+ const theirs = conflict.theirs ?? {};
6
+ return Object.keys({
7
+ ...ours,
8
+ ...theirs
9
+ }).filter((key) => {
10
+ if (key in conflict.primaryKey) return false;
11
+ if (SKIP_COLUMNS.has(key)) return false;
12
+ return JSON.stringify(ours[key]) !== JSON.stringify(theirs[key]);
13
+ });
14
+ }
15
+ function formatValue(value) {
16
+ if (value === null || value === void 0) return "null";
17
+ if (typeof value === "string") return value;
18
+ if (typeof value === "object") return JSON.stringify(value, null, 2);
19
+ return String(value);
20
+ }
21
+ function formatEntityId(primaryKey) {
22
+ return Object.values(primaryKey).join("/");
23
+ }
24
+ function formatDiffType(diffType) {
25
+ switch (diffType) {
26
+ case "added": return "added";
27
+ case "removed": return "deleted";
28
+ case "modified": return "modified";
29
+ default: return diffType;
30
+ }
31
+ }
32
+ function diffTypeColor(diffType) {
33
+ switch (diffType) {
34
+ case "added": return "green";
35
+ case "removed": return "red";
36
+ case "modified": return "yellow";
37
+ default: return "white";
38
+ }
39
+ }
40
+
41
+ //#endregion
42
+ export { diffTypeColor, formatDiffType, formatEntityId, formatValue, getChangedColumns };
43
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../../src/commands/pull-v4/merge-ui/utils.ts"],"sourcesContent":["import type { ConflictItem } from '@inkeep/agents-core';\n\nconst SKIP_COLUMNS = new Set(['created_at', 'updated_at']);\n\nexport function getChangedColumns(conflict: ConflictItem): string[] {\n const ours = conflict.ours ?? {};\n const theirs = conflict.theirs ?? {};\n const allKeys = Object.keys({ ...ours, ...theirs });\n return allKeys.filter((key) => {\n if (key in conflict.primaryKey) return false;\n if (SKIP_COLUMNS.has(key)) return false;\n return JSON.stringify(ours[key]) !== JSON.stringify(theirs[key]);\n });\n}\n\nexport function formatValue(value: unknown): string {\n if (value === null || value === undefined) return 'null';\n if (typeof value === 'string') return value;\n if (typeof value === 'object') return JSON.stringify(value, null, 2);\n return String(value);\n}\n\nexport function formatEntityId(primaryKey: Record<string, string>): string {\n const values = Object.values(primaryKey);\n return values.join('/');\n}\n\nexport function formatDiffType(diffType: string): string {\n switch (diffType) {\n case 'added':\n return 'added';\n case 'removed':\n return 'deleted';\n case 'modified':\n return 'modified';\n default:\n return diffType;\n }\n}\n\nexport function diffTypeColor(diffType: string): string {\n switch (diffType) {\n case 'added':\n return 'green';\n case 'removed':\n return 'red';\n case 'modified':\n return 'yellow';\n default:\n return 'white';\n }\n}\n"],"mappings":";AAEA,MAAM,eAAe,IAAI,IAAI,CAAC,cAAc,aAAa,CAAC;AAE1D,SAAgB,kBAAkB,UAAkC;CAClE,MAAM,OAAO,SAAS,QAAQ,EAAE;CAChC,MAAM,SAAS,SAAS,UAAU,EAAE;AAEpC,QADgB,OAAO,KAAK;EAAE,GAAG;EAAM,GAAG;EAAQ,CAAC,CACpC,QAAQ,QAAQ;AAC7B,MAAI,OAAO,SAAS,WAAY,QAAO;AACvC,MAAI,aAAa,IAAI,IAAI,CAAE,QAAO;AAClC,SAAO,KAAK,UAAU,KAAK,KAAK,KAAK,KAAK,UAAU,OAAO,KAAK;GAChE;;AAGJ,SAAgB,YAAY,OAAwB;AAClD,KAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,KAAI,OAAO,UAAU,SAAU,QAAO;AACtC,KAAI,OAAO,UAAU,SAAU,QAAO,KAAK,UAAU,OAAO,MAAM,EAAE;AACpE,QAAO,OAAO,MAAM;;AAGtB,SAAgB,eAAe,YAA4C;AAEzE,QADe,OAAO,OAAO,WAAW,CAC1B,KAAK,IAAI;;AAGzB,SAAgB,eAAe,UAA0B;AACvD,SAAQ,UAAR;EACE,KAAK,QACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,WACH,QAAO;EACT,QACE,QAAO;;;AAIb,SAAgB,cAAc,UAA0B;AACtD,SAAQ,UAAR;EACE,KAAK,QACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,WACH,QAAO;EACT,QACE,QAAO"}
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import { statusCommand } from "./commands/status.js";
16
16
  import { updateCommand } from "./commands/update.js";
17
17
  import { whoamiCommand } from "./commands/whoami.js";
18
18
  import { getLogger } from "@inkeep/agents-core";
19
- import { Command } from "commander";
19
+ import { Command, Option } from "commander";
20
20
 
21
21
  //#region src/index.ts
22
22
  getLogger("config").updateOptions({ level: "silent" });
@@ -45,7 +45,7 @@ configCommand.command("list").description("List all configuration values").optio
45
45
  await configListCommand({ config: options.config || options.configFilePath });
46
46
  });
47
47
  program.command("push").description("Push a project configuration to the backend").option("--project <project-id>", "Project ID or path to project directory").option("--config <path>", "Path to configuration file").option("--profile <name>", "Profile to use for remote URLs and authentication").option("--tenant-id <id>", "Override tenant ID").option("--agents-api-url <url>", "Override agents API URL").option("--env <environment>", "Environment to use for credential resolution (e.g., development, production)").option("--json", "Generate project data JSON file instead of pushing to backend").option("--all", "Push all projects found in current directory tree").option("--tag <tag>", "Use tagged config file (e.g., --tag prod loads prod.__inkeep.config.ts__)").option("--quiet", "Suppress profile/config logging").action(pushCommand);
48
- program.command("pull").description("Pull project configuration with clean, efficient code generation").option("--project <project-id>", "Project ID to pull (or path to project directory). If in project directory, validates against local project ID.").option("--config <path>", "Path to configuration file").option("--profile <name>", "Profile to use for remote URLs and authentication").option("--env <environment>", "Environment file to generate (development, staging, production). Defaults to development").option("--json", "Output project data as JSON instead of generating files").option("--debug", "Enable debug logging").option("--verbose", "Enable verbose logging").option("--force", "Force regeneration even if no changes detected").option("--all", "Pull all projects for current tenant").option("--tag <tag>", "Use tagged config file (e.g., --tag prod loads prod.__inkeep.config.ts__)").option("--quiet", "Suppress profile/config logging").action(async (options) => {
48
+ program.command("pull").description("Pull project configuration with clean, efficient code generation").option("--project <project-id>", "Project ID to pull (or path to project directory). If in project directory, validates against local project ID.").option("--config <path>", "Path to configuration file").option("--profile <name>", "Profile to use for remote URLs and authentication").option("--env <environment>", "Environment file to generate (development, staging, production). Defaults to development").option("--json", "Output project data as JSON instead of generating files").option("--debug", "Enable debug logging").option("--verbose", "Enable verbose logging").option("--force", "Force regeneration even if no changes detected").option("--all", "Pull all projects for current tenant").option("--tag <tag>", "Use tagged config file (e.g., --tag prod loads prod.__inkeep.config.ts__)").option("--quiet", "Suppress profile/config logging").addOption(new Option("--conflict-strategy <strategy>", "Auto-resolve merge conflicts: ours (keep local) or theirs (accept remote). Skips interactive prompts.").choices(["ours", "theirs"])).action(async (options) => {
49
49
  await pullV4Command(options);
50
50
  });
51
51
  program.command("list-agent").description("List all available agents for a specific project").requiredOption("--project <project-id>", "Project ID to list agent for").option("--tenant-id <tenant-id>", "Tenant ID").option("--agents-api-url <url>", "Agents API URL").option("--config <path>", "Path to configuration file").option("--config-file-path <path>", "Path to configuration file (deprecated, use --config)").action(async (options) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport './env'; // Load environment files first (needed by instrumentation)\nimport './instrumentation'; // Initialize Langfuse tracing second\n\n// Silence config loading logs for cleaner CLI output\nimport { getLogger } from '@inkeep/agents-core';\n\nconst configLogger = getLogger('config');\nconfigLogger.updateOptions({ level: 'silent' });\n\nimport { Command } from 'commander';\nimport { addCommand } from './commands/add';\nimport { configGetCommand, configListCommand, configSetCommand } from './commands/config';\nimport { devCommand } from './commands/dev';\nimport { initCommand } from './commands/init';\nimport { listAgentsCommand } from './commands/list-agents';\nimport { loginCommand } from './commands/login';\nimport { logoutCommand } from './commands/logout';\nimport {\n profileAddCommand,\n profileCurrentCommand,\n profileListCommand,\n profileRemoveCommand,\n profileUseCommand,\n} from './commands/profile';\nimport { pullV4Command } from './commands/pull-v4/introspect';\nimport { pushCommand } from './commands/push';\nimport { statusCommand } from './commands/status';\nimport { updateCommand } from './commands/update';\nimport { whoamiCommand } from './commands/whoami';\nimport { PACKAGE_VERSION } from './utils/version-check';\n\nconst program = new Command();\n\nprogram.name('inkeep').description('CLI tool for Inkeep Agent Framework').version(PACKAGE_VERSION);\n\nprogram\n .command('add [template]')\n .description('Add a new template to the project')\n .option('--project <template>', 'Project template to add')\n .option('--mcp <template>', 'MCP template to add')\n .option(\n '--ui [component-id]',\n 'Add UI component(s) to apps/agents-ui/src/ui (omit id to add all)'\n )\n .option('--list', 'List available UI components (use with --ui)')\n .option('--target-path <path>', 'Target path to add the template to')\n .option('--local-prefix <path_prefix>', 'Use local templates from the given path prefix')\n .option('--config <path>', 'Path to configuration file')\n .option('--profile <name>', 'Profile to use for authentication')\n .option('--quiet', 'Suppress profile/config logging')\n .action(async (template, options) => {\n await addCommand({ template, ...options });\n });\n\nprogram\n .command('init [path]')\n .description('Initialize a new Inkeep project (runs cloud onboarding wizard by default)')\n .option('--local', 'Use local/self-hosted mode instead of cloud onboarding')\n .option('--no-interactive', 'Skip interactive prompts')\n .option('--config <path>', 'Path to use as template for new configuration')\n .action(async (path, options) => {\n await initCommand({ path, ...options });\n });\n\nconst configCommand = program.command('config').description('Manage Inkeep configuration');\n\nconfigCommand\n .command('get [key]')\n .description('Get configuration value(s)')\n .option('--config <path>', 'Path to configuration file')\n .option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')\n .action(async (key, options) => {\n const config = options.config || options.configFilePath;\n await configGetCommand(key, { config });\n });\n\nconfigCommand\n .command('set <key> <value>')\n .description('Set a configuration value')\n .option('--config <path>', 'Path to configuration file')\n .option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')\n .action(async (key, value, options) => {\n const config = options.config || options.configFilePath;\n await configSetCommand(key, value, { config });\n });\n\nconfigCommand\n .command('list')\n .description('List all configuration values')\n .option('--config <path>', 'Path to configuration file')\n .option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')\n .action(async (options) => {\n const config = options.config || options.configFilePath;\n await configListCommand({ config });\n });\n\nprogram\n .command('push')\n .description('Push a project configuration to the backend')\n .option('--project <project-id>', 'Project ID or path to project directory')\n .option('--config <path>', 'Path to configuration file')\n .option('--profile <name>', 'Profile to use for remote URLs and authentication')\n .option('--tenant-id <id>', 'Override tenant ID')\n .option('--agents-api-url <url>', 'Override agents API URL')\n .option(\n '--env <environment>',\n 'Environment to use for credential resolution (e.g., development, production)'\n )\n .option('--json', 'Generate project data JSON file instead of pushing to backend')\n .option('--all', 'Push all projects found in current directory tree')\n .option(\n '--tag <tag>',\n 'Use tagged config file (e.g., --tag prod loads prod.__inkeep.config.ts__)'\n )\n .option('--quiet', 'Suppress profile/config logging')\n .action(pushCommand);\n\nprogram\n .command('pull')\n .description('Pull project configuration with clean, efficient code generation')\n .option(\n '--project <project-id>',\n 'Project ID to pull (or path to project directory). If in project directory, validates against local project ID.'\n )\n .option('--config <path>', 'Path to configuration file')\n .option('--profile <name>', 'Profile to use for remote URLs and authentication')\n .option(\n '--env <environment>',\n 'Environment file to generate (development, staging, production). Defaults to development'\n )\n .option('--json', 'Output project data as JSON instead of generating files')\n .option('--debug', 'Enable debug logging')\n .option('--verbose', 'Enable verbose logging')\n .option('--force', 'Force regeneration even if no changes detected')\n .option('--all', 'Pull all projects for current tenant')\n .option(\n '--tag <tag>',\n 'Use tagged config file (e.g., --tag prod loads prod.__inkeep.config.ts__)'\n )\n .option('--quiet', 'Suppress profile/config logging')\n .action(async (options) => {\n await pullV4Command(options);\n });\n\nprogram\n .command('list-agent')\n .description('List all available agents for a specific project')\n .requiredOption('--project <project-id>', 'Project ID to list agent for')\n .option('--tenant-id <tenant-id>', 'Tenant ID')\n .option('--agents-api-url <url>', 'Agents API URL')\n .option('--config <path>', 'Path to configuration file')\n .option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')\n .action(async (options) => {\n const config = options.config || options.configFilePath;\n await listAgentsCommand({ ...options, config });\n });\n\nprogram\n .command('dev')\n .description('Start the Inkeep dashboard server')\n .option('--port <port>', 'Port to run the server on', '3000')\n .option('--host <host>', 'Host to bind the server to', 'localhost')\n .option('--build', 'Build the Dashboard UI for production', false)\n .option('--export', 'Export the Next.js project source files', false)\n .option('--output-dir <dir>', 'Output directory for build files', './inkeep-dev')\n .option('--path', 'Output the path to the Dashboard UI', false)\n .option('--open-browser', 'Open the browser', false)\n .action(async (options) => {\n await devCommand({\n port: parseInt(options.port, 10),\n host: options.host,\n build: options.build,\n outputDir: options.outputDir,\n path: options.path,\n export: options.export,\n openBrowser: options.openBrowser,\n });\n });\n\nprogram\n .command('update')\n .description('Update @inkeep/agents-cli to the latest version')\n .option('--check', 'Check for updates without installing')\n .option('--force', 'Force update even if already on latest version')\n .action(updateCommand);\n\n// Authentication commands\nprogram\n .command('login')\n .description('Authenticate with Inkeep Cloud')\n .option('--profile <name>', 'Profile to authenticate (defaults to active profile)')\n .action(loginCommand);\n\nprogram\n .command('logout')\n .description('Log out of Inkeep Cloud')\n .option('--profile <name>', 'Profile to log out (defaults to active profile)')\n .action(logoutCommand);\n\nprogram\n .command('status')\n .description('Show current profile, authentication state, and remote URLs')\n .option('--profile <name>', 'Profile to show status for (defaults to active profile)')\n .action(statusCommand);\n\nprogram\n .command('whoami')\n .description('Display current authentication status (alias for status)')\n .action(whoamiCommand);\n\n// Profile management commands\nconst profileCommand = program\n .command('profile')\n .description('Manage CLI profiles for connecting to different remotes');\n\nprofileCommand.command('list').description('List all profiles').action(profileListCommand);\n\nprofileCommand.command('add [name]').description('Add a new profile').action(profileAddCommand);\n\nprofileCommand\n .command('use <name>')\n .description('Set the active profile')\n .action(profileUseCommand);\n\nprofileCommand\n .command('current')\n .description('Display the active profile details')\n .action(profileCurrentCommand);\n\nprofileCommand\n .command('remove <name>')\n .description('Remove a profile')\n .action(profileRemoveCommand);\n\nprogram.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport './env'; // Load environment files first (needed by instrumentation)\nimport './instrumentation'; // Initialize Langfuse tracing second\n\n// Silence config loading logs for cleaner CLI output\nimport { getLogger } from '@inkeep/agents-core';\n\nconst configLogger = getLogger('config');\nconfigLogger.updateOptions({ level: 'silent' });\n\nimport { Command, Option } from 'commander';\nimport { addCommand } from './commands/add';\nimport { configGetCommand, configListCommand, configSetCommand } from './commands/config';\nimport { devCommand } from './commands/dev';\nimport { initCommand } from './commands/init';\nimport { listAgentsCommand } from './commands/list-agents';\nimport { loginCommand } from './commands/login';\nimport { logoutCommand } from './commands/logout';\nimport {\n profileAddCommand,\n profileCurrentCommand,\n profileListCommand,\n profileRemoveCommand,\n profileUseCommand,\n} from './commands/profile';\nimport { pullV4Command } from './commands/pull-v4/introspect';\nimport { pushCommand } from './commands/push';\nimport { statusCommand } from './commands/status';\nimport { updateCommand } from './commands/update';\nimport { whoamiCommand } from './commands/whoami';\nimport { PACKAGE_VERSION } from './utils/version-check';\n\nconst program = new Command();\n\nprogram.name('inkeep').description('CLI tool for Inkeep Agent Framework').version(PACKAGE_VERSION);\n\nprogram\n .command('add [template]')\n .description('Add a new template to the project')\n .option('--project <template>', 'Project template to add')\n .option('--mcp <template>', 'MCP template to add')\n .option(\n '--ui [component-id]',\n 'Add UI component(s) to apps/agents-ui/src/ui (omit id to add all)'\n )\n .option('--list', 'List available UI components (use with --ui)')\n .option('--target-path <path>', 'Target path to add the template to')\n .option('--local-prefix <path_prefix>', 'Use local templates from the given path prefix')\n .option('--config <path>', 'Path to configuration file')\n .option('--profile <name>', 'Profile to use for authentication')\n .option('--quiet', 'Suppress profile/config logging')\n .action(async (template, options) => {\n await addCommand({ template, ...options });\n });\n\nprogram\n .command('init [path]')\n .description('Initialize a new Inkeep project (runs cloud onboarding wizard by default)')\n .option('--local', 'Use local/self-hosted mode instead of cloud onboarding')\n .option('--no-interactive', 'Skip interactive prompts')\n .option('--config <path>', 'Path to use as template for new configuration')\n .action(async (path, options) => {\n await initCommand({ path, ...options });\n });\n\nconst configCommand = program.command('config').description('Manage Inkeep configuration');\n\nconfigCommand\n .command('get [key]')\n .description('Get configuration value(s)')\n .option('--config <path>', 'Path to configuration file')\n .option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')\n .action(async (key, options) => {\n const config = options.config || options.configFilePath;\n await configGetCommand(key, { config });\n });\n\nconfigCommand\n .command('set <key> <value>')\n .description('Set a configuration value')\n .option('--config <path>', 'Path to configuration file')\n .option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')\n .action(async (key, value, options) => {\n const config = options.config || options.configFilePath;\n await configSetCommand(key, value, { config });\n });\n\nconfigCommand\n .command('list')\n .description('List all configuration values')\n .option('--config <path>', 'Path to configuration file')\n .option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')\n .action(async (options) => {\n const config = options.config || options.configFilePath;\n await configListCommand({ config });\n });\n\nprogram\n .command('push')\n .description('Push a project configuration to the backend')\n .option('--project <project-id>', 'Project ID or path to project directory')\n .option('--config <path>', 'Path to configuration file')\n .option('--profile <name>', 'Profile to use for remote URLs and authentication')\n .option('--tenant-id <id>', 'Override tenant ID')\n .option('--agents-api-url <url>', 'Override agents API URL')\n .option(\n '--env <environment>',\n 'Environment to use for credential resolution (e.g., development, production)'\n )\n .option('--json', 'Generate project data JSON file instead of pushing to backend')\n .option('--all', 'Push all projects found in current directory tree')\n .option(\n '--tag <tag>',\n 'Use tagged config file (e.g., --tag prod loads prod.__inkeep.config.ts__)'\n )\n .option('--quiet', 'Suppress profile/config logging')\n .action(pushCommand);\n\nprogram\n .command('pull')\n .description('Pull project configuration with clean, efficient code generation')\n .option(\n '--project <project-id>',\n 'Project ID to pull (or path to project directory). If in project directory, validates against local project ID.'\n )\n .option('--config <path>', 'Path to configuration file')\n .option('--profile <name>', 'Profile to use for remote URLs and authentication')\n .option(\n '--env <environment>',\n 'Environment file to generate (development, staging, production). Defaults to development'\n )\n .option('--json', 'Output project data as JSON instead of generating files')\n .option('--debug', 'Enable debug logging')\n .option('--verbose', 'Enable verbose logging')\n .option('--force', 'Force regeneration even if no changes detected')\n .option('--all', 'Pull all projects for current tenant')\n .option(\n '--tag <tag>',\n 'Use tagged config file (e.g., --tag prod loads prod.__inkeep.config.ts__)'\n )\n .option('--quiet', 'Suppress profile/config logging')\n .addOption(\n new Option(\n '--conflict-strategy <strategy>',\n 'Auto-resolve merge conflicts: ours (keep local) or theirs (accept remote). Skips interactive prompts.'\n ).choices(['ours', 'theirs'])\n )\n .action(async (options) => {\n await pullV4Command(options);\n });\n\nprogram\n .command('list-agent')\n .description('List all available agents for a specific project')\n .requiredOption('--project <project-id>', 'Project ID to list agent for')\n .option('--tenant-id <tenant-id>', 'Tenant ID')\n .option('--agents-api-url <url>', 'Agents API URL')\n .option('--config <path>', 'Path to configuration file')\n .option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')\n .action(async (options) => {\n const config = options.config || options.configFilePath;\n await listAgentsCommand({ ...options, config });\n });\n\nprogram\n .command('dev')\n .description('Start the Inkeep dashboard server')\n .option('--port <port>', 'Port to run the server on', '3000')\n .option('--host <host>', 'Host to bind the server to', 'localhost')\n .option('--build', 'Build the Dashboard UI for production', false)\n .option('--export', 'Export the Next.js project source files', false)\n .option('--output-dir <dir>', 'Output directory for build files', './inkeep-dev')\n .option('--path', 'Output the path to the Dashboard UI', false)\n .option('--open-browser', 'Open the browser', false)\n .action(async (options) => {\n await devCommand({\n port: parseInt(options.port, 10),\n host: options.host,\n build: options.build,\n outputDir: options.outputDir,\n path: options.path,\n export: options.export,\n openBrowser: options.openBrowser,\n });\n });\n\nprogram\n .command('update')\n .description('Update @inkeep/agents-cli to the latest version')\n .option('--check', 'Check for updates without installing')\n .option('--force', 'Force update even if already on latest version')\n .action(updateCommand);\n\n// Authentication commands\nprogram\n .command('login')\n .description('Authenticate with Inkeep Cloud')\n .option('--profile <name>', 'Profile to authenticate (defaults to active profile)')\n .action(loginCommand);\n\nprogram\n .command('logout')\n .description('Log out of Inkeep Cloud')\n .option('--profile <name>', 'Profile to log out (defaults to active profile)')\n .action(logoutCommand);\n\nprogram\n .command('status')\n .description('Show current profile, authentication state, and remote URLs')\n .option('--profile <name>', 'Profile to show status for (defaults to active profile)')\n .action(statusCommand);\n\nprogram\n .command('whoami')\n .description('Display current authentication status (alias for status)')\n .action(whoamiCommand);\n\n// Profile management commands\nconst profileCommand = program\n .command('profile')\n .description('Manage CLI profiles for connecting to different remotes');\n\nprofileCommand.command('list').description('List all profiles').action(profileListCommand);\n\nprofileCommand.command('add [name]').description('Add a new profile').action(profileAddCommand);\n\nprofileCommand\n .command('use <name>')\n .description('Set the active profile')\n .action(profileUseCommand);\n\nprofileCommand\n .command('current')\n .description('Display the active profile details')\n .action(profileCurrentCommand);\n\nprofileCommand\n .command('remove <name>')\n .description('Remove a profile')\n .action(profileRemoveCommand);\n\nprogram.parse();\n"],"mappings":"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"}