gorsee 0.2.13 → 0.2.15

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/README.md CHANGED
@@ -20,6 +20,7 @@ Read the strategic docs:
20
20
  - [Application Modes](./docs/APPLICATION_MODES.md)
21
21
  - [Security Model](./docs/SECURITY_MODEL.md)
22
22
  - [Top-Tier Roadmap](./docs/TOP_TIER_ROADMAP.md)
23
+ - [Top-Tier Competition Plan](./docs/TOP_TIER_COMPETITION_PLAN.md)
23
24
  - [Canonical Language Plan](./docs/CANONICAL_LANGUAGE_PLAN.md)
24
25
  - [Canonical Recipes](./docs/CANONICAL_RECIPES.md)
25
26
  - [Canonical Examples](./examples/README.md)
@@ -47,6 +48,8 @@ Read the strategic docs:
47
48
  - [Runtime Triage](./docs/RUNTIME_TRIAGE.md)
48
49
  - [Starter Failures](./docs/STARTER_FAILURES.md)
49
50
  - [AI Workflows](./docs/AI_WORKFLOWS.md)
51
+ - [AI Artifact Contract](./docs/AI_ARTIFACT_CONTRACT.md)
52
+ - [CLI Contract](./docs/CLI_CONTRACT.json)
50
53
  - [AI IDE Sync Workflow](./docs/AI_IDE_SYNC_WORKFLOW.md)
51
54
  - [AI MCP Workflow](./docs/AI_MCP_WORKFLOW.md)
52
55
  - [AI Bridge Workflow](./docs/AI_BRIDGE_WORKFLOW.md)
@@ -314,6 +317,7 @@ npm create gorsee@latest my-app
314
317
  | `gorsee build` | Build client and server output |
315
318
  | `gorsee start` | Start production runtime |
316
319
  | `gorsee start --runtime node` | Start the built Node production runtime entry |
320
+ | `gorsee worker` | Run the canonical server-mode worker/service runtime entry |
317
321
  | `gorsee check [--rewrite-imports] [--rewrite-loaders]` | Type, structure, TSX contract, and safety audit, with optional canonical autofix |
318
322
  | `gorsee routes` | Show route table |
319
323
  | `gorsee generate <entity>` | Generate CRUD scaffold with typed routes, validated forms, and inferred `memory|sqlite|postgres` data mode |
@@ -322,7 +326,8 @@ npm create gorsee@latest my-app
322
326
  | `gorsee typegen` | Generate typed routes |
323
327
  | `gorsee migrate` | Run database migrations |
324
328
  | `gorsee deploy` | Generate deploy config for supported targets, with `--runtime bun|node` on process-based adapters |
325
- | `gorsee ai` | AI diagnostics, bridge, IDE sync, export, and MCP tooling |
329
+ | `gorsee test` | Run the framework-aware test command surface |
330
+ | `gorsee ai` | AI bootstrap, diagnostics, checkpoints, context export, bridge, IDE sync, and MCP tooling |
326
331
 
327
332
  Runtime debugging surface:
328
333
 
@@ -335,6 +340,13 @@ Migration ergonomics:
335
340
  - `gorsee upgrade` is the canonical end-to-end upgrade flow for installed apps.
336
341
  - `gorsee upgrade --check --report docs/upgrade-report.json` is the dry-run migration audit flow when you want review before installation.
337
342
 
343
+ AI bootstrap and handoff:
344
+
345
+ - `gorsee ai init` scaffolds `.gorsee/rules.md`, `GORSEE.md`, and `.gorsee/agent/checkpoints` for repositories that enable AI workflows.
346
+ - `gorsee ai checkpoint --mode inspect|propose|apply|operate` records explicit operator checkpoints for mutating and non-mutating sessions.
347
+ - `gorsee ai pack` writes the latest grounded handoff bundle to `.gorsee/agent/latest.{json,md}` plus deploy/release/incident briefs.
348
+ - `gorsee ai framework --format markdown` remains the canonical cold-start packet for agents and operators.
349
+
338
350
  ## Product Standards
339
351
 
340
352
  - Production behavior must remain deterministic across dev and prod.
@@ -1,6 +1,7 @@
1
1
  import type { AIDiagnostic, AIEvent } from "./index.js";
2
2
  import type { AIStorePaths, AIHealthReport } from "./store.js";
3
3
  import { type AIContextPacket } from "./summary.js";
4
+ import { type AIOperationMode } from "./rules.js";
4
5
  export interface AIContextSnippet {
5
6
  file: string;
6
7
  startLine: number;
@@ -43,5 +44,6 @@ export declare function buildAIContextBundle(cwd: string, paths: AIStorePaths, o
43
44
  limit?: number;
44
45
  snippetRadius?: number;
45
46
  maxSnippets?: number;
47
+ mode?: AIOperationMode;
46
48
  }): Promise<AIContextBundle>;
47
49
  export declare function renderAIContextBundleMarkdown(bundle: AIContextBundle): string;
@@ -3,8 +3,12 @@ import { join, isAbsolute } from "node:path";
3
3
  import { buildAIHealthReport, readAIDiagnosticsSnapshot, readAIEvents, readReactiveTraceArtifact } from "./store.js";
4
4
  import { createAIContextPacket, renderAIContextMarkdown } from "./summary.js";
5
5
  import { GORSEE_AI_CONTEXT_SCHEMA_VERSION } from "./contracts.js";
