@litfamily/litopencode 1.0.31 → 1.0.33
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/CHANGELOG.md +38 -0
- package/README-Ko-KR.md +6 -6
- package/README.md +6 -6
- package/TRADEMARK.md +12 -0
- package/dist/activation-primary-prompts.js +5 -1
- package/dist/activation-probe.js +1 -0
- package/dist/activation-prompt-utils.d.ts +1 -1
- package/dist/activation-reentry.d.ts +20 -0
- package/dist/activation-reentry.js +110 -1
- package/dist/activation-routing.d.ts +2 -1
- package/dist/activation-routing.js +100 -11
- package/dist/activation-workflow-prompts.d.ts +4 -0
- package/dist/activation-workflow-prompts.js +30 -0
- package/dist/activation.d.ts +1 -1
- package/dist/activation.js +44 -5
- package/dist/adhd-next.d.ts +51 -0
- package/dist/adhd-next.js +150 -0
- package/dist/agents/defaults.js +1 -1
- package/dist/cli/managed-skill-assets.d.ts +1 -1
- package/dist/cli/managed-skill-assets.js +7 -1
- package/dist/cli/native-skill-integrity.js +1 -1
- package/dist/cli.js +7 -1
- package/dist/commands.d.ts +28 -1
- package/dist/commands.js +58 -5
- package/dist/durable-plan.d.ts +5 -1
- package/dist/durable-plan.js +14 -2
- package/dist/features.d.ts +80 -1
- package/dist/features.js +105 -1
- package/dist/hooks.js +3 -0
- package/dist/ledger.js +12 -1
- package/dist/plan-scope-roots.d.ts +23 -0
- package/dist/plan-scope-roots.js +116 -0
- package/dist/restart-notice.d.ts +7 -0
- package/dist/restart-notice.js +40 -0
- package/dist/secret-shapes.js +5 -5
- package/dist/server.js +4 -0
- package/dist/session-liveness.d.ts +20 -0
- package/dist/session-liveness.js +99 -0
- package/dist/skills.d.ts +22 -1
- package/dist/skills.js +36 -0
- package/dist/start-work-typed.d.ts +34 -0
- package/dist/start-work-typed.js +167 -0
- package/dist/state.d.ts +3 -0
- package/dist/state.js +3 -0
- package/dist/tools.js +22 -2
- package/dist/tui/mission-band.d.ts +22 -1
- package/dist/tui/mission-band.js +75 -16
- package/dist/tui/mission-looks.d.ts +38 -0
- package/dist/tui/mission-looks.js +73 -0
- package/dist/tui/mission-model.d.ts +2 -0
- package/dist/tui/mission-model.js +3 -1
- package/dist/tui/mission-rainbow.d.ts +33 -0
- package/dist/tui/mission-rainbow.js +90 -0
- package/dist/tui/mission-source.d.ts +49 -0
- package/dist/tui/mission-source.js +217 -2
- package/dist/tui/mission-text.d.ts +2 -0
- package/dist/tui/mission-text.js +9 -1
- package/dist/tui/mission-threads.d.ts +58 -0
- package/dist/tui/mission-threads.js +128 -0
- package/dist/tui.js +112 -7
- package/dist/uiux-visual-catalog.js +8 -1
- package/dist/v2/events.js +3 -0
- package/dist/v2/session-hooks.js +38 -5
- package/dist/workflow-stack.d.ts +53 -0
- package/dist/workflow-stack.js +196 -0
- package/docs/assets/readme/badge-version.svg +1 -1
- package/docs/assets/skills/lit-schematic.webp +0 -0
- package/docs/reference-Ko-KR.md +48 -3
- package/docs/reference.md +54 -3
- package/package.json +1 -1
- package/skills/frontend-ui-ux/SKILL.md +3 -2
- package/skills/frontend-ui-ux/kit/components.css +414 -0
- package/skills/frontend-ui-ux/kit/fonts.json +22 -0
- package/skills/frontend-ui-ux/kit/layouts/landing.html +164 -0
- package/skills/frontend-ui-ux/kit/layouts/settings.html +114 -0
- package/skills/frontend-ui-ux/kit/layouts/workspace.html +115 -0
- package/skills/frontend-ui-ux/kit/styles/computational-brutalism.json +227 -0
- package/skills/frontend-ui-ux/kit/styles/field-notes.json +205 -0
- package/skills/frontend-ui-ux/kit/styles/graphite.json +200 -0
- package/skills/frontend-ui-ux/kit/styles/meadow.json +199 -0
- package/skills/frontend-ui-ux/kit/styles/neo-brutalism.json +222 -0
- package/skills/frontend-ui-ux/kit/ui.js +226 -0
- package/skills/frontend-ui-ux/references/brand-and-imagery.md +2 -2
- package/skills/frontend-ui-ux/references/complete-contract.md +2 -1
- package/skills/frontend-ui-ux/references/craft-floor.md +6 -2
- package/skills/frontend-ui-ux/references/default-editorial-pixel.json +3 -0
- package/skills/frontend-ui-ux/references/house-styles.md +236 -0
- package/skills/frontend-ui-ux/references/motion-guide.md +2 -2
- package/skills/frontend-ui-ux/references/production.md +3 -1
- package/skills/frontend-ui-ux/references/slop-register.md +4 -4
- package/skills/frontend-ui-ux/scripts/design-lock.mjs +400 -0
- package/skills/frontend-ui-ux/scripts/pixel-art.mjs +60 -0
- package/skills/frontend-ui-ux/scripts/probe-lock.mjs +235 -0
- package/skills/frontend-ui-ux/scripts/probe-page.mjs +34 -12
- package/skills/frontend-ui-ux/scripts/probe-static.mjs +16 -3
- package/skills/frontend-ui-ux/scripts/probe-thresholds.json +8 -2
- package/skills/frontend-ui-ux/scripts/probe.mjs +35 -7
- package/skills/lit-adhd/SKILL.md +209 -0
- package/skills/lit-adhd/references/brief-format.md +46 -0
- package/skills/lit-adhd/references/card-examples.md +103 -0
- package/skills/lit-adhd/references/status-taxonomy.md +34 -0
- package/skills/lit-adhd/scripts/rewind.mjs +933 -0
- package/skills/lit-diagram-drawer/SKILL.md +4 -3
- package/skills/lit-diagram-drawer/references/style-guide.md +20 -11
- package/skills/lit-diagram-drawer/references/type-architecture.md +3 -3
- package/skills/lit-diagram-drawer/references/type-dependency.md +1 -1
- package/skills/lit-diagram-drawer/references/type-tree.md +3 -3
- package/skills/lit-diagram-drawer/references/type-wardley.md +1 -1
- package/skills/lit-diagram-drawer/references/verifier-guide.md +1 -0
- package/skills/lit-diagram-drawer/scripts/craft-thresholds.json +1 -2
- package/skills/lit-diagram-drawer/scripts/visual-quality.mjs +1 -2
- package/skills/lit-docx/SKILL.md +2 -1
- package/skills/lit-handoff/SKILL.md +2 -0
- package/skills/lit-hijack/SKILL.md +422 -0
- package/skills/lit-hijack/references/capture-and-provenance.md +87 -0
- package/skills/lit-hijack/references/clean-room-build.md +111 -0
- package/skills/lit-hijack/references/distil-and-licence.md +100 -0
- package/skills/lit-hijack/references/gap-and-port-design.md +126 -0
- package/skills/lit-hijack/references/parity-and-report.md +110 -0
- package/skills/lit-hijack/scripts/hijack.mjs +993 -0
- package/skills/lit-plan/SKILL.md +8 -0
- package/skills/lit-pptx/SKILL.md +27 -11
- package/skills/lit-pptx/fonts/jetbrains-mono/JetBrainsMono-Bold.ttf +0 -0
- package/skills/lit-pptx/fonts/jetbrains-mono/JetBrainsMono-Regular.ttf +0 -0
- package/skills/lit-pptx/fonts/jetbrains-mono/OFL.txt +93 -0
- package/skills/lit-pptx/fonts/jetbrains-mono/SOURCE.md +17 -0
- package/skills/lit-pptx/references/density-and-fill.md +9 -3
- package/skills/lit-pptx/references/direction-step.md +21 -6
- package/skills/lit-pptx/references/examples/04-lecture-chalk-ko.md +3 -6
- package/skills/lit-pptx/references/examples/05-research-talk-paper-en.md +1 -5
- package/skills/lit-pptx/references/examples/08-reliability-keynote-night-en.md +0 -4
- package/skills/lit-pptx/references/examples/09-status-update-ledger-en.md +2 -2
- package/skills/lit-pptx/references/examples/11-forecast-review-night-ko.md +4 -7
- package/skills/lit-pptx/references/examples/13-engineering-review-computational-brutalism-ko.md +173 -0
- package/skills/lit-pptx/references/examples/14-launch-pitch-neo-brutalism-ko.md +154 -0
- package/skills/lit-pptx/references/examples/15-design-lecture-bauhaus-ko.md +139 -0
- package/skills/lit-pptx/references/examples/16-community-programme-riso-ko.md +158 -0
- package/skills/lit-pptx/references/examples/17-public-data-briefing-newsroom-ko.md +179 -0
- package/skills/lit-pptx/references/layout-families.md +65 -47
- package/skills/lit-pptx/references/title-treatments.md +83 -134
- package/skills/lit-pptx/references/tonalities/atlas.md +3 -3
- package/skills/lit-pptx/references/tonalities/bauhaus.md +140 -0
- package/skills/lit-pptx/references/tonalities/chalk.md +7 -6
- package/skills/lit-pptx/references/tonalities/computational-brutalism.md +150 -0
- package/skills/lit-pptx/references/tonalities/gazette.md +1 -1
- package/skills/lit-pptx/references/tonalities/ledger.md +1 -1
- package/skills/lit-pptx/references/tonalities/neo-brutalism.md +161 -0
- package/skills/lit-pptx/references/tonalities/newsroom.md +144 -0
- package/skills/lit-pptx/references/tonalities/night.md +1 -1
- package/skills/lit-pptx/references/tonalities/paper.md +2 -2
- package/skills/lit-pptx/references/tonalities/riso.md +137 -0
- package/skills/lit-pptx/references/tonalities/signal.md +3 -3
- package/skills/lit-pptx/references/tonalities/studio.md +7 -6
- package/skills/lit-pptx/run.mjs +2 -1
- package/skills/lit-pptx/scripts/compile-deck.js +1 -1
- package/skills/lit-pptx/scripts/craft-thresholds.json +4 -8
- package/skills/lit-pptx/scripts/craft_extras.py +56 -3
- package/skills/lit-pptx/scripts/deck_output.py +75 -90
- package/skills/lit-pptx/scripts/embed_fonts.py +13 -1
- package/skills/lit-pptx/scripts/layout_inventory.py +12 -5
- package/skills/lit-pptx/scripts/lib/grid-resolver.js +101 -110
- package/skills/lit-pptx/scripts/lib/layout-resolver.js +9 -15
- package/skills/lit-pptx/scripts/lib/render-pack.js +373 -566
- package/skills/lit-pptx/scripts/lib/slide-grid.js +104 -0
- package/skills/lit-pptx/scripts/lib/template-registry.js +57 -6
- package/skills/lit-pptx/scripts/qa_deck.py +10 -11
- package/skills/lit-pptx/scripts/render_pages.py +118 -0
- package/skills/lit-pptx/templates/tonalities/atlas/pack.yaml +1 -1
- package/skills/lit-pptx/templates/tonalities/bauhaus/pack.yaml +98 -0
- package/skills/lit-pptx/templates/tonalities/chalk/pack.yaml +1 -1
- package/skills/lit-pptx/templates/tonalities/computational-brutalism/pack.yaml +99 -0
- package/skills/lit-pptx/templates/tonalities/gazette/pack.yaml +1 -1
- package/skills/lit-pptx/templates/tonalities/ledger/pack.yaml +1 -1
- package/skills/lit-pptx/templates/tonalities/neo-brutalism/pack.yaml +107 -0
- package/skills/lit-pptx/templates/tonalities/newsroom/pack.yaml +99 -0
- package/skills/lit-pptx/templates/tonalities/night/pack.yaml +1 -1
- package/skills/lit-pptx/templates/tonalities/paper/pack.yaml +1 -1
- package/skills/lit-pptx/templates/tonalities/riso/pack.yaml +99 -0
- package/skills/lit-pptx/templates/tonalities/signal/pack.yaml +2 -2
- package/skills/lit-pptx/templates/tonalities/studio/pack.yaml +1 -1
- package/skills/lit-recap/SKILL.md +4 -0
- package/skills/lit-schematic/SKILL.md +118 -0
- package/skills/lit-schematic/examples/iso-heat-exchanger/build.mjs +38 -0
- package/skills/lit-schematic/examples/iso-heat-exchanger/scene.mjs +133 -0
- package/skills/lit-schematic/examples/journal-adsorption-rig/build.mjs +87 -0
- package/skills/lit-schematic/examples/pid-dosing-skid/build.mjs +85 -0
- package/skills/lit-schematic/references/cutaway-outputs.md +70 -0
- package/skills/lit-schematic/references/isometric-craft.md +101 -0
- package/skills/lit-schematic/references/journal-figures.md +72 -0
- package/skills/lit-schematic/references/kit-api.md +134 -0
- package/skills/lit-schematic/references/pfd-and-layout.md +53 -0
- package/skills/lit-schematic/references/pid-drafting.md +103 -0
- package/skills/lit-schematic/references/pid-symbols.md +163 -0
- package/skills/lit-schematic/references/verification.md +100 -0
- package/skills/lit-schematic/scripts/doctor.mjs +57 -0
- package/skills/lit-schematic/scripts/lib/figure.mjs +81 -0
- package/skills/lit-schematic/scripts/lib/fonts.mjs +25 -0
- package/skills/lit-schematic/scripts/lib/geom.mjs +113 -0
- package/skills/lit-schematic/scripts/lib/interactive.mjs +292 -0
- package/skills/lit-schematic/scripts/lib/isa.mjs +115 -0
- package/skills/lit-schematic/scripts/lib/iso.mjs +719 -0
- package/skills/lit-schematic/scripts/lib/legend-sheet.mjs +162 -0
- package/skills/lit-schematic/scripts/lib/pid.mjs +937 -0
- package/skills/lit-schematic/scripts/lib/png.mjs +132 -0
- package/skills/lit-schematic/scripts/lib/qa-core.mjs +658 -0
- package/skills/lit-schematic/scripts/lib/route.mjs +218 -0
- package/skills/lit-schematic/scripts/lib/sheet.mjs +890 -0
- package/skills/lit-schematic/scripts/lib/svg.mjs +82 -0
- package/skills/lit-schematic/scripts/lib/theme.mjs +115 -0
- package/skills/lit-schematic/scripts/motion.mjs +129 -0
- package/skills/lit-schematic/scripts/qa.mjs +92 -0
- package/skills/lit-schematic/scripts/render.mjs +233 -0
- package/skills/lit-schematic/scripts/scaffold.mjs +60 -0
- package/skills/lit-scientific-visualization/SKILL.md +27 -4
- package/skills/lit-typographic-motion/SKILL.md +19 -17
- package/skills/lit-typographic-motion/THIRD_PARTY_NOTICES +9 -0
- package/skills/lit-typographic-motion/engine/accents.mjs +6 -0
- package/skills/lit-typographic-motion/engine/assets.mjs +282 -0
- package/skills/lit-typographic-motion/engine/blender/runner.py +228 -0
- package/skills/lit-typographic-motion/engine/blender.mjs +126 -0
- package/skills/lit-typographic-motion/engine/board.mjs +138 -0
- package/skills/lit-typographic-motion/engine/cover/assets.mjs +11 -8
- package/skills/lit-typographic-motion/engine/cover/capture.mjs +6 -6
- package/skills/lit-typographic-motion/engine/cover/render.mjs +20 -7
- package/skills/lit-typographic-motion/engine/cover/treatment.mjs +30 -3
- package/skills/lit-typographic-motion/engine/fill.mjs +54 -0
- package/skills/lit-typographic-motion/engine/gallery.mjs +118 -0
- package/skills/lit-typographic-motion/engine/house.mjs +42 -0
- package/skills/lit-typographic-motion/engine/look.mjs +65 -8
- package/skills/lit-typographic-motion/engine/loudness.mjs +101 -0
- package/skills/lit-typographic-motion/engine/scaffold.mjs +219 -0
- package/skills/lit-typographic-motion/engine/score.mjs +594 -0
- package/skills/lit-typographic-motion/engine/sound.mjs +9 -57
- package/skills/lit-typographic-motion/engine/stage/capture.mjs +23 -9
- package/skills/lit-typographic-motion/engine/stage/clock.js +8 -2
- package/skills/lit-typographic-motion/engine/stage/cover-init.js +12 -1
- package/skills/lit-typographic-motion/engine/stage/frame-worker.mjs +15 -7
- package/skills/lit-typographic-motion/engine/stage/gate.mjs +48 -4
- package/skills/lit-typographic-motion/engine/stage/qa-page.js +16 -5
- package/skills/lit-typographic-motion/engine/stage/qa.mjs +148 -7
- package/skills/lit-typographic-motion/engine/stage/render.mjs +69 -7
- package/skills/lit-typographic-motion/engine/stage/scan.mjs +20 -1
- package/skills/lit-typographic-motion/engine/stage/stage-kit.js +85 -4
- package/skills/lit-typographic-motion/engine/stills.mjs +1 -1
- package/skills/lit-typographic-motion/engine/styles.mjs +221 -0
- package/skills/lit-typographic-motion/engine/text.mjs +1 -1
- package/skills/lit-typographic-motion/engine/treatment.mjs +190 -6
- package/skills/lit-typographic-motion/engine/vendor/three/LICENSE +21 -0
- package/skills/lit-typographic-motion/engine/vendor/three/addons/environments/RoomEnvironment.js +144 -0
- package/skills/lit-typographic-motion/engine/vendor/three/addons/geometries/RoundedBoxGeometry.js +155 -0
- package/skills/lit-typographic-motion/engine/vendor/three/three.module.js +54571 -0
- package/skills/lit-typographic-motion/gate.mjs +18 -2
- package/skills/lit-typographic-motion/probe.mjs +13 -1
- package/skills/lit-typographic-motion/recipes/hero-3d/expected.json +64 -0
- package/skills/lit-typographic-motion/recipes/hero-3d/index.html +132 -0
- package/skills/lit-typographic-motion/recipes/orbit-loop/expected.json +2 -0
- package/skills/lit-typographic-motion/recipes/painted-light/expected.json +2 -0
- package/skills/lit-typographic-motion/recipes/weight-tide/expected.json +2 -0
- package/skills/lit-typographic-motion/references/cover.md +56 -13
- package/skills/lit-typographic-motion/references/craft-loop.md +20 -7
- package/skills/lit-typographic-motion/references/depth.md +112 -0
- package/skills/lit-typographic-motion/references/runtime.md +21 -6
- package/skills/lit-typographic-motion/references/sound.md +76 -0
- package/skills/lit-typographic-motion/references/stage.md +50 -7
- package/skills/lit-typographic-motion/references/studio.md +162 -0
- package/skills/lit-typographic-motion/references/style-bibles.md +18 -0
- package/skills/lit-typographic-motion/references/treatment.md +108 -9
- package/skills/lit-typographic-motion/render.mjs +60 -3
- package/skills/lit-typographic-motion/styles/paper.json +185 -0
- package/skills/lit-typographic-motion/styles/swiss-signal.json +188 -0
- package/skills/lit-typographic-motion/styles/terminalcore.json +182 -0
- package/skills/lit-typographic-motion/styles/tidal.json +187 -0
- package/skills/litresearch/SKILL.md +2 -0
- package/skills/managed-skill-manifest.json +517 -88
- package/skills/readme-studio/SKILL.md +1 -1
- package/skills/review-work/SKILL.md +2 -0
- package/skills/start-work/SKILL.md +8 -0
- package/skills/workflow-loop/SKILL.md +4 -0
- package/tools/check-pack-payload.mjs +5 -2
- package/tools/payload-substance-parity.json +4 -3
- package/tools/qa-cover-recipes.mjs +4 -3
- package/tools/version-manifests.json +2 -2
package/dist/durable-plan.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/** The plan reaches a folder outside the project that no `Scope roots:` line names; the message says what to add. */
|
|
2
|
+
export declare class PlanScopeError extends Error {
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
1
5
|
export type ApprovedPlanRequest = {
|
|
2
6
|
readonly schemaVersion: 1;
|
|
3
7
|
readonly slug: string;
|
|
@@ -20,4 +24,4 @@ export declare function parsePlanSaveArgument(argumentsText: string): ApprovedPl
|
|
|
20
24
|
export declare function persistApprovedPlan(projectRoot: string, request: ApprovedPlanRequest): Promise<DurablePlan>;
|
|
21
25
|
export declare function resolveLatestDurablePlan(projectRoot: string): Promise<DurablePlan | undefined>;
|
|
22
26
|
export declare function formatResolvedPlanNotice(plan: DurablePlan): string;
|
|
23
|
-
export declare function formatSavedPlanNotice(plan: DurablePlan, replayed: boolean): string;
|
|
27
|
+
export declare function formatSavedPlanNotice(plan: DurablePlan, replayed: boolean, goArmed?: boolean): string;
|
package/dist/durable-plan.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { describeUncoveredScopePaths, uncoveredScopePaths } from "./plan-scope-roots.js";
|
|
5
|
+
/** The plan reaches a folder outside the project that no `Scope roots:` line names; the message says what to add. */
|
|
6
|
+
export class PlanScopeError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "PlanScopeError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
4
12
|
const PLAN_DIRECTORY = path.join(".litopencode", "plans");
|
|
5
13
|
const MAX_PLAN_BYTES = 256 * 1024;
|
|
6
14
|
const MAX_ARGUMENT_BYTES = 512 * 1024;
|
|
@@ -261,6 +269,9 @@ export async function persistApprovedPlan(projectRoot, request) {
|
|
|
261
269
|
const validationError = validateRequest(request);
|
|
262
270
|
if (validationError !== "")
|
|
263
271
|
throw new Error(validationError);
|
|
272
|
+
const uncovered = uncoveredScopePaths(request.markdown, projectRoot);
|
|
273
|
+
if (uncovered.length > 0)
|
|
274
|
+
throw new PlanScopeError(describeUncoveredScopePaths(uncovered));
|
|
264
275
|
const body = normalizeMarkdown(request.markdown);
|
|
265
276
|
const directory = path.join(projectRoot, PLAN_DIRECTORY);
|
|
266
277
|
const name = `${request.slug}.md`;
|
|
@@ -343,7 +354,8 @@ export async function resolveLatestDurablePlan(projectRoot) {
|
|
|
343
354
|
export function formatResolvedPlanNotice(plan) {
|
|
344
355
|
return `Durable plan: ${plan.relativePath}. Discovery only. This does not grant start-work authority.\n\n<durable-plan>\n${plan.text}</durable-plan>`;
|
|
345
356
|
}
|
|
346
|
-
export function formatSavedPlanNotice(plan, replayed) {
|
|
357
|
+
export function formatSavedPlanNotice(plan, replayed, goArmed = false) {
|
|
347
358
|
const verb = replayed ? "Durable plan already persisted" : "Saved durable plan";
|
|
348
|
-
|
|
359
|
+
const go = goArmed ? " To start it, type `go` within 30 minutes in this session." : "";
|
|
360
|
+
return `${verb}: ${plan.relativePath}. Discovery only. This does not grant start-work authority.${go}`;
|
|
349
361
|
}
|
package/dist/features.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type LitOpenCodeBindingKind = "agent" | "cli" | "command" | "config" | "hook" | "tool";
|
|
2
|
-
export type LitOpenCodeFeatureId = "planning-start-work-loop" | "lit-litwork-activation" | "start-work" | "review-work" | "litresearch" | "durable-ledger" | "bounded-authority-lifecycle" | "agent-roster" | "lit-plan" | "reference-benchmark-claims" | "native-goal-verdict" | "doctor-install" | "search-workflow-ideas" | "lit-fetch" | "guardrails" | "lit-init" | "lit-crucible" | "lit-brainstorm" | "refactor" | "lit-burnoff" | "lit-burnoff-file" | "comment-checker" | "lit-code" | "debugging" | "lit-commit" | "lsp" | "lsp-setup" | "rules" | "deep-interview" | "structural-search" | "browser-drive" | "lit-humanizer" | "lit-recap" | "lit-comprehend" | "lit-handoff" | "lit-scientific-visualization" | "lit-diagram-drawer" | "lit-pptx" | "lit-typographic-motion" | "lit-docx" | "readme-studio" | "frontend-ui-ux" | "visual-qa" | "autoresearch" | "autoconference" | "wikify";
|
|
2
|
+
export type LitOpenCodeFeatureId = "planning-start-work-loop" | "lit-litwork-activation" | "start-work" | "review-work" | "litresearch" | "durable-ledger" | "bounded-authority-lifecycle" | "agent-roster" | "lit-plan" | "reference-benchmark-claims" | "native-goal-verdict" | "doctor-install" | "search-workflow-ideas" | "lit-fetch" | "guardrails" | "lit-init" | "lit-crucible" | "lit-brainstorm" | "lit-hijack" | "lit-adhd" | "workflow-stack" | "refactor" | "lit-burnoff" | "lit-burnoff-file" | "comment-checker" | "lit-code" | "debugging" | "lit-commit" | "lsp" | "lsp-setup" | "rules" | "deep-interview" | "structural-search" | "browser-drive" | "lit-humanizer" | "lit-recap" | "lit-comprehend" | "lit-handoff" | "lit-scientific-visualization" | "lit-diagram-drawer" | "lit-schematic" | "lit-pptx" | "lit-typographic-motion" | "lit-docx" | "readme-studio" | "frontend-ui-ux" | "visual-qa" | "autoresearch" | "autoconference" | "wikify";
|
|
3
3
|
export type LitOpenCodeFeatureBinding = {
|
|
4
4
|
readonly kind: LitOpenCodeBindingKind;
|
|
5
5
|
readonly id: string;
|
|
@@ -441,6 +441,64 @@ export declare const litOpenCodeFeatures: readonly ({
|
|
|
441
441
|
description: string;
|
|
442
442
|
})[];
|
|
443
443
|
verification: string[];
|
|
444
|
+
} | {
|
|
445
|
+
id: "lit-hijack";
|
|
446
|
+
title: string;
|
|
447
|
+
summary: string;
|
|
448
|
+
bindings: ({
|
|
449
|
+
kind: "config";
|
|
450
|
+
id: string;
|
|
451
|
+
surface: string;
|
|
452
|
+
description: string;
|
|
453
|
+
} | {
|
|
454
|
+
kind: "command";
|
|
455
|
+
id: string;
|
|
456
|
+
surface: string;
|
|
457
|
+
description: string;
|
|
458
|
+
} | {
|
|
459
|
+
kind: "agent";
|
|
460
|
+
id: string;
|
|
461
|
+
surface: string;
|
|
462
|
+
description: string;
|
|
463
|
+
})[];
|
|
464
|
+
verification: string[];
|
|
465
|
+
} | {
|
|
466
|
+
id: "lit-adhd";
|
|
467
|
+
title: string;
|
|
468
|
+
summary: string;
|
|
469
|
+
bindings: ({
|
|
470
|
+
kind: "config";
|
|
471
|
+
id: string;
|
|
472
|
+
surface: string;
|
|
473
|
+
description: string;
|
|
474
|
+
} | {
|
|
475
|
+
kind: "command";
|
|
476
|
+
id: string;
|
|
477
|
+
surface: string;
|
|
478
|
+
description: string;
|
|
479
|
+
} | {
|
|
480
|
+
kind: "hook";
|
|
481
|
+
id: string;
|
|
482
|
+
surface: string;
|
|
483
|
+
description: string;
|
|
484
|
+
})[];
|
|
485
|
+
verification: string[];
|
|
486
|
+
} | {
|
|
487
|
+
id: "workflow-stack";
|
|
488
|
+
title: string;
|
|
489
|
+
summary: string;
|
|
490
|
+
bindings: ({
|
|
491
|
+
kind: "config";
|
|
492
|
+
id: string;
|
|
493
|
+
surface: string;
|
|
494
|
+
description: string;
|
|
495
|
+
} | {
|
|
496
|
+
kind: "hook";
|
|
497
|
+
id: string;
|
|
498
|
+
surface: string;
|
|
499
|
+
description: string;
|
|
500
|
+
})[];
|
|
501
|
+
verification: string[];
|
|
444
502
|
} | {
|
|
445
503
|
id: "refactor";
|
|
446
504
|
title: string;
|
|
@@ -845,6 +903,27 @@ export declare const litOpenCodeFeatures: readonly ({
|
|
|
845
903
|
description: string;
|
|
846
904
|
})[];
|
|
847
905
|
verification: string[];
|
|
906
|
+
} | {
|
|
907
|
+
id: "lit-schematic";
|
|
908
|
+
title: string;
|
|
909
|
+
summary: string;
|
|
910
|
+
bindings: ({
|
|
911
|
+
kind: "config";
|
|
912
|
+
id: string;
|
|
913
|
+
surface: string;
|
|
914
|
+
description: string;
|
|
915
|
+
} | {
|
|
916
|
+
kind: "hook";
|
|
917
|
+
id: string;
|
|
918
|
+
surface: string;
|
|
919
|
+
description: string;
|
|
920
|
+
} | {
|
|
921
|
+
kind: "cli";
|
|
922
|
+
id: string;
|
|
923
|
+
surface: string;
|
|
924
|
+
description: string;
|
|
925
|
+
})[];
|
|
926
|
+
verification: string[];
|
|
848
927
|
} | {
|
|
849
928
|
id: "lit-typographic-motion";
|
|
850
929
|
title: string;
|
package/dist/features.js
CHANGED
|
@@ -532,6 +532,78 @@ export const litOpenCodeFeatures = Object.freeze([
|
|
|
532
532
|
],
|
|
533
533
|
verification: ["node --test test/lit-brainstorm.test.mjs", "node --test test/runtime-skills.test.mjs", "node --test test/docs.test.mjs"]
|
|
534
534
|
},
|
|
535
|
+
{
|
|
536
|
+
id: "lit-hijack",
|
|
537
|
+
title: "Lit Hijack",
|
|
538
|
+
summary: "Ports the mechanism in someone else's published work into the user's own skill or system through capture, licence gate, gap, source-free spec, separate build, parity proof and report, with a bundled script deciding when each phase is done.",
|
|
539
|
+
bindings: [
|
|
540
|
+
{
|
|
541
|
+
kind: "config",
|
|
542
|
+
id: "skills/lit-hijack/SKILL.md",
|
|
543
|
+
surface: "LitOpenCode native-installed managed skill",
|
|
544
|
+
description: "Ships the phase procedure with five references and the zero-dependency hijack.mjs helper, installed together so the script the skill names can run."
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
kind: "command",
|
|
548
|
+
id: "lit-hijack",
|
|
549
|
+
surface: "OpenCode command /lit-hijack",
|
|
550
|
+
description: "Makes Lit Hijack directly invocable; chat routes lit hijack, lit hijacking, lit 하이재킹 and lit 하이잭 reach the same surface."
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
kind: "agent",
|
|
554
|
+
id: "isolated implementer and optional lanes",
|
|
555
|
+
surface: "OpenCode task delegation",
|
|
556
|
+
description: "Builds from the brief alone in a separate git worktree through a write-capable task lane, with optional read-only capture, distil and verifier lanes at depth one; the lit-plan agent stays planning-only."
|
|
557
|
+
}
|
|
558
|
+
],
|
|
559
|
+
verification: ["node --test test/lit-hijack.test.mjs", "node --test test/runtime-skills.test.mjs", "node --test test/docs.test.mjs"]
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
id: "lit-adhd",
|
|
563
|
+
title: "Lit Adhd",
|
|
564
|
+
summary: "Briefs the earlier sessions of this worktree family from a read-only collector (status, goal, real progress or known facts, done, next, roadmap), recommends one next step, and follows it on go; typed start-work, lit approve and lit deny drive the bounded run without pasted JSON.",
|
|
565
|
+
bindings: [
|
|
566
|
+
{
|
|
567
|
+
kind: "config",
|
|
568
|
+
id: "skills/lit-adhd/SKILL.md",
|
|
569
|
+
surface: "LitOpenCode native-installed managed skill",
|
|
570
|
+
description: "Ships the skill with three references and the zero-dependency rewind.mjs collector, installed together so the script the skill names can run."
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
kind: "command",
|
|
574
|
+
id: "lit-adhd",
|
|
575
|
+
surface: "OpenCode commands /lit-adhd and /lit-rewind",
|
|
576
|
+
description: "Makes the brief directly invocable; chat routes lit adhd and lit rewind reach the same surface, and a live go follows the armed step."
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
kind: "hook",
|
|
580
|
+
id: "chat.message typed prompts",
|
|
581
|
+
surface: "OpenCode chat.message and command.execute.before hooks, and the OpenCode 2 prompt hook",
|
|
582
|
+
description: "Routes go, lit approve, lit deny and start-work [plan] from the user's own root-session prompt into the existing re-entry and bounded-authority lifecycle."
|
|
583
|
+
}
|
|
584
|
+
],
|
|
585
|
+
verification: ["node --test test/lit-adhd.test.mjs", "node --test test/adhd-go.test.mjs", "node --test test/start-work-typed.test.mjs", "node --test test/runtime-skills.test.mjs", "node --test test/docs.test.mjs"]
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
id: "workflow-stack",
|
|
589
|
+
title: "Workflow Stack",
|
|
590
|
+
summary: "Pauses a running long discipline when another lit command interrupts it, keeping its stage and real count in a per-session record, and returns to it on lit continue; the mission band and the lit-adhd collector read the same record.",
|
|
591
|
+
bindings: [
|
|
592
|
+
{
|
|
593
|
+
kind: "config",
|
|
594
|
+
id: ".litopencode/workflow-stack/<session>.json",
|
|
595
|
+
surface: "LitOpenCode runtime state",
|
|
596
|
+
description: "One small guarded file per session: link-refusing, size-capped, atomically replaced, with a stale spine never resumed."
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
kind: "hook",
|
|
600
|
+
id: "chat.message activation memory",
|
|
601
|
+
surface: "OpenCode chat.message hook and the OpenCode 2 prompt hook",
|
|
602
|
+
description: "Pushes an interjected discipline over the running one, appends the paused-at line, and resumes the paused discipline on lit continue or go."
|
|
603
|
+
}
|
|
604
|
+
],
|
|
605
|
+
verification: ["node --test test/workflow-stack.test.mjs", "node --test test/workflow-interleave.test.mjs", "node --test test/runtime-skills.test.mjs"]
|
|
606
|
+
},
|
|
535
607
|
{
|
|
536
608
|
id: "refactor",
|
|
537
609
|
title: "Refactor",
|
|
@@ -1145,6 +1217,38 @@ export const litOpenCodeFeatures = Object.freeze([
|
|
|
1145
1217
|
],
|
|
1146
1218
|
verification: ["node --test test/lit-diagram-drawer.test.mjs", "npm run check:managed-skill-manifest", "npm run check:pack-payload"]
|
|
1147
1219
|
},
|
|
1220
|
+
{
|
|
1221
|
+
id: "lit-schematic",
|
|
1222
|
+
title: "Lit Schematic",
|
|
1223
|
+
summary: "Installs an OpenCode native skill with a plain-Node drawing kit, symbol library, QA gate, renderer and worked examples for P&IDs, apparatus figures and isometric cutaways, and routes bounded lit drawing requests to it.",
|
|
1224
|
+
bindings: [
|
|
1225
|
+
{
|
|
1226
|
+
kind: "config",
|
|
1227
|
+
id: "skills/lit-schematic/SKILL.md",
|
|
1228
|
+
surface: "OpenCode native skill picker",
|
|
1229
|
+
description: "Selects the physical-schematic workflow and its complete managed skill tree; no dedicated slash command or bare-id chat route is registered."
|
|
1230
|
+
},
|
|
1231
|
+
{
|
|
1232
|
+
kind: "hook",
|
|
1233
|
+
id: "lit-task schematic drawing intent",
|
|
1234
|
+
surface: "OpenCode chat.message activation",
|
|
1235
|
+
description: "Directs bounded lit P&ID, PFD, apparatus and cutaway drawing requests to load the native skill before drawing, ahead of the diagram, film and Office hand-offs; questions, reviews, charts and reports stay inert."
|
|
1236
|
+
},
|
|
1237
|
+
{
|
|
1238
|
+
kind: "cli",
|
|
1239
|
+
id: "litopencode install",
|
|
1240
|
+
surface: "LitOpenCode managed native skill installer",
|
|
1241
|
+
description: "Installs every hash-pinned reference, script, kit module and example."
|
|
1242
|
+
},
|
|
1243
|
+
{
|
|
1244
|
+
kind: "cli",
|
|
1245
|
+
id: "litopencode doctor",
|
|
1246
|
+
surface: "LitOpenCode managed native skill doctor",
|
|
1247
|
+
description: "Verifies the exact installed file closure; the skill's own doctor script reports Chrome, fonts and encoders without installing tools."
|
|
1248
|
+
}
|
|
1249
|
+
],
|
|
1250
|
+
verification: ["node --test test/lit-schematic.test.mjs test/lit-schematic-symbols.test.mjs test/lit-schematic-outputs.test.mjs", "npm run check:managed-skill-manifest", "npm run check:pack-payload"]
|
|
1251
|
+
},
|
|
1148
1252
|
{
|
|
1149
1253
|
id: "lit-typographic-motion",
|
|
1150
1254
|
title: "Film director",
|
|
@@ -1154,7 +1258,7 @@ export const litOpenCodeFeatures = Object.freeze([
|
|
|
1154
1258
|
{ kind: "hook", id: "lit-task motion-video intent", surface: "OpenCode chat.message activation", description: "Routes bounded film requests before slide and interface guidance with a neutral film context." },
|
|
1155
1259
|
{ kind: "hook", id: "tool.execute.after", surface: "OpenCode tool.execute.after hook", description: "Records each read of a film's or a cover's stills so the done check can confirm the frames were viewed." },
|
|
1156
1260
|
{ kind: "cli", id: "litopencode motion-runtime install|status", surface: "LitOpenCode runtime", description: "Pre-warms pinned dependencies and fonts outside the render session." },
|
|
1157
|
-
{ kind: "cli", id: "litopencode doctor", surface: "LitOpenCode doctor", description: "Reports Chrome, ffmpeg, WebGL2 tier, software warning, pre-warm status
|
|
1261
|
+
{ kind: "cli", id: "litopencode doctor", surface: "LitOpenCode doctor", description: "Reports Chrome, ffmpeg, WebGL2 tier, software warning, pre-warm status, the cover encoder and, as information only, whether Blender is installed." }
|
|
1158
1262
|
],
|
|
1159
1263
|
verification: ["node --test test/lit-typographic-motion.test.mjs", "node --test test/motion-cover.test.mjs", "npm run check:managed-skill-manifest", "npm run check:pack-payload"]
|
|
1160
1264
|
},
|
package/dist/hooks.js
CHANGED
|
@@ -3,6 +3,7 @@ import { dynamicRulesForPaths } from "./rules/hooks.js";
|
|
|
3
3
|
import { applyLitOpenCodePostEditHook, applyLitOpenCodeToolAfterHook, applyLitOpenCodeToolBeforeHook, applyTaskRecursionGuard, mutatedFilePaths } from "./tool-guards.js";
|
|
4
4
|
import { captureKnowledgeEvent } from "./knowledge.js";
|
|
5
5
|
import { recordMotionImageRead } from "./motion-image-reads.js";
|
|
6
|
+
import { markLiveness } from "./session-liveness.js";
|
|
6
7
|
export function createToolExecuteBeforeHook(options = {}) {
|
|
7
8
|
return async (input, output) => {
|
|
8
9
|
await applyTaskRecursionGuard(input, options.getSession);
|
|
@@ -13,6 +14,8 @@ export function createToolExecuteBeforeHook(options = {}) {
|
|
|
13
14
|
}
|
|
14
15
|
export function createToolExecuteAfterHook(options = {}) {
|
|
15
16
|
return async (input, output) => {
|
|
17
|
+
if (options.projectRoot !== undefined)
|
|
18
|
+
await markLiveness(options.projectRoot, input.sessionID, "alive");
|
|
16
19
|
applyLitOpenCodeToolAfterHook(input, output);
|
|
17
20
|
applyLitOpenCodePostEditHook(input, output);
|
|
18
21
|
recordMotionImageRead(input, options.projectRoot);
|
package/dist/ledger.js
CHANGED
|
@@ -407,7 +407,18 @@ async function writeEvidenceLedger(projectRoot, state) {
|
|
|
407
407
|
await removeIfPresent(tempFile);
|
|
408
408
|
throw new LedgerIoError(`Failed to write goals.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
409
409
|
}
|
|
410
|
-
|
|
410
|
+
// The brief is replaced through a temp file and a rename, so a link planted at brief.md is swapped out,
|
|
411
|
+
// never written through.
|
|
412
|
+
goalsTempCounter += 1;
|
|
413
|
+
const briefTemp = path.join(paths.litLoopDir, `${goalsTempPrefix}${process.pid}-${goalsTempCounter}`);
|
|
414
|
+
try {
|
|
415
|
+
await fs.writeFile(briefTemp, renderEvidenceBrief(state), { encoding: "utf8", flag: "wx" });
|
|
416
|
+
await fs.rename(briefTemp, paths.briefFile);
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
await removeIfPresent(briefTemp);
|
|
420
|
+
throw new LedgerIoError(`Failed to write brief.md: ${error instanceof Error ? error.message : String(error)}`);
|
|
421
|
+
}
|
|
411
422
|
return state;
|
|
412
423
|
}
|
|
413
424
|
function evidenceMutationPaths(projectRoot) {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SemanticAuthorityAction } from "./bounded-authority.ts";
|
|
2
|
+
export type ScopeRoot = {
|
|
3
|
+
readonly root: string;
|
|
4
|
+
readonly actions: readonly SemanticAuthorityAction[];
|
|
5
|
+
};
|
|
6
|
+
export type UncoveredScopePath = {
|
|
7
|
+
readonly path: string;
|
|
8
|
+
readonly line: string;
|
|
9
|
+
} | {
|
|
10
|
+
readonly path: string;
|
|
11
|
+
readonly problem: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* `Scope roots:` lines outside code fences, with paths resolved against the project. A line naming a broad
|
|
15
|
+
* folder, or any action other than read, write and execute, grants nothing.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseScopeRoots(planText: string, projectRoot: string): ScopeRoot[];
|
|
18
|
+
/**
|
|
19
|
+
* Each outside folder the plan's todo section reaches that neither the project nor a `Scope roots:` line
|
|
20
|
+
* covers, once per folder: with the exact line to paste, or with a problem when only a broad folder exists.
|
|
21
|
+
*/
|
|
22
|
+
export declare function uncoveredScopePaths(planText: string, projectRoot: string): UncoveredScopePath[];
|
|
23
|
+
export declare function describeUncoveredScopePaths(entries: readonly UncoveredScopePath[]): string;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { realpathSync, statSync } from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const scopeLine = /^Scope roots?:[ \t]*(\S+)[ \t]*\(([^()\r\n]+)\)[ \t]*$/u;
|
|
5
|
+
const semanticActions = new Set(["read", "write", "execute"]);
|
|
6
|
+
// Two or more absolute segments; a lone `/` or a relative path is not a folder the work reaches.
|
|
7
|
+
const absolutePath = /(?<![\w.~/-])\/[\w.@+%,=~-]+(?:\/[\w.@+%,=~-]+)+\/?/gu;
|
|
8
|
+
function linesOutsideFences(text) {
|
|
9
|
+
const kept = [];
|
|
10
|
+
let fence;
|
|
11
|
+
for (const line of text.split(/\r?\n/u)) {
|
|
12
|
+
const marker = /^\s{0,3}(`{3,}|~{3,})/u.exec(line)?.[1];
|
|
13
|
+
if (marker !== undefined && (fence === undefined || marker.startsWith(fence))) {
|
|
14
|
+
fence = fence === undefined ? marker : undefined;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (fence === undefined)
|
|
18
|
+
kept.push(line);
|
|
19
|
+
}
|
|
20
|
+
return kept;
|
|
21
|
+
}
|
|
22
|
+
/** Real path of the deepest existing ancestor, with the missing tail appended unchanged. */
|
|
23
|
+
function realish(target) {
|
|
24
|
+
const missing = [];
|
|
25
|
+
for (let at = path.resolve(target);; at = path.dirname(at)) {
|
|
26
|
+
try {
|
|
27
|
+
return path.join(realpathSync(at), ...missing.reverse());
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
if (path.dirname(at) === at)
|
|
31
|
+
return path.resolve(target);
|
|
32
|
+
missing.push(path.basename(at));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function nearestDirectory(target) {
|
|
37
|
+
for (let at = path.resolve(target);; at = path.dirname(at)) {
|
|
38
|
+
try {
|
|
39
|
+
if (statSync(at).isDirectory())
|
|
40
|
+
return realish(at);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Not created yet; try the parent.
|
|
44
|
+
}
|
|
45
|
+
if (path.dirname(at) === at)
|
|
46
|
+
return at;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** The filesystem root, a top-level folder or the home folder itself is too broad to grant. */
|
|
50
|
+
function tooBroad(directory) {
|
|
51
|
+
const parent = path.dirname(directory);
|
|
52
|
+
return parent === directory || path.dirname(parent) === parent || directory === realish(os.homedir());
|
|
53
|
+
}
|
|
54
|
+
function within(root, candidate) {
|
|
55
|
+
const relative = path.relative(root, candidate);
|
|
56
|
+
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* `Scope roots:` lines outside code fences, with paths resolved against the project. A line naming a broad
|
|
60
|
+
* folder, or any action other than read, write and execute, grants nothing.
|
|
61
|
+
*/
|
|
62
|
+
export function parseScopeRoots(planText, projectRoot) {
|
|
63
|
+
const roots = [];
|
|
64
|
+
for (const line of linesOutsideFences(planText)) {
|
|
65
|
+
const match = scopeLine.exec(line.trim());
|
|
66
|
+
if (match === null)
|
|
67
|
+
continue;
|
|
68
|
+
const actions = match[2].split(",").map((action) => action.trim().toLowerCase());
|
|
69
|
+
if (actions.length === 0 || !actions.every((action) => semanticActions.has(action)))
|
|
70
|
+
continue;
|
|
71
|
+
const root = path.resolve(projectRoot, match[1]);
|
|
72
|
+
if (tooBroad(realish(root)))
|
|
73
|
+
continue;
|
|
74
|
+
roots.push({ root, actions: [...new Set(actions)] });
|
|
75
|
+
}
|
|
76
|
+
return roots;
|
|
77
|
+
}
|
|
78
|
+
/** Absolute paths of a todo line; a code span holding a command (it has a space) is data, not a reach. */
|
|
79
|
+
function pathMentions(line) {
|
|
80
|
+
const spansAsText = line.replace(/`([^`]*)`/gu, (_, span) => (/\s/u.test(span.trim()) ? " " : ` ${span.trim()} `));
|
|
81
|
+
return (spansAsText.match(absolutePath) ?? []).map((mention) => mention.replace(/[.,:;)]+$/u, ""));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Each outside folder the plan's todo section reaches that neither the project nor a `Scope roots:` line
|
|
85
|
+
* covers, once per folder: with the exact line to paste, or with a problem when only a broad folder exists.
|
|
86
|
+
*/
|
|
87
|
+
export function uncoveredScopePaths(planText, projectRoot) {
|
|
88
|
+
const project = realish(projectRoot);
|
|
89
|
+
const covered = [project, ...parseScopeRoots(planText, project).map((scope) => realish(scope.root))];
|
|
90
|
+
const found = new Map();
|
|
91
|
+
let inTodos = false;
|
|
92
|
+
for (const line of linesOutsideFences(planText)) {
|
|
93
|
+
const heading = /^#{1,2}\s+(.+?)\s*$/u.exec(line)?.[1];
|
|
94
|
+
if (heading !== undefined)
|
|
95
|
+
inTodos = /^todos\b/iu.test(heading);
|
|
96
|
+
if (!inTodos)
|
|
97
|
+
continue;
|
|
98
|
+
for (const mention of pathMentions(line)) {
|
|
99
|
+
const real = realish(mention);
|
|
100
|
+
if (covered.some((root) => within(root, real)))
|
|
101
|
+
continue;
|
|
102
|
+
const directory = nearestDirectory(mention);
|
|
103
|
+
if (found.has(directory))
|
|
104
|
+
continue;
|
|
105
|
+
found.set(directory, tooBroad(directory)
|
|
106
|
+
? { path: mention, problem: `${mention} is outside the project; name a narrower existing folder on a Scope roots line.` }
|
|
107
|
+
: { path: mention, line: `Scope roots: ${directory} (read)` });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return [...found.values()];
|
|
111
|
+
}
|
|
112
|
+
export function describeUncoveredScopePaths(entries) {
|
|
113
|
+
return entries.map((entry) => ("line" in entry
|
|
114
|
+
? `${entry.path} is outside the project and no Scope roots line covers it; add this line to the plan: ${entry.line}`
|
|
115
|
+
: entry.problem)).join(" ");
|
|
116
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** The newest stable installed version strictly newer than the loaded one, or undefined. */
|
|
2
|
+
export declare function restartVersion(loaded: unknown, installed: readonly unknown[]): string | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* What is installed now: the package.json version under `packageRoot`, then the target of an automatic
|
|
5
|
+
* update whose receipt says it was installed. Unreadable or malformed sources are left out.
|
|
6
|
+
*/
|
|
7
|
+
export declare function readInstalledVersions(packageRoot: string, homeDir?: string): Promise<string[]>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { readAutoUpdateReceipt } from "./cli/auto-update.js";
|
|
5
|
+
import { compareStableVersions } from "./cli/update-notifier.js";
|
|
6
|
+
// OpenCode keeps running the plugin code it loaded at start, so an update installed meanwhile (by the
|
|
7
|
+
// automatic update at start, or by the CLI from a terminal) waits for the next start. The TUI compares
|
|
8
|
+
// the version it loaded with what is installed now and, when the install is newer, asks for a restart.
|
|
9
|
+
// It never starts anything itself: inside the OpenCode host, `process.execPath` is the host binary.
|
|
10
|
+
/** The newest stable installed version strictly newer than the loaded one, or undefined. */
|
|
11
|
+
export function restartVersion(loaded, installed) {
|
|
12
|
+
let newest;
|
|
13
|
+
for (const candidate of installed) {
|
|
14
|
+
if (compareStableVersions(candidate, loaded) !== 1)
|
|
15
|
+
continue;
|
|
16
|
+
if (newest === undefined || compareStableVersions(candidate, newest) === 1)
|
|
17
|
+
newest = candidate;
|
|
18
|
+
}
|
|
19
|
+
return newest;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* What is installed now: the package.json version under `packageRoot`, then the target of an automatic
|
|
23
|
+
* update whose receipt says it was installed. Unreadable or malformed sources are left out.
|
|
24
|
+
*/
|
|
25
|
+
export async function readInstalledVersions(packageRoot, homeDir = os.homedir()) {
|
|
26
|
+
const versions = [];
|
|
27
|
+
try {
|
|
28
|
+
const parsed = JSON.parse(await fs.readFile(path.join(packageRoot, "package.json"), "utf8"));
|
|
29
|
+
const version = typeof parsed === "object" && parsed !== null ? parsed.version : undefined;
|
|
30
|
+
if (typeof version === "string")
|
|
31
|
+
versions.push(version);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// No readable package.json; the receipt may still say what was installed.
|
|
35
|
+
}
|
|
36
|
+
const receipt = await readAutoUpdateReceipt(homeDir).catch(() => undefined);
|
|
37
|
+
if (receipt !== undefined && receipt.status === "updated" && receipt.targetVersion !== undefined)
|
|
38
|
+
versions.push(receipt.targetVersion);
|
|
39
|
+
return versions;
|
|
40
|
+
}
|
package/dist/secret-shapes.js
CHANGED
|
@@ -25,13 +25,13 @@ const secretShapeAlternatives = [
|
|
|
25
25
|
String.raw `(?<![A-Za-z0-9_])eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+(?![A-Za-z0-9_])`,
|
|
26
26
|
String.raw `\b(?:authorization|proxy-authorization)\s*:\s*\S+\s+\S+`,
|
|
27
27
|
String.raw `\b(?:bearer|basic)\s+[A-Za-z0-9._~+/=-]{8,}(?=$|[^A-Za-z0-9._~+/=-])`,
|
|
28
|
-
String.raw `\b(?:password|passwd|secret|token|api[_-]?key|access[_-]?token)
|
|
29
|
-
String.raw `\b[A-Za-z][A-Za-z0-9]*(?:[_-][A-Za-z0-9]+)*[_-](?:token|secret|key)(?:[_-][A-Za-z0-9]+)
|
|
30
|
-
String.raw `\b_?auth(?:[_-]?token)?\s*[:=]\s*[^\s,;]{8,}`,
|
|
28
|
+
String.raw `\b(?:password|passwd|secret|token|api[_-]?key|access[_-]?token)["']?\s*[:=]\s*[^\s,;]{8,}`,
|
|
29
|
+
String.raw `\b[A-Za-z][A-Za-z0-9]*(?:[_-][A-Za-z0-9]+)*[_-](?:token|secret|key)(?:[_-][A-Za-z0-9]+)*["']?\s*[:=]\s*[^\s,;]{8,}`,
|
|
30
|
+
String.raw `\b_?auth(?:[_-]?token)?["']?\s*[:=]\s*[^\s,;]{8,}`,
|
|
31
31
|
String.raw `(?<![A-Za-z0-9+.-])(?:[A-Za-z][A-Za-z0-9+.-]*:)?\/\/[^/?#\s]+@`
|
|
32
32
|
];
|
|
33
|
-
const shortKeyValueSecretShape = /(?<![A-Za-z0-9_])(?:password|passwd|passphrase|secret|token|api[_-]?key|access[_-]?token|auth[_-]?token|[A-Za-z][A-Za-z0-9]*(?:[_-][A-Za-z0-9]+)*[_-](?:password|passwd|passphrase|secret|token|key)(?:[_-][A-Za-z0-9]+)*)
|
|
34
|
-
const shortUppercaseColonSecretShape = /(?<![A-Za-z0-9_])(?:PASSWORD|PASSWD|PASSPHRASE|SECRET|TOKEN|API[_-]?KEY|ACCESS[_-]?TOKEN|AUTH[_-]?TOKEN|[A-Z][A-Z0-9]*(?:[_-][A-Z0-9]+)*[_-](?:PASSWORD|PASSWD|PASSPHRASE|SECRET|TOKEN|KEY)(?:[_-][A-Z0-9]+)*)
|
|
33
|
+
const shortKeyValueSecretShape = /(?<![A-Za-z0-9_])(?:password|passwd|passphrase|secret|token|api[_-]?key|access[_-]?token|auth[_-]?token|[A-Za-z][A-Za-z0-9]*(?:[_-][A-Za-z0-9]+)*[_-](?:password|passwd|passphrase|secret|token|key)(?:[_-][A-Za-z0-9]+)*)["']?\s*=\s*(?:"[^"\r\n]+"|'[^'\r\n]+'|[^\s,;]+)/iu;
|
|
34
|
+
const shortUppercaseColonSecretShape = /(?<![A-Za-z0-9_])(?:PASSWORD|PASSWD|PASSPHRASE|SECRET|TOKEN|API[_-]?KEY|ACCESS[_-]?TOKEN|AUTH[_-]?TOKEN|[A-Z][A-Z0-9]*(?:[_-][A-Z0-9]+)*[_-](?:PASSWORD|PASSWD|PASSPHRASE|SECRET|TOKEN|KEY)(?:[_-][A-Z0-9]+)*)["']?\s*:\s*(?:"[^"\r\n]+"|'[^'\r\n]+'|[^\s,;]+)/u;
|
|
35
35
|
/** The guarded credential shape. Exported so a consumer can read it, never widen it. */
|
|
36
36
|
export const secretShape = new RegExp(`(?:${secretShapeAlternatives.join("|")})`, "iu");
|
|
37
37
|
const lowercaseTokenShape = /\btoken\s+[A-Za-z0-9._~+/=-]{8,}(?=$|[^A-Za-z0-9._~+/=-])/u;
|
package/dist/server.js
CHANGED
|
@@ -11,6 +11,7 @@ import { createToolExecuteAfterHook, createToolExecuteBeforeHook } from "./hooks
|
|
|
11
11
|
import { createLogger } from "./logger.js";
|
|
12
12
|
import { createIgnitionState } from "./ignition.js";
|
|
13
13
|
import { createSessionLookup } from "./session-lineage.js";
|
|
14
|
+
import { markLiveness } from "./session-liveness.js";
|
|
14
15
|
import { applyCompactionRuleReset, applyStaticRuleInjection } from "./rules/hooks.js";
|
|
15
16
|
import { defaultOpenCodeConfigRoot } from "./state.js";
|
|
16
17
|
import { litOpenCodeTools } from "./tools.js";
|
|
@@ -78,7 +79,10 @@ export function createLitOpenCodePlugin(autoUpdateRunner = runPluginAutoUpdate)
|
|
|
78
79
|
registerLitOpenCodeAgents(config, loaded.config);
|
|
79
80
|
},
|
|
80
81
|
event: async (eventInput) => {
|
|
82
|
+
if (eventInput.event.type === "session.idle")
|
|
83
|
+
await markLiveness(root, eventInput.event.properties.sessionID, "idle");
|
|
81
84
|
if (eventInput.event.type === "session.deleted") {
|
|
85
|
+
await markLiveness(root, eventInput.event.properties.info.id, "ended");
|
|
82
86
|
ignitionState.clear(eventInput.event.properties.info.id);
|
|
83
87
|
activationMemory.forget(eventInput.event.properties.info.id);
|
|
84
88
|
trustedCommandActivations.delete(eventInput.event.properties.info.id);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type LivenessState = "alive" | "idle" | "ended";
|
|
2
|
+
export type LivenessRecord = {
|
|
3
|
+
readonly version: 1;
|
|
4
|
+
readonly sessionId: string;
|
|
5
|
+
readonly state: LivenessState;
|
|
6
|
+
readonly at: string;
|
|
7
|
+
readonly herdrPane: string | null;
|
|
8
|
+
};
|
|
9
|
+
export declare const livenessRepeatMs = 30000;
|
|
10
|
+
export declare function livenessFile(projectRoot: string, sessionID: string): string;
|
|
11
|
+
/** The session's record, or undefined when the id is unsafe or the file is missing, a link, oversized or malformed. */
|
|
12
|
+
export declare function readLivenessSync(projectRoot: string, sessionID: string): LivenessRecord | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Records the session's state; true when a record was written. Never throws: a missing project state folder,
|
|
15
|
+
* a linked folder or record, an unsafe id or a failed write all return false so the calling hook carries on.
|
|
16
|
+
*/
|
|
17
|
+
export declare function markLiveness(projectRoot: string, sessionID: string, state: LivenessState, options?: {
|
|
18
|
+
readonly now?: number;
|
|
19
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
20
|
+
}): Promise<boolean>;
|