portable-agent-layer 0.84.2 → 0.84.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "portable-agent-layer",
3
- "version": "0.84.2",
3
+ "version": "0.84.3",
4
4
  "description": "PAL — Portable Agent Layer: persistent personal context for AI coding assistants",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,10 +14,9 @@ import {
14
14
  countSkills,
15
15
  loadCopilotHooksTemplate,
16
16
  log,
17
- readJson,
18
17
  vscodeSettingsFile,
19
- writeJson,
20
18
  } from "../lib";
19
+ import { enableCopilotInstructions } from "../vscode-settings";
21
20
 
22
21
  const PKG_ROOT = palPkg().replaceAll("\\", "/");
23
22
  const COPILOT_DIR = platform.copilotDir();
@@ -58,18 +57,15 @@ const manualHint =
58
57
  'Add manually: { "chat.instructionsFilesLocations": { "~/.copilot/instructions": true } }';
59
58
  if (vsSettingsPath) {
60
59
  try {
61
- const settings = readJson<Record<string, unknown>>(vsSettingsPath, {});
62
- const existing =
63
- typeof settings["chat.instructionsFilesLocations"] === "object" &&
64
- settings["chat.instructionsFilesLocations"] !== null
65
- ? (settings["chat.instructionsFilesLocations"] as Record<string, unknown>)
66
- : {};
67
- settings["chat.instructionsFilesLocations"] = {
68
- ...existing,
69
- "~/.copilot/instructions": true,
70
- };
71
- writeJson(vsSettingsPath, settings);
72
- log.success("Enabled ~/.copilot/instructions in VS Code settings");
60
+ const outcome = enableCopilotInstructions(vsSettingsPath);
61
+ if (outcome === "enabled")
62
+ log.success("Enabled ~/.copilot/instructions in VS Code settings");
63
+ if (outcome === "needs-manual-edit")
64
+ log.warn(
65
+ `VS Code settings aren't plain JSON, so PAL left them untouched — ${manualHint}`
66
+ );
67
+ if (outcome === "vscode-never-launched")
68
+ log.info("Skipped VS Code settings — VS Code has not been launched yet");
73
69
  } catch {
74
70
  log.warn(`Could not update VS Code settings — ${manualHint}`);
75
71
  }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * VS Code's settings.json is JSONC. PAL rewrites it only when it parses as
3
+ * strict JSON, because a rewrite would drop the user's comments.
4
+ */
5
+
6
+ import { existsSync, readFileSync } from "node:fs";
7
+ import { dirname } from "node:path";
8
+ import { writeJson } from "./lib";
9
+
10
+ const LOCATIONS_KEY = "chat.instructionsFilesLocations";
11
+ const COPILOT_INSTRUCTIONS = "~/.copilot/instructions";
12
+
13
+ type Settings = Record<string, unknown>;
14
+
15
+ type InstructionsOutcome =
16
+ | "enabled"
17
+ | "already-enabled"
18
+ | "needs-manual-edit"
19
+ | "vscode-never-launched";
20
+
21
+ function parsed(raw: string, parse: (text: string) => unknown): Settings | null {
22
+ try {
23
+ const value = parse(raw);
24
+ return typeof value === "object" && value !== null && !Array.isArray(value)
25
+ ? (value as Settings)
26
+ : null;
27
+ } catch {
28
+ return null;
29
+ }
30
+ }
31
+
32
+ function locationsOf(settings: Settings): Settings {
33
+ const locations = settings[LOCATIONS_KEY];
34
+ return typeof locations === "object" && locations !== null
35
+ ? (locations as Settings)
36
+ : {};
37
+ }
38
+
39
+ function writeEnabled(settingsPath: string, settings: Settings): InstructionsOutcome {
40
+ writeJson(settingsPath, {
41
+ ...settings,
42
+ [LOCATIONS_KEY]: { ...locationsOf(settings), [COPILOT_INSTRUCTIONS]: true },
43
+ });
44
+ return "enabled";
45
+ }
46
+
47
+ export function enableCopilotInstructions(settingsPath: string): InstructionsOutcome {
48
+ if (!existsSync(dirname(settingsPath))) return "vscode-never-launched";
49
+ if (!existsSync(settingsPath)) return writeEnabled(settingsPath, {});
50
+ const raw = readFileSync(settingsPath, "utf-8");
51
+ const settings = parsed(raw, Bun.JSONC.parse);
52
+ if (settings && locationsOf(settings)[COPILOT_INSTRUCTIONS] === true)
53
+ return "already-enabled";
54
+ const strict = parsed(raw, JSON.parse);
55
+ return strict ? writeEnabled(settingsPath, strict) : "needs-manual-edit";
56
+ }