@cruxy/cli 1.0.2 → 1.0.4
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/dist/agent/loop.js +3 -0
- package/dist/agent/session.js +2 -1
- package/dist/theme/tokens.js +3 -0
- package/dist/usage/collect.js +41 -2
- package/dist/usage/index.js +1 -1
- package/dist/usage/summary.js +19 -0
- package/dist/usage/types.js +9 -0
- package/package.json +1 -1
- package/dist/agent/budget.d.ts +0 -52
- package/dist/agent/index.d.ts +0 -3
- package/dist/agent/loop.d.ts +0 -159
- package/dist/agent/prompts.d.ts +0 -69
- package/dist/agent/session.d.ts +0 -212
- package/dist/approval/classify.d.ts +0 -18
- package/dist/approval/index.d.ts +0 -6
- package/dist/approval/mutex.d.ts +0 -45
- package/dist/approval/policy.d.ts +0 -43
- package/dist/approval/prompt.d.ts +0 -48
- package/dist/approval/service.d.ts +0 -36
- package/dist/approval/types.d.ts +0 -82
- package/dist/brand/index.d.ts +0 -1
- package/dist/brand/voice.d.ts +0 -94
- package/dist/checkpoint/capture.d.ts +0 -17
- package/dist/checkpoint/gate-hook.d.ts +0 -28
- package/dist/checkpoint/gate.d.ts +0 -71
- package/dist/checkpoint/git-store.d.ts +0 -61
- package/dist/checkpoint/index.d.ts +0 -10
- package/dist/checkpoint/restore.d.ts +0 -23
- package/dist/checkpoint/service.d.ts +0 -89
- package/dist/checkpoint/set-rollback.d.ts +0 -51
- package/dist/checkpoint/set.d.ts +0 -44
- package/dist/checkpoint/shadow-store.d.ts +0 -23
- package/dist/checkpoint/types.d.ts +0 -164
- package/dist/cli/commands/checkpoint.d.ts +0 -7
- package/dist/cli/commands/config.d.ts +0 -2
- package/dist/cli/commands/hooks.d.ts +0 -8
- package/dist/cli/commands/index.d.ts +0 -7
- package/dist/cli/commands/init.d.ts +0 -7
- package/dist/cli/commands/login.d.ts +0 -8
- package/dist/cli/commands/mcp.d.ts +0 -9
- package/dist/cli/commands/memory.d.ts +0 -8
- package/dist/cli/commands/pr.d.ts +0 -8
- package/dist/cli/commands/rollback.d.ts +0 -18
- package/dist/cli/commands/run.d.ts +0 -2
- package/dist/cli/commands/skills.d.ts +0 -8
- package/dist/cli/commands/test.d.ts +0 -9
- package/dist/cli/commands/usage.d.ts +0 -9
- package/dist/cli/onboard.d.ts +0 -25
- package/dist/cli/program.d.ts +0 -2
- package/dist/cli/repl.d.ts +0 -27
- package/dist/cli/session-factory.d.ts +0 -42
- package/dist/cli/stream-print.d.ts +0 -14
- package/dist/components/autocomplete.d.ts +0 -32
- package/dist/components/frame.d.ts +0 -28
- package/dist/components/fuzzy.d.ts +0 -61
- package/dist/components/index.d.ts +0 -6
- package/dist/components/input.d.ts +0 -78
- package/dist/components/keys.d.ts +0 -48
- package/dist/components/select.d.ts +0 -28
- package/dist/config/credentials.d.ts +0 -18
- package/dist/config/index.d.ts +0 -5
- package/dist/config/manager.d.ts +0 -39
- package/dist/config/owner-only.d.ts +0 -19
- package/dist/config/paths.d.ts +0 -9
- package/dist/config/project.d.ts +0 -10
- package/dist/config/schema.d.ts +0 -2143
- package/dist/constants.d.ts +0 -65
- package/dist/errors/boundary.d.ts +0 -43
- package/dist/errors/constructors.d.ts +0 -411
- package/dist/errors/format.d.ts +0 -31
- package/dist/errors/index.d.ts +0 -4
- package/dist/errors/types.d.ts +0 -270
- package/dist/hooks/config.d.ts +0 -21
- package/dist/hooks/index.d.ts +0 -7
- package/dist/hooks/router.d.ts +0 -58
- package/dist/hooks/runner.d.ts +0 -88
- package/dist/hooks/service.d.ts +0 -38
- package/dist/hooks/slash.d.ts +0 -48
- package/dist/hooks/trust.d.ts +0 -46
- package/dist/hooks/types.d.ts +0 -147
- package/dist/index.d.ts +0 -2
- package/dist/indexing/chunker.d.ts +0 -28
- package/dist/indexing/embedder.d.ts +0 -98
- package/dist/indexing/index.d.ts +0 -9
- package/dist/indexing/indexer.d.ts +0 -45
- package/dist/indexing/retriever.d.ts +0 -61
- package/dist/indexing/service.d.ts +0 -49
- package/dist/indexing/store.d.ts +0 -103
- package/dist/indexing/types.d.ts +0 -78
- package/dist/indexing/util.d.ts +0 -34
- package/dist/indexing/walker.d.ts +0 -53
- package/dist/jobs/approval-queue.d.ts +0 -85
- package/dist/jobs/dispatch-tool.d.ts +0 -34
- package/dist/jobs/index.d.ts +0 -6
- package/dist/jobs/log-buffer.d.ts +0 -31
- package/dist/jobs/log-renderer.d.ts +0 -32
- package/dist/jobs/manager.d.ts +0 -139
- package/dist/jobs/types.d.ts +0 -81
- package/dist/lsp/client.d.ts +0 -25
- package/dist/lsp/index.d.ts +0 -8
- package/dist/lsp/pool.d.ts +0 -48
- package/dist/lsp/registry.d.ts +0 -38
- package/dist/lsp/server.d.ts +0 -48
- package/dist/lsp/service.d.ts +0 -44
- package/dist/lsp/tools/common.d.ts +0 -50
- package/dist/lsp/tools/find-definition.d.ts +0 -23
- package/dist/lsp/tools/find-references.d.ts +0 -23
- package/dist/lsp/tools/get-diagnostics.d.ts +0 -17
- package/dist/lsp/tools/hover.d.ts +0 -23
- package/dist/lsp/tools/index.d.ts +0 -4
- package/dist/lsp/transport.d.ts +0 -39
- package/dist/lsp/types.d.ts +0 -107
- package/dist/mcp/adapter.d.ts +0 -44
- package/dist/mcp/bounds.d.ts +0 -35
- package/dist/mcp/client.d.ts +0 -19
- package/dist/mcp/demarcate.d.ts +0 -12
- package/dist/mcp/http-transport.d.ts +0 -89
- package/dist/mcp/index.d.ts +0 -12
- package/dist/mcp/service.d.ts +0 -71
- package/dist/mcp/sibling-banner.d.ts +0 -25
- package/dist/mcp/transport.d.ts +0 -30
- package/dist/mcp/trust-gate.d.ts +0 -59
- package/dist/mcp/trust.d.ts +0 -62
- package/dist/mcp/types.d.ts +0 -62
- package/dist/mcp/url-guard.d.ts +0 -48
- package/dist/memory/index.d.ts +0 -7
- package/dist/memory/recall.d.ts +0 -56
- package/dist/memory/remember-tool.d.ts +0 -28
- package/dist/memory/secrets.d.ts +0 -29
- package/dist/memory/service.d.ts +0 -92
- package/dist/memory/store.d.ts +0 -32
- package/dist/memory/trust.d.ts +0 -52
- package/dist/memory/types.d.ts +0 -101
- package/dist/net/ip-guard.d.ts +0 -55
- package/dist/onboarding/detect.d.ts +0 -26
- package/dist/onboarding/flow.d.ts +0 -28
- package/dist/onboarding/index.d.ts +0 -5
- package/dist/onboarding/io.d.ts +0 -9
- package/dist/onboarding/steps.d.ts +0 -17
- package/dist/onboarding/types.d.ts +0 -81
- package/dist/plan/approve.d.ts +0 -16
- package/dist/plan/execute.d.ts +0 -28
- package/dist/plan/index.d.ts +0 -7
- package/dist/plan/policy.d.ts +0 -26
- package/dist/plan/render.d.ts +0 -5
- package/dist/plan/service.d.ts +0 -58
- package/dist/plan/submit-plan.d.ts +0 -33
- package/dist/plan/types.d.ts +0 -60
- package/dist/render/capabilities.d.ts +0 -31
- package/dist/render/diff.d.ts +0 -18
- package/dist/render/highlight.d.ts +0 -47
- package/dist/render/index.d.ts +0 -22
- package/dist/render/layout.d.ts +0 -59
- package/dist/render/motion.d.ts +0 -76
- package/dist/render/plain-renderer.d.ts +0 -39
- package/dist/render/resize.d.ts +0 -36
- package/dist/render/screen-reader-renderer.d.ts +0 -45
- package/dist/render/state.d.ts +0 -49
- package/dist/render/tty-renderer.d.ts +0 -106
- package/dist/render/types.d.ts +0 -201
- package/dist/routing/index.d.ts +0 -2
- package/dist/routing/resolve.d.ts +0 -17
- package/dist/routing/router.d.ts +0 -47
- package/dist/routing/types.d.ts +0 -42
- package/dist/sandbox/detect.d.ts +0 -22
- package/dist/sandbox/docker-runtime.d.ts +0 -32
- package/dist/sandbox/index.d.ts +0 -7
- package/dist/sandbox/policy.d.ts +0 -26
- package/dist/sandbox/service.d.ts +0 -64
- package/dist/sandbox/types.d.ts +0 -123
- package/dist/skills/index.d.ts +0 -4
- package/dist/skills/loader.d.ts +0 -43
- package/dist/skills/parser.d.ts +0 -31
- package/dist/skills/service.d.ts +0 -41
- package/dist/skills/types.d.ts +0 -94
- package/dist/subagent/index.d.ts +0 -5
- package/dist/subagent/orchestrator.d.ts +0 -169
- package/dist/subagent/registry-scope.d.ts +0 -41
- package/dist/subagent/semaphore.d.ts +0 -56
- package/dist/subagent/spawn-tool.d.ts +0 -86
- package/dist/subagent/types.d.ts +0 -65
- package/dist/testing/detect.d.ts +0 -3
- package/dist/testing/index.d.ts +0 -5
- package/dist/testing/parse.d.ts +0 -33
- package/dist/testing/run-tests-tool.d.ts +0 -64
- package/dist/testing/runner.d.ts +0 -26
- package/dist/testing/sandbox-runner.d.ts +0 -16
- package/dist/testing/types.d.ts +0 -66
- package/dist/theme/index.d.ts +0 -2
- package/dist/theme/resolve.d.ts +0 -43
- package/dist/theme/tokens.d.ts +0 -119
- package/dist/tools/create-pull-request.d.ts +0 -27
- package/dist/tools/file/apply-patch.d.ts +0 -94
- package/dist/tools/file/edit-file.d.ts +0 -12
- package/dist/tools/file/glob.d.ts +0 -17
- package/dist/tools/file/grep-files.d.ts +0 -43
- package/dist/tools/file/index.d.ts +0 -7
- package/dist/tools/file/match.d.ts +0 -43
- package/dist/tools/file/paths.d.ts +0 -160
- package/dist/tools/file/read-file.d.ts +0 -8
- package/dist/tools/file/write-file.d.ts +0 -10
- package/dist/tools/git-status.d.ts +0 -15
- package/dist/tools/index.d.ts +0 -9
- package/dist/tools/list-files.d.ts +0 -13
- package/dist/tools/list-skills.d.ts +0 -9
- package/dist/tools/load-skill.d.ts +0 -21
- package/dist/tools/registry.d.ts +0 -23
- package/dist/tools/search-codebase.d.ts +0 -35
- package/dist/tools/shell/exec.d.ts +0 -53
- package/dist/tools/shell/index.d.ts +0 -1
- package/dist/tools/shell/resolve-shell.d.ts +0 -81
- package/dist/tools/shell/run-command.d.ts +0 -14
- package/dist/tools/types.d.ts +0 -257
- package/dist/usage/collect.d.ts +0 -40
- package/dist/usage/cost.d.ts +0 -19
- package/dist/usage/index.d.ts +0 -15
- package/dist/usage/store.d.ts +0 -37
- package/dist/usage/summary.d.ts +0 -32
- package/dist/usage/types.d.ts +0 -220
- package/dist/utils/child-tree.d.ts +0 -33
- package/dist/utils/git.d.ts +0 -17
- package/dist/utils/logger.d.ts +0 -18
- package/dist/utils/process-tree.d.ts +0 -16
- package/dist/vcs/auth.d.ts +0 -22
- package/dist/vcs/generate.d.ts +0 -74
- package/dist/vcs/git.d.ts +0 -60
- package/dist/vcs/github.d.ts +0 -50
- package/dist/vcs/guidance.d.ts +0 -20
- package/dist/vcs/index.d.ts +0 -7
- package/dist/vcs/service.d.ts +0 -61
- package/dist/vcs/types.d.ts +0 -73
- package/dist/web/demarcate.d.ts +0 -13
- package/dist/web/fetch.d.ts +0 -11
- package/dist/web/index.d.ts +0 -7
- package/dist/web/provider.d.ts +0 -29
- package/dist/web/search.d.ts +0 -17
- package/dist/web/ssrf.d.ts +0 -41
- package/dist/web/tools.d.ts +0 -20
- package/dist/web/types.d.ts +0 -64
- package/dist/workspace/add-root.d.ts +0 -27
- package/dist/workspace/index.d.ts +0 -6
- package/dist/workspace/resolve.d.ts +0 -54
- package/dist/workspace/select.d.ts +0 -41
- package/dist/workspace/types.d.ts +0 -30
- package/dist/workspace/workspace.d.ts +0 -61
package/dist/agent/session.d.ts
DELETED
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import type { Message, Provider, Usage } from "@cruxy/sdk";
|
|
2
|
-
import type { CruxyConfig } from "../config/index.js";
|
|
3
|
-
import type { StreamRenderer } from "../render/index.js";
|
|
4
|
-
import { type Router } from "../routing/index.js";
|
|
5
|
-
import type { ToolContext } from "../tools/index.js";
|
|
6
|
-
import type { ToolRegistry } from "../tools/index.js";
|
|
7
|
-
import type { JobManager } from "../jobs/index.js";
|
|
8
|
-
import { type RequestUsage, type UsageRecord } from "../usage/index.js";
|
|
9
|
-
import { type AgentResult, type LifecycleHookRunner } from "./loop.js";
|
|
10
|
-
/**
|
|
11
|
-
* Plan-mode turn runner (C.31), injected so the agent package doesn't depend on
|
|
12
|
-
* the plan package. When plan mode is on, `send` delegates the whole turn to
|
|
13
|
-
* this instead of a single `runAgent` call. Receives the running history (with
|
|
14
|
-
* the user turn already appended) and returns the extended history to adopt.
|
|
15
|
-
*/
|
|
16
|
-
export type PlanRunner = (args: {
|
|
17
|
-
messages: Message[];
|
|
18
|
-
projectInstructions: string | null;
|
|
19
|
-
recalledMemory: string | null;
|
|
20
|
-
renderer?: StreamRenderer;
|
|
21
|
-
/** Usage telemetry (C.22): forwarded to every model request the plan-mode
|
|
22
|
-
* turn drives (propose + each execution step), so plan runs are attributed
|
|
23
|
-
* exactly like a normal turn. */
|
|
24
|
-
onRequestUsage?: (req: RequestUsage) => void;
|
|
25
|
-
}) => Promise<AgentResult>;
|
|
26
|
-
export interface SessionArgs {
|
|
27
|
-
/** A constructed provider to stream from. */
|
|
28
|
-
provider: Provider;
|
|
29
|
-
/** The tool catalogue advertised to the model and dispatched against. */
|
|
30
|
-
registry: ToolRegistry;
|
|
31
|
-
/** Resolved CLI configuration. */
|
|
32
|
-
config: CruxyConfig;
|
|
33
|
-
/** Ambient capabilities handed to each tool. */
|
|
34
|
-
ctx: ToolContext;
|
|
35
|
-
/** Git context (branch + dirty), loaded at startup, for the system prompt. */
|
|
36
|
-
git?: {
|
|
37
|
-
branch: string;
|
|
38
|
-
dirty: boolean;
|
|
39
|
-
} | null;
|
|
40
|
-
/** Project instructions (e.g. CRUXY.md) folded into every turn's system prompt. */
|
|
41
|
-
projectInstructions?: string | null;
|
|
42
|
-
/**
|
|
43
|
-
* Persistent memory (C.29): the pre-rendered recall block, injected into every
|
|
44
|
-
* turn's system prompt as reference data. Built once at session start (user
|
|
45
|
-
* memory + trusted project memory); null when memory is off or empty. Fixed
|
|
46
|
-
* for the session — it does not re-read mid-session.
|
|
47
|
-
*/
|
|
48
|
-
recalledMemory?: string | null;
|
|
49
|
-
/** Start in plan mode (C.31). Toggleable at runtime via `setPlanMode`. */
|
|
50
|
-
planMode?: boolean;
|
|
51
|
-
/** The plan-mode turn runner; required for plan mode to actually engage. */
|
|
52
|
-
planRunner?: PlanRunner;
|
|
53
|
-
/**
|
|
54
|
-
* Lifecycle hooks (C.19). When set, `before-run` fires before each turn (a
|
|
55
|
-
* blocking failure — including an untrusted project — aborts the turn) and
|
|
56
|
-
* `after-run` fires after; the same runner is threaded into the agent loop for
|
|
57
|
-
* `before-tool`/`after-tool`/`on-file-change`.
|
|
58
|
-
*/
|
|
59
|
-
hooks?: LifecycleHookRunner;
|
|
60
|
-
/**
|
|
61
|
-
* Multi-model routing (C.30). When set, main turns route on `main-turn` and
|
|
62
|
-
* context compaction on `summarize`; omitted → the provider default (unchanged).
|
|
63
|
-
*/
|
|
64
|
-
router?: Router;
|
|
65
|
-
/**
|
|
66
|
-
* Usage telemetry sink (C.22): called once per `send` with that run's
|
|
67
|
-
* {@link UsageRecord} (real per-request usage, tier-attributed). The sink
|
|
68
|
-
* persists it locally — it never transmits. Omitted → no persistence.
|
|
69
|
-
*/
|
|
70
|
-
onRunUsage?: (record: UsageRecord) => void;
|
|
71
|
-
/**
|
|
72
|
-
* Session-scoped background jobs (C.28): the manager the `run_in_background`
|
|
73
|
-
* tool dispatches onto. Exposed on the session so the REPL can service pending
|
|
74
|
-
* job approvals between turns and drive `/jobs`/`/logs`/`/cancel`, and so
|
|
75
|
-
* `cruxy run` can cancel every live job on session exit. Present only when
|
|
76
|
-
* `jobs.enabled`; omitted → no background jobs (unchanged behaviour).
|
|
77
|
-
*/
|
|
78
|
-
jobs?: JobManager;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Estimate the token footprint of a message list with a cheap chars/4 heuristic
|
|
82
|
-
* — no tokenizer dependency. Good enough to decide *when* to compact; exact
|
|
83
|
-
* counts are deferred to a later phase. Counts only textual payload (block
|
|
84
|
-
* structure and role labels are negligible and ignored).
|
|
85
|
-
*/
|
|
86
|
-
export declare function estimateTokens(messages: Message[]): number;
|
|
87
|
-
/**
|
|
88
|
-
* Owns the state of one multi-turn conversation: the running message history and
|
|
89
|
-
* the usage accumulated across turns. Each `send` continues from the prior
|
|
90
|
-
* history (tool_use/tool_result blocks included) rather than starting cold.
|
|
91
|
-
*
|
|
92
|
-
* This is also the home for context compaction: before each turn the running
|
|
93
|
-
* history is measured and, if it crosses the configured threshold, its older
|
|
94
|
-
* prefix is summarized away so the conversation stays within the model's window.
|
|
95
|
-
* The system prompt lives in `runAgent`, never in `messages`, so compaction
|
|
96
|
-
* cannot touch it.
|
|
97
|
-
*/
|
|
98
|
-
export declare class Session {
|
|
99
|
-
/** The full running conversation, replaced with the extended history each turn. */
|
|
100
|
-
messages: Message[];
|
|
101
|
-
/** Token usage summed across every `send` (and every compaction) in this session. */
|
|
102
|
-
readonly usage: Usage;
|
|
103
|
-
/** Stable id for this session (C.22), so a run's usage record groups with the
|
|
104
|
-
* other runs of the same interactive session (`cruxy usage --session`). */
|
|
105
|
-
readonly sessionId: string;
|
|
106
|
-
/** The most recent run's usage record (C.22) — the one-shot path reads it to
|
|
107
|
-
* print the end-of-run summary. */
|
|
108
|
-
lastRun?: UsageRecord;
|
|
109
|
-
private readonly args;
|
|
110
|
-
/** Mutable so `/reload` can refresh CRUXY.md mid-session. */
|
|
111
|
-
private projectInstructions;
|
|
112
|
-
/** Mutable so `/plan` can toggle plan mode mid-session. */
|
|
113
|
-
private planMode;
|
|
114
|
-
constructor(args: SessionArgs);
|
|
115
|
-
/** The ambient tool capabilities (gate + sandbox + cwd/config). Exposed so a
|
|
116
|
-
* shell-bound custom slash command (C.19) runs through the SAME gated path. */
|
|
117
|
-
get toolContext(): ToolContext;
|
|
118
|
-
/** The background-job manager (C.28), or undefined when jobs are disabled.
|
|
119
|
-
* The REPL uses it to service paused-job approvals and drive `/jobs`; `cruxy
|
|
120
|
-
* run` uses it to cancel every live job on exit. */
|
|
121
|
-
get jobs(): JobManager | undefined;
|
|
122
|
-
/** Whether plan mode is currently on. */
|
|
123
|
-
getPlanMode(): boolean;
|
|
124
|
-
/**
|
|
125
|
-
* Toggle plan mode. Only takes effect when a `planRunner` was wired (built by
|
|
126
|
-
* the session factory); without one, plan mode stays off.
|
|
127
|
-
*/
|
|
128
|
-
setPlanMode(enabled: boolean): void;
|
|
129
|
-
/**
|
|
130
|
-
* Run one user turn: append the prompt, compact if the history has grown past
|
|
131
|
-
* the threshold, drive the agent loop over the full history, adopt the
|
|
132
|
-
* extended history, and accumulate usage. Returns the turn's `AgentResult`.
|
|
133
|
-
*
|
|
134
|
-
* `renderer`, when supplied, receives assistant text deltas and tool-call
|
|
135
|
-
* progress as they stream so the caller sees the turn live (see the REPL);
|
|
136
|
-
* history is unaffected.
|
|
137
|
-
*/
|
|
138
|
-
send(userPrompt: string, renderer?: StreamRenderer): Promise<AgentResult>;
|
|
139
|
-
/**
|
|
140
|
-
* Re-read project instructions (CRUXY.md / AGENTS.md) from the working
|
|
141
|
-
* directory so edits take effect without restarting. Returns the new text, or
|
|
142
|
-
* `null` if none is present. Backs the `/reload` command.
|
|
143
|
-
*/
|
|
144
|
-
reloadProjectInstructions(): string | null;
|
|
145
|
-
/** Drop the conversation history but keep the session (for `/clear`). */
|
|
146
|
-
clear(): void;
|
|
147
|
-
/**
|
|
148
|
-
* Compact `this.messages` only when it has grown past threshold, adopting the
|
|
149
|
-
* result. On success logs a one-line notice and returns the number of older
|
|
150
|
-
* messages folded into the summary; otherwise returns `null` (under threshold,
|
|
151
|
-
* nothing safe to cut, or summary failed).
|
|
152
|
-
*/
|
|
153
|
-
maybeCompact(onRequestUsage?: (req: RequestUsage) => void): Promise<number | null>;
|
|
154
|
-
/**
|
|
155
|
-
* The mid-loop compaction seam (build item 3) handed to {@link runAgent}: same
|
|
156
|
-
* threshold/cut/summarize path as {@link maybeCompact}, but over the loop's own
|
|
157
|
-
* running history rather than `this.messages` (the loop owns and adopts its
|
|
158
|
-
* copy). Reuses the exact machinery so no summarization logic is duplicated and
|
|
159
|
-
* the loop stays ignorant of it. Under threshold it returns the history
|
|
160
|
-
* unchanged — cheap, no model call.
|
|
161
|
-
*/
|
|
162
|
-
private compactLoopHistory;
|
|
163
|
-
/**
|
|
164
|
-
* Force compaction regardless of the threshold (backs `/compact`). Returns the
|
|
165
|
-
* number of older messages summarized, or `null` if there was nothing safe to
|
|
166
|
-
* cut or the summary call failed.
|
|
167
|
-
*/
|
|
168
|
-
compact(): Promise<number | null>;
|
|
169
|
-
/**
|
|
170
|
-
* Compact `messages` when its estimated footprint exceeds
|
|
171
|
-
* `compactThreshold * maxTokens`, else return it untouched. The estimate adds a
|
|
172
|
-
* fixed `reserveTokens` allowance for the system prompt and tool schemas that
|
|
173
|
-
* {@link estimateTokens} never sees (~4.5k+ tokens of real request payload), so
|
|
174
|
-
* the trigger reflects the actual request size rather than only the visible
|
|
175
|
-
* history — otherwise the loop can sit just under the visible threshold while
|
|
176
|
-
* the real request has already overrun the window. Logs a one-line notice on a
|
|
177
|
-
* successful compaction.
|
|
178
|
-
*/
|
|
179
|
-
private compactIfOverThreshold;
|
|
180
|
-
/**
|
|
181
|
-
* Find a clean cut, summarize the older prefix into a synthetic user/assistant
|
|
182
|
-
* pair, and splice it in front of the kept-recent messages. Best-effort: a
|
|
183
|
-
* failed summary call leaves the history untouched and reports `compacted:
|
|
184
|
-
* null` (fail open — losing compaction is degraded, not unsafe). Pure with
|
|
185
|
-
* respect to `this.messages`: it returns the new array for the caller to adopt
|
|
186
|
-
* (the loop and the session each own their own history), and only accumulates
|
|
187
|
-
* the summary's usage into the session total.
|
|
188
|
-
*/
|
|
189
|
-
private runCompaction;
|
|
190
|
-
/**
|
|
191
|
-
* Choose the boundary between the summarized prefix and the kept-recent tail.
|
|
192
|
-
*
|
|
193
|
-
* Tool-call integrity is the constraint: a `tool_use` (assistant) and its
|
|
194
|
-
* matching `tool_result` (the next user message) must never straddle the cut,
|
|
195
|
-
* or the next provider call breaks. A real user *prompt* (`role:"user"` with
|
|
196
|
-
* string content) only occurs at a completed turn boundary, where every prior
|
|
197
|
-
* tool exchange is already resolved — so the kept region must begin there. The
|
|
198
|
-
* synthetic compaction-summary user message is also string content, so a
|
|
199
|
-
* repeat compaction always finds at least the previous summary as a clean cut.
|
|
200
|
-
*
|
|
201
|
-
* Start from `length - keepRecentMessages` and walk *backwards* to the nearest
|
|
202
|
-
* such prompt: this keeps at least the recent floor and lands clean. Returns
|
|
203
|
-
* the cut index, or `null` if no safe boundary leaves a non-empty prefix
|
|
204
|
-
* (e.g. a single long in-progress turn — nothing safe to compact).
|
|
205
|
-
*/
|
|
206
|
-
private findCut;
|
|
207
|
-
/**
|
|
208
|
-
* Summarize a prefix via a standalone, tool-less provider call over a rendered
|
|
209
|
-
* transcript. Throws on a stream error or empty output so callers fail open.
|
|
210
|
-
*/
|
|
211
|
-
private summarize;
|
|
212
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { ApproveAction } from "../tools/types.js";
|
|
2
|
-
import type { ApprovalRequest } from "./types.js";
|
|
3
|
-
/**
|
|
4
|
-
* Classify a pending tool action into a {@link RiskTier} + a tight session
|
|
5
|
-
* {@link Scope}. The cardinal rule: **anything unrecognized is `destructive`**
|
|
6
|
-
* (most-restrictive) so a future/unknown action can never slip through as
|
|
7
|
-
* read-only or low-risk.
|
|
8
|
-
*/
|
|
9
|
-
export declare function classify(action: ApproveAction, cwd: string): ApprovalRequest;
|
|
10
|
-
/**
|
|
11
|
-
* Tokenize a command **only if** we can positively prove it is a single, simple
|
|
12
|
-
* invocation (the granted program plus plain args, no shell features). Returns
|
|
13
|
-
* the tokens, or `null` for anything we can't prove safe — deny-by-default. This
|
|
14
|
-
* is what makes a `git` session grant refuse `git push && rm -rf /`.
|
|
15
|
-
*/
|
|
16
|
-
export declare function commandTokens(command: string): string[] | null;
|
|
17
|
-
/** Is `target` the root itself or a descendant of it? (Also true if root is a file == target.) */
|
|
18
|
-
export declare function isInside(root: string, target: string): boolean;
|
package/dist/approval/index.d.ts
DELETED
package/dist/approval/mutex.d.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { ApprovalDecision } from "./types.js";
|
|
2
|
-
import type { ApproveAction } from "../tools/types.js";
|
|
3
|
-
/**
|
|
4
|
-
* The approval mutex (C.33, JC-C) — the spine of the concurrent-subagent safety
|
|
5
|
-
* model. Node is single-threaded, so the only hazard between parallel subagents
|
|
6
|
-
* is interleaving at `await` boundaries; the one resource they genuinely contend
|
|
7
|
-
* for is the interactive terminal (one prompt at a time) and the run's shared
|
|
8
|
-
* checkpoint state (one snapshot/set-write at a time). Serializing every
|
|
9
|
-
* *gated write* through this one lock resolves BOTH with a single mechanism:
|
|
10
|
-
*
|
|
11
|
-
* • **one prompt at a time** — a child blocked awaiting the user's keypress
|
|
12
|
-
* holds the lock, so no sibling can paint a second prompt over it (the
|
|
13
|
-
* keypress is always attributable to the one displayed prompt); and
|
|
14
|
-
* • **serialized gated writes** — the checkpoint hook (snapshot + per-root set
|
|
15
|
-
* member write) runs inside the same critical section, so two concurrent
|
|
16
|
-
* writes to disjoint roots can never race on `ensureCheckpoint`'s latch or
|
|
17
|
-
* the set manifest.
|
|
18
|
-
*
|
|
19
|
-
* It is a plain promise-chain serializer: `runExclusive(fn)` runs `fn` only
|
|
20
|
-
* after every previously-enqueued `fn` has settled. It is a LEAF lock — nothing
|
|
21
|
-
* is acquired while holding it except the terminal and the filesystem, neither
|
|
22
|
-
* of which waits on a subagent resource — so it cannot take part in a cycle
|
|
23
|
-
* (see the deadlock argument in the C.33 design doc).
|
|
24
|
-
*/
|
|
25
|
-
export declare class ApprovalMutex {
|
|
26
|
-
/** The settled-marker chain: always resolves (never rejects), so a rejecting
|
|
27
|
-
* critical section never wedges the queue for the next waiter. */
|
|
28
|
-
private tail;
|
|
29
|
-
/** Run `fn` in mutual exclusion with every other `runExclusive` on this mutex. */
|
|
30
|
-
runExclusive<T>(fn: () => Promise<T>): Promise<T>;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Wrap a fully-built gate (`ApprovalService.requestApproval` behind the C.32
|
|
34
|
-
* checkpoint hook) so that every gated action serializes through `mutex`.
|
|
35
|
-
*
|
|
36
|
-
* Every action that actually reaches the gate is a *mutation* — read-only tools
|
|
37
|
-
* never call `requestApproval` at all (see the ToolContext contract), so a
|
|
38
|
-
* parallel READ fan-out is already free of the lock and never stalls behind a
|
|
39
|
-
* sibling's pending prompt. The `read`-tier short-circuit below is therefore
|
|
40
|
-
* defensive belt-and-suspenders (mirroring `ApprovalService`'s own read check):
|
|
41
|
-
* if a read-classified action ever did flow here, it would bypass the spine
|
|
42
|
-
* rather than needlessly hold it. What the mutex serializes in practice is the
|
|
43
|
-
* mutating set — exactly the prompt + checkpoint work that must be one-at-a-time.
|
|
44
|
-
*/
|
|
45
|
-
export declare function serializeGate(gate: (action: ApproveAction) => Promise<ApprovalDecision>, mutex: ApprovalMutex, cwd: string): (action: ApproveAction) => Promise<ApprovalDecision>;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { type PromptIO } from "./prompt.js";
|
|
2
|
-
import type { ApprovalDecision, ApprovalPolicy, ApprovalRequest, Scope } from "./types.js";
|
|
3
|
-
/**
|
|
4
|
-
* The in-memory, per-session allowlist. Grants are **scoped** (a command prefix
|
|
5
|
-
* or a path subtree) and **tier-keyed** (a `mutate` grant can never cover a
|
|
6
|
-
* `destructive` action), **never blanket**, and **never persisted**. A new
|
|
7
|
-
* session ⇒ a new allowlist (it is owned by the per-session ApprovalService).
|
|
8
|
-
*/
|
|
9
|
-
export declare class SessionAllowlist {
|
|
10
|
-
private grants;
|
|
11
|
-
/** Record a session grant for `request`'s scope. No-op when nothing is safe to grant. */
|
|
12
|
-
grant(request: ApprovalRequest): void;
|
|
13
|
-
/** Does an existing grant cover `request`? Requires same tier **and** scope match. */
|
|
14
|
-
allows(request: ApprovalRequest): boolean;
|
|
15
|
-
clear(): void;
|
|
16
|
-
size(): number;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Whether `scope` covers `request`. Shell: the command must be *provably simple*
|
|
20
|
-
* ({@link commandTokens}) and its program token must equal the granted token —
|
|
21
|
-
* so a `git` grant never matches `git push && rm -rf /`. File: every target must
|
|
22
|
-
* resolve inside the granted subtree.
|
|
23
|
-
*
|
|
24
|
-
* Multi-repo (C.26): `shell-prefix`, `shell-exact`, and `mcp-tool` grants are
|
|
25
|
-
* additionally **bound to the root they were taken in** — the grant only covers a
|
|
26
|
-
* request whose `cwd` is the same root. So "allow `git` this session" in repo A
|
|
27
|
-
* never auto-approves `git` in repo B. `file-subtree` needs no such check: it is
|
|
28
|
-
* an absolute path, so a different root is already a different subtree.
|
|
29
|
-
*/
|
|
30
|
-
export declare function scopeCovers(scope: Exclude<Scope, {
|
|
31
|
-
kind: "none";
|
|
32
|
-
}>, request: ApprovalRequest): boolean;
|
|
33
|
-
/**
|
|
34
|
-
* The default policy: consult the allowlist, otherwise prompt. On "allow this
|
|
35
|
-
* session" it records the scoped grant; a rejection carries optional feedback
|
|
36
|
-
* back to the agent.
|
|
37
|
-
*/
|
|
38
|
-
export declare class InteractivePolicy implements ApprovalPolicy {
|
|
39
|
-
private readonly allowlist;
|
|
40
|
-
private readonly io;
|
|
41
|
-
constructor(allowlist: SessionAllowlist, io: PromptIO);
|
|
42
|
-
decide(request: ApprovalRequest): Promise<ApprovalDecision>;
|
|
43
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import type { ApprovalRequest } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* The interactive prompt: render a pending action (a real diff for file edits,
|
|
4
|
-
* the exact command + cwd for shell) and read a 4-way choice. Rendering is data
|
|
5
|
-
* → string so it's testable; color is gated on `io.color` (NO_COLOR / non-TTY
|
|
6
|
-
* aware). **Default-deny**: EOF / Ctrl-C / any unrecognized key → reject.
|
|
7
|
-
*
|
|
8
|
-
* Diff/preview rendering is the shared implementation in `render/diff.ts` —
|
|
9
|
-
* the streaming path and this prompt draw the same bytes for the same change.
|
|
10
|
-
*/
|
|
11
|
-
/** The four user choices (plus the implicit default-deny). */
|
|
12
|
-
export type PromptChoice = {
|
|
13
|
-
kind: "once";
|
|
14
|
-
} | {
|
|
15
|
-
kind: "session";
|
|
16
|
-
} | {
|
|
17
|
-
kind: "reject";
|
|
18
|
-
reason?: string;
|
|
19
|
-
} | {
|
|
20
|
-
kind: "instruct";
|
|
21
|
-
instruction: string;
|
|
22
|
-
};
|
|
23
|
-
/** I/O surface for the prompt — injectable so tests script the keys/lines. */
|
|
24
|
-
export interface PromptIO {
|
|
25
|
-
write(text: string): void;
|
|
26
|
-
/** Read a single keypress; resolves "" on EOF / Ctrl-C. */
|
|
27
|
-
readKey(): Promise<string>;
|
|
28
|
-
/** Read one line (no trailing newline); resolves "" on EOF. */
|
|
29
|
-
readLine(): Promise<string>;
|
|
30
|
-
/** Whether to emit ANSI color. */
|
|
31
|
-
color: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Terminal columns (U.12). Optional so every existing PromptIO literal is
|
|
34
|
-
* unchanged; when absent the render resolves the width itself. Threaded so a
|
|
35
|
-
* narrow prompt reflows the command and never truncates the risk marker.
|
|
36
|
-
*/
|
|
37
|
-
columns?: number;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Render the action, read one key, and map it to a {@link PromptChoice}. `n`/`t`
|
|
41
|
-
* read a follow-up line (reason / instruction). Anything else — including EOF —
|
|
42
|
-
* is a reject.
|
|
43
|
-
*/
|
|
44
|
-
export declare function promptForApproval(request: ApprovalRequest, io: PromptIO): Promise<PromptChoice>;
|
|
45
|
-
/** Render the full prompt block: header, detail (diff or command+cwd), choices. */
|
|
46
|
-
export declare function render(request: ApprovalRequest, color: boolean, columns?: number): string;
|
|
47
|
-
/** Build the real PromptIO: prompt to stderr, read keys/lines from stdin. */
|
|
48
|
-
export declare function defaultPromptIO(color: boolean): PromptIO;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { ApproveAction } from "../tools/types.js";
|
|
2
|
-
import { type PromptIO } from "./prompt.js";
|
|
3
|
-
import type { ApprovalDecision, ApprovalPolicy } from "./types.js";
|
|
4
|
-
/**
|
|
5
|
-
* The approval gate, called by the tool layer **before any side effect**. It
|
|
6
|
-
* classifies the action, lets read-only actions through, **throws
|
|
7
|
-
* CRUXY_E_APPROVAL_REQUIRED when it can't ask** (non-interactive — default-deny,
|
|
8
|
-
* never auto-approve), and otherwise defers to the policy. It owns the
|
|
9
|
-
* per-session allowlist, so a new service ⇒ a fresh session.
|
|
10
|
-
*/
|
|
11
|
-
export interface ApprovalServiceOptions {
|
|
12
|
-
/** Resolved project root the actions run in. */
|
|
13
|
-
cwd: string;
|
|
14
|
-
/** Whether cruxy can actually prompt (stdin is a TTY). */
|
|
15
|
-
interactive: boolean;
|
|
16
|
-
/** Override the decision policy (the seam — tests / a future CI policy). */
|
|
17
|
-
policy?: ApprovalPolicy;
|
|
18
|
-
/** Override the prompt I/O (tests script keys/lines). */
|
|
19
|
-
io?: PromptIO;
|
|
20
|
-
}
|
|
21
|
-
export declare class ApprovalService {
|
|
22
|
-
private readonly cwd;
|
|
23
|
-
private readonly interactive;
|
|
24
|
-
private readonly allowlist;
|
|
25
|
-
private readonly policy;
|
|
26
|
-
constructor(opts: ApprovalServiceOptions);
|
|
27
|
-
/**
|
|
28
|
-
* Decide whether `action` may proceed. Read-only ⇒ allow. Non-interactive ⇒
|
|
29
|
-
* throw {@link approvalRequired} (the U.5 error system, exit 10). Otherwise the
|
|
30
|
-
* policy prompts. A returned `{allow:false}` is a clean rejection (fed back to
|
|
31
|
-
* the agent), not an error.
|
|
32
|
-
*/
|
|
33
|
-
requestApproval(action: ApproveAction): Promise<ApprovalDecision>;
|
|
34
|
-
/** Clear all session grants (a fresh session). */
|
|
35
|
-
resetSession(): void;
|
|
36
|
-
}
|
package/dist/approval/types.d.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import type { ApproveAction } from "../tools/types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Types for the approval gate (U.3) — the security boundary between the agent
|
|
4
|
-
* and side-effecting actions. The gate is **default-deny**: no response means
|
|
5
|
-
* reject, never auto-approve.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Risk classification for a pending action. Friction is reserved for what's
|
|
9
|
-
* risky, so users don't rubber-stamp.
|
|
10
|
-
* - `read` — read-only, auto-allowed (read tools bypass the gate entirely).
|
|
11
|
-
* - `mutate` — reversible-ish mutation (file write/edit) → approve, normal style.
|
|
12
|
-
* - `destructive` — irreversible / high blast radius (shell, delete) → approve,
|
|
13
|
-
* visually distinct. **Unknown actions classify here.**
|
|
14
|
-
*/
|
|
15
|
-
export type RiskTier = "read" | "mutate" | "destructive";
|
|
16
|
-
/**
|
|
17
|
-
* The tight scope a session grant is keyed by. Never blanket.
|
|
18
|
-
* - `shell-prefix` — a command's leading program token (e.g. `git`); only ever
|
|
19
|
-
* matches commands we can *positively* prove are simple (no shell features).
|
|
20
|
-
* **Bound to `root`** (C.26): a `git` grant in repo A never covers `git` in B.
|
|
21
|
-
* - `shell-exact` — one exact command string, for `test` actions only (C.13):
|
|
22
|
-
* a grant covers re-runs of precisely that test command, nothing else.
|
|
23
|
-
* **Bound to `root`**: a `pnpm test` grant in A never covers B.
|
|
24
|
-
* - `file-subtree` — an absolute directory (or, under the root-cap, an exact
|
|
25
|
-
* file path); matches targets that resolve inside it. Inherently root-safe —
|
|
26
|
-
* different roots are different absolute subtrees, so it needs no `root` field.
|
|
27
|
-
* - `mcp-tool` — one exact MCP server+tool pair (C.27): a grant covers re-calls
|
|
28
|
-
* of precisely that tool on that server, and never any other MCP tool.
|
|
29
|
-
* **Bound to `root`**: the same server+tool in another root still prompts.
|
|
30
|
-
* - `none` — nothing safe to grant (e.g. a multi-file patch spanning the root).
|
|
31
|
-
*/
|
|
32
|
-
export type Scope = {
|
|
33
|
-
readonly kind: "shell-prefix";
|
|
34
|
-
readonly token: string;
|
|
35
|
-
readonly root: string;
|
|
36
|
-
} | {
|
|
37
|
-
readonly kind: "shell-exact";
|
|
38
|
-
readonly command: string;
|
|
39
|
-
readonly root: string;
|
|
40
|
-
} | {
|
|
41
|
-
readonly kind: "file-subtree";
|
|
42
|
-
readonly root: string;
|
|
43
|
-
} | {
|
|
44
|
-
readonly kind: "mcp-tool";
|
|
45
|
-
readonly server: string;
|
|
46
|
-
readonly tool: string;
|
|
47
|
-
readonly root: string;
|
|
48
|
-
} | {
|
|
49
|
-
readonly kind: "none";
|
|
50
|
-
};
|
|
51
|
-
/** A pending action, classified and ready to show / decide on. */
|
|
52
|
-
export interface ApprovalRequest {
|
|
53
|
-
/** The raw tool action (kind, path/command, preview). */
|
|
54
|
-
readonly action: ApproveAction;
|
|
55
|
-
/** Risk classification. */
|
|
56
|
-
readonly tier: RiskTier;
|
|
57
|
-
/** The tight scope a session grant would use. */
|
|
58
|
-
readonly scope: Scope;
|
|
59
|
-
/** One plain line describing the action (e.g. "run: git status"). */
|
|
60
|
-
readonly summary: string;
|
|
61
|
-
/** Absolute resolved target paths for file actions; `[]` for shell. */
|
|
62
|
-
readonly targets: readonly string[];
|
|
63
|
-
/** Resolved project root the action runs in (shown as the shell cwd). */
|
|
64
|
-
readonly cwd: string;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* The gate's verdict. On reject, `feedback` (if any) is fed back to the agent as
|
|
68
|
-
* the tool result so it can adapt — a rejection is data, not an error.
|
|
69
|
-
*/
|
|
70
|
-
export type ApprovalDecision = {
|
|
71
|
-
readonly allow: true;
|
|
72
|
-
} | {
|
|
73
|
-
readonly allow: false;
|
|
74
|
-
readonly feedback?: string;
|
|
75
|
-
};
|
|
76
|
-
/**
|
|
77
|
-
* Pluggable decision strategy — the seam. Only `InteractivePolicy` ships in U.3;
|
|
78
|
-
* a future non-interactive/CI policy slots in here without touching call sites.
|
|
79
|
-
*/
|
|
80
|
-
export interface ApprovalPolicy {
|
|
81
|
-
decide(request: ApprovalRequest): Promise<ApprovalDecision>;
|
|
82
|
-
}
|
package/dist/brand/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { CANONICAL_TERMS, FORBIDDEN_MODEL_NAMES, FORBIDDEN_TERMS, MODEL_NAME_PLACEHOLDER, MODEL_TIERS, PRODUCT_MASTHEAD, PRODUCT_NAME, PRODUCT_TAGLINE, scanForbidden, scrubModelNames, type ForbiddenTerm, type LexiconViolation, } from "./voice.js";
|
package/dist/brand/voice.d.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The cruxy brand voice (U.8) — a tiny living document, enforced by a test, not
|
|
3
|
-
* vibes. It centralizes the product name/tagline, the canonical lexicon, and the
|
|
4
|
-
* forbidden set (deprecated synonyms + the base-model gag) so every user-facing
|
|
5
|
-
* surface reads as one product. Presentation/copy only — nothing here changes
|
|
6
|
-
* behavior; the {@link scanForbidden} helper backs the lexicon test.
|
|
7
|
-
*
|
|
8
|
-
* Voice, in one breath: concise, direct, second-person for guidance,
|
|
9
|
-
* lowercase-leaning for status, no marketing fluff, no exclamation-spam. The
|
|
10
|
-
* product name is ALWAYS lowercase `cruxy`.
|
|
11
|
-
*/
|
|
12
|
-
/** The product name — always lowercase, in running text, banners, and help. */
|
|
13
|
-
export declare const PRODUCT_NAME = "cruxy";
|
|
14
|
-
/** The one-line tagline (mirrors package.json's description). */
|
|
15
|
-
export declare const PRODUCT_TAGLINE = "an agentic coding CLI";
|
|
16
|
-
/** The `cruxy --help` / banner masthead: `cruxy — an agentic coding CLI`. */
|
|
17
|
-
export declare const PRODUCT_MASTHEAD = "cruxy \u2014 an agentic coding CLI";
|
|
18
|
-
/**
|
|
19
|
-
* The ONLY model names cruxy ever shows a user. The upstream model powering a
|
|
20
|
-
* tier is never named — a hard rule asserted by the lexicon test.
|
|
21
|
-
*/
|
|
22
|
-
export declare const MODEL_TIERS: readonly ["kavi", "vaani", "mira"];
|
|
23
|
-
/**
|
|
24
|
-
* The canonical term for each concept — the words every surface must use.
|
|
25
|
-
* Documented here so the lexicon is reviewable in one place; the forbidden
|
|
26
|
-
* synonyms below are what the test actually enforces.
|
|
27
|
-
*/
|
|
28
|
-
export declare const CANONICAL_TERMS: {
|
|
29
|
-
readonly product: "cruxy";
|
|
30
|
-
readonly backend: "gateway";
|
|
31
|
-
readonly extension: "skill";
|
|
32
|
-
readonly lifecycleHook: "hook";
|
|
33
|
-
readonly undoUnit: "checkpoint";
|
|
34
|
-
readonly isolation: "sandbox";
|
|
35
|
-
readonly secret: "API key";
|
|
36
|
-
readonly pullRequest: "pull request";
|
|
37
|
-
readonly permission: "approval";
|
|
38
|
-
};
|
|
39
|
-
/** One deprecated/off-voice term the copy must not use, and what to use instead. */
|
|
40
|
-
export interface ForbiddenTerm {
|
|
41
|
-
/** Matches the forbidden term (word-bounded, case-insensitive). */
|
|
42
|
-
pattern: RegExp;
|
|
43
|
-
/** The forbidden term, for the failure message. */
|
|
44
|
-
term: string;
|
|
45
|
-
/** The canonical term to use instead. */
|
|
46
|
-
use: string;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Deprecated synonyms banned from user-facing copy. Scoped to the curated
|
|
50
|
-
* surfaces the lexicon test scans (command descriptions, error output, brand +
|
|
51
|
-
* onboarding constants) — NOT a raw source grep — so legitimate internal uses
|
|
52
|
-
* (`mcp.servers` config key, docker `.Server.Version`, code comments) never
|
|
53
|
-
* false-trip, while every string a user reads is covered.
|
|
54
|
-
*/
|
|
55
|
-
export declare const FORBIDDEN_TERMS: readonly ForbiddenTerm[];
|
|
56
|
-
/**
|
|
57
|
-
* Upstream model names — the base-model gag. None may appear in user-facing
|
|
58
|
-
* copy; only {@link MODEL_TIERS} ever do. `anthropic`/`openai` are deliberately
|
|
59
|
-
* absent: they are real bring-your-own-provider config values, not model names.
|
|
60
|
-
*/
|
|
61
|
-
export declare const FORBIDDEN_MODEL_NAMES: RegExp;
|
|
62
|
-
/** The neutral token an upstream model name is replaced with in user-facing copy. */
|
|
63
|
-
export declare const MODEL_NAME_PLACEHOLDER = "\u00ABmodel\u00BB";
|
|
64
|
-
/**
|
|
65
|
-
* Replace every upstream model IDENTIFIER in an arbitrary, externally-sourced
|
|
66
|
-
* string with {@link MODEL_NAME_PLACEHOLDER}, collapsing a whole `name-name-vers`
|
|
67
|
-
* run to a single token.
|
|
68
|
-
*
|
|
69
|
-
* The U.8 gag is structural *inside the process* (the routing package can't
|
|
70
|
-
* produce an upstream id — see `resolveModelId`), but a gateway/provider error
|
|
71
|
-
* body is an arbitrary external string that bypasses that guarantee. This is the
|
|
72
|
-
* scrub applied at the error-construction boundary so no upstream id reaches a
|
|
73
|
-
* user-facing `CruxyError.cause`.
|
|
74
|
-
*
|
|
75
|
-
* Scrubs model ids as whole TOKENS, never a bare vendor word or a substring
|
|
76
|
-
* inside an unrelated word/path — so legitimate output (`/home/claude`, the
|
|
77
|
-
* `opus` codec, a `claude-bot` username) is left intact (see {@link isModelId}).
|
|
78
|
-
* Provider names (`anthropic`/`openai`) are absent from the set, so bring-your-own
|
|
79
|
-
* provider config values survive too.
|
|
80
|
-
*/
|
|
81
|
-
export declare function scrubModelNames(text: string): string;
|
|
82
|
-
/** One lexicon violation found in a scanned string. */
|
|
83
|
-
export interface LexiconViolation {
|
|
84
|
-
/** The forbidden term (or "model-name" for a gag violation). */
|
|
85
|
-
term: string;
|
|
86
|
-
/** The canonical replacement, when the term is a deprecated synonym. */
|
|
87
|
-
use?: string;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Scan one user-facing string for lexicon violations — deprecated synonyms and
|
|
91
|
-
* upstream model names. Returns every violation (empty ⇒ on-voice). Pure; the
|
|
92
|
-
* lexicon test runs it over the curated surfaces.
|
|
93
|
-
*/
|
|
94
|
-
export declare function scanForbidden(text: string): LexiconViolation[];
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { CaptureFile } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Snapshot-scope enumeration (C.32): every regular file the agent could touch —
|
|
4
|
-
* tracked + untracked-non-ignored — and nothing it must never see:
|
|
5
|
-
* • gitignored paths (they are not the run's undo unit and may be huge),
|
|
6
|
-
* • the C.17 secrets denylist ({@link isSecretPath} — a checkpoint must never
|
|
7
|
-
* copy a secret into `.cruxy/` or the git object DB),
|
|
8
|
-
* • `.cruxy/` itself (a checkpoint of the checkpoints would recurse),
|
|
9
|
-
* • symlinks and other non-regular files (restore writes plain files only).
|
|
10
|
-
*
|
|
11
|
-
* In a git repo the file list comes from `git ls-files` (read-only), which
|
|
12
|
-
* honors `.gitignore`, `.git/info/exclude`, and the user's global excludes
|
|
13
|
-
* exactly. Outside a repo, the indexing walker enumerates with its gitignore
|
|
14
|
-
* emulation — with binaries included and no size cap, because a snapshot that
|
|
15
|
-
* skips files cannot restore them.
|
|
16
|
-
*/
|
|
17
|
-
export declare function captureFiles(root: string, gitWorkTree: boolean): Promise<CaptureFile[]>;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { ApprovalDecision } from "../approval/types.js";
|
|
2
|
-
import type { ApproveAction } from "../tools/types.js";
|
|
3
|
-
import type { Workspace } from "../workspace/index.js";
|
|
4
|
-
import type { CheckpointGate } from "./gate.js";
|
|
5
|
-
/**
|
|
6
|
-
* Wrap an approval gate with the C.32 auto-checkpoint hook. Ordering is the whole
|
|
7
|
-
* point: a tool mutates only *after* `requestApproval` resolves, so snapshotting
|
|
8
|
-
* after an `allow` decision but before returning it means the checkpoint always
|
|
9
|
-
* lands before the run's first mutation — and a denied action never creates one.
|
|
10
|
-
* The same seam records which paths the run touched (file actions) or that
|
|
11
|
-
* attribution is lost (shell), for rollback's external-change detection.
|
|
12
|
-
*
|
|
13
|
-
* Lives in the checkpoint package (not the CLI wiring) so the SAME hook can be
|
|
14
|
-
* composed by the session factory, the subagent orchestrator, AND the C.28 job
|
|
15
|
-
* approval path without any of them importing the others.
|
|
16
|
-
*/
|
|
17
|
-
export declare function withCheckpointGate(requestApproval: (action: ApproveAction) => Promise<ApprovalDecision>, gate: CheckpointGate | undefined, ws: Workspace): (action: ApproveAction) => Promise<ApprovalDecision>;
|
|
18
|
-
/**
|
|
19
|
-
* Group a file action's resolved absolute targets by the root that contains each
|
|
20
|
-
* (JC-G). write/edit carry an already-absolute `path`; patch preview paths are
|
|
21
|
-
* relative to the PRIMARY cwd (`path.relative(ctx.cwd, abs)` in apply_patch), so
|
|
22
|
-
* we reconstruct the absolute path from the primary root rather than trusting
|
|
23
|
-
* classify's `targets` — which also correctly handles a patch spanning roots.
|
|
24
|
-
*/
|
|
25
|
-
export declare function attributeFileTargets(action: ApproveAction, ws: Workspace): Map<string, {
|
|
26
|
-
rootAbsPath: string;
|
|
27
|
-
paths: string[];
|
|
28
|
-
}>;
|