@lsctech/polaris 0.3.29 → 0.4.1

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 (40) hide show
  1. package/dist/agent-plugin/args.js +77 -0
  2. package/dist/agent-plugin/claude-generator.js +158 -0
  3. package/dist/agent-plugin/commands.js +73 -0
  4. package/dist/agent-plugin/help.js +69 -0
  5. package/dist/agent-plugin/sync.js +108 -0
  6. package/dist/autoresearch/dev-gate.js +51 -0
  7. package/dist/autoresearch/gates.js +310 -0
  8. package/dist/autoresearch/index.js +20 -0
  9. package/dist/autoresearch/proposal.js +121 -0
  10. package/dist/autoresearch/routing.js +180 -0
  11. package/dist/autoresearch/score.js +213 -0
  12. package/dist/cli/adopt-approve.js +124 -4
  13. package/dist/cli/adopt-assets.js +9 -1
  14. package/dist/cli/adopt-command.js +123 -11
  15. package/dist/cli/adopt-instructions.js +17 -2
  16. package/dist/cli/adopt-smartdocs.js +9 -0
  17. package/dist/cli/adoption-context.js +46 -0
  18. package/dist/cli/adoption-plan.js +105 -12
  19. package/dist/cli/agent-setup.js +47 -0
  20. package/dist/cli/autoresearch.js +96 -0
  21. package/dist/cli/index.js +2 -0
  22. package/dist/cli/init.js +69 -1
  23. package/dist/cli/setup-interview/generate.js +380 -0
  24. package/dist/cli/setup-interview/report.js +138 -0
  25. package/dist/cli/setup-interview/runner.js +105 -0
  26. package/dist/cli/setup-interview/schema.js +16 -0
  27. package/dist/cli/setup-interview/store.js +73 -0
  28. package/dist/cli/worker.js +18 -8
  29. package/dist/finalize/index.js +5 -4
  30. package/dist/loop/adapters/foreman-dispatch.js +65 -0
  31. package/dist/loop/adapters/index.js +3 -1
  32. package/dist/loop/bootstrap-packet.js +1 -1
  33. package/dist/loop/checkpoint.js +120 -1
  34. package/dist/loop/continue.js +13 -5
  35. package/dist/loop/parent.js +129 -1
  36. package/dist/loop/resume.js +14 -8
  37. package/dist/loop/worker-packet.js +1 -1
  38. package/dist/skill-packet/generator.js +149 -1
  39. package/dist/workspace/.polaris/skills/polaris-tools/tools.js +31 -22
  40. package/package.json +2 -2
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadOperatorContext = loadOperatorContext;
4
+ exports.saveOperatorContext = saveOperatorContext;
5
+ exports.createEmptyOperatorContext = createEmptyOperatorContext;
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ const ADOPTION_DIR = (0, node_path_1.join)(".polaris", "adoption");
9
+ const CONTEXT_FILE = "operator-context.json";
10
+ function contextPath(repoRoot) {
11
+ return (0, node_path_1.join)(repoRoot, ADOPTION_DIR, CONTEXT_FILE);
12
+ }
13
+ function loadOperatorContext(repoRoot) {
14
+ const path = contextPath(repoRoot);
15
+ if (!(0, node_fs_1.existsSync)(path))
16
+ return null;
17
+ try {
18
+ const parsed = JSON.parse((0, node_fs_1.readFileSync)(path, "utf-8"));
19
+ if (!Array.isArray(parsed?.trusted_docs) ||
20
+ !Array.isArray(parsed?.never_touch) ||
21
+ typeof parsed?.instruction_file_intent !== "object" ||
22
+ parsed?.instruction_file_intent === null ||
23
+ Array.isArray(parsed?.instruction_file_intent)) {
24
+ return null;
25
+ }
26
+ return parsed;
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
32
+ function saveOperatorContext(repoRoot, context) {
33
+ (0, node_fs_1.mkdirSync)((0, node_path_1.join)(repoRoot, ADOPTION_DIR), { recursive: true });
34
+ (0, node_fs_1.writeFileSync)(contextPath(repoRoot), `${JSON.stringify(context, null, 2)}\n`, "utf-8");
35
+ }
36
+ function createEmptyOperatorContext(now) {
37
+ return {
38
+ schema_version: "1.0",
39
+ answered_at: (now ?? new Date()).toISOString(),
40
+ trusted_docs: [],
41
+ stale_docs: [],
42
+ never_touch: [],
43
+ priority_systems: [],
44
+ instruction_file_intent: {},
45
+ };
46
+ }
@@ -11,14 +11,49 @@ function formatPlanId(isoTimestamp) {
11
11
  function normalizePath(path) {
12
12
  return path.endsWith("/") ? path.slice(0, -1) : path;
13
13
  }
14
+ function isTrusted(path, operatorContext) {
15
+ const normalized = normalizePath(path);
16
+ return operatorContext?.trusted_docs.some((p) => normalizePath(p) === normalized) ?? false;
17
+ }
18
+ function isStale(path, operatorContext) {
19
+ const normalized = normalizePath(path);
20
+ return operatorContext?.stale_docs.some((p) => normalizePath(p) === normalized) ?? false;
21
+ }
22
+ function isNeverTouch(path, operatorContext) {
23
+ const normalized = normalizePath(path);
24
+ return operatorContext?.never_touch.some((p) => normalizePath(p) === normalized) ?? false;
25
+ }
26
+ function instructionIntent(path, operatorContext) {
27
+ return operatorContext?.instruction_file_intent[path];
28
+ }
29
+ function deriveSmartDocsRouting(candidate, operatorContext) {
30
+ const evidence_refs = [`scan:smartdocs_candidate:${candidate.path}`];
31
+ const operator_refs = [];
32
+ if (isNeverTouch(candidate.path, operatorContext) || isStale(candidate.path, operatorContext)) {
33
+ if (isNeverTouch(candidate.path, operatorContext))
34
+ operator_refs.push(`operator:never_touch:${candidate.path}`);
35
+ if (isStale(candidate.path, operatorContext))
36
+ operator_refs.push(`operator:stale_docs:${candidate.path}`);
37
+ return { routing: "hold", evidence_refs, operator_refs };
38
+ }
39
+ if (isTrusted(candidate.path, operatorContext)) {
40
+ operator_refs.push(`operator:trusted_docs:${candidate.path}`);
41
+ return { routing: "candidate", evidence_refs, operator_refs };
42
+ }
43
+ return { routing: "review-required", evidence_refs, operator_refs };
44
+ }
14
45
  function createStep(order, partial) {
46
+ const { evidence_refs, operator_refs, routing, ...rest } = partial;
15
47
  return {
16
- ...partial,
48
+ evidence_refs: evidence_refs ?? [],
49
+ operator_refs: operator_refs ?? [],
50
+ routing: routing ?? "candidate",
51
+ ...rest,
17
52
  order,
18
53
  status: "pending",
19
54
  };
20
55
  }
21
- function buildSteps(inventory) {
56
+ function buildSteps(inventory, operatorContext) {
22
57
  const steps = [];
23
58
  let order = 1;
24
59
  steps.push(createStep(order++, {
@@ -31,6 +66,9 @@ function buildSteps(inventory) {
31
66
  destructive: true,
32
67
  requires_approval: false,
33
68
  estimated_risk: "low",
69
+ routing: "candidate",
70
+ evidence_refs: ["adoption:step:provider-config-lock"],
71
+ operator_refs: [],
34
72
  }));
35
73
  steps.push(createStep(order++, {
36
74
  step_id: "adoption-scaffold",
@@ -42,6 +80,9 @@ function buildSteps(inventory) {
42
80
  destructive: false,
43
81
  requires_approval: false,
44
82
  estimated_risk: "low",
83
+ routing: "candidate",
84
+ evidence_refs: ["adoption:step:adoption-scaffold"],
85
+ operator_refs: [],
45
86
  }));
46
87
  steps.push(createStep(order++, {
47
88
  step_id: "workspace-root-surfaces",
@@ -53,10 +94,15 @@ function buildSteps(inventory) {
53
94
  destructive: false,
54
95
  requires_approval: false,
55
96
  estimated_risk: "low",
97
+ routing: "candidate",
98
+ evidence_refs: ["adoption:step:workspace-root-surfaces"],
99
+ operator_refs: [],
56
100
  }));
57
101
  for (const candidate of inventory.smartdocs_candidates) {
58
- steps.push(createStep(order++, {
59
- step_id: `smartdocs-migrate-${order.toString().padStart(3, "0")}`,
102
+ const { routing, evidence_refs, operator_refs } = deriveSmartDocsRouting(candidate, operatorContext);
103
+ const stepOrder = order++;
104
+ steps.push(createStep(stepOrder, {
105
+ step_id: `smartdocs-migrate-${stepOrder.toString().padStart(3, "0")}`,
60
106
  phase: "C",
61
107
  category: "smartdocs-migrate",
62
108
  action: "move",
@@ -66,12 +112,27 @@ function buildSteps(inventory) {
66
112
  destructive: true,
67
113
  requires_approval: true,
68
114
  estimated_risk: candidate.estimated_risk,
115
+ routing,
116
+ evidence_refs,
117
+ operator_refs,
69
118
  }));
70
119
  }
71
120
  for (const folder of inventory.likely_canonical_folders) {
72
121
  const normalizedFolder = normalizePath(folder);
73
- steps.push(createStep(order++, {
74
- step_id: `cognition-generate-${order.toString().padStart(3, "0")}`,
122
+ const evidence_refs = [`scan:canonical_folder:${normalizedFolder}`];
123
+ const operator_refs = [];
124
+ let routing = "raw";
125
+ if (isNeverTouch(normalizedFolder, operatorContext)) {
126
+ routing = "hold";
127
+ operator_refs.push(`operator:never_touch:${normalizedFolder}`);
128
+ }
129
+ else if (isTrusted(normalizedFolder, operatorContext)) {
130
+ routing = "candidate";
131
+ operator_refs.push(`operator:trusted_docs:${normalizedFolder}`);
132
+ }
133
+ const stepOrder = order++;
134
+ steps.push(createStep(stepOrder, {
135
+ step_id: `cognition-generate-${stepOrder.toString().padStart(3, "0")}`,
75
136
  phase: "C",
76
137
  category: "cognition-generate",
77
138
  action: "create",
@@ -80,6 +141,9 @@ function buildSteps(inventory) {
80
141
  destructive: false,
81
142
  requires_approval: true,
82
143
  estimated_risk: "medium",
144
+ routing,
145
+ evidence_refs,
146
+ operator_refs,
83
147
  }));
84
148
  }
85
149
  for (const file of inventory.agent_instruction_files) {
@@ -90,8 +154,24 @@ function buildSteps(inventory) {
90
154
  : file.recommendation === "thin-adapter"
91
155
  ? "medium"
92
156
  : "low";
93
- steps.push(createStep(order++, {
94
- step_id: `instruction-refactor-${order.toString().padStart(3, "0")}`,
157
+ const evidence_refs = [`scan:agent_instruction_file:${file.path}`];
158
+ const operator_refs = [];
159
+ const intent = instructionIntent(file.path, operatorContext);
160
+ let routing;
161
+ if (intent === "preserve") {
162
+ routing = "hold";
163
+ operator_refs.push(`operator:instruction_file_intent:${file.path}:preserve`);
164
+ }
165
+ else if (intent === "migrate" || intent === "thin-adapter") {
166
+ routing = "candidate";
167
+ operator_refs.push(`operator:instruction_file_intent:${file.path}:${intent}`);
168
+ }
169
+ else {
170
+ routing = "review-required";
171
+ }
172
+ const stepOrder = order++;
173
+ steps.push(createStep(stepOrder, {
174
+ step_id: `instruction-refactor-${stepOrder.toString().padStart(3, "0")}`,
95
175
  phase: "C",
96
176
  category: "instruction-refactor",
97
177
  action,
@@ -105,11 +185,15 @@ function buildSteps(inventory) {
105
185
  destructive,
106
186
  requires_approval: destructive,
107
187
  estimated_risk: risk,
188
+ routing,
189
+ evidence_refs,
190
+ operator_refs,
108
191
  }));
109
192
  }
110
193
  for (const ignorePath of inventory.ignore_candidates) {
111
- steps.push(createStep(order++, {
112
- step_id: `ignore-rules-${order.toString().padStart(3, "0")}`,
194
+ const stepOrder = order++;
195
+ steps.push(createStep(stepOrder, {
196
+ step_id: `ignore-rules-${stepOrder.toString().padStart(3, "0")}`,
113
197
  phase: "C",
114
198
  category: "ignore-rules",
115
199
  action: "append",
@@ -118,6 +202,9 @@ function buildSteps(inventory) {
118
202
  destructive: true,
119
203
  requires_approval: true,
120
204
  estimated_risk: "low",
205
+ routing: "candidate",
206
+ evidence_refs: [`scan:ignore_candidate:${ignorePath}`],
207
+ operator_refs: [],
121
208
  }));
122
209
  }
123
210
  steps.push(createStep(order++, {
@@ -130,6 +217,9 @@ function buildSteps(inventory) {
130
217
  destructive: true,
131
218
  requires_approval: true,
132
219
  estimated_risk: "medium",
220
+ routing: "candidate",
221
+ evidence_refs: ["adoption:step:atlas-generate"],
222
+ operator_refs: [],
133
223
  }));
134
224
  steps.push(createStep(order++, {
135
225
  step_id: "stage-adoption",
@@ -141,6 +231,9 @@ function buildSteps(inventory) {
141
231
  destructive: true,
142
232
  requires_approval: true,
143
233
  estimated_risk: "medium",
234
+ routing: "candidate",
235
+ evidence_refs: ["adoption:step:stage-adoption"],
236
+ operator_refs: [],
144
237
  }));
145
238
  return steps;
146
239
  }
@@ -160,7 +253,7 @@ function buildImpactSummary(steps, inventory) {
160
253
  }
161
254
  function generateAdoptionPlan(inventory, options = {}) {
162
255
  const generatedAt = (options.now ?? new Date()).toISOString();
163
- const steps = buildSteps(inventory);
256
+ const steps = buildSteps(inventory, options.operatorContext);
164
257
  return {
165
258
  plan_id: formatPlanId(generatedAt),
166
259
  generated_at: generatedAt,
@@ -206,7 +299,7 @@ function renderAdoptionPlanMarkdown(plan) {
206
299
  for (const step of phaseSteps) {
207
300
  const source = step.source_path ? ` source: \`${step.source_path}\`` : "";
208
301
  const dest = step.dest_path ? ` destination: \`${step.dest_path}\`` : "";
209
- lines.push(`- **${step.order}. ${step.step_id}** — ${step.category} / ${step.action} / approval ${step.requires_approval ? "required" : "not required"} / risk ${step.estimated_risk} / status ${step.status}${source}${dest}`);
302
+ lines.push(`- **${step.order}. ${step.step_id}** — ${step.category} / ${step.action} / approval ${step.requires_approval ? "required" : "not required"} / risk ${step.estimated_risk} / routing ${step.routing} / status ${step.status}${source}${dest}`);
210
303
  lines.push(` - ${step.description}`);
211
304
  }
212
305
  lines.push("");
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveForeman = resolveForeman;
36
37
  exports.runAgentSetup = runAgentSetup;
37
38
  const node_child_process_1 = require("node:child_process");
38
39
  const readline = __importStar(require("node:readline"));
@@ -86,6 +87,52 @@ async function selectProvider(role, detected, currentProviders) {
86
87
  });
87
88
  });
88
89
  }
90
+ /**
91
+ * Resolves the Foreman provider for init/adopt.
92
+ *
93
+ * If `execution.providerPolicy.foreman.providers[0]` is already set in config,
94
+ * returns a binding immediately (no prompt). Otherwise prompts once, persists
95
+ * the choice to polaris.config.json, and returns the binding.
96
+ *
97
+ * The binding always references `.polaris/roles/foreman.md` — role text is not
98
+ * duplicated here.
99
+ */
100
+ async function resolveForeman(repoRoot, config, opts) {
101
+ const execution = config.execution ?? {};
102
+ const providerPolicy = execution.providerPolicy ?? {};
103
+ const foremanPolicy = providerPolicy.foreman ?? {};
104
+ const existing = foremanPolicy.providers?.[0];
105
+ const roleFile = ".polaris/roles/foreman.md";
106
+ if (existing) {
107
+ return { provider: existing, roleFile };
108
+ }
109
+ // Prompt once for Foreman provider
110
+ const detected = opts?.detectProviders?.() ?? detectProviders();
111
+ const chosen = opts?.selectProvider
112
+ ? await opts.selectProvider(detected)
113
+ : await selectProvider("foreman", detected, []);
114
+ if (!chosen) {
115
+ throw new Error("No supported agent installed. Cannot assign a Foreman. " +
116
+ "Install one of: " + SUPPORTED_PROVIDERS.map((p) => p.name).join(", "));
117
+ }
118
+ // Persist choice
119
+ const updatedPolicy = {
120
+ ...providerPolicy,
121
+ foreman: { ...foremanPolicy, providers: [chosen] },
122
+ };
123
+ const updatedConfig = {
124
+ ...config,
125
+ execution: { ...execution, providerPolicy: updatedPolicy },
126
+ };
127
+ const configPath = (0, node_path_1.resolve)(repoRoot, "polaris.config.json");
128
+ if (opts?.writeConfig) {
129
+ opts.writeConfig(configPath, updatedConfig);
130
+ }
131
+ else {
132
+ (0, node_fs_1.writeFileSync)(configPath, JSON.stringify(updatedConfig, null, 2) + "\n");
133
+ }
134
+ return { provider: chosen, roleFile };
135
+ }
89
136
  async function runAgentSetup(repoRoot) {
90
137
  console.log("\nPolaris Agent Setup — configure one provider per role\n");
91
138
  const detected = detectProviders();
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAutoresearchCommand = createAutoresearchCommand;
4
+ const node_path_1 = require("node:path");
5
+ const commander_1 = require("commander");
6
+ const dev_gate_js_1 = require("../autoresearch/dev-gate.js");
7
+ const score_js_1 = require("../autoresearch/score.js");
8
+ const proposal_js_1 = require("../autoresearch/proposal.js");
9
+ const routing_js_1 = require("../autoresearch/routing.js");
10
+ function createAutoresearchCommand(options) {
11
+ const repoRoot = options.repoRoot;
12
+ const autoresearch = new commander_1.Command("autoresearch")
13
+ .description("Autoresearch tools (dev-gated — Polaris development context only)")
14
+ .showHelpAfterError()
15
+ .showSuggestionAfterError();
16
+ autoresearch
17
+ .command("score <run-id>")
18
+ .description("Score a completed Polaris run against the binary gate scorecard and output a diagnosis report")
19
+ .option("-r, --repo-root <path>", "Repository root", repoRoot)
20
+ .option("--json", "Output raw JSON (default: pretty-printed)")
21
+ .action((runId, cmdOptions) => {
22
+ const root = (0, node_path_1.resolve)(cmdOptions.repoRoot ?? repoRoot);
23
+ try {
24
+ (0, dev_gate_js_1.assertPolarisDevContext)(root);
25
+ }
26
+ catch (err) {
27
+ process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
28
+ process.exit(1);
29
+ }
30
+ try {
31
+ const report = (0, score_js_1.scoreRun)(root, runId);
32
+ const output = cmdOptions.json
33
+ ? JSON.stringify(report)
34
+ : JSON.stringify(report, null, 2);
35
+ process.stdout.write(`${output}\n`);
36
+ }
37
+ catch (err) {
38
+ process.stderr.write(`autoresearch score error: ${err instanceof Error ? err.message : String(err)}\n`);
39
+ process.exit(1);
40
+ }
41
+ });
42
+ autoresearch
43
+ .command("propose <diagnosis-file>")
44
+ .description("File Linear improvement proposals from a diagnosis report (dev-gated — never auto-applied)")
45
+ .option("-r, --repo-root <path>", "Repository root", repoRoot)
46
+ .option("--team <team>", "Linear team name or ID to file issues in", "Polaris")
47
+ .option("--dry-run", "Log what would be created without calling Linear")
48
+ .option("--json", "Output raw JSON (default: pretty-printed)")
49
+ .action(async (diagnosisFile, cmdOptions) => {
50
+ const root = (0, node_path_1.resolve)(cmdOptions.repoRoot ?? repoRoot);
51
+ try {
52
+ (0, dev_gate_js_1.assertPolarisDevContext)(root);
53
+ }
54
+ catch (err) {
55
+ process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
56
+ process.exit(1);
57
+ }
58
+ let report;
59
+ try {
60
+ report = (0, proposal_js_1.loadDiagnosisReport)((0, node_path_1.resolve)(diagnosisFile));
61
+ }
62
+ catch (err) {
63
+ process.stderr.write(`autoresearch propose: invalid diagnosis file: ${err instanceof Error ? err.message : String(err)}\n`);
64
+ process.exit(1);
65
+ }
66
+ const proposals = (0, proposal_js_1.buildProposals)(report);
67
+ if (proposals.length === 0) {
68
+ process.stdout.write("No failed gates with fix zone mappings — nothing to propose.\n");
69
+ process.exit(0);
70
+ }
71
+ const apiKey = process.env["LINEAR_API_KEY"];
72
+ if (!apiKey && !cmdOptions.dryRun) {
73
+ process.stderr.write("autoresearch propose: LINEAR_API_KEY environment variable is required.\n");
74
+ process.exit(1);
75
+ }
76
+ try {
77
+ const result = await (0, routing_js_1.routeProposals)(proposals, {
78
+ apiKey: apiKey ?? "",
79
+ teamKey: cmdOptions.team,
80
+ dryRun: cmdOptions.dryRun,
81
+ });
82
+ const output = cmdOptions.json
83
+ ? JSON.stringify(result)
84
+ : JSON.stringify(result, null, 2);
85
+ process.stdout.write(`${output}\n`);
86
+ if (result.total_errors > 0) {
87
+ process.exit(1);
88
+ }
89
+ }
90
+ catch (err) {
91
+ process.stderr.write(`autoresearch propose error: ${err instanceof Error ? err.message : String(err)}\n`);
92
+ process.exit(1);
93
+ }
94
+ });
95
+ return autoresearch;
96
+ }
package/dist/cli/index.js CHANGED
@@ -28,6 +28,7 @@ const medic_js_1 = require("./medic.js");
28
28
  const welfare_js_1 = require("../map/welfare.js");
29
29
  const adopt_command_js_1 = require("./adopt-command.js");
30
30
  const simplicity_js_1 = require("../loop/simplicity.js");
31
+ const autoresearch_js_1 = require("./autoresearch.js");
31
32
  function resolveStateFile(repoRoot, explicit) {
32
33
  if (explicit)
33
34
  return (0, node_path_1.resolve)(explicit);
@@ -109,6 +110,7 @@ function createPolarisCommand(options = {}) {
109
110
  repoRoot,
110
111
  }));
111
112
  program.addCommand((0, adopt_command_js_1.createAdoptCommand)({ repoRoot }));
113
+ program.addCommand((0, autoresearch_js_1.createAutoresearchCommand)({ repoRoot }));
112
114
  program
113
115
  .command("simplicity")
114
116
  .description("View or override the simplicity discipline mode for the active run")
package/dist/cli/init.js CHANGED
@@ -21,9 +21,15 @@ const index_js_1 = require("../map/index.js");
21
21
  const adopt_instructions_js_1 = require("./adopt-instructions.js");
22
22
  const adopt_workspace_js_1 = require("./adopt-workspace.js");
23
23
  const adopt_assets_js_1 = require("./adopt-assets.js");
24
+ const agent_setup_js_1 = require("./agent-setup.js");
25
+ const runner_js_1 = require("./setup-interview/runner.js");
26
+ const generate_js_1 = require("./setup-interview/generate.js");
27
+ const generator_js_1 = require("../skill-packet/generator.js");
28
+ const foreman_dispatch_js_1 = require("../loop/adapters/foreman-dispatch.js");
24
29
  const adopt_genesis_js_1 = require("./adopt-genesis.js");
25
30
  const adopt_report_js_1 = require("./adopt-report.js");
26
31
  const artifact_policy_js_1 = require("../finalize/artifact-policy.js");
32
+ const report_js_1 = require("./setup-interview/report.js");
27
33
  var init_detect_js_2 = require("./init-detect.js");
28
34
  Object.defineProperty(exports, "detectRepoState", { enumerable: true, get: function () { return init_detect_js_2.detectRepoState; } });
29
35
  const PLAN_COMPLETE_STATUSES = new Set(["completed", "skipped"]);
@@ -377,6 +383,50 @@ async function runInit(options = {}) {
377
383
  process.stdout.write("This repo has existing content. Run `polaris init --adopt` to begin adoption.\nThis repo has existing content. Run polaris init --adopt to begin adoption.\n");
378
384
  return;
379
385
  }
386
+ // New/empty repo: run the setup interview and generate artifacts behind an approval gate.
387
+ if (!options.adopt && (repoState === "empty" || repoState === "new")) {
388
+ const interviewFn = options.runInterview ?? runner_js_1.runInterview;
389
+ let record;
390
+ try {
391
+ record = await interviewFn(repoRoot, { now: options.now });
392
+ }
393
+ catch (err) {
394
+ const msg = err instanceof Error ? err.message : String(err);
395
+ process.stdout.write(`${msg}\n`);
396
+ return;
397
+ }
398
+ const detected = detectCompaction(repoRoot);
399
+ const detectedRepoAnalysis = detectRepoAnalysis(repoRoot);
400
+ const generateFn = options.generateSetupArtifacts ?? generate_js_1.generateSetupArtifacts;
401
+ await generateFn(record, {
402
+ repoRoot,
403
+ dryRun: options.dryRun,
404
+ yes: options.yes,
405
+ now: options.now,
406
+ detectedProviders: detected,
407
+ detectedRepoAnalysis,
408
+ scaffoldRootSurfaces: options.scaffoldRootSurfaces,
409
+ generatePolarisRules: options.generatePolarisRules,
410
+ migrateSmartDocs: options.migrateSmartDocs,
411
+ runMapIndex: options.runMapIndex,
412
+ });
413
+ // Post-setup validation and checkpoint report
414
+ if (!options.dryRun) {
415
+ const checkpointReport = (0, report_js_1.buildCheckpointReport)({
416
+ repoRoot,
417
+ record,
418
+ now: options.now,
419
+ });
420
+ (0, report_js_1.writeCheckpointReport)(repoRoot, checkpointReport);
421
+ (0, report_js_1.printCheckpointReport)(checkpointReport);
422
+ // Check for validation failures
423
+ const failedValidations = Object.entries(checkpointReport.validationResults).filter(([_, result]) => !result.passed);
424
+ if (failedValidations.length > 0) {
425
+ process.stdout.write(`\nWarning: ${failedValidations.length} file(s) failed validation. Check the report above for details.\n`);
426
+ }
427
+ }
428
+ return;
429
+ }
380
430
  // Load existing config (if any) so we preserve user-authored fields.
381
431
  let existing = {};
382
432
  if ((0, node_fs_1.existsSync)(configPath)) {
@@ -415,6 +465,24 @@ async function runInit(options = {}) {
415
465
  process.stdout.write(`polaris.config.json written to ${configPath}\n${providerSummary}\n`);
416
466
  }
417
467
  if (!options.adopt) {
468
+ // Launch Foreman with setup-bootstrap packet when execution providers are configured.
469
+ const initExecution = asRecord(updated.execution);
470
+ const initProviders = asRecord(initExecution.providers);
471
+ if (Object.keys(initProviders).length > 0) {
472
+ try {
473
+ const binding = await (0, agent_setup_js_1.resolveForeman)(repoRoot, updated);
474
+ const setupPacket = (0, generator_js_1.generateSetupBootstrapPacket)("init");
475
+ await (0, foreman_dispatch_js_1.dispatchForeman)({
476
+ packet: setupPacket,
477
+ provider: binding.provider,
478
+ executionConfig: updated.execution,
479
+ dryRun: options.dryRun,
480
+ });
481
+ }
482
+ catch {
483
+ // Foreman dispatch is best-effort during init — don't block setup.
484
+ }
485
+ }
418
486
  return;
419
487
  }
420
488
  const adoptionPlanPath = (0, node_path_1.join)(repoRoot, ".polaris", "adoption-plan.json");
@@ -548,7 +616,7 @@ function createInitCommand(options = {}) {
548
616
  .option("--status", "detect and print current repository state without writing files")
549
617
  .option("--adopt", "run existing repository adoption flow")
550
618
  .option("--resume", "resume an approved adoption plan without prompting")
551
- .option("--yes", "auto-approve adoption plan when used with --adopt")
619
+ .option("--yes", "auto-approve setup or adoption plan without prompting")
552
620
  .option("--commit", "create an adoption commit when used with --adopt")
553
621
  .action(async (cmdOptions) => {
554
622
  await runInit({