@gajae-code/coding-agent 0.2.3 → 0.2.5

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.
Files changed (197) hide show
  1. package/CHANGELOG.md +34 -8600
  2. package/README.md +1 -1
  3. package/dist/types/async/job-manager.d.ts +61 -0
  4. package/dist/types/cli/update-cli.d.ts +3 -0
  5. package/dist/types/config/settings-schema.d.ts +27 -3
  6. package/dist/types/config/settings.d.ts +1 -1
  7. package/dist/types/defaults/gjc-defaults.d.ts +19 -6
  8. package/dist/types/discovery/helpers.d.ts +1 -0
  9. package/dist/types/exec/bash-executor.d.ts +8 -1
  10. package/dist/types/gjc-runtime/restricted-role-agent-bash.d.ts +2 -0
  11. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -1
  12. package/dist/types/modes/components/settings-selector.d.ts +4 -0
  13. package/dist/types/modes/components/skill-hud/render.d.ts +1 -1
  14. package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
  15. package/dist/types/modes/interactive-mode.d.ts +2 -0
  16. package/dist/types/modes/theme/defaults/index.d.ts +45 -9351
  17. package/dist/types/modes/theme/theme.d.ts +6 -5
  18. package/dist/types/modes/types.d.ts +2 -0
  19. package/dist/types/sdk.d.ts +2 -0
  20. package/dist/types/session/streaming-output.d.ts +11 -0
  21. package/dist/types/skill-state/active-state.d.ts +1 -0
  22. package/dist/types/task/types.d.ts +1 -0
  23. package/dist/types/tools/bash-allowed-prefixes.d.ts +5 -0
  24. package/dist/types/tools/bash.d.ts +24 -0
  25. package/dist/types/tools/cron.d.ts +110 -0
  26. package/dist/types/tools/index.d.ts +4 -0
  27. package/dist/types/tools/monitor.d.ts +54 -0
  28. package/dist/types/web/search/index.d.ts +1 -0
  29. package/dist/types/web/search/provider.d.ts +11 -4
  30. package/dist/types/web/search/providers/duckduckgo.d.ts +57 -0
  31. package/dist/types/web/search/types.d.ts +1 -1
  32. package/package.json +7 -7
  33. package/src/async/job-manager.ts +224 -0
  34. package/src/cli/agents-cli.ts +3 -0
  35. package/src/cli/update-cli.ts +67 -16
  36. package/src/config/settings-schema.ts +30 -2
  37. package/src/config/settings.ts +44 -7
  38. package/src/defaults/gjc/skills/deep-interview/SKILL.md +48 -6
  39. package/src/defaults/gjc/skills/deep-interview/auto-answer-uncertain.md +37 -0
  40. package/src/defaults/gjc/skills/deep-interview/auto-research-greenfield.md +42 -0
  41. package/src/defaults/gjc/skills/ralplan/SKILL.md +8 -4
  42. package/src/defaults/gjc/skills/ultragoal/SKILL.md +9 -6
  43. package/src/defaults/gjc-defaults.ts +68 -16
  44. package/src/discovery/helpers.ts +5 -0
  45. package/src/eval/js/shared/rewrite-imports.ts +1 -2
  46. package/src/exec/bash-executor.ts +20 -9
  47. package/src/gjc-runtime/deep-interview-runtime.ts +44 -0
  48. package/src/gjc-runtime/ralplan-runtime.ts +2 -0
  49. package/src/gjc-runtime/restricted-role-agent-bash.ts +5 -0
  50. package/src/gjc-runtime/state-runtime.ts +3 -2
  51. package/src/goals/tools/goal-tool.ts +5 -1
  52. package/src/hooks/skill-state.ts +1 -1
  53. package/src/internal-urls/docs-index.generated.ts +8 -4
  54. package/src/lsp/render.ts +1 -1
  55. package/src/memories/index.ts +5 -4
  56. package/src/modes/acp/acp-agent.ts +1 -1
  57. package/src/modes/acp/acp-client-bridge.ts +1 -1
  58. package/src/modes/components/agent-dashboard.ts +1 -1
  59. package/src/modes/components/diff.ts +2 -2
  60. package/src/modes/components/settings-selector.ts +25 -14
  61. package/src/modes/components/skill-hud/render.ts +7 -2
  62. package/src/modes/controllers/command-controller.ts +1 -1
  63. package/src/modes/controllers/input-controller.ts +10 -2
  64. package/src/modes/controllers/selector-controller.ts +67 -0
  65. package/src/modes/interactive-mode.ts +34 -3
  66. package/src/modes/theme/defaults/blue-crab.json +126 -0
  67. package/src/modes/theme/defaults/index.ts +2 -196
  68. package/src/modes/theme/theme.ts +75 -36
  69. package/src/modes/types.ts +2 -0
  70. package/src/prompts/agents/architect.md +5 -1
  71. package/src/prompts/agents/critic.md +5 -1
  72. package/src/prompts/agents/frontmatter.md +1 -0
  73. package/src/prompts/agents/planner.md +5 -1
  74. package/src/prompts/memories/unavailable.md +9 -0
  75. package/src/prompts/tools/bash.md +9 -0
  76. package/src/prompts/tools/cron.md +25 -0
  77. package/src/prompts/tools/monitor.md +30 -0
  78. package/src/runtime-mcp/oauth-flow.ts +4 -2
  79. package/src/sdk.ts +7 -0
  80. package/src/session/agent-session.ts +16 -5
  81. package/src/session/streaming-output.ts +21 -0
  82. package/src/skill-state/active-state.ts +163 -12
  83. package/src/slash-commands/builtin-registry.ts +11 -1
  84. package/src/task/agents.ts +1 -0
  85. package/src/task/executor.ts +1 -0
  86. package/src/task/types.ts +1 -0
  87. package/src/tools/bash-allowed-prefixes.ts +169 -0
  88. package/src/tools/bash.ts +190 -29
  89. package/src/tools/browser/tab-worker.ts +1 -1
  90. package/src/tools/cron.ts +665 -0
  91. package/src/tools/index.ts +20 -2
  92. package/src/tools/monitor.ts +136 -0
  93. package/src/vim/engine.ts +3 -3
  94. package/src/web/search/index.ts +31 -18
  95. package/src/web/search/provider.ts +57 -12
  96. package/src/web/search/providers/duckduckgo.ts +279 -0
  97. package/src/web/search/types.ts +2 -0
  98. package/src/modes/theme/dark.json +0 -95
  99. package/src/modes/theme/defaults/alabaster.json +0 -93
  100. package/src/modes/theme/defaults/amethyst.json +0 -96
  101. package/src/modes/theme/defaults/anthracite.json +0 -93
  102. package/src/modes/theme/defaults/basalt.json +0 -91
  103. package/src/modes/theme/defaults/birch.json +0 -95
  104. package/src/modes/theme/defaults/dark-abyss.json +0 -91
  105. package/src/modes/theme/defaults/dark-arctic.json +0 -104
  106. package/src/modes/theme/defaults/dark-aurora.json +0 -95
  107. package/src/modes/theme/defaults/dark-catppuccin.json +0 -107
  108. package/src/modes/theme/defaults/dark-cavern.json +0 -91
  109. package/src/modes/theme/defaults/dark-copper.json +0 -95
  110. package/src/modes/theme/defaults/dark-cosmos.json +0 -90
  111. package/src/modes/theme/defaults/dark-cyberpunk.json +0 -102
  112. package/src/modes/theme/defaults/dark-dracula.json +0 -98
  113. package/src/modes/theme/defaults/dark-eclipse.json +0 -91
  114. package/src/modes/theme/defaults/dark-ember.json +0 -95
  115. package/src/modes/theme/defaults/dark-equinox.json +0 -90
  116. package/src/modes/theme/defaults/dark-forest.json +0 -96
  117. package/src/modes/theme/defaults/dark-github.json +0 -105
  118. package/src/modes/theme/defaults/dark-gruvbox.json +0 -112
  119. package/src/modes/theme/defaults/dark-lavender.json +0 -95
  120. package/src/modes/theme/defaults/dark-lunar.json +0 -89
  121. package/src/modes/theme/defaults/dark-midnight.json +0 -95
  122. package/src/modes/theme/defaults/dark-monochrome.json +0 -94
  123. package/src/modes/theme/defaults/dark-monokai.json +0 -98
  124. package/src/modes/theme/defaults/dark-nebula.json +0 -90
  125. package/src/modes/theme/defaults/dark-nord.json +0 -97
  126. package/src/modes/theme/defaults/dark-ocean.json +0 -101
  127. package/src/modes/theme/defaults/dark-one.json +0 -100
  128. package/src/modes/theme/defaults/dark-poimandres.json +0 -141
  129. package/src/modes/theme/defaults/dark-rainforest.json +0 -91
  130. package/src/modes/theme/defaults/dark-reef.json +0 -91
  131. package/src/modes/theme/defaults/dark-retro.json +0 -92
  132. package/src/modes/theme/defaults/dark-rose-pine.json +0 -96
  133. package/src/modes/theme/defaults/dark-sakura.json +0 -95
  134. package/src/modes/theme/defaults/dark-slate.json +0 -95
  135. package/src/modes/theme/defaults/dark-solarized.json +0 -97
  136. package/src/modes/theme/defaults/dark-solstice.json +0 -90
  137. package/src/modes/theme/defaults/dark-starfall.json +0 -91
  138. package/src/modes/theme/defaults/dark-sunset.json +0 -99
  139. package/src/modes/theme/defaults/dark-swamp.json +0 -90
  140. package/src/modes/theme/defaults/dark-synthwave.json +0 -103
  141. package/src/modes/theme/defaults/dark-taiga.json +0 -91
  142. package/src/modes/theme/defaults/dark-terminal.json +0 -95
  143. package/src/modes/theme/defaults/dark-tokyo-night.json +0 -101
  144. package/src/modes/theme/defaults/dark-tundra.json +0 -91
  145. package/src/modes/theme/defaults/dark-twilight.json +0 -91
  146. package/src/modes/theme/defaults/dark-volcanic.json +0 -91
  147. package/src/modes/theme/defaults/graphite.json +0 -92
  148. package/src/modes/theme/defaults/light-arctic.json +0 -107
  149. package/src/modes/theme/defaults/light-aurora-day.json +0 -91
  150. package/src/modes/theme/defaults/light-canyon.json +0 -91
  151. package/src/modes/theme/defaults/light-catppuccin.json +0 -106
  152. package/src/modes/theme/defaults/light-cirrus.json +0 -90
  153. package/src/modes/theme/defaults/light-coral.json +0 -95
  154. package/src/modes/theme/defaults/light-cyberpunk.json +0 -96
  155. package/src/modes/theme/defaults/light-dawn.json +0 -90
  156. package/src/modes/theme/defaults/light-dunes.json +0 -91
  157. package/src/modes/theme/defaults/light-eucalyptus.json +0 -95
  158. package/src/modes/theme/defaults/light-forest.json +0 -100
  159. package/src/modes/theme/defaults/light-frost.json +0 -95
  160. package/src/modes/theme/defaults/light-github.json +0 -115
  161. package/src/modes/theme/defaults/light-glacier.json +0 -91
  162. package/src/modes/theme/defaults/light-gruvbox.json +0 -108
  163. package/src/modes/theme/defaults/light-haze.json +0 -90
  164. package/src/modes/theme/defaults/light-honeycomb.json +0 -95
  165. package/src/modes/theme/defaults/light-lagoon.json +0 -91
  166. package/src/modes/theme/defaults/light-lavender.json +0 -95
  167. package/src/modes/theme/defaults/light-meadow.json +0 -91
  168. package/src/modes/theme/defaults/light-mint.json +0 -95
  169. package/src/modes/theme/defaults/light-monochrome.json +0 -101
  170. package/src/modes/theme/defaults/light-ocean.json +0 -99
  171. package/src/modes/theme/defaults/light-one.json +0 -99
  172. package/src/modes/theme/defaults/light-opal.json +0 -91
  173. package/src/modes/theme/defaults/light-orchard.json +0 -91
  174. package/src/modes/theme/defaults/light-paper.json +0 -95
  175. package/src/modes/theme/defaults/light-poimandres.json +0 -141
  176. package/src/modes/theme/defaults/light-prism.json +0 -90
  177. package/src/modes/theme/defaults/light-retro.json +0 -98
  178. package/src/modes/theme/defaults/light-sand.json +0 -95
  179. package/src/modes/theme/defaults/light-savanna.json +0 -91
  180. package/src/modes/theme/defaults/light-solarized.json +0 -102
  181. package/src/modes/theme/defaults/light-soleil.json +0 -90
  182. package/src/modes/theme/defaults/light-sunset.json +0 -99
  183. package/src/modes/theme/defaults/light-synthwave.json +0 -98
  184. package/src/modes/theme/defaults/light-tokyo-night.json +0 -111
  185. package/src/modes/theme/defaults/light-wetland.json +0 -91
  186. package/src/modes/theme/defaults/light-zenith.json +0 -89
  187. package/src/modes/theme/defaults/limestone.json +0 -94
  188. package/src/modes/theme/defaults/mahogany.json +0 -97
  189. package/src/modes/theme/defaults/marble.json +0 -93
  190. package/src/modes/theme/defaults/obsidian.json +0 -91
  191. package/src/modes/theme/defaults/onyx.json +0 -91
  192. package/src/modes/theme/defaults/pearl.json +0 -93
  193. package/src/modes/theme/defaults/porcelain.json +0 -91
  194. package/src/modes/theme/defaults/quartz.json +0 -96
  195. package/src/modes/theme/defaults/sandstone.json +0 -95
  196. package/src/modes/theme/defaults/titanium.json +0 -90
  197. package/src/modes/theme/light.json +0 -93
