ossclip 0.1.27 → 0.1.29
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-BBJKC2Z2.js +164 -0
- package/editor-dist/index.html +1 -1
- package/package.json +4 -4
- package/src/edit.ts +42 -0
- package/src/interactive/produce-argv.ts +14 -0
- package/src/interactive/produce-wizard.ts +28 -0
- package/src/llm-detect.ts +11 -0
- package/src/produce.ts +638 -177
- package/src/program.ts +48 -4
- package/src/replay-argv.ts +22 -1
- package/src/setup/download.ts +24 -0
- package/src/setup/manifest.ts +30 -12
- package/src/setup/setup.ts +47 -4
- package/editor-dist/assets/index-CWIUcpJC.js +0 -163
package/editor-dist/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>ossclip editor</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-BBJKC2Z2.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-Bx2VQLP8.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ossclip",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.29",
|
|
4
4
|
"description": "Local-first CLI video producer: cuts silence and fillers, word-timed captions, face-aware framing, and LLM-planned code-rendered graphics — transcription and rendering never leave your machine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"commander": "^12.1.0",
|
|
37
37
|
"tsx": "^4.19.0",
|
|
38
38
|
"zod": "^3.25.76",
|
|
39
|
-
"@ossclip/core": "0.1.
|
|
40
|
-
"@ossclip/scenes": "0.1.
|
|
41
|
-
"@ossclip/renderer": "0.1.
|
|
39
|
+
"@ossclip/core": "0.1.29",
|
|
40
|
+
"@ossclip/scenes": "0.1.29",
|
|
41
|
+
"@ossclip/renderer": "0.1.29"
|
|
42
42
|
},
|
|
43
43
|
"homepage": "https://github.com/AhsanAyaz/ossclip#readme",
|
|
44
44
|
"bugs": {
|
package/src/edit.ts
CHANGED
|
@@ -30,6 +30,8 @@ import {
|
|
|
30
30
|
PORTRAIT_MIME_TYPES,
|
|
31
31
|
portraitMimeType,
|
|
32
32
|
readCoverProvenance,
|
|
33
|
+
SegmentSchema,
|
|
34
|
+
type Segment,
|
|
33
35
|
thumbnailImageCacheName,
|
|
34
36
|
type CoverProvenance,
|
|
35
37
|
type GenerateThumbnailImageOptions,
|
|
@@ -548,6 +550,46 @@ export async function startEditServer(
|
|
|
548
550
|
});
|
|
549
551
|
}
|
|
550
552
|
|
|
553
|
+
if (url.pathname === "/api/cleanup" && req.method === "GET") {
|
|
554
|
+
// The labeled removals: since cut review step 3 this serves the
|
|
555
|
+
// PROPOSAL (`cutlistProposed` — the automatic cutlist before the
|
|
556
|
+
// user's cleanup vetoes and user cuts), because that is what the
|
|
557
|
+
// editor's checkboxes and seams reason about: a DECLINED pause has
|
|
558
|
+
// already merged into a plain keep in the resolved `cutlist`, so
|
|
559
|
+
// serving that would make the veto invisible the moment it worked.
|
|
560
|
+
// The fallback to `cutlist` keeps pre-step-3 workdirs drawing their
|
|
561
|
+
// seams — back then the recorded cutlist WAS the proposal (plus
|
|
562
|
+
// applied user cuts, whose seams the applied-cut restore marker
|
|
563
|
+
// draws independently anyway). Same lenient-read posture as
|
|
564
|
+
// /api/usage above: a missing or corrupt production.json degrades
|
|
565
|
+
// to an empty cutlist, never a 500 — the timeline simply draws no
|
|
566
|
+
// removal seams.
|
|
567
|
+
if (!workdir) return send(409, { error: "no workdir open" });
|
|
568
|
+
let cutlist: Segment[] = [];
|
|
569
|
+
try {
|
|
570
|
+
const production = JSON.parse(
|
|
571
|
+
await readFile(join(workdir, "production.json"), "utf8"),
|
|
572
|
+
) as { cutlist?: unknown; cutlistProposed?: unknown };
|
|
573
|
+
const source = Array.isArray(production.cutlistProposed)
|
|
574
|
+
? production.cutlistProposed
|
|
575
|
+
: production.cutlist;
|
|
576
|
+
if (Array.isArray(source)) {
|
|
577
|
+
// Each span parses ALONE: a hand-edited production.json with
|
|
578
|
+
// one bad span (a string srcIn, a negative time) drops that
|
|
579
|
+
// span and keeps the rest, instead of either 500ing or letting
|
|
580
|
+
// a NaN through to position a seam off-screen. zod parse, not
|
|
581
|
+
// a cast — the house rule for anything a user can have edited.
|
|
582
|
+
cutlist = source.flatMap((s) => {
|
|
583
|
+
const parsed = SegmentSchema.safeParse(s);
|
|
584
|
+
return parsed.success ? [parsed.data] : [];
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
} catch {
|
|
588
|
+
// degrade — same as /api/usage's readJson
|
|
589
|
+
}
|
|
590
|
+
return send(200, { cutlist });
|
|
591
|
+
}
|
|
592
|
+
|
|
551
593
|
if (url.pathname === "/api/workdir" && req.method === "POST") {
|
|
552
594
|
// Open/switch the project (R17 §83). Refused mid-render: the
|
|
553
595
|
// running child belongs to the CURRENT workdir, and its status
|
|
@@ -63,6 +63,15 @@ export interface ProduceAnswers {
|
|
|
63
63
|
graphics: boolean;
|
|
64
64
|
intent?: string;
|
|
65
65
|
out?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Review the cut in the editor instead of rendering now (§148). A main-flow
|
|
68
|
+
* answer like `graphics`, not an extra: it decides what the run DOES, and
|
|
69
|
+
* burying it in "Anything else?" would hide it from the people the wizard
|
|
70
|
+
* exists for. The only answer whose wizard default (review) differs from
|
|
71
|
+
* the CLI's (render) — which costs nothing here, because the elision rule
|
|
72
|
+
* below keys off the CLI default, not off what the prompt preselected.
|
|
73
|
+
*/
|
|
74
|
+
review?: boolean;
|
|
66
75
|
extras: ProduceExtras;
|
|
67
76
|
}
|
|
68
77
|
|
|
@@ -76,6 +85,11 @@ export function produceArgv(a: ProduceAnswers): string[] {
|
|
|
76
85
|
if (a.aspect !== "9:16") argv.push("--aspect", a.aspect);
|
|
77
86
|
if (a.cleanup !== "standard") argv.push("--cleanup", a.cleanup);
|
|
78
87
|
if (a.out) argv.push("--out", a.out);
|
|
88
|
+
// Rendering is the CLI's default, so only reviewing is worth saying — the
|
|
89
|
+
// rule above is about the DEFAULT, not about which option the prompt
|
|
90
|
+
// preselected. --out still travels either way: nothing renders now, but the
|
|
91
|
+
// editor's Render button replays command.json, and that is where out lands.
|
|
92
|
+
if (a.review === true) argv.push("--review");
|
|
79
93
|
|
|
80
94
|
if (a.graphics) {
|
|
81
95
|
argv.push("--produce");
|
|
@@ -505,6 +505,33 @@ export async function produceWizard(
|
|
|
505
505
|
) as ProduceExtras["llm"];
|
|
506
506
|
}
|
|
507
507
|
|
|
508
|
+
// LAST, because it decides what happens after every answer above it — and
|
|
509
|
+
// asked at all because until §148 the wizard could not reach --review, so
|
|
510
|
+
// `ossclip` with no arguments, the entry point a first-time user takes,
|
|
511
|
+
// could only render first and offer the editor afterwards. That is the
|
|
512
|
+
// opposite of what --review is for: the render is the expensive step, and
|
|
513
|
+
// reviewing exists so it happens once, on a cut you already agreed with.
|
|
514
|
+
//
|
|
515
|
+
// Leaning to review is the one place a wizard default differs from the
|
|
516
|
+
// CLI's. It costs nothing: produceArgv elides against the CLI default, so
|
|
517
|
+
// choosing to render still teaches `ossclip produce <file>` and choosing to
|
|
518
|
+
// review teaches the flag that did it.
|
|
519
|
+
const review =
|
|
520
|
+
unwrap(
|
|
521
|
+
await select({
|
|
522
|
+
message: "Render now, or review the cut first?",
|
|
523
|
+
initialValue: "review",
|
|
524
|
+
options: [
|
|
525
|
+
{
|
|
526
|
+
value: "review",
|
|
527
|
+
label: "Review the cut first",
|
|
528
|
+
hint: "opens the editor; render from its button",
|
|
529
|
+
},
|
|
530
|
+
{ value: "render", label: "Render now", hint: "straight to a finished file" },
|
|
531
|
+
],
|
|
532
|
+
}),
|
|
533
|
+
) === "review";
|
|
534
|
+
|
|
508
535
|
return produceArgv({
|
|
509
536
|
input,
|
|
510
537
|
aspect,
|
|
@@ -514,6 +541,7 @@ export async function produceWizard(
|
|
|
514
541
|
// Already `string | undefined`: pickSavePath's use-default row IS the
|
|
515
542
|
// old empty answer — no --out, produce derives its own default.
|
|
516
543
|
out,
|
|
544
|
+
review,
|
|
517
545
|
extras,
|
|
518
546
|
});
|
|
519
547
|
}
|
package/src/llm-detect.ts
CHANGED
|
@@ -60,3 +60,14 @@ export function detectionLine(name: ProviderName): string {
|
|
|
60
60
|
return "▸ using the mock provider (no LLM)";
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The out-loud line for a §143 timeout fallback (2026-08-22): agy expired its
|
|
66
|
+
* own print timeout on the editorial call and another provider is answering
|
|
67
|
+
* it. Names all three facts — who failed, on which call, who took over —
|
|
68
|
+
* because a silent substitution would be worse than the hang: the user must
|
|
69
|
+
* know which model planned their video.
|
|
70
|
+
*/
|
|
71
|
+
export function fallbackLine(from: string, to: string, schemaName: string): string {
|
|
72
|
+
return `⚠ ${from} timed out on ${schemaName} — falling back to ${to}`;
|
|
73
|
+
}
|