ossclip 0.1.11 → 0.1.12
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/editor-dist/assets/{index-Bo0WME7k.js → index-BBVLCP-N.js} +24 -24
- package/editor-dist/index.html +1 -1
- package/package.json +4 -4
- package/src/interactive/produce-argv.ts +9 -0
- package/src/interactive/produce-wizard.ts +133 -17
- package/src/produce.ts +170 -9
- package/src/program.ts +57 -3
- package/src/replay-argv.ts +19 -1
- package/src/stranded-overrides.ts +77 -0
package/src/replay-argv.ts
CHANGED
|
@@ -48,7 +48,11 @@ export function consumeReplayArgv(): string[] | null {
|
|
|
48
48
|
* `includes` so a flag the user actually typed — or a pin recorded by the
|
|
49
49
|
* run a replay is re-running — is never appended twice.
|
|
50
50
|
*/
|
|
51
|
-
export function recordedProduceArgs(pins: {
|
|
51
|
+
export function recordedProduceArgs(pins: {
|
|
52
|
+
llm?: string;
|
|
53
|
+
clipWindow?: string;
|
|
54
|
+
watermark?: boolean;
|
|
55
|
+
}): string[] {
|
|
52
56
|
const args = consumeReplayArgv() ?? process.argv.slice(2);
|
|
53
57
|
if (pins.llm !== undefined && !args.includes("--llm")) {
|
|
54
58
|
args.push("--llm", pins.llm);
|
|
@@ -56,5 +60,19 @@ export function recordedProduceArgs(pins: { llm?: string; clipWindow?: string })
|
|
|
56
60
|
if (pins.clipWindow !== undefined && !args.includes("--clip-window")) {
|
|
57
61
|
args.push("--clip-window", pins.clipWindow);
|
|
58
62
|
}
|
|
63
|
+
// The watermark, pinned like §75 pinned the provider — in BOTH directions
|
|
64
|
+
// (review, Important): the effective default is config-dependent, so "no
|
|
65
|
+
// flag in the argv" does not replay identically everywhere. An off-record
|
|
66
|
+
// left unpinned would silently GAIN a watermark the moment the replay runs
|
|
67
|
+
// under a config-on (`~/.ossclip/config.json` edited later, or the editor's
|
|
68
|
+
// Render on another machine) — the exact drift §75 exists to prevent, just
|
|
69
|
+
// mirrored. So every record carries the RESOLVED state: `--watermark` when
|
|
70
|
+
// on, `--no-watermark` when off, and a typed flag (already in the argv,
|
|
71
|
+
// caught by the includes-guard) is never doubled. One flag per command.json
|
|
72
|
+
// is the price; determinism is the contract, byte-identity of off-records
|
|
73
|
+
// was only ever a nicety.
|
|
74
|
+
if (pins.watermark !== undefined && !args.includes("--watermark") && !args.includes("--no-watermark")) {
|
|
75
|
+
args.push(pins.watermark ? "--watermark" : "--no-watermark");
|
|
76
|
+
}
|
|
59
77
|
return args;
|
|
60
78
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* §131's residue: renaming/adding/removing clips in a folder input re-keys
|
|
5
|
+
* the content hash, so produce derives a FRESH workdir — correct for every
|
|
6
|
+
* cache (a stale transcript against a different edit is the bug §131's
|
|
7
|
+
* manifest hashing exists to prevent), but the OLD workdir's editor edits
|
|
8
|
+
* (`overrides.json`) are user-owned work that silently stops being found.
|
|
9
|
+
* The user sees a clean produce and never learns their edits live one
|
|
10
|
+
* sibling directory over. This module is the pure half of the pointer that
|
|
11
|
+
* closes that gap: given the sibling directory listing, decide WHICH
|
|
12
|
+
* directories to point at. All filesystem reads stay in produce.ts so the
|
|
13
|
+
* cross-folder matching rules below are testable without a disk.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The `<basename>-<hash8>` naming's basename half, shared with
|
|
18
|
+
* `deriveWorkdir` (produce.ts) so the sibling scan can never disagree with
|
|
19
|
+
* the naming scheme it scans for — a drift between the two would make every
|
|
20
|
+
* pointer silently miss.
|
|
21
|
+
*/
|
|
22
|
+
export function workdirBaseName(identity: string): string {
|
|
23
|
+
return basename(identity).replace(/\.[^.]+$/, "");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface SiblingWorkdirEntry {
|
|
27
|
+
/** Directory entry name inside the workdir root (not a full path). */
|
|
28
|
+
name: string;
|
|
29
|
+
hasOverrides: boolean;
|
|
30
|
+
/** mtime of the entry's overrides.json — 0 when it has none. */
|
|
31
|
+
mtimeMs: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Cap on printed pointers — a folder edited across many re-keys must not flood the run log. */
|
|
35
|
+
export const MAX_STRANDED_POINTERS = 3;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Which sibling workdirs hold stranded editor edits for this folder, newest
|
|
39
|
+
* edit first. Matching is prefix + exactly-8-lowercase-hex (sha1's own
|
|
40
|
+
* alphabet), NOT a loose startsWith: `MyClips2-bbbbbbbb` must never match
|
|
41
|
+
* base `MyClips` (a different folder entirely), and requiring the hash shape
|
|
42
|
+
* after the `-` is what rules it out — `2-bbbbbbbb` is not 8 hex. The
|
|
43
|
+
* optional `-16x9` tail mirrors deriveWorkdir's landscape suffix; edits
|
|
44
|
+
* stranded in either aspect's workdir are still this folder's edits. Same
|
|
45
|
+
* hash in the other aspect is excluded: that workdir is reachable by
|
|
46
|
+
* re-running with the other --aspect, not stranded by a re-key.
|
|
47
|
+
*/
|
|
48
|
+
export function strandedOverrideSiblings(p: {
|
|
49
|
+
base: string;
|
|
50
|
+
/** This run's 8-hex content hash — its own workdirs are not "previous". */
|
|
51
|
+
currentHash: string;
|
|
52
|
+
entries: SiblingWorkdirEntry[];
|
|
53
|
+
}): string[] {
|
|
54
|
+
const prefix = `${p.base}-`;
|
|
55
|
+
return p.entries
|
|
56
|
+
.filter((e) => {
|
|
57
|
+
if (!e.hasOverrides || !e.name.startsWith(prefix)) return false;
|
|
58
|
+
const m = /^([0-9a-f]{8})(-16x9)?$/.exec(e.name.slice(prefix.length));
|
|
59
|
+
return m !== null && m[1] !== p.currentHash;
|
|
60
|
+
})
|
|
61
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs)
|
|
62
|
+
.slice(0, MAX_STRANDED_POINTERS)
|
|
63
|
+
.map((e) => e.name);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The printed pointer. Says "for this folder" deliberately loosely — two
|
|
68
|
+
* different folders sharing a basename under one --workdir root can collide
|
|
69
|
+
* into this list, and the wording stays honest for that case rather than
|
|
70
|
+
* claiming a provenance the name alone can't prove (§131 brief).
|
|
71
|
+
*/
|
|
72
|
+
export function strandedPointerLine(path: string): string {
|
|
73
|
+
return (
|
|
74
|
+
`▸ previous project for this folder: ${path} ` +
|
|
75
|
+
`(has editor edits — they don't carry over; open it with: ossclip edit '${path}')`
|
|
76
|
+
);
|
|
77
|
+
}
|