@nocville/npc 0.0.0-stage → 0.2.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/README.md +268 -2
- package/dist/cjs/cli.js +584 -0
- package/dist/cjs/core/api-key.js +69 -0
- package/dist/cjs/core/base-npc.js +160 -0
- package/dist/cjs/core/config.js +108 -0
- package/dist/cjs/core/event-npc.js +14 -0
- package/dist/cjs/core/logger.js +39 -0
- package/dist/cjs/core/polling-npc.js +65 -0
- package/dist/cjs/core/screen.js +28 -0
- package/dist/cjs/core/session-filter.js +150 -0
- package/dist/cjs/core/text.js +15 -0
- package/dist/cjs/core/thresholds.js +48 -0
- package/dist/cjs/core/types.js +10 -0
- package/dist/cjs/core/user-config.js +92 -0
- package/dist/cjs/doctor.js +130 -0
- package/dist/cjs/index.js +95 -0
- package/dist/cjs/npcs/agent-common/activity.js +291 -0
- package/dist/cjs/npcs/agent-common/git-stats.js +71 -0
- package/dist/cjs/npcs/agent-common/hook-runner.js +252 -0
- package/dist/cjs/npcs/agent-common/hook-settings.js +279 -0
- package/dist/cjs/npcs/agent-common/liveness.js +112 -0
- package/dist/cjs/npcs/agent-common/lock.js +99 -0
- package/dist/cjs/npcs/agent-common/runtime.js +154 -0
- package/dist/cjs/npcs/agent-common/session.js +412 -0
- package/dist/cjs/npcs/agent-common/shim.js +96 -0
- package/dist/cjs/npcs/agent-common/watchdog.js +149 -0
- package/dist/cjs/npcs/claude-code/defaults.js +20 -0
- package/dist/cjs/npcs/claude-code/hook-handler.js +139 -0
- package/dist/cjs/npcs/claude-code/index.js +104 -0
- package/dist/cjs/npcs/claude-code/setup.js +133 -0
- package/dist/cjs/npcs/claude-code/state-machine.js +130 -0
- package/dist/cjs/npcs/codex/defaults.js +32 -0
- package/dist/cjs/npcs/codex/hook-handler.js +116 -0
- package/dist/cjs/npcs/codex/index.js +92 -0
- package/dist/cjs/npcs/codex/rollout.js +246 -0
- package/dist/cjs/npcs/codex/setup.js +104 -0
- package/dist/cjs/npcs/codex/watcher.js +361 -0
- package/dist/cjs/npcs/cursor/defaults.js +15 -0
- package/dist/cjs/npcs/cursor/hook-handler.js +65 -0
- package/dist/cjs/npcs/cursor/index.js +72 -0
- package/dist/cjs/npcs/cursor/normalize.js +54 -0
- package/dist/cjs/npcs/cursor/setup.js +98 -0
- package/dist/cjs/npcs/gemini/defaults.js +15 -0
- package/dist/cjs/npcs/gemini/hook-handler.js +93 -0
- package/dist/cjs/npcs/gemini/index.js +69 -0
- package/dist/cjs/npcs/gemini/setup.js +98 -0
- package/dist/cjs/npcs/github-watcher/defaults.js +11 -0
- package/dist/cjs/npcs/github-watcher/format.js +21 -0
- package/dist/cjs/npcs/github-watcher/github-api.js +126 -0
- package/dist/cjs/npcs/github-watcher/index.js +148 -0
- package/dist/cjs/npcs/internet-connectivity/checks.js +92 -0
- package/dist/cjs/npcs/internet-connectivity/defaults.js +22 -0
- package/dist/cjs/npcs/internet-connectivity/index.js +251 -0
- package/dist/cjs/npcs/log-watcher/buffer.js +40 -0
- package/dist/cjs/npcs/log-watcher/defaults.js +12 -0
- package/dist/cjs/npcs/log-watcher/index.js +161 -0
- package/dist/cjs/npcs/log-watcher/tail.js +81 -0
- package/dist/cjs/npcs/process-watcher/defaults.js +9 -0
- package/dist/cjs/npcs/process-watcher/index.js +140 -0
- package/dist/cjs/npcs/process-watcher/process-scanner.js +114 -0
- package/dist/cjs/npcs/receptionist/defaults.js +9 -0
- package/dist/cjs/npcs/receptionist/index.js +120 -0
- package/dist/cjs/npcs/receptionist/weather.js +129 -0
- package/dist/cjs/npcs/system-monitor/collectors.js +68 -0
- package/dist/cjs/npcs/system-monitor/defaults.js +13 -0
- package/dist/cjs/npcs/system-monitor/index.js +105 -0
- package/dist/cjs/npcs/web-page-watcher/basic-mode.js +58 -0
- package/dist/cjs/npcs/web-page-watcher/capture.js +80 -0
- package/dist/cjs/npcs/web-page-watcher/defaults.js +31 -0
- package/dist/cjs/npcs/web-page-watcher/index.js +234 -0
- package/dist/cjs/npcs/web-page-watcher/pixelate.js +181 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +549 -0
- package/dist/core/api-key.d.ts +34 -0
- package/dist/core/api-key.js +64 -0
- package/dist/core/base-npc.d.ts +41 -0
- package/dist/core/base-npc.js +156 -0
- package/dist/core/config.d.ts +22 -0
- package/dist/core/config.js +101 -0
- package/dist/core/event-npc.d.ts +8 -0
- package/dist/core/event-npc.js +10 -0
- package/dist/core/logger.d.ts +11 -0
- package/dist/core/logger.js +35 -0
- package/dist/core/polling-npc.d.ts +18 -0
- package/dist/core/polling-npc.js +61 -0
- package/dist/core/screen.d.ts +11 -0
- package/dist/core/screen.js +24 -0
- package/dist/core/session-filter.d.ts +59 -0
- package/dist/core/session-filter.js +143 -0
- package/dist/core/text.d.ts +6 -0
- package/dist/core/text.js +12 -0
- package/dist/core/thresholds.d.ts +10 -0
- package/dist/core/thresholds.js +44 -0
- package/dist/core/types.d.ts +60 -0
- package/dist/core/types.js +7 -0
- package/dist/core/user-config.d.ts +43 -0
- package/dist/core/user-config.js +85 -0
- package/dist/doctor.d.ts +8 -0
- package/dist/doctor.js +126 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +26 -0
- package/dist/npcs/agent-common/activity.d.ts +42 -0
- package/dist/npcs/agent-common/activity.js +280 -0
- package/dist/npcs/agent-common/git-stats.d.ts +11 -0
- package/dist/npcs/agent-common/git-stats.js +67 -0
- package/dist/npcs/agent-common/hook-runner.d.ts +62 -0
- package/dist/npcs/agent-common/hook-runner.js +245 -0
- package/dist/npcs/agent-common/hook-settings.d.ts +75 -0
- package/dist/npcs/agent-common/hook-settings.js +265 -0
- package/dist/npcs/agent-common/liveness.d.ts +12 -0
- package/dist/npcs/agent-common/liveness.js +105 -0
- package/dist/npcs/agent-common/lock.d.ts +6 -0
- package/dist/npcs/agent-common/lock.js +95 -0
- package/dist/npcs/agent-common/runtime.d.ts +16 -0
- package/dist/npcs/agent-common/runtime.js +149 -0
- package/dist/npcs/agent-common/session.d.ts +192 -0
- package/dist/npcs/agent-common/session.js +390 -0
- package/dist/npcs/agent-common/shim.d.ts +4 -0
- package/dist/npcs/agent-common/shim.js +90 -0
- package/dist/npcs/agent-common/watchdog.d.ts +16 -0
- package/dist/npcs/agent-common/watchdog.js +144 -0
- package/dist/npcs/claude-code/defaults.d.ts +15 -0
- package/dist/npcs/claude-code/defaults.js +17 -0
- package/dist/npcs/claude-code/hook-handler.d.ts +40 -0
- package/dist/npcs/claude-code/hook-handler.js +131 -0
- package/dist/npcs/claude-code/index.d.ts +36 -0
- package/dist/npcs/claude-code/index.js +92 -0
- package/dist/npcs/claude-code/setup.d.ts +58 -0
- package/dist/npcs/claude-code/setup.js +121 -0
- package/dist/npcs/claude-code/state-machine.d.ts +28 -0
- package/dist/npcs/claude-code/state-machine.js +125 -0
- package/dist/npcs/codex/defaults.d.ts +24 -0
- package/dist/npcs/codex/defaults.js +28 -0
- package/dist/npcs/codex/hook-handler.d.ts +24 -0
- package/dist/npcs/codex/hook-handler.js +110 -0
- package/dist/npcs/codex/index.d.ts +21 -0
- package/dist/npcs/codex/index.js +76 -0
- package/dist/npcs/codex/rollout.d.ts +39 -0
- package/dist/npcs/codex/rollout.js +242 -0
- package/dist/npcs/codex/setup.d.ts +37 -0
- package/dist/npcs/codex/setup.js +96 -0
- package/dist/npcs/codex/watcher.d.ts +65 -0
- package/dist/npcs/codex/watcher.js +356 -0
- package/dist/npcs/cursor/defaults.d.ts +9 -0
- package/dist/npcs/cursor/defaults.js +11 -0
- package/dist/npcs/cursor/hook-handler.d.ts +8 -0
- package/dist/npcs/cursor/hook-handler.js +60 -0
- package/dist/npcs/cursor/index.d.ts +18 -0
- package/dist/npcs/cursor/index.js +57 -0
- package/dist/npcs/cursor/normalize.d.ts +6 -0
- package/dist/npcs/cursor/normalize.js +49 -0
- package/dist/npcs/cursor/setup.d.ts +29 -0
- package/dist/npcs/cursor/setup.js +90 -0
- package/dist/npcs/gemini/defaults.d.ts +9 -0
- package/dist/npcs/gemini/defaults.js +11 -0
- package/dist/npcs/gemini/hook-handler.d.ts +10 -0
- package/dist/npcs/gemini/hook-handler.js +87 -0
- package/dist/npcs/gemini/index.d.ts +17 -0
- package/dist/npcs/gemini/index.js +56 -0
- package/dist/npcs/gemini/setup.d.ts +29 -0
- package/dist/npcs/gemini/setup.js +90 -0
- package/dist/npcs/github-watcher/defaults.d.ts +8 -0
- package/dist/npcs/github-watcher/defaults.js +8 -0
- package/dist/npcs/github-watcher/format.d.ts +3 -0
- package/dist/npcs/github-watcher/format.js +18 -0
- package/dist/npcs/github-watcher/github-api.d.ts +55 -0
- package/dist/npcs/github-watcher/github-api.js +120 -0
- package/dist/npcs/github-watcher/index.d.ts +35 -0
- package/dist/npcs/github-watcher/index.js +144 -0
- package/dist/npcs/internet-connectivity/checks.d.ts +24 -0
- package/dist/npcs/internet-connectivity/checks.js +84 -0
- package/dist/npcs/internet-connectivity/defaults.d.ts +20 -0
- package/dist/npcs/internet-connectivity/defaults.js +19 -0
- package/dist/npcs/internet-connectivity/index.d.ts +55 -0
- package/dist/npcs/internet-connectivity/index.js +246 -0
- package/dist/npcs/log-watcher/buffer.d.ts +18 -0
- package/dist/npcs/log-watcher/buffer.js +34 -0
- package/dist/npcs/log-watcher/defaults.d.ts +9 -0
- package/dist/npcs/log-watcher/defaults.js +9 -0
- package/dist/npcs/log-watcher/index.d.ts +45 -0
- package/dist/npcs/log-watcher/index.js +157 -0
- package/dist/npcs/log-watcher/tail.d.ts +9 -0
- package/dist/npcs/log-watcher/tail.js +78 -0
- package/dist/npcs/process-watcher/defaults.d.ts +6 -0
- package/dist/npcs/process-watcher/defaults.js +6 -0
- package/dist/npcs/process-watcher/index.d.ts +26 -0
- package/dist/npcs/process-watcher/index.js +136 -0
- package/dist/npcs/process-watcher/process-scanner.d.ts +19 -0
- package/dist/npcs/process-watcher/process-scanner.js +110 -0
- package/dist/npcs/receptionist/defaults.d.ts +6 -0
- package/dist/npcs/receptionist/defaults.js +6 -0
- package/dist/npcs/receptionist/index.d.ts +29 -0
- package/dist/npcs/receptionist/index.js +116 -0
- package/dist/npcs/receptionist/weather.d.ts +37 -0
- package/dist/npcs/receptionist/weather.js +121 -0
- package/dist/npcs/system-monitor/collectors.d.ts +45 -0
- package/dist/npcs/system-monitor/collectors.js +60 -0
- package/dist/npcs/system-monitor/defaults.d.ts +7 -0
- package/dist/npcs/system-monitor/defaults.js +10 -0
- package/dist/npcs/system-monitor/index.d.ts +27 -0
- package/dist/npcs/system-monitor/index.js +101 -0
- package/dist/npcs/web-page-watcher/basic-mode.d.ts +16 -0
- package/dist/npcs/web-page-watcher/basic-mode.js +52 -0
- package/dist/npcs/web-page-watcher/capture.d.ts +49 -0
- package/dist/npcs/web-page-watcher/capture.js +75 -0
- package/dist/npcs/web-page-watcher/defaults.d.ts +19 -0
- package/dist/npcs/web-page-watcher/defaults.js +27 -0
- package/dist/npcs/web-page-watcher/index.d.ts +42 -0
- package/dist/npcs/web-page-watcher/index.js +230 -0
- package/dist/npcs/web-page-watcher/pixelate.d.ts +36 -0
- package/dist/npcs/web-page-watcher/pixelate.js +172 -0
- package/package.json +73 -3
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { userConfigPath } from './user-config.js';
|
|
5
|
+
const EMPTY = { projects: [], sessions: [] };
|
|
6
|
+
export const SESSION_FILTER_TEMPLATE = {
|
|
7
|
+
_help: [
|
|
8
|
+
'Choose which AI agent sessions (Claude Code, Codex, Gemini CLI, Cursor) appear in your Nocville office.',
|
|
9
|
+
'Leave every list empty to publish all sessions (the default).',
|
|
10
|
+
'deny always wins. If any allow entry is set, ONLY sessions matching an allow entry publish.',
|
|
11
|
+
'projects: a folder name anywhere in the session working directory, e.g. "client-*",',
|
|
12
|
+
' or a path containing / such as "~/work/secret" (that folder and everything inside it).',
|
|
13
|
+
'sessions: a Claude Code session name, e.g. "*private*".',
|
|
14
|
+
'Patterns are case-insensitive; * matches anything, ? one character.',
|
|
15
|
+
'Changes apply to running sessions on their next update. Check with: npx @nocville/npc sessions',
|
|
16
|
+
],
|
|
17
|
+
allow: { projects: [], sessions: [] },
|
|
18
|
+
deny: { projects: [], sessions: [] },
|
|
19
|
+
};
|
|
20
|
+
/** `NOCVILLE_SESSIONS_CONFIG` overrides; otherwise `sessions.json` beside config.json. */
|
|
21
|
+
export function sessionFilterPath() {
|
|
22
|
+
return (process.env['NOCVILLE_SESSIONS_CONFIG'] || join(dirname(userConfigPath()), 'sessions.json'));
|
|
23
|
+
}
|
|
24
|
+
function rules(raw, where) {
|
|
25
|
+
if (raw === undefined || raw === null)
|
|
26
|
+
return EMPTY;
|
|
27
|
+
if (typeof raw !== 'object' || Array.isArray(raw))
|
|
28
|
+
throw new Error(`"${where}" must be an object with "projects" and "sessions" lists`);
|
|
29
|
+
const list = (key) => {
|
|
30
|
+
const value = raw[key];
|
|
31
|
+
if (value === undefined || value === null)
|
|
32
|
+
return [];
|
|
33
|
+
if (!Array.isArray(value) || value.some((v) => typeof v !== 'string'))
|
|
34
|
+
throw new Error(`"${where}.${key}" must be a list of strings`);
|
|
35
|
+
return value.map((v) => v.trim()).filter(Boolean);
|
|
36
|
+
};
|
|
37
|
+
return { projects: list('projects'), sessions: list('sessions') };
|
|
38
|
+
}
|
|
39
|
+
/** Never throws. A missing file means "publish everything". */
|
|
40
|
+
export function loadSessionFilter(path = sessionFilterPath()) {
|
|
41
|
+
let text;
|
|
42
|
+
try {
|
|
43
|
+
text = readFileSync(path, 'utf-8');
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
if (err.code === 'ENOENT')
|
|
47
|
+
return { allow: EMPTY, deny: EMPTY };
|
|
48
|
+
return { allow: EMPTY, deny: EMPTY, error: `can't read ${path}: ${err.message}` };
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const raw = JSON.parse(text);
|
|
52
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
53
|
+
throw new Error('expected a JSON object with "allow" and "deny"');
|
|
54
|
+
const obj = raw;
|
|
55
|
+
return { allow: rules(obj['allow'], 'allow'), deny: rules(obj['deny'], 'deny') };
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
return { allow: EMPTY, deny: EMPTY, error: `${path}: ${err.message}` };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Write the commented template if no file exists; returns the path. */
|
|
62
|
+
export function ensureSessionFilterTemplate(path = sessionFilterPath()) {
|
|
63
|
+
if (existsSync(path))
|
|
64
|
+
return { path, created: false };
|
|
65
|
+
try {
|
|
66
|
+
const dir = dirname(path);
|
|
67
|
+
if (!existsSync(dir))
|
|
68
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
69
|
+
writeFileSync(path, JSON.stringify(SESSION_FILTER_TEMPLATE, null, 2) + '\n', {
|
|
70
|
+
encoding: 'utf-8',
|
|
71
|
+
mode: 0o600,
|
|
72
|
+
flag: 'wx',
|
|
73
|
+
});
|
|
74
|
+
return { path, created: true };
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return { path, created: false };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const normalizePath = (p) => p.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
81
|
+
function globRegExp(pattern, pathMode) {
|
|
82
|
+
let src = '';
|
|
83
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
84
|
+
const c = pattern[i];
|
|
85
|
+
if (c === '*') {
|
|
86
|
+
if (pattern[i + 1] === '*') {
|
|
87
|
+
src += '.*';
|
|
88
|
+
i++;
|
|
89
|
+
}
|
|
90
|
+
else
|
|
91
|
+
src += pathMode ? '[^/]*' : '.*';
|
|
92
|
+
}
|
|
93
|
+
else if (c === '?')
|
|
94
|
+
src += pathMode ? '[^/]' : '.';
|
|
95
|
+
else
|
|
96
|
+
src += c.replace(/[.+^${}()|[\]\\]/g, '\\$&');
|
|
97
|
+
}
|
|
98
|
+
return new RegExp(`^${src}$`, 'i');
|
|
99
|
+
}
|
|
100
|
+
function projectMatches(pattern, projectDir) {
|
|
101
|
+
const dir = normalizePath(projectDir);
|
|
102
|
+
if (!dir)
|
|
103
|
+
return false;
|
|
104
|
+
const isPath = pattern.includes('/') || pattern.includes('\\') || pattern.startsWith('~');
|
|
105
|
+
if (!isPath) {
|
|
106
|
+
const re = globRegExp(pattern, false);
|
|
107
|
+
return dir.split('/').some((segment) => segment && re.test(segment));
|
|
108
|
+
}
|
|
109
|
+
const expanded = normalizePath(pattern.startsWith('~') ? homedir() + pattern.slice(1) : pattern);
|
|
110
|
+
const re = globRegExp(expanded, true);
|
|
111
|
+
// The directory itself or any ancestor: a rule for a folder covers its subfolders.
|
|
112
|
+
for (let p = dir; p; p = p.includes('/') ? p.slice(0, p.lastIndexOf('/')) : '') {
|
|
113
|
+
if (re.test(p))
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
function firstMatch(set, who) {
|
|
119
|
+
for (const p of set.projects)
|
|
120
|
+
if (projectMatches(p, who.projectDir))
|
|
121
|
+
return `project "${p}"`;
|
|
122
|
+
if (who.name)
|
|
123
|
+
for (const p of set.sessions)
|
|
124
|
+
if (globRegExp(p, false).test(who.name.trim()))
|
|
125
|
+
return `session "${p}"`;
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
/** Decide whether a session may publish. Pure apart from `homedir()` for `~` patterns. */
|
|
129
|
+
export function sessionPublishDecision(filter, who) {
|
|
130
|
+
if (filter.error)
|
|
131
|
+
return { publish: false, reason: `sessions.json is invalid (${filter.error})` };
|
|
132
|
+
const denied = firstMatch(filter.deny, who);
|
|
133
|
+
if (denied)
|
|
134
|
+
return { publish: false, reason: `denied by ${denied}` };
|
|
135
|
+
const hasAllow = filter.allow.projects.length > 0 || filter.allow.sessions.length > 0;
|
|
136
|
+
if (!hasAllow)
|
|
137
|
+
return { publish: true, reason: 'no allowlist (all sessions publish)' };
|
|
138
|
+
const allowed = firstMatch(filter.allow, who);
|
|
139
|
+
return allowed
|
|
140
|
+
? { publish: true, reason: `allowed by ${allowed}` }
|
|
141
|
+
: { publish: false, reason: 'not on the allowlist' };
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=session-filter.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Truncate a string to at most `max` characters, appending an ellipsis when cut.
|
|
3
|
+
* Used to keep messages and screen lines within API limits.
|
|
4
|
+
*/
|
|
5
|
+
export function truncate(s, max = 200) {
|
|
6
|
+
if (s.length <= max)
|
|
7
|
+
return s;
|
|
8
|
+
if (max <= 1)
|
|
9
|
+
return s.slice(0, Math.max(0, max));
|
|
10
|
+
return s.slice(0, max - 1) + '…';
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Status, ThresholdConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Evaluate a numeric value against thresholds to determine status.
|
|
4
|
+
*/
|
|
5
|
+
export declare function evaluateThreshold(value: number, config: ThresholdConfig): Status;
|
|
6
|
+
/**
|
|
7
|
+
* Returns the worst (most severe) status from an array.
|
|
8
|
+
*/
|
|
9
|
+
export declare function worstStatus(statuses: Status[]): Status;
|
|
10
|
+
//# sourceMappingURL=thresholds.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluate a numeric value against thresholds to determine status.
|
|
3
|
+
*/
|
|
4
|
+
export function evaluateThreshold(value, config) {
|
|
5
|
+
const direction = config.direction ?? 'above';
|
|
6
|
+
if (direction === 'above') {
|
|
7
|
+
if (value >= config.critical)
|
|
8
|
+
return 'critical';
|
|
9
|
+
if (value >= config.warning)
|
|
10
|
+
return 'warning';
|
|
11
|
+
return 'healthy';
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
if (value <= config.critical)
|
|
15
|
+
return 'critical';
|
|
16
|
+
if (value <= config.warning)
|
|
17
|
+
return 'warning';
|
|
18
|
+
return 'healthy';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const STATUS_SEVERITY = {
|
|
22
|
+
healthy: 0,
|
|
23
|
+
unknown: 1,
|
|
24
|
+
warning: 2,
|
|
25
|
+
critical: 3,
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Returns the worst (most severe) status from an array.
|
|
29
|
+
*/
|
|
30
|
+
export function worstStatus(statuses) {
|
|
31
|
+
if (statuses.length === 0)
|
|
32
|
+
return 'unknown';
|
|
33
|
+
let worst = 'healthy';
|
|
34
|
+
let worstSeverity = 0;
|
|
35
|
+
for (const s of statuses) {
|
|
36
|
+
const severity = STATUS_SEVERITY[s];
|
|
37
|
+
if (severity > worstSeverity) {
|
|
38
|
+
worst = s;
|
|
39
|
+
worstSeverity = severity;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return worst;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=thresholds.js.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Status, Mood, ScreenData, BehaviorHints, CompanionSpec } from '@nocville/node';
|
|
2
|
+
export type { Status, Mood } from '@nocville/node';
|
|
3
|
+
export type { ScreenData, ScreenValue, BehaviorHints, CompanionSpec } from '@nocville/node';
|
|
4
|
+
/** NPC archetype — drives server-side movement speed and default behavior. */
|
|
5
|
+
export type Archetype = 'service' | 'database' | 'trading' | 'ai-agent' | 'pipeline' | 'gateway' | 'custom';
|
|
6
|
+
/** A companion declaration is the SDK's CompanionSpec. */
|
|
7
|
+
export type CompanionDecl = CompanionSpec;
|
|
8
|
+
export interface NpcConfig {
|
|
9
|
+
apiUrl: string;
|
|
10
|
+
apiKey: string;
|
|
11
|
+
serviceId: string;
|
|
12
|
+
debug?: boolean;
|
|
13
|
+
/** Target map for status pushes — a map id or name. Omit for the team default. */
|
|
14
|
+
map?: string;
|
|
15
|
+
/** Friendly display name for the NPC banner. Overrides the per-NPC default. */
|
|
16
|
+
name?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface CollectedMetrics {
|
|
19
|
+
status: Status;
|
|
20
|
+
mood?: Mood;
|
|
21
|
+
message: string;
|
|
22
|
+
metrics: Record<string, number | string>;
|
|
23
|
+
/** Granular sub-state (e.g. 'offline', 'new-commit', 'degraded'). */
|
|
24
|
+
subStatus?: string;
|
|
25
|
+
/** Companion screen payload for this cycle. */
|
|
26
|
+
screenData?: ScreenData;
|
|
27
|
+
/** Per-cycle behavior override, merged over the NPC's base `behavior`. */
|
|
28
|
+
behavior?: BehaviorHints;
|
|
29
|
+
}
|
|
30
|
+
export interface ThresholdConfig {
|
|
31
|
+
warning: number;
|
|
32
|
+
critical: number;
|
|
33
|
+
/** 'above' means value > threshold triggers; 'below' means value < threshold triggers */
|
|
34
|
+
direction?: 'above' | 'below';
|
|
35
|
+
}
|
|
36
|
+
export type NpcState = 'stopped' | 'running' | 'stopping';
|
|
37
|
+
export interface LogLevel {
|
|
38
|
+
name: string;
|
|
39
|
+
value: number;
|
|
40
|
+
}
|
|
41
|
+
export declare const LOG_LEVELS: {
|
|
42
|
+
readonly debug: {
|
|
43
|
+
readonly name: "DEBUG";
|
|
44
|
+
readonly value: 0;
|
|
45
|
+
};
|
|
46
|
+
readonly info: {
|
|
47
|
+
readonly name: "INFO";
|
|
48
|
+
readonly value: 1;
|
|
49
|
+
};
|
|
50
|
+
readonly warn: {
|
|
51
|
+
readonly name: "WARN";
|
|
52
|
+
readonly value: 2;
|
|
53
|
+
};
|
|
54
|
+
readonly error: {
|
|
55
|
+
readonly name: "ERROR";
|
|
56
|
+
readonly value: 3;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
export type LogLevelName = keyof typeof LOG_LEVELS;
|
|
60
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persisted per-user CLI config (`nocville-npc init`). Lets hook commands and
|
|
3
|
+
* long-running NPCs run without `--api-key` flags or env vars — the key never
|
|
4
|
+
* has to appear in ~/.claude/settings.json, ~/.codex/hooks.json or `ps` output.
|
|
5
|
+
*/
|
|
6
|
+
export interface UserConfig {
|
|
7
|
+
apiUrl?: string;
|
|
8
|
+
apiKey?: string;
|
|
9
|
+
map?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Location of the config file. `NOCVILLE_CONFIG` overrides (used by tests);
|
|
13
|
+
* otherwise `$XDG_CONFIG_HOME/nocville/config.json`, else `~/.config/nocville/config.json`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function userConfigPath(): string;
|
|
16
|
+
/** Read the user config; missing or unreadable files yield `{}` (never throws). */
|
|
17
|
+
export declare function loadUserConfig(path?: string): UserConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Merge `patch` into the stored config and write it with owner-only perms
|
|
20
|
+
* (dir 0700, file 0600) via an atomic rename. Undefined fields are left as-is;
|
|
21
|
+
* an empty string clears a field. Returns the written path.
|
|
22
|
+
*/
|
|
23
|
+
export declare function saveUserConfig(patch: UserConfig, path?: string): string;
|
|
24
|
+
/** Mask an API key for display: keep a short prefix/suffix only. */
|
|
25
|
+
export declare function maskKey(key: string | undefined): string;
|
|
26
|
+
/**
|
|
27
|
+
* Save credentials (explicit flags win; else migrate any from a legacy hook
|
|
28
|
+
* command) and return the effective config. Shared by claude-code/codex setup.
|
|
29
|
+
*/
|
|
30
|
+
export declare function persistCredentials(explicit: {
|
|
31
|
+
apiUrl?: string;
|
|
32
|
+
apiKey?: string;
|
|
33
|
+
map?: string;
|
|
34
|
+
}, legacy?: {
|
|
35
|
+
apiUrl?: string;
|
|
36
|
+
apiKey?: string;
|
|
37
|
+
}): {
|
|
38
|
+
apiUrl?: string;
|
|
39
|
+
apiKey?: string;
|
|
40
|
+
map?: string;
|
|
41
|
+
path: string;
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=user-config.d.ts.map
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* Location of the config file. `NOCVILLE_CONFIG` overrides (used by tests);
|
|
6
|
+
* otherwise `$XDG_CONFIG_HOME/nocville/config.json`, else `~/.config/nocville/config.json`.
|
|
7
|
+
*/
|
|
8
|
+
export function userConfigPath() {
|
|
9
|
+
const override = process.env['NOCVILLE_CONFIG'];
|
|
10
|
+
if (override)
|
|
11
|
+
return override;
|
|
12
|
+
const xdg = process.env['XDG_CONFIG_HOME'];
|
|
13
|
+
const base = xdg && xdg.trim() ? xdg : join(homedir(), '.config');
|
|
14
|
+
return join(base, 'nocville', 'config.json');
|
|
15
|
+
}
|
|
16
|
+
/** Read the user config; missing or unreadable files yield `{}` (never throws). */
|
|
17
|
+
export function loadUserConfig(path = userConfigPath()) {
|
|
18
|
+
try {
|
|
19
|
+
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
20
|
+
const out = {};
|
|
21
|
+
if (typeof raw['apiUrl'] === 'string' && raw['apiUrl'])
|
|
22
|
+
out.apiUrl = raw['apiUrl'];
|
|
23
|
+
if (typeof raw['apiKey'] === 'string' && raw['apiKey'])
|
|
24
|
+
out.apiKey = raw['apiKey'];
|
|
25
|
+
if (typeof raw['map'] === 'string' && raw['map'])
|
|
26
|
+
out.map = raw['map'];
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Merge `patch` into the stored config and write it with owner-only perms
|
|
35
|
+
* (dir 0700, file 0600) via an atomic rename. Undefined fields are left as-is;
|
|
36
|
+
* an empty string clears a field. Returns the written path.
|
|
37
|
+
*/
|
|
38
|
+
export function saveUserConfig(patch, path = userConfigPath()) {
|
|
39
|
+
const current = loadUserConfig(path);
|
|
40
|
+
const next = { ...current };
|
|
41
|
+
for (const [k, v] of Object.entries(patch)) {
|
|
42
|
+
if (v === undefined)
|
|
43
|
+
continue;
|
|
44
|
+
if (v === '')
|
|
45
|
+
delete next[k];
|
|
46
|
+
else
|
|
47
|
+
next[k] = v;
|
|
48
|
+
}
|
|
49
|
+
const dir = dirname(path);
|
|
50
|
+
if (!existsSync(dir))
|
|
51
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
52
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
53
|
+
writeFileSync(tmp, JSON.stringify(next, null, 2) + '\n', { encoding: 'utf-8', mode: 0o600 });
|
|
54
|
+
renameSync(tmp, path);
|
|
55
|
+
try {
|
|
56
|
+
chmodSync(path, 0o600);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// best effort (e.g. Windows)
|
|
60
|
+
}
|
|
61
|
+
return path;
|
|
62
|
+
}
|
|
63
|
+
/** Mask an API key for display: keep a short prefix/suffix only. */
|
|
64
|
+
export function maskKey(key) {
|
|
65
|
+
if (!key)
|
|
66
|
+
return '(none)';
|
|
67
|
+
if (key.length <= 10)
|
|
68
|
+
return '****';
|
|
69
|
+
return `${key.slice(0, 4)}…${key.slice(-4)}`;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Save credentials (explicit flags win; else migrate any from a legacy hook
|
|
73
|
+
* command) and return the effective config. Shared by claude-code/codex setup.
|
|
74
|
+
*/
|
|
75
|
+
export function persistCredentials(explicit, legacy = {}) {
|
|
76
|
+
const saved = loadUserConfig();
|
|
77
|
+
const patch = {
|
|
78
|
+
apiUrl: explicit.apiUrl ?? (saved.apiUrl ? undefined : legacy.apiUrl),
|
|
79
|
+
apiKey: explicit.apiKey ?? (saved.apiKey ? undefined : legacy.apiKey),
|
|
80
|
+
map: explicit.map,
|
|
81
|
+
};
|
|
82
|
+
const path = patch.apiUrl || patch.apiKey || patch.map ? saveUserConfig(patch) : userConfigPath();
|
|
83
|
+
return { ...loadUserConfig(), path };
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=user-config.js.map
|
package/dist/doctor.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NpcConfig } from './core/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Diagnose connectivity to the Nocville API: hit `/api/v1/health/ready`, then POST a single
|
|
4
|
+
* offline status push and report HTTP status, latency, and rate-limit headroom.
|
|
5
|
+
*/
|
|
6
|
+
export declare function runDoctor(config: NpcConfig): Promise<void>;
|
|
7
|
+
export declare function hasCodexHookWatcherOverlap(dir?: string): boolean;
|
|
8
|
+
//# sourceMappingURL=doctor.d.ts.map
|
package/dist/doctor.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { readdirSync } from 'node:fs';
|
|
3
|
+
import { isAgentAlive } from './npcs/agent-common/liveness.js';
|
|
4
|
+
import { CODEX_DEFAULTS } from './npcs/codex/defaults.js';
|
|
5
|
+
/**
|
|
6
|
+
* Diagnose connectivity to the Nocville API: hit `/api/v1/health/ready`, then POST a single
|
|
7
|
+
* offline status push and report HTTP status, latency, and rate-limit headroom.
|
|
8
|
+
*/
|
|
9
|
+
export async function runDoctor(config) {
|
|
10
|
+
const apiUrl = config.apiUrl.replace(/\/+$/, '');
|
|
11
|
+
console.log(`nocville-npc doctor — checking ${apiUrl}`);
|
|
12
|
+
console.log('');
|
|
13
|
+
if (hasCodexHookWatcherOverlap())
|
|
14
|
+
console.warn(' [WARN] Codex hooks and codex watch are both active. Stop the fallback watcher; hooks own these sessions.');
|
|
15
|
+
// 1) Health check
|
|
16
|
+
let healthOk = false;
|
|
17
|
+
{
|
|
18
|
+
const start = Date.now();
|
|
19
|
+
const t = withTimeout(5000);
|
|
20
|
+
try {
|
|
21
|
+
const res = await fetch(`${apiUrl}/api/v1/health/ready`, { method: 'GET', signal: t.signal });
|
|
22
|
+
const ms = Date.now() - start;
|
|
23
|
+
const body = await res.text();
|
|
24
|
+
healthOk = res.ok;
|
|
25
|
+
console.log(` [${res.ok ? 'OK' : 'FAIL'}] GET /api/v1/health/ready -> ${res.status} (${ms}ms)`);
|
|
26
|
+
if (config.debug)
|
|
27
|
+
console.log(` ${body.slice(0, 200)}`);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
console.log(` [FAIL] GET /api/v1/health/ready -> ${err instanceof Error ? err.message : String(err)}`);
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
t.done();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// 2) Test status push
|
|
37
|
+
let pushOk = false;
|
|
38
|
+
const hasKey = Boolean(config.apiKey);
|
|
39
|
+
if (!hasKey) {
|
|
40
|
+
console.log(' [SKIP] POST /api/v1/status — no --api-key / NOCVILLE_API_KEY set');
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const start = Date.now();
|
|
44
|
+
const t = withTimeout(5000);
|
|
45
|
+
try {
|
|
46
|
+
const res = await fetch(`${apiUrl}/api/v1/status`, {
|
|
47
|
+
method: 'POST',
|
|
48
|
+
headers: {
|
|
49
|
+
'Content-Type': 'application/json',
|
|
50
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
51
|
+
},
|
|
52
|
+
signal: t.signal,
|
|
53
|
+
body: JSON.stringify({
|
|
54
|
+
// Unique offline probe: personal-key ownership must not reserve a shared doctor ID.
|
|
55
|
+
serviceId: `${(config.serviceId || 'npc').slice(0, 60)}-doctor-${randomUUID().slice(0, 16)}`,
|
|
56
|
+
status: 'unknown',
|
|
57
|
+
mood: 'idle',
|
|
58
|
+
offline: true,
|
|
59
|
+
subStatus: 'offline',
|
|
60
|
+
...(config.map ? { map: config.map } : {}),
|
|
61
|
+
}),
|
|
62
|
+
});
|
|
63
|
+
const ms = Date.now() - start;
|
|
64
|
+
const text = await res.text();
|
|
65
|
+
pushOk = res.ok;
|
|
66
|
+
let remaining = res.headers.get('x-ratelimit-remaining') ?? res.headers.get('ratelimit-remaining');
|
|
67
|
+
if (!remaining) {
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(text);
|
|
70
|
+
if (typeof parsed.remaining === 'number')
|
|
71
|
+
remaining = String(parsed.remaining);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// non-JSON body
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
console.log(` [${res.ok ? 'OK' : 'FAIL'}] POST /api/v1/status -> ${res.status} ` +
|
|
78
|
+
`(${ms}ms, rate-limit remaining: ${remaining ?? 'n/a'})`);
|
|
79
|
+
if (config.map)
|
|
80
|
+
console.log(` target map: ${config.map}`);
|
|
81
|
+
if (!res.ok)
|
|
82
|
+
console.log(` ${text.slice(0, 200)}`);
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
console.log(` [FAIL] POST /api/v1/status -> ${err instanceof Error ? err.message : String(err)}`);
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
t.done();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Verdict
|
|
92
|
+
console.log('');
|
|
93
|
+
if (healthOk && pushOk) {
|
|
94
|
+
console.log('Verdict: OK — API reachable and status push accepted.');
|
|
95
|
+
console.log('The offline probe does not create a coworker in your office.');
|
|
96
|
+
}
|
|
97
|
+
else if (!healthOk) {
|
|
98
|
+
console.log('Verdict: FAIL — API health check is unreachable. Check --api-url and that the server is running.');
|
|
99
|
+
}
|
|
100
|
+
else if (!hasKey) {
|
|
101
|
+
console.log('Verdict: PARTIAL — API is up, but no API key was provided to test a push.');
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
console.log('Verdict: FAIL — API is up but the push was rejected. Check your API key / team settings.');
|
|
105
|
+
}
|
|
106
|
+
process.exitCode = healthOk && (pushOk || !hasKey) ? 0 : 1;
|
|
107
|
+
}
|
|
108
|
+
function withTimeout(timeoutMs) {
|
|
109
|
+
const controller = new AbortController();
|
|
110
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
111
|
+
return { signal: controller.signal, done: () => clearTimeout(timer) };
|
|
112
|
+
}
|
|
113
|
+
export function hasCodexHookWatcherOverlap(dir = CODEX_DEFAULTS.stateDir) {
|
|
114
|
+
try {
|
|
115
|
+
const files = readdirSync(dir);
|
|
116
|
+
return (files.some((file) => /^session-.*\.json$/.test(file)) &&
|
|
117
|
+
files.some((file) => {
|
|
118
|
+
const match = file.match(/^watcher-(\d+)\.pid$/);
|
|
119
|
+
return !!match && isAgentAlive({ pid: Number(match[1]) });
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=doctor.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export { BaseNPC } from './core/base-npc.js';
|
|
2
|
+
export { PollingNPC } from './core/polling-npc.js';
|
|
3
|
+
export type { PollingNpcConfig } from './core/polling-npc.js';
|
|
4
|
+
export { EventNPC } from './core/event-npc.js';
|
|
5
|
+
export { Logger } from './core/logger.js';
|
|
6
|
+
export { parseArgs, resolveConfig, stringFlag, boolFlag, numberFlag } from './core/config.js';
|
|
7
|
+
export type { ParsedArgs } from './core/config.js';
|
|
8
|
+
export { evaluateThreshold, worstStatus } from './core/thresholds.js';
|
|
9
|
+
export { truncate } from './core/text.js';
|
|
10
|
+
export { statusColor, pushHistory } from './core/screen.js';
|
|
11
|
+
export type { ScreenColor } from './core/screen.js';
|
|
12
|
+
export type { Status, Mood, NpcConfig, CollectedMetrics, ThresholdConfig, NpcState, LogLevelName, Archetype, BehaviorHints, CompanionSpec, CompanionDecl, ScreenData, ScreenValue, } from './core/types.js';
|
|
13
|
+
export { SystemMonitorNPC } from './npcs/system-monitor/index.js';
|
|
14
|
+
export type { SystemMonitorConfig } from './npcs/system-monitor/index.js';
|
|
15
|
+
export { ClaudeCodeNPC, handleClaudeCodeCommand, handleHookEvent, setupHooks, uninstallHooks, processHookEvent, claudeTransition, } from './npcs/claude-code/index.js';
|
|
16
|
+
export type { ClaudeCodeSubcommandOptions, SetupOptions, SessionState, HookEvent, StatusOutput, SessionMachineState, } from './npcs/claude-code/index.js';
|
|
17
|
+
export { handleCodexCommand, handleCodexHookEvent, codexTransition, setupCodexHooks, uninstallCodexHooks, parseRolloutLine, CodexWatcher, } from './npcs/codex/index.js';
|
|
18
|
+
export type { CodexSetupOptions, CodexWatcherOptions, RolloutSignal } from './npcs/codex/index.js';
|
|
19
|
+
export { describeToolUse, shortCommand, shortPath, redactSecrets, } from './npcs/agent-common/activity.js';
|
|
20
|
+
export { loadUserConfig, saveUserConfig, userConfigPath } from './core/user-config.js';
|
|
21
|
+
export { loadSessionFilter, sessionFilterPath, sessionPublishDecision, ensureSessionFilterTemplate, } from './core/session-filter.js';
|
|
22
|
+
export type { SessionFilter, SessionRules, PublishDecision } from './core/session-filter.js';
|
|
23
|
+
export type { UserConfig } from './core/user-config.js';
|
|
24
|
+
export { InternetConnectivityNPC } from './npcs/internet-connectivity/index.js';
|
|
25
|
+
export type { InternetConnectivityConfig } from './npcs/internet-connectivity/index.js';
|
|
26
|
+
export { ProcessWatcherNPC } from './npcs/process-watcher/index.js';
|
|
27
|
+
export type { ProcessWatcherConfig } from './npcs/process-watcher/index.js';
|
|
28
|
+
export { LogWatcherNPC } from './npcs/log-watcher/index.js';
|
|
29
|
+
export type { LogWatcherConfig } from './npcs/log-watcher/index.js';
|
|
30
|
+
export { ReceptionistNPC } from './npcs/receptionist/index.js';
|
|
31
|
+
export type { ReceptionistConfig } from './npcs/receptionist/index.js';
|
|
32
|
+
export { GitHubWatcherNPC } from './npcs/github-watcher/index.js';
|
|
33
|
+
export type { GitHubWatcherConfig } from './npcs/github-watcher/index.js';
|
|
34
|
+
export { WebPageWatcherNPC } from './npcs/web-page-watcher/index.js';
|
|
35
|
+
export type { WebPageWatcherConfig } from './npcs/web-page-watcher/index.js';
|
|
36
|
+
export { GEMINI_DEFAULTS, GEMINI_ADAPTER, geminiTransition, geminiServiceId, handleGeminiHookEvent, setupGeminiHooks, uninstallGeminiHooks, installGeminiHooksInto, GEMINI_HOOK_EVENTS, } from './npcs/gemini/index.js';
|
|
37
|
+
export type { GeminiSetupOptions } from './npcs/gemini/index.js';
|
|
38
|
+
export { CURSOR_DEFAULTS, CURSOR_ADAPTER, cursorServiceId, handleCursorHookEvent, setupCursorHooks, uninstallCursorHooks, installCursorHooksInto, CURSOR_HOOK_EVENTS, } from './npcs/cursor/index.js';
|
|
39
|
+
export type { CursorSetupOptions } from './npcs/cursor/index.js';
|
|
40
|
+
export { isCursorInvocation, normalizeCursorEvent } from './npcs/cursor/normalize.js';
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Core
|
|
2
|
+
export { BaseNPC } from './core/base-npc.js';
|
|
3
|
+
export { PollingNPC } from './core/polling-npc.js';
|
|
4
|
+
export { EventNPC } from './core/event-npc.js';
|
|
5
|
+
export { Logger } from './core/logger.js';
|
|
6
|
+
export { parseArgs, resolveConfig, stringFlag, boolFlag, numberFlag } from './core/config.js';
|
|
7
|
+
export { evaluateThreshold, worstStatus } from './core/thresholds.js';
|
|
8
|
+
export { truncate } from './core/text.js';
|
|
9
|
+
export { statusColor, pushHistory } from './core/screen.js';
|
|
10
|
+
// NPCs
|
|
11
|
+
export { SystemMonitorNPC } from './npcs/system-monitor/index.js';
|
|
12
|
+
export { ClaudeCodeNPC, handleClaudeCodeCommand, handleHookEvent, setupHooks, uninstallHooks, processHookEvent, claudeTransition, } from './npcs/claude-code/index.js';
|
|
13
|
+
export { handleCodexCommand, handleCodexHookEvent, codexTransition, setupCodexHooks, uninstallCodexHooks, parseRolloutLine, CodexWatcher, } from './npcs/codex/index.js';
|
|
14
|
+
export { describeToolUse, shortCommand, shortPath, redactSecrets, } from './npcs/agent-common/activity.js';
|
|
15
|
+
export { loadUserConfig, saveUserConfig, userConfigPath } from './core/user-config.js';
|
|
16
|
+
export { loadSessionFilter, sessionFilterPath, sessionPublishDecision, ensureSessionFilterTemplate, } from './core/session-filter.js';
|
|
17
|
+
export { InternetConnectivityNPC } from './npcs/internet-connectivity/index.js';
|
|
18
|
+
export { ProcessWatcherNPC } from './npcs/process-watcher/index.js';
|
|
19
|
+
export { LogWatcherNPC } from './npcs/log-watcher/index.js';
|
|
20
|
+
export { ReceptionistNPC } from './npcs/receptionist/index.js';
|
|
21
|
+
export { GitHubWatcherNPC } from './npcs/github-watcher/index.js';
|
|
22
|
+
export { WebPageWatcherNPC } from './npcs/web-page-watcher/index.js';
|
|
23
|
+
export { GEMINI_DEFAULTS, GEMINI_ADAPTER, geminiTransition, geminiServiceId, handleGeminiHookEvent, setupGeminiHooks, uninstallGeminiHooks, installGeminiHooksInto, GEMINI_HOOK_EVENTS, } from './npcs/gemini/index.js';
|
|
24
|
+
export { CURSOR_DEFAULTS, CURSOR_ADAPTER, cursorServiceId, handleCursorHookEvent, setupCursorHooks, uninstallCursorHooks, installCursorHooksInto, CURSOR_HOOK_EVENTS, } from './npcs/cursor/index.js';
|
|
25
|
+
export { isCursorInvocation, normalizeCursorEvent } from './npcs/cursor/normalize.js';
|
|
26
|
+
//# sourceMappingURL=index.js.map
|