@rubytech/create-maxy-code 0.1.164 → 0.1.166
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/index.js +17 -9
- package/package.json +1 -1
- package/payload/platform/neo4j/schema.cypher +3 -5
- package/payload/platform/plugins/email/PLUGIN.md +2 -2
- package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts +0 -29
- package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/credentials.js +7 -115
- package/payload/platform/plugins/email/mcp/dist/lib/credentials.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +7 -44
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js +24 -177
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-read.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-read.js +4 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-read.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-search.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-search.js +4 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-search.js.map +1 -1
- package/payload/platform/plugins/email/skills/email-composition/SKILL.md +1 -1
- package/payload/platform/plugins/memory/references/schema-base.md +1 -1
- package/payload/platform/plugins/memory/references/schema-estate-agent.md +1 -1
- package/payload/platform/scripts/lib/read-brand-json.sh +1 -1
- package/payload/platform/scripts/lib/resolve-account-dir.sh +1 -1
- package/payload/platform/scripts/seed-neo4j.sh +29 -421
- package/payload/platform/scripts/setup-account.sh +370 -0
- package/payload/platform/services/claude-session-manager/dist/config.js +2 -2
- package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts +9 -1
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +74 -38
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +16 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +16 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +21 -7
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts +7 -0
- package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-sidecar.js +10 -0
- package/payload/platform/services/claude-session-manager/dist/session-sidecar.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/systemd-scope.d.ts +52 -10
- package/payload/platform/services/claude-session-manager/dist/systemd-scope.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/systemd-scope.js +73 -13
- package/payload/platform/services/claude-session-manager/dist/systemd-scope.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================
|
|
3
|
+
# setup-account.sh — Phase 0 account setup
|
|
4
|
+
# Creates the account directory from templates, writes the
|
|
5
|
+
# Claude Code project settings file (hooks only — no permission
|
|
6
|
+
# allowlist; native agent frontmatter is the permission surface),
|
|
7
|
+
# installs specialist plugin templates, seeds account.json
|
|
8
|
+
# defaults, and resolves the owner userId. Neo4j seeding lives
|
|
9
|
+
# in `seed-neo4j.sh`; this script does no Neo4j work.
|
|
10
|
+
# ============================================================
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
16
|
+
TEMPLATES_DIR="$PROJECT_DIR/templates"
|
|
17
|
+
# Accounts live at {installDir}/data/accounts/ — outside the platform/ wipe zone.
|
|
18
|
+
INSTALL_DIR="$(dirname "$PROJECT_DIR")"
|
|
19
|
+
ACCOUNTS_DIR="$INSTALL_DIR/data/accounts"
|
|
20
|
+
|
|
21
|
+
# ------------------------------------------------------------------
|
|
22
|
+
# 1. Resolve / create account directory
|
|
23
|
+
# ------------------------------------------------------------------
|
|
24
|
+
# Resolve existing account by identity (users.json[0].userId) or mint a new one on fresh install.
|
|
25
|
+
# Orphan siblings under data/accounts/ — non-matching dirs left behind by the userId
|
|
26
|
+
# regeneration — are swept to data/accounts/.trash/<uuid>-<ISO8601-ts>/. Multi-candidate with
|
|
27
|
+
# no identity match aborts loud; .trash/ is operator-emptied, never auto-cleaned.
|
|
28
|
+
# shellcheck source=lib/resolve-account-dir.sh
|
|
29
|
+
. "$SCRIPT_DIR/lib/resolve-account-dir.sh"
|
|
30
|
+
# shellcheck source=lib/read-brand-json.sh
|
|
31
|
+
. "$SCRIPT_DIR/lib/read-brand-json.sh"
|
|
32
|
+
# Resolve brand-aware persistent users.json path before the resolver runs.
|
|
33
|
+
_RESOLVER_CONFIG_DIR_NAME=".maxy"
|
|
34
|
+
read_brand_json_key "$PROJECT_DIR/config/brand.json" "configDir"
|
|
35
|
+
[ -n "$BRAND_JSON_VALUE" ] && _RESOLVER_CONFIG_DIR_NAME="$BRAND_JSON_VALUE"
|
|
36
|
+
USERS_FILE="$HOME/$_RESOLVER_CONFIG_DIR_NAME/users.json" resolve_and_sweep_account_dir
|
|
37
|
+
|
|
38
|
+
mkdir -p "$ACCOUNT_DIR/agents/admin" "$ACCOUNT_DIR/agents/public" "$ACCOUNT_DIR/.claude" "$ACCOUNT_DIR/specialists/.claude-plugin" "$ACCOUNT_DIR/specialists/agents"
|
|
39
|
+
|
|
40
|
+
# Claude Code discovers project-level .claude/ (agents, settings) relative to the
|
|
41
|
+
# nearest .git root. Without a .git in the account directory, Claude Code traverses
|
|
42
|
+
# up to ~/maxy/.git and misses everything in accountDir/.claude/. Initialise a git
|
|
43
|
+
# repo so the account directory IS the project root for Claude Code.
|
|
44
|
+
[ -d "$ACCOUNT_DIR/.git" ] || git init -q "$ACCOUNT_DIR"
|
|
45
|
+
|
|
46
|
+
# ------------------------------------------------------------------
|
|
47
|
+
# 2. Write project-level .claude/settings.json (HOOKS ONLY)
|
|
48
|
+
# ------------------------------------------------------------------
|
|
49
|
+
# Task 453: no `permissions.allow` block. The previous short-prefix
|
|
50
|
+
# allowlist (mcp__memory__*, mcp__contacts__*, …) never matched the
|
|
51
|
+
# plugin-manifest long-prefix tool names Claude Code actually emits
|
|
52
|
+
# (mcp__plugin_memory_memory__…), so every Task-subagent plugin call
|
|
53
|
+
# was denied at use-time. Permission enforcement comes from each agent's
|
|
54
|
+
# frontmatter `tools:` list (native CC permission surface) and from the
|
|
55
|
+
# PreToolUse approval hooks below for review-gated tools.
|
|
56
|
+
#
|
|
57
|
+
# Hook commands use $PLATFORM_ROOT (set by claude-agent.ts at spawn time)
|
|
58
|
+
# to locate scripts relative to the platform installation, not the account dir.
|
|
59
|
+
ACCOUNT_SETTINGS="$ACCOUNT_DIR/.claude/settings.json"
|
|
60
|
+
HOOKS_PATH="\$PLATFORM_ROOT/plugins/admin/hooks"
|
|
61
|
+
cat > "$ACCOUNT_SETTINGS" << SETTINGS_EOF
|
|
62
|
+
{
|
|
63
|
+
"hooks": {
|
|
64
|
+
"PreToolUse": [
|
|
65
|
+
{
|
|
66
|
+
"matcher": "Write",
|
|
67
|
+
"hooks": [
|
|
68
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/pre-tool-use.sh admin" },
|
|
69
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" }
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"matcher": "Edit",
|
|
74
|
+
"hooks": [
|
|
75
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/pre-tool-use.sh admin" },
|
|
76
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" }
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"matcher": "NotebookEdit",
|
|
81
|
+
"hooks": [
|
|
82
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" }
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"matcher": "Bash",
|
|
87
|
+
"hooks": [
|
|
88
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/pre-tool-use.sh admin" },
|
|
89
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" }
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"matcher": "mcp__plugin_memory_memory__memory-write",
|
|
94
|
+
"hooks": [
|
|
95
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/pre-tool-use.sh admin" }
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"matcher": "mcp__plugin_memory_memory__memory-update",
|
|
100
|
+
"hooks": [
|
|
101
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/pre-tool-use.sh admin" }
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"hooks": [
|
|
106
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" }
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"matcher": "mcp__plugin_playwright_playwright__browser_navigate",
|
|
111
|
+
"hooks": [
|
|
112
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/playwright-file-guard.sh" }
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"matcher": "WebFetch",
|
|
117
|
+
"hooks": [
|
|
118
|
+
{ "type": "command", "command": "node $HOOKS_PATH/webfetch-preflight.mjs" }
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"matcher": "AskUserQuestion",
|
|
123
|
+
"hooks": [
|
|
124
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/askuserquestion-investigate-gate.sh" }
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
"PostToolUse": [
|
|
129
|
+
{
|
|
130
|
+
"matcher": "mcp__.*__.*-(export|import)-parse$",
|
|
131
|
+
"hooks": [
|
|
132
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" }
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"UserPromptSubmit": [
|
|
137
|
+
{
|
|
138
|
+
"hooks": [
|
|
139
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" }
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
],
|
|
143
|
+
"Stop": [
|
|
144
|
+
{
|
|
145
|
+
"hooks": [
|
|
146
|
+
{ "type": "command", "command": "bash $HOOKS_PATH/session-end-retrospective.sh" }
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
SETTINGS_EOF
|
|
153
|
+
|
|
154
|
+
# ------------------------------------------------------------------
|
|
155
|
+
# 3. Install agent identities and specialist plugin templates
|
|
156
|
+
# ------------------------------------------------------------------
|
|
157
|
+
# Always overwrite IDENTITY.md — Rubytech-controlled, pure behaviour.
|
|
158
|
+
cp "$TEMPLATES_DIR/agents/admin/IDENTITY.md" "$ACCOUNT_DIR/agents/admin/IDENTITY.md"
|
|
159
|
+
cp "$TEMPLATES_DIR/agents/public/IDENTITY.md" "$ACCOUNT_DIR/agents/public/IDENTITY.md"
|
|
160
|
+
echo " agents/public/IDENTITY.md installed"
|
|
161
|
+
|
|
162
|
+
# Always overwrite specialist plugin — Rubytech-controlled, not user-editable.
|
|
163
|
+
# Specialists are a Claude Code plugin loaded via --plugin-dir. The plugin lives at
|
|
164
|
+
# accountDir/specialists/ with .claude-plugin/plugin.json and agents/*.md.
|
|
165
|
+
# The admin agent dispatches them as specialists:{name} via the Agent tool.
|
|
166
|
+
cp "$TEMPLATES_DIR/specialists/.claude-plugin/plugin.json" "$ACCOUNT_DIR/specialists/.claude-plugin/plugin.json"
|
|
167
|
+
|
|
168
|
+
# Remove orphaned core specialist files before copying fresh templates.
|
|
169
|
+
# Core specialists (no '--' in filename) are Rubytech-controlled and fully replaced
|
|
170
|
+
# on every seed. Premium plugin agents (filename contains '--') are preserved —
|
|
171
|
+
# they are managed by the admin agent when plugins are activated/deactivated.
|
|
172
|
+
for _existing in "$ACCOUNT_DIR/specialists/agents/"*.md; do
|
|
173
|
+
[ -f "$_existing" ] || continue
|
|
174
|
+
case "$(basename "$_existing")" in
|
|
175
|
+
*--*) continue ;; # Premium plugin agent — preserve
|
|
176
|
+
esac
|
|
177
|
+
rm -f "$_existing"
|
|
178
|
+
done
|
|
179
|
+
|
|
180
|
+
for specialist in "$TEMPLATES_DIR/specialists/agents/"*.md; do
|
|
181
|
+
[ -f "$specialist" ] && cp "$specialist" "$ACCOUNT_DIR/specialists/agents/$(basename "$specialist")"
|
|
182
|
+
done
|
|
183
|
+
|
|
184
|
+
# Clean up stale .claude/agents/*.md from previous seed format.
|
|
185
|
+
# The old format placed specialists here as slash-command agents — that never worked
|
|
186
|
+
# for programmatic dispatch. Safe to remove; .claude/ dir stays for settings.json.
|
|
187
|
+
rm -f "$ACCOUNT_DIR/.claude/agents/"*.md 2>/dev/null || true
|
|
188
|
+
|
|
189
|
+
# SOUL.md — user-controlled personalisation. Only create if missing. Never overwrite.
|
|
190
|
+
[ -f "$ACCOUNT_DIR/agents/admin/SOUL.md" ] || cp "$TEMPLATES_DIR/agents/admin/SOUL.md" "$ACCOUNT_DIR/agents/admin/SOUL.md"
|
|
191
|
+
|
|
192
|
+
# Public agent SOUL.md + config.json — create if missing, never overwrite.
|
|
193
|
+
# IDENTITY.md is handled in the Rubytech-controlled block above.
|
|
194
|
+
[ -f "$ACCOUNT_DIR/agents/public/SOUL.md" ] || cp "$TEMPLATES_DIR/agents/public/SOUL.md" "$ACCOUNT_DIR/agents/public/SOUL.md"
|
|
195
|
+
[ -f "$ACCOUNT_DIR/agents/public/config.json" ] || cp "$TEMPLATES_DIR/agents/public/config.json" "$ACCOUNT_DIR/agents/public/config.json"
|
|
196
|
+
|
|
197
|
+
# AGENTS.md — specialist registry. Pre-populated from templates, maintained by admin agent at runtime.
|
|
198
|
+
# Always overwrite on re-seed (Rubytech-controlled initial state, like IDENTITY.md).
|
|
199
|
+
# Dispatch format: specialists:{name} via the Agent tool.
|
|
200
|
+
printf '# Installed Roles\n\nDispatch via the Agent tool with `subagent_type: "specialists:{name}"`.\n\n' > "$ACCOUNT_DIR/agents/admin/AGENTS.md"
|
|
201
|
+
for specialist in "$ACCOUNT_DIR/specialists/agents/"*.md; do
|
|
202
|
+
[ -f "$specialist" ] || continue
|
|
203
|
+
# Extract name and description from YAML frontmatter
|
|
204
|
+
_name=$(sed -n 's/^name: *//p' "$specialist" | head -1)
|
|
205
|
+
_desc=$(sed -n 's/^description: *"*//p' "$specialist" | sed 's/"$//' | head -1)
|
|
206
|
+
[ -z "$_name" ] && continue
|
|
207
|
+
# Skip Phase 1 stubs — not yet functional
|
|
208
|
+
echo "$_desc" | grep -qi "Phase 1" && continue
|
|
209
|
+
printf -- '- **specialists:%s**: %s\n' "$_name" "$_desc" >> "$ACCOUNT_DIR/agents/admin/AGENTS.md"
|
|
210
|
+
done
|
|
211
|
+
|
|
212
|
+
# ------------------------------------------------------------------
|
|
213
|
+
# 4. Create / backfill account.json
|
|
214
|
+
# ------------------------------------------------------------------
|
|
215
|
+
# Create account.json only if it doesn't exist (business config is in the graph).
|
|
216
|
+
# Reads defaults from the template so there is a single source of truth.
|
|
217
|
+
if [ ! -f "$ACCOUNT_DIR/account.json" ]; then
|
|
218
|
+
TEMPLATE="$TEMPLATES_DIR/account.json"
|
|
219
|
+
if [ -f "$TEMPLATE" ]; then
|
|
220
|
+
sed "s/\"accountId\": *\"[^\"]*\"/\"accountId\":\"$ACCOUNT_ID\"/" "$TEMPLATE" \
|
|
221
|
+
| sed "s/\"tier\": *\"[^\"]*\"/\"tier\":\"solo\"/" \
|
|
222
|
+
> "$ACCOUNT_DIR/account.json"
|
|
223
|
+
else
|
|
224
|
+
echo "ERROR: account.json template not found at $TEMPLATE" >&2
|
|
225
|
+
exit 1
|
|
226
|
+
fi
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
# Backfill defaultAgent in account.json if missing (existing accounts earlier).
|
|
230
|
+
# Uses the first non-admin agent directory that has a config.json.
|
|
231
|
+
if [ -f "$ACCOUNT_DIR/account.json" ] && ! grep -q '"defaultAgent"' "$ACCOUNT_DIR/account.json"; then
|
|
232
|
+
_DEFAULT_SLUG=""
|
|
233
|
+
for _AGENT_DIR in "$ACCOUNT_DIR/agents"/*/; do
|
|
234
|
+
_AGENT_NAME="$(basename "$_AGENT_DIR")"
|
|
235
|
+
[ "$_AGENT_NAME" = "admin" ] && continue
|
|
236
|
+
[ -f "$_AGENT_DIR/config.json" ] && { _DEFAULT_SLUG="$_AGENT_NAME"; break; }
|
|
237
|
+
done
|
|
238
|
+
if [ -n "$_DEFAULT_SLUG" ]; then
|
|
239
|
+
# Insert defaultAgent before the closing brace
|
|
240
|
+
sed -i'' "s/}$/,\"defaultAgent\":\"$_DEFAULT_SLUG\"}/" "$ACCOUNT_DIR/account.json"
|
|
241
|
+
echo " Backfilled defaultAgent=$_DEFAULT_SLUG in account.json"
|
|
242
|
+
fi
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
# ------------------------------------------------------------------
|
|
246
|
+
# 5. Seed enabledPlugins from brand.json plugins.defaultEnabled
|
|
247
|
+
# ------------------------------------------------------------------
|
|
248
|
+
# Fresh accounts: replaces the template's empty [] with defaultEnabled.
|
|
249
|
+
# Existing accounts: additive merge — adds missing defaultEnabled entries,
|
|
250
|
+
# never removes plugins the user enabled manually.
|
|
251
|
+
# Dependency validation: skips any defaultEnabled plugin whose PLUGIN.md
|
|
252
|
+
# `requires:` dependencies are not satisfied by core or defaultEnabled.
|
|
253
|
+
BRAND_JSON="$PROJECT_DIR/config/brand.json"
|
|
254
|
+
if [ -f "$BRAND_JSON" ] && [ -f "$ACCOUNT_DIR/account.json" ]; then
|
|
255
|
+
python3 -c "
|
|
256
|
+
import json, os, sys
|
|
257
|
+
|
|
258
|
+
brand_path = '$BRAND_JSON'
|
|
259
|
+
account_path = '$ACCOUNT_DIR/account.json'
|
|
260
|
+
plugins_dir = '$PROJECT_DIR/plugins'
|
|
261
|
+
|
|
262
|
+
with open(brand_path) as f:
|
|
263
|
+
brand = json.load(f)
|
|
264
|
+
|
|
265
|
+
plugins_cfg = brand.get('plugins', {})
|
|
266
|
+
default_enabled = plugins_cfg.get('defaultEnabled', [])
|
|
267
|
+
core = set(plugins_cfg.get('core', []))
|
|
268
|
+
|
|
269
|
+
if not default_enabled:
|
|
270
|
+
print(' [setup] no defaultEnabled plugins in brand.json — skipping')
|
|
271
|
+
sys.exit(0)
|
|
272
|
+
|
|
273
|
+
# Dependency validation: check each plugin's PLUGIN.md requires field.
|
|
274
|
+
# A dependency is satisfied if it appears in core or in defaultEnabled.
|
|
275
|
+
satisfied = core | set(default_enabled)
|
|
276
|
+
validated = []
|
|
277
|
+
for plugin in default_enabled:
|
|
278
|
+
plugin_md = os.path.join(plugins_dir, plugin, 'PLUGIN.md')
|
|
279
|
+
requires = []
|
|
280
|
+
if os.path.isfile(plugin_md):
|
|
281
|
+
in_frontmatter = False
|
|
282
|
+
in_requires = False
|
|
283
|
+
with open(plugin_md) as f:
|
|
284
|
+
for line in f:
|
|
285
|
+
stripped = line.rstrip()
|
|
286
|
+
if stripped == '---':
|
|
287
|
+
if in_frontmatter:
|
|
288
|
+
break
|
|
289
|
+
in_frontmatter = True
|
|
290
|
+
continue
|
|
291
|
+
if not in_frontmatter:
|
|
292
|
+
continue
|
|
293
|
+
if stripped.startswith('requires:'):
|
|
294
|
+
# Handle inline list: requires: [a, b]
|
|
295
|
+
inline = stripped.split(':', 1)[1].strip()
|
|
296
|
+
if inline.startswith('['):
|
|
297
|
+
requires = [x.strip().strip('\"').strip(\"'\") for x in inline.strip('[]').split(',') if x.strip()]
|
|
298
|
+
in_requires = False
|
|
299
|
+
else:
|
|
300
|
+
in_requires = True
|
|
301
|
+
continue
|
|
302
|
+
if in_requires:
|
|
303
|
+
if stripped.startswith(' - '):
|
|
304
|
+
requires.append(stripped.lstrip(' -').strip())
|
|
305
|
+
else:
|
|
306
|
+
in_requires = False
|
|
307
|
+
unmet = [r for r in requires if r not in satisfied]
|
|
308
|
+
if unmet:
|
|
309
|
+
print(f' [setup] WARNING: skipping defaultEnabled plugin \"{plugin}\" — unmet requires: {unmet}')
|
|
310
|
+
else:
|
|
311
|
+
validated.append(plugin)
|
|
312
|
+
|
|
313
|
+
with open(account_path) as f:
|
|
314
|
+
account = json.load(f)
|
|
315
|
+
|
|
316
|
+
existing = account.get('enabledPlugins', [])
|
|
317
|
+
existing_set = set(existing)
|
|
318
|
+
added = [p for p in validated if p not in existing_set]
|
|
319
|
+
account['enabledPlugins'] = existing + added
|
|
320
|
+
|
|
321
|
+
with open(account_path, 'w') as f:
|
|
322
|
+
json.dump(account, f, indent=2)
|
|
323
|
+
f.write('\n')
|
|
324
|
+
|
|
325
|
+
if not existing:
|
|
326
|
+
print(f' [setup] seeded enabledPlugins: {validated}')
|
|
327
|
+
elif added:
|
|
328
|
+
print(f' [setup] merged into enabledPlugins: +{added} (existing: {existing})')
|
|
329
|
+
else:
|
|
330
|
+
print(f' [setup] enabledPlugins already contains all defaultEnabled entries')
|
|
331
|
+
"
|
|
332
|
+
fi
|
|
333
|
+
|
|
334
|
+
# ------------------------------------------------------------------
|
|
335
|
+
# 6. Stamp first admin userId into account.json (if users.json present)
|
|
336
|
+
# ------------------------------------------------------------------
|
|
337
|
+
# users.json is created by the set-pin POST during onboarding. This
|
|
338
|
+
# script reads it to stamp the owner into account.json admins[]; the
|
|
339
|
+
# matching :AdminUser graph node is created by seed-neo4j.sh.
|
|
340
|
+
CONFIG_DIR="$PROJECT_DIR/config"
|
|
341
|
+
_CONFIG_DIR_NAME=".maxy"
|
|
342
|
+
read_brand_json_key "$CONFIG_DIR/brand.json" "configDir"
|
|
343
|
+
[ -n "$BRAND_JSON_VALUE" ] && _CONFIG_DIR_NAME="$BRAND_JSON_VALUE"
|
|
344
|
+
USERS_FILE="$HOME/$_CONFIG_DIR_NAME/users.json"
|
|
345
|
+
mkdir -p "$HOME/$_CONFIG_DIR_NAME"
|
|
346
|
+
|
|
347
|
+
if [ -f "$USERS_FILE" ]; then
|
|
348
|
+
USER_ID=$(python3 -c "import json; print(json.load(open('$USERS_FILE'))[0]['userId'])" 2>/dev/null || true)
|
|
349
|
+
[ -n "$USER_ID" ] && echo " Existing users.json found, userId=$USER_ID"
|
|
350
|
+
|
|
351
|
+
# Ensure account.json admins[] contains the owner. Idempotent.
|
|
352
|
+
if [ -n "$USER_ID" ] && [ -f "$ACCOUNT_DIR/account.json" ]; then
|
|
353
|
+
python3 -c "
|
|
354
|
+
import json
|
|
355
|
+
with open('$ACCOUNT_DIR/account.json', 'r') as f:
|
|
356
|
+
config = json.load(f)
|
|
357
|
+
config.setdefault('admins', [])
|
|
358
|
+
if not any(a.get('userId') == '$USER_ID' for a in config['admins']):
|
|
359
|
+
config['admins'].append({'userId': '$USER_ID', 'role': 'owner'})
|
|
360
|
+
with open('$ACCOUNT_DIR/account.json', 'w') as f:
|
|
361
|
+
json.dump(config, f, indent=2)
|
|
362
|
+
f.write('\n')
|
|
363
|
+
print(' Stamped userId=$USER_ID as owner in account.json admins')
|
|
364
|
+
"
|
|
365
|
+
fi
|
|
366
|
+
else
|
|
367
|
+
echo " No users.json found — skipping owner stamp (set-pin POST creates it)"
|
|
368
|
+
fi
|
|
369
|
+
|
|
370
|
+
echo " Account $ACCOUNT_ID at $ACCOUNT_DIR"
|
|
@@ -177,12 +177,12 @@ export function loadConfig(env = process.env) {
|
|
|
177
177
|
const accountDir = resolveAccountDir(platformRoot);
|
|
178
178
|
if (!accountDir) {
|
|
179
179
|
throw new Error(`[claude-session-manager] account-dir-unresolved: no <installDir>/data/accounts/<uuid>/account.json under ${dirname(platformRoot)}/data/accounts. ` +
|
|
180
|
-
'The installer (
|
|
180
|
+
'The installer (setup-account.sh / writeInstallDefaults) must run before manager start.');
|
|
181
181
|
}
|
|
182
182
|
// Claude Code walks `.claude/settings.json` from cwd to .git root. Defaulting
|
|
183
183
|
// spawnCwd to process.cwd() — i.e. the manager service directory — strands
|
|
184
184
|
// the account-scoped settings.json (and its Stop hook) outside that walk.
|
|
185
|
-
// Default to accountDir so
|
|
185
|
+
// Default to accountDir so setup-account.sh's `<accountDir>/.claude/settings.json`
|
|
186
186
|
// is on the discovery path. Env-var override is preserved for tests.
|
|
187
187
|
const spawnCwd = env.CLAUDE_SESSION_MANAGER_SPAWN_CWD ?? accountDir;
|
|
188
188
|
const lan = resolveLanIPv4();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Logger, Role, Channel } from './types.js';
|
|
2
|
-
import { type SystemctlRunner } from './systemd-scope.js';
|
|
2
|
+
import { type ProcessSignals, type SystemctlRunner } from './systemd-scope.js';
|
|
3
3
|
export type RowState = 'live' | 'ended' | 'archived';
|
|
4
4
|
/** Task 250 — `detached` is reached only via the boot-seed reconciler.
|
|
5
5
|
* When the manager restarts and finds a surviving `claude-session-*.scope`
|
|
@@ -130,5 +130,13 @@ export declare function createFsWatcher(opts: {
|
|
|
130
130
|
* user manager (macOS dev hosts), the default runner returns non-zero
|
|
131
131
|
* exit codes and the boot-seed degrades to "0 survivors" gracefully. */
|
|
132
132
|
runSystemctl?: SystemctlRunner;
|
|
133
|
+
/** Task 451 — injectable kill/alive-check primitives for the boot-seed
|
|
134
|
+
* orphan-stop post-flight verify. Default delegates to `process.kill`.
|
|
135
|
+
* Tests inject a recording stub to assert SIGTERM/SIGKILL escalation. */
|
|
136
|
+
processSignals?: ProcessSignals;
|
|
137
|
+
/** Task 451 — grace period between SIGTERM and SIGKILL during boot-seed
|
|
138
|
+
* orphan-stop escalation. Default 5_000 ms (matches the scope's
|
|
139
|
+
* `TimeoutStopSec`). Tests pass small values to keep run time bounded. */
|
|
140
|
+
killGraceMs?: number;
|
|
133
141
|
}): FsWatcher;
|
|
134
142
|
//# sourceMappingURL=fs-watcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-watcher.d.ts","sourceRoot":"","sources":["../src/fs-watcher.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"fs-watcher.d.ts","sourceRoot":"","sources":["../src/fs-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
import { existsSync, mkdirSync, openSync, closeSync, readSync, readFileSync, readdirSync, statSync, watch } from 'node:fs';
|
|
37
37
|
import { dirname, join } from 'node:path';
|
|
38
38
|
import { readSidecar } from './session-sidecar.js';
|
|
39
|
-
import { defaultSystemctlRunner, getScopeMainPid, listSurvivingScopes, stopScopeUnit, } from './systemd-scope.js';
|
|
39
|
+
import { defaultProcessSignals, defaultSystemctlRunner, getScopeMainPid, listSurvivingScopes, stopScopeUnit, } from './systemd-scope.js';
|
|
40
40
|
const DEBOUNCE_MS = 200;
|
|
41
41
|
// First `agent-setting` record sits near the JSONL head (Claude Code writes
|
|
42
42
|
// it after env+meta, before the first user turn). 32 KiB is enough to cover
|
|
@@ -121,6 +121,8 @@ function parsePidFile(path) {
|
|
|
121
121
|
export function createFsWatcher(opts) {
|
|
122
122
|
const { sessionsDir, projectsDir, logger } = opts;
|
|
123
123
|
const runSystemctl = opts.runSystemctl ?? defaultSystemctlRunner;
|
|
124
|
+
const processSignals = opts.processSignals ?? defaultProcessSignals;
|
|
125
|
+
const killGraceMs = opts.killGraceMs ?? 5_000;
|
|
124
126
|
// Transient row cache, keyed on sessionId. Built by bootSeed and kept
|
|
125
127
|
// in sync by fs event reconciliation. Not the source of truth — disk is.
|
|
126
128
|
const rowsBySessionId = new Map();
|
|
@@ -219,6 +221,10 @@ export function createFsWatcher(opts) {
|
|
|
219
221
|
effectivePermissionMode: sidecar.effectivePermissionMode,
|
|
220
222
|
hidden: sidecar.hidden,
|
|
221
223
|
sidecarSpecialist: sidecar.specialist,
|
|
224
|
+
// Task 451 — carry the scope token from the sidecar onto the row so
|
|
225
|
+
// boot-seed's reconcileSurvivingScopes can find the row by token,
|
|
226
|
+
// even when the unit token does not equal sessionId (fresh spawns).
|
|
227
|
+
scopeUnitToken: sidecar.scopeUnitToken ?? row.scopeUnitToken,
|
|
222
228
|
};
|
|
223
229
|
}
|
|
224
230
|
/** Find the pid file (if any) whose content names `sessionId`. Used at
|
|
@@ -631,52 +637,82 @@ export function createFsWatcher(opts) {
|
|
|
631
637
|
let orphaned = 0;
|
|
632
638
|
let orphanedStopped = 0;
|
|
633
639
|
for (const scope of scopes) {
|
|
634
|
-
const decision =
|
|
635
|
-
if (decision === '
|
|
640
|
+
const decision = classifyScope(scope);
|
|
641
|
+
if (decision.match === 'reattach') {
|
|
642
|
+
reattach(scope, decision.row);
|
|
636
643
|
reattached += 1;
|
|
644
|
+
continue;
|
|
637
645
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
646
|
+
orphaned += 1;
|
|
647
|
+
// Task 451 — orphan-stop is fire-and-forget so a single slow scope
|
|
648
|
+
// with a stuck pid does not block the rest of the boot-seed loop.
|
|
649
|
+
// The `[boot-seed] orphan-stop` line lands when the promise resolves;
|
|
650
|
+
// `orphaned-stopped` counts entries whose stop request was issued,
|
|
651
|
+
// not entries whose verify completed (the verify path is hundreds of
|
|
652
|
+
// ms when escalation runs and we don't want to serialise boot on it).
|
|
653
|
+
const pidForStop = decision.match === 'orphan-pid-dead'
|
|
654
|
+
? null
|
|
655
|
+
: getScopeMainPid(runSystemctl, scope.unitToken);
|
|
656
|
+
orphanedStopped += 1;
|
|
657
|
+
void stopScopeUnit(runSystemctl, scope.unitToken, {
|
|
658
|
+
pid: pidForStop,
|
|
659
|
+
killGraceMs,
|
|
660
|
+
signals: processSignals,
|
|
661
|
+
})
|
|
662
|
+
.then((stop) => {
|
|
663
|
+
logger(`[boot-seed] orphan-stop unit=${scope.unitName} outcome=${stop.outcome} exit-code=${stop.exitCode}`);
|
|
664
|
+
})
|
|
665
|
+
.catch((err) => {
|
|
666
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
667
|
+
logger(`[boot-seed] orphan-stop-threw unit=${scope.unitName} err=${JSON.stringify(msg)}`);
|
|
668
|
+
});
|
|
652
669
|
}
|
|
653
670
|
logger(`[boot-seed] survived-scopes=${scopes.length} reattached=${reattached} orphaned=${orphaned} orphaned-stopped=${orphanedStopped}`);
|
|
654
671
|
}
|
|
655
|
-
function
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
//
|
|
660
|
-
//
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
672
|
+
function classifyScope(scope) {
|
|
673
|
+
// Resolve the row two ways:
|
|
674
|
+
// 1. The unit token matches a sessionId directly (resume spawns,
|
|
675
|
+
// where unitToken === claude's intrinsic sessionId).
|
|
676
|
+
// 2. The unit token matches a sidecar-recorded scopeUnitToken on
|
|
677
|
+
// some row (fresh spawns, where unitToken is a random UUID
|
|
678
|
+
// minted at spawn time).
|
|
679
|
+
// Both paths are tried because we cannot tell at this point which
|
|
680
|
+
// type of spawn produced the scope; iterating rows is fine because
|
|
681
|
+
// the inner loop runs once per surviving scope at boot.
|
|
682
|
+
let row = rowsBySessionId.get(scope.unitToken) ?? null;
|
|
683
|
+
if (!row) {
|
|
684
|
+
for (const r of rowsBySessionId.values()) {
|
|
685
|
+
if (r.scopeUnitToken === scope.unitToken) {
|
|
686
|
+
row = r;
|
|
687
|
+
break;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
const sessionId = row?.sessionId ?? 'none';
|
|
692
|
+
if (!row) {
|
|
693
|
+
logger(`[boot-seed] scope-classify unit=${scope.unitName} sessionId=${sessionId} match=orphan reason=no-row-on-disk`);
|
|
694
|
+
return { match: 'orphan', reason: 'no-row-on-disk' };
|
|
695
|
+
}
|
|
696
|
+
// Task 451 — only reattach when the row's pid is still alive. Without
|
|
697
|
+
// this check we would mark a row `detached` for a process that has
|
|
698
|
+
// already exited, and the operator's End click would route to the
|
|
699
|
+
// row-scope branch and stop a unit whose pid is long dead.
|
|
700
|
+
if (row.pid === null || !processSignals.isAlive(row.pid)) {
|
|
701
|
+
logger(`[boot-seed] scope-classify unit=${scope.unitName} sessionId=${sessionId.slice(0, 8)} match=orphan-pid-dead reason=pid-already-dead`);
|
|
702
|
+
return { match: 'orphan-pid-dead', reason: 'pid-already-dead' };
|
|
703
|
+
}
|
|
704
|
+
logger(`[boot-seed] scope-classify unit=${scope.unitName} sessionId=${sessionId.slice(0, 8)} match=reattach reason=row-on-disk`);
|
|
705
|
+
return { match: 'reattach', row, reason: 'row-on-disk' };
|
|
706
|
+
}
|
|
707
|
+
function reattach(scope, row) {
|
|
708
|
+
// unindex/indexRow keeps the reverse indexes consistent (sessionId
|
|
709
|
+
// and pid keys are unchanged; the re-index is defensive against
|
|
710
|
+
// future field-change ordering).
|
|
674
711
|
unindexRow(row);
|
|
675
712
|
row.status = 'detached';
|
|
676
713
|
row.scopeUnitToken = scope.unitToken;
|
|
677
714
|
indexRow(row);
|
|
678
|
-
logger(`[boot-seed] reattached sessionId=${
|
|
679
|
-
return 'reattached';
|
|
715
|
+
logger(`[boot-seed] reattached sessionId=${row.sessionId} unit=${scope.unitName} pid=${row.pid ?? 'unknown'}`);
|
|
680
716
|
}
|
|
681
717
|
function arm() {
|
|
682
718
|
if (armed)
|