dsh-hashline-edit 0.2.0 → 0.2.2

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 (109) hide show
  1. package/README.md +59 -55
  2. package/cordis.patch.yml +1 -1
  3. package/lib/index.js +7225 -6445
  4. package/lib/types/dsh/contracts.d.ts +3 -12
  5. package/lib/types/dsh/fs.d.ts +0 -3
  6. package/lib/types/dsh/guidance.d.ts +5 -5
  7. package/lib/types/dsh/host-compat.d.ts +78 -7
  8. package/lib/types/dsh/index.d.ts +7 -17
  9. package/lib/types/dsh/metrics/events.d.ts +1 -1
  10. package/lib/types/dsh/metrics/observer.d.ts +1 -1
  11. package/lib/types/dsh/sandbox.d.ts +2 -2
  12. package/lib/types/dsh/shell-hook.d.ts +1 -1
  13. package/lib/types/dsh/tools/edit.d.ts +10 -0
  14. package/lib/types/dsh/tools/read.d.ts +3 -3
  15. package/lib/types/src/domain-errors.d.ts +2 -16
  16. package/lib/types/src/edit-tool.d.ts +41 -0
  17. package/lib/types/src/edit-undo.d.ts +2 -11
  18. package/lib/types/src/file-content/index.d.ts +1 -1
  19. package/lib/types/src/file-content/preview.d.ts +1 -1
  20. package/lib/types/src/hash-store.d.ts +2 -2
  21. package/lib/types/src/hashline/alphabet.d.ts +16 -1
  22. package/lib/types/src/hashline/hash-identity.d.ts +10 -4
  23. package/lib/types/src/mutation-engine/engine.d.ts +31 -0
  24. package/lib/types/src/mutation-engine/pipeline.d.ts +1 -8
  25. package/lib/types/src/mutation-engine/types.d.ts +50 -40
  26. package/lib/types/src/payload-contract.d.ts +135 -0
  27. package/lib/types/src/served-session/serve-render.d.ts +0 -6
  28. package/lib/types/src/undo-store.d.ts +1 -17
  29. package/package.json +21 -10
  30. package/prompts/edit-guidelines.md +10 -0
  31. package/prompts/edit-snippet.md +1 -0
  32. package/prompts/edit.md +1 -0
  33. package/prompts/read-guidelines.md +4 -4
  34. package/prompts/read.md +1 -1
  35. package/prompts/undo-last-edit-guidelines.md +2 -2
  36. package/prompts/undo-last-edit-snippet.md +1 -1
  37. package/prompts/undo-last-edit.md +1 -1
  38. package/src/bash-classifier.ts +1626 -0
  39. package/src/bash-conversion/decide.ts +812 -0
  40. package/src/bash-display-transform.ts +50 -0
  41. package/src/bash-multifile-config.ts +239 -0
  42. package/src/bash-view-config.ts +158 -0
  43. package/src/cut-repair.ts +11 -77
  44. package/src/domain-errors.ts +3 -35
  45. package/src/edit-normalize.ts +8 -0
  46. package/src/edit-render.ts +161 -0
  47. package/src/edit-tool.ts +118 -0
  48. package/src/edit-undo.ts +25 -379
  49. package/src/edit.ts +136 -0
  50. package/src/file-content/index.ts +1 -1
  51. package/src/file-content/preview.ts +1 -1
  52. package/src/file-content/served-header.ts +1 -1
  53. package/src/hash-store.ts +1 -18
  54. package/src/hashline/alphabet.ts +42 -1
  55. package/src/hashline/hash-identity.ts +12 -3
  56. package/src/integrations/pi-lens/command.ts +712 -0
  57. package/src/integrations/pi-lens/config.ts +148 -0
  58. package/src/integrations/pi-lens/io-bridge-adapter.ts +234 -0
  59. package/src/integrations/pi-lens/io-bridge.ts +112 -0
  60. package/src/integrations/pi-lens/settings-overlay.ts +272 -0
  61. package/src/lifecycle-hooks/index.ts +1992 -0
  62. package/src/lifecycle-hooks/types.ts +64 -0
  63. package/src/mutated-files.ts +75 -0
  64. package/src/mutation-engine/engine.ts +239 -0
  65. package/src/mutation-engine/index.ts +17 -0
  66. package/src/mutation-engine/pipeline.ts +27 -198
  67. package/src/mutation-engine/types.ts +57 -39
  68. package/src/mutation-queue.ts +1 -1
  69. package/src/payload-contract.ts +685 -0
  70. package/src/preview-controller.ts +84 -0
  71. package/src/prompts.ts +43 -10
  72. package/src/read.ts +865 -0
  73. package/src/search-hook.ts +41 -0
  74. package/src/served-session/serve-render.ts +2 -2
  75. package/src/store-config.ts +73 -0
  76. package/src/store-janitor-warning.ts +169 -0
  77. package/src/store-janitor.ts +539 -0
  78. package/src/store-kernel/settings.ts +233 -0
  79. package/src/store.ts +154 -0
  80. package/src/tui-presenter.ts +134 -0
  81. package/src/undo-store.ts +5 -74
  82. package/src/write-hook.ts +130 -0
  83. package/lib/types/dsh/hide.d.ts +0 -78
  84. package/lib/types/dsh/tools/apply-patch.d.ts +0 -38
  85. package/lib/types/src/apply-patch/commit.d.ts +0 -49
  86. package/lib/types/src/apply-patch/grammar.d.ts +0 -29
  87. package/lib/types/src/apply-patch/lifecycle.d.ts +0 -32
  88. package/lib/types/src/apply-patch/plan.d.ts +0 -50
  89. package/lib/types/src/apply-patch/render.d.ts +0 -51
  90. package/lib/types/src/apply-patch/resolve.d.ts +0 -129
  91. package/lib/types/src/apply-patch/tool.d.ts +0 -54
  92. package/lib/types/src/apply-patch/types.d.ts +0 -362
  93. package/lib/types/src/fs-lifecycle.d.ts +0 -44
  94. package/lib/types/src/host-utils.d.ts +0 -63
  95. package/lib/types/src/mutation-engine/edit-request.d.ts +0 -34
  96. package/prompts/apply-patch-guidelines.md +0 -10
  97. package/prompts/apply-patch.md +0 -1
  98. package/src/apply-patch/commit.ts +0 -190
  99. package/src/apply-patch/grammar.ts +0 -620
  100. package/src/apply-patch/index.ts +0 -17
  101. package/src/apply-patch/lifecycle.ts +0 -195
  102. package/src/apply-patch/plan.ts +0 -800
  103. package/src/apply-patch/render.ts +0 -137
  104. package/src/apply-patch/resolve.ts +0 -470
  105. package/src/apply-patch/tool.ts +0 -257
  106. package/src/apply-patch/types.ts +0 -387
  107. package/src/fs-lifecycle.ts +0 -201
  108. package/src/host-utils.ts +0 -224
  109. package/src/mutation-engine/edit-request.ts +0 -39
