@lsctech/polaris 0.3.17 → 0.3.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/adopt-canon.js +24 -45
- package/package.json +1 -1
package/dist/cli/adopt-canon.js
CHANGED
|
@@ -98,6 +98,24 @@ function injectLinkedDocs(content, docs, summaryLines) {
|
|
|
98
98
|
: lines.slice(headingIdx + 1);
|
|
99
99
|
return [...before, ...yamlLines, ...after].join("\n");
|
|
100
100
|
}
|
|
101
|
+
function parseCanonResponse(text) {
|
|
102
|
+
const trimmed = text.trim();
|
|
103
|
+
const jsonLine = trimmed.split("\n").reverse().find((l) => l.trim().startsWith("{") && l.includes("relevant_docs"));
|
|
104
|
+
if (jsonLine) {
|
|
105
|
+
try {
|
|
106
|
+
return JSON.parse(jsonLine);
|
|
107
|
+
}
|
|
108
|
+
catch { /* fall through */ }
|
|
109
|
+
}
|
|
110
|
+
const blockMatch = trimmed.match(/\{[\s\S]*"relevant_docs"[\s\S]*\}/);
|
|
111
|
+
if (blockMatch) {
|
|
112
|
+
try {
|
|
113
|
+
return JSON.parse(blockMatch[0]);
|
|
114
|
+
}
|
|
115
|
+
catch { /* fall through */ }
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
101
119
|
// Strip flags that require worker permissions and aren't needed for reasoning-only calls.
|
|
102
120
|
function stripWorkerFlags(args) {
|
|
103
121
|
const stripped = [];
|
|
@@ -127,6 +145,7 @@ function dispatchCanonAgent(options) {
|
|
|
127
145
|
return null;
|
|
128
146
|
const cfg = providers[providerName];
|
|
129
147
|
const docList = doctrineDocs
|
|
148
|
+
.slice(0, 30)
|
|
130
149
|
.map((d, i) => `${i + 1}. [${d.title}] path: ${d.path}`)
|
|
131
150
|
.join("\n");
|
|
132
151
|
const prompt = `You are a Polaris librarian generating context files for an agent work area.
|
|
@@ -147,29 +166,13 @@ Respond with ONLY valid JSON on a single line:
|
|
|
147
166
|
{"relevant_docs":[{"path":"<doc path>","title":"<doc title>"}],"summary_lines":["line1","line2"],"polaris_lines":["line1","line2"]}
|
|
148
167
|
|
|
149
168
|
If no doctrine docs are relevant, return an empty array for relevant_docs.`;
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
// When cfg.command is "env", extract KEY=VALUE prefix args into the spawn env
|
|
155
|
-
// so credentials and env vars are inherited correctly by the subprocess.
|
|
156
|
-
let spawnCmd = cfg.command;
|
|
157
|
-
let spawnArgs = args;
|
|
158
|
-
const extraEnv = {};
|
|
159
|
-
if (cfg.command === "env") {
|
|
160
|
-
const firstNonEnvIdx = args.findIndex((a) => !a.includes("=") || a.startsWith("-"));
|
|
161
|
-
for (const a of args.slice(0, firstNonEnvIdx)) {
|
|
162
|
-
const [k, ...v] = a.split("=");
|
|
163
|
-
extraEnv[k] = v.join("=");
|
|
164
|
-
}
|
|
165
|
-
spawnCmd = args[firstNonEnvIdx];
|
|
166
|
-
spawnArgs = args.slice(firstNonEnvIdx + 1);
|
|
167
|
-
}
|
|
168
|
-
const result = (0, node_child_process_1.spawnSync)(spawnCmd, spawnArgs, {
|
|
169
|
+
// Same dispatch pattern as dispatchLibrarianReview — pass args straight through,
|
|
170
|
+
// letting the provider config (e.g. env CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=0) handle auth.
|
|
171
|
+
const args = (cfg.args ?? []).map((a) => (a === "{{worker_prompt}}" ? prompt : a));
|
|
172
|
+
const result = (0, node_child_process_1.spawnSync)(cfg.command, stripWorkerFlags(args), {
|
|
169
173
|
encoding: "utf-8",
|
|
170
174
|
timeout: 120000,
|
|
171
175
|
cwd: repoRoot,
|
|
172
|
-
env: { ...process.env, ...extraEnv },
|
|
173
176
|
});
|
|
174
177
|
if (result.error) {
|
|
175
178
|
console.log(` agent error: ${result.error.message}`);
|
|
@@ -179,31 +182,7 @@ If no doctrine docs are relevant, return an empty array for relevant_docs.`;
|
|
|
179
182
|
console.log(` agent stderr: ${result.stderr.trim().slice(0, 200)}`);
|
|
180
183
|
}
|
|
181
184
|
const stdout = (result.stdout ?? "").trim();
|
|
182
|
-
|
|
183
|
-
// Try single-line JSON first (ideal case)
|
|
184
|
-
const jsonLine = stdout
|
|
185
|
-
.split("\n")
|
|
186
|
-
.reverse()
|
|
187
|
-
.find((l) => l.trim().startsWith("{") && l.includes("relevant_docs"));
|
|
188
|
-
if (jsonLine) {
|
|
189
|
-
try {
|
|
190
|
-
return JSON.parse(jsonLine);
|
|
191
|
-
}
|
|
192
|
-
catch {
|
|
193
|
-
// fall through to block extraction
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
// Try extracting JSON block (handles multi-line or code-fenced output)
|
|
197
|
-
const blockMatch = stdout.match(/\{[\s\S]*"relevant_docs"[\s\S]*\}/);
|
|
198
|
-
if (blockMatch) {
|
|
199
|
-
try {
|
|
200
|
-
return JSON.parse(blockMatch[0]);
|
|
201
|
-
}
|
|
202
|
-
catch {
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return null;
|
|
185
|
+
return parseCanonResponse(stdout);
|
|
207
186
|
}
|
|
208
187
|
async function enrichCanonFiles(repoRoot) {
|
|
209
188
|
let config = null;
|