@tekmidian/pai 0.6.3 → 0.6.5
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/cli/index.mjs +55 -37
- package/dist/cli/index.mjs.map +1 -1
- package/dist/hooks/context-compression-hook.mjs +1 -1
- package/dist/hooks/context-compression-hook.mjs.map +2 -2
- package/dist/hooks/load-project-context.mjs +1 -1
- package/dist/hooks/load-project-context.mjs.map +2 -2
- package/dist/hooks/stop-hook.mjs.map +2 -2
- package/dist/hooks/sync-todo-to-md.mjs.map +2 -2
- package/package.json +2 -2
- package/scripts/build-hooks.mjs +115 -2
- package/src/hooks/ts/lib/project-utils/session-notes.ts +0 -1
- package/statusline-command.sh +6 -2
package/dist/cli/index.mjs
CHANGED
|
@@ -4783,11 +4783,14 @@ async function stepSkillStubs(rl) {
|
|
|
4783
4783
|
//#endregion
|
|
4784
4784
|
//#region src/cli/commands/setup/steps/08-hooks.ts
|
|
4785
4785
|
/** Step 7: Shell lifecycle hooks installation (pre-compact, session-stop, statusline). */
|
|
4786
|
+
const useSymlinks$1 = platform() !== "win32";
|
|
4786
4787
|
async function stepHooks(rl) {
|
|
4787
4788
|
section("Step 7: Lifecycle Hooks");
|
|
4788
4789
|
line$1();
|
|
4789
4790
|
line$1(" PAI hooks fire on session stop and context compaction to save state,");
|
|
4790
4791
|
line$1(" update notes, and display live statusline information.");
|
|
4792
|
+
if (useSymlinks$1) line$1(" Files are symlinked so they auto-update when PAI is rebuilt.");
|
|
4793
|
+
else line$1(" Files are copied (Windows — re-run setup after PAI updates).");
|
|
4791
4794
|
line$1();
|
|
4792
4795
|
if (!await promptYesNo(rl, "Install PAI lifecycle hooks (session stop, pre-compact, statusline)?", true)) {
|
|
4793
4796
|
console.log(c.dim(" Skipping hook installation."));
|
|
@@ -4800,29 +4803,38 @@ async function stepHooks(rl) {
|
|
|
4800
4803
|
const hooksTarget = join(claudeDir, "Hooks");
|
|
4801
4804
|
if (!existsSync(hooksTarget)) mkdirSync(hooksTarget, { recursive: true });
|
|
4802
4805
|
let anyInstalled = false;
|
|
4803
|
-
function
|
|
4806
|
+
function installLink(src, dest, label) {
|
|
4804
4807
|
if (!existsSync(src)) {
|
|
4805
4808
|
console.log(c.warn(` Source not found: ${src}`));
|
|
4806
4809
|
return;
|
|
4807
4810
|
}
|
|
4808
|
-
const
|
|
4809
|
-
if (existsSync(dest)) {
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4811
|
+
const absSrc = resolve(src);
|
|
4812
|
+
if (existsSync(dest) || lstatSync(dest, { throwIfNoEntry: false })?.isSymbolicLink?.()) try {
|
|
4813
|
+
const stat = lstatSync(dest);
|
|
4814
|
+
if (stat.isSymbolicLink()) {
|
|
4815
|
+
if (resolve(readlinkSync(dest)) === absSrc) {
|
|
4816
|
+
console.log(c.dim(` Current: ${label}`));
|
|
4817
|
+
return;
|
|
4818
|
+
}
|
|
4819
|
+
unlinkSync(dest);
|
|
4820
|
+
} else if (stat.isFile()) unlinkSync(dest);
|
|
4821
|
+
else return;
|
|
4822
|
+
} catch {}
|
|
4823
|
+
if (useSymlinks$1) symlinkSync(absSrc, dest);
|
|
4824
|
+
else {
|
|
4825
|
+
copyFileSync(src, dest);
|
|
4826
|
+
chmodSync(dest, 493);
|
|
4814
4827
|
}
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
console.log(c.ok(`Installed: ${label}`));
|
|
4828
|
+
const verb = useSymlinks$1 ? "Linked" : "Installed";
|
|
4829
|
+
console.log(c.ok(`${verb}: ${label}`));
|
|
4818
4830
|
anyInstalled = true;
|
|
4819
4831
|
}
|
|
4820
4832
|
line$1();
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
if (statuslineSrc)
|
|
4833
|
+
installLink(join(hooksDir, "pre-compact.sh"), join(hooksTarget, "pai-pre-compact.sh"), "pai-pre-compact.sh");
|
|
4834
|
+
installLink(join(hooksDir, "session-stop.sh"), join(hooksTarget, "pai-session-stop.sh"), "pai-session-stop.sh");
|
|
4835
|
+
if (statuslineSrc) installLink(statuslineSrc, join(claudeDir, "statusline-command.sh"), "statusline-command.sh");
|
|
4824
4836
|
else console.log(c.warn(" statusline-command.sh not found — skipping statusline."));
|
|
4825
|
-
if (tabColorSrc)
|
|
4837
|
+
if (tabColorSrc) installLink(tabColorSrc, join(claudeDir, "tab-color-command.sh"), "tab-color-command.sh");
|
|
4826
4838
|
else console.log(c.warn(" tab-color-command.sh not found — skipping tab color."));
|
|
4827
4839
|
return anyInstalled;
|
|
4828
4840
|
}
|
|
@@ -4830,11 +4842,14 @@ async function stepHooks(rl) {
|
|
|
4830
4842
|
//#endregion
|
|
4831
4843
|
//#region src/cli/commands/setup/steps/09-ts-hooks.ts
|
|
4832
4844
|
/** Step 7b: TypeScript (.mjs) hooks installation to ~/.claude/Hooks/. */
|
|
4845
|
+
const useSymlinks = platform() !== "win32";
|
|
4833
4846
|
async function stepTsHooks(rl) {
|
|
4834
4847
|
section("Step 7b: TypeScript Hooks Installation");
|
|
4835
4848
|
line$1();
|
|
4836
|
-
line$1(" PAI ships
|
|
4849
|
+
line$1(" PAI ships compiled TypeScript hooks (.mjs) that fire on session events,");
|
|
4837
4850
|
line$1(" tool use, and context compaction to capture context and update notes.");
|
|
4851
|
+
if (useSymlinks) line$1(" Files are symlinked so they auto-update when PAI is rebuilt.");
|
|
4852
|
+
else line$1(" Files are copied (Windows — re-run setup after PAI updates).");
|
|
4838
4853
|
line$1();
|
|
4839
4854
|
if (!await promptYesNo(rl, "Install PAI TypeScript hooks to ~/.claude/Hooks/?", true)) {
|
|
4840
4855
|
console.log(c.dim(" Skipping TypeScript hooks installation."));
|
|
@@ -4860,30 +4875,32 @@ async function stepTsHooks(rl) {
|
|
|
4860
4875
|
return false;
|
|
4861
4876
|
}
|
|
4862
4877
|
line$1();
|
|
4863
|
-
let
|
|
4878
|
+
let linkedCount = 0;
|
|
4864
4879
|
let skippedCount = 0;
|
|
4865
4880
|
let cleanedCount = 0;
|
|
4866
4881
|
for (const filename of allFiles) {
|
|
4867
|
-
const src = join(distHooksDir, filename);
|
|
4882
|
+
const src = resolve(join(distHooksDir, filename));
|
|
4868
4883
|
const dest = join(hooksTarget, filename);
|
|
4869
|
-
|
|
4870
|
-
if (existsSync(dest)) {
|
|
4871
|
-
|
|
4872
|
-
|
|
4884
|
+
let needsLink = true;
|
|
4885
|
+
if (existsSync(dest) || lstatSync(dest, { throwIfNoEntry: false })?.isSymbolicLink?.()) try {
|
|
4886
|
+
const stat = lstatSync(dest);
|
|
4887
|
+
if (stat.isSymbolicLink()) if (resolve(readlinkSync(dest)) === src) {
|
|
4888
|
+
console.log(c.dim(` Current: ${filename}`));
|
|
4873
4889
|
skippedCount++;
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4890
|
+
needsLink = false;
|
|
4891
|
+
} else unlinkSync(dest);
|
|
4892
|
+
else if (stat.isFile()) unlinkSync(dest);
|
|
4893
|
+
} catch {}
|
|
4894
|
+
if (needsLink) {
|
|
4895
|
+
if (useSymlinks) symlinkSync(src, dest);
|
|
4896
|
+
else {
|
|
4897
|
+
copyFileSync(src, dest);
|
|
4898
|
+
chmodSync(dest, 493);
|
|
4881
4899
|
}
|
|
4900
|
+
const verb = useSymlinks ? "Linked" : "Installed";
|
|
4901
|
+
console.log(c.ok(`${verb}: ${filename}`));
|
|
4902
|
+
linkedCount++;
|
|
4882
4903
|
}
|
|
4883
|
-
copyFileSync(src, dest);
|
|
4884
|
-
chmodSync(dest, 493);
|
|
4885
|
-
console.log(c.ok(`Installed: ${filename}`));
|
|
4886
|
-
copiedCount++;
|
|
4887
4904
|
const staleTsPath = join(hooksTarget, filename.replace(/\.mjs$/, ".ts"));
|
|
4888
4905
|
if (existsSync(staleTsPath)) {
|
|
4889
4906
|
unlinkSync(staleTsPath);
|
|
@@ -4892,14 +4909,15 @@ async function stepTsHooks(rl) {
|
|
|
4892
4909
|
}
|
|
4893
4910
|
}
|
|
4894
4911
|
line$1();
|
|
4895
|
-
if (
|
|
4912
|
+
if (linkedCount > 0 || cleanedCount > 0) {
|
|
4896
4913
|
const parts = [];
|
|
4897
|
-
|
|
4898
|
-
if (
|
|
4914
|
+
const verb = useSymlinks ? "linked" : "installed";
|
|
4915
|
+
if (linkedCount > 0) parts.push(`${linkedCount} hook(s) ${verb}`);
|
|
4916
|
+
if (skippedCount > 0) parts.push(`${skippedCount} current`);
|
|
4899
4917
|
if (cleanedCount > 0) parts.push(`${cleanedCount} stale .ts file(s) cleaned up`);
|
|
4900
4918
|
console.log(c.ok(parts.join(", ") + "."));
|
|
4901
|
-
} else console.log(c.dim(` All ${skippedCount} hook(s) already
|
|
4902
|
-
return
|
|
4919
|
+
} else console.log(c.dim(` All ${skippedCount} hook(s) already current.`));
|
|
4920
|
+
return linkedCount > 0 || cleanedCount > 0;
|
|
4903
4921
|
}
|
|
4904
4922
|
|
|
4905
4923
|
//#endregion
|