@@ -0,0 +1,84 @@
1
+ import { getPreviewInput, type RPreview, type RRState } from "./edit-render.js";
2
+
3
+ export const PREVIEW_DEBOUNCE_MS = 150;
4
+
5
+ export interface PreviewHost {
6
+ cwd: string;
7
+ executionStarted: boolean;
8
+ argsComplete: boolean;
9
+ state: RRState;
10
+ invalidate: () => void;
11
+ }
12
+
13
+ export type PreviewCompute = (args: unknown, cwd: string) => Promise<RPreview>;
14
+
15
+ // SAFETY: large-class — cohesive store owns DB and cache as single owner; split would scatter invariants.
16
+ export class DebouncedPreview {
17
+ constructor(
18
+ private readonly compute: PreviewCompute,
19
+ private readonly debounceMs: number = PREVIEW_DEBOUNCE_MS,
20
+ private readonly getSessionId?: () => string | undefined,
21
+ ) {}
22
+
23
+ renderCall(host: PreviewHost, args: unknown): void {
24
+ const { state } = host;
25
+ const previewInput = getPreviewInput(args);
26
+ if (host.executionStarted || !host.argsComplete || !previewInput) {
27
+ this.cancel(state);
28
+ return;
29
+ }
30
+ const argsKey = JSON.stringify(previewInput);
31
+ if (state.argsKey === argsKey) return;
32
+ this.cancel(state);
33
+ state.argsKey = argsKey;
34
+ const previewGeneration = (state.previewGeneration ?? 0) + 1;
35
+ state.previewGeneration = previewGeneration;
36
+ // WHY: (#168-class) the compute's session is bound at arm time: if the serving session
37
+ // WHY: changed before the timer fires, verifying these anchors against the new session
38
+ // WHY: would mint a false E_UNKNOWN_ANCHOR, so the stale compute is dropped (cancelled)
39
+ // WHY: and the next renderCall re-arms against the session that actually serves anchors.
40
+ const armedSessionId = this.getSessionId?.();
41
+ state.previewTimer = setTimeout(() => {
42
+ delete state.previewTimer;
43
+ if (this.getSessionId && this.getSessionId() !== armedSessionId) {
44
+ this.cancel(state);
45
+ host.invalidate();
46
+ return;
47
+ }
48
+ this.compute(args, host.cwd)
49
+ .then((preview) => {
50
+ if (state.argsKey === argsKey && state.previewGeneration === previewGeneration) {
51
+ state.preview = preview;
52
+ host.invalidate();
53
+ }
54
+ })
55
+ .catch((err: unknown) => {
56
+ if (state.argsKey === argsKey && state.previewGeneration === previewGeneration) {
57
+ state.preview = {
58
+ error: err instanceof Error ? err.message : String(err),
59
+ };
60
+ host.invalidate();
61
+ }
62
+ });
63
+ }, this.debounceMs);
64
+ }
65
+
66
+ cancel(state: RRState): void {
67
+ if (state.previewTimer) {
68
+ clearTimeout(state.previewTimer);
69
+ delete state.previewTimer;
70
+ }
71
+ delete state.argsKey;
72
+ delete state.preview;
73
+ state.previewGeneration = (state.previewGeneration ?? 0) + 1;
74
+ }
75
+
76
+ clearResult(state: RRState): void {
77
+ if (state.previewTimer) {
78
+ clearTimeout(state.previewTimer);
79
+ delete state.previewTimer;
80
+ }
81
+ delete state.preview;
82
+ state.previewGeneration = (state.previewGeneration ?? 0) + 1;
83
+ }
84
+ }
package/src/prompts.ts CHANGED
@@ -1,23 +1,56 @@
1
1
  import { readFileSync } from "node:fs";
