@kujolang/paperclip 0.1.2 → 0.1.4
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/CHANGELOG.md +11 -0
- package/README.md +3 -3
- package/VERSION +1 -1
- package/dist/manifest.js +17 -8
- package/dist/ui/index.js +307 -113
- package/dist/worker.js +2 -218
- package/docs/CATALOG_SUBMISSION.md +2 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/OPERATIONS.md +4 -0
- package/docs/RELEASE_READINESS.md +1 -1
- package/docs/USAGE.md +3 -1
- package/package.json +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.4 - 2026-09-02
|
|
4
|
+
|
|
5
|
+
- Show Kujo automatically in Paperclip's current issue view while keeping the shared detail tab for project, issue, and run pages.
|
|
6
|
+
- Replace the basic action list with a polished monochrome workspace, clearer action cards, stronger artifact states, and responsive controls.
|
|
7
|
+
- Correct the empty Context Pack state so it reports that a pack has not been generated.
|
|
8
|
+
|
|
9
|
+
## 0.1.3 - 2026-09-02
|
|
10
|
+
|
|
11
|
+
- Resolve the installed `@kujolang/kujo-runtime` package at worker runtime instead of inlining its package resolver into the ESM worker bundle.
|
|
12
|
+
- Add a package verification regression gate for the external runtime boundary.
|
|
13
|
+
|
|
3
14
|
## 0.1.2 - 2026-09-02
|
|
4
15
|
|
|
5
16
|
- Publish through npm trusted publishing with short-lived GitHub Actions identity tokens instead of a stored npm token.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Kujo for Paperclip
|
|
2
2
|
|
|
3
|
-
[](https://github.com/kujolang/paperclip/releases/tag/v0.1.4)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://github.com/kujolang/kujo)
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ You need Paperclip `2026.824.1` or later and Node.js `24.11.0` or later.
|
|
|
14
14
|
npx paperclipai plugin install @kujolang/paperclip
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Restart Paperclip if it is already running.
|
|
17
|
+
Restart Paperclip if it is already running. Kujo appears automatically inside Paperclip's current task view. On project and run pages, open the **Kujo** tab. You do not need to switch to the Classic Task Interface.
|
|
18
18
|
|
|
19
19
|
The npm package includes the correct Kujo runtime for macOS arm64/x64, Linux arm64/x64, and Windows x64. Installation does not run `preinstall`, `install`, or `postinstall` scripts.
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@ See [Installation](docs/INSTALLATION.md) for upgrades, local development install
|
|
|
22
22
|
|
|
23
23
|
## Use
|
|
24
24
|
|
|
25
|
-
Open the **Kujo** tab on a project or
|
|
25
|
+
Open an issue to use the inline Kujo workspace, or open the **Kujo** tab on a project, issue detail page, or run to:
|
|
26
26
|
|
|
27
27
|
- generate a **Review Pack** for the working tree;
|
|
28
28
|
- create a task-specific **Context Pack**;
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.4
|
package/dist/manifest.js
CHANGED
|
@@ -14527,7 +14527,7 @@ var DEFAULT_LIMITS = {
|
|
|
14527
14527
|
maxInputLogBytes: 2e5,
|
|
14528
14528
|
maxContextFileBytes: 2e3
|
|
14529
14529
|
};
|
|
14530
|
-
var PLUGIN_VERSION = "0.1.
|
|
14530
|
+
var PLUGIN_VERSION = "0.1.4";
|
|
14531
14531
|
var MINIMUM_HOST_VERSION = "0.0.0";
|
|
14532
14532
|
|
|
14533
14533
|
// src/config/schema.ts
|
|
@@ -14677,13 +14677,22 @@ var manifest = {
|
|
|
14677
14677
|
description: "Request focused Context Packs before broad repository exploration."
|
|
14678
14678
|
}],
|
|
14679
14679
|
ui: {
|
|
14680
|
-
slots: [
|
|
14681
|
-
|
|
14682
|
-
|
|
14683
|
-
|
|
14684
|
-
|
|
14685
|
-
|
|
14686
|
-
|
|
14680
|
+
slots: [
|
|
14681
|
+
{
|
|
14682
|
+
type: "detailTab",
|
|
14683
|
+
id: "kujo",
|
|
14684
|
+
displayName: "Kujo",
|
|
14685
|
+
exportName: "KujoDetailTab",
|
|
14686
|
+
entityTypes: ["project", "issue", "run"]
|
|
14687
|
+
},
|
|
14688
|
+
{
|
|
14689
|
+
type: "taskDetailView",
|
|
14690
|
+
id: "kujo-task-view",
|
|
14691
|
+
displayName: "Kujo",
|
|
14692
|
+
exportName: "KujoTaskDetailView",
|
|
14693
|
+
entityTypes: ["issue"]
|
|
14694
|
+
}
|
|
14695
|
+
]
|
|
14687
14696
|
}
|
|
14688
14697
|
};
|
|
14689
14698
|
var manifest_default = manifest;
|
package/dist/ui/index.js
CHANGED
|
@@ -1,122 +1,244 @@
|
|
|
1
1
|
// src/ui/index.tsx
|
|
2
2
|
import { useState } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
StatusBadge,
|
|
5
|
+
Spinner,
|
|
6
|
+
usePluginAction,
|
|
7
|
+
usePluginData
|
|
8
|
+
} from "@paperclipai/plugin-sdk/ui";
|
|
4
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
var colors = {
|
|
11
|
+
ink: "var(--foreground, #111111)",
|
|
12
|
+
muted: "var(--muted-foreground, #6b7280)",
|
|
13
|
+
border: "var(--border, #e5e7eb)",
|
|
14
|
+
surface: "var(--card, #ffffff)",
|
|
15
|
+
canvas: "var(--background, #ffffff)",
|
|
16
|
+
soft: "var(--muted, #f5f5f5)",
|
|
17
|
+
danger: "var(--destructive, #b42318)"
|
|
18
|
+
};
|
|
19
|
+
var panel = {
|
|
20
|
+
color: colors.ink,
|
|
21
|
+
display: "grid",
|
|
22
|
+
gap: 16,
|
|
23
|
+
width: "100%",
|
|
24
|
+
fontFamily: "inherit"
|
|
25
|
+
};
|
|
26
|
+
var card = {
|
|
27
|
+
background: colors.surface,
|
|
28
|
+
border: `1px solid ${colors.border}`,
|
|
29
|
+
borderRadius: 14,
|
|
30
|
+
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.04)",
|
|
31
|
+
display: "grid",
|
|
32
|
+
gap: 14,
|
|
33
|
+
padding: 18
|
|
34
|
+
};
|
|
35
|
+
var hero = {
|
|
36
|
+
...card,
|
|
37
|
+
alignItems: "center",
|
|
38
|
+
background: `linear-gradient(135deg, ${colors.surface} 0%, ${colors.soft} 100%)`,
|
|
39
|
+
gridTemplateColumns: "auto minmax(0, 1fr) auto"
|
|
40
|
+
};
|
|
41
|
+
var actionGrid = {
|
|
42
|
+
display: "grid",
|
|
43
|
+
gap: 14,
|
|
44
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(240px, 1fr))"
|
|
45
|
+
};
|
|
46
|
+
var actionCard = {
|
|
47
|
+
background: colors.canvas,
|
|
48
|
+
border: `1px solid ${colors.border}`,
|
|
49
|
+
borderRadius: 12,
|
|
50
|
+
display: "flex",
|
|
51
|
+
flexDirection: "column",
|
|
52
|
+
gap: 10,
|
|
53
|
+
minWidth: 0,
|
|
54
|
+
padding: 16
|
|
55
|
+
};
|
|
56
|
+
var input = {
|
|
57
|
+
background: colors.canvas,
|
|
58
|
+
border: `1px solid ${colors.border}`,
|
|
59
|
+
borderRadius: 9,
|
|
60
|
+
boxSizing: "border-box",
|
|
61
|
+
color: colors.ink,
|
|
62
|
+
display: "block",
|
|
63
|
+
font: "inherit",
|
|
64
|
+
fontSize: 13,
|
|
65
|
+
lineHeight: 1.45,
|
|
66
|
+
marginTop: 6,
|
|
67
|
+
outline: "none",
|
|
68
|
+
padding: "10px 12px",
|
|
69
|
+
resize: "vertical",
|
|
70
|
+
width: "100%"
|
|
71
|
+
};
|
|
72
|
+
var buttonBase = {
|
|
73
|
+
alignItems: "center",
|
|
74
|
+
borderRadius: 9,
|
|
75
|
+
cursor: "pointer",
|
|
76
|
+
display: "inline-flex",
|
|
77
|
+
font: "inherit",
|
|
78
|
+
fontSize: 13,
|
|
79
|
+
fontWeight: 650,
|
|
80
|
+
gap: 7,
|
|
81
|
+
justifyContent: "center",
|
|
82
|
+
lineHeight: 1,
|
|
83
|
+
minHeight: 38,
|
|
84
|
+
padding: "10px 14px",
|
|
85
|
+
transition: "opacity 120ms ease, transform 120ms ease"
|
|
86
|
+
};
|
|
87
|
+
var primaryButton = {
|
|
88
|
+
...buttonBase,
|
|
89
|
+
background: colors.ink,
|
|
90
|
+
border: `1px solid ${colors.ink}`,
|
|
91
|
+
color: colors.canvas,
|
|
92
|
+
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.14)"
|
|
93
|
+
};
|
|
94
|
+
var secondaryButton = {
|
|
95
|
+
...buttonBase,
|
|
96
|
+
background: colors.canvas,
|
|
97
|
+
border: `1px solid ${colors.border}`,
|
|
98
|
+
color: colors.ink
|
|
99
|
+
};
|
|
100
|
+
var dangerButton = {
|
|
101
|
+
...secondaryButton,
|
|
102
|
+
color: colors.danger
|
|
103
|
+
};
|
|
104
|
+
var eyebrow = {
|
|
105
|
+
color: colors.muted,
|
|
106
|
+
fontSize: 11,
|
|
107
|
+
fontWeight: 700,
|
|
108
|
+
letterSpacing: "0.09em",
|
|
109
|
+
textTransform: "uppercase"
|
|
110
|
+
};
|
|
111
|
+
var muted = { color: colors.muted, fontSize: 13, lineHeight: 1.5 };
|
|
112
|
+
function KujoMark() {
|
|
113
|
+
return /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: {
|
|
114
|
+
alignItems: "center",
|
|
115
|
+
background: colors.ink,
|
|
116
|
+
borderRadius: 11,
|
|
117
|
+
color: colors.canvas,
|
|
118
|
+
display: "flex",
|
|
119
|
+
fontSize: 15,
|
|
120
|
+
fontWeight: 800,
|
|
121
|
+
height: 42,
|
|
122
|
+
justifyContent: "center",
|
|
123
|
+
letterSpacing: "-0.04em",
|
|
124
|
+
width: 42
|
|
125
|
+
}, children: "K" });
|
|
126
|
+
}
|
|
127
|
+
function ActionButton({ children, disabled, onClick, tone = "primary" }) {
|
|
128
|
+
const style = tone === "primary" ? primaryButton : tone === "danger" ? dangerButton : secondaryButton;
|
|
129
|
+
return /* @__PURE__ */ jsx(
|
|
130
|
+
"button",
|
|
131
|
+
{
|
|
132
|
+
type: "button",
|
|
133
|
+
disabled,
|
|
134
|
+
onClick,
|
|
135
|
+
style: { ...style, ...disabled ? { cursor: "not-allowed", opacity: 0.45 } : {} },
|
|
136
|
+
children
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
function SectionTitle({ title, detail, badge }) {
|
|
141
|
+
return /* @__PURE__ */ jsxs("div", { style: { alignItems: "flex-start", display: "flex", gap: 12, justifyContent: "space-between" }, children: [
|
|
142
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 4 }, children: [
|
|
143
|
+
/* @__PURE__ */ jsx("strong", { style: { fontSize: 15 }, children: title }),
|
|
144
|
+
/* @__PURE__ */ jsx("span", { style: muted, children: detail })
|
|
145
|
+
] }),
|
|
146
|
+
badge
|
|
12
147
|
] });
|
|
148
|
+
}
|
|
149
|
+
function EmptySection({ title, detail }) {
|
|
150
|
+
return /* @__PURE__ */ jsx("section", { style: card, children: /* @__PURE__ */ jsx(SectionTitle, { title, detail, badge: /* @__PURE__ */ jsx(StatusBadge, { status: "pending", label: "NOT GENERATED" }) }) });
|
|
151
|
+
}
|
|
152
|
+
function ReviewSection({ review }) {
|
|
153
|
+
if (!review) return /* @__PURE__ */ jsx(EmptySection, { title: "Review Pack", detail: "Generate a bounded summary of the current workspace changes." });
|
|
13
154
|
return /* @__PURE__ */ jsxs("section", { style: card, children: [
|
|
14
|
-
/* @__PURE__ */
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
]
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
] }),
|
|
38
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
39
|
-
"lines"
|
|
40
|
-
] }),
|
|
41
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
42
|
-
/* @__PURE__ */ jsx("b", { children: review.footprint.churn }),
|
|
43
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
44
|
-
"lines churn"
|
|
45
|
-
] })
|
|
46
|
-
] }),
|
|
155
|
+
/* @__PURE__ */ jsx(
|
|
156
|
+
SectionTitle,
|
|
157
|
+
{
|
|
158
|
+
title: "Review Pack",
|
|
159
|
+
detail: "Change size, risk signals, and suggested checks.",
|
|
160
|
+
badge: /* @__PURE__ */ jsx(
|
|
161
|
+
StatusBadge,
|
|
162
|
+
{
|
|
163
|
+
status: review.footprint.riskLevel === "high" ? "error" : review.footprint.riskLevel === "medium" ? "warning" : "ok",
|
|
164
|
+
label: `${review.footprint.riskLevel.toUpperCase()} RISK`
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
),
|
|
169
|
+
review.stale && /* @__PURE__ */ jsx("div", { role: "alert", style: { ...muted, color: colors.danger }, children: "This review is stale. Generate a new Review Pack before using it." }),
|
|
170
|
+
/* @__PURE__ */ jsx("div", { style: { display: "grid", gap: 10, gridTemplateColumns: "repeat(auto-fit, minmax(130px, 1fr))" }, children: [
|
|
171
|
+
[review.footprint.filesChanged, "Files changed"],
|
|
172
|
+
[`+${review.footprint.additions} / -${review.footprint.deletions}`, "Line delta"],
|
|
173
|
+
[review.footprint.churn, "Lines churn"]
|
|
174
|
+
].map(([value, label]) => /* @__PURE__ */ jsxs("div", { style: { background: colors.soft, borderRadius: 10, display: "grid", gap: 3, padding: 12 }, children: [
|
|
175
|
+
/* @__PURE__ */ jsx("strong", { style: { fontSize: 18 }, children: value }),
|
|
176
|
+
/* @__PURE__ */ jsx("span", { style: eyebrow, children: label })
|
|
177
|
+
] }, label)) }),
|
|
47
178
|
review.footprint.signals.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
48
|
-
/* @__PURE__ */ jsx("
|
|
49
|
-
/* @__PURE__ */ jsx("ul", { children: review.footprint.signals.map((signal) => /* @__PURE__ */ jsx("li", { children: signal.message }, signal.id)) })
|
|
179
|
+
/* @__PURE__ */ jsx("strong", { style: { fontSize: 13 }, children: "Signals" }),
|
|
180
|
+
/* @__PURE__ */ jsx("ul", { style: { ...muted, marginBottom: 0, paddingLeft: 20 }, children: review.footprint.signals.map((signal) => /* @__PURE__ */ jsx("li", { children: signal.message }, signal.id)) })
|
|
50
181
|
] }),
|
|
51
182
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
52
|
-
/* @__PURE__ */ jsx("
|
|
53
|
-
/* @__PURE__ */ jsx("div", { style:
|
|
54
|
-
/* @__PURE__ */ jsx("ul", { children: review.suggestedTests.slice(0, 12).map((test) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("code", { children: test.command }) }, test.command)) })
|
|
183
|
+
/* @__PURE__ */ jsx("strong", { style: { fontSize: 13 }, children: "Suggested verification" }),
|
|
184
|
+
/* @__PURE__ */ jsx("div", { style: muted, children: "Suggestions only. Kujo does not claim these commands ran." }),
|
|
185
|
+
/* @__PURE__ */ jsx("ul", { style: { marginBottom: 0, paddingLeft: 20 }, children: review.suggestedTests.slice(0, 12).map((test) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("code", { children: test.command }) }, test.command)) })
|
|
55
186
|
] }),
|
|
56
|
-
/* @__PURE__ */ jsx("
|
|
187
|
+
/* @__PURE__ */ jsx("span", { style: eyebrow, children: "ChangeBucket + PatchBrief" })
|
|
57
188
|
] });
|
|
58
189
|
}
|
|
59
190
|
function FailureSection({ failure }) {
|
|
60
|
-
if (!failure) return /* @__PURE__ */
|
|
61
|
-
/* @__PURE__ */ jsx("strong", { children: "Failure Evidence" }),
|
|
62
|
-
/* @__PURE__ */ jsx("span", { children: "None" })
|
|
63
|
-
] });
|
|
191
|
+
if (!failure) return /* @__PURE__ */ jsx(EmptySection, { title: "Failure Evidence", detail: "No redacted failure record has been captured." });
|
|
64
192
|
return /* @__PURE__ */ jsxs("section", { style: card, children: [
|
|
65
|
-
/* @__PURE__ */
|
|
66
|
-
/* @__PURE__ */ jsx("strong", { children: "Failure Evidence" }),
|
|
67
|
-
/* @__PURE__ */ jsx(StatusBadge, { status: "error", label: "FAILED" })
|
|
68
|
-
] }),
|
|
69
|
-
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("b", { children: failure.failure.title }) }),
|
|
193
|
+
/* @__PURE__ */ jsx(SectionTitle, { title: "Failure Evidence", detail: failure.failure.title, badge: /* @__PURE__ */ jsx(StatusBadge, { status: "error", label: "CAPTURED" }) }),
|
|
70
194
|
failure.failure.command && /* @__PURE__ */ jsxs("div", { children: [
|
|
71
|
-
/* @__PURE__ */ jsx("
|
|
195
|
+
/* @__PURE__ */ jsx("span", { style: eyebrow, children: "Command" }),
|
|
72
196
|
/* @__PURE__ */ jsx("br", {}),
|
|
73
197
|
/* @__PURE__ */ jsx("code", { children: failure.failure.command })
|
|
74
198
|
] }),
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
failure.failure.exitCode
|
|
78
|
-
] }),
|
|
79
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
80
|
-
"Redaction applied: ",
|
|
199
|
+
/* @__PURE__ */ jsxs("div", { style: muted, children: [
|
|
200
|
+
failure.failure.exitCode !== void 0 ? `Exit code ${failure.failure.exitCode} \xB7 ` : "",
|
|
81
201
|
failure.redaction.redactedCount,
|
|
82
|
-
" match(es)"
|
|
202
|
+
" sensitive match(es) redacted"
|
|
83
203
|
] }),
|
|
84
|
-
failure.evidence.map((item) => /* @__PURE__ */ jsxs("details", { children: [
|
|
85
|
-
/* @__PURE__ */ jsxs("summary", { children: [
|
|
204
|
+
failure.evidence.map((item) => /* @__PURE__ */ jsxs("details", { style: { background: colors.soft, borderRadius: 10, padding: 12 }, children: [
|
|
205
|
+
/* @__PURE__ */ jsxs("summary", { style: { cursor: "pointer", fontSize: 13, fontWeight: 650 }, children: [
|
|
86
206
|
item.label,
|
|
87
|
-
item.truncated ? "
|
|
207
|
+
item.truncated ? " \xB7 truncated" : ""
|
|
88
208
|
] }),
|
|
89
|
-
/* @__PURE__ */ jsx("pre", { style: {
|
|
209
|
+
/* @__PURE__ */ jsx("pre", { style: { fontSize: 12, marginBottom: 0, maxHeight: 320, overflow: "auto", whiteSpace: "pre-wrap" }, children: item.content })
|
|
90
210
|
] }, item.label)),
|
|
91
|
-
/* @__PURE__ */ jsx("
|
|
211
|
+
/* @__PURE__ */ jsx("span", { style: eyebrow, children: "CaseFile" })
|
|
92
212
|
] });
|
|
93
213
|
}
|
|
94
214
|
function ContextSection({ context }) {
|
|
95
|
-
if (!context) return /* @__PURE__ */
|
|
96
|
-
/* @__PURE__ */ jsx("strong", { children: "Context Pack" }),
|
|
97
|
-
/* @__PURE__ */ jsx("span", { children: "Available" })
|
|
98
|
-
] });
|
|
215
|
+
if (!context) return /* @__PURE__ */ jsx(EmptySection, { title: "Context Pack", detail: "Select the files that matter before an agent reads broadly." });
|
|
99
216
|
return /* @__PURE__ */ jsxs("section", { style: card, children: [
|
|
100
|
-
/* @__PURE__ */ jsx(
|
|
101
|
-
|
|
102
|
-
|
|
217
|
+
/* @__PURE__ */ jsx(
|
|
218
|
+
SectionTitle,
|
|
219
|
+
{
|
|
220
|
+
title: "Context Pack",
|
|
221
|
+
detail: context.task,
|
|
222
|
+
badge: /* @__PURE__ */ jsx(StatusBadge, { status: context.stale ? "warning" : "ok", label: context.stale ? "STALE" : "READY" })
|
|
223
|
+
}
|
|
224
|
+
),
|
|
225
|
+
/* @__PURE__ */ jsxs("div", { style: { ...muted, fontWeight: 600 }, children: [
|
|
103
226
|
context.files.length,
|
|
104
|
-
"
|
|
227
|
+
" files \xB7 about ",
|
|
105
228
|
context.estimatedTokens.toLocaleString(),
|
|
106
229
|
" tokens \xB7 ",
|
|
107
|
-
context.depth
|
|
230
|
+
context.depth,
|
|
231
|
+
" depth"
|
|
108
232
|
] }),
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
/* @__PURE__ */ jsx("
|
|
112
|
-
/* @__PURE__ */ jsx("br", {}),
|
|
113
|
-
/* @__PURE__ */ jsx("small", { children: file.reason })
|
|
233
|
+
/* @__PURE__ */ jsx("div", { style: { display: "grid", gap: 8 }, children: context.files.slice(0, 20).map((file) => /* @__PURE__ */ jsxs("div", { style: { background: colors.soft, borderRadius: 9, display: "grid", gap: 3, padding: "10px 12px" }, children: [
|
|
234
|
+
/* @__PURE__ */ jsx("code", { style: { fontSize: 12 }, children: file.path }),
|
|
235
|
+
/* @__PURE__ */ jsx("span", { style: muted, children: file.reason })
|
|
114
236
|
] }, file.path)) }),
|
|
115
|
-
context.truncated && /* @__PURE__ */ jsx("div", { children: "
|
|
116
|
-
/* @__PURE__ */ jsx("
|
|
237
|
+
context.truncated && /* @__PURE__ */ jsx("div", { style: muted, children: "The configured token budget bounded this selection." }),
|
|
238
|
+
/* @__PURE__ */ jsx("span", { style: eyebrow, children: "Scent" })
|
|
117
239
|
] });
|
|
118
240
|
}
|
|
119
|
-
function
|
|
241
|
+
function KujoPanel({ context, compact = false }) {
|
|
120
242
|
const { data, loading, error, refresh } = usePluginData("detail", { entityType: context.entityType, entityId: context.entityId });
|
|
121
243
|
const generateReview = usePluginAction("generate-review");
|
|
122
244
|
const generateContext = usePluginAction("generate-context");
|
|
@@ -140,40 +262,112 @@ function KujoDetailTab({ context }) {
|
|
|
140
262
|
setBusy(null);
|
|
141
263
|
}
|
|
142
264
|
}
|
|
143
|
-
if (loading) return /* @__PURE__ */ jsx(Spinner, { label: "Loading Kujo
|
|
144
|
-
if (error) return /* @__PURE__ */ jsxs("div", { role: "alert", children: [
|
|
145
|
-
"Unable to load Kujo
|
|
265
|
+
if (loading) return /* @__PURE__ */ jsx(Spinner, { label: "Loading Kujo workspace intelligence" });
|
|
266
|
+
if (error) return /* @__PURE__ */ jsxs("div", { role: "alert", style: { ...card, color: colors.danger }, children: [
|
|
267
|
+
"Unable to load Kujo: ",
|
|
146
268
|
error.message
|
|
147
269
|
] });
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
/* @__PURE__ */ jsx(
|
|
270
|
+
const hasArtifacts = Boolean(data?.review || data?.failure || data?.context);
|
|
271
|
+
return /* @__PURE__ */ jsxs("div", { style: { ...panel, ...compact ? { marginTop: 12 } : {} }, children: [
|
|
272
|
+
/* @__PURE__ */ jsxs("header", { style: hero, children: [
|
|
273
|
+
/* @__PURE__ */ jsx(KujoMark, {}),
|
|
274
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 3, minWidth: 0 }, children: [
|
|
275
|
+
/* @__PURE__ */ jsx("span", { style: eyebrow, children: "Workspace intelligence" }),
|
|
276
|
+
/* @__PURE__ */ jsx("strong", { style: { fontSize: compact ? 17 : 20, letterSpacing: "-0.02em" }, children: "Kujo" }),
|
|
277
|
+
/* @__PURE__ */ jsx("span", { style: muted, children: "Scope the work. Review the change. Preserve the evidence." })
|
|
278
|
+
] }),
|
|
279
|
+
/* @__PURE__ */ jsx(StatusBadge, { status: "ok", label: "READY" })
|
|
152
280
|
] }),
|
|
153
|
-
actionError && /* @__PURE__ */ jsx("div", { role: "alert", children: actionError }),
|
|
281
|
+
actionError && /* @__PURE__ */ jsx("div", { role: "alert", style: { ...card, borderColor: colors.danger, color: colors.danger }, children: actionError }),
|
|
154
282
|
canGenerate && /* @__PURE__ */ jsxs("section", { style: card, children: [
|
|
155
|
-
/* @__PURE__ */
|
|
156
|
-
|
|
157
|
-
"
|
|
158
|
-
/* @__PURE__ */ jsx("input", { value: task, onChange: (event) => setTask(event.target.value), maxLength: 1e4, style: { display: "block", width: "100%" } })
|
|
159
|
-
] }),
|
|
160
|
-
/* @__PURE__ */ jsx("button", { disabled: busy !== null || !task.trim(), onClick: () => run("context", () => generateContext({ entityType: context.entityType, entityId: context.entityId, task, depth: "focused" })), children: busy === "context" ? "Selecting\u2026" : "Generate Context Pack" }),
|
|
161
|
-
/* @__PURE__ */ jsxs("label", { children: [
|
|
162
|
-
"Failure title",
|
|
163
|
-
/* @__PURE__ */ jsx("input", { value: failureTitle, onChange: (event) => setFailureTitle(event.target.value), maxLength: 200, style: { display: "block", width: "100%" } })
|
|
283
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
284
|
+
/* @__PURE__ */ jsx("div", { style: eyebrow, children: "Actions" }),
|
|
285
|
+
/* @__PURE__ */ jsx("strong", { style: { display: "block", fontSize: 16, marginTop: 4 }, children: "Create a reviewable work record" })
|
|
164
286
|
] }),
|
|
165
|
-
/* @__PURE__ */ jsxs("
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
287
|
+
/* @__PURE__ */ jsxs("div", { style: actionGrid, children: [
|
|
288
|
+
/* @__PURE__ */ jsxs("div", { style: actionCard, children: [
|
|
289
|
+
/* @__PURE__ */ jsx(SectionTitle, { title: "Review changes", detail: "Measure blast radius and prepare a review handoff." }),
|
|
290
|
+
/* @__PURE__ */ jsx("div", { style: { flex: 1 } }),
|
|
291
|
+
/* @__PURE__ */ jsxs(ActionButton, { disabled: busy !== null, onClick: () => run("review", () => generateReview({ entityType: context.entityType, entityId: context.entityId })), children: [
|
|
292
|
+
busy === "review" ? "Generating\u2026" : "Generate Review Pack",
|
|
293
|
+
" ",
|
|
294
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2192" })
|
|
295
|
+
] })
|
|
296
|
+
] }),
|
|
297
|
+
/* @__PURE__ */ jsxs("div", { style: actionCard, children: [
|
|
298
|
+
/* @__PURE__ */ jsx(SectionTitle, { title: "Select context", detail: "Build a focused, bounded file set for a task." }),
|
|
299
|
+
/* @__PURE__ */ jsxs("label", { style: { ...eyebrow, display: "block" }, children: [
|
|
300
|
+
"Task",
|
|
301
|
+
/* @__PURE__ */ jsx(
|
|
302
|
+
"textarea",
|
|
303
|
+
{
|
|
304
|
+
value: task,
|
|
305
|
+
onChange: (event) => setTask(event.target.value),
|
|
306
|
+
maxLength: 1e4,
|
|
307
|
+
placeholder: "What should the agent investigate?",
|
|
308
|
+
rows: 3,
|
|
309
|
+
style: input
|
|
310
|
+
}
|
|
311
|
+
)
|
|
312
|
+
] }),
|
|
313
|
+
/* @__PURE__ */ jsxs(ActionButton, { disabled: busy !== null || !task.trim(), onClick: () => run("context", () => generateContext({ entityType: context.entityType, entityId: context.entityId, task, depth: "focused" })), children: [
|
|
314
|
+
busy === "context" ? "Selecting\u2026" : "Generate Context Pack",
|
|
315
|
+
" ",
|
|
316
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2192" })
|
|
317
|
+
] })
|
|
318
|
+
] }),
|
|
319
|
+
/* @__PURE__ */ jsxs("div", { style: actionCard, children: [
|
|
320
|
+
/* @__PURE__ */ jsx(SectionTitle, { title: "Capture a failure", detail: "Store bounded logs with sensitive values redacted." }),
|
|
321
|
+
/* @__PURE__ */ jsxs("label", { style: { ...eyebrow, display: "block" }, children: [
|
|
322
|
+
"Title",
|
|
323
|
+
/* @__PURE__ */ jsx(
|
|
324
|
+
"input",
|
|
325
|
+
{
|
|
326
|
+
value: failureTitle,
|
|
327
|
+
onChange: (event) => setFailureTitle(event.target.value),
|
|
328
|
+
maxLength: 200,
|
|
329
|
+
placeholder: "CI verification failure",
|
|
330
|
+
style: input
|
|
331
|
+
}
|
|
332
|
+
)
|
|
333
|
+
] }),
|
|
334
|
+
/* @__PURE__ */ jsxs("label", { style: { ...eyebrow, display: "block" }, children: [
|
|
335
|
+
"Bounded log",
|
|
336
|
+
/* @__PURE__ */ jsx(
|
|
337
|
+
"textarea",
|
|
338
|
+
{
|
|
339
|
+
value: failureLog,
|
|
340
|
+
onChange: (event) => setFailureLog(event.target.value),
|
|
341
|
+
maxLength: 2e5,
|
|
342
|
+
placeholder: "Paste the relevant output here.",
|
|
343
|
+
rows: 3,
|
|
344
|
+
style: input
|
|
345
|
+
}
|
|
346
|
+
)
|
|
347
|
+
] }),
|
|
348
|
+
/* @__PURE__ */ jsxs(ActionButton, { disabled: busy !== null || !failureTitle.trim(), onClick: () => run("failure", () => captureFailure({ entityType: context.entityType, entityId: context.entityId, title: failureTitle, log: failureLog })), children: [
|
|
349
|
+
busy === "failure" ? "Capturing\u2026" : "Capture Failure Evidence",
|
|
350
|
+
" ",
|
|
351
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2192" })
|
|
352
|
+
] })
|
|
353
|
+
] })
|
|
354
|
+
] })
|
|
355
|
+
] }),
|
|
356
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 12 }, children: [
|
|
357
|
+
/* @__PURE__ */ jsx(ReviewSection, { review: data?.review ?? null }),
|
|
358
|
+
/* @__PURE__ */ jsx(FailureSection, { failure: data?.failure ?? null }),
|
|
359
|
+
/* @__PURE__ */ jsx(ContextSection, { context: data?.context ?? null })
|
|
171
360
|
] }),
|
|
172
|
-
/* @__PURE__ */ jsx(
|
|
173
|
-
/* @__PURE__ */ jsx(FailureSection, { failure: data?.failure ?? null }),
|
|
174
|
-
/* @__PURE__ */ jsx(ContextSection, { context: data?.context ?? null })
|
|
361
|
+
hasArtifacts && /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ jsx(ActionButton, { tone: "danger", disabled: busy !== null, onClick: () => run("clear", () => clearArtifacts({ entityType: context.entityType, entityId: context.entityId })), children: busy === "clear" ? "Clearing\u2026" : "Clear Kujo data" }) })
|
|
175
362
|
] });
|
|
176
363
|
}
|
|
364
|
+
function KujoDetailTab(props) {
|
|
365
|
+
return /* @__PURE__ */ jsx(KujoPanel, { ...props });
|
|
366
|
+
}
|
|
367
|
+
function KujoTaskDetailView(props) {
|
|
368
|
+
return /* @__PURE__ */ jsx(KujoPanel, { ...props, compact: true });
|
|
369
|
+
}
|
|
177
370
|
export {
|
|
178
|
-
KujoDetailTab
|
|
371
|
+
KujoDetailTab,
|
|
372
|
+
KujoTaskDetailView
|
|
179
373
|
};
|
package/dist/worker.js
CHANGED
|
@@ -1,224 +1,8 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
1
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
-
}) : x)(function(x) {
|
|
10
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
-
});
|
|
13
|
-
var __commonJS = (cb, mod) => function __require2() {
|
|
14
|
-
try {
|
|
15
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
16
|
-
} catch (e) {
|
|
17
|
-
throw mod = 0, e;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
2
|
var __export = (target, all) => {
|
|
21
3
|
for (var name in all)
|
|
22
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
23
5
|
};
|
|
24
|
-
var __copyProps = (to, from, except, desc) => {
|
|
25
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
26
|
-
for (let key of __getOwnPropNames(from))
|
|
27
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
28
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
29
|
-
}
|
|
30
|
-
return to;
|
|
31
|
-
};
|
|
32
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
33
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
34
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
35
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
36
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
37
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
38
|
-
mod
|
|
39
|
-
));
|
|
40
|
-
|
|
41
|
-
// node_modules/@kujolang/kujo-runtime/package.json
|
|
42
|
-
var require_package = __commonJS({
|
|
43
|
-
"node_modules/@kujolang/kujo-runtime/package.json"(exports, module) {
|
|
44
|
-
module.exports = {
|
|
45
|
-
name: "@kujolang/kujo-runtime",
|
|
46
|
-
version: "1.2.2",
|
|
47
|
-
description: "Kujo programming language runtime",
|
|
48
|
-
license: "MIT",
|
|
49
|
-
repository: {
|
|
50
|
-
type: "git",
|
|
51
|
-
url: "git+https://github.com/kujolang/kujo.git",
|
|
52
|
-
directory: "npm/runtime"
|
|
53
|
-
},
|
|
54
|
-
homepage: "https://github.com/kujolang/kujo",
|
|
55
|
-
engines: {
|
|
56
|
-
node: ">=18"
|
|
57
|
-
},
|
|
58
|
-
bin: {
|
|
59
|
-
kujo: "bin/kujo.js"
|
|
60
|
-
},
|
|
61
|
-
main: "index.js",
|
|
62
|
-
types: "index.d.ts",
|
|
63
|
-
exports: {
|
|
64
|
-
".": {
|
|
65
|
-
types: "./index.d.ts",
|
|
66
|
-
require: "./index.js",
|
|
67
|
-
default: "./index.js"
|
|
68
|
-
},
|
|
69
|
-
"./package.json": "./package.json"
|
|
70
|
-
},
|
|
71
|
-
files: [
|
|
72
|
-
"bin/kujo.js",
|
|
73
|
-
"index.js",
|
|
74
|
-
"index.d.ts",
|
|
75
|
-
"README.md"
|
|
76
|
-
],
|
|
77
|
-
optionalDependencies: {
|
|
78
|
-
"@kujolang/kujo-darwin-arm64": "1.2.2",
|
|
79
|
-
"@kujolang/kujo-darwin-x64": "1.2.2",
|
|
80
|
-
"@kujolang/kujo-linux-arm64": "1.2.2",
|
|
81
|
-
"@kujolang/kujo-linux-x64": "1.2.2",
|
|
82
|
-
"@kujolang/kujo-win32-x64": "1.2.2"
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// node_modules/@kujolang/kujo-runtime/index.js
|
|
89
|
-
var require_kujo_runtime = __commonJS({
|
|
90
|
-
"node_modules/@kujolang/kujo-runtime/index.js"(exports, module) {
|
|
91
|
-
"use strict";
|
|
92
|
-
var fs2 = __require("node:fs");
|
|
93
|
-
var path2 = __require("node:path");
|
|
94
|
-
var RUNTIME_PACKAGE_VERSION = require_package().version;
|
|
95
|
-
var TARGETS = Object.freeze({
|
|
96
|
-
"darwin-arm64": Object.freeze({
|
|
97
|
-
packageName: "@kujolang/kujo-darwin-arm64",
|
|
98
|
-
binaryName: "kujo"
|
|
99
|
-
}),
|
|
100
|
-
"darwin-x64": Object.freeze({
|
|
101
|
-
packageName: "@kujolang/kujo-darwin-x64",
|
|
102
|
-
binaryName: "kujo"
|
|
103
|
-
}),
|
|
104
|
-
"linux-x64": Object.freeze({
|
|
105
|
-
packageName: "@kujolang/kujo-linux-x64",
|
|
106
|
-
binaryName: "kujo"
|
|
107
|
-
}),
|
|
108
|
-
"linux-arm64": Object.freeze({
|
|
109
|
-
packageName: "@kujolang/kujo-linux-arm64",
|
|
110
|
-
binaryName: "kujo"
|
|
111
|
-
}),
|
|
112
|
-
"win32-x64": Object.freeze({
|
|
113
|
-
packageName: "@kujolang/kujo-win32-x64",
|
|
114
|
-
binaryName: "kujo.exe"
|
|
115
|
-
})
|
|
116
|
-
});
|
|
117
|
-
function targetFor(platform = process.platform, arch = process.arch) {
|
|
118
|
-
return TARGETS[`${platform}-${arch}`] || null;
|
|
119
|
-
}
|
|
120
|
-
var KujoRuntimeError = class extends Error {
|
|
121
|
-
constructor(message, code, platform, arch, options = {}) {
|
|
122
|
-
super(message, options);
|
|
123
|
-
this.name = this.constructor.name;
|
|
124
|
-
this.code = code;
|
|
125
|
-
this.platform = platform;
|
|
126
|
-
this.arch = arch;
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
var UnsupportedPlatformError = class extends KujoRuntimeError {
|
|
130
|
-
constructor(platform, arch) {
|
|
131
|
-
const supported = Object.keys(TARGETS).sort().join(", ");
|
|
132
|
-
super(
|
|
133
|
-
`Kujo does not provide an npm runtime for ${platform}-${arch}. Supported targets: ${supported}.`,
|
|
134
|
-
"KUJO_UNSUPPORTED_PLATFORM",
|
|
135
|
-
platform,
|
|
136
|
-
arch
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
var MissingPlatformPackageError = class extends KujoRuntimeError {
|
|
141
|
-
constructor(platform, arch, target, cause) {
|
|
142
|
-
super(
|
|
143
|
-
[
|
|
144
|
-
`Kujo's platform package ${target.packageName} is not installed.`,
|
|
145
|
-
"Reinstall @kujolang/kujo-runtime without --omit=optional or --no-optional,",
|
|
146
|
-
"and ensure your package manager is allowed to install optional dependencies."
|
|
147
|
-
].join(" "),
|
|
148
|
-
"KUJO_PLATFORM_PACKAGE_MISSING",
|
|
149
|
-
platform,
|
|
150
|
-
arch,
|
|
151
|
-
{ cause }
|
|
152
|
-
);
|
|
153
|
-
this.packageName = target.packageName;
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
var BinaryNotFoundError = class extends KujoRuntimeError {
|
|
157
|
-
constructor(platform, arch, packageName, binaryPath) {
|
|
158
|
-
super(
|
|
159
|
-
`Kujo's platform package ${packageName} does not contain the expected binary at ${binaryPath}. Reinstall the package and verify your npm cache.`,
|
|
160
|
-
"KUJO_BINARY_MISSING",
|
|
161
|
-
platform,
|
|
162
|
-
arch
|
|
163
|
-
);
|
|
164
|
-
this.packageName = packageName;
|
|
165
|
-
this.binaryPath = binaryPath;
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
function selectedTarget(options = {}) {
|
|
169
|
-
const platform = options.platform || process.platform;
|
|
170
|
-
const arch = options.arch || process.arch;
|
|
171
|
-
const target = targetFor(platform, arch);
|
|
172
|
-
if (!target) {
|
|
173
|
-
throw new UnsupportedPlatformError(platform, arch);
|
|
174
|
-
}
|
|
175
|
-
return { platform, arch, ...target };
|
|
176
|
-
}
|
|
177
|
-
function resolveRuntime(options = {}) {
|
|
178
|
-
const { platform, arch, packageName, binaryName } = selectedTarget(options);
|
|
179
|
-
const resolvePackage = options.resolvePackage || __require.resolve;
|
|
180
|
-
const fileExists = options.fileExists || fs2.existsSync;
|
|
181
|
-
const readManifest = options.readManifest || ((manifestPath2) => JSON.parse(fs2.readFileSync(manifestPath2, "utf8")));
|
|
182
|
-
let manifestPath;
|
|
183
|
-
try {
|
|
184
|
-
manifestPath = resolvePackage(`${packageName}/package.json`);
|
|
185
|
-
} catch (error51) {
|
|
186
|
-
throw new MissingPlatformPackageError(platform, arch, { packageName }, error51);
|
|
187
|
-
}
|
|
188
|
-
const binaryPath = path2.join(path2.dirname(manifestPath), "bin", binaryName);
|
|
189
|
-
if (!fileExists(binaryPath)) {
|
|
190
|
-
throw new BinaryNotFoundError(platform, arch, packageName, binaryPath);
|
|
191
|
-
}
|
|
192
|
-
const platformManifest = readManifest(manifestPath);
|
|
193
|
-
return Object.freeze({
|
|
194
|
-
platform,
|
|
195
|
-
arch,
|
|
196
|
-
packageName,
|
|
197
|
-
packageVersion: RUNTIME_PACKAGE_VERSION,
|
|
198
|
-
runtimeVersion: platformManifest.version,
|
|
199
|
-
binaryName,
|
|
200
|
-
binaryPath,
|
|
201
|
-
source: "bundled"
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
function getKujoRuntimeInfo(options = {}) {
|
|
205
|
-
return resolveRuntime(options);
|
|
206
|
-
}
|
|
207
|
-
function resolveKujoBinary(options = {}) {
|
|
208
|
-
return resolveRuntime(options).binaryPath;
|
|
209
|
-
}
|
|
210
|
-
module.exports = {
|
|
211
|
-
BinaryNotFoundError,
|
|
212
|
-
KujoRuntimeError,
|
|
213
|
-
MissingPlatformPackageError,
|
|
214
|
-
TARGETS,
|
|
215
|
-
UnsupportedPlatformError,
|
|
216
|
-
getKujoRuntimeInfo,
|
|
217
|
-
resolveKujoBinary,
|
|
218
|
-
targetFor
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
6
|
|
|
223
7
|
// node_modules/@paperclipai/plugin-sdk/dist/define-plugin.js
|
|
224
8
|
function definePlugin(definition) {
|
|
@@ -28926,7 +28710,7 @@ var CONTEXT_BUDGETS = {
|
|
|
28926
28710
|
focused: 16e3,
|
|
28927
28711
|
broad: 4e4
|
|
28928
28712
|
};
|
|
28929
|
-
var PLUGIN_VERSION = "0.1.
|
|
28713
|
+
var PLUGIN_VERSION = "0.1.4";
|
|
28930
28714
|
var PAPERCLIP_API_VERSION = 1;
|
|
28931
28715
|
|
|
28932
28716
|
// src/config/schema.ts
|
|
@@ -29309,7 +29093,7 @@ async function resolveKujo(config2, cwd) {
|
|
|
29309
29093
|
return await assertCompatible(executable, cwd, "configured");
|
|
29310
29094
|
}
|
|
29311
29095
|
try {
|
|
29312
|
-
const runtime = await
|
|
29096
|
+
const runtime = await import("@kujolang/kujo-runtime");
|
|
29313
29097
|
const info = runtime.getKujoRuntimeInfo();
|
|
29314
29098
|
const executable = await validateExecutable(info.binaryPath);
|
|
29315
29099
|
return await assertCompatible(executable, cwd, "bundled");
|
|
@@ -14,12 +14,13 @@
|
|
|
14
14
|
- `projects.read`, `project.workspaces.read`: canonical workspace resolution only
|
|
15
15
|
- `plugin.state.read`, `plugin.state.write`: normalized artifact persistence
|
|
16
16
|
- `ui.detailTab.register`: one shared Kujo tab on project/issue/run details
|
|
17
|
+
- `ui.taskDetailView.register`: an inline Kujo workspace in the current issue view
|
|
17
18
|
- `skills.managed`: optional Scoped Repository Context guidance
|
|
18
19
|
|
|
19
20
|
The plugin requests no HTTP, secret, issue-write, approval, budget, database, job, webhook, or arbitrary local-folder capability.
|
|
20
21
|
|
|
21
22
|
## UI walkthrough
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Kujo appears automatically in the current issue view and remains available as a shared detail tab on project, issue detail, and run pages. The workspace presents **Generate Review Pack**, **Generate Context Pack**, and **Capture Failure Evidence** as distinct, styled actions. Review shows blast radius, explainable signals, and clearly labeled suggested verification. Failure Evidence shows bounded excerpts and redaction counts. Context shows selected paths, reasons, estimated tokens, depth, and stale/budget status. Run views show associated persisted evidence without exposing a terminal.
|
|
24
25
|
|
|
25
26
|
Catalog review should require the tagged cross-platform workflow, npm provenance for all six runtime packages and this plugin, install/upgrade/uninstall evidence on the declared minimum host, and the security assertions in `THREAT_MODEL.md`.
|
package/docs/INSTALLATION.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
npx paperclipai plugin install @kujolang/paperclip
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
Restart Paperclip if it is running. Open
|
|
15
|
+
Restart Paperclip if it is running. Open an issue and confirm that the Kujo workspace appears in the current task view. On project and run pages, open the **Kujo** tab. No Classic Task Interface setting is required.
|
|
16
16
|
|
|
17
17
|
The package installs `@kujolang/kujo-runtime` and one matching optional native package. Supported targets are macOS arm64/x64, Linux arm64/x64, and Windows x64. No Kujo package uses `preinstall`, `install`, or `postinstall`.
|
|
18
18
|
|
package/docs/OPERATIONS.md
CHANGED
|
@@ -36,6 +36,10 @@ Component updates must start from clean, reviewed source repositories at exact c
|
|
|
36
36
|
|
|
37
37
|
Never hand-edit a bundled file without updating its canonical source. Runtime checks reject any file that differs from the component lock.
|
|
38
38
|
|
|
39
|
+
## Release credentials
|
|
40
|
+
|
|
41
|
+
GitHub Actions publishes through the npm trusted publisher bound to `kujolang/paperclip`, `.github/workflows/release.yml`, and the `npm` environment. Keep `id-token: write`; do not add an npm access token or `NODE_AUTH_TOKEN`. The npm package requires two-factor authentication and disallows traditional token publishing, while trusted OIDC publishing remains available.
|
|
42
|
+
|
|
39
43
|
## Recover from corrupt state
|
|
40
44
|
|
|
41
45
|
If a detail view shows no artifact after an upgrade, inspect worker logs for schema or state errors. Clear the entity's Kujo data, then regenerate the artifact. Do not edit Paperclip's plugin-state tables directly.
|
|
@@ -27,7 +27,7 @@ The release order is platform runtime packages, neutral `@kujolang/kujo-runtime`
|
|
|
27
27
|
|
|
28
28
|
The runtime release workflows build and smoke macOS arm64/x64, Linux arm64/x64, and Windows x64. Paperclip CI tests those five targets. A separate compatibility matrix tests Node.js 24.11 and current Node.js 24 against the minimum, locked, and latest compatible Paperclip SDK versions. Local plugin feature execution is verified on the developer host; every supported target is exercised during a tagged release.
|
|
29
29
|
|
|
30
|
-
The tag workflow accepts only an annotated
|
|
30
|
+
The tag workflow accepts only an annotated tag with a GitHub-verified SSH or PGP signature whose name matches `package.json`. It verifies the repository, packs once, attests that tarball, publishes that exact file through npm trusted publishing with short-lived OIDC credentials, and attaches its checksum, CycloneDX SBOM, component lock, and JSON schemas to the GitHub release. Package settings require two-factor authentication and disallow traditional token publishing.
|
|
31
31
|
|
|
32
32
|
## Performance bounds
|
|
33
33
|
|
package/docs/USAGE.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Paperclip UI
|
|
4
4
|
|
|
5
|
-
Open the **Kujo** detail tab
|
|
5
|
+
Open an issue and Kujo appears inline in Paperclip's current task view. There is no Classic Task Interface prerequisite. Project, issue detail, and run pages also expose the **Kujo** detail tab where the host supports tabs.
|
|
6
6
|
|
|
7
7
|
- **Generate Review Pack** measures the current working tree and builds a handoff.
|
|
8
8
|
- **Generate Context Pack** selects files for a task at minimal, focused, or broad depth.
|
|
@@ -10,6 +10,8 @@ Open the **Kujo** detail tab on a project or issue.
|
|
|
10
10
|
|
|
11
11
|
Run views display saved evidence. They do not expose a terminal.
|
|
12
12
|
|
|
13
|
+
The inline workspace and detail tab use the same actions and persisted artifacts, so changing views does not create a second copy of Kujo data.
|
|
14
|
+
|
|
13
15
|
## Agent tools
|
|
14
16
|
|
|
15
17
|
### Review changes
|
package/package.json
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kujolang/paperclip",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Make Paperclip agent work easier to scope, review, reproduce, and verify.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/kujolang/paperclip#readme",
|
|
7
|
-
"bugs": {
|
|
8
|
-
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "https://github.com/kujolang/paperclip/issues"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/kujolang/paperclip.git"
|
|
13
|
+
},
|
|
9
14
|
"type": "module",
|
|
10
15
|
"engines": {
|
|
11
16
|
"node": ">=24.11.0"
|