@vincemakes/kiso-code 0.46.1 → 0.47.0

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 (43) hide show
  1. package/dist/auth/oauth/chatgpt.js +25 -8
  2. package/dist/auth/oauth/page.d.ts +25 -0
  3. package/dist/auth/oauth/page.js +44 -0
  4. package/dist/chat.d.ts +12 -1
  5. package/dist/chat.js +133 -46
  6. package/dist/coding-prompt.d.ts +7 -0
  7. package/dist/coding-prompt.js +12 -4
  8. package/dist/config.d.ts +7 -3
  9. package/dist/config.js +39 -4
  10. package/dist/create-coding-agent.js +16 -6
  11. package/dist/dispatch.d.ts +2 -0
  12. package/dist/dispatch.js +337 -83
  13. package/dist/floor.d.ts +21 -0
  14. package/dist/floor.js +35 -35
  15. package/dist/git-branch.d.ts +17 -0
  16. package/dist/git-branch.js +69 -0
  17. package/dist/in-run-compaction.d.ts +54 -0
  18. package/dist/in-run-compaction.js +44 -0
  19. package/dist/index.js +106 -45
  20. package/dist/opening.d.ts +48 -0
  21. package/dist/opening.js +43 -0
  22. package/dist/protected-writes.d.ts +8 -0
  23. package/dist/protected-writes.js +12 -0
  24. package/dist/remote-boundary.d.ts +55 -0
  25. package/dist/remote-boundary.js +217 -0
  26. package/dist/replay.d.ts +8 -1
  27. package/dist/replay.js +22 -10
  28. package/dist/resume.js +21 -16
  29. package/dist/session-cards.d.ts +2 -0
  30. package/dist/session-cards.js +3 -3
  31. package/dist/settings.d.ts +19 -0
  32. package/dist/settings.js +34 -5
  33. package/dist/skill-invoke.d.ts +11 -0
  34. package/dist/skill-invoke.js +59 -0
  35. package/dist/state.d.ts +14 -3
  36. package/dist/state.js +29 -3
  37. package/dist/task-notice.d.ts +48 -7
  38. package/dist/task-notice.js +123 -13
  39. package/dist/trust-ui.d.ts +7 -0
  40. package/dist/trust-ui.js +54 -9
  41. package/dist/window-title.d.ts +43 -23
  42. package/dist/window-title.js +78 -50
  43. package/package.json +14 -14
package/dist/config.js CHANGED
@@ -153,6 +153,10 @@ export function parseConfig(text, source) {
153
153
  out.model = obj.model;
154
154
  }