2
+ import { HASH_LEN } from "./hashline/alphabet.js";
3
+ import {
4
+ ANCHOR_EXAMPLE,
5
+ EDIT_DESCRIPTION,
6
+ EDIT_SNIPPET,
7
+ EDIT_GUIDELINES,
8
+ } from "./payload-contract.js";
2
9
 
3
- export function loadP(relativePath: string, replacements?: Record<string, string>): string {
4
- let content = readFileSync(new URL(relativePath, import.meta.url), "utf-8").trim();
10
+ /**
11
+ * Resolve template variables in shipped prompt prose. Beyond caller-supplied replacements, the
12
+ * anchor-width token and its example are ALWAYS resolved from the live HASH_LEN: the width is a
13
+ * build-time setting (ADR-0020), so any prompt that quotes it must not hardcode a digit.
14
+ */
15
+ function applyReplacements(content: string, replacements?: Record<string, string>): string {
16
+ let out = content;
5
17
  if (replacements) {
6
18
  for (const [key, value] of Object.entries(replacements)) {
7
- content = content.split(`{{${key}}}`).join(value);
19
+ out = out.split(`{{${key}}}`).join(value);
8
20
  }
9
21
  }
10
- return content;
22
+ return out
23
+ .split("{{HASH_LEN}}")
24
+ .join(String(HASH_LEN))
25
+ .split("{{ANCHOR_EXAMPLE}}")
26
+ .join(ANCHOR_EXAMPLE);
27
+ }
28
+
29
+ const EDIT_PROMPT_FILES = new Set([
30
+ "../prompts/edit.md",
31
+ "prompts/edit.md",
32
+ "../prompts/edit-snippet.md",
33
+ "prompts/edit-snippet.md",
34
+ ]);
35
+
36
+ const EDIT_GUIDE_FILES = new Set(["../prompts/edit-guidelines.md", "prompts/edit-guidelines.md"]);
37
+
38
+ export function loadP(relativePath: string, replacements?: Record<string, string>): string {
39
+ if (EDIT_PROMPT_FILES.has(relativePath)) {
40
+ const content = relativePath.includes("snippet") ? EDIT_SNIPPET : EDIT_DESCRIPTION;
41
+ return applyReplacements(content, replacements);
42
+ }
43
+ const content = readFileSync(new URL(relativePath, import.meta.url), "utf-8").trim();
44
+ return applyReplacements(content, replacements);
11
45
  }
12
46
 
13
47
  export function loadGuide(relativePath: string, replacements?: Record<string, string>): string[] {
14
- let content = readFileSync(new URL(relativePath, import.meta.url), "utf-8");
15
- if (replacements) {
16
- for (const [key, value] of Object.entries(replacements)) {
17
- content = content.split(`{{${key}}}`).join(value);
18
- }
48
+ if (EDIT_GUIDE_FILES.has(relativePath)) {
49
+ const guidelines = [...EDIT_GUIDELINES];
50
+ return guidelines.map((line) => applyReplacements(line, replacements));
19
51
  }
20
- return content
52
+ const content = readFileSync(new URL(relativePath, import.meta.url), "utf-8");
53
+ return applyReplacements(content, replacements)
21
54
  .split("\n")
22
55
  .map((line) => line.trim())
23
56
  .filter((line) => line.startsWith("- "))