@codeam/shared 2.75.7 → 2.75.9
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/index.d.mts +108 -9
- package/dist/index.d.ts +108 -9
- package/dist/index.js +185 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +180 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -49,10 +49,13 @@ __export(index_exports, {
|
|
|
49
49
|
MANAGED_AGENT_SUBTITLE: () => MANAGED_AGENT_SUBTITLE,
|
|
50
50
|
MANAGED_PROVIDER_DISPLAY_NAMES: () => MANAGED_PROVIDER_DISPLAY_NAMES,
|
|
51
51
|
MANAGED_PROVIDER_IDS: () => MANAGED_PROVIDER_IDS,
|
|
52
|
+
MAX_PACK_FINDINGS: () => MAX_PACK_FINDINGS,
|
|
52
53
|
MODEL_CONTEXT_WINDOW: () => MODEL_CONTEXT_WINDOW,
|
|
53
54
|
MODEL_PRICING: () => MODEL_PRICING,
|
|
54
55
|
OBSERVER_BRIDGE_PORT: () => OBSERVER_BRIDGE_PORT,
|
|
55
56
|
PACK_ACTION_COMMAND: () => PACK_ACTION_COMMAND,
|
|
57
|
+
PACK_FINDINGS_FILE: () => PACK_FINDINGS_FILE,
|
|
58
|
+
PACK_HANDOFF_HEADING: () => PACK_HANDOFF_HEADING,
|
|
56
59
|
PACK_REGISTRY: () => PACK_REGISTRY,
|
|
57
60
|
PACK_START_COMMAND: () => PACK_START_COMMAND,
|
|
58
61
|
PACK_STATUS_COMMAND: () => PACK_STATUS_COMMAND,
|
|
@@ -80,6 +83,7 @@ __export(index_exports, {
|
|
|
80
83
|
clampHopBudget: () => clampHopBudget,
|
|
81
84
|
classifyStack: () => classifyStack,
|
|
82
85
|
detectedIntegrationsFromDeps: () => detectedIntegrationsFromDeps,
|
|
86
|
+
extractHandoffSection: () => extractHandoffSection,
|
|
83
87
|
getAgent: () => getAgent,
|
|
84
88
|
getContextWindow: () => getContextWindow,
|
|
85
89
|
getEnabledAgents: () => getEnabledAgents,
|
|
@@ -103,6 +107,7 @@ __export(index_exports, {
|
|
|
103
107
|
isSkillId: () => isSkillId,
|
|
104
108
|
normalizeAgentId: () => normalizeAgentId,
|
|
105
109
|
normalizeGuardrailPolicy: () => normalizeGuardrailPolicy,
|
|
110
|
+
parsePackFindings: () => parsePackFindings,
|
|
106
111
|
publicToInternal: () => publicToInternal,
|
|
107
112
|
recommendForDeps: () => recommendForDeps,
|
|
108
113
|
renderToLines: () => renderToLines,
|
|
@@ -2707,6 +2712,9 @@ function normalizeGuardrailPolicy(raw) {
|
|
|
2707
2712
|
var GUARDRAIL_CONFIGURE_COMMAND = "guardrail_configure";
|
|
2708
2713
|
|
|
2709
2714
|
// src/packs/types.ts
|
|
2715
|
+
var PACK_FINDINGS_FILE = "REVIEW-FINDINGS.pack.json";
|
|
2716
|
+
var MAX_PACK_FINDINGS = 50;
|
|
2717
|
+
var PACK_HANDOFF_HEADING = "## Handoff";
|
|
2710
2718
|
var PACK_START_COMMAND = "pack_start";
|
|
2711
2719
|
var PACK_ACTION_COMMAND = "pack_action";
|
|
2712
2720
|
var PACK_STATUS_COMMAND = "pack_status";
|
|
@@ -2726,6 +2734,8 @@ Method:
|
|
|
2726
2734
|
- **Verification plan** \u2014 for each criterion, the level that proves it (unit / integration / manual) and why.
|
|
2727
2735
|
3. Right-size: if the task is clearly too large for one pipeline run, narrow the criteria to a coherent first slice and record the rest under "Out of scope / next".
|
|
2728
2736
|
|
|
2737
|
+
4. Close with a \`## Handoff\` section: the criteria count, what you scoped out, and any assumption the Coder must know.
|
|
2738
|
+
|
|
2729
2739
|
Handoff bar: the spec file is committed; every acceptance criterion is testable as written; a competent implementer could start without asking you anything.`;
|
|
2730
2740
|
var CODER_PROMPT = `# Role: Coder
|
|
2731
2741
|
|
|
@@ -2736,6 +2746,7 @@ Method:
|
|
|
2736
2746
|
2. Test-first where it fits: write the test that proves a criterion, watch it fail, implement until it passes. Where strict test-first doesn't fit, still land tests alongside the change.
|
|
2737
2747
|
3. Match the project's existing style, structure, and conventions. Simplest design that fully solves the problem \u2014 no speculative abstractions, no "while I'm here" changes.
|
|
2738
2748
|
4. Run the project's tests / linters / build and make them pass.
|
|
2749
|
+
5. Close with a \`## Handoff\` section: which criteria are implemented (by number) and where their tests live, anything you consciously did NOT do, and what the Reviewer should look at first.
|
|
2739
2750
|
|
|
2740
2751
|
Handoff bar: every acceptance criterion is implemented and covered by a test; the project's checks pass; the work is committed in focused commits.`;
|
|
2741
2752
|
var REVIEWER_PROMPT = `# Role: Reviewer
|
|
@@ -2751,21 +2762,42 @@ Method:
|
|
|
2751
2762
|
- **Conventions & naming** \u2014 matches the surrounding code; names say what things are.
|
|
2752
2763
|
- **Safety** \u2014 no secrets, credentials, or debugging remnants in code, tests, or fixtures.
|
|
2753
2764
|
3. Fix what is justified \u2014 smallest change that resolves the finding, keeping behavior. Re-run the checks after material fixes.
|
|
2754
|
-
4.
|
|
2755
|
-
|
|
2756
|
-
|
|
2765
|
+
4. Write your findings as DATA to \`REVIEW-FINDINGS.pack.json\` at the repo root \u2014 the next stage verifies them one by one, so what is not in this file does not get verified. Exact shape:
|
|
2766
|
+
\`\`\`json
|
|
2767
|
+
{
|
|
2768
|
+
"findings": [
|
|
2769
|
+
{
|
|
2770
|
+
"id": "R1",
|
|
2771
|
+
"severity": "blocker | major | minor | nit",
|
|
2772
|
+
"title": "one line: what is wrong",
|
|
2773
|
+
"detail": "why it matters and what you did about it",
|
|
2774
|
+
"file": "src/path/to/file.ts",
|
|
2775
|
+
"line": 42,
|
|
2776
|
+
"resolution": "fixed | deferred | wont_fix | needs_verification",
|
|
2777
|
+
"commit": "abcdef1234"
|
|
2778
|
+
}
|
|
2779
|
+
],
|
|
2780
|
+
"checked": ["what you audited when the list is empty: e.g. error paths of X, test coverage of Y"]
|
|
2781
|
+
}
|
|
2782
|
+
\`\`\`
|
|
2783
|
+
Every finding you fixed says \`fixed\` with its commit; anything you deliberately left says \`deferred\` or \`wont_fix\` with the reason in \`detail\`; anything you could not verify says \`needs_verification\`. An empty \`findings\` array is a valid, honest result \u2014 then \`checked\` must say what you looked at. Commit this file with your stage.
|
|
2784
|
+
5. Close with a \`## Handoff\` section: what you found (counts by severity), what you fixed, what you deliberately left, and what the next stage must verify.
|
|
2785
|
+
|
|
2786
|
+
Handoff bar: checks pass on YOUR final commit; every fix is committed; \`REVIEW-FINDINGS.pack.json\` is committed and lists every finding with its resolution (an empty list says what you checked).`;
|
|
2757
2787
|
var QA_PROMPT = `# Role: QA
|
|
2758
2788
|
|
|
2759
2789
|
You are the final gate. You verify the delivered work against the acceptance criteria as a whole \u2014 end to end, the way a demanding user would \u2014 and produce the run's closing report.
|
|
2760
2790
|
|
|
2761
2791
|
Method:
|
|
2762
2792
|
1. Read the task and \`SPEC.pack.md\` (when present). Your contract is the acceptance criteria; without a spec, derive them from the task.
|
|
2763
|
-
2.
|
|
2764
|
-
3.
|
|
2765
|
-
4.
|
|
2766
|
-
5.
|
|
2793
|
+
2. Read \`REVIEW-FINDINGS.pack.json\` (when present \u2014 the Reviewer's structured findings, also summarized in your handoff input). Every finding there is an item on YOUR checklist: a \`fixed\` one must be verified fixed without regression; a \`deferred\`/\`wont_fix\` one must be judged acceptable or escalated; a \`needs_verification\` one is yours to settle.
|
|
2794
|
+
3. For EACH criterion, verify it against the real project: run the relevant tests, execute the code paths where feasible, inspect actual behavior/output. Do not take earlier stages' word for anything.
|
|
2795
|
+
4. Run the project's full checks (tests, lint, types, build) one final time.
|
|
2796
|
+
5. Write \`QA-REPORT.pack.md\` at the repo root with two sections: **Acceptance criteria** \u2014 per-criterion verdict (\u2705 verified / \u26A0\uFE0F partially / \u274C failed \u2014 with evidence for each); **Review findings** \u2014 per finding id, verdict (\u2705 verified fixed / \u26A0\uFE0F still open / \u274C regressed \u2014 with evidence). Then the checks' results, anything not verifiable in this environment (stated plainly), and a short "ready to ship?" conclusion.
|
|
2797
|
+
6. If a criterion FAILS: fix it only when the fix is small and unambiguous; otherwise mark it failed with exact evidence \u2014 the user decides. Never paper over a failure.
|
|
2798
|
+
7. Close with a \`## Handoff\` section: the ship/no-ship conclusion, the failed or open items by id, and what you could not verify.
|
|
2767
2799
|
|
|
2768
|
-
Handoff bar: the report is committed; every verdict carries evidence; the conclusion is honest about anything unverified.`;
|
|
2800
|
+
Handoff bar: the report is committed; every verdict carries evidence; every finding id from the Reviewer appears in the report; the conclusion is honest about anything unverified.`;
|
|
2769
2801
|
|
|
2770
2802
|
// src/packs/registry.ts
|
|
2771
2803
|
var PACK_REGISTRY = {
|
|
@@ -2789,7 +2821,9 @@ var PACK_REGISTRY = {
|
|
|
2789
2821
|
skillIds: ["code-review", "code-naming"],
|
|
2790
2822
|
prompt: REVIEWER_PROMPT,
|
|
2791
2823
|
// Review-only: approving clean with no change is success, not a stall.
|
|
2792
|
-
requiresCommit: false
|
|
2824
|
+
requiresCommit: false,
|
|
2825
|
+
// Leaves REVIEW-FINDINGS.pack.json — the next stage gets a list, not prose.
|
|
2826
|
+
producesFindings: true
|
|
2793
2827
|
}
|
|
2794
2828
|
]
|
|
2795
2829
|
},
|
|
@@ -2820,7 +2854,9 @@ var PACK_REGISTRY = {
|
|
|
2820
2854
|
skillIds: ["code-review", "code-naming"],
|
|
2821
2855
|
prompt: REVIEWER_PROMPT,
|
|
2822
2856
|
// Review-only: approving clean with no change is success, not a stall.
|
|
2823
|
-
requiresCommit: false
|
|
2857
|
+
requiresCommit: false,
|
|
2858
|
+
// Leaves REVIEW-FINDINGS.pack.json — the next stage gets a list, not prose.
|
|
2859
|
+
producesFindings: true
|
|
2824
2860
|
},
|
|
2825
2861
|
{
|
|
2826
2862
|
role: "qa",
|
|
@@ -2850,8 +2886,140 @@ You are ONE specialist role in a multi-role pipeline running on this repository.
|
|
|
2850
2886
|
- **Never leave the tree broken.** Run the project's checks before finishing when the project has them; your stage ends with a working tree the next role can build on.
|
|
2851
2887
|
- **Do not push, force-push, or touch remotes** \u2014 the pipeline works locally; publishing is the user's call at the end.
|
|
2852
2888
|
- **Never read, edit, or commit anything under \`.codeam/\`** \u2014 that is the pipeline's own ledger, not project code.
|
|
2853
|
-
- **Finish
|
|
2854
|
-
- **If you
|
|
2889
|
+
- **Finish with a \`## Handoff\` section.** When your stage's job is done and committed, end your reply with a heading \`## Handoff\` followed by 2-6 lines: what you did, what you verified, anything the next stage must know. That section \u2014 not the rest of your reply \u2014 is what the next role receives. Don't ask "should I continue?" \u2014 the pipeline advances automatically.
|
|
2890
|
+
- **If you need the user's decision** (contradictory requirements, a real product choice), ask ONE clear question and end your reply with 2-4 numbered options on their own lines (\`1. \u2026\`), then stop. The pipeline pauses until they answer in this conversation; keep working in it once they do, and commit as usual.
|
|
2891
|
+
- **If you are genuinely blocked** (missing access, a broken environment you cannot fix), say exactly what is blocking you and stop \u2014 the user is supervising and will decide.`;
|
|
2892
|
+
|
|
2893
|
+
// src/packs/findings.ts
|
|
2894
|
+
var SEVERITIES = /* @__PURE__ */ new Set([
|
|
2895
|
+
"blocker",
|
|
2896
|
+
"major",
|
|
2897
|
+
"minor",
|
|
2898
|
+
"nit"
|
|
2899
|
+
]);
|
|
2900
|
+
var RESOLUTIONS = /* @__PURE__ */ new Set([
|
|
2901
|
+
"fixed",
|
|
2902
|
+
"deferred",
|
|
2903
|
+
"wont_fix",
|
|
2904
|
+
"needs_verification"
|
|
2905
|
+
]);
|
|
2906
|
+
var TITLE_MAX = 200;
|
|
2907
|
+
var DETAIL_MAX = 1200;
|
|
2908
|
+
function parsePackFindings(raw) {
|
|
2909
|
+
const text = stripFence(raw).trim();
|
|
2910
|
+
if (text.length === 0) return { ok: false, error: "findings file is empty" };
|
|
2911
|
+
let data;
|
|
2912
|
+
try {
|
|
2913
|
+
data = JSON.parse(text);
|
|
2914
|
+
} catch {
|
|
2915
|
+
const salvaged = salvageJson(text);
|
|
2916
|
+
if (salvaged === null) return { ok: false, error: "findings file is not valid JSON" };
|
|
2917
|
+
data = salvaged;
|
|
2918
|
+
}
|
|
2919
|
+
const container = Array.isArray(data) ? { findings: data } : data;
|
|
2920
|
+
if (!isRecord(container) || !Array.isArray(container.findings)) {
|
|
2921
|
+
return { ok: false, error: 'findings file has no "findings" array' };
|
|
2922
|
+
}
|
|
2923
|
+
const findings = [];
|
|
2924
|
+
let dropped = 0;
|
|
2925
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2926
|
+
for (const entry of container.findings) {
|
|
2927
|
+
const f = coerceFinding(entry, findings.length + 1);
|
|
2928
|
+
if (!f) {
|
|
2929
|
+
dropped += 1;
|
|
2930
|
+
continue;
|
|
2931
|
+
}
|
|
2932
|
+
if (seen.has(f.id)) f.id = `${f.id}-${findings.length + 1}`;
|
|
2933
|
+
seen.add(f.id);
|
|
2934
|
+
findings.push(f);
|
|
2935
|
+
if (findings.length >= MAX_PACK_FINDINGS) break;
|
|
2936
|
+
}
|
|
2937
|
+
const truncated = container.findings.length - dropped - findings.length;
|
|
2938
|
+
const checked = Array.isArray(container.checked) ? container.checked.filter((c) => typeof c === "string" && c.trim().length > 0).slice(0, 20) : void 0;
|
|
2939
|
+
const notes = [];
|
|
2940
|
+
if (dropped > 0) notes.push(`${dropped} malformed entr${dropped === 1 ? "y" : "ies"} dropped`);
|
|
2941
|
+
if (truncated > 0)
|
|
2942
|
+
notes.push(`list truncated to ${MAX_PACK_FINDINGS} (${truncated} more in the file)`);
|
|
2943
|
+
return {
|
|
2944
|
+
ok: true,
|
|
2945
|
+
value: {
|
|
2946
|
+
findings,
|
|
2947
|
+
...checked && checked.length > 0 ? { checked } : {},
|
|
2948
|
+
...notes.length > 0 ? { note: notes.join("; ") } : {}
|
|
2949
|
+
}
|
|
2950
|
+
};
|
|
2951
|
+
}
|
|
2952
|
+
function coerceFinding(entry, ordinal) {
|
|
2953
|
+
if (!isRecord(entry)) return null;
|
|
2954
|
+
const title = str(entry.title) ?? str(entry.summary);
|
|
2955
|
+
if (!title) return null;
|
|
2956
|
+
const id = str(entry.id) ?? `R${ordinal}`;
|
|
2957
|
+
const severityRaw = (str(entry.severity) ?? "").toLowerCase();
|
|
2958
|
+
const resolutionRaw = (str(entry.resolution) ?? str(entry.status) ?? "").toLowerCase().replace(/[\s-]+/g, "_");
|
|
2959
|
+
const line = typeof entry.line === "number" && Number.isFinite(entry.line) && entry.line > 0 ? Math.floor(entry.line) : void 0;
|
|
2960
|
+
const detail = str(entry.detail) ?? str(entry.description);
|
|
2961
|
+
const file = str(entry.file) ?? str(entry.path);
|
|
2962
|
+
const commit = str(entry.commit);
|
|
2963
|
+
return {
|
|
2964
|
+
id: id.slice(0, 32),
|
|
2965
|
+
severity: SEVERITIES.has(severityRaw) ? severityRaw : "major",
|
|
2966
|
+
title: title.slice(0, TITLE_MAX),
|
|
2967
|
+
...detail ? { detail: detail.slice(0, DETAIL_MAX) } : {},
|
|
2968
|
+
...file ? { file: file.slice(0, 300) } : {},
|
|
2969
|
+
...line !== void 0 ? { line } : {},
|
|
2970
|
+
resolution: RESOLUTIONS.has(resolutionRaw) ? resolutionRaw : "needs_verification",
|
|
2971
|
+
...commit && /^[0-9a-f]{7,40}$/i.test(commit) ? { commit: commit.slice(0, 10) } : {}
|
|
2972
|
+
};
|
|
2973
|
+
}
|
|
2974
|
+
function extractHandoffSection(reply) {
|
|
2975
|
+
const lines = reply.split("\n");
|
|
2976
|
+
const want = PACK_HANDOFF_HEADING.replace(/^#+\s*/, "").toLowerCase();
|
|
2977
|
+
let start = -1;
|
|
2978
|
+
let level = 0;
|
|
2979
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
2980
|
+
const m = lines[i].match(/^\s{0,3}(#{1,4})\s+(.+?)\s*#*\s*$/);
|
|
2981
|
+
if (m && m[2].trim().toLowerCase().replace(/[:.]+$/, "") === want) {
|
|
2982
|
+
start = i;
|
|
2983
|
+
level = m[1].length;
|
|
2984
|
+
break;
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
if (start < 0) return null;
|
|
2988
|
+
const body = [];
|
|
2989
|
+
for (let i = start + 1; i < lines.length; i++) {
|
|
2990
|
+
const m = lines[i].match(/^\s{0,3}(#{1,6})\s+/);
|
|
2991
|
+
if (m && m[1].length <= level) break;
|
|
2992
|
+
body.push(lines[i]);
|
|
2993
|
+
}
|
|
2994
|
+
const text = body.join("\n").trim();
|
|
2995
|
+
return text.length > 0 ? text : null;
|
|
2996
|
+
}
|
|
2997
|
+
function isRecord(v) {
|
|
2998
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2999
|
+
}
|
|
3000
|
+
function str(v) {
|
|
3001
|
+
return typeof v === "string" && v.trim().length > 0 ? v.trim() : void 0;
|
|
3002
|
+
}
|
|
3003
|
+
function stripFence(raw) {
|
|
3004
|
+
const m = raw.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
3005
|
+
return m ? m[1] : raw;
|
|
3006
|
+
}
|
|
3007
|
+
function salvageJson(text) {
|
|
3008
|
+
for (const [open, close] of [
|
|
3009
|
+
["{", "}"],
|
|
3010
|
+
["[", "]"]
|
|
3011
|
+
]) {
|
|
3012
|
+
const a = text.indexOf(open);
|
|
3013
|
+
const b = text.lastIndexOf(close);
|
|
3014
|
+
if (a >= 0 && b > a) {
|
|
3015
|
+
try {
|
|
3016
|
+
return JSON.parse(text.slice(a, b + 1));
|
|
3017
|
+
} catch {
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
return null;
|
|
3022
|
+
}
|
|
2855
3023
|
|
|
2856
3024
|
// src/api-url.ts
|
|
2857
3025
|
var DEFAULT_API_BASE_URL = "https://api.codeagent-mobile.com";
|
|
@@ -3098,10 +3266,13 @@ OUTPUT JSON ONLY. NO MARKDOWN. NO COMMENTARY.
|
|
|
3098
3266
|
MANAGED_AGENT_SUBTITLE,
|
|
3099
3267
|
MANAGED_PROVIDER_DISPLAY_NAMES,
|
|
3100
3268
|
MANAGED_PROVIDER_IDS,
|
|
3269
|
+
MAX_PACK_FINDINGS,
|
|
3101
3270
|
MODEL_CONTEXT_WINDOW,
|
|
3102
3271
|
MODEL_PRICING,
|
|
3103
3272
|
OBSERVER_BRIDGE_PORT,
|
|
3104
3273
|
PACK_ACTION_COMMAND,
|
|
3274
|
+
PACK_FINDINGS_FILE,
|
|
3275
|
+
PACK_HANDOFF_HEADING,
|
|
3105
3276
|
PACK_REGISTRY,
|
|
3106
3277
|
PACK_START_COMMAND,
|
|
3107
3278
|
PACK_STATUS_COMMAND,
|
|
@@ -3129,6 +3300,7 @@ OUTPUT JSON ONLY. NO MARKDOWN. NO COMMENTARY.
|
|
|
3129
3300
|
clampHopBudget,
|
|
3130
3301
|
classifyStack,
|
|
3131
3302
|
detectedIntegrationsFromDeps,
|
|
3303
|
+
extractHandoffSection,
|
|
3132
3304
|
getAgent,
|
|
3133
3305
|
getContextWindow,
|
|
3134
3306
|
getEnabledAgents,
|
|
@@ -3152,6 +3324,7 @@ OUTPUT JSON ONLY. NO MARKDOWN. NO COMMENTARY.
|
|
|
3152
3324
|
isSkillId,
|
|
3153
3325
|
normalizeAgentId,
|
|
3154
3326
|
normalizeGuardrailPolicy,
|
|
3327
|
+
parsePackFindings,
|
|
3155
3328
|
publicToInternal,
|
|
3156
3329
|
recommendForDeps,
|
|
3157
3330
|
renderToLines,
|