155
155
  if (obj.models !== undefined) {
156
+ // 0.46.2: a profile names where requests go and which of the
157
+ // person's env vars is the key — a repository must never choose that
158
+ if (source.startsWith("<cwd>"))
159
+ fail("models", 'belongs in the USER config — a project may pick one of your profiles with "model", never define one');
156
160
  if (obj.models === null || typeof obj.models !== "object" || Array.isArray(obj.models))
157
161
  fail("models", "expected an object of profiles");
158
162
  const models = {};
@@ -261,15 +265,43 @@ export function loadProjectConfig(cwd, trusted) {
261
265
  return null;
262
266
  return readConfigFile(join(cwd, ".kiso", "config.json"), "<cwd>/.kiso/config.json");
263
267
  }
264
- /** Merge: project wins over user (each layer's own keys only). */
268
+ /** 0.46.2 — how much a tier lets run without a person, strictest first;
269
+ * `manual` sits with `default` (both ask). */
270
+ const MODE_LOOSENESS = { plan: 0, manual: 1, default: 1, "accept-edits": 2, "full-access": 3 };
271
+ /**
272
+ * 0.46.2 — a repository's config may only make kiso STRICTER. A project
273
+ * mode looser than the user level (the user config's mode, else
274
+ * `default`) is refused, and a project may turn don't-ask on but never off
275
+ * — including the switch the old `dontAsk` mode spelling carries. Flags
276
+ * and env are the person's own choice and are not judged here.
277
+ */
278
+ function assertProjectTightens(u, p) {
279
+ const where = "config <cwd>/.kiso/config.json";
280
+ const base = parseMode(u.mode ?? "default");
281
+ const proj = p.mode !== undefined ? parseMode(p.mode) : undefined;
282
+ if (proj !== undefined && base !== undefined && MODE_LOOSENESS[proj.mode] > MODE_LOOSENESS[base.mode]) {
283
+ const than = u.mode !== undefined ? `your config's "${u.mode}"` : "the default";
284
+ throw new ConfigError(`${where}: mode — "${p.mode}" is looser than ${than}: a project can make the mode stricter, never looser`);
285
+ }
286
+ if (p.dontAsk === false) {
287
+ throw new ConfigError(`${where}: dontAsk — a project can turn don't-ask on, never off`);
288
+ }
289
+ if (base?.dontAsk === true && proj !== undefined && proj.dontAsk !== true && p.dontAsk !== true) {
290
+ throw new ConfigError(`${where}: mode — "${p.mode}" would turn off the don't-ask switch your config's "${u.mode}" carries: a project can turn don't-ask on, never off`);
291
+ }
292
+ }
293
+ /** Merge: a project's keys win over the user's (each layer's own keys
294
+ * only) — except that a project may only tighten (assertProjectTightens). */
265
295
  export function mergeConfigs(user, project) {
266
296
  const u = user ?? {};
267
297
  const p = project ?? {};
298
+ assertProjectTightens(u, p);
268
299
  return {
269
300
  ...(u.model !== undefined ? { model: u.model } : {}),
270
301
  ...(p.model !== undefined ? { model: p.model } : {}),
302
+ // 0.46.2: profiles come from the user config only — parseConfig
303
+ // refuses a project's `models`, so there is nothing here to merge
271
304
  ...(u.models !== undefined ? { models: u.models } : {}),
272
- ...(p.models !== undefined ? { models: { ...u.models, ...p.models } } : u.models !== undefined ? { models: u.models } : {}),
273
305
  ...(u.mode !== undefined ? { mode: u.mode } : {}),
274
306
  ...(p.mode !== undefined ? { mode: p.mode } : {}),
275
307
  ...(u.dontAsk !== undefined ? { dontAsk: u.dontAsk } : {}),
@@ -521,8 +553,11 @@ export function resolveAutoCompact(merged) {
521
553
  }
522
554
  return merged.autoCompact;
523
555
  }
524
- /** Project-trust policy: config.projectTrust (project wins over user) —
525
- * "ask" (the E3 gate, default) or "never" (the gate auto-refuses). */
556
+ /** Project-trust policy: the USER config's projectTrust — "ask" (the E3
557
+ * gate, default) or "never" (the gate auto-refuses). The gate passes
558
+ * loadUserConfig() alone (trust-ui.ts): a project never relaxes its own
559
+ * gate, and it could not anyway, since an untrusted project's config is
560
+ * never read. */
526
561
  export function resolveProjectTrustPolicy(merged) {
527
562
  return merged.projectTrust ?? "ask";
528
563
  }
@@ -7,7 +7,8 @@
7
7
  * Moved verbatim from index.ts's makeAgent (R1, 2026-09-23) and renamed;
8
8
  * the body is not edited beyond the rename and activeStoreDir's setter.
9
9
  */
10
- import { activeStoreDir, childTurnBudget, setActiveStoreDir, body, bodyLog, codingToolOptions, extensionsDir, floorOn, kisoHome, loadedExtensions, ownSessionsDir, projectRoot, protectedFiles, secretEnvNamesOf, sessionsDir, setAgentModel, setConfigModels, setConfiguredWindow, setCurrentAgentExtensions, setCurrentFaux, setCurrentModelName, setCurrentProfileName, setExtensionLists, setFloorOn, setMergedConfig, setModelChoice, setNeverInherited, setRetryShown, setSessionStore, setUserProtectedPaths, settingsLayers, workspaceRoot } from "./state.js";
10
+ import { onInRunSummary } from "./in-run-compaction.js";
11
+ import { activeStoreDir, childTurnBudget, setActiveStoreDir, body, bodyLog, dock, codingToolOptions, extensionsDir, floorOn, kisoHome, loadedExtensions, ownSessionsDir, projectRoot, protectedFiles, secretEnvNamesOf, sessionsDir, setAgentModel, setConfigModels, setConfiguredWindow, setCurrentAgentExtensions, setCurrentFaux, setCurrentModelName, setCurrentProfileName, setExtensionLists, setFloorOn, setMergedConfig, setModelChoice, setNeverInherited, setRetryShown, setSessionStore, setUserProtectedPaths, settingsLayers, workspaceRoot } from "./state.js";
11
12
  import { claimProjectDir, projectLayoutActive } from "./projects.js";
12
13
  import { migrationNotice, pendingLegacyIds, planMigration, runMigration } from "./session-migration.js";
13
14
  import { askUi, resolveProjectTrust } from "./trust-ui.js";
@@ -18,8 +19,8 @@ import { builtInLayer } from "./builtin.js";
18
19
  import { recordLearnedWindow, useLearnedWindows } from "./learned-windows.js";
19
20
  import { compactionDiscardedNotice, contextWindowTokens, knownContextWindow, unknownWindowNotice, windowLearnedNotice } from "./chat.js";
20
21
  import {} from "@vincemakes/kiso-core";
21
- import { guardSavedAllow, isProtectedWrite } from "./protected-writes.js";
22
- import { floorExtension, isDestructiveCall } from "./floor.js";
22
+ import { guardSavedAllow, neverInheritedCall } from "./protected-writes.js";
23
+ import { floorExtension } from "./floor.js";
23
24
  import { protectedShellExtension } from "./protected-shell.js";
24
25
  import { homedir } from "node:os";
25
26
  import { breakerExtension } from "./breaker.js";
@@ -202,7 +203,12 @@ export async function createCodingAgent(sessionId, input, modelFlag) {
202
203
  setConfiguredWindow(resolveContextWindow(merged, resolved?.profile));
203
204
  const model = resolved === null ? "faux" : resolved.profile.model;
204
205
  if (resolved === null) {
205
- console.log("[faux mode — set ANTHROPIC_API_KEY or OPENAI_API_KEY, or configure models in ~/.kiso/config.json]\n");
206
+ // the last sweep (owner, 2026-10-06): on a dock this line was written
207
+ // into the frame and painted over at once — the opening's MODEL row
208
+ // says it instead (opening.ts). A pipe, and -p, keep it.
209
+ if (!dock.active) {
210
+ console.log("[faux mode — set ANTHROPIC_API_KEY or OPENAI_API_KEY, or configure models in ~/.kiso/config.json]\n");
211
+ }
206
212
  setCurrentFaux(true);
207
213
  setCurrentModelName("faux");
208
214
  setCurrentProfileName(null);
@@ -230,9 +236,10 @@ export async function createCodingAgent(sessionId, input, modelFlag) {
230
236
  // 0.40.0: the read-only shell allow sits after the tiers — an allow from
231
237
  // it outranks a tier's ask and names itself in decidedBy.
232
238
  // 0.40.0: a saved allow never carries a write into .git/ or .kiso/, nor
233
- // a destructive shell command.
239
+ // a destructive shell command; 0.46.2: nor a command across the remote
240
+ // boundary (remote-boundary.ts).
234
241
  const workspaceRoot = () => codingToolOptions().workspaceRoot;
235
- const neverInherited = (call) => isProtectedWrite(call, workspaceRoot()) || isDestructiveCall(call);
242
+ const neverInherited = (call) => neverInheritedCall(call, workspaceRoot());
236
243
  setNeverInherited(neverInherited);
237
244
  // 0.40.0: the catastrophe floor, at the chain's HEAD — a deny there
238
245
  // names itself in decidedBy and outranks every tier, bypass included.
@@ -301,6 +308,9 @@ export async function createCodingAgent(sessionId, input, modelFlag) {
301
308
  isCheck: (command) => runsACheck(command, Object.values(merged.checks ?? {})),
302
309
  // ADR-0055 Amendment 2: a discarded checkpoint says so, in sizes only.
303
310
  onDiscard: (d) => body.notice(compactionDiscardedNotice(d)),
311
+ // the compaction round (owner, 2026-10-06): a summary inside a run
312
+ // is drawn while it runs — the running row reads it
313
+ onSummary: onInRunSummary,
304
314
  // ADR-0055 Amendment 2 (decision 3): only a window someone stated
305
315
  // arms the overflow belt — read from the LIVE binding, so it moves
306
316
  // with /model and /resume; the fallback reads as null.
@@ -69,4 +69,6 @@ export declare function parseBang(trimmed: string): {
69
69
  readonly command: string;
70
70
  readonly send: boolean;
71
71
  } | null;
72
+ export declare function markCompactWhy(why: string): void;
73
+ export declare function markAutoCompact(): void;
72
74
  export declare function dispatch(line: string, ctx: DispatchCtx): void;