@elhu/pit 0.1.1
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/LICENSE +21 -0
- package/README.md +380 -0
- package/dist/adapters/claude-code.d.ts +70 -0
- package/dist/adapters/claude-code.d.ts.map +1 -0
- package/dist/adapters/claude-code.js +166 -0
- package/dist/adapters/claude-code.js.map +1 -0
- package/dist/adapters/index.d.ts +16 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +49 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/opencode.d.ts +53 -0
- package/dist/adapters/opencode.d.ts.map +1 -0
- package/dist/adapters/opencode.js +120 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/process-utils.d.ts +29 -0
- package/dist/adapters/process-utils.d.ts.map +1 -0
- package/dist/adapters/process-utils.js +96 -0
- package/dist/adapters/process-utils.js.map +1 -0
- package/dist/adapters/types.d.ts +41 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +6 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/assets.generated.d.ts +13 -0
- package/dist/assets.generated.d.ts.map +1 -0
- package/dist/assets.generated.js +162 -0
- package/dist/assets.generated.js.map +1 -0
- package/dist/beads.d.ts +85 -0
- package/dist/beads.d.ts.map +1 -0
- package/dist/beads.js +120 -0
- package/dist/beads.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +39 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add.d.ts +10 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +58 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/cleanup.d.ts +13 -0
- package/dist/commands/cleanup.d.ts.map +1 -0
- package/dist/commands/cleanup.js +174 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/daemon.d.ts +3 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +162 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/init.d.ts +20 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +125 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/install-keybinding.d.ts +61 -0
- package/dist/commands/install-keybinding.d.ts.map +1 -0
- package/dist/commands/install-keybinding.js +138 -0
- package/dist/commands/install-keybinding.js.map +1 -0
- package/dist/commands/install-status.d.ts +35 -0
- package/dist/commands/install-status.d.ts.map +1 -0
- package/dist/commands/install-status.js +115 -0
- package/dist/commands/install-status.js.map +1 -0
- package/dist/commands/log.d.ts +7 -0
- package/dist/commands/log.d.ts.map +1 -0
- package/dist/commands/log.js +60 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/pause.d.ts +12 -0
- package/dist/commands/pause.d.ts.map +1 -0
- package/dist/commands/pause.js +47 -0
- package/dist/commands/pause.js.map +1 -0
- package/dist/commands/resume.d.ts +12 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +59 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/shared.d.ts +7 -0
- package/dist/commands/shared.d.ts.map +1 -0
- package/dist/commands/shared.js +56 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/start.d.ts +12 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +274 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +24 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +101 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +11 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +52 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/teardown.d.ts +15 -0
- package/dist/commands/teardown.d.ts.map +1 -0
- package/dist/commands/teardown.js +72 -0
- package/dist/commands/teardown.js.map +1 -0
- package/dist/config.d.ts +58 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +129 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon/client.d.ts +38 -0
- package/dist/daemon/client.d.ts.map +1 -0
- package/dist/daemon/client.js +254 -0
- package/dist/daemon/client.js.map +1 -0
- package/dist/daemon/context.d.ts +63 -0
- package/dist/daemon/context.d.ts.map +1 -0
- package/dist/daemon/context.js +14 -0
- package/dist/daemon/context.js.map +1 -0
- package/dist/daemon/handlers.d.ts +79 -0
- package/dist/daemon/handlers.d.ts.map +1 -0
- package/dist/daemon/handlers.js +1260 -0
- package/dist/daemon/handlers.js.map +1 -0
- package/dist/daemon/index.d.ts +6 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +7 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/lifecycle.d.ts +56 -0
- package/dist/daemon/lifecycle.d.ts.map +1 -0
- package/dist/daemon/lifecycle.js +341 -0
- package/dist/daemon/lifecycle.js.map +1 -0
- package/dist/daemon/protocol.d.ts +174 -0
- package/dist/daemon/protocol.d.ts.map +1 -0
- package/dist/daemon/protocol.js +3 -0
- package/dist/daemon/protocol.js.map +1 -0
- package/dist/daemon/recovery.d.ts +37 -0
- package/dist/daemon/recovery.d.ts.map +1 -0
- package/dist/daemon/recovery.js +197 -0
- package/dist/daemon/recovery.js.map +1 -0
- package/dist/daemon/server.d.ts +31 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +294 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/socket.d.ts +18 -0
- package/dist/daemon/socket.d.ts.map +1 -0
- package/dist/daemon/socket.js +36 -0
- package/dist/daemon/socket.js.map +1 -0
- package/dist/daemon/state.d.ts +60 -0
- package/dist/daemon/state.d.ts.map +1 -0
- package/dist/daemon/state.js +156 -0
- package/dist/daemon/state.js.map +1 -0
- package/dist/daemon/systemd.d.ts +19 -0
- package/dist/daemon/systemd.d.ts.map +1 -0
- package/dist/daemon/systemd.js +131 -0
- package/dist/daemon/systemd.js.map +1 -0
- package/dist/hooks/claude-code-hook.d.ts +32 -0
- package/dist/hooks/claude-code-hook.d.ts.map +1 -0
- package/dist/hooks/claude-code-hook.js +112 -0
- package/dist/hooks/claude-code-hook.js.map +1 -0
- package/dist/instructions-template.d.ts +9 -0
- package/dist/instructions-template.d.ts.map +1 -0
- package/dist/instructions-template.js +123 -0
- package/dist/instructions-template.js.map +1 -0
- package/dist/logger.d.ts +25 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +44 -0
- package/dist/logger.js.map +1 -0
- package/dist/loop.d.ts +88 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +161 -0
- package/dist/loop.js.map +1 -0
- package/dist/orchestrator-instructions-template.d.ts +13 -0
- package/dist/orchestrator-instructions-template.d.ts.map +1 -0
- package/dist/orchestrator-instructions-template.js +147 -0
- package/dist/orchestrator-instructions-template.js.map +1 -0
- package/dist/output.d.ts +12 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +25 -0
- package/dist/output.js.map +1 -0
- package/dist/plugin/pit.js +57 -0
- package/dist/session.d.ts +55 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +135 -0
- package/dist/session.js.map +1 -0
- package/dist/setup.d.ts +92 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +382 -0
- package/dist/setup.js.map +1 -0
- package/dist/shell-quote.d.ts +16 -0
- package/dist/shell-quote.d.ts.map +1 -0
- package/dist/shell-quote.js +18 -0
- package/dist/shell-quote.js.map +1 -0
- package/dist/signals.d.ts +17 -0
- package/dist/signals.d.ts.map +1 -0
- package/dist/signals.js +26 -0
- package/dist/signals.js.map +1 -0
- package/dist/state-machine.d.ts +74 -0
- package/dist/state-machine.d.ts.map +1 -0
- package/dist/state-machine.js +153 -0
- package/dist/state-machine.js.map +1 -0
- package/dist/tmux.d.ts +101 -0
- package/dist/tmux.d.ts.map +1 -0
- package/dist/tmux.js +208 -0
- package/dist/tmux.js.map +1 -0
- package/dist/worktree.d.ts +33 -0
- package/dist/worktree.d.ts.map +1 -0
- package/dist/worktree.js +116 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +66 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration module for pit.
|
|
3
|
+
*
|
|
4
|
+
* Reads .pit.json from the project root and merges with CLI flags and defaults.
|
|
5
|
+
* Exported for use by the daemon and CLI commands.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* User-facing configuration loaded from .pit.json.
|
|
9
|
+
* All fields are optional — missing fields fall back to DEFAULT_CONFIG.
|
|
10
|
+
*/
|
|
11
|
+
export interface PitConfig {
|
|
12
|
+
agent?: "auto" | "opencode" | "claude-code";
|
|
13
|
+
worktreeDir?: string;
|
|
14
|
+
baseBranch?: string;
|
|
15
|
+
tmuxSession?: string;
|
|
16
|
+
/** Inline prompt template string (NOT a file path). */
|
|
17
|
+
promptTemplate?: string;
|
|
18
|
+
/** Delay in ms before clearing agent context after ticket completion. */
|
|
19
|
+
clearDelay?: number;
|
|
20
|
+
/** Delay in ms before starting the agent after setup. */
|
|
21
|
+
initDelay?: number;
|
|
22
|
+
/** Ticket timeout in minutes, or null to disable. */
|
|
23
|
+
ticketTimeout?: number | null;
|
|
24
|
+
/** Model to use for the agent, or null to use agent default. */
|
|
25
|
+
model?: string | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Fully resolved configuration — every field is required (no optionals).
|
|
29
|
+
* Produced by resolveConfig() after merging CLI flags > file > defaults.
|
|
30
|
+
*/
|
|
31
|
+
export interface ResolvedConfig {
|
|
32
|
+
agent: "auto" | "opencode" | "claude-code";
|
|
33
|
+
worktreeDir: string;
|
|
34
|
+
baseBranch: string;
|
|
35
|
+
tmuxSession: string;
|
|
36
|
+
promptTemplate: string;
|
|
37
|
+
clearDelay: number;
|
|
38
|
+
initDelay: number;
|
|
39
|
+
ticketTimeout: number | null;
|
|
40
|
+
model: string | null;
|
|
41
|
+
}
|
|
42
|
+
export declare const DEFAULT_CONFIG: ResolvedConfig;
|
|
43
|
+
/**
|
|
44
|
+
* Load configuration from `<projectRoot>/.pit.json`.
|
|
45
|
+
*
|
|
46
|
+
* - Returns `{}` when the file is missing or unparseable (logs a warning).
|
|
47
|
+
* - Warns on unknown fields (typo detection).
|
|
48
|
+
* - Warns and drops fields with invalid types (uses default instead).
|
|
49
|
+
*/
|
|
50
|
+
export declare function loadPitConfig(projectRoot: string): PitConfig;
|
|
51
|
+
/**
|
|
52
|
+
* Three-tier merge: CLI flags > .pit.json values > DEFAULT_CONFIG.
|
|
53
|
+
*
|
|
54
|
+
* `cliFlags` should contain ONLY fields the user explicitly set on the CLI
|
|
55
|
+
* (use Commander's `command.getOptionValueSource(name) === 'cli'` to filter).
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveConfig(cliFlags: Partial<PitConfig>, fileConfig: PitConfig): ResolvedConfig;
|
|
58
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa,CAAC;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAMD,eAAO,MAAM,cAAc,EAAE,cAU5B,CAAC;AAyBF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAsD5D;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,SAAS,GAAG,cAAc,CAoBjG"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration module for pit.
|
|
3
|
+
*
|
|
4
|
+
* Reads .pit.json from the project root and merges with CLI flags and defaults.
|
|
5
|
+
* Exported for use by the daemon and CLI commands.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from "node:fs";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import { createLogger } from "./logger.js";
|
|
10
|
+
const logger = createLogger();
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Defaults
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
export const DEFAULT_CONFIG = {
|
|
15
|
+
agent: "auto",
|
|
16
|
+
worktreeDir: ".worktrees",
|
|
17
|
+
baseBranch: "main",
|
|
18
|
+
tmuxSession: "pit",
|
|
19
|
+
promptTemplate: "",
|
|
20
|
+
clearDelay: 2000,
|
|
21
|
+
initDelay: 5000,
|
|
22
|
+
ticketTimeout: null,
|
|
23
|
+
model: null,
|
|
24
|
+
};
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Field validators
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
const VALID_AGENTS = new Set(["auto", "opencode", "claude-code"]);
|
|
29
|
+
/** Map of field name → runtime type-check predicate. */
|
|
30
|
+
const FIELD_VALIDATORS = {
|
|
31
|
+
agent: (v) => typeof v === "string" && VALID_AGENTS.has(v),
|
|
32
|
+
worktreeDir: (v) => typeof v === "string",
|
|
33
|
+
baseBranch: (v) => typeof v === "string",
|
|
34
|
+
tmuxSession: (v) => typeof v === "string",
|
|
35
|
+
promptTemplate: (v) => typeof v === "string",
|
|
36
|
+
clearDelay: (v) => typeof v === "number" && Number.isFinite(v),
|
|
37
|
+
initDelay: (v) => typeof v === "number" && Number.isFinite(v),
|
|
38
|
+
ticketTimeout: (v) => v === null || (typeof v === "number" && Number.isFinite(v)),
|
|
39
|
+
model: (v) => v === null || typeof v === "string",
|
|
40
|
+
};
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// loadPitConfig
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
/**
|
|
45
|
+
* Load configuration from `<projectRoot>/.pit.json`.
|
|
46
|
+
*
|
|
47
|
+
* - Returns `{}` when the file is missing or unparseable (logs a warning).
|
|
48
|
+
* - Warns on unknown fields (typo detection).
|
|
49
|
+
* - Warns and drops fields with invalid types (uses default instead).
|
|
50
|
+
*/
|
|
51
|
+
export function loadPitConfig(projectRoot) {
|
|
52
|
+
const configPath = path.join(projectRoot, ".pit.json");
|
|
53
|
+
let raw;
|
|
54
|
+
try {
|
|
55
|
+
raw = fs.readFileSync(configPath, "utf8");
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// File missing — perfectly fine, return empty config.
|
|
59
|
+
return {};
|
|
60
|
+
}
|
|
61
|
+
let parsed;
|
|
62
|
+
try {
|
|
63
|
+
parsed = JSON.parse(raw);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
logger.warn("Failed to parse .pit.json", {
|
|
67
|
+
error: String(error),
|
|
68
|
+
configPath,
|
|
69
|
+
});
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
73
|
+
logger.warn(".pit.json must be a JSON object", { configPath });
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
const obj = parsed;
|
|
77
|
+
const knownKeys = new Set(Object.keys(FIELD_VALIDATORS));
|
|
78
|
+
const result = {};
|
|
79
|
+
// Warn on unknown fields
|
|
80
|
+
for (const key of Object.keys(obj)) {
|
|
81
|
+
if (!knownKeys.has(key)) {
|
|
82
|
+
logger.warn(`Unknown field in .pit.json: "${key}"`, { configPath });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Validate and pick known fields
|
|
86
|
+
for (const [key, validator] of Object.entries(FIELD_VALIDATORS)) {
|
|
87
|
+
const typedKey = key;
|
|
88
|
+
if (typedKey in obj) {
|
|
89
|
+
const value = obj[typedKey];
|
|
90
|
+
if (validator(value)) {
|
|
91
|
+
// Type assertion is safe — validator just confirmed the type.
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
93
|
+
result[typedKey] = value;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
logger.warn(`Invalid type for "${typedKey}" in .pit.json, ignoring`, { value, configPath });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// resolveConfig
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
/**
|
|
106
|
+
* Three-tier merge: CLI flags > .pit.json values > DEFAULT_CONFIG.
|
|
107
|
+
*
|
|
108
|
+
* `cliFlags` should contain ONLY fields the user explicitly set on the CLI
|
|
109
|
+
* (use Commander's `command.getOptionValueSource(name) === 'cli'` to filter).
|
|
110
|
+
*/
|
|
111
|
+
export function resolveConfig(cliFlags, fileConfig) {
|
|
112
|
+
const resolved = { ...DEFAULT_CONFIG };
|
|
113
|
+
// Layer 1: file config overrides defaults
|
|
114
|
+
for (const key of Object.keys(FIELD_VALIDATORS)) {
|
|
115
|
+
if (key in fileConfig && fileConfig[key] !== undefined) {
|
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
117
|
+
resolved[key] = fileConfig[key];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Layer 2: CLI flags override file config
|
|
121
|
+
for (const key of Object.keys(FIELD_VALIDATORS)) {
|
|
122
|
+
if (key in cliFlags && cliFlags[key] !== undefined) {
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
124
|
+
resolved[key] = cliFlags[key];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return resolved;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { DaemonRequest, DaemonResponse } from "./protocol.js";
|
|
2
|
+
/** Error classes for daemon connection failures */
|
|
3
|
+
export declare class DaemonConnectionError extends Error {
|
|
4
|
+
readonly code: "NO_SOCKET" | "CONNECTION_REFUSED" | "TIMEOUT";
|
|
5
|
+
constructor(message: string, code: "NO_SOCKET" | "CONNECTION_REFUSED" | "TIMEOUT");
|
|
6
|
+
}
|
|
7
|
+
export declare class DaemonVersionError extends Error {
|
|
8
|
+
readonly daemonVersion: string;
|
|
9
|
+
readonly clientVersion: string;
|
|
10
|
+
constructor(message: string, daemonVersion: string, clientVersion: string);
|
|
11
|
+
}
|
|
12
|
+
/** Result of daemon discovery */
|
|
13
|
+
export interface DaemonInfo {
|
|
14
|
+
socketPath: string;
|
|
15
|
+
running: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** Connected client that can send requests */
|
|
18
|
+
export interface DaemonClientConnection {
|
|
19
|
+
send<T extends DaemonResponse>(request: DaemonRequest): Promise<T>;
|
|
20
|
+
close(): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Discover daemon for given project and session
|
|
24
|
+
*/
|
|
25
|
+
export declare function discoverDaemon(projectRoot: string, tmuxSession?: string): Promise<DaemonInfo>;
|
|
26
|
+
/**
|
|
27
|
+
* Ensure daemon is running, start if needed
|
|
28
|
+
*/
|
|
29
|
+
export declare function ensureDaemon(projectRoot: string, tmuxSession?: string): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* Connect to daemon socket
|
|
32
|
+
*/
|
|
33
|
+
export declare function connectToDaemon(socketPath: string): Promise<DaemonClientConnection>;
|
|
34
|
+
/** Connect with protocol version check */
|
|
35
|
+
export declare function connectWithVersionCheck(socketPath: string): Promise<DaemonClientConnection>;
|
|
36
|
+
/** Connect with retry logic */
|
|
37
|
+
export declare function connectWithRetry(socketPath: string, maxRetries?: number): Promise<DaemonClientConnection>;
|
|
38
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/daemon/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAgB,MAAM,eAAe,CAAC;AAIjF,mDAAmD;AACnD,qBAAa,qBAAsB,SAAQ,KAAK;aAG5B,IAAI,EAAE,WAAW,GAAG,oBAAoB,GAAG,SAAS;gBADpE,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,WAAW,GAAG,oBAAoB,GAAG,SAAS;CAKvE;AAED,qBAAa,kBAAmB,SAAQ,KAAK;aAGzB,aAAa,EAAE,MAAM;aACrB,aAAa,EAAE,MAAM;gBAFrC,OAAO,EAAE,MAAM,EACC,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM;CAKxC;AAED,iCAAiC;AACjC,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,8CAA8C;AAC9C,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,CAAC,SAAS,cAAc,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACnE,KAAK,IAAI,IAAI,CAAC;CACf;AAKD;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,WAAW,SAAQ,GAClB,OAAO,CAAC,UAAU,CAAC,CASrB;AAeD;;GAEG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,SAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA2B5F;AAiCD;;GAEG;AACH,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA6BzF;AAkDD,0CAA0C;AAC1C,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA8BjG;AAED,+BAA+B;AAC/B,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,UAAU,SAAI,GACb,OAAO,CAAC,sBAAsB,CAAC,CA+BjC"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as net from "node:net";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
import { PROTOCOL_VERSION } from "./protocol.js";
|
|
6
|
+
import { generateSessionId } from "../session.js";
|
|
7
|
+
/** Error classes for daemon connection failures */
|
|
8
|
+
export class DaemonConnectionError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
constructor(message, code) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.code = code;
|
|
13
|
+
this.name = "DaemonConnectionError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class DaemonVersionError extends Error {
|
|
17
|
+
daemonVersion;
|
|
18
|
+
clientVersion;
|
|
19
|
+
constructor(message, daemonVersion, clientVersion) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.daemonVersion = daemonVersion;
|
|
22
|
+
this.clientVersion = clientVersion;
|
|
23
|
+
this.name = "DaemonVersionError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const STARTUP_TIMEOUT_MS = 5000;
|
|
27
|
+
const STARTUP_POLL_MS = 100;
|
|
28
|
+
/**
|
|
29
|
+
* Discover daemon for given project and session
|
|
30
|
+
*/
|
|
31
|
+
export async function discoverDaemon(projectRoot, tmuxSession = "pit") {
|
|
32
|
+
// Derive session ID (same logic as src/session.ts:generateSessionId)
|
|
33
|
+
const sessionId = generateSessionId(projectRoot, tmuxSession);
|
|
34
|
+
const socketPath = path.join("/tmp/pit", sessionId, "daemon.sock");
|
|
35
|
+
// Test if socket is connectable
|
|
36
|
+
const running = await testConnection(socketPath);
|
|
37
|
+
return { socketPath, running };
|
|
38
|
+
}
|
|
39
|
+
async function testConnection(socketPath) {
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
const socket = net.createConnection(socketPath);
|
|
42
|
+
socket.on("connect", () => {
|
|
43
|
+
socket.destroy();
|
|
44
|
+
resolve(true);
|
|
45
|
+
});
|
|
46
|
+
socket.on("error", () => {
|
|
47
|
+
resolve(false);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Ensure daemon is running, start if needed
|
|
53
|
+
*/
|
|
54
|
+
export async function ensureDaemon(projectRoot, tmuxSession = "pit") {
|
|
55
|
+
const info = await discoverDaemon(projectRoot, tmuxSession);
|
|
56
|
+
if (info.running) {
|
|
57
|
+
return info.socketPath;
|
|
58
|
+
}
|
|
59
|
+
// Acquire startup lock to prevent race with other clients
|
|
60
|
+
const lockPath = path.join(path.dirname(info.socketPath), "daemon.lock");
|
|
61
|
+
await acquireLock(lockPath);
|
|
62
|
+
try {
|
|
63
|
+
// Double-check after acquiring lock (another client may have started it)
|
|
64
|
+
if (await testConnection(info.socketPath)) {
|
|
65
|
+
return info.socketPath;
|
|
66
|
+
}
|
|
67
|
+
// Spawn daemon process (detached, stdio ignored)
|
|
68
|
+
await spawnDaemon(projectRoot, tmuxSession);
|
|
69
|
+
// Wait for socket to become ready
|
|
70
|
+
await waitForSocket(info.socketPath, STARTUP_TIMEOUT_MS);
|
|
71
|
+
return info.socketPath;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
await releaseLock(lockPath);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function spawnDaemon(projectRoot, _tmuxSession) {
|
|
78
|
+
// Spawn daemon __run directly (not daemon start) because the caller
|
|
79
|
+
// (ensureDaemon) already holds daemon.lock. Going through daemon start
|
|
80
|
+
// would deadlock since it tries to acquire the same lock.
|
|
81
|
+
const child = spawn(process.execPath, // node
|
|
82
|
+
[
|
|
83
|
+
path.resolve(process.argv[1]), // Use resolved path to CLI
|
|
84
|
+
"daemon",
|
|
85
|
+
"__run",
|
|
86
|
+
], {
|
|
87
|
+
detached: true,
|
|
88
|
+
stdio: "ignore",
|
|
89
|
+
cwd: projectRoot,
|
|
90
|
+
});
|
|
91
|
+
child.unref();
|
|
92
|
+
}
|
|
93
|
+
async function waitForSocket(socketPath, timeoutMs) {
|
|
94
|
+
const deadline = Date.now() + timeoutMs;
|
|
95
|
+
while (Date.now() < deadline) {
|
|
96
|
+
if (await testConnection(socketPath)) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
await new Promise((r) => setTimeout(r, STARTUP_POLL_MS));
|
|
100
|
+
}
|
|
101
|
+
throw new Error(`Daemon failed to start within ${timeoutMs}ms`);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Connect to daemon socket
|
|
105
|
+
*/
|
|
106
|
+
export async function connectToDaemon(socketPath) {
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
const socket = net.createConnection(socketPath);
|
|
109
|
+
const timeout = setTimeout(() => {
|
|
110
|
+
socket.destroy();
|
|
111
|
+
reject(new DaemonConnectionError("Connection timeout", "TIMEOUT"));
|
|
112
|
+
}, 5000);
|
|
113
|
+
socket.on("connect", () => {
|
|
114
|
+
clearTimeout(timeout);
|
|
115
|
+
resolve(createClient(socket));
|
|
116
|
+
});
|
|
117
|
+
socket.on("error", (err) => {
|
|
118
|
+
clearTimeout(timeout);
|
|
119
|
+
if (err.code === "ENOENT") {
|
|
120
|
+
reject(new DaemonConnectionError("Daemon socket not found", "NO_SOCKET"));
|
|
121
|
+
}
|
|
122
|
+
else if (err.code === "ECONNREFUSED") {
|
|
123
|
+
reject(new DaemonConnectionError("Daemon not responding (may have crashed)", "CONNECTION_REFUSED"));
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
reject(err);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/** Create client with proper error handling */
|
|
132
|
+
function createClient(socket) {
|
|
133
|
+
let buffer = "";
|
|
134
|
+
return {
|
|
135
|
+
async send(request) {
|
|
136
|
+
const REQUEST_TIMEOUT_MS = 30000;
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
const timeout = setTimeout(() => {
|
|
139
|
+
socket.off("data", onData);
|
|
140
|
+
reject(new Error(`Request timeout after ${REQUEST_TIMEOUT_MS}ms`));
|
|
141
|
+
}, REQUEST_TIMEOUT_MS);
|
|
142
|
+
const onData = (chunk) => {
|
|
143
|
+
buffer += chunk.toString();
|
|
144
|
+
const newlineIdx = buffer.indexOf("\n");
|
|
145
|
+
if (newlineIdx !== -1) {
|
|
146
|
+
const line = buffer.slice(0, newlineIdx);
|
|
147
|
+
buffer = buffer.slice(newlineIdx + 1);
|
|
148
|
+
socket.off("data", onData);
|
|
149
|
+
clearTimeout(timeout);
|
|
150
|
+
try {
|
|
151
|
+
resolve(JSON.parse(line));
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
reject(new Error("Invalid JSON response from daemon"));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
socket.on("data", onData);
|
|
159
|
+
socket.write(JSON.stringify(request) + "\n");
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
close() {
|
|
163
|
+
socket.destroy();
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/** Check if daemon protocol version is compatible */
|
|
168
|
+
function isVersionCompatible(daemon, client) {
|
|
169
|
+
// Same major version = compatible (semver-like)
|
|
170
|
+
const daemonMajor = daemon.split(".")[0];
|
|
171
|
+
const clientMajor = client.split(".")[0];
|
|
172
|
+
return daemonMajor === clientMajor;
|
|
173
|
+
}
|
|
174
|
+
/** Connect with protocol version check */
|
|
175
|
+
export async function connectWithVersionCheck(socketPath) {
|
|
176
|
+
const client = await connectToDaemon(socketPath);
|
|
177
|
+
try {
|
|
178
|
+
// Send status request to check version
|
|
179
|
+
const status = await client.send({
|
|
180
|
+
id: "version-check",
|
|
181
|
+
method: "status",
|
|
182
|
+
params: {},
|
|
183
|
+
});
|
|
184
|
+
if (!status.success || !status.result || !status.result.protocolVersion) {
|
|
185
|
+
client.close();
|
|
186
|
+
throw new Error("Daemon status response missing protocol version");
|
|
187
|
+
}
|
|
188
|
+
if (!isVersionCompatible(status.result.protocolVersion, PROTOCOL_VERSION)) {
|
|
189
|
+
client.close();
|
|
190
|
+
throw new DaemonVersionError(`Daemon version ${status.result.protocolVersion} incompatible with client ${PROTOCOL_VERSION}`, status.result.protocolVersion, PROTOCOL_VERSION);
|
|
191
|
+
}
|
|
192
|
+
return client;
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
client.close();
|
|
196
|
+
throw err;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/** Connect with retry logic */
|
|
200
|
+
export async function connectWithRetry(socketPath, maxRetries = 1) {
|
|
201
|
+
let lastError = null;
|
|
202
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
203
|
+
try {
|
|
204
|
+
return await connectWithVersionCheck(socketPath);
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
lastError = err;
|
|
208
|
+
// Retry only for transient failures
|
|
209
|
+
if (err instanceof DaemonConnectionError) {
|
|
210
|
+
if (err.code === "CONNECTION_REFUSED" && attempt < maxRetries) {
|
|
211
|
+
// Wait briefly before retry
|
|
212
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Don't retry version mismatch or other permanent failures
|
|
217
|
+
if (err instanceof DaemonVersionError) {
|
|
218
|
+
throw err;
|
|
219
|
+
}
|
|
220
|
+
// Don't retry socket not found (daemon not running)
|
|
221
|
+
if (err instanceof DaemonConnectionError && err.code === "NO_SOCKET") {
|
|
222
|
+
throw err;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
throw lastError;
|
|
227
|
+
}
|
|
228
|
+
async function acquireLock(lockPath) {
|
|
229
|
+
const dir = path.dirname(lockPath);
|
|
230
|
+
await fs.mkdir(dir, { recursive: true });
|
|
231
|
+
// Simple spinlock with exponential backoff
|
|
232
|
+
let attempts = 0;
|
|
233
|
+
while (attempts < 50) {
|
|
234
|
+
try {
|
|
235
|
+
// O_EXCL ensures atomic creation
|
|
236
|
+
await fs.writeFile(lockPath, String(process.pid), { flag: "wx" });
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
if (err.code !== "EEXIST")
|
|
241
|
+
throw err;
|
|
242
|
+
// Lock held by another process
|
|
243
|
+
await new Promise((r) => setTimeout(r, Math.min(100, 10 * Math.pow(1.5, attempts))));
|
|
244
|
+
attempts++;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
throw new Error("Failed to acquire daemon startup lock");
|
|
248
|
+
}
|
|
249
|
+
async function releaseLock(lockPath) {
|
|
250
|
+
await fs.unlink(lockPath).catch(() => {
|
|
251
|
+
// Ignore if file doesn't exist
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/daemon/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared context type for the pit daemon.
|
|
3
|
+
*
|
|
4
|
+
* DaemonContext encapsulates all mutable runtime state that daemon handlers
|
|
5
|
+
* need to close over. It is a plain mutable object — not a class — so that
|
|
6
|
+
* state updates are straightforward assignments.
|
|
7
|
+
*
|
|
8
|
+
* The module-level let variables in commands/daemon.ts (daemonState,
|
|
9
|
+
* debouncedSaver, loopHandles, agentInstance) will be migrated to this
|
|
10
|
+
* context in a later task (.7/.8). For now this module only defines the
|
|
11
|
+
* shared types.
|
|
12
|
+
*/
|
|
13
|
+
import type { AgentAdapter } from "../adapters/types.js";
|
|
14
|
+
import type { DaemonState, PersistedEpicState } from "./state.js";
|
|
15
|
+
import type { LoopHandle } from "../loop.js";
|
|
16
|
+
import type { PitConfig } from "../config.js";
|
|
17
|
+
import type * as beads from "../beads.js";
|
|
18
|
+
/**
|
|
19
|
+
* All runtime state for a running daemon instance.
|
|
20
|
+
*
|
|
21
|
+
* daemonState, debouncedSaver, and agentInstance start as null and are
|
|
22
|
+
* populated on the first `start` call or during state recovery.
|
|
23
|
+
*/
|
|
24
|
+
export interface DaemonContext {
|
|
25
|
+
daemonState: DaemonState | null;
|
|
26
|
+
debouncedSaver: ((state: DaemonState) => void) | null;
|
|
27
|
+
loopHandles: Map<string, LoopHandle>;
|
|
28
|
+
agentInstance: AgentAdapter | null;
|
|
29
|
+
daemonStartTime: number;
|
|
30
|
+
projectRoot: string;
|
|
31
|
+
sessionId: string;
|
|
32
|
+
tmuxSession: string;
|
|
33
|
+
fileConfig: PitConfig;
|
|
34
|
+
healthCheckInterval: ReturnType<typeof setInterval> | null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Narrowed version of DaemonContext for handlers that require the daemon to
|
|
38
|
+
* have been started at least once. Guarantees that daemonState, debouncedSaver,
|
|
39
|
+
* and agentInstance are non-null.
|
|
40
|
+
*/
|
|
41
|
+
export type InitializedDaemonContext = DaemonContext & {
|
|
42
|
+
daemonState: DaemonState;
|
|
43
|
+
debouncedSaver: (state: DaemonState) => void;
|
|
44
|
+
agentInstance: AgentAdapter;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Signature of the clearAndReprompt helper used by daemon handlers and the
|
|
48
|
+
* recovery pipeline.
|
|
49
|
+
*
|
|
50
|
+
* Moved here (from commands/daemon.ts) to avoid future import cycles between
|
|
51
|
+
* the handler modules and the recovery module.
|
|
52
|
+
*/
|
|
53
|
+
export type ClearAndRepromptFn = (options: {
|
|
54
|
+
epicId: string;
|
|
55
|
+
machine: LoopHandle["machine"];
|
|
56
|
+
windowName: string;
|
|
57
|
+
adapter: AgentAdapter;
|
|
58
|
+
transitionReason: "TICKET_COMPLETE" | "RESUME_NO_MESSAGE";
|
|
59
|
+
epicState: PersistedEpicState;
|
|
60
|
+
}) => Promise<{
|
|
61
|
+
nextTicket: beads.BeadTicket | null;
|
|
62
|
+
}>;
|
|
63
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/daemon/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAC;AAM1C;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACtD,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACrC,aAAa,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,SAAS,CAAC;IACtB,mBAAmB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,GAAG,IAAI,CAAC;CAC5D;AAMD;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,GAAG,aAAa,GAAG;IACrD,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,aAAa,EAAE,YAAY,CAAC;CAC7B,CAAC;AAMF;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,gBAAgB,EAAE,iBAAiB,GAAG,mBAAmB,CAAC;IAC1D,SAAS,EAAE,kBAAkB,CAAC;CAC/B,KAAK,OAAO,CAAC;IAAE,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,IAAI,CAAA;CAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared context type for the pit daemon.
|
|
3
|
+
*
|
|
4
|
+
* DaemonContext encapsulates all mutable runtime state that daemon handlers
|
|
5
|
+
* need to close over. It is a plain mutable object — not a class — so that
|
|
6
|
+
* state updates are straightforward assignments.
|
|
7
|
+
*
|
|
8
|
+
* The module-level let variables in commands/daemon.ts (daemonState,
|
|
9
|
+
* debouncedSaver, loopHandles, agentInstance) will be migrated to this
|
|
10
|
+
* context in a later task (.7/.8). For now this module only defines the
|
|
11
|
+
* shared types.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/daemon/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|