litcodex-ai 0.3.21 → 0.3.22

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.
@@ -0,0 +1,10 @@
1
+ <init-deep-mode>
2
+
3
+ **MANDATORY**: First user-visible line this turn MUST be exactly:
4
+ `🔥 INIT-DEEP ENABLED 🔥`
5
+
6
+ You are in init-deep: create or refresh sparse, evidence-backed repository guidance.
7
+ Read existing local instructions and the real directory structure before proposing edits.
8
+ Preserve secrets boundaries, ignored runtime state, and unrelated user changes.
9
+
10
+ </init-deep-mode>
@@ -17,7 +17,7 @@
17
17
  // On activation the payload is the trusted bundled directive, loaded behind a FAIL-SILENT boundary:
18
18
  // a directive-load error resolves to "" (→ noop), so a missing dist/directive.md degrades the hook
19
19
  // to a silent no-op + exit 0 rather than throwing into the Codex host.
20
- import { loadDirectiveFrom } from "./directive.js";
20
+ import { loadDirectiveWithSkillBodyFrom } from "./directive.js";
21
21
  import { shouldSuppressInjection } from "./guards.js";
22
22
  import { modeForToken } from "./modes.js";
23
23
  import { matchLitTrigger } from "./trigger.js";
@@ -125,7 +125,7 @@ export function applyPreToolUseCreateGoalGuard(input) {
125
125
  */
126
126
  function loadDirectiveForModeFailSilent(mode) {
127
127
  try {
128
- return loadDirectiveFrom(mode.directivePath, mode.openMarker, mode.closeMarker);
128
+ return loadDirectiveWithSkillBodyFrom(mode.directivePath, mode.openMarker, mode.closeMarker, mode.skillName, mode.skillPath);
129
129
  }
130
130
  catch {
131
131
  return "";
@@ -14,6 +14,12 @@ export declare class LitLoopDirectiveError extends Error {
14
14
  * Normalization: CRLF→LF, lone CR→LF, then trim(). Fail-loud with a typed error (codes are generic).
15
15
  */
16
16
  export declare function loadDirectiveFrom(resolvedPath: string, openMarker: string, closeMarker: string): string;
17
+ /**
18
+ * Load a mode directive and splice the matching bundled SKILL.md body inside the same wrapper.
19
+ * This keeps the small host-adapted directive as the safety envelope while satisfying the
20
+ * bare-invocation contract: the model receives the full installed skill text for the selected mode.
21
+ */
22
+ export declare function loadDirectiveWithSkillBodyFrom(resolvedPath: string, openMarker: string, closeMarker: string, skillName: string, skillPath: string): string;
17
23
  /**
18
24
  * Read + normalize + validate the lit-loop directive at an explicit path. Test-only seam (S10
19
25
  * §Test plan) so corrupt / CRLF / missing-file cases can be exercised without swapping the bundled
@@ -55,6 +55,40 @@ export function loadDirectiveFrom(resolvedPath, openMarker, closeMarker) {
55
55
  }
56
56
  return normalized;
57
57
  }
58
+ function readNormalizedBody(resolvedPath, label) {
59
+ let raw;
60
+ try {
61
+ raw = readFileSync(resolvedPath, "utf8");
62
+ }
63
+ catch (err) {
64
+ const detail = err instanceof Error ? err.message : String(err);
65
+ throw new LitLoopDirectiveError("LIT_LOOP_DIRECTIVE_UNREADABLE", `${label}: unreadable at ${resolvedPath}: ${detail}`, resolvedPath);
66
+ }
67
+ const normalized = raw.replace(/\r\n/g, "\n").replace(/\r/g, "\n").trim();
68
+ if (normalized.length === 0) {
69
+ throw new LitLoopDirectiveError("LIT_LOOP_DIRECTIVE_EMPTY", `${label}: empty after normalization at ${resolvedPath}`, resolvedPath);
70
+ }
71
+ return normalized;
72
+ }
73
+ /**
74
+ * Load a mode directive and splice the matching bundled SKILL.md body inside the same wrapper.
75
+ * This keeps the small host-adapted directive as the safety envelope while satisfying the
76
+ * bare-invocation contract: the model receives the full installed skill text for the selected mode.
77
+ */
78
+ export function loadDirectiveWithSkillBodyFrom(resolvedPath, openMarker, closeMarker, skillName, skillPath) {
79
+ const directive = loadDirectiveFrom(resolvedPath, openMarker, closeMarker);
80
+ const skillBody = readNormalizedBody(skillPath, `skill body ${skillName}`);
81
+ const bodyBlock = [
82
+ "",
83
+ "# Installed skill body",
84
+ "",
85
+ `<litcodex-skill-body name="${skillName}">`,
86
+ skillBody,
87
+ "</litcodex-skill-body>",
88
+ "",
89
+ ].join("\n");
90
+ return `${directive.slice(0, -closeMarker.length).trimEnd()}${bodyBlock}${closeMarker}`;
91
+ }
58
92
  /**
59
93
  * Read + normalize + validate the lit-loop directive at an explicit path. Test-only seam (S10
60
94
  * §Test plan) so corrupt / CRLF / missing-file cases can be exercised without swapping the bundled
@@ -16,4 +16,6 @@ export declare const LIT_RECAP_DIRECTIVE_MARKER: "<lit-recap-mode>";
16
16
  export declare const LIT_RECAP_DIRECTIVE_CLOSE: "</lit-recap-mode>";
17
17
  export declare const HYPERPLAN_DIRECTIVE_MARKER: "<hyperplan-mode>";
18
18
  export declare const HYPERPLAN_DIRECTIVE_CLOSE: "</hyperplan-mode>";
19
+ export declare const INIT_DEEP_DIRECTIVE_MARKER: "<init-deep-mode>";
20
+ export declare const INIT_DEEP_DIRECTIVE_CLOSE: "</init-deep-mode>";
19
21
  export type LitLoopDirectiveMarker = typeof LIT_LOOP_DIRECTIVE_MARKER;
@@ -22,3 +22,5 @@ export const LIT_RECAP_DIRECTIVE_MARKER = "<lit-recap-mode>";
22
22
  export const LIT_RECAP_DIRECTIVE_CLOSE = "</lit-recap-mode>";
23
23
  export const HYPERPLAN_DIRECTIVE_MARKER = "<hyperplan-mode>";
24
24
  export const HYPERPLAN_DIRECTIVE_CLOSE = "</hyperplan-mode>";
25
+ export const INIT_DEEP_DIRECTIVE_MARKER = "<init-deep-mode>";
26
+ export const INIT_DEEP_DIRECTIVE_CLOSE = "</init-deep-mode>";
@@ -1,6 +1,6 @@
1
1
  import type { LitTriggerToken } from "./trigger.js";
2
2
  /** Lit-family modes. Multiple tokens may map to one mode (lit/litcodex/lit-loop → lit-loop). */
3
- export type LitMode = "hyperplan" | "lit-loop" | "litwork" | "lit-plan" | "litgoal" | "review-work" | "litresearch" | "start-work" | "lit-recap";
3
+ export type LitMode = "hyperplan" | "init-deep" | "lit-loop" | "litwork" | "lit-plan" | "litgoal" | "review-work" | "litresearch" | "start-work" | "lit-recap";
4
4
  /** Per-mode routing spec: its marker pair (guard) + resolved directive path (loader). */
5
5
  export interface LitModeSpec {
6
6
  readonly mode: LitMode;
@@ -8,6 +8,10 @@ export interface LitModeSpec {
8
8
  readonly closeMarker: string;
9
9
  /** Absolute path to the mode's directive.md, resolved from this module. */
10
10
  readonly directivePath: string;
11
+ /** The bundled skill whose full SKILL.md body must be injected for this mode. */
12
+ readonly skillName: string;
13
+ /** Absolute path to the bundled skill body. */
14
+ readonly skillPath: string;
11
15
  }
12
16
  /** Token → mode spec. Frozen; the single source the hook router branches on. */
13
17
  export declare const MODE_BY_TOKEN: Readonly<Record<LitTriggerToken, LitModeSpec>>;
@@ -14,7 +14,7 @@
14
14
  //
15
15
  // Imports markers + the trigger token type only (no cycle: hook → modes → {markers, trigger}).
16
16
  import { fileURLToPath } from "node:url";
17
- import { HYPERPLAN_DIRECTIVE_CLOSE, HYPERPLAN_DIRECTIVE_MARKER, LIT_LOOP_DIRECTIVE_CLOSE, LIT_LOOP_DIRECTIVE_MARKER, LIT_PLAN_DIRECTIVE_CLOSE, LIT_PLAN_DIRECTIVE_MARKER, LIT_RECAP_DIRECTIVE_CLOSE, LIT_RECAP_DIRECTIVE_MARKER, LITGOAL_DIRECTIVE_CLOSE, LITGOAL_DIRECTIVE_MARKER, LITRESEARCH_DIRECTIVE_CLOSE, LITRESEARCH_DIRECTIVE_MARKER, LITWORK_DIRECTIVE_CLOSE, LITWORK_DIRECTIVE_MARKER, REVIEW_WORK_DIRECTIVE_CLOSE, REVIEW_WORK_DIRECTIVE_MARKER, START_WORK_DIRECTIVE_CLOSE, START_WORK_DIRECTIVE_MARKER, } from "./markers.js";
17
+ import { HYPERPLAN_DIRECTIVE_CLOSE, HYPERPLAN_DIRECTIVE_MARKER, INIT_DEEP_DIRECTIVE_CLOSE, INIT_DEEP_DIRECTIVE_MARKER, LIT_LOOP_DIRECTIVE_CLOSE, LIT_LOOP_DIRECTIVE_MARKER, LIT_PLAN_DIRECTIVE_CLOSE, LIT_PLAN_DIRECTIVE_MARKER, LIT_RECAP_DIRECTIVE_CLOSE, LIT_RECAP_DIRECTIVE_MARKER, LITGOAL_DIRECTIVE_CLOSE, LITGOAL_DIRECTIVE_MARKER, LITRESEARCH_DIRECTIVE_CLOSE, LITRESEARCH_DIRECTIVE_MARKER, LITWORK_DIRECTIVE_CLOSE, LITWORK_DIRECTIVE_MARKER, REVIEW_WORK_DIRECTIVE_CLOSE, REVIEW_WORK_DIRECTIVE_MARKER, START_WORK_DIRECTIVE_CLOSE, START_WORK_DIRECTIVE_MARKER, } from "./markers.js";
18
18
  /** Resolve a path relative to this module (percent-decoding, space/#/Hangul-safe). */
19
19
  function resolveFromHere(rel) {
20
20
  return fileURLToPath(new URL(rel, import.meta.url));
@@ -25,6 +25,8 @@ const LIT_LOOP_SPEC = Object.freeze({
25
25
  openMarker: LIT_LOOP_DIRECTIVE_MARKER,
26
26
  closeMarker: LIT_LOOP_DIRECTIVE_CLOSE,
27
27
  directivePath: resolveFromHere("../directive.md"),
28
+ skillName: "lit-loop",
29
+ skillPath: resolveFromHere("../../../skills/lit-loop/SKILL.md"),
28
30
  });
29
31
  /** Token → mode spec. Frozen; the single source the hook router branches on. */
30
32
  export const MODE_BY_TOKEN = Object.freeze({
@@ -33,6 +35,16 @@ export const MODE_BY_TOKEN = Object.freeze({
33
35
  openMarker: HYPERPLAN_DIRECTIVE_MARKER,
34
36
  closeMarker: HYPERPLAN_DIRECTIVE_CLOSE,
35
37
  directivePath: resolveFromHere("../directives/hyperplan.md"),
38
+ skillName: "hyperplan",
39
+ skillPath: resolveFromHere("../../../skills/hyperplan/SKILL.md"),
40
+ }),
41
+ "init-deep": Object.freeze({
42
+ mode: "init-deep",
43
+ openMarker: INIT_DEEP_DIRECTIVE_MARKER,
44
+ closeMarker: INIT_DEEP_DIRECTIVE_CLOSE,
45
+ directivePath: resolveFromHere("../directives/init-deep.md"),
46
+ skillName: "init-deep",
47
+ skillPath: resolveFromHere("../../../skills/init-deep/SKILL.md"),
36
48
  }),
37
49
  "lit-loop": LIT_LOOP_SPEC,
38
50
  litcodex: LIT_LOOP_SPEC,
@@ -42,42 +54,56 @@ export const MODE_BY_TOKEN = Object.freeze({
42
54
  openMarker: LITWORK_DIRECTIVE_MARKER,
43
55
  closeMarker: LITWORK_DIRECTIVE_CLOSE,
44
56
  directivePath: resolveFromHere("../directives/litwork.md"),
57
+ skillName: "litwork",
58
+ skillPath: resolveFromHere("../../../skills/litwork/SKILL.md"),
45
59
  }),
46
60
  "lit-plan": Object.freeze({
47
61
  mode: "lit-plan",
48
62
  openMarker: LIT_PLAN_DIRECTIVE_MARKER,
49
63
  closeMarker: LIT_PLAN_DIRECTIVE_CLOSE,
50
64
  directivePath: resolveFromHere("../directives/lit-plan.md"),
65
+ skillName: "lit-plan",
66
+ skillPath: resolveFromHere("../../../skills/lit-plan/SKILL.md"),
51
67
  }),
52
68
  litgoal: Object.freeze({
53
69
  mode: "litgoal",
54
70
  openMarker: LITGOAL_DIRECTIVE_MARKER,
55
71
  closeMarker: LITGOAL_DIRECTIVE_CLOSE,
56
72
  directivePath: resolveFromHere("../directives/litgoal.md"),
73
+ skillName: "litgoal",
74
+ skillPath: resolveFromHere("../../../skills/litgoal/SKILL.md"),
57
75
  }),
58
76
  "review-work": Object.freeze({
59
77
  mode: "review-work",
60
78
  openMarker: REVIEW_WORK_DIRECTIVE_MARKER,
61
79
  closeMarker: REVIEW_WORK_DIRECTIVE_CLOSE,
62
80
  directivePath: resolveFromHere("../directives/review-work.md"),
81
+ skillName: "review-work",
82
+ skillPath: resolveFromHere("../../../skills/review-work/SKILL.md"),
63
83
  }),
64
84
  litresearch: Object.freeze({
65
85
  mode: "litresearch",
66
86
  openMarker: LITRESEARCH_DIRECTIVE_MARKER,
67
87
  closeMarker: LITRESEARCH_DIRECTIVE_CLOSE,
68
88
  directivePath: resolveFromHere("../directives/litresearch.md"),
89
+ skillName: "litresearch",
90
+ skillPath: resolveFromHere("../../../skills/litresearch/SKILL.md"),
69
91
  }),
70
92
  "start-work": Object.freeze({
71
93
  mode: "start-work",
72
94
  openMarker: START_WORK_DIRECTIVE_MARKER,
73
95
  closeMarker: START_WORK_DIRECTIVE_CLOSE,
74
96
  directivePath: resolveFromHere("../directives/start-work.md"),
97
+ skillName: "start-work",
98
+ skillPath: resolveFromHere("../../../skills/start-work/SKILL.md"),
75
99
  }),
76
100
  "lit-recap": Object.freeze({
77
101
  mode: "lit-recap",
78
102
  openMarker: LIT_RECAP_DIRECTIVE_MARKER,
79
103
  closeMarker: LIT_RECAP_DIRECTIVE_CLOSE,
80
104
  directivePath: resolveFromHere("../directives/lit-recap.md"),
105
+ skillName: "lit-recap",
106
+ skillPath: resolveFromHere("../../../skills/lit-recap/SKILL.md"),
81
107
  }),
82
108
  });
83
109
  /** The mode spec for a matched token. Total over the token union (every token has a spec). */
@@ -1,3 +1,4 @@
1
1
  import type { LitTriggerToken } from "./trigger.js";
2
2
  export declare function isCodexSkillMentionToken(prompt: string, tokenIndex: number): boolean;
3
3
  export declare function scopedTokenForBareLit(prompt: string, tokenIndex: number): LitTriggerToken | null;
4
+ export declare function suppressesBareLitAfterCodexSkillMention(prompt: string, tokenIndex: number): boolean;
@@ -13,19 +13,28 @@ export function isCodexSkillMentionToken(prompt, tokenIndex) {
13
13
  return mention.startsWith("$") && mention.includes(":") && tokenIndex > start;
14
14
  }
15
15
  export function scopedTokenForBareLit(prompt, tokenIndex) {
16
- let scopedToken = null;
16
+ const skillName = nearestLitcodexSkillNameBefore(prompt, tokenIndex);
17
+ if (skillName === null || suppressesBareLitAfterCodexSkillMention(prompt, tokenIndex)) {
18
+ return null;
19
+ }
20
+ return tokenForSkillName(skillName);
21
+ }
22
+ export function suppressesBareLitAfterCodexSkillMention(prompt, tokenIndex) {
23
+ return nearestLitcodexSkillNameBefore(prompt, tokenIndex) === "start-work";
24
+ }
25
+ function nearestLitcodexSkillNameBefore(prompt, tokenIndex) {
26
+ let scopedSkillName = null;
17
27
  for (const match of prompt.slice(0, tokenIndex).matchAll(CODEX_SKILL_MENTION_PATTERN)) {
18
28
  const pluginName = match[1]?.toLowerCase();
19
29
  const skillName = match[2]?.toLowerCase();
20
30
  if (pluginName !== LITCODEX_PLUGIN_NAME || skillName === undefined) {
21
31
  continue;
22
32
  }
23
- const token = tokenForSkillName(skillName);
24
- if (token !== null) {
25
- scopedToken = token;
33
+ if (tokenForSkillName(skillName) !== null) {
34
+ scopedSkillName = skillName;
26
35
  }
27
36
  }
28
- return scopedToken;
37
+ return scopedSkillName;
29
38
  }
30
39
  function tokenForSkillName(skillName) {
31
40
  switch (skillName) {
@@ -41,6 +50,8 @@ function tokenForSkillName(skillName) {
41
50
  return "litresearch";
42
51
  case "lit-recap":
43
52
  return "lit-recap";
53
+ case "init-deep":
54
+ return "init-deep";
44
55
  case "start-work":
45
56
  return "start-work";
46
57
  case "review-work":
@@ -1,5 +1,5 @@
1
1
  /** The accepted bounded lit-family tokens, longest-first (ordering is load-bearing — see below). */
2
- export type LitTriggerToken = "hyperplan" | "start-work" | "review-work" | "litresearch" | "lit-recap" | "lit-loop" | "lit-plan" | "litcodex" | "litgoal" | "litwork" | "lit";
2
+ export type LitTriggerToken = "hyperplan" | "init-deep" | "start-work" | "review-work" | "litresearch" | "lit-recap" | "lit-loop" | "lit-plan" | "litcodex" | "litgoal" | "litwork" | "lit";
3
3
  /**
4
4
  * Frozen tuple of the accepted tokens in match-priority (longest-first) order.
5
5
  * Exported so tests and the mode router (modes.ts) can enumerate without re-deriving.
@@ -14,7 +14,7 @@ export declare const LIT_TRIGGER_TOKENS: readonly LitTriggerToken[];
14
14
  *
15
15
  * MUST NOT carry the /g or /y flag: a global regex retains `lastIndex` between calls and would
16
16
  * make `.test()` return alternating results for the same input. Longest-first alternation
17
- * (`hyperplan|review-work|litresearch|lit-recap|lit-loop|lit-plan|litcodex|litrecap|litgoal|litwork|recap|리캡|lit`)
17
+ * (`hyperplan|init-deep|start-work|review-work|litresearch|lit-recap|lit-loop|lit-plan|litcodex|litrecap|litgoal|litwork|recap|리캡|lit`)
18
18
  * guarantees a longer family token wins over a bare `lit` at the same start; the trailing-`-`
19
19
  * lookahead means `lit work` (space) is a bare `lit` while `litwork` (glued) is the work mode.
20
20
  * The `litrecap` / `recap` / `리캡` alternatives are ROUTING ALIASES normalized to the canonical
@@ -3,8 +3,8 @@
3
3
  // Single source of truth for deciding whether a user prompt activates the LitCodex `lit-loop`
4
4
  // workflow. Pure, side-effect-free, Unicode-aware. Accepts the bounded tokens `lit`, `lit-loop`,
5
5
  // and `litcodex` (case-insensitive), plus sibling mode tokens that are safe to inject directly.
6
- // `start-work` is intentionally NOT a direct token: bare `start-work ...` is a Codex skill
7
- // invocation surface, while natural `lit start work ...` still routes to the safe blocked handoff.
6
+ // Bare `start-work ...` routes to the safe blocked handoff with the installed skill body, while
7
+ // scoped Codex skill mentions such as `$litcodex:start-work ...` stay on the native skill surface.
8
8
  // Recap aliases (`litrecap` / `recap` / `리캡`) normalize to the single `lit-recap` token. Rejects
9
9
  // every substring collision (`split`, `literal`, `litmus`, `lithium`, `glitter`, `flit`, `slit`,
10
10
  // `litter`, `recapture`, …) while respecting Korean (Hangul) and English boundaries.
@@ -12,13 +12,14 @@
12
12
  // This module imports NOTHING from `state-store`, `directive`, `guards`, `markers`, or
13
13
  // `codex-hook` (one-way: hook → trigger, never the reverse). It reads no files, touches no state,
14
14
  // emits no hook JSON, and never mutates the prompt. (A3 C9 flat layout; A2 §2.1 export surface.)
15
- import { isCodexSkillMentionToken, scopedTokenForBareLit } from "./skill-mention-scope.js";
15
+ import { isCodexSkillMentionToken, scopedTokenForBareLit, suppressesBareLitAfterCodexSkillMention, } from "./skill-mention-scope.js";
16
16
  /**
17
17
  * Frozen tuple of the accepted tokens in match-priority (longest-first) order.
18
18
  * Exported so tests and the mode router (modes.ts) can enumerate without re-deriving.
19
19
  */
20
20
  export const LIT_TRIGGER_TOKENS = Object.freeze([
21
21
  "hyperplan",
22
+ "init-deep",
22
23
  "start-work",
23
24
  "review-work",
24
25
  "litresearch",
@@ -39,14 +40,14 @@ export const LIT_TRIGGER_TOKENS = Object.freeze([
39
40
  *
40
41
  * MUST NOT carry the /g or /y flag: a global regex retains `lastIndex` between calls and would
41
42
  * make `.test()` return alternating results for the same input. Longest-first alternation
42
- * (`hyperplan|review-work|litresearch|lit-recap|lit-loop|lit-plan|litcodex|litrecap|litgoal|litwork|recap|리캡|lit`)
43
+ * (`hyperplan|init-deep|start-work|review-work|litresearch|lit-recap|lit-loop|lit-plan|litcodex|litrecap|litgoal|litwork|recap|리캡|lit`)
43
44
  * guarantees a longer family token wins over a bare `lit` at the same start; the trailing-`-`
44
45
  * lookahead means `lit work` (space) is a bare `lit` while `litwork` (glued) is the work mode.
45
46
  * The `litrecap` / `recap` / `리캡` alternatives are ROUTING ALIASES normalized to the canonical
46
47
  * `lit-recap` token by `matchLitTrigger` (they are not members of the token union).
47
48
  * No nested quantifiers / no backreferences ⇒ ReDoS-free.
48
49
  */
49
- export const LIT_TRIGGER_PATTERN = /(?:^|[^\p{L}\p{N}_])(hyperplan|review-work|litresearch|lit-recap|lit-loop|lit-plan|litcodex|litrecap|litgoal|litwork|recap|리캡|lit)(?![\p{L}\p{N}_-])/iu;
50
+ export const LIT_TRIGGER_PATTERN = /(?:^|[^\p{L}\p{N}_])(hyperplan|init-deep|start-work|review-work|litresearch|lit-recap|lit-loop|lit-plan|litcodex|litrecap|litgoal|litwork|recap|리캡|lit)(?![\p{L}\p{N}_-])/iu;
50
51
  const NOT_A_STRING = "lit trigger: prompt must be a string";
51
52
  /**
52
53
  * Returns true iff `prompt` contains at least one bounded lit trigger.
@@ -72,11 +73,8 @@ export function matchLitTrigger(prompt) {
72
73
  if (typeof prompt !== "string") {
73
74
  throw new TypeError(NOT_A_STRING);
74
75
  }
75
- if (isLeadingStartWorkInvocation(prompt)) {
76
- return null;
77
- }
78
76
  const searchable = maskMarkdownCode(prompt);
79
- const scan = /(?:^|[^\p{L}\p{N}_])(hyperplan|review-work|litresearch|lit-recap|lit-loop|lit-plan|litcodex|litrecap|litgoal|litwork|recap|리캡|lit)(?![\p{L}\p{N}_-])/giu;
77
+ const scan = /(?:^|[^\p{L}\p{N}_])(hyperplan|init-deep|start-work|review-work|litresearch|lit-recap|lit-loop|lit-plan|litcodex|litrecap|litgoal|litwork|recap|리캡|lit)(?![\p{L}\p{N}_-])/giu;
80
78
  for (const m of searchable.matchAll(scan)) {
81
79
  const raw = m[1];
82
80
  if (raw === undefined) {
@@ -101,6 +99,9 @@ export function matchLitTrigger(prompt) {
101
99
  if (phrase !== null) {
102
100
  return phrase;
103
101
  }
102
+ if (raw.toLowerCase() === "lit" && suppressesBareLitAfterCodexSkillMention(prompt, index)) {
103
+ continue;
104
+ }
104
105
  const scopedToken = raw.toLowerCase() === "lit" ? scopedTokenForBareLit(prompt, index) : null;
105
106
  if (scopedToken !== null) {
106
107
  return { token: scopedToken, raw: prompt.slice(index, index + raw.length), index };
@@ -109,13 +110,10 @@ export function matchLitTrigger(prompt) {
109
110
  }
110
111
  return null;
111
112
  }
112
- function isLeadingStartWorkInvocation(prompt) {
113
- return /^(?:\$litcodex:|\$)?start-work(?:$|\s)/iu.test(prompt.trimStart());
114
- }
115
113
  function naturalPhraseAfterLit(prompt, searchable, index, rawLength) {
116
114
  const start = index + rawLength;
117
115
  const rest = searchable.slice(start);
118
- const m = /^(\s+)(start\s+work|hyperplan|plan|review|research|goal|recap)(?![\p{L}\p{N}_-])/iu.exec(rest);
116
+ const m = /^(\s+)(start\s+work|hyperplan|init-deep|plan|review|research|goal|recap)(?![\p{L}\p{N}_-])/iu.exec(rest);
119
117
  if (m === null || m[1] === undefined || m[2] === undefined) {
120
118
  return null;
121
119
  }
@@ -123,6 +121,7 @@ function naturalPhraseAfterLit(prompt, searchable, index, rawLength) {
123
121
  const tokenByPhrase = {
124
122
  "start work": "start-work",
125
123
  hyperplan: "hyperplan",
124
+ "init-deep": "init-deep",
126
125
  plan: "lit-plan",
127
126
  review: "review-work",
128
127
  research: "litresearch",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litcodex/lit-loop",
3
- "version": "0.3.21",
3
+ "version": "0.3.22",
4
4
  "description": "LitCodex Lit-Loop runtime: durable repo-native multi-goal orchestration with embedded success criteria and observable evidence audit.",
5
5
  "type": "module",
6
6
  "bin": {
package/package.json CHANGED
@@ -1,23 +1,44 @@
1
1
  {
2
2
  "name": "litcodex-ai",
3
- "version": "0.3.21",
3
+ "version": "0.3.22",
4
4
  "description": "Codex loop harness installer. Run `npx litcodex-ai install` to set up the LitCodex Codex platform: the bare `lit` hook and the durable lit-loop runtime.",
5
- "keywords": ["codex", "litcodex", "lit-loop", "ai-agents", "orchestration"],
5
+ "keywords": [
6
+ "codex",
7
+ "litcodex",
8
+ "lit-loop",
9
+ "ai-agents",
10
+ "orchestration"
11
+ ],
6
12
  "author": "LitCodex Authors",
7
13
  "license": "MIT",
8
- "publishConfig": { "access": "public" },
9
- "repository": { "type": "git", "url": "git+https://github.com/wjgoarxiv/litcodex.git" },
10
- "bugs": { "url": "https://github.com/wjgoarxiv/litcodex/issues" },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/wjgoarxiv/litcodex.git"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/wjgoarxiv/litcodex/issues"
23
+ },
11
24
  "homepage": "https://github.com/wjgoarxiv/litcodex#readme",
12
25
  "type": "module",
13
26
  "bin": {
14
27
  "litcodex": "bin/litcodex.js"
15
28
  },
16
- "files": ["bin", "dist", "model-catalog.json", "README.md", "LICENSE"],
29
+ "files": [
30
+ "bin",
31
+ "dist",
32
+ "model-catalog.json",
33
+ "README.md",
34
+ "LICENSE"
35
+ ],
17
36
  "dependencies": {
18
- "@litcodex/lit-loop": "0.3.21"
37
+ "@litcodex/lit-loop": "0.3.22"
19
38
  },
20
- "bundledDependencies": ["@litcodex/lit-loop"],
39
+ "bundledDependencies": [
40
+ "@litcodex/lit-loop"
41
+ ],
21
42
  "scripts": {
22
43
  "build": "tsc -p tsconfig.build.json",
23
44
  "typecheck": "tsc --noEmit",