6
+ import { resolveAIRulesFile } from "./rules.js";
6
7
  export async function buildAIContextBundle(cwd, paths, options = {}) {
7
- const events = await readAIEvents(paths.eventsPath, { limit: options.limit ?? 200 }), diagnostics = await readAIDiagnosticsSnapshot(paths.diagnosticsPath), reactiveTrace = await readReactiveTraceArtifact(paths.reactiveTracePath), report = await buildAIHealthReport(paths, { limit: options.limit ?? 200 }), packet = createAIContextPacket(report, events, diagnostics?.latest, reactiveTrace), rootCauses = buildRootCauseRanking(report, diagnostics?.latest, events), snippets = await collectSnippets(cwd, diagnostics?.latest, report, events, rootCauses, {
8
+ const events = await readAIEvents(paths.eventsPath, { limit: options.limit ?? 200 }), diagnostics = await readAIDiagnosticsSnapshot(paths.diagnosticsPath), reactiveTrace = await readReactiveTraceArtifact(paths.reactiveTracePath), report = await buildAIHealthReport(paths, { limit: options.limit ?? 200 }), rules = await resolveAIRulesFile(cwd), packet = createAIContextPacket(report, events, diagnostics?.latest, reactiveTrace, {
9
+ currentMode: options.mode ?? "inspect",
10
+ rules
11
+ }), rootCauses = buildRootCauseRanking(report, diagnostics?.latest, events), snippets = await collectSnippets(cwd, diagnostics?.latest, report, events, rootCauses, {
8
12
  snippetRadius: options.snippetRadius ?? 6,
9
13
  maxSnippets: options.maxSnippets ?? 5
10
14
  });
@@ -0,0 +1,33 @@
1
+ import { type AIContextBundle } from "./bundle.js";
2
+ import type { AIStorePaths } from "./store.js";
3
+ import { type AIOperationMode, type AITransportContract } from "./rules.js";
4
+ export interface AICheckpointMetadata {
5
+ schemaVersion: string;
6
+ createdAt: string;
7
+ name: string;
8
+ slug: string;
9
+ mode: AIOperationMode;
10
+ bundleJsonPath: string;
11
+ bundleMarkdownPath: string;
12
+ rulesPath?: string;
13
+ transport: AITransportContract;
14
+ }
15
+ export interface AICheckpointPaths {
16
+ checkpointsDir: string;
17
+ bundleJsonPath: string;
18
+ bundleMarkdownPath: string;
19
+ metadataPath: string;
20
+ latestPointerPath: string;
21
+ }
22
+ export declare function slugifyCheckpointName(input: string): string;
23
+ export declare function resolveAICheckpointPaths(cwd: string, name: string): AICheckpointPaths;
24
+ export declare function writeAICheckpoint(cwd: string, storePaths: AIStorePaths, options: {
25
+ name?: string;
26
+ mode: AIOperationMode;
27
+ limit?: number;
28
+ maxSnippets?: number;
29
+ }): Promise<{
30
+ bundle: AIContextBundle;
31
+ metadata: AICheckpointMetadata;
32
+ paths: AICheckpointPaths;
33
+ }>;
@@ -0,0 +1,50 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { buildAIContextBundle, renderAIContextBundleMarkdown } from "./bundle.js";
4
+ import { GORSEE_AI_CONTEXT_SCHEMA_VERSION } from "./contracts.js";
5
+ import { resolveAISessionPackPaths } from "./session-pack.js";
6
+ import {
7
+ AI_TRANSPORT_CONTRACT,
8
+ resolveAIRulesFile
9
+ } from "./rules.js";
10
+ export function slugifyCheckpointName(input) {
11
+ return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "checkpoint";
12
+ }
13
+ export function resolveAICheckpointPaths(cwd, name) {
14
+ const sessionPackPaths = resolveAISessionPackPaths(cwd), checkpointsDir = join(sessionPackPaths.outDir, "checkpoints"), slug = slugifyCheckpointName(name);
15
+ return {
16
+ checkpointsDir,
17
+ bundleJsonPath: join(checkpointsDir, `${slug}.json`),
18
+ bundleMarkdownPath: join(checkpointsDir, `${slug}.md`),
19
+ metadataPath: join(checkpointsDir, `${slug}.meta.json`),
20
+ latestPointerPath: join(checkpointsDir, "latest.json")
21
+ };
22
+ }
23
+ export async function writeAICheckpoint(cwd, storePaths, options) {
24
+ const createdAt = new Date().toISOString(), name = options.name?.trim().length ? options.name.trim() : createdAt.replace(/[:.]/g, "-"), paths = resolveAICheckpointPaths(cwd, name), bundle = await buildAIContextBundle(cwd, storePaths, {
25
+ limit: options.limit,
26
+ maxSnippets: options.maxSnippets
27
+ }), rules = await resolveAIRulesFile(cwd);
28
+ await mkdir(paths.checkpointsDir, { recursive: !0 });
29
+ const metadata = {
30
+ schemaVersion: GORSEE_AI_CONTEXT_SCHEMA_VERSION,
31
+ createdAt,
32
+ name,
33
+ slug: slugifyCheckpointName(name),
34
+ mode: options.mode,
35
+ bundleJsonPath: paths.bundleJsonPath,
36
+ bundleMarkdownPath: paths.bundleMarkdownPath,
37
+ rulesPath: rules?.path,
38
+ transport: AI_TRANSPORT_CONTRACT
39
+ }, markdown = [
40
+ `<!-- gorsee-ai-schema: ${GORSEE_AI_CONTEXT_SCHEMA_VERSION} -->`,
41
+ `<!-- gorsee-ai-mode: ${options.mode} -->`,
42
+ renderAIContextBundleMarkdown(bundle)
43
+ ].join(`
44
+ `);
45
+ await writeFile(paths.bundleJsonPath, JSON.stringify(bundle, null, 2), "utf-8");
46
+ await writeFile(paths.bundleMarkdownPath, markdown, "utf-8");
47
+ await writeFile(paths.metadataPath, JSON.stringify(metadata, null, 2), "utf-8");
48
+ await writeFile(paths.latestPointerPath, JSON.stringify(metadata, null, 2), "utf-8");
49
+ return { bundle, metadata, paths };
50
+ }
@@ -1,4 +1,5 @@
1
1
  import { type AppMode } from "../runtime/app-config.js";
2
+ import { type AIOperationModeDefinition, type AITransportContract } from "./rules.js";
2
3
  export interface AIFrameworkDocRef {
3
4
  path: string;
4
5
  purpose: string;
@@ -32,6 +33,12 @@ export interface AIFrameworkPacket {
32
33
  command: string;
33
34
  purpose: string;
34
35
  }>;
36
+ operationModes: AIOperationModeDefinition[];
37
+ transport: AITransportContract;
38
+ rules?: {
39
+ path: string;
40
+ content: string;
41
+ };
35
42
  docs: {
36
43
  local: AIFrameworkDocRef[];
37
44
  canonical: AIFrameworkDocRef[];
@@ -2,6 +2,11 @@ import { access, readFile } from "node:fs/promises";
2
2
  import { basename, join, relative } from "node:path";
3
3
  import { generateFrameworkMD } from "../cli/framework-md.js";
4
4
  import { loadAppConfig, resolveAppMode } from "../runtime/app-config.js";
5
+ import {
6
+ AI_OPERATION_MODES,
7
+ AI_TRANSPORT_CONTRACT,
8
+ resolveAIRulesFile
9
+ } from "./rules.js";
5
10
  const LOCAL_DOCS = [
6
11
  { path: "AGENTS.md", purpose: "\u041F\u0440\u043E\u0435\u043A\u0442\u043D\u044B\u0439 operating contract \u0434\u043B\u044F \u0430\u0433\u0435\u043D\u0442\u043E\u0432" },
7
12
  { path: "FRAMEWORK.md", purpose: "AI-friendly reference \u0434\u043B\u044F \u0442\u0435\u043A\u0443\u0449\u0435\u0433\u043E \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F" },
@@ -10,21 +15,32 @@ const LOCAL_DOCS = [
10
15
  { path: "docs/FRAMEWORK_DOCTRINE.md", purpose: "\u0410\u0440\u0445\u0438\u0442\u0435\u043A\u0442\u0443\u0440\u043D\u0430\u044F \u0434\u043E\u043A\u0442\u0440\u0438\u043D\u0430 \u0438 \u0438\u043D\u0432\u0430\u0440\u0438\u0430\u043D\u0442\u044B" },
11
16
  { path: "docs/APPLICATION_MODES.md", purpose: "\u041A\u0430\u043D\u043E\u043D\u0438\u0447\u0435\u0441\u043A\u0438\u0435 \u0440\u0435\u0436\u0438\u043C\u044B frontend/fullstack/server \u0438 \u0433\u0440\u0430\u043D\u0438\u0446\u044B \u043C\u0435\u0436\u0434\u0443 \u043D\u0438\u043C\u0438" },
12
17
  { path: "docs/API_STABILITY.md", purpose: "\u0421\u0442\u0430\u0431\u0438\u043B\u044C\u043D\u044B\u0435 \u043F\u0443\u0431\u043B\u0438\u0447\u043D\u044B\u0435 entrypoints \u0438 migration semantics" },
18
+ { path: "docs/PUBLIC_SURFACE_MAP.md", purpose: "\u041A\u0430\u043D\u043E\u043D\u0438\u0447\u0435\u0441\u043A\u0430\u044F import map \u0438 bounded public surfaces" },
19
+ { path: "docs/CLI_CONTRACT.json", purpose: "Machine-readable CLI command matrix \u0438 AI subcommand surface" },
13
20
  { path: "docs/SECURITY_MODEL.md", purpose: "Runtime/security guarantees \u0438 fail-closed \u043C\u043E\u0434\u0435\u043B\u044C" },
14
21
  { path: "docs/AI_WORKFLOWS.md", purpose: "\u041A\u0430\u043D\u043E\u043D\u0438\u0447\u0435\u0441\u043A\u0438\u0439 human+agent workflow" },
15
22
  { path: "docs/AI_SURFACE_STABILITY.md", purpose: "\u0421\u0442\u0430\u0431\u0438\u043B\u044C\u043D\u043E\u0441\u0442\u044C AI-facing surface" },
23
+ { path: "docs/AI_ARTIFACT_CONTRACT.md", purpose: "Versioned AI artifacts, checkpoints, and handoff expectations" },
16
24
  { path: "docs/AI_SESSION_PACKS.md", purpose: "Cross-session handoff \u0434\u043B\u044F \u0430\u0433\u0435\u043D\u0442\u043E\u0432" },
25
+ { path: "docs/REACTIVE_RUNTIME.md", purpose: "\u0420\u0435\u0430\u043A\u0442\u0438\u0432\u043D\u0430\u044F \u043C\u043E\u0434\u0435\u043B\u044C, diagnostics, resources, mutations, islands" },
26
+ { path: "docs/SUPPORT_MATRIX.md", purpose: "\u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0435 runtime targets, CLI surfaces, and CI-validated contract" },
27
+ { path: "docs/DEPLOY_TARGET_GUIDE.md", purpose: "Mode-aware deploy target guidance \u0438 runtime profiles" },
17
28
  { path: "docs/STARTER_ONBOARDING.md", purpose: "\u0421\u0442\u0430\u0440\u0442\u043E\u0432\u044B\u0435 app-\u043A\u043B\u0430\u0441\u0441\u044B \u0438 onboarding path" },
18
29
  { path: "docs/MIGRATION_GUIDE.md", purpose: "\u041F\u0435\u0440\u0435\u0445\u043E\u0434 \u0441 compatibility imports \u043D\u0430 canonical surfaces" },
19
30
  { path: "docs/RUNTIME_TRIAGE.md", purpose: "\u0422\u0440\u0438\u0430\u0436 runtime/regression \u043F\u0440\u043E\u0431\u043B\u0435\u043C" },
20
31
  { path: "docs/STARTER_FAILURES.md", purpose: "\u0427\u0430\u0441\u0442\u044B\u0435 \u043E\u0448\u0438\u0431\u043A\u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438 \u0438 scaffold" }
21
32
  ], AI_COMMANDS = [
33
+ { command: "gorsee ai init", purpose: "Bootstrap local AI rules, operator guide, and checkpoint directory" },
22
34
  { command: "gorsee ai framework --format markdown", purpose: "\u041A\u0430\u043D\u043E\u043D\u0438\u0447\u0435\u0441\u043A\u0438\u0439 cold-start packet \u043F\u043E \u0444\u0440\u0435\u0439\u043C\u0432\u043E\u0440\u043A\u0443" },
35
+ { command: "gorsee ai tail --limit 20", purpose: "\u041F\u0440\u043E\u0441\u043C\u043E\u0442\u0440 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0445 structured AI events" },
36
+ { command: "gorsee ai replay", purpose: "\u0412\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u043A\u043E\u0440\u0440\u0435\u043B\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u043E\u0433\u043E AI/runtime event timeline" },
37
+ { command: "gorsee ai doctor", purpose: "\u0421\u0432\u043E\u0434\u043A\u0430 diagnostics/incidents/artifact regressions" },
23
38
  { command: "gorsee ai export --format markdown", purpose: "\u041A\u043E\u043C\u043F\u0430\u043A\u0442\u043D\u044B\u0439 packet \u043F\u043E \u0442\u0435\u043A\u0443\u0449\u0435\u043C\u0443 AI/runtime \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u044E" },
24
39
  { command: "gorsee ai export --bundle --format markdown", purpose: "Runtime packet \u0441 \u0440\u0430\u043D\u0436\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u043C\u0438 code snippets" },
25
- { command: "gorsee ai doctor", purpose: "\u0421\u0432\u043E\u0434\u043A\u0430 diagnostics/incidents/artifact regressions" },
26
40
  { command: "gorsee ai pack", purpose: "\u0417\u0430\u043F\u0438\u0441\u044C session pack \u0432 .gorsee/agent" },
41
+ { command: "gorsee ai checkpoint --mode inspect", purpose: "\u042F\u0432\u043D\u044B\u0439 checkpoint \u0442\u0435\u043A\u0443\u0449\u0435\u0433\u043E AI session state \u0441 metadata \u043F\u043E \u0440\u0435\u0436\u0438\u043C\u0443" },
27
42
  { command: "gorsee ai ide-sync", purpose: "IDE-friendly projection \u0444\u0430\u0439\u043B\u043E\u0432" },
43
+ { command: "gorsee ai bridge", purpose: "\u041B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0439 ingest bridge \u0434\u043B\u044F trusted IDE/agent tooling" },
28
44
  { command: "gorsee ai mcp", purpose: "stdio MCP \u0441\u0435\u0440\u0432\u0435\u0440 \u043F\u043E\u0432\u0435\u0440\u0445 \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u0433\u043E AI state" }
29
45
  ];
30
46
  async function pathExists(path) {
@@ -70,7 +86,7 @@ function renderDocLines(docs) {
70
86
  return docs.map((doc) => `- \`${doc.path}\` -- ${doc.purpose}`);
71
87
  }
72
88
  export async function buildAIFrameworkPacket(cwd) {
73
- const projectName = await resolveProjectName(cwd), appMode = resolveAppMode(await loadAppConfig(cwd)), localDocs = await collectDocRefs(cwd, LOCAL_DOCS), canonicalDocs = await collectDocRefs(cwd, CANONICAL_DOCS), frameworkReferencePath = await pathExists(join(cwd, "FRAMEWORK.md")) ? relative(cwd, join(cwd, "FRAMEWORK.md")) || "FRAMEWORK.md" : void 0, frameworkReferenceMarkdown = frameworkReferencePath ? await readFile(join(cwd, frameworkReferencePath), "utf-8") : generateFrameworkMD(projectName);
89
+ const projectName = await resolveProjectName(cwd), appMode = resolveAppMode(await loadAppConfig(cwd)), localDocs = await collectDocRefs(cwd, LOCAL_DOCS), canonicalDocs = await collectDocRefs(cwd, CANONICAL_DOCS), frameworkReferencePath = await pathExists(join(cwd, "FRAMEWORK.md")) ? relative(cwd, join(cwd, "FRAMEWORK.md")) || "FRAMEWORK.md" : void 0, frameworkReferenceMarkdown = frameworkReferencePath ? await readFile(join(cwd, frameworkReferencePath), "utf-8") : generateFrameworkMD(projectName), rules = await resolveAIRulesFile(cwd);
74
90
  return {
75
91
  kind: "gorsee.framework",
76
92
  schemaVersion: 1,
@@ -88,7 +104,19 @@ export async function buildAIFrameworkPacket(cwd) {
88
104
  browser: "gorsee/client",
89
105
  server: "gorsee/server",
90
106
  compatibility: "gorsee and gorsee/compat are compatibility-only for new code",
91
- scoped: ["gorsee/auth", "gorsee/db", "gorsee/security", "gorsee/log", "gorsee/forms", "gorsee/routes", "gorsee/ai"]
107
+ scoped: [
108
+ "gorsee/auth",
109
+ "gorsee/db",
110
+ "gorsee/security",
111
+ "gorsee/ai",
112
+ "gorsee/forms",
113
+ "gorsee/routes",
114
+ "gorsee/i18n",
115
+ "gorsee/content",
116
+ "gorsee/env",
117
+ "gorsee/log",
118
+ "gorsee/testing"
119
+ ]
92
120
  },
93
121
  routeGrammar: [
94
122
  "default export -> page UI",
@@ -104,6 +132,12 @@ export async function buildAIFrameworkPacket(cwd) {
104
132
  routeExample: "routes/users/[id].tsx -> /users/:id"
105
133
  },
106
134
  aiCommands: AI_COMMANDS,
135
+ operationModes: AI_OPERATION_MODES,
136
+ transport: AI_TRANSPORT_CONTRACT,
137
+ rules: rules ? {
138
+ path: rules.path,
139
+ content: rules.content
140
+ } : void 0,
107
141
  docs: {
108
142
  local: localDocs,
109
143
  canonical: canonicalDocs
@@ -111,9 +145,14 @@ export async function buildAIFrameworkPacket(cwd) {
111
145
  recommendedStart: [
112
146
  "Read AGENTS.md first when it exists.",
113
147
  "Read FRAMEWORK.md for the current app shape and syntax.",
148
+ "Read docs/PUBLIC_SURFACE_MAP.md for the canonical import map and scoped stable surfaces.",
149
+ "Read docs/SUPPORT_MATRIX.md when runtime, packaging, or deploy assumptions matter.",
150
+ "Prefer inspect/propose modes before apply/operate when the task is still ambiguous.",
114
151
  `Respect the current app.mode contract: ${appMode}.`,
115
152
  "Use gorsee/client for browser-safe code and gorsee/server for runtime/server boundaries.",
116
- "Prefer scoped stable subpaths when auth, db, security, forms, routes, ai, or log is the primary concern.",
153
+ "Prefer scoped stable subpaths when auth, db, security, forms, routes, ai, i18n, content, env, log, or testing is the primary concern.",
154
+ "Keep model traffic provider-direct or self-hosted; treat the AI bridge as diagnostics transport, not as the production request path.",
155
+ "Use gorsee ai init when local AI workflows are enabled but the repository has no explicit local rules scaffold yet.",
117
156
  "Use gorsee ai export --bundle for incident/debug context, not for framework cold-start context."
118
157
  ],
119
158
  frameworkReferencePath,
@@ -159,6 +198,16 @@ export function renderAIFrameworkMarkdown(packet) {
159
198
  "",
160
199
  ...packet.aiCommands.map((entry) => `- \`${entry.command}\` -- ${entry.purpose}`),
161
200
  "",
201
+ "## AI Operation Modes",
202
+ "",
203
+ ...packet.operationModes.map((entry) => `- \`${entry.mode}\` -- ${entry.purpose}`),
204
+ "",
205
+ "## AI Transport Contract",
206
+ "",
207
+ `- Model traffic: ${packet.transport.modelTraffic}`,
208
+ `- Bridge role: ${packet.transport.bridgeRole}`,
209
+ `- Production role: ${packet.transport.productionRole}`,
210
+ "",
162
211
  "## Local Docs",
163
212
  "",
164
213
  ...packet.docs.local.length > 0 ? renderDocLines(packet.docs.local) : ["- No local AI/context docs detected in the current cwd."],
@@ -171,6 +220,14 @@ export function renderAIFrameworkMarkdown(packet) {
171
220
  "",
172
221
  packet.frameworkReferencePath ? `Source: \`${packet.frameworkReferencePath}\`` : "Source: generated built-in framework reference",
173
222
  "",
223
+ ...packet.rules ? [
224
+ "## AI Rules",
225
+ "",
226
+ `Source: \`${packet.rules.path}\``,
227
+ "",
228
+ packet.rules.content,
229
+ ""
230
+ ] : [],
174
231
  packet.frameworkReferenceMarkdown
175
232
  ].filter((line) => line !== void 0).join(`
176
233
  `);
@@ -1,5 +1,6 @@
1
1
  import { type AIContextPacket } from "./summary.js";
2
2
  import { type AIStorePaths } from "./store.js";
3
+ import { type AIOperationMode } from "./rules.js";
3
4
  export interface IDEProjectionPaths {
4
5
  diagnosticsPath: string;
5
6
  eventsPath: string;
@@ -8,6 +9,7 @@ export interface IDEProjectionPaths {
8
9
  export interface IDEProjection {
9
10
  schemaVersion: string;
10
11
  updatedAt: string;
12
+ agent: AIContextPacket["agent"];
11
13
  app?: AIContextPacket["app"];
12
14
  diagnostics: Array<{
13
15
  code?: string;
@@ -34,5 +36,7 @@ export interface IDEProjection {
34
36
  export declare function resolveIDEProjectionPaths(cwd: string): IDEProjectionPaths;
35
37
  export declare function buildIDEProjection(storePaths: AIStorePaths, options?: {
36
38
  limit?: number;
39
+ cwd?: string;
40
+ mode?: AIOperationMode;
37
41
  }): Promise<IDEProjection>;
38
42
  export declare function writeIDEProjection(projectionPaths: IDEProjectionPaths, projection: IDEProjection): Promise<void>;
@@ -3,6 +3,7 @@ import { dirname, join } from "node:path";
3
3
  import { createAIContextPacket, renderAIContextMarkdown } from "./summary.js";
4
4
  import { buildAIHealthReport, readAIDiagnosticsSnapshot, readAIEvents, readReactiveTraceArtifact } from "./store.js";
5
5
  import { GORSEE_AI_CONTEXT_SCHEMA_VERSION } from "./contracts.js";
6
+ import { resolveAIRulesFile } from "./rules.js";
6
7
  export function resolveIDEProjectionPaths(cwd) {
7
8
  const base = join(cwd, ".gorsee", "ide");
8
9
  return {
@@ -12,10 +13,14 @@ export function resolveIDEProjectionPaths(cwd) {
12
13
  };
13
14
  }
14
15
  export async function buildIDEProjection(storePaths, options = {}) {
15
- const events = await readAIEvents(storePaths.eventsPath, { limit: options.limit ?? 100 }), diagnosticsSnapshot = await readAIDiagnosticsSnapshot(storePaths.diagnosticsPath), reactiveTrace = await readReactiveTraceArtifact(storePaths.reactiveTracePath), report = await buildAIHealthReport(storePaths, { limit: options.limit ?? 200 }), context = createAIContextPacket(report, events, diagnosticsSnapshot?.latest, reactiveTrace);
16
+ const events = await readAIEvents(storePaths.eventsPath, { limit: options.limit ?? 100 }), diagnosticsSnapshot = await readAIDiagnosticsSnapshot(storePaths.diagnosticsPath), reactiveTrace = await readReactiveTraceArtifact(storePaths.reactiveTracePath), report = await buildAIHealthReport(storePaths, { limit: options.limit ?? 200 }), rules = options.cwd ? await resolveAIRulesFile(options.cwd) : void 0, context = createAIContextPacket(report, events, diagnosticsSnapshot?.latest, reactiveTrace, {
17
+ currentMode: options.mode ?? "inspect",
18
+ rules
19
+ });
16
20
  return {
17
21
  schemaVersion: GORSEE_AI_CONTEXT_SCHEMA_VERSION,
18
22
  updatedAt: new Date().toISOString(),
23
+ agent: context.agent,
19
24
  app: context.app,
20
25
  diagnostics: diagnosticsSnapshot?.latest ? [{
21
26
  code: diagnosticsSnapshot.latest.code,
@@ -45,12 +50,14 @@ export async function writeIDEProjection(projectionPaths, projection) {
45
50
  await writeFile(projectionPaths.diagnosticsPath, JSON.stringify({
46
51
  schemaVersion: projection.schemaVersion,
47
52
  updatedAt: projection.updatedAt,
53
+ agent: projection.agent,
48
54
  app: projection.app,
49
55
  diagnostics: projection.diagnostics
50
56
  }, null, 2), "utf-8");
51
57
  await writeFile(projectionPaths.eventsPath, JSON.stringify({
52
58
  schemaVersion: projection.schemaVersion,
53
59
  updatedAt: projection.updatedAt,
60
+ agent: projection.agent,
54
61
  app: projection.app,
55
62
  events: projection.recentEvents,
56
63
  artifactRegressions: projection.artifactRegressions
@@ -1,5 +1,7 @@
1
1
  import { type AISessionPackConfig } from "./session-pack.js";
2
2
  export { GORSEE_AI_CONTEXT_SCHEMA_VERSION, } from "./contracts.js";
3
+ export { AI_OPERATION_MODES, AI_TRANSPORT_CONTRACT, renderDefaultAIRulesMarkdown, renderDefaultAIGuideMarkdown, resolveAIRulesFile, type AIOperationMode, type AIOperationModeDefinition, type AIRulesFile, type AITransportContract, } from "./rules.js";
4
+ export { resolveAICheckpointPaths, slugifyCheckpointName, writeAICheckpoint, type AICheckpointMetadata, type AICheckpointPaths, } from "./checkpoint.js";
3
5
  export { writeArtifactFailurePack, writeArtifactLifecycleEvent, writeArtifactSuccessPack, runArtifactLifecycleStep, type ArtifactLifecycleEventInput, } from "./artifact-lifecycle.js";
4
6
  export { createAIBridgeHandler, createAIBridgeServer, type AIBridgeHandler, type AIBridgeServer, type AIBridgeServerOptions, type AIBridgeSnapshot, } from "./bridge.js";
5
7
  export { buildAIHealthReport, readAIDiagnosticsSnapshot, readReactiveTraceArtifact, readAIEvents, resolveAIStorePaths, type AIHealthReport, type AIStorePaths, } from "./store.js";
@@ -8,6 +8,18 @@ import {
8
8
  export {
9
9
  GORSEE_AI_CONTEXT_SCHEMA_VERSION
10
10
  } from "./contracts.js";
11
+ export {
12
+ AI_OPERATION_MODES,
13
+ AI_TRANSPORT_CONTRACT,
14
+ renderDefaultAIRulesMarkdown,
15
+ renderDefaultAIGuideMarkdown,
16
+ resolveAIRulesFile
17
+ } from "./rules.js";
18
+ export {
19
+ resolveAICheckpointPaths,
20
+ slugifyCheckpointName,
21
+ writeAICheckpoint
22
+ } from "./checkpoint.js";
11
23
  export {
12
24
  writeArtifactFailurePack,
13
25
  writeArtifactLifecycleEvent,
@@ -0,0 +1,28 @@
1
+ import type { AppMode } from "../runtime/app-config.js";
2
+ export type AIOperationMode = "inspect" | "propose" | "apply" | "operate";
3
+ export interface AIOperationModeDefinition {
4
+ mode: AIOperationMode;
5
+ purpose: string;
6
+ mutatesFiles: boolean;
7
+ mutatesRuntime: boolean;
8
+ }
9
+ export interface AIRulesFile {
10
+ path: string;
11
+ content: string;
12
+ }
13
+ export interface AITransportContract {
14
+ modelTraffic: "provider-direct-or-self-hosted";
15
+ bridgeRole: "diagnostics-and-ingestion-only";
16
+ productionRole: "must-not-sit-on-the-runtime-request-path";
17
+ }
18
+ export declare const AI_OPERATION_MODES: AIOperationModeDefinition[];
19
+ export declare const AI_TRANSPORT_CONTRACT: AITransportContract;
20
+ export declare function renderDefaultAIRulesMarkdown(input: {
21
+ projectName: string;
22
+ appMode: AppMode;
23
+ }): string;
24
+ export declare function renderDefaultAIGuideMarkdown(input: {
25
+ projectName: string;
26
+ appMode: AppMode;
27
+ }): string;
28
+ export declare function resolveAIRulesFile(cwd: string): Promise<AIRulesFile | undefined>;
@@ -0,0 +1,118 @@
1
+ import { access, readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ export const AI_OPERATION_MODES = [
4
+ {
5
+ mode: "inspect",
6
+ purpose: "Read code, diagnostics, and contracts without mutating files or runtime state.",
7
+ mutatesFiles: !1,
8
+ mutatesRuntime: !1
9
+ },
10
+ {
11
+ mode: "propose",
12
+ purpose: "Prepare change plans, patches, or remediation guidance without applying them.",
13
+ mutatesFiles: !1,
14
+ mutatesRuntime: !1
15
+ },
16
+ {
17
+ mode: "apply",
18
+ purpose: "Write code or config changes in the repository without operating long-running runtime surfaces.",
19
+ mutatesFiles: !0,
20
+ mutatesRuntime: !1
21
+ },
22
+ {
23
+ mode: "operate",
24
+ purpose: "Perform runtime-facing actions such as deploy, worker, bridge, or incident operations with explicit operator intent.",
25
+ mutatesFiles: !0,
26
+ mutatesRuntime: !0
27
+ }
28
+ ], AI_TRANSPORT_CONTRACT = {
29
+ modelTraffic: "provider-direct-or-self-hosted",
30
+ bridgeRole: "diagnostics-and-ingestion-only",
31
+ productionRole: "must-not-sit-on-the-runtime-request-path"
32
+ };
33
+ export function renderDefaultAIRulesMarkdown(input) {
34
+ return [
35
+ "# AI Rules",
36
+ "",
37
+ `Project: ${input.projectName}`,
38
+ `App Mode: ${input.appMode}`,
39
+ "",
40
+ "## Defaults",
41
+ "",
42
+ "- Start in `inspect` mode unless the task clearly requires mutation.",
43
+ "- Prefer `propose` before `apply` when requirements are still ambiguous.",
44
+ "- Use `operate` only for deploy, worker, bridge, incident, or other runtime-facing actions.",
45
+ "- Before `apply` or `operate`, write an explicit checkpoint with `gorsee ai checkpoint --mode <mode>`.",
46
+ "- Treat `gorsee/client` and `gorsee/server` boundaries as framework contracts, not convenience suggestions.",
47
+ "- Prefer scoped stable subpaths (`gorsee/auth`, `gorsee/forms`, `gorsee/routes`, etc.) when the concern is already domain-specific.",
48
+ "",
49
+ "## Safety",
50
+ "",
51
+ "- Keep model traffic provider-direct or self-hosted when integrating external models.",
52
+ "- Do not place AI bridge transport on the production request path.",
53
+ "- Prefer structured artifacts in `.gorsee/` over scraped logs.",
54
+ "- Run `gorsee check` after mutating AI workflows.",
55
+ "",
56
+ "## Local Notes",
57
+ "",
58
+ "- Record project-specific constraints here instead of repeating them in every prompt.",
59
+ "- Add product, security, deploy, or incident rules here when this repo develops stronger local requirements.",
60
+ ""
61
+ ].join(`
62
+ `);
63
+ }
64
+ export function renderDefaultAIGuideMarkdown(input) {
65
+ return [
66
+ "# Gorsee AI Local Guide",
67
+ "",
68
+ `Project: ${input.projectName}`,
69
+ `App Mode: ${input.appMode}`,
70
+ "",
71
+ "This file is the local operator-facing AI guide for the repository.",
72
+ "",
73
+ "## Canonical Files",
74
+ "",
75
+ "- `.gorsee/rules.md` is the canonical local rules file consumed by Gorsee AI workflows.",
76
+ "- `AGENTS.md` remains the primary repository contract when present.",
77
+ "- `FRAMEWORK.md` remains the app/framework reference when present.",
78
+ "",
79
+ "## Recommended Workflow",
80
+ "",
81
+ "1. Run `gorsee ai framework --format markdown` for cold-start context.",
82
+ "2. Keep the session in `inspect` or `propose` until mutation is justified.",
83
+ "3. Before `apply` or `operate`, run `gorsee ai checkpoint --mode <mode>`.",
84
+ "4. Use `gorsee ai pack` for handoff and `gorsee ai doctor` for diagnostics-first triage.",
85
+ "5. Run `gorsee check` after mutating work.",
86
+ "",
87
+ "## Local Customization",
88
+ "",
89
+ "- Extend `.gorsee/rules.md` with repo-specific constraints.",
90
+ "- Add team-specific AI operating notes here only when they are broader than per-task instructions.",
91
+ ""
92
+ ].join(`
93
+ `);
94
+ }
95
+ const RULES_CANDIDATES = [
96
+ ".gorsee/rules.md",
97
+ "GORSEE.md"
98
+ ];
99
+ async function pathExists(path) {
100
+ try {
101
+ await access(path);
102
+ return !0;
103
+ } catch {
104
+ return !1;
105
+ }
106
+ }
107
+ export async function resolveAIRulesFile(cwd) {
108
+ for (const candidate of RULES_CANDIDATES) {
109
+ const absolutePath = join(cwd, candidate);
110
+ if (!await pathExists(absolutePath))
111
+ continue;
112
+ return {
113
+ path: candidate,
114
+ content: await readFile(absolutePath, "utf-8")
115
+ };
116
+ }
117
+ return;
118
+ }
@@ -1,5 +1,6 @@
1
1
  import type { AIStorePaths } from "./store.js";
2
2
  import { type AIContextBundle } from "./bundle.js";
3
+ import type { AIOperationMode } from "./rules.js";
3
4
  export interface AISessionPackConfig {
4
5
  enabled?: boolean;
5
6
  outDir?: string;
@@ -8,6 +9,7 @@ export interface AISessionPackConfig {
8
9
  limit?: number;
9
10
  maxSnippets?: number;
10
11
  formats?: Array<"json" | "markdown">;
12
+ mode?: AIOperationMode;
11
13
  }
12
14
  export interface AISessionPackPaths {
13
15
  outDir: string;
@@ -45,7 +45,8 @@ export function resolveAISessionPackPaths(cwd, config) {
45
45
  export async function writeAISessionPack(cwd, storePaths, config) {
46
46
  const resolved = resolveAISessionPackConfig(cwd, { enabled: !0, ...config ?? {} }), paths = resolveAISessionPackPaths(cwd, resolved), bundle = await buildAIContextBundle(cwd, storePaths, {
47
47
  limit: resolved.limit,
48
- maxSnippets: resolved.maxSnippets
48
+ maxSnippets: resolved.maxSnippets,
49
+ mode: resolved.mode
49
50
  });
50
51
  await mkdir(paths.historyDir, { recursive: !0 });
51
52
  const stamp = bundle.generatedAt.replace(/[:.]/g, "-"), deploySummary = createAIDeploySummary(bundle.packet), releaseBrief = createAIReleaseBrief(bundle.packet), incidentBrief = createAIIncidentBrief(bundle.packet), incidentSnapshot = createAIIncidentSnapshot(bundle.packet), json = JSON.stringify(bundle, null, 2), markdown = [
@@ -1,9 +1,28 @@
1
1
  import type { AIDiagnostic, AIEvent } from "./index.js";
2
2
  import type { AIHealthReport } from "./store.js";
3
3
  import type { ReactiveTraceArtifact } from "../reactive/diagnostics.js";
4
+ import { type AIOperationMode, type AIRulesFile } from "./rules.js";
4
5
  export interface AIContextPacket {
5
6
  schemaVersion: string;
6
7
  generatedAt: string;
8
+ agent: {
9
+ currentMode: AIOperationMode;
10
+ availableModes: Array<{
11
+ mode: AIOperationMode;
12
+ purpose: string;
13
+ mutatesFiles: boolean;
14
+ mutatesRuntime: boolean;
15
+ }>;
16
+ transport: {
17
+ modelTraffic: string;
18
+ bridgeRole: string;
19
+ productionRole: string;
20
+ };
21
+ rules?: {
22
+ path: string;
23
+ content: string;
24
+ };
25
+ };
7
26
  app?: {
8
27
  mode: "frontend" | "fullstack" | "server";
9
28
  runtimeTopology: "single-instance" | "multi-instance";
@@ -133,7 +152,10 @@ export interface AIIncidentSnapshot {
133
152
  hotspots: AIContextPacket["hotspots"];
134
153
  recommendations: string[];
135
154
  }
136
- export declare function createAIContextPacket(report: AIHealthReport, events: AIEvent[], latestDiagnostic?: Partial<AIDiagnostic>, reactiveTrace?: ReactiveTraceArtifact | null): AIContextPacket;
155
+ export declare function createAIContextPacket(report: AIHealthReport, events: AIEvent[], latestDiagnostic?: Partial<AIDiagnostic>, reactiveTrace?: ReactiveTraceArtifact | null, agentInput?: {
156
+ currentMode?: AIOperationMode;
157
+ rules?: AIRulesFile;
158
+ }): AIContextPacket;
137
159
  export declare function renderAIContextMarkdown(packet: AIContextPacket): string;
138
160
  export declare function createAIReleaseBrief(packet: AIContextPacket): AIReleaseBrief;
139
161
  export declare function renderAIReleaseBriefMarkdown(brief: AIReleaseBrief): string;