@kilnai/cli 0.23.2 → 1.0.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.
- package/README.md +33 -0
- package/dist/application/__tests__/plan-exit-tool.test.d.ts +2 -0
- package/dist/application/__tests__/plan-exit-tool.test.d.ts.map +1 -0
- package/dist/application/__tests__/plan-exit-tool.test.js +12 -0
- package/dist/application/__tests__/plan-exit-tool.test.js.map +1 -0
- package/dist/application/agent-loader.d.ts +12 -0
- package/dist/application/agent-loader.d.ts.map +1 -0
- package/dist/application/agent-loader.js +114 -0
- package/dist/application/agent-loader.js.map +1 -0
- package/dist/application/agent-loader.test.d.ts +2 -0
- package/dist/application/agent-loader.test.d.ts.map +1 -0
- package/dist/application/agent-loader.test.js +151 -0
- package/dist/application/agent-loader.test.js.map +1 -0
- package/dist/application/context-artifact-keys.d.ts +5 -0
- package/dist/application/context-artifact-keys.d.ts.map +1 -0
- package/dist/application/context-artifact-keys.js +14 -0
- package/dist/application/context-artifact-keys.js.map +1 -0
- package/dist/application/context-governance.d.ts +6 -0
- package/dist/application/context-governance.d.ts.map +1 -0
- package/dist/application/context-governance.js +20 -0
- package/dist/application/context-governance.js.map +1 -0
- package/dist/application/context-governor.d.ts +26 -0
- package/dist/application/context-governor.d.ts.map +1 -0
- package/dist/application/context-governor.js +164 -0
- package/dist/application/context-governor.js.map +1 -0
- package/dist/application/context-types.d.ts +20 -0
- package/dist/application/context-types.d.ts.map +1 -0
- package/dist/application/context-types.js +21 -0
- package/dist/application/context-types.js.map +1 -0
- package/dist/application/plan-exit-tool.d.ts +19 -0
- package/dist/application/plan-exit-tool.d.ts.map +1 -0
- package/dist/application/plan-exit-tool.js +13 -0
- package/dist/application/plan-exit-tool.js.map +1 -0
- package/dist/application/repo-summary-cache.d.ts +5 -0
- package/dist/application/repo-summary-cache.d.ts.map +1 -0
- package/dist/application/repo-summary-cache.js +82 -0
- package/dist/application/repo-summary-cache.js.map +1 -0
- package/dist/application/resume-strategy-feedback.d.ts +5 -0
- package/dist/application/resume-strategy-feedback.d.ts.map +1 -0
- package/dist/application/resume-strategy-feedback.js +81 -0
- package/dist/application/resume-strategy-feedback.js.map +1 -0
- package/dist/application/resume-strategy-policy.d.ts +26 -0
- package/dist/application/resume-strategy-policy.d.ts.map +1 -0
- package/dist/application/resume-strategy-policy.js +35 -0
- package/dist/application/resume-strategy-policy.js.map +1 -0
- package/dist/application/run-session.d.ts +39 -0
- package/dist/application/run-session.d.ts.map +1 -0
- package/dist/application/run-session.js +349 -0
- package/dist/application/run-session.js.map +1 -0
- package/dist/application/session-hooks.d.ts +20 -0
- package/dist/application/session-hooks.d.ts.map +1 -0
- package/dist/application/session-hooks.js +55 -0
- package/dist/application/session-hooks.js.map +1 -0
- package/dist/application/session-ledger.d.ts +12 -0
- package/dist/application/session-ledger.d.ts.map +1 -0
- package/dist/application/session-ledger.js +29 -0
- package/dist/application/session-ledger.js.map +1 -0
- package/dist/application/session-report.d.ts +19 -0
- package/dist/application/session-report.d.ts.map +1 -0
- package/dist/application/session-report.js +207 -0
- package/dist/application/session-report.js.map +1 -0
- package/dist/application/session-resume.d.ts +3 -0
- package/dist/application/session-resume.d.ts.map +1 -0
- package/dist/application/session-resume.js +16 -0
- package/dist/application/session-resume.js.map +1 -0
- package/dist/commands/auth.d.ts +2 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +138 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/config.d.ts +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +141 -27
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/cron.d.ts +3 -0
- package/dist/commands/cron.d.ts.map +1 -0
- package/dist/commands/cron.js +201 -0
- package/dist/commands/cron.js.map +1 -0
- package/dist/commands/dev.js +2 -2
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/domain.js +17 -17
- package/dist/commands/domain.js.map +1 -1
- package/dist/commands/init.d.ts +2 -11
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +14 -25
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp-config.d.ts +7 -1
- package/dist/commands/mcp-config.d.ts.map +1 -1
- package/dist/commands/mcp-config.js +26 -10
- package/dist/commands/mcp-config.js.map +1 -1
- package/dist/commands/memory.d.ts +1 -1
- package/dist/commands/memory.d.ts.map +1 -1
- package/dist/commands/memory.js +10 -10
- package/dist/commands/memory.js.map +1 -1
- package/dist/commands/run.d.ts +15 -3
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +464 -85
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/serve.d.ts +1 -1
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +3 -3
- package/dist/commands/serve.js.map +1 -1
- package/dist/commands/skill-capture.d.ts +13 -0
- package/dist/commands/skill-capture.d.ts.map +1 -0
- package/dist/commands/skill-capture.js +212 -0
- package/dist/commands/skill-capture.js.map +1 -0
- package/dist/commands/skill.d.ts.map +1 -1
- package/dist/commands/skill.js +7 -3
- package/dist/commands/skill.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +15 -16
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/sync.d.ts +11 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +114 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/tools.d.ts +6 -0
- package/dist/commands/tools.d.ts.map +1 -0
- package/dist/commands/tools.js +28 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/commands/tui.d.ts +29 -0
- package/dist/commands/tui.d.ts.map +1 -0
- package/dist/commands/tui.js +444 -0
- package/dist/commands/tui.js.map +1 -0
- package/dist/config/config-merger.d.ts +5 -0
- package/dist/config/config-merger.d.ts.map +1 -0
- package/dist/config/config-merger.js +25 -0
- package/dist/config/config-merger.js.map +1 -0
- package/dist/config/config-merger.test.d.ts +2 -0
- package/dist/config/config-merger.test.d.ts.map +1 -0
- package/dist/config/config-merger.test.js +165 -0
- package/dist/config/config-merger.test.js.map +1 -0
- package/dist/config/env-config.d.ts +5 -0
- package/dist/config/env-config.d.ts.map +1 -0
- package/dist/config/env-config.js +24 -0
- package/dist/config/env-config.js.map +1 -0
- package/dist/config/env-config.test.d.ts +2 -0
- package/dist/config/env-config.test.d.ts.map +1 -0
- package/dist/config/env-config.test.js +79 -0
- package/dist/config/env-config.test.js.map +1 -0
- package/dist/config/global-config.d.ts +23 -0
- package/dist/config/global-config.d.ts.map +1 -0
- package/dist/config/global-config.js +48 -0
- package/dist/config/global-config.js.map +1 -0
- package/dist/config/global-config.test.d.ts +2 -0
- package/dist/config/global-config.test.d.ts.map +1 -0
- package/dist/config/global-config.test.js +96 -0
- package/dist/config/global-config.test.js.map +1 -0
- package/dist/config-resolver.d.ts +5 -0
- package/dist/config-resolver.d.ts.map +1 -0
- package/dist/config-resolver.js +19 -0
- package/dist/config-resolver.js.map +1 -0
- package/dist/config.d.ts +8 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +14 -1
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +193 -16
- package/dist/index.js.map +1 -1
- package/dist/kiln-yaml-types.d.ts +127 -0
- package/dist/kiln-yaml-types.d.ts.map +1 -0
- package/dist/kiln-yaml-types.js +42 -0
- package/dist/kiln-yaml-types.js.map +1 -0
- package/dist/kiln-yaml.d.ts +10 -0
- package/dist/kiln-yaml.d.ts.map +1 -0
- package/dist/kiln-yaml.js +109 -0
- package/dist/kiln-yaml.js.map +1 -0
- package/dist/mcp/config-generator.d.ts +9 -2
- package/dist/mcp/config-generator.d.ts.map +1 -1
- package/dist/mcp/config-generator.js +132 -2
- package/dist/mcp/config-generator.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +2 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +2 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp-entry.js +0 -5
- package/dist/mcp-entry.js.map +1 -1
- package/dist/sync/agent-sync.d.ts +13 -0
- package/dist/sync/agent-sync.d.ts.map +1 -0
- package/dist/sync/agent-sync.js +130 -0
- package/dist/sync/agent-sync.js.map +1 -0
- package/dist/sync/agent-sync.test.d.ts +2 -0
- package/dist/sync/agent-sync.test.d.ts.map +1 -0
- package/dist/sync/agent-sync.test.js +130 -0
- package/dist/sync/agent-sync.test.js.map +1 -0
- package/dist/sync/agents-md-sync.d.ts +7 -0
- package/dist/sync/agents-md-sync.d.ts.map +1 -0
- package/dist/sync/agents-md-sync.js +44 -0
- package/dist/sync/agents-md-sync.js.map +1 -0
- package/dist/sync/agents-md-sync.test.d.ts +2 -0
- package/dist/sync/agents-md-sync.test.d.ts.map +1 -0
- package/dist/sync/agents-md-sync.test.js +154 -0
- package/dist/sync/agents-md-sync.test.js.map +1 -0
- package/dist/sync/hook-sync.d.ts +8 -0
- package/dist/sync/hook-sync.d.ts.map +1 -0
- package/dist/sync/hook-sync.js +90 -0
- package/dist/sync/hook-sync.js.map +1 -0
- package/dist/sync/security-sync.d.ts +9 -0
- package/dist/sync/security-sync.d.ts.map +1 -0
- package/dist/sync/security-sync.js +161 -0
- package/dist/sync/security-sync.js.map +1 -0
- package/dist/sync/skill-sync.d.ts +10 -0
- package/dist/sync/skill-sync.d.ts.map +1 -0
- package/dist/sync/skill-sync.js +87 -0
- package/dist/sync/skill-sync.js.map +1 -0
- package/dist/sync/skill-sync.test.d.ts +2 -0
- package/dist/sync/skill-sync.test.d.ts.map +1 -0
- package/dist/sync/skill-sync.test.js +163 -0
- package/dist/sync/skill-sync.test.js.map +1 -0
- package/dist/wrapper/approval-memory-store.d.ts +40 -0
- package/dist/wrapper/approval-memory-store.d.ts.map +1 -0
- package/dist/wrapper/approval-memory-store.js +132 -0
- package/dist/wrapper/approval-memory-store.js.map +1 -0
- package/dist/wrapper/claude-code-process.d.ts +32 -34
- package/dist/wrapper/claude-code-process.d.ts.map +1 -1
- package/dist/wrapper/claude-code-process.js +181 -66
- package/dist/wrapper/claude-code-process.js.map +1 -1
- package/dist/wrapper/cleanup-registry.d.ts +7 -0
- package/dist/wrapper/cleanup-registry.d.ts.map +1 -0
- package/dist/wrapper/cleanup-registry.js +11 -0
- package/dist/wrapper/cleanup-registry.js.map +1 -0
- package/dist/wrapper/codex-session.d.ts +49 -0
- package/dist/wrapper/codex-session.d.ts.map +1 -0
- package/dist/wrapper/codex-session.js +470 -0
- package/dist/wrapper/codex-session.js.map +1 -0
- package/dist/wrapper/debug.d.ts +2 -0
- package/dist/wrapper/debug.d.ts.map +1 -0
- package/dist/wrapper/debug.js +7 -0
- package/dist/wrapper/debug.js.map +1 -0
- package/dist/wrapper/executable-provider-session.d.ts +26 -0
- package/dist/wrapper/executable-provider-session.d.ts.map +1 -0
- package/dist/wrapper/executable-provider-session.js +214 -0
- package/dist/wrapper/executable-provider-session.js.map +1 -0
- package/dist/wrapper/hook-executor.d.ts +21 -0
- package/dist/wrapper/hook-executor.d.ts.map +1 -0
- package/dist/wrapper/hook-executor.js +100 -0
- package/dist/wrapper/hook-executor.js.map +1 -0
- package/dist/wrapper/hook-registry.d.ts +10 -0
- package/dist/wrapper/hook-registry.d.ts.map +1 -0
- package/dist/wrapper/hook-registry.js +57 -0
- package/dist/wrapper/hook-registry.js.map +1 -0
- package/dist/wrapper/index.d.ts +83 -2
- package/dist/wrapper/index.d.ts.map +1 -1
- package/dist/wrapper/index.js +11 -0
- package/dist/wrapper/index.js.map +1 -1
- package/dist/wrapper/mcp-selector.d.ts +2 -0
- package/dist/wrapper/mcp-selector.d.ts.map +1 -0
- package/dist/wrapper/mcp-selector.js +8 -0
- package/dist/wrapper/mcp-selector.js.map +1 -0
- package/dist/wrapper/opencode-session.d.ts +69 -0
- package/dist/wrapper/opencode-session.d.ts.map +1 -0
- package/dist/wrapper/opencode-session.js +568 -0
- package/dist/wrapper/opencode-session.js.map +1 -0
- package/dist/wrapper/permission-evaluator.d.ts +57 -0
- package/dist/wrapper/permission-evaluator.d.ts.map +1 -0
- package/dist/wrapper/permission-evaluator.js +310 -0
- package/dist/wrapper/permission-evaluator.js.map +1 -0
- package/dist/wrapper/permission-normalizer.d.ts +13 -0
- package/dist/wrapper/permission-normalizer.d.ts.map +1 -0
- package/dist/wrapper/permission-normalizer.js +88 -0
- package/dist/wrapper/permission-normalizer.js.map +1 -0
- package/dist/wrapper/permission-policy-authorizer.d.ts +12 -0
- package/dist/wrapper/permission-policy-authorizer.d.ts.map +1 -0
- package/dist/wrapper/permission-policy-authorizer.js +64 -0
- package/dist/wrapper/permission-policy-authorizer.js.map +1 -0
- package/dist/wrapper/preamble-builder.d.ts +7 -0
- package/dist/wrapper/preamble-builder.d.ts.map +1 -0
- package/dist/wrapper/preamble-builder.js +103 -0
- package/dist/wrapper/preamble-builder.js.map +1 -0
- package/dist/wrapper/provider-context.d.ts +20 -0
- package/dist/wrapper/provider-context.d.ts.map +1 -0
- package/dist/wrapper/provider-context.js +58 -0
- package/dist/wrapper/provider-context.js.map +1 -0
- package/dist/wrapper/provider-session.d.ts +27 -0
- package/dist/wrapper/provider-session.d.ts.map +1 -0
- package/dist/wrapper/provider-session.js +208 -0
- package/dist/wrapper/provider-session.js.map +1 -0
- package/dist/wrapper/session-manager.d.ts +21 -4
- package/dist/wrapper/session-manager.d.ts.map +1 -1
- package/dist/wrapper/session-manager.js +173 -14
- package/dist/wrapper/session-manager.js.map +1 -1
- package/dist/wrapper/session-registry.d.ts +136 -0
- package/dist/wrapper/session-registry.d.ts.map +1 -0
- package/dist/wrapper/session-registry.js +977 -0
- package/dist/wrapper/session-registry.js.map +1 -0
- package/dist/wrapper/session-store.d.ts +63 -0
- package/dist/wrapper/session-store.d.ts.map +1 -0
- package/dist/wrapper/session-store.js +215 -0
- package/dist/wrapper/session-store.js.map +1 -0
- package/dist/wrapper/session.d.ts +127 -0
- package/dist/wrapper/session.d.ts.map +1 -0
- package/dist/wrapper/session.js +14 -0
- package/dist/wrapper/session.js.map +1 -0
- package/dist/wrapper/worktree-manager.d.ts +30 -0
- package/dist/wrapper/worktree-manager.d.ts.map +1 -0
- package/dist/wrapper/worktree-manager.js +139 -0
- package/dist/wrapper/worktree-manager.js.map +1 -0
- package/package.json +11 -7
package/README.md
CHANGED
|
@@ -66,6 +66,28 @@ Run a single task:
|
|
|
66
66
|
kiln run "Implement the login page"
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
### `kiln tui`
|
|
70
|
+
|
|
71
|
+
Start the interactive terminal UI:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
kiln tui
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Useful flags:
|
|
78
|
+
|
|
79
|
+
- `--provider <name>` to select the initial provider
|
|
80
|
+
- `--theme <name>` to select a theme
|
|
81
|
+
- `--port <number>` to override the local TUI gateway port
|
|
82
|
+
- `--plan` to start in plan mode
|
|
83
|
+
|
|
84
|
+
Current transport behavior:
|
|
85
|
+
|
|
86
|
+
- gateway transport is the default path
|
|
87
|
+
- direct transport is available only with `KILN_TUI_TRANSPORT=direct`
|
|
88
|
+
|
|
89
|
+
The default gateway path keeps TUI conversations on the runtime session pipeline so provider routing, continuity, approvals, and sidebar route labels reflect the actual backend used for each turn.
|
|
90
|
+
|
|
69
91
|
### `kiln gateway`
|
|
70
92
|
|
|
71
93
|
Start the production gateway:
|
|
@@ -109,6 +131,17 @@ Show current session status:
|
|
|
109
131
|
kiln status
|
|
110
132
|
```
|
|
111
133
|
|
|
134
|
+
### `kiln cron`
|
|
135
|
+
|
|
136
|
+
Manage schedule triggers:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
kiln cron list # List all schedules
|
|
140
|
+
kiln cron add <name> <cron> <task> [--timezone <tz>]
|
|
141
|
+
kiln cron remove <name>
|
|
142
|
+
kiln cron run <name> # Fire immediately without resetting schedule
|
|
143
|
+
```
|
|
144
|
+
|
|
112
145
|
## MCP Server
|
|
113
146
|
|
|
114
147
|
The CLI includes a built-in MCP server for Claude Code integration:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-exit-tool.test.d.ts","sourceRoot":"","sources":["../../../src/application/__tests__/plan-exit-tool.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { PLAN_EXIT_TOOL_NAME, planExitToolSchema } from "../plan-exit-tool.js";
|
|
3
|
+
describe("plan-exit-tool", () => {
|
|
4
|
+
it("uses submit_plan as schema name", () => {
|
|
5
|
+
expect(PLAN_EXIT_TOOL_NAME).toBe("submit_plan");
|
|
6
|
+
expect(planExitToolSchema.name).toBe("submit_plan");
|
|
7
|
+
});
|
|
8
|
+
it("requires the plan field in input schema", () => {
|
|
9
|
+
expect(planExitToolSchema.inputSchema.required).toContain("plan");
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=plan-exit-tool.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-exit-tool.test.js","sourceRoot":"","sources":["../../../src/application/__tests__/plan-exit-tool.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/E,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChD,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,kBAAkB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface KilnAgentDefinition {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly role: string;
|
|
4
|
+
readonly tools?: readonly string[];
|
|
5
|
+
readonly model?: string;
|
|
6
|
+
readonly skills?: readonly string[];
|
|
7
|
+
readonly instructions?: string;
|
|
8
|
+
readonly scope: "global" | "project";
|
|
9
|
+
}
|
|
10
|
+
export declare function loadAgentDefinitions(projectPath: string): Promise<KilnAgentDefinition[]>;
|
|
11
|
+
export declare function findAgent(definitions: KilnAgentDefinition[], name: string): KilnAgentDefinition | undefined;
|
|
12
|
+
//# sourceMappingURL=agent-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-loader.d.ts","sourceRoot":"","sources":["../../src/application/agent-loader.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;CACtC;AAiHD,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAe9F;AAED,wBAAgB,SAAS,CACvB,WAAW,EAAE,mBAAmB,EAAE,EAClC,IAAI,EAAE,MAAM,GACX,mBAAmB,GAAG,SAAS,CAOjC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { parse } from "yaml";
|
|
5
|
+
function parseFrontmatter(raw) {
|
|
6
|
+
const content = raw.replace(/^\uFEFF/, "");
|
|
7
|
+
const match = /^---\s*\r?\n([\s\S]*?)\r?\n---\s*([\s\S]*)$/u.exec(content);
|
|
8
|
+
if (!match) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
frontmatter: match[1] ?? "",
|
|
13
|
+
body: (match[2] ?? "").trim(),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function asNonEmptyString(value) {
|
|
17
|
+
if (typeof value !== "string") {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const trimmed = value.trim();
|
|
21
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
22
|
+
}
|
|
23
|
+
function asStringArray(value) {
|
|
24
|
+
if (!Array.isArray(value)) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const entries = value
|
|
28
|
+
.filter((entry) => typeof entry === "string")
|
|
29
|
+
.map((entry) => entry.trim())
|
|
30
|
+
.filter((entry) => entry.length > 0);
|
|
31
|
+
return entries.length > 0 ? entries : undefined;
|
|
32
|
+
}
|
|
33
|
+
function parseAgentDefinition(raw, scope) {
|
|
34
|
+
const parsed = parseFrontmatter(raw);
|
|
35
|
+
if (!parsed) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
let frontmatter;
|
|
39
|
+
try {
|
|
40
|
+
frontmatter = parse(parsed.frontmatter);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
if (!frontmatter || typeof frontmatter !== "object") {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const record = frontmatter;
|
|
49
|
+
const name = asNonEmptyString(record.name);
|
|
50
|
+
const role = asNonEmptyString(record.role);
|
|
51
|
+
if (!name || !role) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
const tools = asStringArray(record.tools);
|
|
55
|
+
const model = asNonEmptyString(record.model);
|
|
56
|
+
const skills = asStringArray(record.skills);
|
|
57
|
+
const instructions = parsed.body.length > 0 ? parsed.body : undefined;
|
|
58
|
+
return {
|
|
59
|
+
name,
|
|
60
|
+
role,
|
|
61
|
+
...(tools ? { tools } : {}),
|
|
62
|
+
...(model ? { model } : {}),
|
|
63
|
+
...(skills ? { skills } : {}),
|
|
64
|
+
...(instructions ? { instructions } : {}),
|
|
65
|
+
scope,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function readDefinitionsFromDirectory(directory, scope) {
|
|
69
|
+
let entries;
|
|
70
|
+
try {
|
|
71
|
+
entries = readdirSync(directory);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
const definitions = [];
|
|
77
|
+
for (const entry of entries) {
|
|
78
|
+
if (!entry.toLowerCase().endsWith(".md")) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const filePath = join(directory, entry);
|
|
83
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
84
|
+
const definition = parseAgentDefinition(raw, scope);
|
|
85
|
+
if (definition) {
|
|
86
|
+
definitions.push(definition);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// skip unreadable or malformed files
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return definitions;
|
|
94
|
+
}
|
|
95
|
+
export async function loadAgentDefinitions(projectPath) {
|
|
96
|
+
const globalDirectory = join(homedir(), ".kiln", "agents");
|
|
97
|
+
const projectDirectory = join(projectPath, ".kiln", "agents");
|
|
98
|
+
const merged = new Map();
|
|
99
|
+
for (const definition of readDefinitionsFromDirectory(globalDirectory, "global")) {
|
|
100
|
+
merged.set(definition.name.toLowerCase(), definition);
|
|
101
|
+
}
|
|
102
|
+
for (const definition of readDefinitionsFromDirectory(projectDirectory, "project")) {
|
|
103
|
+
merged.set(definition.name.toLowerCase(), definition);
|
|
104
|
+
}
|
|
105
|
+
return [...merged.values()];
|
|
106
|
+
}
|
|
107
|
+
export function findAgent(definitions, name) {
|
|
108
|
+
const target = name.trim().toLowerCase();
|
|
109
|
+
if (target.length === 0) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
return definitions.find((definition) => definition.name.toLowerCase() === target);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=agent-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-loader.js","sourceRoot":"","sources":["../../src/application/agent-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-loader.test.d.ts","sourceRoot":"","sources":["../../src/application/agent-loader.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { readFileSync, readdirSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
vi.mock("node:fs", () => ({
|
|
6
|
+
readdirSync: vi.fn(),
|
|
7
|
+
readFileSync: vi.fn(),
|
|
8
|
+
}));
|
|
9
|
+
vi.mock("node:os", () => ({
|
|
10
|
+
homedir: vi.fn(() => "/home/test-user"),
|
|
11
|
+
}));
|
|
12
|
+
import { findAgent, loadAgentDefinitions } from "./agent-loader.js";
|
|
13
|
+
const HOME_DIR = "/home/test-user";
|
|
14
|
+
const PROJECT_PATH = "/workspace/project";
|
|
15
|
+
const GLOBAL_AGENTS_DIR = join(HOME_DIR, ".kiln", "agents");
|
|
16
|
+
const PROJECT_AGENTS_DIR = join(PROJECT_PATH, ".kiln", "agents");
|
|
17
|
+
const readdirSyncMock = readdirSync;
|
|
18
|
+
const readFileSyncMock = readFileSync;
|
|
19
|
+
const homedirMock = homedir;
|
|
20
|
+
function throwNotFound() {
|
|
21
|
+
const error = new Error("ENOENT");
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
function markdownWithFrontmatter(frontmatter, body = "") {
|
|
25
|
+
return `---\n${frontmatter}\n---\n${body}`;
|
|
26
|
+
}
|
|
27
|
+
function configureDirectories(globalEntries, projectEntries) {
|
|
28
|
+
readdirSyncMock.mockImplementation((directoryPath) => {
|
|
29
|
+
if (directoryPath === GLOBAL_AGENTS_DIR) {
|
|
30
|
+
if (!globalEntries)
|
|
31
|
+
throwNotFound();
|
|
32
|
+
return [...globalEntries];
|
|
33
|
+
}
|
|
34
|
+
if (directoryPath === PROJECT_AGENTS_DIR) {
|
|
35
|
+
if (!projectEntries)
|
|
36
|
+
throwNotFound();
|
|
37
|
+
return [...projectEntries];
|
|
38
|
+
}
|
|
39
|
+
throwNotFound();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function configureFiles(files) {
|
|
43
|
+
readFileSyncMock.mockImplementation((filePath) => {
|
|
44
|
+
const content = files[String(filePath)];
|
|
45
|
+
if (content === undefined) {
|
|
46
|
+
throwNotFound();
|
|
47
|
+
}
|
|
48
|
+
return content;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
describe("agent-loader", () => {
|
|
52
|
+
beforeEach(() => {
|
|
53
|
+
vi.clearAllMocks();
|
|
54
|
+
homedirMock.mockReturnValue(HOME_DIR);
|
|
55
|
+
configureDirectories();
|
|
56
|
+
configureFiles({});
|
|
57
|
+
});
|
|
58
|
+
afterEach(() => {
|
|
59
|
+
vi.restoreAllMocks();
|
|
60
|
+
});
|
|
61
|
+
it("returns empty array when both directories missing", async () => {
|
|
62
|
+
const definitions = await loadAgentDefinitions(PROJECT_PATH);
|
|
63
|
+
expect(definitions).toEqual([]);
|
|
64
|
+
expect(readdirSyncMock).toHaveBeenCalledWith(GLOBAL_AGENTS_DIR);
|
|
65
|
+
expect(readdirSyncMock).toHaveBeenCalledWith(PROJECT_AGENTS_DIR);
|
|
66
|
+
});
|
|
67
|
+
it("parses frontmatter correctly (name, role, tools, model, skills)", async () => {
|
|
68
|
+
configureDirectories(["architect.md"], []);
|
|
69
|
+
configureFiles({
|
|
70
|
+
[join(GLOBAL_AGENTS_DIR, "architect.md")]: markdownWithFrontmatter([
|
|
71
|
+
"name: Architect",
|
|
72
|
+
"role: System architect",
|
|
73
|
+
"tools:",
|
|
74
|
+
" - read",
|
|
75
|
+
" - write",
|
|
76
|
+
"model: claude-sonnet-4-6",
|
|
77
|
+
"skills:",
|
|
78
|
+
" - sequel-spring",
|
|
79
|
+
" - refactor",
|
|
80
|
+
].join("\n")),
|
|
81
|
+
});
|
|
82
|
+
const definitions = await loadAgentDefinitions(PROJECT_PATH);
|
|
83
|
+
expect(definitions).toEqual([
|
|
84
|
+
{
|
|
85
|
+
name: "Architect",
|
|
86
|
+
role: "System architect",
|
|
87
|
+
tools: ["read", "write"],
|
|
88
|
+
model: "claude-sonnet-4-6",
|
|
89
|
+
skills: ["sequel-spring", "refactor"],
|
|
90
|
+
scope: "global",
|
|
91
|
+
},
|
|
92
|
+
]);
|
|
93
|
+
});
|
|
94
|
+
it("captures markdown body as instructions", async () => {
|
|
95
|
+
configureDirectories(["planner.md"], []);
|
|
96
|
+
configureFiles({
|
|
97
|
+
[join(GLOBAL_AGENTS_DIR, "planner.md")]: markdownWithFrontmatter(["name: Planner", "role: Planning specialist"].join("\n"), "\n# Plan\n\nCreate a concrete implementation plan.\n"),
|
|
98
|
+
});
|
|
99
|
+
const [definition] = await loadAgentDefinitions(PROJECT_PATH);
|
|
100
|
+
expect(definition?.instructions).toBe("# Plan\n\nCreate a concrete implementation plan.");
|
|
101
|
+
});
|
|
102
|
+
it("project agents override global agents with same name", async () => {
|
|
103
|
+
configureDirectories(["shared.md", "global-only.md"], ["shared.md", "project-only.md"]);
|
|
104
|
+
configureFiles({
|
|
105
|
+
[join(GLOBAL_AGENTS_DIR, "shared.md")]: markdownWithFrontmatter(["name: Shared", "role: Global role"].join("\n")),
|
|
106
|
+
[join(GLOBAL_AGENTS_DIR, "global-only.md")]: markdownWithFrontmatter(["name: GlobalOnly", "role: Global only role"].join("\n")),
|
|
107
|
+
[join(PROJECT_AGENTS_DIR, "shared.md")]: markdownWithFrontmatter(["name: Shared", "role: Project role"].join("\n")),
|
|
108
|
+
[join(PROJECT_AGENTS_DIR, "project-only.md")]: markdownWithFrontmatter(["name: ProjectOnly", "role: Project only role"].join("\n")),
|
|
109
|
+
});
|
|
110
|
+
const definitions = await loadAgentDefinitions(PROJECT_PATH);
|
|
111
|
+
expect(definitions).toHaveLength(3);
|
|
112
|
+
expect(findAgent(definitions, "shared")).toEqual({
|
|
113
|
+
name: "Shared",
|
|
114
|
+
role: "Project role",
|
|
115
|
+
scope: "project",
|
|
116
|
+
});
|
|
117
|
+
expect(findAgent(definitions, "globalonly")?.scope).toBe("global");
|
|
118
|
+
expect(findAgent(definitions, "projectonly")?.scope).toBe("project");
|
|
119
|
+
});
|
|
120
|
+
it("skips files missing required name field", async () => {
|
|
121
|
+
configureDirectories(["missing-name.md"], []);
|
|
122
|
+
configureFiles({
|
|
123
|
+
[join(GLOBAL_AGENTS_DIR, "missing-name.md")]: markdownWithFrontmatter(["role: No name present"].join("\n")),
|
|
124
|
+
});
|
|
125
|
+
const definitions = await loadAgentDefinitions(PROJECT_PATH);
|
|
126
|
+
expect(definitions).toEqual([]);
|
|
127
|
+
});
|
|
128
|
+
it("skips files missing required role field", async () => {
|
|
129
|
+
configureDirectories(["missing-role.md"], []);
|
|
130
|
+
configureFiles({
|
|
131
|
+
[join(GLOBAL_AGENTS_DIR, "missing-role.md")]: markdownWithFrontmatter(["name: MissingRole"].join("\n")),
|
|
132
|
+
});
|
|
133
|
+
const definitions = await loadAgentDefinitions(PROJECT_PATH);
|
|
134
|
+
expect(definitions).toEqual([]);
|
|
135
|
+
});
|
|
136
|
+
it("findAgent() returns correct definition case-insensitively", () => {
|
|
137
|
+
const definitions = [
|
|
138
|
+
{ name: "Planner", role: "Planning specialist", scope: "global" },
|
|
139
|
+
{ name: "Code-Reviewer", role: "Review specialist", scope: "project" },
|
|
140
|
+
];
|
|
141
|
+
expect(findAgent(definitions, "planner")).toBe(definitions[0]);
|
|
142
|
+
expect(findAgent(definitions, "CODE-REVIEWER")).toBe(definitions[1]);
|
|
143
|
+
});
|
|
144
|
+
it("findAgent() returns undefined for unknown name", () => {
|
|
145
|
+
const definitions = [
|
|
146
|
+
{ name: "Planner", role: "Planning specialist", scope: "global" },
|
|
147
|
+
];
|
|
148
|
+
expect(findAgent(definitions, "unknown")).toBeUndefined();
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=agent-loader.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-loader.test.js","sourceRoot":"","sources":["../../src/application/agent-loader.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function buildCliSessionSummaryArtifactKey(sessionId: string): string;
|
|
2
|
+
export declare function buildCliProjectSummaryArtifactKey(projectPath: string): string;
|
|
3
|
+
export declare function buildCliPlanSummaryArtifactKey(projectPath: string, task: string, maxTaskShapeLength?: number): string;
|
|
4
|
+
export declare function buildCliPlanSummaryArtifactKeyFromShape(projectPath: string, taskShape: string): string;
|
|
5
|
+
//# sourceMappingURL=context-artifact-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-artifact-keys.d.ts","sourceRoot":"","sources":["../../src/application/context-artifact-keys.ts"],"names":[],"mappings":"AAEA,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,iCAAiC,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,kBAAkB,SAAK,GACtB,MAAM,CAER;AAED,wBAAgB,uCAAuC,CACrD,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { normalizeTaskShapeKey } from "@kilnai/core";
|
|
2
|
+
export function buildCliSessionSummaryArtifactKey(sessionId) {
|
|
3
|
+
return `session-summary:${sessionId}`;
|
|
4
|
+
}
|
|
5
|
+
export function buildCliProjectSummaryArtifactKey(projectPath) {
|
|
6
|
+
return `project-summary:${projectPath}`;
|
|
7
|
+
}
|
|
8
|
+
export function buildCliPlanSummaryArtifactKey(projectPath, task, maxTaskShapeLength = 80) {
|
|
9
|
+
return `plan-summary:${projectPath}:${normalizeTaskShapeKey(task, maxTaskShapeLength)}`;
|
|
10
|
+
}
|
|
11
|
+
export function buildCliPlanSummaryArtifactKeyFromShape(projectPath, taskShape) {
|
|
12
|
+
return `plan-summary:${projectPath}:${taskShape}`;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=context-artifact-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-artifact-keys.js","sourceRoot":"","sources":["../../src/application/context-artifact-keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,UAAU,iCAAiC,CAAC,SAAiB;IACjE,OAAO,mBAAmB,SAAS,EAAE,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,iCAAiC,CAAC,WAAmB;IACnE,OAAO,mBAAmB,WAAW,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,WAAmB,EACnB,IAAY,EACZ,kBAAkB,GAAG,EAAE;IAEvB,OAAO,gBAAgB,WAAW,IAAI,qBAAqB,CAAC,IAAI,EAAE,kBAAkB,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,uCAAuC,CACrD,WAAmB,EACnB,SAAiB;IAEjB,OAAO,gBAAgB,WAAW,IAAI,SAAS,EAAE,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ProjectedContext } from "./context-types.js";
|
|
2
|
+
import type { KilnPermissionPolicy } from "../wrapper/session.js";
|
|
3
|
+
import type { SessionContext } from "../wrapper/index.js";
|
|
4
|
+
export declare function governProjectedContext(projectedContext: ProjectedContext, permissionPolicy: KilnPermissionPolicy): ProjectedContext;
|
|
5
|
+
export declare function governSessionContext(context: SessionContext, permissionPolicy: KilnPermissionPolicy): SessionContext;
|
|
6
|
+
//# sourceMappingURL=context-governance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-governance.d.ts","sourceRoot":"","sources":["../../src/application/context-governance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,wBAAgB,sBAAsB,CACpC,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,oBAAoB,GACrC,gBAAgB,CAalB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,EACvB,gBAAgB,EAAE,oBAAoB,GACrC,cAAc,CAKhB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function governProjectedContext(projectedContext, permissionPolicy) {
|
|
2
|
+
if (permissionPolicy.fileGovernance?.excludeFromContext !== true) {
|
|
3
|
+
return projectedContext;
|
|
4
|
+
}
|
|
5
|
+
const blocks = projectedContext.blocks.filter((block) => block.kind !== "memory");
|
|
6
|
+
return {
|
|
7
|
+
blocks,
|
|
8
|
+
estimatedTokens: blocks.reduce((total, block) => total + (block.estimatedTokens ?? 0), 0),
|
|
9
|
+
tokenBudget: projectedContext.tokenBudget,
|
|
10
|
+
deferredBlocks: projectedContext.deferredBlocks?.filter((block) => block.kind !== "memory"),
|
|
11
|
+
overflow: projectedContext.overflow,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function governSessionContext(context, permissionPolicy) {
|
|
15
|
+
return {
|
|
16
|
+
...context,
|
|
17
|
+
projectedContext: governProjectedContext(context.projectedContext, permissionPolicy),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=context-governance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-governance.js","sourceRoot":"","sources":["../../src/application/context-governance.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,sBAAsB,CACpC,gBAAkC,EAClC,gBAAsC;IAEtC,IAAI,gBAAgB,CAAC,cAAc,EAAE,kBAAkB,KAAK,IAAI,EAAE,CAAC;QACjE,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAClF,OAAO;QACL,MAAM;QACN,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QACzF,WAAW,EAAE,gBAAgB,CAAC,WAAW;QACzC,cAAc,EAAE,gBAAgB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;QAC3F,QAAQ,EAAE,gBAAgB,CAAC,QAAQ;KACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,OAAuB,EACvB,gBAAsC;IAEtC,OAAO;QACL,GAAG,OAAO;QACV,gBAAgB,EAAE,sBAAsB,CAAC,OAAO,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;KACrF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ContextArtifactCache } from "@kilnai/core";
|
|
2
|
+
import type { ProjectedContext } from "./context-types.js";
|
|
3
|
+
import type { SessionLedger } from "./session-ledger.js";
|
|
4
|
+
import type { KilnContextGovernanceAggressiveness, KilnContextGovernanceSource } from "../kiln-yaml-types.js";
|
|
5
|
+
export interface ProjectContextInput {
|
|
6
|
+
readonly memorySnapshot?: string;
|
|
7
|
+
readonly sessionLedger?: SessionLedger;
|
|
8
|
+
readonly exactArtifacts?: readonly string[];
|
|
9
|
+
readonly cache?: ContextArtifactCache;
|
|
10
|
+
readonly moduleArtifactKeys?: readonly string[];
|
|
11
|
+
readonly projectArtifactKey?: string;
|
|
12
|
+
readonly planArtifactKey?: string;
|
|
13
|
+
readonly sessionArtifactKey?: string;
|
|
14
|
+
readonly tokenBudget?: number;
|
|
15
|
+
readonly preferredSources?: readonly KilnContextGovernanceSource[];
|
|
16
|
+
readonly summaryAggressiveness?: KilnContextGovernanceAggressiveness;
|
|
17
|
+
}
|
|
18
|
+
export interface ContextGovernor {
|
|
19
|
+
project(input: ProjectContextInput): ProjectedContext;
|
|
20
|
+
}
|
|
21
|
+
export declare const DEFAULT_PROJECTED_CONTEXT_TOKEN_BUDGET = 2000;
|
|
22
|
+
export declare const DEFAULT_SESSION_ARTIFACT_TTL_MS: number;
|
|
23
|
+
export declare class DefaultContextGovernor implements ContextGovernor {
|
|
24
|
+
project(input: ProjectContextInput): ProjectedContext;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=context-governor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-governor.d.ts","sourceRoot":"","sources":["../../src/application/context-governor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAA0B,MAAM,cAAc,CAAC;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAyB,MAAM,oBAAoB,CAAC;AAElF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EACV,mCAAmC,EACnC,2BAA2B,EAC5B,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,2BAA2B,EAAE,CAAC;IACnE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,mCAAmC,CAAC;CACtE;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,KAAK,EAAE,mBAAmB,GAAG,gBAAgB,CAAC;CACvD;AAED,eAAO,MAAM,sCAAsC,OAAO,CAAC;AAC3D,eAAO,MAAM,+BAA+B,QAAsB,CAAC;AA0CnE,qBAAa,sBAAuB,YAAW,eAAe;IAC5D,OAAO,CAAC,KAAK,EAAE,mBAAmB,GAAG,gBAAgB;CAkItD"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { getFieldStrength, selectContextWithinBudget } from "@kilnai/core";
|
|
2
|
+
import { estimateTextTokens } from "./context-types.js";
|
|
3
|
+
import { renderSessionLedger } from "./session-ledger.js";
|
|
4
|
+
export const DEFAULT_PROJECTED_CONTEXT_TOKEN_BUDGET = 2000;
|
|
5
|
+
export const DEFAULT_SESSION_ARTIFACT_TTL_MS = 1000 * 60 * 60 * 12;
|
|
6
|
+
const PREFERRED_SOURCE_SCORE_BONUS = 0.2;
|
|
7
|
+
const FIELD_CATEGORY_BONUS = 0.35;
|
|
8
|
+
const SUMMARY_AGGRESSIVENESS_ADJUSTMENTS = {
|
|
9
|
+
low: { summaryBonus: -0.08, artifactPenalty: 0 },
|
|
10
|
+
medium: { summaryBonus: 0, artifactPenalty: 0 },
|
|
11
|
+
high: { summaryBonus: 0.12, artifactPenalty: -0.08 },
|
|
12
|
+
};
|
|
13
|
+
function classifyGovernanceSource(block) {
|
|
14
|
+
switch (block.kind) {
|
|
15
|
+
case "ledger":
|
|
16
|
+
return "ledger";
|
|
17
|
+
case "artifact":
|
|
18
|
+
return "artifact";
|
|
19
|
+
case "summary":
|
|
20
|
+
return "summary";
|
|
21
|
+
case "memory":
|
|
22
|
+
return "memory";
|
|
23
|
+
case "knowledge":
|
|
24
|
+
return "knowledge";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function mapBlockToFieldCategory(block) {
|
|
28
|
+
return `category:${block.kind}`;
|
|
29
|
+
}
|
|
30
|
+
function applySummaryAggressiveness(block, aggressiveness) {
|
|
31
|
+
const adjustment = SUMMARY_AGGRESSIVENESS_ADJUSTMENTS[aggressiveness];
|
|
32
|
+
if (block.required)
|
|
33
|
+
return 0;
|
|
34
|
+
if (block.kind === "summary")
|
|
35
|
+
return adjustment.summaryBonus;
|
|
36
|
+
if (block.kind === "artifact")
|
|
37
|
+
return adjustment.artifactPenalty;
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
export class DefaultContextGovernor {
|
|
41
|
+
project(input) {
|
|
42
|
+
const blocks = [];
|
|
43
|
+
for (const [index, key] of (input.moduleArtifactKeys ?? []).entries()) {
|
|
44
|
+
const cachedModuleSummary = input.cache?.get(key);
|
|
45
|
+
if (cachedModuleSummary && cachedModuleSummary.content.trim() !== "") {
|
|
46
|
+
blocks.push({
|
|
47
|
+
id: `summary:cached-module:${index}`,
|
|
48
|
+
kind: "summary",
|
|
49
|
+
source: "context-artifact-cache",
|
|
50
|
+
content: cachedModuleSummary.content,
|
|
51
|
+
required: false,
|
|
52
|
+
score: 0.78,
|
|
53
|
+
estimatedTokens: estimateTextTokens(cachedModuleSummary.content),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const cachedPlanSummary = input.planArtifactKey && input.cache
|
|
58
|
+
? input.cache.get(input.planArtifactKey)
|
|
59
|
+
: undefined;
|
|
60
|
+
if (cachedPlanSummary && cachedPlanSummary.content.trim() !== "") {
|
|
61
|
+
blocks.push({
|
|
62
|
+
id: "summary:cached-plan",
|
|
63
|
+
kind: "summary",
|
|
64
|
+
source: "context-artifact-cache",
|
|
65
|
+
content: cachedPlanSummary.content,
|
|
66
|
+
required: false,
|
|
67
|
+
score: 0.85,
|
|
68
|
+
estimatedTokens: estimateTextTokens(cachedPlanSummary.content),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const cachedProjectSummary = input.projectArtifactKey && input.cache
|
|
72
|
+
? input.cache.get(input.projectArtifactKey)
|
|
73
|
+
: undefined;
|
|
74
|
+
if (cachedProjectSummary && cachedProjectSummary.content.trim() !== "") {
|
|
75
|
+
blocks.push({
|
|
76
|
+
id: "summary:cached-project",
|
|
77
|
+
kind: "summary",
|
|
78
|
+
source: "context-artifact-cache",
|
|
79
|
+
content: cachedProjectSummary.content,
|
|
80
|
+
required: false,
|
|
81
|
+
score: 0.75,
|
|
82
|
+
estimatedTokens: estimateTextTokens(cachedProjectSummary.content),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const cachedSummary = input.sessionArtifactKey && input.cache
|
|
86
|
+
? input.cache.get(input.sessionArtifactKey)
|
|
87
|
+
: undefined;
|
|
88
|
+
if (cachedSummary && cachedSummary.content.trim() !== "") {
|
|
89
|
+
blocks.push({
|
|
90
|
+
id: "summary:cached-session",
|
|
91
|
+
kind: "summary",
|
|
92
|
+
source: "context-artifact-cache",
|
|
93
|
+
content: cachedSummary.content,
|
|
94
|
+
required: false,
|
|
95
|
+
score: 0.8,
|
|
96
|
+
estimatedTokens: estimateTextTokens(cachedSummary.content),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const renderedLedger = input.sessionLedger ? renderSessionLedger(input.sessionLedger) : undefined;
|
|
100
|
+
if (renderedLedger) {
|
|
101
|
+
blocks.push({
|
|
102
|
+
id: "ledger:session",
|
|
103
|
+
kind: "ledger",
|
|
104
|
+
source: "session-ledger",
|
|
105
|
+
content: renderedLedger,
|
|
106
|
+
required: true,
|
|
107
|
+
score: 1,
|
|
108
|
+
estimatedTokens: estimateTextTokens(renderedLedger),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
for (const [index, artifact] of (input.exactArtifacts ?? []).entries()) {
|
|
112
|
+
if (artifact.trim() === "")
|
|
113
|
+
continue;
|
|
114
|
+
blocks.push({
|
|
115
|
+
id: `artifact:${index}`,
|
|
116
|
+
kind: "artifact",
|
|
117
|
+
source: "session-artifact",
|
|
118
|
+
content: artifact,
|
|
119
|
+
required: true,
|
|
120
|
+
score: 0.95,
|
|
121
|
+
estimatedTokens: estimateTextTokens(artifact),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (input.memorySnapshot && input.memorySnapshot.trim() !== "") {
|
|
125
|
+
blocks.push({
|
|
126
|
+
id: "memory:snapshot",
|
|
127
|
+
kind: "memory",
|
|
128
|
+
source: "session-memory-snapshot",
|
|
129
|
+
content: input.memorySnapshot,
|
|
130
|
+
required: false,
|
|
131
|
+
score: 0.6,
|
|
132
|
+
estimatedTokens: estimateTextTokens(input.memorySnapshot),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
const tokenBudget = input.tokenBudget ?? DEFAULT_PROJECTED_CONTEXT_TOKEN_BUDGET;
|
|
136
|
+
const preferredSources = new Set(input.preferredSources ?? []);
|
|
137
|
+
const summaryAggressiveness = input.summaryAggressiveness ?? "medium";
|
|
138
|
+
const candidates = blocks.map((block) => {
|
|
139
|
+
const preferredBonus = preferredSources.has(classifyGovernanceSource(block))
|
|
140
|
+
? PREFERRED_SOURCE_SCORE_BONUS
|
|
141
|
+
: 0;
|
|
142
|
+
const summaryAdjustment = applySummaryAggressiveness(block, summaryAggressiveness);
|
|
143
|
+
const fieldBoost = FIELD_CATEGORY_BONUS * getFieldStrength(mapBlockToFieldCategory(block));
|
|
144
|
+
return {
|
|
145
|
+
id: block.id,
|
|
146
|
+
required: block.required,
|
|
147
|
+
estimatedTokens: block.estimatedTokens ?? estimateTextTokens(block.content),
|
|
148
|
+
score: block.score + preferredBonus + summaryAdjustment + fieldBoost,
|
|
149
|
+
meta: block,
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
const selection = selectContextWithinBudget(candidates, tokenBudget);
|
|
153
|
+
const selectedBlocks = selection.selected.map((candidate) => candidate.meta);
|
|
154
|
+
const deferredBlocks = selection.deferred.map((candidate) => candidate.meta);
|
|
155
|
+
return {
|
|
156
|
+
blocks: selectedBlocks,
|
|
157
|
+
estimatedTokens: selection.selectedTokens,
|
|
158
|
+
tokenBudget,
|
|
159
|
+
deferredBlocks,
|
|
160
|
+
overflow: selection.overflow,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=context-governor.js.map
|