@@ -131,9 +131,17 @@ interface ResolvedDeepInterviewArgs {
131
131
  thresholdSource: string;
132
132
  sessionId?: string;
133
133
  idea: string;
134
+ language?: DeepInterviewLanguagePreference;
134
135
  json: boolean;
135
136
  }
136
137
 
138
+ interface DeepInterviewLanguagePreference {
139
+ code: "en" | "ko";
140
+ label: "English" | "Korean";
141
+ source: "explicit-user-request" | "initial-idea";
142
+ instruction: string;
143
+ }
144
+
137
145
  export interface ResolvedDeepInterviewSpecWriteArgs {
138
146
  stage: "final";
139
147
  slug: string;
@@ -205,6 +213,35 @@ async function resolveConfiguredAmbiguityThreshold(
205
213
  return await readSettingsAmbiguityThreshold(userSettings);
206
214
  }
207
215
 
216
+ function englishLanguagePreference(): DeepInterviewLanguagePreference {
217
+ return {
218
+ code: "en",
219
+ label: "English",
220
+ source: "explicit-user-request",
221
+ instruction:
222
+ "Ask every user-facing deep-interview question in English because the user explicitly requested English.",
223
+ };
224
+ }
225
+
226
+ function resolveDeepInterviewLanguagePreference(idea: string): DeepInterviewLanguagePreference | undefined {
227
+ if (/\b(?:answer|ask|respond|reply|write|use|speak)\s+(?:only\s+)?in\s+English\b/i.test(idea)) {
228
+ return englishLanguagePreference();
229
+ }
230
+ if (/(?:영어로|영문으로|영어\s*(?:질문|답변|응답)|English\s+only)/i.test(idea)) {
231
+ return englishLanguagePreference();
232
+ }
233
+ if (/\p{Script=Hangul}/u.test(idea)) {
234
+ return {
235
+ code: "ko",
236
+ label: "Korean",
237
+ source: "initial-idea",
238
+ instruction:
239
+ "Ask every user-facing deep-interview question in Korean unless the user explicitly requests another language.",
240
+ };
241
+ }
242
+ return undefined;
243
+ }
244
+
208
245
  function isDeepInterviewSpecWriteInvocation(args: readonly string[]): boolean {
209
246
  return hasFlag(args, "--write");
210
247
  }
@@ -327,6 +364,7 @@ async function resolveDeepInterviewArgs(args: readonly string[], cwd: string): P
327
364
  thresholdSource,
328
365
  sessionId,
329
366
  idea,
367
+ language: resolveDeepInterviewLanguagePreference(idea),
330
368
  json: hasFlag(args, "--json"),
331
369
  };
