shadok-ai 0.17.40 → 0.17.41

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.
@@ -88,6 +88,26 @@ export declare function commonsOsUser(input: {
88
88
  migrated: boolean;
89
89
  mode: DeploymentMode;
90
90
  }): string | null;
91
+ /**
92
+ * Repoint a cron `check` command from the OLD commons HOME's `.claude` tree to the
93
+ * NEW one, after migration moved the commons agent off `/root` to `/home/main`.
94
+ *
95
+ * Why this is needed at all: an agent that authored a monitoring script stored it
96
+ * (and hard-coded the guard path) under `$HOME/.claude/skills/.../scripts/` when
97
+ * its HOME was still `/root`. Since cron guards now run DROPPED as the commons
98
+ * `main` user (which cannot traverse `/root`, 0700), that absolute `/root/.claude`
99
+ * path is unreadable and the guard dies `check-failed` in silence. The migration
100
+ * relocates the `.claude` tree into the new HOME, so the reference must follow.
101
+ *
102
+ * Only the `<oldHome>/.claude` base is rewritten — the one tree that moved — not
103
+ * every `<oldHome>` mention, so an unrelated `/root/...` reference is left intact.
104
+ * Identity when the home did not move (mono-tenant, or old === new) or when either
105
+ * base is blank (never blank out a path). A `$HOME`-relative check is already
106
+ * portable and contains no absolute base to match, so it passes through untouched.
107
+ * Pure, so the boot self-heal that walks the cron file stays a thin caller — and
108
+ * the exact substitution is locked by test, the twin of `rewriteSkillsBase`.
109
+ */
110
+ export declare function rewriteCronCheckHome(check: string, oldHome: string, newHome: string): string;
91
111
  /**
92
112
  * The running agents to respawn, as session ids — deduped, order preserved so
93
113
  * the caller cycles them ONE AT A TIME (the OAuth refresh-token race,
@@ -89,6 +89,30 @@ export function migrationPlan(input) {
89
89
  export function commonsOsUser(input) {
90
90
  return input.migrated && input.mode === "multi-tenant" ? COMMONS_USER : null;
91
91
  }
92
+ /**
93
+ * Repoint a cron `check` command from the OLD commons HOME's `.claude` tree to the
94
+ * NEW one, after migration moved the commons agent off `/root` to `/home/main`.
95
+ *
96
+ * Why this is needed at all: an agent that authored a monitoring script stored it
97
+ * (and hard-coded the guard path) under `$HOME/.claude/skills/.../scripts/` when
98
+ * its HOME was still `/root`. Since cron guards now run DROPPED as the commons
99
+ * `main` user (which cannot traverse `/root`, 0700), that absolute `/root/.claude`
100
+ * path is unreadable and the guard dies `check-failed` in silence. The migration
101
+ * relocates the `.claude` tree into the new HOME, so the reference must follow.
102
+ *
103
+ * Only the `<oldHome>/.claude` base is rewritten — the one tree that moved — not
104
+ * every `<oldHome>` mention, so an unrelated `/root/...` reference is left intact.
105
+ * Identity when the home did not move (mono-tenant, or old === new) or when either
106
+ * base is blank (never blank out a path). A `$HOME`-relative check is already
107
+ * portable and contains no absolute base to match, so it passes through untouched.
108
+ * Pure, so the boot self-heal that walks the cron file stays a thin caller — and
109
+ * the exact substitution is locked by test, the twin of `rewriteSkillsBase`.
110
+ */
111
+ export function rewriteCronCheckHome(check, oldHome, newHome) {
112
+ if (!check || !oldHome || !newHome || oldHome === newHome)
113
+ return check;
114
+ return check.split(oldHome + "/.claude").join(newHome + "/.claude");
115
+ }
92
116
  /**
93
117
  * The running agents to respawn, as session ids — deduped, order preserved so
94
118
  * the caller cycles them ONE AT A TIME (the OAuth refresh-token race,
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-groups.js","sourceRoot":"","sources":["../src/migrate-groups.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migrate-groups.js","sourceRoot":"","sources":["../src/migrate-groups.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -34,7 +34,7 @@ import { readGroundAt } from "./ground.js";
34
34
  import { homeGreetingBrief } from "./greeting.js";
35
35
  import { ensureSshIdentity } from "./ssh.js";
36
36
  import { accountsEnabled, deploymentMode, probeCanProvision } from "./capability.js";
37
- import { migrationPlan, runMigration, respawnPlan, commonsOsUser, COMMONS_USER, MIGRATION_MARKER_FILE, } from "./migrate-groups.js";
37
+ import { migrationPlan, runMigration, respawnPlan, commonsOsUser, COMMONS_USER, MIGRATION_MARKER_FILE, rewriteCronCheckHome, } from "./migrate-groups.js";
38
38
  import { relayOAuthCallback } from "./oauth-relay.js";
39
39
  import { openBrowser } from "./open-browser.js";
40
40
  import { parseSkillMeta, prepromptParts, prepromptFingerprint, stalenessReasons, LEGACY_FINGERPRINT, } from "./preprompt.js";
@@ -3011,6 +3011,75 @@ async function ensureGroupsProvisioned() {
3011
3011
  // of trusted directories in one write each, so none strands on the trust
3012
3012
  // dialog when the resume storm rebuilds a wiped (ephemeral) group HOME.
3013
3013
  preseedGroupHomes();
3014
+ // And heal the commons agent's own helper scripts + cron guards, which the HOME
3015
+ // move off /root left stranded (see below).
3016
+ await healCommonsClaudeScripts();
3017
+ }
3018
+ /**
3019
+ * Boot self-heal for the commons agent's OWN `.claude` content and cron guards
3020
+ * after its HOME moved off `/root` to `/home/main`.
3021
+ *
3022
+ * The one-shot migration (`migChownTreeToCommons`) relocates the transcript tree
3023
+ * but NOT `~/.claude/skills`, where an agent keeps the custom monitoring scripts
3024
+ * it authored. Those scripts (and any cron `check` that hard-codes their old
3025
+ * `/root/.claude/...` path) are then unreachable: a cron guard runs DROPPED as the
3026
+ * commons `main` user, which cannot traverse `/root` (0700) — so the guard dies
3027
+ * `check-failed` in silence (measured on a live instance: three monitoring crons
3028
+ * stuck, "son script est sous /root"). New agents are fine (their HOME is already
3029
+ * `/home/main`); this is the one-way carry for what predates the move.
3030
+ *
3031
+ * Runs on EVERY capable boot, independent of the migration marker (the twin of
3032
+ * the reprovision reconciler above), so an ALREADY-migrated instance self-heals on
3033
+ * the next update rather than needing a hand fix. Idempotent and best-effort: a
3034
+ * failure here must never take down boot, and a re-run finds the copy already done
3035
+ * (`cp -rn`, non-clobber) and the checks already rewritten (identity). No-op unless
3036
+ * the HOME actually moved (mono-tenant / pre-migration: old === new).
3037
+ */
3038
+ async function healCommonsClaudeScripts() {
3039
+ if (DEPLOYMENT_MODE !== "multi-tenant")
3040
+ return;
3041
+ const oldHome = os.homedir();
3042
+ const newHome = homeForUser(COMMONS_USER, GROUP_HOME_BASE);
3043
+ if (!newHome || newHome === oldHome)
3044
+ return; // not migrated off /root → nothing moved
3045
+ // 1) Carry the agent-authored scripts across: <oldHome>/.claude/skills →
3046
+ // <newHome>/.claude/skills, non-clobber, owned by `main`. This is the one
3047
+ // `.claude` subtree the migration skipped (skills are seeded machine-wide in
3048
+ // MT, but an agent's CUSTOM files live only in this per-HOME copy).
3049
+ try {
3050
+ const srcSkills = path.join(oldHome, ".claude", "skills");
3051
+ if (fs.existsSync(srcSkills)) {
3052
+ const owner = `${COMMONS_USER}:${COMMONS_USER}`;
3053
+ const dstSkills = path.join(newHome, ".claude", "skills");
3054
+ await runPrivileged("install", ["-d", "-o", COMMONS_USER, "-g", COMMONS_USER, dstSkills]);
3055
+ await runPrivileged("cp", ["-rn", `${srcSkills}/.`, `${dstSkills}/`], { timeoutMs: TREE_OP_TIMEOUT_MS });
3056
+ await runPrivileged("chown", ["-R", owner, dstSkills], { timeoutMs: TREE_OP_TIMEOUT_MS });
3057
+ }
3058
+ }
3059
+ catch (e) {
3060
+ console.error(`heal: relocating commons ~/.claude/skills failed (best-effort): ${e?.message ?? e}`);
3061
+ }
3062
+ // 2) Repoint this instance's cron guards that still name the old /root HOME.
3063
+ try {
3064
+ const crons = loadCrons();
3065
+ let changed = false;
3066
+ for (const c of crons) {
3067
+ if (!c.check)
3068
+ continue;
3069
+ const next = rewriteCronCheckHome(c.check, oldHome, newHome);
3070
+ if (next !== c.check) {
3071
+ c.check = next;
3072
+ changed = true;
3073
+ }
3074
+ }
3075
+ if (changed) {
3076
+ saveCrons(crons);
3077
+ console.log(`heal: repointed cron guard path(s) from ${oldHome}/.claude → ${newHome}/.claude`);
3078
+ }
3079
+ }
3080
+ catch (e) {
3081
+ console.error(`heal: rewriting cron guard paths failed (best-effort): ${e?.message ?? e}`);
3082
+ }
3014
3083
  }
3015
3084
  /** Step 1 — create the non-root commons user `main` (+ HOME). Idempotent. */
3016
3085
  async function migCreateCommonsUser() {