@litfamily/litopencode 1.0.31 → 1.0.32
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 +24 -0
- package/README-Ko-KR.md +6 -6
- package/README.md +6 -6
- 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/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 +48 -1
- package/dist/features.d.ts +80 -1
- package/dist/features.js +105 -1
- package/dist/ledger.js +12 -1
- package/dist/secret-shapes.js +5 -5
- 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 +156 -0
- package/dist/state.d.ts +2 -0
- package/dist/state.js +2 -0
- package/dist/tools.js +22 -2
- package/dist/tui/mission-band.d.ts +20 -1
- package/dist/tui/mission-band.js +73 -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 +48 -0
- package/dist/tui/mission-source.js +184 -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 +50 -0
- package/dist/tui/mission-threads.js +119 -0
- package/dist/tui.js +84 -6
- package/dist/uiux-visual-catalog.js +8 -1
- 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 +30 -2
- package/docs/reference.md +34 -2
- 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 +208 -0
- package/skills/lit-adhd/references/brief-format.md +43 -0
- package/skills/lit-adhd/references/card-examples.md +82 -0
- package/skills/lit-adhd/references/status-taxonomy.md +29 -0
- package/skills/lit-adhd/scripts/rewind.mjs +835 -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 +2 -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 +4 -2
- package/tools/payload-substance-parity.json +4 -3
- package/tools/qa-cover-recipes.mjs +4 -3
package/dist/v2/session-hooks.js
CHANGED
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
// than from LitOpenCode's own instructions (local knowledge, a start-work receipt, an auto-handoff setting
|
|
7
7
|
// reply) rides the latest user message instead, the channel it had on OpenCode 1.
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import {
|
|
9
|
+
import { typedPromptReply } from "../adhd-next.js";
|
|
10
|
+
import { createActivationMemory, decideReentry, recordActivation } from "../activation-reentry.js";
|
|
10
11
|
import { detectChatActivationMode, promptForChatActivationMode } from "../activation-routing.js";
|
|
11
|
-
import { startWorkPromptInjection } from "../activation-workflow-prompts.js";
|
|
12
|
+
import { adhdSessionNote, litAdhdPromptInjection, startWorkPromptInjection } from "../activation-workflow-prompts.js";
|
|
12
13
|
import { autoHandoffSettingText } from "../auto-handoff.js";
|
|
13
14
|
import { applyTrustedStartWorkDirective, parseStartWorkLifecycleDirective } from "../bounded-authority-hooks.js";
|
|
14
15
|
import { queryKnowledge } from "../knowledge.js";
|
|
16
|
+
import { startTypedWork, typedStartArgument } from "../start-work-typed.js";
|
|
15
17
|
import { createLitGoalOperations } from "../ledger.js";
|
|
16
18
|
import { applyCompactionRuleReset, applyStaticRuleInjection } from "../rules/hooks.js";
|
|
17
19
|
import { isReadOnlyWorkflowFamilyPlan } from "../workflow-families.js";
|
|
@@ -125,13 +127,42 @@ export function createV2SessionHooks(options) {
|
|
|
125
127
|
catch { // no-excuse-ok: catch -- local relevance must never block the user message.
|
|
126
128
|
// A malformed or unreadable knowledge store stays silent instead of inventing context.
|
|
127
129
|
}
|
|
130
|
+
const typed = await typedPromptReply(options.projectRoot, event.sessionID, input, activationMemory, options.config.boundedAuthority);
|
|
131
|
+
if (typed !== undefined) {
|
|
132
|
+
state.turn.push(typed.text);
|
|
133
|
+
event.metadata = { ...(event.metadata ?? {}), litopencode: { mode: typed.mode, trigger: "lit", source: "prompt", typed: typed.kind } };
|
|
134
|
+
if (typed.continued)
|
|
135
|
+
options.onActivation?.(event.sessionID, typed.mode);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// An installed alias file makes the host expand /lit-adhd (or /lit-rewind) itself, so the prompt
|
|
139
|
+
// arrives as the command body with no plugin mark; it still runs the brief and takes its look.
|
|
140
|
+
if (input.trimStart().startsWith(litAdhdPromptInjection.trim())) {
|
|
141
|
+
state.turn.push(adhdSessionNote(event.sessionID));
|
|
142
|
+
event.metadata = { ...(event.metadata ?? {}), litopencode: { mode: "lit-adhd", trigger: "lit", source: "alias" } };
|
|
143
|
+
options.onActivation?.(event.sessionID, "lit-adhd");
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
128
146
|
const mode = detectChatActivationMode(input, session.agent);
|
|
129
147
|
if (mode === undefined)
|
|
130
148
|
return;
|
|
131
149
|
const trigger = mode === "lit-handoff" ? "handoff" : mode === "lit-scientific-visualization" ? mode : "lit";
|
|
132
150
|
let activation = promptForChatActivationMode(mode, input);
|
|
151
|
+
if (mode === "lit-adhd")
|
|
152
|
+
activation = `${activation}\n${adhdSessionNote(event.sessionID)}`;
|
|
133
153
|
if (mode === "start-work" && session.agent !== "lit-plan") {
|
|
134
154
|
const directive = parseStartWorkLifecycleDirective(input, { chat: true });
|
|
155
|
+
const planArgument = directive === undefined ? typedStartArgument(input) : undefined;
|
|
156
|
+
if (planArgument !== undefined) {
|
|
157
|
+
const started = await startTypedWork({
|
|
158
|
+
projectRoot: options.projectRoot,
|
|
159
|
+
sessionID: event.sessionID,
|
|
160
|
+
...(planArgument === "" ? {} : { plan: planArgument }),
|
|
161
|
+
options: options.config.boundedAuthority
|
|
162
|
+
});
|
|
163
|
+
if (started.quiet !== true)
|
|
164
|
+
state.user.push(started.text);
|
|
165
|
+
}
|
|
135
166
|
if (directive?.action === "resume") {
|
|
136
167
|
try {
|
|
137
168
|
const receipt = await applyTrustedStartWorkDirective(options.projectRoot, event.sessionID, directive, options.config.boundedAuthority);
|
|
@@ -160,15 +191,17 @@ export function createV2SessionHooks(options) {
|
|
|
160
191
|
activation = `${reentry.line}\n${activation}`;
|
|
161
192
|
else if (reentry.kind === "confirm")
|
|
162
193
|
activation = `${activation}\n${reentry.line}`;
|
|
194
|
+
if (reentry.kind !== "confirm" && mode !== "lit-handoff" && mode !== "lit-scientific-visualization") {
|
|
195
|
+
const recorded = await recordActivation({ memory: activationMemory, projectRoot: options.projectRoot, sessionID: event.sessionID, mode });
|
|
196
|
+
if (recorded.line !== undefined)
|
|
197
|
+
activation = `${activation}\n${recorded.line}`;
|
|
198
|
+
}
|
|
163
199
|
state.activation = activation;
|
|
164
200
|
event.metadata = {
|
|
165
201
|
...(event.metadata ?? {}),
|
|
166
202
|
litopencode: { mode, trigger, source: "prompt", ...(reentry.kind === "full" ? {} : { reentry: reentry.kind }) }
|
|
167
203
|
};
|
|
168
204
|
options.onActivation?.(event.sessionID, mode);
|
|
169
|
-
if (reentry.kind !== "confirm" && mode !== "lit-handoff" && mode !== "lit-scientific-visualization") {
|
|
170
|
-
activationMemory.remember(event.sessionID, mode);
|
|
171
|
-
}
|
|
172
205
|
if (mode === "lit-task" || mode === "lit-recap" || mode === "lit-brainstorm" || isReadOnlyWorkflowFamilyPlan(mode))
|
|
173
206
|
return;
|
|
174
207
|
try {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare const workflowStackSchema = "litopencode.workflow-stack/v1";
|
|
2
|
+
export type FrameStatus = "active" | "paused";
|
|
3
|
+
export type StackFrame = {
|
|
4
|
+
readonly skill: string;
|
|
5
|
+
readonly status: FrameStatus;
|
|
6
|
+
readonly at: number;
|
|
7
|
+
readonly phase?: string;
|
|
8
|
+
/** Both counts or neither: an unknown total is never stored as zero. */
|
|
9
|
+
readonly done?: number;
|
|
10
|
+
readonly total?: number;
|
|
11
|
+
};
|
|
12
|
+
export type WorkflowStack = {
|
|
13
|
+
readonly schema: typeof workflowStackSchema;
|
|
14
|
+
readonly sessionID: string;
|
|
15
|
+
readonly frames: readonly StackFrame[];
|
|
16
|
+
readonly updatedAt: number;
|
|
17
|
+
};
|
|
18
|
+
export type FrameProgress = {
|
|
19
|
+
readonly phase?: string;
|
|
20
|
+
readonly done?: number;
|
|
21
|
+
readonly total?: number;
|
|
22
|
+
};
|
|
23
|
+
export declare function isSpineSkill(skill: string): boolean;
|
|
24
|
+
export declare function emptyStack(sessionID: string): WorkflowStack;
|
|
25
|
+
/** A new spine skill ends whatever the stack held: the user moved on to a different discipline. */
|
|
26
|
+
export declare function startSpine(stack: WorkflowStack, skill: string, now: number): WorkflowStack;
|
|
27
|
+
/** Records the spine's progress without pausing it, so a later pause or a card read has real numbers. */
|
|
28
|
+
export declare function pauseSpine(stack: WorkflowStack, now: number, progress?: FrameProgress): WorkflowStack;
|
|
29
|
+
/**
|
|
30
|
+
* Starts a side skill. An active spine is paused under it, keeping its stage and counts; a second side
|
|
31
|
+
* skill replaces the first. With no spine the side skill stands alone.
|
|
32
|
+
*/
|
|
33
|
+
export declare function pushSide(stack: WorkflowStack, skill: string, now: number, progress: FrameProgress | undefined): WorkflowStack;
|
|
34
|
+
/** Closes the side frame and makes the paused spine active again at the stage it was paused in. */
|
|
35
|
+
export declare function resumeSpine(stack: WorkflowStack, now: number): {
|
|
36
|
+
readonly stack: WorkflowStack;
|
|
37
|
+
readonly resumed?: StackFrame;
|
|
38
|
+
};
|
|
39
|
+
export declare function stackFile(projectRoot: string, sessionID: string): string;
|
|
40
|
+
/** The session's stack, or undefined when the id is unsafe, the file is missing, a link, oversized or malformed. */
|
|
41
|
+
export declare function readStack(projectRoot: string, sessionID: string): Promise<WorkflowStack | undefined>;
|
|
42
|
+
export declare function writeStack(projectRoot: string, stack: WorkflowStack): Promise<void>;
|
|
43
|
+
export type SiblingOptions = {
|
|
44
|
+
readonly now: number;
|
|
45
|
+
readonly freshMs: number;
|
|
46
|
+
readonly max: number;
|
|
47
|
+
};
|
|
48
|
+
/** Other sessions' stacks that moved recently, for the thread rows. Links and the session's own file are skipped. */
|
|
49
|
+
export declare function readSiblingStacks(projectRoot: string, selfID: string, options: SiblingOptions): Promise<readonly WorkflowStack[]>;
|
|
50
|
+
/** The TUI reads on its own refresh and cannot await: the same checks as `readStack`, synchronously. */
|
|
51
|
+
export declare function readStackSync(projectRoot: string, sessionID: string): WorkflowStack | undefined;
|
|
52
|
+
/** Synchronous twin of `readSiblingStacks`. */
|
|
53
|
+
export declare function readSiblingStacksSync(projectRoot: string, selfID: string, options: SiblingOptions): readonly WorkflowStack[];
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { lstatSync, readFileSync, readdirSync } from "node:fs";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { createRuntimePaths } from "./state.js";
|
|
5
|
+
// A session's workflow stack: the discipline it is running (the spine) and, while another lit command
|
|
6
|
+
// is interjected, the paused spine underneath it. An interjected command pauses the spine and never
|
|
7
|
+
// erases it, so `lit continue` returns to the same stage and the same k/n. Transitions are pure; the
|
|
8
|
+
// store keeps one small JSON file per session so the TUI band and a restarted plugin read the same
|
|
9
|
+
// record.
|
|
10
|
+
export const workflowStackSchema = "litopencode.workflow-stack/v1";
|
|
11
|
+
const spineSkills = new Set(["lit-loop", "lit-plan", "start-work", "lit-task"]);
|
|
12
|
+
const safeSessionID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/u;
|
|
13
|
+
const stackByteLimit = 64 * 1024;
|
|
14
|
+
const frameLimit = 4;
|
|
15
|
+
export function isSpineSkill(skill) {
|
|
16
|
+
return spineSkills.has(skill);
|
|
17
|
+
}
|
|
18
|
+
export function emptyStack(sessionID) {
|
|
19
|
+
return { schema: workflowStackSchema, sessionID, frames: [], updatedAt: 0 };
|
|
20
|
+
}
|
|
21
|
+
function counts(progress) {
|
|
22
|
+
const done = progress?.done;
|
|
23
|
+
const total = progress?.total;
|
|
24
|
+
return Number.isInteger(done) && Number.isInteger(total) && total > 0 && done >= 0 && done <= total
|
|
25
|
+
? { done: done, total: total }
|
|
26
|
+
: {};
|
|
27
|
+
}
|
|
28
|
+
function frame(skill, status, at, progress) {
|
|
29
|
+
return { skill, status, at, ...(progress?.phase === undefined ? {} : { phase: progress.phase }), ...counts(progress) };
|
|
30
|
+
}
|
|
31
|
+
function withFrames(stack, frames, now) {
|
|
32
|
+
return { ...stack, frames: frames.slice(-frameLimit), updatedAt: now };
|
|
33
|
+
}
|
|
34
|
+
/** A new spine skill ends whatever the stack held: the user moved on to a different discipline. */
|
|
35
|
+
export function startSpine(stack, skill, now) {
|
|
36
|
+
return withFrames(stack, [frame(skill, "active", now)], now);
|
|
37
|
+
}
|
|
38
|
+
/** Records the spine's progress without pausing it, so a later pause or a card read has real numbers. */
|
|
39
|
+
export function pauseSpine(stack, now, progress) {
|
|
40
|
+
const [spine, ...rest] = stack.frames;
|
|
41
|
+
if (spine === undefined || !isSpineSkill(spine.skill))
|
|
42
|
+
return stack;
|
|
43
|
+
return withFrames(stack, [frame(spine.skill, "paused", spine.at, { phase: progress?.phase ?? spine.phase, done: progress?.done ?? spine.done, total: progress?.total ?? spine.total }), ...rest], now);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Starts a side skill. An active spine is paused under it, keeping its stage and counts; a second side
|
|
47
|
+
* skill replaces the first. With no spine the side skill stands alone.
|
|
48
|
+
*/
|
|
49
|
+
export function pushSide(stack, skill, now, progress) {
|
|
50
|
+
const spine = stack.frames.find((candidate) => isSpineSkill(candidate.skill));
|
|
51
|
+
if (spine === undefined)
|
|
52
|
+
return withFrames(stack, [frame(skill, "active", now)], now);
|
|
53
|
+
const paused = pauseSpine({ ...stack, frames: [spine] }, now, progress).frames[0];
|
|
54
|
+
return withFrames(stack, [paused, frame(skill, "active", now)], now);
|
|
55
|
+
}
|
|
56
|
+
/** Closes the side frame and makes the paused spine active again at the stage it was paused in. */
|
|
57
|
+
export function resumeSpine(stack, now) {
|
|
58
|
+
const spine = stack.frames.find((candidate) => isSpineSkill(candidate.skill) && candidate.status === "paused");
|
|
59
|
+
if (spine === undefined)
|
|
60
|
+
return { stack };
|
|
61
|
+
const resumed = { ...spine, status: "active" };
|
|
62
|
+
return { stack: withFrames(stack, [resumed], now), resumed };
|
|
63
|
+
}
|
|
64
|
+
export function stackFile(projectRoot, sessionID) {
|
|
65
|
+
if (!safeSessionID.test(sessionID))
|
|
66
|
+
throw new Error("workflow stack session id must match [A-Za-z0-9_-]");
|
|
67
|
+
return path.join(createRuntimePaths(projectRoot).workflowStackDir, `${sessionID}.json`);
|
|
68
|
+
}
|
|
69
|
+
function isFrame(value) {
|
|
70
|
+
if (typeof value !== "object" || value === null)
|
|
71
|
+
return false;
|
|
72
|
+
const record = value;
|
|
73
|
+
const optionalInt = (field) => field === undefined || (Number.isInteger(field) && field >= 0);
|
|
74
|
+
return typeof record.skill === "string" && (record.status === "active" || record.status === "paused") && Number.isFinite(record.at) &&
|
|
75
|
+
(record.phase === undefined || typeof record.phase === "string") && optionalInt(record.done) && optionalInt(record.total);
|
|
76
|
+
}
|
|
77
|
+
async function readRegular(file) {
|
|
78
|
+
try {
|
|
79
|
+
const stat = await fs.lstat(file);
|
|
80
|
+
if (!stat.isFile() || stat.size > stackByteLimit)
|
|
81
|
+
return undefined;
|
|
82
|
+
return await fs.readFile(file, "utf8");
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function parseStack(text, sessionID) {
|
|
89
|
+
if (text === undefined)
|
|
90
|
+
return undefined;
|
|
91
|
+
let value;
|
|
92
|
+
try {
|
|
93
|
+
value = JSON.parse(text);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
if (typeof value !== "object" || value === null)
|
|
99
|
+
return undefined;
|
|
100
|
+
const record = value;
|
|
101
|
+
if (record.schema !== workflowStackSchema || record.sessionID !== sessionID || !Array.isArray(record.frames) || !record.frames.every(isFrame) || !Number.isFinite(record.updatedAt))
|
|
102
|
+
return undefined;
|
|
103
|
+
return { schema: workflowStackSchema, sessionID, frames: record.frames.slice(-frameLimit), updatedAt: record.updatedAt };
|
|
104
|
+
}
|
|
105
|
+
/** The session's stack, or undefined when the id is unsafe, the file is missing, a link, oversized or malformed. */
|
|
106
|
+
export async function readStack(projectRoot, sessionID) {
|
|
107
|
+
if (!safeSessionID.test(sessionID))
|
|
108
|
+
return undefined;
|
|
109
|
+
return parseStack(await readRegular(stackFile(projectRoot, sessionID)), sessionID);
|
|
110
|
+
}
|
|
111
|
+
export async function writeStack(projectRoot, stack) {
|
|
112
|
+
const file = stackFile(projectRoot, stack.sessionID);
|
|
113
|
+
const dir = path.dirname(file);
|
|
114
|
+
await fs.mkdir(dir, { recursive: true });
|
|
115
|
+
const dirStat = await fs.lstat(dir);
|
|
116
|
+
if (!dirStat.isDirectory())
|
|
117
|
+
throw new Error("workflow stack directory is not a directory");
|
|
118
|
+
try {
|
|
119
|
+
if ((await fs.lstat(file)).isSymbolicLink())
|
|
120
|
+
throw new Error("workflow stack file is a link");
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error.code !== "ENOENT")
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
const temp = `${file}.${process.pid}.tmp`;
|
|
127
|
+
await fs.writeFile(temp, `${JSON.stringify(stack)}\n`, { mode: 0o600 });
|
|
128
|
+
await fs.rename(temp, file);
|
|
129
|
+
}
|
|
130
|
+
/** Other sessions' stacks that moved recently, for the thread rows. Links and the session's own file are skipped. */
|
|
131
|
+
export async function readSiblingStacks(projectRoot, selfID, options) {
|
|
132
|
+
const dir = createRuntimePaths(projectRoot).workflowStackDir;
|
|
133
|
+
let names;
|
|
134
|
+
try {
|
|
135
|
+
names = await fs.readdir(dir);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
const found = [];
|
|
141
|
+
for (const name of names.sort()) {
|
|
142
|
+
if (!name.endsWith(".json"))
|
|
143
|
+
continue;
|
|
144
|
+
const sessionID = name.slice(0, -".json".length);
|
|
145
|
+
if (sessionID === selfID || !safeSessionID.test(sessionID))
|
|
146
|
+
continue;
|
|
147
|
+
const stack = parseStack(await readRegular(path.join(dir, name)), sessionID);
|
|
148
|
+
if (stack === undefined || stack.frames.length === 0 || options.now - stack.updatedAt > options.freshMs)
|
|
149
|
+
continue;
|
|
150
|
+
found.push(stack);
|
|
151
|
+
if (found.length >= options.max)
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
return found;
|
|
155
|
+
}
|
|
156
|
+
function readRegularSync(file) {
|
|
157
|
+
try {
|
|
158
|
+
const stat = lstatSync(file);
|
|
159
|
+
return stat.isFile() && stat.size <= stackByteLimit ? readFileSync(file, "utf8") : undefined;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** The TUI reads on its own refresh and cannot await: the same checks as `readStack`, synchronously. */
|
|
166
|
+
export function readStackSync(projectRoot, sessionID) {
|
|
167
|
+
if (!safeSessionID.test(sessionID))
|
|
168
|
+
return undefined;
|
|
169
|
+
return parseStack(readRegularSync(stackFile(projectRoot, sessionID)), sessionID);
|
|
170
|
+
}
|
|
171
|
+
/** Synchronous twin of `readSiblingStacks`. */
|
|
172
|
+
export function readSiblingStacksSync(projectRoot, selfID, options) {
|
|
173
|
+
const dir = createRuntimePaths(projectRoot).workflowStackDir;
|
|
174
|
+
let names;
|
|
175
|
+
try {
|
|
176
|
+
names = readdirSync(dir);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
const found = [];
|
|
182
|
+
for (const name of names.sort()) {
|
|
183
|
+
if (!name.endsWith(".json"))
|
|
184
|
+
continue;
|
|
185
|
+
const sessionID = name.slice(0, -".json".length);
|
|
186
|
+
if (sessionID === selfID || !safeSessionID.test(sessionID))
|
|
187
|
+
continue;
|
|
188
|
+
const stack = parseStack(readRegularSync(path.join(dir, name)), sessionID);
|
|
189
|
+
if (stack === undefined || stack.frames.length === 0 || options.now - stack.updatedAt > options.freshMs)
|
|
190
|
+
continue;
|
|
191
|
+
found.push(stack);
|
|
192
|
+
if (found.length >= options.max)
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
return found;
|
|
196
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="146" height="20" role="img" aria-label="release: 1.0.
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="146" height="20" role="img" aria-label="release: 1.0.32"><title>release: 1.0.32</title><g shape-rendering="crispEdges"><rect width="49" height="20" fill="#080d14"/><rect x="49" width="97" height="20" fill="#ff6337"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text x="255" y="140" textLength="390" transform="scale(.1)">release</text><text x="965" y="140" textLength="870" transform="scale(.1)" fill="#080D14">1.0.32</text></g></svg>
|
|
Binary file
|
package/docs/reference-Ko-KR.md
CHANGED
|
@@ -140,6 +140,8 @@ litopencode install
|
|
|
140
140
|
| `/review-work` | `lit-plan` 뒤에는 계획 검토, `lit-loop`나 `/start-work` 뒤에는 작업 검토. 있는 것을 보고 고르며 `/review-work plan`, `/review-work work`로 직접 정할 수 있음 |
|
|
141
141
|
| `/litgoal` | 끝나는 지점을 정하고 지킴: 확인 가능한 기준이 붙은 목표 하나를 디스크에 남김. `lit-loop`와 `/start-work`가 그 목표를 향해 일함 |
|
|
142
142
|
| `/lit-brainstorm` | 열린 질문을 여러 선택지로 펼친 뒤 짧은 목록으로 좁히고, 고른 것을 `deep-interview`나 `lit-plan`에 넘김. 채팅에서는 `lit brainstorm`, `lit brainstorming`, `lit ideation`, `lit ideate`, `lit idea`, `lit ideas`. 직접 만들지는 않음 |
|
|
143
|
+
| `/lit-hijack` | 다른 사람이 공개한 작업의 기법 원리를 내 스킬이나 시스템에 옮김: 출처 기록, 라이선스 확인, 격차 분석, 원문 없는 명세, 분리된 구현, 동작 비교, 보고서. 각 단계의 완료는 동봉된 `hijack.mjs`가 판정함. 채팅에서는 `lit hijack`, `lit hijacking`, `lit 하이재킹`, `lit 하이잭` |
|
|
144
|
+
| `/lit-adhd`, `/lit-rewind` | 하던 일을 이어서 시작: 이전 세션의 상태, 실제 진행 또는 아는 사실, 로드맵, 추천 한 단계를 읽기 전용으로 보여 줌. 동봉된 `rewind.mjs`가 수집함. 채팅에서는 `lit adhd`, `lit rewind`, 이어서 `go`가 30분간 준비된 단계를 따라감. `lit approve`와 `lit deny`는 대기 중인 경계에 답하고, `lit deny`는 실행을 끝냄. |
|
|
143
145
|
| `/litresearch` 또는 `/lit-research` | 순차 대체 경로를 포함한 근거 기반 연구 |
|
|
144
146
|
| `/lit-handoff` | 이어서 작업할 수 있는 핸드오프 작성 |
|
|
145
147
|
| `/lit-recap` | 로컬 ledger와 세션 맥락으로 짧은 리캡 작성 |
|
|
@@ -405,6 +407,28 @@ OpenCode 1.18은 `tui.json`이나 `tui.jsonc`의 `plugin` 배열에 적힌 TUI
|
|
|
405
407
|
자리가 모자라면 남은 칩을 `+N`으로 접습니다.
|
|
406
408
|
- 아래 테두리에는 context 사용량(75%부터 주황), 첫 lit 턴부터 지난 시간(`⟳ 7m`), git 브랜치가
|
|
407
409
|
붙습니다.
|
|
410
|
+
- 나란히 도는 작업이 둘 이상이면 스킬 칩 줄 아래에 줄이 늘어납니다. `┬ 3 lanes in parallel` 다음에
|
|
411
|
+
작업마다 `├─`/`└─` 한 줄씩입니다(이 세션의 워크플로 스택 항목, 실행 중인 `task` 호출, 최근 15분
|
|
412
|
+
안에 스택이 움직인 같은 작업 공간의 다른 세션). 최대 네 줄이고 나머지는 `+N more`입니다. 줄마다 이름,
|
|
413
|
+
상태 단어(`working`, `paused`, `done`, `failed`, `idle`), 그리고 실제 총량이 있을 때만 게이지
|
|
414
|
+
(`[▉▉░░░░░░] 3/10`)가 붙습니다. 총량을 모르면 아는 것(단계, 걸린 시간)을 글로 쓰고 일하는 중이면 작은
|
|
415
|
+
펄스를 보여 줄 뿐 물음표는 쓰지 않습니다. 작업이 살아 있는 동안 카드는 가장 높았던 높이를 유지하고,
|
|
416
|
+
모두 가라앉으면 네 줄로 돌아옵니다.
|
|
417
|
+
- `lit-adhd`(별칭 `lit-rewind`)가 도는 동안 테두리, LIT 글자, 게이지가 같은 밝기의 색상환을 따라 돕니다.
|
|
418
|
+
1초에 네 번 색이 조금씩 바뀌고 깜박이지 않습니다. `motion: false`와 `NO_COLOR`에서는 꺼집니다. 이전
|
|
419
|
+
작업이 있는 작업 공간의 쉬는 세션은 `lit adhd to pick up where you left off`를 보여 주고, 그곳에서 처음 연
|
|
420
|
+
새 세션은 같은 문구로 토스트를 한 번 띄웁니다(v1 TUI만. v2 TUI에는 띠도 토스트도 없습니다).
|
|
421
|
+
- 카드의 모양은 한 번에 하나이고, `src/tui/mission-looks.ts`의 작은 목록에서 고릅니다. lit-adhd를 실행하는
|
|
422
|
+
길은 모두 되감기 모양이 됩니다. 채팅의 `lit adhd`/`lit rewind`, `/lit-adhd`/`/lit-rewind`(v2에 설치된 별칭
|
|
423
|
+
파일에서 온 것도 포함), 네이티브 `skill` 로드가 그렇습니다. 세션이 사용자를 기다리는 동안(권한 요청이나 질문,
|
|
424
|
+
또는 목표 결정, `BLOCKED:`로 시작하는 답, 경계에서 멈춘 타이핑 start-work 실행으로 끝난 쉬는 턴) 테두리가
|
|
425
|
+
주황빛이 되고 모서리에 `◆ YOUR TURN`이 뜹니다. 주황빛은 3초 호흡으로 천천히 바뀌고 깜박이지 않으며,
|
|
426
|
+
`motion: false`와 `NO_COLOR`에서는 멈춰 있고, 사용자가 입력하면 꺼집니다. `review-work`가 도는 동안에는
|
|
427
|
+
위 테두리가 다섯 갈래(scope, tests, package, security, surface)로 나뉘고 모서리에 `◇ REVIEW 2/5`처럼 보고된
|
|
428
|
+
수를 셉니다. 에이전트가 `review-work` 도구(`action: "lane"`, 갈래 이름, `pass`·`fail`·`blocked`)로 보고한
|
|
429
|
+
뒤에만 그 갈래가 켜집니다. 실패한 갈래는 오류 색이 되고, 보고되지 않은 갈래는 흐리게 남습니다. 목표가 끝나면
|
|
430
|
+
완료 불꽃이 한 번 터지고 카드가 가라앉으며, 평소 턴에서는 다시 터지지 않습니다. 릴리스 게시는 카드가 받는
|
|
431
|
+
신호가 없어서 불꽃도 없습니다.
|
|
408
432
|
|
|
409
433
|
하위(subagent) 세션에서는 부모 세션의 카드를 `· in lane`과 함께 보여 주고, 홈 화면에는 띠가
|
|
410
434
|
없습니다. 폭이 좁으면 줄마다 덜 중요한 것부터 덜어 냅니다. 단계 줄은 지금 하는 일과 다음 할 일
|
|
@@ -640,10 +664,14 @@ Install은 `<root>/skills`가 심볼릭 링크여도(예: `~/.config/opencode/sk
|
|
|
640
664
|
|
|
641
665
|
## 디자인 제작과 README
|
|
642
666
|
|
|
643
|
-
OpenCode 네이티브 스킬 `frontend-ui-ux`는 충분한 구현 요청을 받으면 작업 화면을 만들고 렌더링을 확인합니다. 중요한 방향이 모호할 때만 질문하며 답변을 보존합니다. 검토·계획 요청은 읽기 전용입니다.
|
|
667
|
+
OpenCode 네이티브 스킬 `frontend-ui-ux`는 충분한 구현 요청을 받으면 작업 화면을 만들고 렌더링을 확인합니다. 중요한 방향이 모호할 때만 질문하며 답변을 보존합니다. 검토·계획 요청은 읽기 전용입니다. 새 페이지나 화면은 `scripts/design-lock.mjs`로 룩(하우스 스타일, 레이아웃 계열, 시그니처 순간, 풍부 또는 차분한 밀도)을 먼저 고정합니다. 생성된 `design.lock.json`, `ui/tokens.css`, `ui/components.css`와 글꼴은 프로젝트에 놓이며, 글꼴은 sha256 확인 후 `lit-diagram-drawer`와 `lit-typographic-motion` 스킬에서 복사합니다. 락이 페이지 옆에 있으면 `scripts/probe.mjs`가 DS-001~DS-008과 LOOK-1~LOOK-6 질문을 더합니다. `--viewports`는 일부 뷰만 돌리며 승인하지 않습니다.
|
|
644
668
|
|
|
645
669
|
네이티브 스킬 도구에서 `readme-studio`를 선택하면 실제 저장소 정보로 README와 표지를 제작합니다. 로컬 글꼴의 윤곽선, Remotion/HyperFrames 예제, 정적·동적 출력 절차가 함께 설치됩니다. 이미지 생성 도구가 없으면 `IMAGE_GENERATION_UNAVAILABLE`을 알리고 제공된 배경으로 이어갑니다. 공개 GitHub/npm 렌더링 검증은 별도 단계입니다. 전용 슬래시 명령은 없습니다.
|
|
646
670
|
|
|
671
|
+
네이티브 스킬 `lit-typographic-motion`은 무대 영화에 이야기(`story`: 보는 사람의 기대, 반전, 반전이 떨어지는 샷, 결말)와 영화의 절반 이상에서 움직이는 주인공을 요구합니다. 요청에 링크가 있으면 제품이 필수입니다. `render.mjs assets --out <dir> --url <https 링크> [--cover]`가 페이지와 README를 신뢰할 수 없는 데이터로 읽어, 형식을 확인하고 크기를 제한한 이미지만(SVG는 정리, 배지는 제외) `stage/assets/` 또는 `cover/assets/`에 두며, 그 이미지를 한 번도 보여 주지 않는 영화는 `ASSET-USED` 게이트 행에서 실패합니다. 제품에 닿을 수 없으면 화면을 지어내지 않고 종료 코드 22로 사용자에게 묻습니다. `depth: "3d"`는 고정된 three.js r170(`/lit/three/`로 제공, 해시는 `THIRD_PARTY_NOTICES`)을 GPU 단계에서 쓰고, GPU가 시작되지 않으면 표시를 달아 SwiftShader로 내려갑니다. 사용자 그림이 없는 README 표지는 `hero-3d` 레시피를, `painted-light`는 사용자 그림이 있을 때만 씁니다. 영화는 기본적으로 풍부합니다(`register: rich`). 무대 영화는 화면을 채워야 하고(열두 구역 중 둘 넘게 비는 샷이 둘 이상이면 `RICH-FILL` 실패), 실제 이름의 촘촘한 라벨과 움직이는 카메라를 갖추며, 영화마다 겹겹의 점수(`sound.mode: score`; 킥·클랩·하이햇·퍼커션·베이스·코드·리드·fx·액센트 스템, 사이드체인, -16 LUFS, 이야기 박자에 떨어지는 드롭, 스템은 `sound/stems/`에 보관)를 받습니다. 차분하거나 미니멀한 영화를 요청할 때만 `minimal`이 됩니다. `render3d: "blender"`는 선택형 Cycles 플레이트 단계를 더하며(`render.mjs blender --out <dir> [--final] [--detach]`; `scaffold`가 `BLENDER:` 줄을 알리고, Blender가 없으면 표시를 달아 three.js로 내려갑니다), 보는 확인은 무대 경로에서 질문 11개(타입 경로와 표지는 9개)이며 영화가 자기 방식에 충분히 풍부한지, 반전이 닿는지를 묻습니다. `gate.mjs --done`은 폴더 위쪽에서 실행을 찾으므로 영화 폴더 안에서 `--out .`으로도 동작합니다. 트리트먼트 전에는 경로·스타일·형식·방식을 `question` 호출 한 번으로 묻고 규칙의 추천을 먼저 둡니다.
|
|
672
|
+
|
|
647
673
|
개념·편집·기술 다이어그램은 `lit-diagram-drawer` 네이티브 스킬 선택기에서 제작하고 검증합니다. 제품 인터페이스는 `frontend-ui-ux`, 측정된 과학 데이터 그림은 `lit-scientific-visualization`을 사용합니다.
|
|
648
674
|
|
|
649
|
-
|
|
675
|
+
실제 장비의 P&ID, PFD, 실험 장치 그림, 아이소메트릭 단면도는 `lit-schematic` 네이티브 스킬 선택기에서 제작하고 QA 스크립트와 렌더 확인으로 검증합니다. 범위가 분명한 도면 요청에 `lit`을 붙이면 그리기 전에 이 스킬을 불러오도록 안내합니다. 전용 슬래시 명령은 없습니다.
|
|
676
|
+
|
|
677
|
+
`lit-docx`는 워드 보고서, `lit-pptx`는 파워포인트 발표자료를 만듭니다. `lit`과 함께 쓰면 요청한 형식의 네이티브 스킬을 선택하고, 마크다운 원본·품질 검사·렌더 확인을 유지합니다. 두 스킬은 만들기 전에 디자인 방향을 정하고 다른 후보 두 개와 함께 알려 줍니다. 발표자료는 Ledger, Signal, Atlas, Chalk, Paper, Gazette, Studio, Night, Computational Brutalism, Neo-Brutalism, Bauhaus, Riso, Newsroom 열세 가지, 보고서는 Report, Brief, Manual, Proposal, Memo, Journal 여섯 가지 방향 중에서 고릅니다.
|
package/docs/reference.md
CHANGED
|
@@ -168,6 +168,8 @@ for an approved plan; `/review-work` checks the `DoneClaim` through a five-lane
|
|
|
168
168
|
| `/review-work` | Plan review after `lit-plan` or work review after `lit-loop` or `/start-work`, picked from what exists; `/review-work plan` or `/review-work work` forces one. |
|
|
169
169
|
| `/litgoal` | Set and keep the finish line: one goal with checkable criteria on durable state. `lit-loop` and `/start-work` run toward it. |
|
|
170
170
|
| `/lit-brainstorm` | Open a question into options, narrow them to a short list, and hand the pick to `deep-interview` or `lit-plan`. Chat: `lit brainstorm`, `lit brainstorming`, `lit ideation`, `lit ideate`, `lit idea`, `lit ideas`. It never builds. |
|
|
171
|
+
| `/lit-hijack` | Port the mechanism in someone else's published work into your own skill or system: capture with provenance, licence gate, gap, source-free spec, separate build, parity proof and report. A bundled `hijack.mjs` decides when each phase is done. Chat: `lit hijack`, `lit hijacking`, `lit 하이재킹`, `lit 하이잭`. |
|
|
172
|
+
| `/lit-adhd`, `/lit-rewind` | Pick up where you left off: a read-only brief of earlier sessions with status, real progress or known facts, a roadmap and one recommended step. A bundled `rewind.mjs` collects it. Chat: `lit adhd`, `lit rewind`; then `go` follows the armed step for 30 minutes. `lit approve` and `lit deny` answer a pending boundary; `lit deny` ends the run. |
|
|
171
173
|
| `/litresearch` or `/lit-research` | Run evidence-backed research with a sequential fallback. |
|
|
172
174
|
| `/lit-handoff` | Create a resumable handoff; exact bare `handoff` also routes here. |
|
|
173
175
|
| `/lit-recap` | Read a concise recap from local ledger and session context. |
|
|
@@ -263,6 +265,8 @@ flowchart LR
|
|
|
263
265
|
- <code>lit-commit</code>
|
|
264
266
|
- <code>lit-crucible</code>
|
|
265
267
|
- <code>lit-brainstorm</code>
|
|
268
|
+
- <code>lit-hijack</code>
|
|
269
|
+
- <code>lit-adhd</code>
|
|
266
270
|
- <code>lit-init</code>
|
|
267
271
|
- <code>lit-comprehend</code>
|
|
268
272
|
- <code>lit-handoff</code>
|
|
@@ -270,6 +274,7 @@ flowchart LR
|
|
|
270
274
|
- <code>lit-recap</code>
|
|
271
275
|
- <code>lit-scientific-visualization</code>
|
|
272
276
|
- <code>lit-diagram-drawer</code>
|
|
277
|
+
- <code>lit-schematic</code>
|
|
273
278
|
- <code>lit-pptx</code>
|
|
274
279
|
- <code>lit-docx</code>
|
|
275
280
|
- <code>lit-typographic-motion</code>
|
|
@@ -522,7 +527,32 @@ What it draws:
|
|
|
522
527
|
gets a short light sweep as it arrives; when the turn ends they dim and stay as the recent list,
|
|
523
528
|
newest first, and firing one again brightens it. Chips that do not fit collapse into `+N`;
|
|
524
529
|
- the bottom border holds the context use (amber from 75%), the time since the first lit turn
|
|
525
|
-
(`⟳ 7m`) and the git branch
|
|
530
|
+
(`⟳ 7m`) and the git branch;
|
|
531
|
+
- lanes of parallel work add rows under the skill row while two or more exist: `┬ 3 lanes in
|
|
532
|
+
parallel`, then one `├─`/`└─` row per lane (this session's workflow-stack frames, running `task`
|
|
533
|
+
calls and other sessions in the workspace whose stack moved in the last 15 minutes), four at
|
|
534
|
+
most and `+N more` for the rest. Each row has the lane name, a status word (`working`,
|
|
535
|
+
`paused`, `done`, `failed`, `idle`) and a gauge only when the lane has a real total
|
|
536
|
+
(`[▉▉░░░░░░] 3/10`); otherwise it says what is known (the stage, how long it has run) and a
|
|
537
|
+
working lane shows a small pulse, never a question mark. The card keeps its tallest height while
|
|
538
|
+
lanes are live and drops back to four rows once everything has settled;
|
|
539
|
+
- while `lit-adhd` (alias `lit-rewind`) runs, the border, the LIT word and the gauges cycle through
|
|
540
|
+
the colour wheel at one fixed lightness, four small colour steps a second with no flashing. It
|
|
541
|
+
is off under `motion: false` and `NO_COLOR`. An idle session in a workspace with earlier work
|
|
542
|
+
says `lit adhd to pick up where you left off`, and the first fresh session there raises one
|
|
543
|
+
toast with the same words (v1 TUI only; the v2 TUI has no band and no toast).
|
|
544
|
+
- one look at a time, picked from a small registry in `src/tui/mission-looks.ts`. Every route that runs
|
|
545
|
+
lit-adhd wears the rewind look: `lit adhd`/`lit rewind` in chat, `/lit-adhd`/`/lit-rewind` (also from an
|
|
546
|
+
installed v2 alias file) and a native `skill` load. While the session waits on you (a permission or a
|
|
547
|
+
question, or an idle turn that ended on a goal decision, a reply opening with `BLOCKED:`, or a typed
|
|
548
|
+
start-work run paused on a boundary) the border turns amber and the corner says `◆ YOUR TURN`; the
|
|
549
|
+
amber eases over a 3 s breath with no flashing, holds still under `motion: false` and `NO_COLOR`, and
|
|
550
|
+
stops once you type. While `review-work` runs, the top border splits into its five lanes (scope, tests,
|
|
551
|
+
package, security, surface) and the corner counts them, `◇ REVIEW 2/5`. A lane lights only after the
|
|
552
|
+
agent reports it with the `review-work` tool (`action: "lane"`, a lane and `pass`, `fail` or
|
|
553
|
+
`blocked`); a failed lane turns the error colour and an unreported one stays dim. When a goal reaches
|
|
554
|
+
done the completion sparks play once and the card settles; a routine turn never replays them. A
|
|
555
|
+
published release has no signal on the card, so it raises no burst;
|
|
526
556
|
|
|
527
557
|
A subagent session shows its parent's card with `· in lane`; the home screen has no band. When the
|
|
528
558
|
card is narrow each row drops its own low-priority parts: the track drops the live step and
|
|
@@ -771,6 +801,8 @@ unmanaged copy, or accept that OpenCode may prefer it over the LitOpenCode-manag
|
|
|
771
801
|
|
|
772
802
|
## Design production and README Studio
|
|
773
803
|
|
|
774
|
-
The native `frontend-ui-ux` skill takes an adequate authorized build request through working implementation and rendered inspection. It asks only material design choices and retains answers; review and plan requests remain read-only.
|
|
804
|
+
The native `frontend-ui-ux` skill takes an adequate authorized build request through working implementation and rendered inspection. It asks only material design choices and retains answers; review and plan requests remain read-only. A new page or screen locks its look first with `scripts/design-lock.mjs` (house style, layout family, signature moment, rich or calm density); the generated `design.lock.json`, `ui/tokens.css`, `ui/components.css` and fonts live in the project, fonts are copied from the `lit-diagram-drawer` and `lit-typographic-motion` skills after a sha256 check, and `scripts/probe.mjs` adds DS-001 to DS-008 and the LOOK-1 to LOOK-6 questions when the lock sits beside the page. `--viewports` runs a subset of the matrix and never approves.
|
|
775
805
|
|
|
776
806
|
Select `readme-studio` through OpenCode's native skill tool for factual README writing and local cover composition. The installed resources include outlined typography helpers and pinned Remotion/HyperFrames recipes. Without a native image generator it reports `IMAGE_GENERATION_UNAVAILABLE` and can continue from a supplied background. Public GitHub/npm rendering is a separate gate. No dedicated slash command is claimed.
|
|
807
|
+
|
|
808
|
+
The native `lit-typographic-motion` skill gives a stage film a story (`story`: what the viewer expects, the turn, the shot where it lands, the payoff) and a protagonist that acts across at least half of the film. A link in the request makes the product required: `render.mjs assets --out <dir> --url <https link> [--cover]` reads the page and its README as untrusted data and keeps only sniffed, size-capped images (SVG cleaned, badges skipped) under `stage/assets/` or `cover/assets/`, and the `ASSET-USED` gate row fails a film that never shows them; an unreachable product exits 22 and asks the user instead of drawing an invented screen. `depth: "3d"` draws with the pinned three.js r170 (served under `/lit/three/`, hashes in `THIRD_PARTY_NOTICES`) on the GPU rung, and a failed GPU start falls back, labelled, to SwiftShader. A README cover without user art takes the `hero-3d` recipe; `painted-light` needs user art. Films are rich by default (`register: rich`): a stage film must fill its frame (`RICH-FILL` fails when more than two of twelve regions stay empty in more than one shot), carry dense real labels and a moving camera, and takes a per-film layered score (`sound.mode: score`; kick, clap, hats, perc, bass, chords, lead, fx and accents stems, sidechained, -16 LUFS, the drop on the story beat, stems kept under `sound/stems/`); only a request for a calm or minimal film makes it `minimal`. `render3d: "blender"` adds an optional Cycles plate rung (`render.mjs blender --out <dir> [--final] [--detach]`; `scaffold` prints a `BLENDER:` line, and an absent Blender falls back to three.js with a labelled note). The look round asks 11 questions on the stage path (9 on the type path and for covers), including whether the film is rich enough for its register and whether the turn lands, and `gate.mjs --done` finds the run up the tree, so it works with `--out .` from inside the film folder. Before the treatment the skill makes one `question` call for path, style, format and register, with the rules' pick first.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@litfamily/litopencode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.32",
|
|
4
4
|
"description": "Workflow plugin for OpenCode: add lit to a prompt and the work is planned, built, checked and written down so the next session can pick it up.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"opencode",
|
|
@@ -36,9 +36,10 @@ Diagrams: use `lit-diagram-drawer`.
|
|
|
36
36
|
## #contract.procedure
|
|
37
37
|
|
|
38
38
|
1. Use `references/production.md` for direction, finite inventories, defaults, and material choices; explicit user direction wins.
|
|
39
|
-
2.
|
|
39
|
+
2. A new page or screen first asks the user to pick the house style with OpenCode's `question` tool (two to four from `references/house-styles.md`, the family default first as `(Recommended)`) unless the request names one or brand tokens or says "you choose"; a non-interactive run takes the default and says so in one line. Then it locks its look with `scripts/design-lock.mjs init` (`references/house-styles.md`): one house style, layout family and signature moment, rich density unless the request says minimal or calm; build only from the generated kit. Brand tokens win.
|
|
40
|
+
3. Evolve `litfamily.design-contract/v1beta2` with the build; validate before acceptance. Implement actions, states, accessibility, and responsive behavior. Inspect the running surface; `references/production.md` gives the full procedure and evidence boundaries.
|
|
40
41
|
|
|
41
|
-
Choose `build` by default, `polish` for value-only fixes, `audit` for read-only findings, or `harden` for cue-gated state stress. Read `references/craft-floor.md` and `references/slop-register.md`; run `node scripts/probe.mjs --path <entry.html> --out <evidence-dir>` against the finished page through the installed browser path, even when UI work is one slice of a larger loop. The command must attempt the full RS matrix; --help is not a page probe, and an ad hoc screenshot cannot replace its result. A missing browser or exit 2 is BLOCKED, not PASS. Fix remaining measured or derived HIGH findings before claiming done. For competing directions left unresolved, ask before choosing. Keep the fixed review table and explicit `Not verified` list.
|
|
42
|
+
Choose `build` by default, `polish` for value-only fixes, `audit` for read-only findings, or `harden` for cue-gated state stress. Read `references/craft-floor.md` and `references/slop-register.md`; run `node scripts/probe.mjs --path <entry.html> --out <evidence-dir>` against the finished page through the installed browser path, even when UI work is one slice of a larger loop. The command must attempt the full RS matrix; --help is not a page probe, and an ad hoc screenshot cannot replace its result. A missing browser or exit 2 is BLOCKED, not PASS. A lock adds DS-001..008 and LOOK-1..6 to the probe. Fix remaining measured or derived HIGH findings before claiming done. For competing directions left unresolved, ask before choosing. Keep the fixed review table and explicit `Not verified` list.
|
|
42
43
|
|
|
43
44
|
For motion, read `references/motion-guide.md`; Phase 3 capture examples are specified in `references/complete-contract.md`.
|
|
44
45
|
|