@lsctech/polaris 0.4.2 → 0.4.3
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/agent-plugin/claude-generator.js +3 -3
- package/dist/agent-plugin/codex-generator.js +131 -0
- package/dist/agent-plugin/commands.js +46 -1
- package/dist/agent-plugin/sync.js +5 -0
- package/dist/autoresearch/gates.js +58 -5
- package/dist/autoresearch/score.js +15 -3
- package/package.json +1 -1
|
@@ -46,7 +46,7 @@ const commands_js_1 = require("./commands.js");
|
|
|
46
46
|
* `.claude/commands/polaris-<verb>.md` file per verb.
|
|
47
47
|
*
|
|
48
48
|
* Skill-backed verbs route through the existing packet+chain path:
|
|
49
|
-
* 1. Read .polaris/skills/<skill>/SKILL.md
|
|
49
|
+
* 1. Read .polaris/skills/<target-skill>/SKILL.md
|
|
50
50
|
* 2. Run `polaris skill packet <skill>`
|
|
51
51
|
* 3. Execute the chain
|
|
52
52
|
*
|
|
@@ -96,8 +96,8 @@ See \`${command.routing}\` for the full routing protocol and skill directory res
|
|
|
96
96
|
|
|
97
97
|
## Execution
|
|
98
98
|
|
|
99
|
-
1. Look up \`/${command.name}\` in \`${command.routing}\` to
|
|
100
|
-
2. Read \`.polaris/skills
|
|
99
|
+
1. Look up \`/${command.name}\` in \`${command.routing}\` to confirm the target skill directory.
|
|
100
|
+
2. Read \`.polaris/skills/${command.targetSkill}/SKILL.md\` — it is the authoritative instruction source.
|
|
101
101
|
3. Run the skill bootloader:
|
|
102
102
|
\`\`\`bash
|
|
103
103
|
polaris skill packet ${command.skill}${command.args.length > 0 ? " $ARGUMENTS" : ""}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CODEX_PLUGIN_SKILL_VERSION = void 0;
|
|
37
|
+
exports.generateCodexPluginSkill = generateCodexPluginSkill;
|
|
38
|
+
exports.generateCodexOpenAiYaml = generateCodexOpenAiYaml;
|
|
39
|
+
exports.generateAllCodexPluginSkills = generateAllCodexPluginSkills;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const commands_js_1 = require("./commands.js");
|
|
43
|
+
exports.CODEX_PLUGIN_SKILL_VERSION = "1";
|
|
44
|
+
function skillCommands() {
|
|
45
|
+
return commands_js_1.SLASH_COMMANDS.filter((command) => command.kind === "skill");
|
|
46
|
+
}
|
|
47
|
+
function renderArgs(command) {
|
|
48
|
+
if (command.args.length === 0)
|
|
49
|
+
return "None.";
|
|
50
|
+
return command.args
|
|
51
|
+
.map((arg) => `- \`${arg.name}\`${arg.required ? " (required)" : " (optional)"} - ${arg.description}`)
|
|
52
|
+
.join("\n");
|
|
53
|
+
}
|
|
54
|
+
function renderUsage(command) {
|
|
55
|
+
const argUsage = command.args
|
|
56
|
+
.map((arg) => (arg.required ? `<${arg.name}>` : `[${arg.name}]`))
|
|
57
|
+
.join(" ");
|
|
58
|
+
return argUsage ? `${command.name} ${argUsage}` : command.name;
|
|
59
|
+
}
|
|
60
|
+
function renderBootloaderArgs(command) {
|
|
61
|
+
const argUsage = command.args
|
|
62
|
+
.map((arg) => (arg.required ? `<${arg.name}>` : `[${arg.name}]`))
|
|
63
|
+
.join(" ");
|
|
64
|
+
return argUsage ? ` ${argUsage}` : "";
|
|
65
|
+
}
|
|
66
|
+
function generateCodexPluginSkill(command) {
|
|
67
|
+
return `---
|
|
68
|
+
name: ${command.name}
|
|
69
|
+
description: ${command.description}
|
|
70
|
+
---
|
|
71
|
+
<!-- polaris-codex-skill-version: ${exports.CODEX_PLUGIN_SKILL_VERSION} -->
|
|
72
|
+
|
|
73
|
+
# ${command.name}
|
|
74
|
+
|
|
75
|
+
${command.description}
|
|
76
|
+
|
|
77
|
+
This Codex plugin skill is a thin wrapper around the canonical Polaris skill. It does not implement a parallel runtime.
|
|
78
|
+
|
|
79
|
+
## Usage
|
|
80
|
+
|
|
81
|
+
\`\`\`text
|
|
82
|
+
${renderUsage(command)}
|
|
83
|
+
\`\`\`
|
|
84
|
+
|
|
85
|
+
## Arguments
|
|
86
|
+
|
|
87
|
+
${renderArgs(command)}
|
|
88
|
+
|
|
89
|
+
## Mandatory Routing
|
|
90
|
+
|
|
91
|
+
1. Read \`${command.routing}\` and resolve \`${command.name}\` to its target skill.
|
|
92
|
+
2. Read \`.polaris/skills/${command.targetSkill}/SKILL.md\` before any repo inspection, tracker lookup, or runtime file reads.
|
|
93
|
+
3. Run the skill bootloader from that canonical \`SKILL.md\`:
|
|
94
|
+
\`\`\`bash
|
|
95
|
+
polaris skill packet ${command.skill}${renderBootloaderArgs(command)}
|
|
96
|
+
\`\`\`
|
|
97
|
+
4. If no packet is returned, stop and report: \`Blocking: Polaris could not authorize this run.\`
|
|
98
|
+
5. Execute \`.polaris/skills/${command.targetSkill}/chain.md\` in strict step order.
|
|
99
|
+
|
|
100
|
+
If \`.polaris/skills/${command.targetSkill}/SKILL.md\` is missing, stop and report:
|
|
101
|
+
\`Blocking: skill packet not found at .polaris/skills/${command.targetSkill}/SKILL.md\`
|
|
102
|
+
`;
|
|
103
|
+
}
|
|
104
|
+
function generateCodexOpenAiYaml(command) {
|
|
105
|
+
const displayName = command.name
|
|
106
|
+
.split("-")
|
|
107
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
108
|
+
.join(" ");
|
|
109
|
+
return `interface:
|
|
110
|
+
display_name: "${displayName}"
|
|
111
|
+
short_description: "${command.description.replaceAll('"', '\\"')}"
|
|
112
|
+
brand_color: "#6366F1"
|
|
113
|
+
default_prompt: "Use $${command.name} to ${command.description.charAt(0).toLowerCase()}${command.description.slice(1)}."
|
|
114
|
+
`;
|
|
115
|
+
}
|
|
116
|
+
function generateAllCodexPluginSkills(outDir = ".codex/plugins/polaris/skills") {
|
|
117
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
118
|
+
const written = [];
|
|
119
|
+
for (const command of skillCommands()) {
|
|
120
|
+
const skillDir = path.join(outDir, command.name);
|
|
121
|
+
const agentsDir = path.join(skillDir, "agents");
|
|
122
|
+
fs.mkdirSync(agentsDir, { recursive: true });
|
|
123
|
+
const skillPath = path.join(skillDir, "SKILL.md");
|
|
124
|
+
fs.writeFileSync(skillPath, generateCodexPluginSkill(command), "utf8");
|
|
125
|
+
written.push(skillPath);
|
|
126
|
+
const yamlPath = path.join(agentsDir, "openai.yaml");
|
|
127
|
+
fs.writeFileSync(yamlPath, generateCodexOpenAiYaml(command), "utf8");
|
|
128
|
+
written.push(yamlPath);
|
|
129
|
+
}
|
|
130
|
+
return written;
|
|
131
|
+
}
|
|
@@ -7,6 +7,7 @@ exports.SLASH_COMMANDS = [
|
|
|
7
7
|
name: "polaris-run",
|
|
8
8
|
kind: "skill",
|
|
9
9
|
skill: "run",
|
|
10
|
+
targetSkill: "polaris-run",
|
|
10
11
|
routing: ".polaris/skills/ROUTING.md",
|
|
11
12
|
args: [
|
|
12
13
|
{
|
|
@@ -21,6 +22,7 @@ exports.SLASH_COMMANDS = [
|
|
|
21
22
|
name: "polaris-analyze",
|
|
22
23
|
kind: "skill",
|
|
23
24
|
skill: "analyze",
|
|
25
|
+
targetSkill: "polaris-analyze",
|
|
24
26
|
routing: ".polaris/skills/ROUTING.md",
|
|
25
27
|
args: [
|
|
26
28
|
{
|
|
@@ -31,6 +33,15 @@ exports.SLASH_COMMANDS = [
|
|
|
31
33
|
],
|
|
32
34
|
description: "Analyze a cluster and produce an implementation plan via the Analyst skill packet",
|
|
33
35
|
},
|
|
36
|
+
{
|
|
37
|
+
name: "polaris-finalize",
|
|
38
|
+
kind: "skill",
|
|
39
|
+
skill: "run",
|
|
40
|
+
targetSkill: "polaris-run",
|
|
41
|
+
routing: ".polaris/skills/ROUTING.md",
|
|
42
|
+
args: [],
|
|
43
|
+
description: "Finalize the active Polaris run through the Foreman skill packet",
|
|
44
|
+
},
|
|
34
45
|
{
|
|
35
46
|
name: "polaris-init",
|
|
36
47
|
kind: "cli",
|
|
@@ -48,7 +59,8 @@ exports.SLASH_COMMANDS = [
|
|
|
48
59
|
{
|
|
49
60
|
name: "polaris-reconcile",
|
|
50
61
|
kind: "skill",
|
|
51
|
-
skill: "
|
|
62
|
+
skill: "reconcile",
|
|
63
|
+
targetSkill: "polaris-reconcile",
|
|
52
64
|
routing: ".polaris/skills/ROUTING.md",
|
|
53
65
|
args: [
|
|
54
66
|
{
|
|
@@ -59,6 +71,21 @@ exports.SLASH_COMMANDS = [
|
|
|
59
71
|
],
|
|
60
72
|
description: "Reconcile project cognition via the triage skill packet",
|
|
61
73
|
},
|
|
74
|
+
{
|
|
75
|
+
name: "polaris-catalog",
|
|
76
|
+
kind: "skill",
|
|
77
|
+
skill: "catalog",
|
|
78
|
+
targetSkill: "polaris-catalog",
|
|
79
|
+
routing: ".polaris/skills/ROUTING.md",
|
|
80
|
+
args: [
|
|
81
|
+
{
|
|
82
|
+
name: "cluster_id",
|
|
83
|
+
required: true,
|
|
84
|
+
description: "Cluster ID to catalog (e.g., POL-257)",
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
description: "Catalog project cognition and SmartDocs via the catalog skill packet",
|
|
88
|
+
},
|
|
62
89
|
{
|
|
63
90
|
name: "polaris-status",
|
|
64
91
|
kind: "cli",
|
|
@@ -66,6 +93,24 @@ exports.SLASH_COMMANDS = [
|
|
|
66
93
|
args: [],
|
|
67
94
|
description: "Print the current Polaris loop run state summary",
|
|
68
95
|
},
|
|
96
|
+
{
|
|
97
|
+
name: "docs-ingest",
|
|
98
|
+
kind: "skill",
|
|
99
|
+
skill: "ingest",
|
|
100
|
+
targetSkill: "docs-ingest",
|
|
101
|
+
routing: ".polaris/skills/ROUTING.md",
|
|
102
|
+
args: [],
|
|
103
|
+
description: "Ingest raw documentation files through the Polaris SmartDocs skill packet",
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "docs-promote",
|
|
107
|
+
kind: "skill",
|
|
108
|
+
skill: "promote",
|
|
109
|
+
targetSkill: "docs-promote",
|
|
110
|
+
routing: ".polaris/skills/ROUTING.md",
|
|
111
|
+
args: [],
|
|
112
|
+
description: "Review and promote candidate SmartDocs through the Polaris governance skill packet",
|
|
113
|
+
},
|
|
69
114
|
];
|
|
70
115
|
exports.SLASH_COMMAND_BY_NAME = Object.fromEntries(exports.SLASH_COMMANDS.map((command) => [command.name, command]));
|
|
71
116
|
function resolveSlashCommand(name) {
|
|
@@ -35,10 +35,12 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.detectShimDrift = detectShimDrift;
|
|
37
37
|
exports.syncShims = syncShims;
|
|
38
|
+
exports.syncCodexPluginSkills = syncCodexPluginSkills;
|
|
38
39
|
const fs = __importStar(require("fs"));
|
|
39
40
|
const path = __importStar(require("path"));
|
|
40
41
|
const commands_js_1 = require("./commands.js");
|
|
41
42
|
const claude_generator_js_1 = require("./claude-generator.js");
|
|
43
|
+
const codex_generator_js_1 = require("./codex-generator.js");
|
|
42
44
|
/**
|
|
43
45
|
* Workspace sync and versioning for generated agent-plugin shims.
|
|
44
46
|
*
|
|
@@ -106,3 +108,6 @@ function syncShims(outDir = ".claude/commands") {
|
|
|
106
108
|
}
|
|
107
109
|
return { written, drift };
|
|
108
110
|
}
|
|
111
|
+
function syncCodexPluginSkills(outDir = ".codex/plugins/polaris/skills") {
|
|
112
|
+
return { written: (0, codex_generator_js_1.generateAllCodexPluginSkills)(outDir) };
|
|
113
|
+
}
|
|
@@ -86,9 +86,18 @@ function gateUserIntervened(artifacts) {
|
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
|
-
* foreman-resent-packet: Was the
|
|
89
|
+
* foreman-resent-packet: Was the same child dispatched more than once?
|
|
90
90
|
*
|
|
91
|
-
* Evidence:
|
|
91
|
+
* Evidence:
|
|
92
|
+
* - open_children_meta.<child>.dispatch_record.dispatch_count (if runtime tracks it)
|
|
93
|
+
* - ledger child-dispatched events (issue_id)
|
|
94
|
+
* - telemetry child-dispatched events (child_id)
|
|
95
|
+
*
|
|
96
|
+
* A normal multi-session run has dispatch_epoch > 1 because distinct children are
|
|
97
|
+
* dispatched across sessions. That is expected. The problematic pattern is the
|
|
98
|
+
* foreman re-sending a worker packet to the same child after that child already
|
|
99
|
+
* returned a result. When per-child dispatch count data is unavailable, the gate
|
|
100
|
+
* is skipped rather than failing on dispatch_epoch alone.
|
|
92
101
|
*/
|
|
93
102
|
function gateForemanResentPacket(artifacts) {
|
|
94
103
|
const state = artifacts.currentState;
|
|
@@ -98,13 +107,57 @@ function gateForemanResentPacket(artifacts) {
|
|
|
98
107
|
if (typeof dispatchEpoch !== "number") {
|
|
99
108
|
return { gate: "foreman-resent-packet", outcome: "skipped", detail: "dispatch_epoch not present in state" };
|
|
100
109
|
}
|
|
101
|
-
const
|
|
110
|
+
const perChildCounts = countChildDispatches(artifacts);
|
|
111
|
+
if (perChildCounts) {
|
|
112
|
+
const reDispatched = Array.from(perChildCounts.entries())
|
|
113
|
+
.filter(([, count]) => count > 1)
|
|
114
|
+
.map(([childId]) => childId);
|
|
115
|
+
const failed = reDispatched.length > 0;
|
|
116
|
+
return {
|
|
117
|
+
gate: "foreman-resent-packet",
|
|
118
|
+
outcome: failed ? "failed" : "passed",
|
|
119
|
+
detail: failed ? `child re-dispatched: ${reDispatched.join(", ")}` : undefined,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// No per-child dispatch data available. A single epoch cannot contain a re-dispatch.
|
|
123
|
+
if (dispatchEpoch === 1) {
|
|
124
|
+
return { gate: "foreman-resent-packet", outcome: "passed" };
|
|
125
|
+
}
|
|
102
126
|
return {
|
|
103
127
|
gate: "foreman-resent-packet",
|
|
104
|
-
outcome:
|
|
105
|
-
detail:
|
|
128
|
+
outcome: "skipped",
|
|
129
|
+
detail: "per-child dispatch count data unavailable",
|
|
106
130
|
};
|
|
107
131
|
}
|
|
132
|
+
/** Counts per-child dispatches from all available artifact sources, or null if none are present. */
|
|
133
|
+
function countChildDispatches(artifacts) {
|
|
134
|
+
const counts = new Map();
|
|
135
|
+
const state = asRecord(artifacts.currentState);
|
|
136
|
+
const openChildrenMeta = asRecord(state?.["open_children_meta"]);
|
|
137
|
+
for (const [childId, meta] of Object.entries(openChildrenMeta ?? {})) {
|
|
138
|
+
const metaRec = asRecord(meta);
|
|
139
|
+
const dispatchRecord = asRecord(metaRec?.["dispatch_record"]);
|
|
140
|
+
const dispatchCount = dispatchRecord?.["dispatch_count"];
|
|
141
|
+
if (typeof dispatchCount === "number") {
|
|
142
|
+
counts.set(childId, Math.max(counts.get(childId) ?? 0, dispatchCount));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
for (const event of artifacts.ledgerEvents) {
|
|
146
|
+
const rec = asRecord(event);
|
|
147
|
+
if (rec?.["event"] === "child-dispatched" && typeof rec["issue_id"] === "string") {
|
|
148
|
+
const childId = rec["issue_id"];
|
|
149
|
+
counts.set(childId, (counts.get(childId) ?? 0) + 1);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
for (const event of artifacts.telemetryEvents) {
|
|
153
|
+
const rec = asRecord(event);
|
|
154
|
+
if (rec?.["event"] === "child-dispatched" && typeof rec["child_id"] === "string") {
|
|
155
|
+
const childId = rec["child_id"];
|
|
156
|
+
counts.set(childId, (counts.get(childId) ?? 0) + 1);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return counts.size > 0 ? counts : null;
|
|
160
|
+
}
|
|
108
161
|
/**
|
|
109
162
|
* foreman-fixed-worker-output: Did foreman make commits between child-complete
|
|
110
163
|
* and the next dispatch?
|
|
@@ -94,6 +94,7 @@ function safeReaddir(dir) {
|
|
|
94
94
|
return [];
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
+
const NON_WORKER_PREFIXES = ["librarian-", "CHART-", "medic-result-"];
|
|
97
98
|
function readResultPackets(clusterDir) {
|
|
98
99
|
if (!clusterDir)
|
|
99
100
|
return [];
|
|
@@ -101,7 +102,7 @@ function readResultPackets(clusterDir) {
|
|
|
101
102
|
if (!(0, node_fs_1.existsSync)(resultsDir))
|
|
102
103
|
return [];
|
|
103
104
|
return safeReaddir(resultsDir)
|
|
104
|
-
.filter((f) => f.endsWith(".json"))
|
|
105
|
+
.filter((f) => f.endsWith(".json") && !NON_WORKER_PREFIXES.some((p) => f.startsWith(p)))
|
|
105
106
|
.map((f) => readJson((0, node_path_1.join)(resultsDir, f)))
|
|
106
107
|
.filter((v) => v !== undefined);
|
|
107
108
|
}
|
|
@@ -158,8 +159,19 @@ function loadRunArtifacts(repoRoot, runId) {
|
|
|
158
159
|
const telemetryEvents = telemetryPath ? (0, gates_js_1.readJsonLines)(telemetryPath) : [];
|
|
159
160
|
// Result packets from cluster results dir
|
|
160
161
|
const resultPackets = readResultPackets(clusterDir);
|
|
161
|
-
//
|
|
162
|
-
|
|
162
|
+
// WorkerResultContracts: prefer completed_children_results from current-state.json (Bug A fix)
|
|
163
|
+
let workerResultContracts;
|
|
164
|
+
const stateRec = currentState && typeof currentState === "object" && currentState !== null
|
|
165
|
+
? currentState
|
|
166
|
+
: null;
|
|
167
|
+
const completedChildrenResults = stateRec?.["completed_children_results"];
|
|
168
|
+
if (completedChildrenResults && typeof completedChildrenResults === "object" && !Array.isArray(completedChildrenResults)) {
|
|
169
|
+
workerResultContracts = Object.values(completedChildrenResults).filter((v) => v !== null && typeof v === "object" && typeof v["worker_id"] === "string");
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
// Legacy fallback: extract from result packet files
|
|
173
|
+
workerResultContracts = extractWorkerResultContracts(resultPackets);
|
|
174
|
+
}
|
|
163
175
|
return {
|
|
164
176
|
runId,
|
|
165
177
|
runDir,
|