@codyswann/lisa 4.17.19 → 4.18.0

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.
Files changed (94) hide show
  1. package/dist/cli/ui-config-write-document.d.ts +53 -0
  2. package/dist/cli/ui-config-write-document.d.ts.map +1 -0
  3. package/dist/cli/ui-config-write-document.js +212 -0
  4. package/dist/cli/ui-config-write-document.js.map +1 -0
  5. package/dist/cli/ui-config-write-patch-plan.d.ts +30 -0
  6. package/dist/cli/ui-config-write-patch-plan.d.ts.map +1 -0
  7. package/dist/cli/ui-config-write-patch-plan.js +151 -0
  8. package/dist/cli/ui-config-write-patch-plan.js.map +1 -0
  9. package/dist/cli/ui-config-write-persistence.d.ts +19 -0
  10. package/dist/cli/ui-config-write-persistence.d.ts.map +1 -0
  11. package/dist/cli/ui-config-write-persistence.js +294 -0
  12. package/dist/cli/ui-config-write-persistence.js.map +1 -0
  13. package/dist/cli/ui-config-write-property-edits.d.ts +40 -0
  14. package/dist/cli/ui-config-write-property-edits.d.ts.map +1 -0
  15. package/dist/cli/ui-config-write-property-edits.js +250 -0
  16. package/dist/cli/ui-config-write-property-edits.js.map +1 -0
  17. package/dist/cli/ui-config-write-provenance.d.ts +12 -0
  18. package/dist/cli/ui-config-write-provenance.d.ts.map +1 -0
  19. package/dist/cli/ui-config-write-provenance.js +29 -0
  20. package/dist/cli/ui-config-write-provenance.js.map +1 -0
  21. package/dist/cli/ui-config-write-root-identity.d.ts +25 -0
  22. package/dist/cli/ui-config-write-root-identity.d.ts.map +1 -0
  23. package/dist/cli/ui-config-write-root-identity.js +66 -0
  24. package/dist/cli/ui-config-write-root-identity.js.map +1 -0
  25. package/dist/cli/ui-config-write.d.ts.map +1 -1
  26. package/dist/cli/ui-config-write.js +47 -92
  27. package/dist/cli/ui-config-write.js.map +1 -1
  28. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  29. package/dist/core/upstream-evidence-manifest.js +7 -1
  30. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  31. package/dist/sync/json-path.d.ts +10 -0
  32. package/dist/sync/json-path.d.ts.map +1 -1
  33. package/dist/sync/json-path.js +14 -0
  34. package/dist/sync/json-path.js.map +1 -1
  35. package/dist/sync/sync-population.d.ts +6 -0
  36. package/dist/sync/sync-population.d.ts.map +1 -1
  37. package/dist/sync/sync-population.js +8 -0
  38. package/dist/sync/sync-population.js.map +1 -1
  39. package/dist/utils/atomic-file-write.d.ts +5 -4
  40. package/dist/utils/atomic-file-write.d.ts.map +1 -1
  41. package/dist/utils/atomic-file-write.js +3 -0
  42. package/dist/utils/atomic-file-write.js.map +1 -1
  43. package/package.json +2 -2
  44. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  46. package/plugins/lisa-agy/plugin.json +1 -1
  47. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  49. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  50. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  56. package/plugins/lisa-expo-agy/plugin.json +1 -1
  57. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  61. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  62. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  66. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  67. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  71. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  72. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  76. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  77. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  81. package/plugins/lisa-rails-agy/plugin.json +1 -1
  82. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  86. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  87. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  91. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  92. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  94. package/ui/README.md +62 -8
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-config-write-provenance.js","sourceRoot":"","sources":["../../src/cli/ui-config-write-provenance.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEpE;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA4C;IAE5C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;SAChC,GAAG,CAAC,YAAY,CAAC;SACjB,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AAC1D,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,aAAa,CAAC,MAAM,CAAqB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC/D,IAAI,GAAG,KAAK,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YAC1D,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;YAC3D,CAAC,CAAC,KAAK,CAAC,GAAG;YACX,CAAC,CAAC,KAAK,CAAC;IACZ,CAAC,EAAE,SAAS,CAAC,CAAC;AAChB,CAAC"}
@@ -0,0 +1,25 @@
1
+ /** Canonical path and stable metadata used to detect directory replacement. */
2
+ export interface ProjectRootIdentity {
3
+ readonly path: string;
4
+ readonly dev: bigint;
5
+ readonly ino: bigint;
6
+ readonly birthtimeNs: bigint;
7
+ readonly mode: bigint;
8
+ readonly uid: bigint;
9
+ readonly gid: bigint;
10
+ }
11
+ /**
12
+ * Capture and immediately revalidate an existing project directory.
13
+ * @param projectRoot - Project path supplied by the UI server
14
+ * @returns Canonical directory identity for all later transaction boundaries
15
+ */
16
+ export declare function requireCanonicalProjectRoot(projectRoot: string): Promise<ProjectRootIdentity>;
17
+ /**
18
+ * Revalidate the path against its initial directory identity. A realpath
19
+ * sandwich catches ancestor redirection during metadata capture; stable
20
+ * device/inode/birth/ownership metadata catches a byte-identical replacement
21
+ * at the same canonical spelling.
22
+ * @param expected - Identity captured before locking and file access
23
+ */
24
+ export declare function assertProjectRootIdentity(expected: ProjectRootIdentity): Promise<void>;
25
+ //# sourceMappingURL=ui-config-write-root-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-config-write-root-identity.d.ts","sourceRoot":"","sources":["../../src/cli/ui-config-write-root-identity.ts"],"names":[],"mappings":"AAcA,+EAA+E;AAC/E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAiB9B;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,mBAAmB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAsBf"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @file ui-config-write-root-identity.ts
3
+ * @description Portable fail-closed identity checks for UI config roots.
4
+ *
5
+ * Node exposes path-based filesystem calls but no portable `openat`/`renameat`
6
+ * equivalents. A canonical realpath sandwich plus stable directory metadata is
7
+ * therefore the strongest portable anchor available at each call boundary;
8
+ * callers must still disclose the same-user race inside a final check-to-use
9
+ * gap instead of claiming descriptor-relative protection.
10
+ * @module cli/ui-config-write-root-identity
11
+ */
12
+ import { lstat, realpath } from "node:fs/promises";
13
+ import * as path from "node:path";
14
+ /**
15
+ * Capture and immediately revalidate an existing project directory.
16
+ * @param projectRoot - Project path supplied by the UI server
17
+ * @returns Canonical directory identity for all later transaction boundaries
18
+ */
19
+ export async function requireCanonicalProjectRoot(projectRoot) {
20
+ const canonical = await realpath(path.resolve(projectRoot));
21
+ const metadata = await lstat(canonical, { bigint: true });
22
+ if (!metadata.isDirectory()) {
23
+ throw new Error("Config project root must be a directory");
24
+ }
25
+ const identity = {
26
+ path: canonical,
27
+ dev: metadata.dev,
28
+ ino: metadata.ino,
29
+ birthtimeNs: metadata.birthtimeNs,
30
+ mode: metadata.mode,
31
+ uid: metadata.uid,
32
+ gid: metadata.gid,
33
+ };
34
+ await assertProjectRootIdentity(identity);
35
+ return identity;
36
+ }
37
+ /**
38
+ * Revalidate the path against its initial directory identity. A realpath
39
+ * sandwich catches ancestor redirection during metadata capture; stable
40
+ * device/inode/birth/ownership metadata catches a byte-identical replacement
41
+ * at the same canonical spelling.
42
+ * @param expected - Identity captured before locking and file access
43
+ */
44
+ export async function assertProjectRootIdentity(expected) {
45
+ try {
46
+ const canonicalBefore = await realpath(expected.path);
47
+ const current = await lstat(expected.path, { bigint: true });
48
+ const canonicalAfter = await realpath(expected.path);
49
+ if (canonicalBefore !== expected.path ||
50
+ canonicalAfter !== expected.path ||
51
+ !current.isDirectory() ||
52
+ current.isSymbolicLink() ||
53
+ current.dev !== expected.dev ||
54
+ current.ino !== expected.ino ||
55
+ current.birthtimeNs !== expected.birthtimeNs ||
56
+ current.mode !== expected.mode ||
57
+ current.uid !== expected.uid ||
58
+ current.gid !== expected.gid) {
59
+ throw new Error("identity mismatch");
60
+ }
61
+ }
62
+ catch {
63
+ throw new Error("Config project root changed during write");
64
+ }
65
+ }
66
+ //# sourceMappingURL=ui-config-write-root-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-config-write-root-identity.js","sourceRoot":"","sources":["../../src/cli/ui-config-write-root-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAalC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,WAAmB;IAEnB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,QAAQ,GAAwB;QACpC,IAAI,EAAE,SAAS;QACf,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,GAAG,EAAE,QAAQ,CAAC,GAAG;KAClB,CAAC;IACF,MAAM,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,QAA6B;IAE7B,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrD,IACE,eAAe,KAAK,QAAQ,CAAC,IAAI;YACjC,cAAc,KAAK,QAAQ,CAAC,IAAI;YAChC,CAAC,OAAO,CAAC,WAAW,EAAE;YACtB,OAAO,CAAC,cAAc,EAAE;YACxB,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG;YAC5B,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG;YAC5B,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC,WAAW;YAC5C,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;YAC9B,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG;YAC5B,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,EAC5B,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ui-config-write.d.ts","sourceRoot":"","sources":["../../src/cli/ui-config-write.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AA2TlC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,IAAI,CAAC,eAAe,EAC7B,QAAQ,EAAE,IAAI,CAAC,cAAc,EAC7B,OAAO,EAAE,MAAM,GACd,IAAI,CAsDN"}
1
+ {"version":3,"file":"ui-config-write.d.ts","sourceRoot":"","sources":["../../src/cli/ui-config-write.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAqQlC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,IAAI,CAAC,eAAe,EAC7B,QAAQ,EAAE,IAAI,CAAC,cAAc,EAC7B,OAAO,EAAE,MAAM,GACd,IAAI,CA0DN"}
@@ -1,42 +1,19 @@
1
- import * as path from "node:path";
2
- import { readFile } from "node:fs/promises";
3
- import { getAtPath, isJsonObject, setAtPath, } from "../sync/json-path.js";
4
- import { writeJson } from "../utils/index.js";
1
+ import { getAtPath, isJsonObject, } from "../sync/json-path.js";
5
2
  import { SYNC_REGISTRY } from "../sync/registry.js";
6
- import { removePopulation } from "../sync/sync-population.js";
7
- const CONFIG_FILE = ".lisa.config.json";
3
+ import { persistRoutedConfigChanges, } from "./ui-config-write-persistence.js";
4
+ import { parseUnambiguousJson } from "./ui-config-write-document.js";
8
5
  const JSON_CONTENT_TYPE = "application/json; charset=utf-8";
9
6
  const MAX_CONFIG_WRITE_BYTES = 128 * 1024;
10
7
  const NO_STORE = "no-store";
11
8
  const TEXT_CONTENT_TYPE = "text/plain; charset=utf-8";
12
- const configWriteQueues = new Map();
9
+ const LOCAL_CONFIG_KEYS = new Set([
10
+ "atlassian.email",
11
+ "intake.assignee",
12
+ "playStore.serviceAccountKeyPath",
13
+ ]);
13
14
  /** Error raised for malformed request bodies that should return 400. */
14
15
  class RequestBodyError extends Error {
15
16
  }
16
- /**
17
- * Read the project's committed config file.
18
- * @param destDir - Project root
19
- * @returns Committed config object, or an empty config if absent/malformed
20
- */
21
- async function readCommittedConfig(destDir) {
22
- const configPath = path.join(destDir, CONFIG_FILE);
23
- try {
24
- const committed = JSON.parse(await readFile(configPath, "utf8"));
25
- if (!isJsonObject(committed)) {
26
- throw new Error(`${CONFIG_FILE} must contain a JSON object`);
27
- }
28
- return committed;
29
- }
30
- catch (error) {
31
- if (typeof error === "object" &&
32
- error !== null &&
33
- "code" in error &&
34
- error.code === "ENOENT") {
35
- return {};
36
- }
37
- throw error;
38
- }
39
- }
40
17
  /**
41
18
  * Restrict loopback origins to the authority advertised by `lisa ui`.
42
19
  * @param host - Origin URL host
@@ -116,10 +93,22 @@ function validateConfigKey(key) {
116
93
  }
117
94
  const unsafe = new Set(["__proto__", "constructor", "prototype"]);
118
95
  if (segments.some(segment => unsafe.has(segment))) {
119
- return `Config change key "${key}" is not writable`;
96
+ return `Config key "${key}" is not writable`;
120
97
  }
121
98
  return undefined;
122
99
  }
100
+ /**
101
+ * Classify one validated key without consulting either project file.
102
+ * @param key - Safe non-empty dot path
103
+ * @returns Fixed persistence target, or undefined when the key is unauthorized
104
+ */
105
+ function configTarget(key) {
106
+ if (LOCAL_CONFIG_KEYS.has(key))
107
+ return "local";
108
+ return SYNC_REGISTRY.some(entry => key === entry.key || key.startsWith(`${entry.key}.`))
109
+ ? "committed"
110
+ : undefined;
111
+ }
123
112
  /**
124
113
  * Validate one sparse config-write entry.
125
114
  * @param key - Dot-path config key
@@ -157,23 +146,6 @@ function validateProspectiveConfig(config) {
157
146
  }
158
147
  });
159
148
  }
160
- /**
161
- * Resolve a UI change to the registry boundary that sync treats atomically.
162
- * @param key - Submitted dot-path config key
163
- * @returns Most specific owning registry key, when the change is sync-managed
164
- * @remarks Descendant saves claim human ownership at the registry root because
165
- * sync records and evolves the whole registered value as one default.
166
- */
167
- function syncOwnerKey(key) {
168
- return SYNC_REGISTRY.reduce((owner, entry) => {
169
- if (key !== entry.key && !key.startsWith(`${entry.key}.`)) {
170
- return owner;
171
- }
172
- return owner === undefined || entry.key.length > owner.length
173
- ? entry.key
174
- : owner;
175
- }, undefined);
176
- }
177
149
  /**
178
150
  * Parse and validate the sparse config-write payload.
179
151
  * @param value - Parsed JSON request body
@@ -183,11 +155,11 @@ function parseConfigWritePayload(value) {
183
155
  if (!isJsonObject(value)) {
184
156
  return { error: "Payload must be a JSON object" };
185
157
  }
186
- const changes = value.changes;
187
- if (!isJsonObject(changes)) {
158
+ const rawChanges = value.changes;
159
+ if (!isJsonObject(rawChanges)) {
188
160
  return { error: "Payload must include a changes object" };
189
161
  }
190
- const entries = Object.entries(changes);
162
+ const entries = Object.entries(rawChanges);
191
163
  if (entries.length === 0) {
192
164
  return { error: "Payload changes must include at least one config key" };
193
165
  }
@@ -197,7 +169,18 @@ function parseConfigWritePayload(value) {
197
169
  if (error !== undefined) {
198
170
  return { error };
199
171
  }
200
- return { changes: Object.fromEntries(entries) };
172
+ const unknown = entries.find(([key]) => configTarget(key) === undefined);
173
+ if (unknown !== undefined) {
174
+ return { error: `Config key "${unknown[0]}" is not writable` };
175
+ }
176
+ const changes = entries.reduce((routed, [key, change]) => {
177
+ const target = configTarget(key);
178
+ return {
179
+ ...routed,
180
+ [target]: { ...routed[target], [key]: change },
181
+ };
182
+ }, { committed: {}, local: {} });
183
+ return { changes };
201
184
  }
202
185
  /**
203
186
  * Read a bounded JSON body from an incoming request.
@@ -220,56 +203,28 @@ async function readJsonBody(request) {
220
203
  if (chunks.length === 0) {
221
204
  throw new RequestBodyError("Payload body is required");
222
205
  }
206
+ const text = decodeRequestBody(Buffer.concat(chunks));
223
207
  try {
224
- return JSON.parse(Buffer.concat(chunks).toString("utf8"));
208
+ return parseUnambiguousJson(text, "Payload body");
225
209
  }
226
210
  catch {
227
211
  throw new RequestBodyError("Payload body must be valid JSON");
228
212
  }
229
213
  }
230
214
  /**
231
- * Serialize committed-config writes per project root.
232
- * @param destDir - Project root whose committed config is being written
233
- * @param operation - Read-modify-write operation to run after prior writes
234
- * @returns Result of the queued operation
215
+ * Decode request bytes without replacement characters so malformed encodings
216
+ * cannot be normalized into a different valid property name or value.
217
+ * @param bytes - Exact bounded request entity
218
+ * @returns Valid UTF-8 request text
235
219
  */
236
- async function withConfigWriteLock(destDir, operation) {
237
- const previous = configWriteQueues.get(destDir) ?? Promise.resolve();
238
- const running = previous.catch(() => undefined).then(operation);
239
- const marker = running.then(() => undefined, () => undefined);
240
- // eslint-disable-next-line functional/immutable-data -- per-project async write queue
241
- configWriteQueues.set(destDir, marker);
220
+ function decodeRequestBody(bytes) {
242
221
  try {
243
- return await running;
222
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
244
223
  }
245
- finally {
246
- if (configWriteQueues.get(destDir) === marker) {
247
- // eslint-disable-next-line functional/immutable-data -- queue entry is complete
248
- configWriteQueues.delete(destDir);
249
- }
224
+ catch {
225
+ throw new RequestBodyError("Payload body must be valid JSON");
250
226
  }
251
227
  }
252
- /**
253
- * Write a sparse config payload after all validation has completed.
254
- * @param destDir - Project root whose committed config is written
255
- * @param changes - Validated dot-path changes
256
- * @returns The updated committed config
257
- */
258
- async function writeConfigChanges(destDir, changes) {
259
- return await withConfigWriteLock(destDir, async () => {
260
- const original = await readCommittedConfig(destDir);
261
- const next = Object.entries(changes).reduce((state, [key, value]) => {
262
- const changed = setAtPath(state, key, value);
263
- const ownerKey = syncOwnerKey(key);
264
- return ownerKey === undefined
265
- ? changed
266
- : removePopulation(changed, ownerKey);
267
- }, original);
268
- validateProspectiveConfig(next);
269
- await writeJson(path.join(destDir, CONFIG_FILE), next);
270
- return next;
271
- });
272
- }
273
228
  /**
274
229
  * Serve the same-origin committed-config write endpoint.
275
230
  * @param request - Incoming loopback request
@@ -307,7 +262,7 @@ export function serveConfigWrite(request, response, destDir) {
307
262
  response.end(JSON.stringify({ error: parsed.error }));
308
263
  return;
309
264
  }
310
- const committed = await writeConfigChanges(destDir, parsed.changes);
265
+ const committed = await persistRoutedConfigChanges(destDir, parsed.changes, validateProspectiveConfig);
311
266
  response.writeHead(200, {
312
267
  "cache-control": NO_STORE,
313
268
  "content-type": JSON_CONTENT_TYPE,
@@ -1 +1 @@
1
- {"version":3,"file":"ui-config-write.js","sourceRoot":"","sources":["../../src/cli/ui-config-write.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ui-config-write.js","sourceRoot":"","sources":["../../src/cli/ui-config-write.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"upstream-evidence-manifest.d.ts","sourceRoot":"","sources":["../../src/core/upstream-evidence-manifest.ts"],"names":[],"mappings":"AACA,iFAAiF;AACjF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA46EpE,CAAC;AAEL,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAiuPjE,CAAC;AAEL,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAk6I/D,CAAC"}
1
+ {"version":3,"file":"upstream-evidence-manifest.d.ts","sourceRoot":"","sources":["../../src/core/upstream-evidence-manifest.ts"],"names":[],"mappings":"AACA,iFAAiF;AACjF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA46EpE,CAAC;AAEL,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAuuPjE,CAAC;AAEL,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAk6I/D,CAAC"}
@@ -1236,7 +1236,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
1236
1236
  "typescript/merge/.claude/settings.json": "834e6456cae81f45073bbbb08bf731fef043efb30cae2658cb4a59f17e66d165",
1237
1237
  "typescript/merge/.oxlintrc.json": "9504c20db80470c242c4ffe8cccad6951ed8141dfb5bf6503053e0b2712ab276",
1238
1238
  "typescript/package-lisa/package.lisa.json": "f1ac8d411748b66a2c32a0d81eefac4962d2829b25ec21940a1bd0727dc167a4",
1239
- "ui/README.md": "ee05dac69cbba5f74a4ff945e78afdd54bd62d26087a255799dbbfc943f52b45",
1239
+ "ui/README.md": "5e5a66c41035b3748cdf2c0015558dc420c53fb904596bcede636ba058786b87",
1240
1240
  "ui/index.html": "97db4b30d9168bf96db7fb0bbcf4b87fe175f415182fe58abf0026750c9db69c",
1241
1241
  });
1242
1242
  /** Exact paths tracked by the public Lisa repository at generation time. */
@@ -7312,6 +7312,12 @@ export const UPSTREAM_SURFACE_MANIFEST = Object.freeze({
7312
7312
  "src/cli/ui-ci-quality-jobs-parse.ts": true,
7313
7313
  "src/cli/ui-ci-quality-jobs.ts": true,
7314
7314
  "src/cli/ui-cmd.ts": true,
7315
+ "src/cli/ui-config-write-document.ts": true,
7316
+ "src/cli/ui-config-write-patch-plan.ts": true,
7317
+ "src/cli/ui-config-write-persistence.ts": true,
7318
+ "src/cli/ui-config-write-property-edits.ts": true,
7319
+ "src/cli/ui-config-write-provenance.ts": true,
7320
+ "src/cli/ui-config-write-root-identity.ts": true,
7315
7321
  "src/cli/ui-config-write.ts": true,
7316
7322
  "src/cli/ui-confined-project-read.ts": true,
7317
7323
  "src/cli/ui-deploy-pipeline-model.ts": true,