skill-flow 1.0.3 → 1.0.5

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 (84) hide show
  1. package/README.md +40 -3
  2. package/README.zh.md +40 -3
  3. package/dist/adapters/channel-adapters.js +11 -3
  4. package/dist/adapters/channel-adapters.js.map +1 -1
  5. package/dist/cli.js +69 -37
  6. package/dist/cli.js.map +1 -1
  7. package/dist/domain/types.d.ts +54 -1
  8. package/dist/services/config-coordinator.d.ts +38 -0
  9. package/dist/services/config-coordinator.js +81 -0
  10. package/dist/services/config-coordinator.js.map +1 -0
  11. package/dist/services/doctor-service.d.ts +2 -0
  12. package/dist/services/doctor-service.js +62 -0
  13. package/dist/services/doctor-service.js.map +1 -1
  14. package/dist/services/inventory-service.d.ts +3 -1
  15. package/dist/services/inventory-service.js +12 -5
  16. package/dist/services/inventory-service.js.map +1 -1
  17. package/dist/services/skill-flow.d.ts +50 -26
  18. package/dist/services/skill-flow.js +502 -89
  19. package/dist/services/skill-flow.js.map +1 -1
  20. package/dist/services/source-service.d.ts +20 -10
  21. package/dist/services/source-service.js +359 -75
  22. package/dist/services/source-service.js.map +1 -1
  23. package/dist/services/workflow-service.d.ts +2 -2
  24. package/dist/services/workflow-service.js +17 -4
  25. package/dist/services/workflow-service.js.map +1 -1
  26. package/dist/services/workspace-bootstrap-service.d.ts +25 -0
  27. package/dist/services/workspace-bootstrap-service.js +140 -0
  28. package/dist/services/workspace-bootstrap-service.js.map +1 -0
  29. package/dist/state/store.d.ts +16 -0
  30. package/dist/state/store.js +93 -18
  31. package/dist/state/store.js.map +1 -1
  32. package/dist/tests/clawhub.test.d.ts +1 -0
  33. package/dist/tests/clawhub.test.js +63 -0
  34. package/dist/tests/clawhub.test.js.map +1 -0
  35. package/dist/tests/cli-utils.test.d.ts +1 -0
  36. package/dist/tests/cli-utils.test.js +15 -0
  37. package/dist/tests/cli-utils.test.js.map +1 -0
  38. package/dist/tests/config-coordinator.test.d.ts +1 -0
  39. package/dist/tests/config-coordinator.test.js +172 -0
  40. package/dist/tests/config-coordinator.test.js.map +1 -0
  41. package/dist/tests/config-integration.test.d.ts +1 -0
  42. package/dist/tests/config-integration.test.js +238 -0
  43. package/dist/tests/config-integration.test.js.map +1 -0
  44. package/dist/tests/config-ui-utils.test.d.ts +1 -0
  45. package/dist/tests/config-ui-utils.test.js +389 -0
  46. package/dist/tests/config-ui-utils.test.js.map +1 -0
  47. package/dist/tests/find-and-naming-utils.test.d.ts +1 -0
  48. package/dist/tests/find-and-naming-utils.test.js +127 -0
  49. package/dist/tests/find-and-naming-utils.test.js.map +1 -0
  50. package/dist/tests/skill-flow.test.js +334 -881
  51. package/dist/tests/skill-flow.test.js.map +1 -1
  52. package/dist/tests/source-lifecycle.test.d.ts +1 -0
  53. package/dist/tests/source-lifecycle.test.js +605 -0
  54. package/dist/tests/source-lifecycle.test.js.map +1 -0
  55. package/dist/tests/target-definitions.test.d.ts +1 -0
  56. package/dist/tests/target-definitions.test.js +51 -0
  57. package/dist/tests/target-definitions.test.js.map +1 -0
  58. package/dist/tests/test-helpers.d.ts +18 -0
  59. package/dist/tests/test-helpers.js +123 -0
  60. package/dist/tests/test-helpers.js.map +1 -0
  61. package/dist/tui/config-app.d.ts +147 -24
  62. package/dist/tui/config-app.js +1081 -335
  63. package/dist/tui/config-app.js.map +1 -1
  64. package/dist/tui/find-app.d.ts +1 -1
  65. package/dist/tui/find-app.js +36 -4
  66. package/dist/tui/find-app.js.map +1 -1
  67. package/dist/utils/clawhub.d.ts +3 -0
  68. package/dist/utils/clawhub.js +32 -3
  69. package/dist/utils/clawhub.js.map +1 -1
  70. package/dist/utils/cli.d.ts +1 -0
  71. package/dist/utils/cli.js +15 -0
  72. package/dist/utils/cli.js.map +1 -0
  73. package/dist/utils/constants.d.ts +4 -0
  74. package/dist/utils/constants.js +31 -0
  75. package/dist/utils/constants.js.map +1 -1
  76. package/dist/utils/fs.d.ts +5 -0
  77. package/dist/utils/fs.js +52 -1
  78. package/dist/utils/fs.js.map +1 -1
  79. package/dist/utils/naming.d.ts +1 -0
  80. package/dist/utils/naming.js +7 -1
  81. package/dist/utils/naming.js.map +1 -1
  82. package/dist/utils/source-id.js +4 -0
  83. package/dist/utils/source-id.js.map +1 -1
  84. package/package.json +1 -1