332
370
  }
@@ -405,6 +443,10 @@ async function seedDeepInterviewState(cwd: string, resolved: ResolvedDeepIntervi
405
443
  },
406
444
  updated_at: now,
407
445
  };
446
+ if (resolved.language) {
447
+ payload.language = resolved.language;
448
+ (payload.state as Record<string, unknown>).language = resolved.language;
449
+ }
408
450
  if (resolved.sessionId) payload.session_id = resolved.sessionId;
409
451
  await fs.writeFile(statePath, `${JSON.stringify(payload, null, 2)}\n`);
410
452
  return statePath;
@@ -469,6 +511,7 @@ async function handleSpecWrite(args: readonly string[], cwd: string): Promise<De
469
511
 
470
512
  const handoffArgs = ["handoff", "--mode", "deep-interview", "--to", "ralplan", "--json"];
471
513
  if (resolved.sessionId) handoffArgs.push("--session-id", resolved.sessionId);
514
+ else handoffArgs.push("--session-id", "");
472
515
  const handoffResult = await runNativeStateCommand(handoffArgs, cwd);
473
516
  if (handoffResult.status !== 0) {
474
517
  throw new DeepInterviewCommandError(
@@ -527,6 +570,7 @@ export async function runNativeDeepInterviewCommand(
527
570
  threshold: resolved.threshold,
528
571
  threshold_source: resolved.thresholdSource,
529
572
  idea: resolved.idea,
573
+ language: resolved.language,
530
574
  state_path: statePath,
531
575
  handoff: "Run `/skill:deep-interview` inside the GJC agent to drive the Socratic interview loop.",
532
576
  };
@@ -3,6 +3,7 @@ import * as fs from "node:fs/promises";
3
3
  import * as path from "node:path";
4
4
  import { syncSkillActiveState } from "../skill-state/active-state";
5
5
  import { buildRalplanHudSummary } from "../skill-state/workflow-hud";
6
+ import { isRestrictedRoleAgentBash } from "./restricted-role-agent-bash";
6
7
 
7
8
  /**
8
9
  * Native implementation of `gjc ralplan`.
@@ -110,6 +111,7 @@ function defaultRunId(now: Date = new Date()): string {
110
111
  }
111
112
 
112
113
  async function resolveArtifactContent(rawArtifact: string, cwd: string): Promise<string> {
114
+ if (isRestrictedRoleAgentBash()) return rawArtifact;
113
115
  const candidate = path.isAbsolute(rawArtifact) ? rawArtifact : path.resolve(cwd, rawArtifact);
114
116
  try {
115
117
  const stat = await fs.stat(candidate);
@@ -0,0 +1,5 @@
1
+ export const GJC_RESTRICTED_ROLE_AGENT_BASH_ENV = "GJC_RESTRICTED_ROLE_AGENT_BASH";
2
+
3
+ export function isRestrictedRoleAgentBash(): boolean {
4
+ return process.env[GJC_RESTRICTED_ROLE_AGENT_BASH_ENV] === "1";
5
+ }
@@ -171,16 +171,17 @@ async function resolveSelectors(
171
171
  }
172
172
  if (mode) assertKnownMode(mode);
173
173
 
174
+ const explicitSessionId = flagValue(args, "--session-id");
174
175
  // Session-id resolution order: explicit --session-id flag, then payload
175
176
  // session_id, then GJC_SESSION_ID env var (set by AgentSession.sdk for
176
177
  // agent-initiated CLI invocations). The env-var default keeps shell
177
178
  // snippets in skill docs short while still routing writes/reads to the
178
179
  // caller's session-scoped state files.
179
- let sessionId = flagValue(args, "--session-id")?.trim() || undefined;
180
+ let sessionId = explicitSessionId !== undefined ? explicitSessionId.trim() || undefined : undefined;
180
181
  if (!sessionId && payload && typeof payload.session_id === "string") {
181
182
  sessionId = payload.session_id.trim() || undefined;
182
183
  }
183
- if (!sessionId) {
184
+ if (!sessionId && explicitSessionId === undefined) {
184
185
  const envSessionId = process.env.GJC_SESSION_ID?.trim();
185
186
  if (envSessionId) sessionId = envSessionId;
186
187
  }
@@ -16,7 +16,11 @@ import { validateGoalObjective } from "../runtime";
16
16
  import type { Goal, GoalStatus, GoalToolDetails } from "../state";
17
17
 
18
18
  const goalSchema = z.object({
19
- op: z.enum(["create", "get", "complete", "resume", "drop"]).describe("goal operation"),
19
+ op: z
20
+ .enum(["create", "get", "complete", "resume", "drop"])
21
+ .describe(
22
+ "op: get | create | complete | drop | resume — drop clears the active goal without exiting goal mode (tool stays callable for the next create)",
23
+ ),
20
24
  objective: z.string().describe("goal objective").optional(),
21
25
  });
22
26
 
@@ -345,7 +345,7 @@ export async function recordSkillActivation(input: RecordSkillActivationInput):
345
345
  }
346
346
 
347
347
  function isTerminalModeState(state: ModeState | null): boolean {
348
- if (!state || state.active !== true) return true;
348
+ if (state?.active !== true) return true;
349
349
  const phase = String(state.current_phase ?? "")
350
350
  .trim()
351
351
  .toLowerCase();