@@ -0,0 +1,51 @@
1
+ import os from "node:os";
2
+ import path from "node:path";
3
+ import { describe, expect, test } from "vitest";
4
+ import { getExplicitTargetNames, getTargetDetectionCandidates, getTargetScanRoots, TARGET_COMPAT_READ_CANDIDATES, TARGET_DEFINITIONS, TARGET_PATH_CANDIDATES, } from "../utils/constants.js";
5
+ describe("target definitions", () => {
6
+ test("includes config-based OpenCode skills directory in default detection paths", () => {
7
+ expect(TARGET_PATH_CANDIDATES.opencode).toContain(path.join(os.homedir(), ".config", "opencode", "skills"));
8
+ expect(TARGET_PATH_CANDIDATES["github-copilot"]).toContain(path.join(os.homedir(), ".copilot", "skills"));
9
+ expect(TARGET_PATH_CANDIDATES["gemini-cli"]).toContain(path.join(os.homedir(), ".gemini", "skills"));
10
+ expect(TARGET_PATH_CANDIDATES.windsurf).toContain(path.join(os.homedir(), ".codeium", "windsurf", "skills"));
11
+ expect(TARGET_PATH_CANDIDATES["roo-code"]).toContain(path.join(os.homedir(), ".roo", "skills"));
12
+ expect(TARGET_PATH_CANDIDATES.cline).toContain(path.join(os.homedir(), ".cline", "skills"));
13
+ expect(TARGET_PATH_CANDIDATES.amp).toContain(path.join(os.homedir(), ".config", "agents", "skills"));
14
+ expect(TARGET_PATH_CANDIDATES.kiro).toContain(path.join(os.homedir(), ".kiro", "skills"));
15
+ });
16
+ test("classifies shared global roots as compatibility reads instead of write roots", () => {
17
+ expect(TARGET_DEFINITIONS.codex.writerKey).toBe("agents-skills");
18
+ expect(TARGET_PATH_CANDIDATES.codex).toContain(path.join(os.homedir(), ".agents", "skills"));
19
+ expect(TARGET_COMPAT_READ_CANDIDATES["gemini-cli"]).toContain(path.join(os.homedir(), ".agents", "skills"));
20
+ expect(TARGET_COMPAT_READ_CANDIDATES["github-copilot"]).toContain(path.join(os.homedir(), ".agents", "skills"));
21
+ expect(TARGET_COMPAT_READ_CANDIDATES.cursor).toContain(path.join(os.homedir(), ".claude", "skills"));
22
+ expect(TARGET_COMPAT_READ_CANDIDATES.pi).toContain(path.join(os.homedir(), ".claude", "skills"));
23
+ expect(TARGET_COMPAT_READ_CANDIDATES.amp).toContain(path.join(os.homedir(), ".claude", "skills"));
24
+ expect(TARGET_PATH_CANDIDATES["gemini-cli"]).not.toContain(path.join(os.homedir(), ".agents", "skills"));
25
+ expect(TARGET_PATH_CANDIDATES["github-copilot"]).not.toContain(path.join(os.homedir(), ".claude", "skills"));
26
+ });
27
+ test("explicit target mode only exposes overridden targets", () => {
28
+ const previousClaude = process.env.SKILL_FLOW_TARGET_CLAUDE_CODE;
29
+ const previousCodex = process.env.SKILL_FLOW_TARGET_CODEX;
30
+ process.env.SKILL_FLOW_TARGET_CLAUDE_CODE = "/tmp/claude-skills";
31
+ delete process.env.SKILL_FLOW_TARGET_CODEX;
32
+ expect(getExplicitTargetNames()).toEqual(["claude-code"]);
33
+ expect(getTargetDetectionCandidates("claude-code")).toEqual(["/tmp/claude-skills"]);
34
+ expect(getTargetDetectionCandidates("codex")).toEqual([]);
35
+ expect(getTargetScanRoots("claude-code")).toEqual(["/tmp/claude-skills"]);
36
+ expect(getTargetScanRoots("codex")).toEqual([]);
37
+ if (previousClaude === undefined) {
38
+ delete process.env.SKILL_FLOW_TARGET_CLAUDE_CODE;
39
+ }
40
+ else {
41
+ process.env.SKILL_FLOW_TARGET_CLAUDE_CODE = previousClaude;
42
+ }
43
+ if (previousCodex === undefined) {
44
+ delete process.env.SKILL_FLOW_TARGET_CODEX;
45
+ }
46
+ else {
47
+ process.env.SKILL_FLOW_TARGET_CODEX = previousCodex;
48
+ }
49
+ });
50
+ });
51
+ //# sourceMappingURL=target-definitions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target-definitions.test.js","sourceRoot":"","sources":["../../src/tests/target-definitions.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { SkillFlowApp } from "../services/skill-flow.js";
2
+ export type SandboxContext = {
3
+ sandboxRoot: string;
4
+ stateRoot: string;
5
+ targetsRoot: string;
6
+ };
7
+ export declare function useSkillFlowSandbox(): {
8
+ sandboxRoot: string;
9
+ stateRoot: string;
10
+ targetsRoot: string;
11
+ };
12
+ export declare function createRepo(root: string, files: Record<string, string>): Promise<string>;
13
+ export declare function createBareRemote(repoPath: string, root: string): Promise<string>;
14
+ export declare function seedBuiltinCatalog(app: SkillFlowApp): Promise<void>;
15
+ export declare function writeRepoFiles(root: string, files: Record<string, string>): Promise<void>;
16
+ export declare function skillDoc(name: string, description: string, heading?: string): string;
17
+ export declare function git(cwd: string, args: string[]): void;
18
+ export declare function pathExists(targetPath: string): Promise<boolean>;
@@ -0,0 +1,123 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { execFileSync } from "node:child_process";
5
+ import { afterEach, beforeEach, vi } from "vitest";
6
+ import * as builtinGitSources from "../utils/builtin-git-sources.js";
7
+ import { deriveSourceId } from "../utils/source-id.js";
8
+ export function useSkillFlowSandbox() {
9
+ const context = {
10
+ sandboxRoot: "",
11
+ stateRoot: "",
12
+ targetsRoot: "",
13
+ };
14
+ beforeEach(async () => {
15
+ context.sandboxRoot = await fs.mkdtemp(path.join(os.tmpdir(), "skill-flow-test-"));
16
+ context.stateRoot = path.join(context.sandboxRoot, "state");
17
+ context.targetsRoot = path.join(context.sandboxRoot, "targets");
18
+ await fs.mkdir(context.targetsRoot, { recursive: true });
19
+ process.env.SKILL_FLOW_STATE_ROOT = context.stateRoot;
20
+ process.env.SKILL_FLOW_TARGET_CLAUDE_CODE = path.join(context.targetsRoot, "claude");
21
+ process.env.SKILL_FLOW_TARGET_CODEX = path.join(context.targetsRoot, "codex");
22
+ process.env.SKILL_FLOW_TARGET_CURSOR = path.join(context.targetsRoot, "cursor");
23
+ process.env.SKILL_FLOW_TARGET_GITHUB_COPILOT = path.join(context.targetsRoot, "github-copilot");
24
+ process.env.SKILL_FLOW_TARGET_GEMINI_CLI = path.join(context.targetsRoot, "gemini-cli");
25
+ process.env.SKILL_FLOW_TARGET_OPENCODE = path.join(context.targetsRoot, "opencode");
26
+ process.env.SKILL_FLOW_TARGET_OPENCLAW = path.join(context.targetsRoot, "openclaw");
27
+ process.env.SKILL_FLOW_TARGET_PI = path.join(context.targetsRoot, "pi");
28
+ process.env.SKILL_FLOW_TARGET_WINDSURF = path.join(context.targetsRoot, "windsurf");
29
+ process.env.SKILL_FLOW_TARGET_ROO_CODE = path.join(context.targetsRoot, "roo-code");
30
+ process.env.SKILL_FLOW_TARGET_CLINE = path.join(context.targetsRoot, "cline");
31
+ process.env.SKILL_FLOW_TARGET_AMP = path.join(context.targetsRoot, "amp");
32
+ process.env.SKILL_FLOW_TARGET_KIRO = path.join(context.targetsRoot, "kiro");
33
+ await Promise.all([
34
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_CLAUDE_CODE, { recursive: true }),
35
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_CODEX, { recursive: true }),
36
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_CURSOR, { recursive: true }),
37
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_GITHUB_COPILOT, { recursive: true }),
38
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_GEMINI_CLI, { recursive: true }),
39
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_OPENCODE, { recursive: true }),
40
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_OPENCLAW, { recursive: true }),
41
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_PI, { recursive: true }),
42
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_WINDSURF, { recursive: true }),
43
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_ROO_CODE, { recursive: true }),
44
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_CLINE, { recursive: true }),
45
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_AMP, { recursive: true }),
46
+ fs.mkdir(process.env.SKILL_FLOW_TARGET_KIRO, { recursive: true }),
47
+ ]);
48
+ });
49
+ afterEach(async () => {
50
+ vi.restoreAllMocks();
51
+ delete process.env.SKILL_FLOW_STATE_ROOT;
52
+ delete process.env.SKILL_FLOW_TARGET_CLAUDE_CODE;
53
+ delete process.env.SKILL_FLOW_TARGET_CODEX;
54
+ delete process.env.SKILL_FLOW_TARGET_CURSOR;
55
+ delete process.env.SKILL_FLOW_TARGET_GITHUB_COPILOT;
56
+ delete process.env.SKILL_FLOW_TARGET_GEMINI_CLI;
57
+ delete process.env.SKILL_FLOW_TARGET_OPENCODE;
58
+ delete process.env.SKILL_FLOW_TARGET_OPENCLAW;
59
+ delete process.env.SKILL_FLOW_TARGET_PI;
60
+ delete process.env.SKILL_FLOW_TARGET_WINDSURF;
61
+ delete process.env.SKILL_FLOW_TARGET_ROO_CODE;
62
+ delete process.env.SKILL_FLOW_TARGET_CLINE;
63
+ delete process.env.SKILL_FLOW_TARGET_AMP;
64
+ delete process.env.SKILL_FLOW_TARGET_KIRO;
65
+ if (context.sandboxRoot) {
66
+ await fs.rm(context.sandboxRoot, { recursive: true, force: true });
67
+ }
68
+ });
69
+ return context;
70
+ }
71
+ export async function createRepo(root, files) {
72
+ const repoPath = await fs.mkdtemp(path.join(root, "repo-"));
73
+ git(repoPath, ["init"]);
74
+ git(repoPath, ["config", "user.email", "test@example.com"]);
75
+ git(repoPath, ["config", "user.name", "Skill Flow Test"]);
76
+ await writeRepoFiles(repoPath, files);
77
+ git(repoPath, ["add", "."]);
78
+ git(repoPath, ["commit", "-m", "initial"]);
79
+ return repoPath;
80
+ }
81
+ export async function createBareRemote(repoPath, root) {
82
+ const remotePath = await fs.mkdtemp(path.join(root, "remote-"));
83
+ git(remotePath, ["init", "--bare"]);
84
+ git(repoPath, ["remote", "add", "origin", remotePath]);
85
+ git(repoPath, ["push", "-u", "origin", "HEAD"]);
86
+ return remotePath;
87
+ }
88
+ export async function seedBuiltinCatalog(app) {
89
+ for (const builtin of builtinGitSources.getBuiltinGitSources()) {
90
+ await fs.mkdir(app.store.getCatalogCheckoutPath(deriveSourceId(builtin.locator)), {
91
+ recursive: true,
92
+ });
93
+ }
94
+ }
95
+ export async function writeRepoFiles(root, files) {
96
+ for (const [relativePath, content] of Object.entries(files)) {
97
+ const absolutePath = path.join(root, relativePath);
98
+ await fs.mkdir(path.dirname(absolutePath), { recursive: true });
99
+ await fs.writeFile(absolutePath, content, "utf8");
100
+ }
101
+ }
102
+ export function skillDoc(name, description, heading) {
103
+ return `---
104
+ name: ${name}
105
+ description: |
106
+ ${description}
107
+ ---
108
+ ${heading ? `\n# ${heading}\n` : ""}
109
+ `;
110
+ }
111
+ export function git(cwd, args) {
112
+ execFileSync("git", args, { cwd, stdio: "pipe" });
113
+ }
114
+ export async function pathExists(targetPath) {
115
+ try {
116
+ await fs.lstat(targetPath);
117
+ return true;
118
+ }
119
+ catch {
120
+ return false;
121
+ }
122
+ }
123
+ //# sourceMappingURL=test-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../src/tests/test-helpers.ts"],"names":[],"mappings":"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"}
@@ -1,47 +1,170 @@
1
- import type { DeploymentAction, DeploymentTargetName, WorkflowSummary } from "../domain/types.js";
2
- import type { DraftBinding, SkillFlowApp } from "../services/skill-flow.js";
1
+ import type { ConfigBootStatus, DeploymentAction, DeploymentTargetName, DraftBinding, WorkflowSummary } from "../domain/types.js";
2
+ import type { SkillFlowApp } from "../services/skill-flow.js";
3
3
  type ConfigAppProps = {
4
4
  app: SkillFlowApp;
5
5
  availableTargets: DeploymentTargetName[];
6
6
  summaries: WorkflowSummary[];
7
7
  initialDrafts: Record<string, DraftBinding>;
8
+ bootStatus: ConfigBootStatus;
8
9
  };
9
- type FocusPane = "groups" | "skills" | "targets";
10
+ type FocusPane = "groups" | "detail.agents" | "detail.skills" | "detail.actions";
11
+ type DetailFocus = Exclude<FocusPane, "groups">;
12
+ type ActionName = "update" | "delete";
13
+ type AlertLevel = "error" | "blocked" | "warning";
10
14
  type SaveState = {
11
15
  phase: "idle" | "saving" | "saved" | "failed";
12
16
  message: string | undefined;
13
17
  };
14
- export type SaveDisplayPhase = "clean" | "dirty" | "saving" | "saved" | "failed";
18
+ type UpdateState = {
19
+ phase: "idle" | "updating" | "updated" | "failed";
20
+ message: string | undefined;
21
+ };
22
+ type DeleteState = {
23
+ phase: "idle" | "deleting" | "failed";
24
+ sourceId: string | undefined;
25
+ message: string | undefined;
26
+ };
27
+ type StatusKind = "clean" | "saving" | "saved" | "failed" | "updating" | "updated" | "update-failed" | "deleting";
28
+ type StatusDisplay = {
29
+ kind: StatusKind;
30
+ label: string;
31
+ color: "green" | "cyan" | "red" | "yellow" | "gray";
32
+ };
33
+ type PaneRow = {
34
+ key: string;
35
+ text: string;
36
+ active: boolean;
37
+ color: "cyan" | "gray" | "green" | "red" | "white" | "yellow" | undefined;
38
+ bold?: boolean;
39
+ activeColor?: "cyan" | "gray" | "green" | "red" | "white" | "yellow";
40
+ };
41
+ type AlertItem = {
42
+ level: AlertLevel;
43
+ message: string;
44
+ };
45
+ export type ConfigGroup = {
46
+ id: string;
47
+ title: string;
48
+ kind: "source" | "clawhub";
49
+ summaries: WorkflowSummary[];
50
+ };
51
+ type ConfigSkillRow = {
52
+ summary: WorkflowSummary;
53
+ leaf: WorkflowSummary["leafs"][number];
54
+ };
55
+ type WindowedRows<T> = {
56
+ rows: T[];
57
+ start: number;
58
+ end: number;
59
+ };
60
+ type FocusSnapshot = {
61
+ focus: FocusPane;
62
+ groupIndex: number;
63
+ groupId: string;
64
+ sourceId: string | undefined;
65
+ agentTarget: DeploymentTargetName | undefined;
66
+ skillId: string | undefined;
67
+ action: ActionName;
68
+ };
15
69
  type ProjectionWarningMap = Record<string, string[]>;
16
70
  export declare function normalizeDraft(draft: DraftBinding): DraftBinding;
17
71
  export declare function draftsEqual(left: DraftBinding, right: DraftBinding): boolean;
18
- export declare function getSaveDisplayPhase(savePhase: SaveState["phase"], isDirty: boolean): SaveDisplayPhase;
72
+ export declare function buildDraftsFromSummaries(summaries: WorkflowSummary[]): Record<string, DraftBinding>;
73
+ export declare function buildConfigGroups(summaries: WorkflowSummary[]): ConfigGroup[];
74
+ export declare function buildConfigGroupSkillRows(group: ConfigGroup): ConfigSkillRow[];
19
75
  export declare function getPaneViewportCount(paneHeight: number, reservedRows?: number): number;
20
- export declare function getPaneWidths(terminalColumns: number): [number, number, number];
76
+ export declare function getPaneWidths(terminalColumns: number): [number, number];
21
77
  export declare function getActionChangeCount(actions: DeploymentAction[]): number;
22
- export declare function buildSaveLabel(phase: SaveDisplayPhase, changeCount: number): string;
23
- export declare function buildCommandBar({ changeCount, focus, saveFocused, savePhase, }: {
24
- changeCount: number;
25
- focus: FocusPane;
26
- saveFocused: boolean;
27
- savePhase: SaveDisplayPhase;
28
- }): string;
29
- export declare function buildContextBar({ blockedCount, changeCount, previewError, previewLoading, savePhase, saveMessage, selectedLeafName, selectedLeafWarnings, skippedLeafs, sourceLabel, }: {
30
- blockedCount: number;
78
+ export declare function getGroupSelectedLeafCount({ drafts, group, }: {
79
+ drafts: Record<string, DraftBinding>;
80
+ group: ConfigGroup;
81
+ }): number;
82
+ export declare function getStatusDisplay({ deleteState, isSelectedDelete, saveState, updateState, }: {
83
+ deleteState: DeleteState;
84
+ isSelectedDelete: boolean;
85
+ saveState: SaveState;
86
+ updateState: UpdateState;
87
+ }): StatusDisplay;
88
+ export declare function buildTopBar({ width, isDirty, changeCount, showDelete, statusLabel, }: {
89
+ width: number;
90
+ isDirty: boolean;
31
91
  changeCount: number;
32
- previewError: string | undefined;
33
- previewLoading: boolean;
34
- savePhase: SaveDisplayPhase;
35
- saveMessage: string | undefined;
36
- selectedLeafName: string | undefined;
37
- selectedLeafWarnings: string[];
38
- skippedLeafs: number;
39
- sourceLabel: string;
92
+ showDelete: boolean;
93
+ statusLabel: string;
40
94
  }): string;
95
+ export declare function prioritizeAlerts(alerts: AlertItem[]): AlertItem[];
96
+ export declare function getInitialDetailFocus({ hasAgents, hasSkills, }: {
97
+ hasAgents: boolean;
98
+ hasSkills: boolean;
99
+ }): DetailFocus;
100
+ export declare function moveDetailFocus({ actionCursor, actionCount, agentCount, agentCursor, direction, focus, skillCount, skillCursor, }: {
101
+ actionCursor: number;
102
+ actionCount: number;
103
+ agentCount: number;
104
+ agentCursor: number;
105
+ direction: -1 | 1;
106
+ focus: DetailFocus;
107
+ skillCount: number;
108
+ skillCursor: number;
109
+ }): {
110
+ focus: DetailFocus;
111
+ agentCursor: number;
112
+ skillCursor: number;
113
+ actionCursor: number;
114
+ };
115
+ export declare function getNextSelectionIndexAfterDelete(currentIndex: number, nextCount: number): number;
116
+ export declare function captureFocusSnapshot({ actionCursor, agentCursor, availableTargets, focus, groupId, selectedGroupIndex, selectedSummary, skillCursor, }: {
117
+ actionCursor: number;
118
+ agentCursor: number;
119
+ availableTargets: DeploymentTargetName[];
120
+ focus: FocusPane;
121
+ groupId: string;
122
+ selectedGroupIndex: number;
123
+ selectedSummary: WorkflowSummary | undefined;
124
+ skillCursor: number;
125
+ }): FocusSnapshot;
126
+ export declare function reconcileFocusAfterReload({ availableTargets, nextGroups, snapshot, }: {
127
+ availableTargets: DeploymentTargetName[];
128
+ nextGroups: ConfigGroup[];
129
+ snapshot: FocusSnapshot;
130
+ }): {
131
+ actionCursor: number;
132
+ agentCursor: number;
133
+ focus: FocusPane;
134
+ groupCursor: number;
135
+ selectedGroupIndex: number;
136
+ skillCursor: number;
137
+ };
138
+ export declare function getRequestedAction({ actionCursor, canDelete, focus, input, keyReturn, }: {
139
+ actionCursor: number;
140
+ canDelete: boolean;
141
+ focus: FocusPane;
142
+ input: string;
143
+ keyReturn: boolean;
144
+ }): ActionName | undefined;
41
145
  export declare function buildProjectionWarningMap({ drafts, summaries, sourceId, }: {
42
146
  drafts: Record<string, DraftBinding>;
43
147
  summaries: WorkflowSummary[];
44
148
  sourceId: string;
45
149
  }): ProjectionWarningMap;
46
- export declare function ConfigApp({ app, availableTargets, summaries, initialDrafts, }: ConfigAppProps): import("react/jsx-runtime").JSX.Element;
150
+ export declare function buildScrollableRows<T extends PaneRow>(items: T[], cursorIndex: number, visibleCount: number, keyPrefix?: string, reserveHintSlots?: boolean): WindowedRows<T | PaneRow>;
151
+ export declare function ConfigApp({ app, availableTargets, summaries, initialDrafts, bootStatus, }: ConfigAppProps): import("react/jsx-runtime").JSX.Element;
152
+ export declare function ConfigBootstrapApp({ app }: {
153
+ app: SkillFlowApp;
154
+ }): import("react/jsx-runtime").JSX.Element;
155
+ export declare function buildDetailMetadataRows({ alerts, detailWidth, group, summary, }: {
156
+ alerts: AlertItem[];
157
+ detailWidth: number;
158
+ group: ConfigGroup;
159
+ summary: WorkflowSummary;
160
+ }): PaneRow[];
161
+ export declare function buildActionRows({ actionCursor, canRunActions, deleteState, focus, isSelectedDelete, showDeleteAction, updateState, }: {
162
+ actionCursor: number;
163
+ canRunActions: boolean;
164
+ deleteState: DeleteState;
165
+ focus: FocusPane;
166
+ isSelectedDelete: boolean;
167
+ showDeleteAction: boolean;
168
+ updateState: UpdateState;
169
+ }): PaneRow[];
47
170
  export {};