gm-copilot-cli 2.0.538 → 2.0.539
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/copilot-profile.md +1 -1
- package/index.html +168 -524
- package/manifest.yml +1 -1
- package/package.json +1 -1
- package/tools.json +1 -1
package/copilot-profile.md
CHANGED
package/index.html
CHANGED
|
@@ -1,531 +1,175 @@
|
|
|
1
|
-
<!
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en"><head>
|
|
3
|
+
<meta charset="utf-8">
|
|
4
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
5
|
+
<title>Copilot CLI · gm</title>
|
|
6
|
+
<meta name="description" content="State machine agent with hooks, skills, and automated git enforcement">
|
|
7
|
+
<meta name="color-scheme" content="light">
|
|
8
|
+
<meta name="theme-color" content="#EFE9DD">
|
|
9
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
|
+
<link href="https://fonts.googleapis.com/css2?family=Archivo:wght@400;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&family=Space+Grotesk:wght@400;500;600&display=swap" rel="stylesheet">
|
|
12
|
+
<style>
|
|
13
|
+
@font-face{font-family:'Archivo';src:local('Archivo');}
|
|
14
|
+
:root{
|
|
15
|
+
--paper:#EFE9DD;--ink:#0B0B09;--acid:#B8FF00;--link:#1F4DFF;--warn:#FF3B1F;--live:#00A86B;
|
|
16
|
+
--fg:var(--ink);--bg:var(--paper);--fg-2:#3a3a36;--fg-3:#6b6b64;
|
|
17
|
+
--ff-display:'Archivo','Archivo Narrow',ui-sans-serif,sans-serif;
|
|
18
|
+
--ff-mono:'JetBrains Mono','ui-monospace',Menlo,Consolas,monospace;
|
|
19
|
+
--ff-body:'Space Grotesk','Archivo',ui-sans-serif,sans-serif;
|
|
20
|
+
--fs-hero:clamp(64px,12vw,144px);--fs-h1:clamp(40px,6vw,72px);--fs-h2:28px;--fs-h3:18px;--fs-h4:15px;
|
|
21
|
+
--fs-body:14px;--fs-lg:17px;--fs-xs:11px;--fs-micro:10px;
|
|
22
|
+
--lh-tight:1.02;--lh-snug:1.18;--lh-base:1.5;--lh-long:1.6;
|
|
23
|
+
--tr-tight:-0.02em;--tr-label:0.08em;
|
|
24
|
+
--space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:24px;--space-6:32px;--space-7:48px;--space-8:64px;
|
|
25
|
+
--measure:64ch;
|
|
26
|
+
--dur-snap:80ms;--dur-base:160ms;--ease:cubic-bezier(0.2,0,0,1);
|
|
27
|
+
}
|
|
28
|
+
*,*::before,*::after{box-sizing:border-box;border:0;outline:0;border-radius:0;}
|
|
29
|
+
html,body{margin:0;padding:0;background:var(--paper);color:var(--ink);font-family:var(--ff-mono);font-size:var(--fs-body);line-height:var(--lh-base);-webkit-font-smoothing:antialiased;}
|
|
30
|
+
a{color:inherit;text-decoration:none;}
|
|
31
|
+
a:hover{text-decoration:underline;text-underline-offset:3px;}
|
|
32
|
+
.rule{border-top:1px solid var(--ink);height:0;margin:0;flex:1;}
|
|
33
|
+
.rule-double{border-top:3px double var(--ink);height:0;margin:0;}
|
|
34
|
+
.t-hero{font-family:var(--ff-display);font-size:var(--fs-hero);line-height:var(--lh-tight);letter-spacing:var(--tr-tight);font-weight:800;margin:0;text-transform:lowercase;}
|
|
35
|
+
.t-hero .slash{color:var(--fg-3);font-weight:400;margin:0 0.05em;}
|
|
36
|
+
h1,h2,h3{margin:0;font-family:var(--ff-display);}
|
|
37
|
+
.t-h2,h2{font-size:var(--fs-h2);line-height:var(--lh-snug);font-weight:700;letter-spacing:var(--tr-tight);}
|
|
38
|
+
.t-body{font-family:var(--ff-mono);font-size:var(--fs-body);line-height:var(--lh-base);}
|
|
39
|
+
.t-prose{font-family:var(--ff-body);font-size:var(--fs-lg);line-height:var(--lh-long);max-width:var(--measure);}
|
|
40
|
+
.t-label{font-family:var(--ff-mono);font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:var(--tr-label);font-weight:500;color:var(--fg-2);}
|
|
41
|
+
.t-micro{font-family:var(--ff-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--fg-3);}
|
|
42
|
+
.t-meta{font-family:var(--ff-mono);font-size:var(--fs-xs);color:var(--fg-3);}
|
|
22
43
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
? props.children
|
|
27
|
-
: [props.children]
|
|
28
|
-
: [];
|
|
29
|
-
};
|
|
44
|
+
.stamp{display:inline-block;padding:var(--space-1) var(--space-3);font-family:var(--ff-mono);font-size:var(--fs-xs);letter-spacing:var(--tr-label);text-transform:uppercase;font-weight:600;transform:rotate(-2deg);}
|
|
45
|
+
.stamp.ink{background:var(--ink);color:var(--paper);}
|
|
46
|
+
.stamp.acid{background:var(--acid);color:var(--ink);}
|
|
30
47
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
function updateEventListener(el, eventName, newHandler, oldHandler) {
|
|
35
|
-
if (oldHandler && oldHandler !== newHandler) {
|
|
36
|
-
el.removeEventListener(eventName, oldHandler);
|
|
37
|
-
}
|
|
38
|
-
if (newHandler && oldHandler !== newHandler) {
|
|
39
|
-
el.addEventListener(eventName, newHandler);
|
|
40
|
-
el.__webjsx_listeners = {
|
|
41
|
-
...(el.__webjsx_listeners || {}),
|
|
42
|
-
[eventName]: newHandler,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Updates a single property or attribute on an element
|
|
48
|
-
*/
|
|
49
|
-
function updatePropOrAttr(el, key, value) {
|
|
50
|
-
if (el instanceof HTMLElement) {
|
|
51
|
-
if (key in el) {
|
|
52
|
-
// Fast path: property exists on HTMLElement
|
|
53
|
-
el[key] = value;
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
if (typeof value === "string") {
|
|
57
|
-
el.setAttribute(key, value);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
// Fallback for non-string values on HTMLElement
|
|
61
|
-
el[key] = value;
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
// SVG/Other namespace elements
|
|
65
|
-
const isSVG = el.namespaceURI === "http://www.w3.org/2000/svg";
|
|
66
|
-
if (isSVG) {
|
|
67
|
-
if (value != null) {
|
|
68
|
-
el.setAttribute(key, value.toString());
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
el.removeAttribute(key);
|
|
72
|
-
}
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
// Fallback for other element types
|
|
76
|
-
if (typeof value === "string") {
|
|
77
|
-
el.setAttribute(key, value);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
el[key] = value;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Handles suspension of rendering during updates
|
|
85
|
-
*/
|
|
86
|
-
function withRenderSuspension(el, callback) {
|
|
87
|
-
const isRenderingSuspended = !!el
|
|
88
|
-
.__webjsx_suspendRendering;
|
|
89
|
-
if (isRenderingSuspended) {
|
|
90
|
-
el.__webjsx_suspendRendering();
|
|
91
|
-
}
|
|
92
|
-
try {
|
|
93
|
-
return callback();
|
|
94
|
-
}
|
|
95
|
-
finally {
|
|
96
|
-
if (isRenderingSuspended) {
|
|
97
|
-
el.__webjsx_resumeRendering();
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Core function to update attributes and properties on a DOM element
|
|
103
|
-
*/
|
|
104
|
-
function updateAttributesCore(el, newProps, oldProps = {}) {
|
|
105
|
-
// Handle new/updated props
|
|
106
|
-
for (const [key, value] of Object.entries(newProps)) {
|
|
107
|
-
if (key === "children" ||
|
|
108
|
-
key === "key" ||
|
|
109
|
-
key === "dangerouslySetInnerHTML")
|
|
110
|
-
continue;
|
|
111
|
-
if (key.startsWith("on") && typeof value === "function") {
|
|
112
|
-
const eventName = key.substring(2).toLowerCase();
|
|
113
|
-
updateEventListener(el, eventName, value, el.__webjsx_listeners?.[eventName]);
|
|
114
|
-
}
|
|
115
|
-
else if (value !== oldProps[key]) {
|
|
116
|
-
updatePropOrAttr(el, key, value);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
// Handle dangerouslySetInnerHTML
|
|
120
|
-
if ("dangerouslySetInnerHTML" in newProps) {
|
|
121
|
-
const html = newProps.dangerouslySetInnerHTML.__html || "";
|
|
122
|
-
el.innerHTML = html;
|
|
123
|
-
}
|
|
124
|
-
else if ("dangerouslySetInnerHTML" in oldProps) {
|
|
125
|
-
el.innerHTML = "";
|
|
126
|
-
}
|
|
127
|
-
// If this is a fresh set (no oldProps), remove any attributes not in newProps
|
|
128
|
-
if (Object.keys(oldProps).length === 0) {
|
|
129
|
-
const currentAttrs = Array.from(el.attributes).map((attr) => attr.name);
|
|
130
|
-
for (const attr of currentAttrs) {
|
|
131
|
-
if (!(attr in newProps) && !attr.startsWith("on")) {
|
|
132
|
-
el.removeAttribute(attr);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
// Remove old props/attributes
|
|
137
|
-
for (const key of Object.keys(oldProps)) {
|
|
138
|
-
if (!(key in newProps) &&
|
|
139
|
-
key !== "children" &&
|
|
140
|
-
key !== "key" &&
|
|
141
|
-
key !== "dangerouslySetInnerHTML") {
|
|
142
|
-
if (key.startsWith("on")) {
|
|
143
|
-
const eventName = key.substring(2).toLowerCase();
|
|
144
|
-
const existingListener = el.__webjsx_listeners?.[eventName];
|
|
145
|
-
if (existingListener) {
|
|
146
|
-
el.removeEventListener(eventName, existingListener);
|
|
147
|
-
delete el.__webjsx_listeners[eventName];
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
else if (key in el) {
|
|
151
|
-
el[key] = undefined;
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
el.removeAttribute(key);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
// Store current props for future updates
|
|
159
|
-
el.__webjsx_props = newProps;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Sets attributes and properties on a DOM element based on the provided props.
|
|
163
|
-
* If the property exists on the element, it sets it as a property.
|
|
164
|
-
* Otherwise, it sets it as an attribute or property based on the value type.
|
|
165
|
-
*
|
|
166
|
-
* @param el - The DOM element to update.
|
|
167
|
-
* @param props - The new properties to apply.
|
|
168
|
-
*/
|
|
169
|
-
function setAttributes(el, props) {
|
|
170
|
-
withRenderSuspension(el, () => {
|
|
171
|
-
updateAttributesCore(el, props);
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Updates attributes and properties on a DOM element based on the new and old props.
|
|
176
|
-
*
|
|
177
|
-
* @param el - The DOM element to update.
|
|
178
|
-
* @param newProps - The new properties to apply.
|
|
179
|
-
* @param oldProps - The old properties to compare against.
|
|
180
|
-
*/
|
|
181
|
-
function updateAttributes(el, newProps, oldProps) {
|
|
182
|
-
withRenderSuspension(el, () => {
|
|
183
|
-
updateAttributesCore(el, newProps, oldProps);
|
|
184
|
-
});
|
|
185
|
-
}
|
|
48
|
+
.btn-stamp{display:inline-flex;align-items:center;gap:var(--space-2);padding:var(--space-3) var(--space-4);background:var(--ink);color:var(--paper);box-shadow:4px 4px 0 var(--ink);font-family:var(--ff-mono);font-weight:600;font-size:var(--fs-body);text-transform:uppercase;letter-spacing:var(--tr-label);cursor:pointer;transition:transform var(--dur-snap) var(--ease),box-shadow var(--dur-snap) var(--ease);}
|
|
49
|
+
.btn-stamp:hover{transform:translate(1px,1px);box-shadow:3px 3px 0 var(--ink);text-decoration:none;}
|
|
50
|
+
.btn-stamp:active{transform:translate(4px,4px);box-shadow:0 0 0 var(--ink);}
|
|
186
51
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (typeof vnode === "string" ||
|
|
192
|
-
typeof vnode === "number" ||
|
|
193
|
-
typeof vnode === "boolean") {
|
|
194
|
-
return document.createTextNode(String(vnode));
|
|
195
|
-
}
|
|
196
|
-
else if (isFragment(vnode.type)) {
|
|
197
|
-
const fragment = document.createDocumentFragment();
|
|
198
|
-
if (vnode.props.children) {
|
|
199
|
-
const children = vnode.props.children;
|
|
200
|
-
children.forEach((child) => {
|
|
201
|
-
fragment.appendChild(createNode(child, undefined));
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
return fragment;
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
const namespaceURI = vnode.props.xmlns !== undefined
|
|
208
|
-
? vnode.props.xmlns
|
|
209
|
-
: vnode.type === "svg"
|
|
210
|
-
? SVG_NAMESPACE
|
|
211
|
-
: parentNamespaceURI ?? undefined;
|
|
212
|
-
const el = vnode.props.is !== undefined
|
|
213
|
-
? namespaceURI !== undefined
|
|
214
|
-
? document.createElementNS(namespaceURI, vnode.type, {
|
|
215
|
-
is: vnode.props.is,
|
|
216
|
-
})
|
|
217
|
-
: document.createElement(vnode.type, {
|
|
218
|
-
is: vnode.props.is,
|
|
219
|
-
})
|
|
220
|
-
: namespaceURI !== undefined
|
|
221
|
-
? document.createElementNS(namespaceURI, vnode.type)
|
|
222
|
-
: document.createElement(vnode.type);
|
|
223
|
-
if (vnode.props) {
|
|
224
|
-
setAttributes(el, vnode.props);
|
|
225
|
-
}
|
|
226
|
-
if (vnode.props.key != null) {
|
|
227
|
-
el.__webjsx_key = vnode.props.key;
|
|
228
|
-
el.setAttribute("data-key", String(vnode.props.key));
|
|
229
|
-
}
|
|
230
|
-
if (vnode.props.ref) {
|
|
231
|
-
assignRef(el, vnode.props.ref);
|
|
232
|
-
}
|
|
233
|
-
if (vnode.props.children && !vnode.props.dangerouslySetInnerHTML) {
|
|
234
|
-
const children = vnode.props.children;
|
|
235
|
-
children.forEach((child) => {
|
|
236
|
-
el.appendChild(createNode(child, namespaceURI));
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
return el;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Assigns a ref to a node.
|
|
244
|
-
* @param node The DOM node.
|
|
245
|
-
* @param ref The ref to assign.
|
|
246
|
-
*/
|
|
247
|
-
function assignRef(node, ref) {
|
|
248
|
-
const currentRef = node.__webjsx_assignedRef;
|
|
249
|
-
// Only assign the ref if it's different
|
|
250
|
-
if (currentRef !== ref) {
|
|
251
|
-
if (typeof ref === "function") {
|
|
252
|
-
ref(node);
|
|
253
|
-
}
|
|
254
|
-
else if (ref && typeof ref === "object") {
|
|
255
|
-
ref.current = node;
|
|
256
|
-
}
|
|
257
|
-
// Store the assigned ref
|
|
258
|
-
node.__webjsx_assignedRef = ref;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
52
|
+
.app-top{position:sticky;top:0;z-index:10;background:var(--paper);display:flex;align-items:center;gap:var(--space-4);padding:var(--space-3) var(--space-5);border-bottom:1px solid var(--ink);}
|
|
53
|
+
.app-top .brand{font-family:var(--ff-mono);font-weight:700;text-transform:uppercase;letter-spacing:var(--tr-label);}
|
|
54
|
+
.app-top .brand .slash{color:var(--fg-3);margin:0 var(--space-1);}
|
|
55
|
+
.app-top nav{margin-left:auto;display:flex;gap:var(--space-4);font-family:var(--ff-mono);font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:var(--tr-label);}
|
|
261
56
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
else if (typeof child === "string" || typeof child === "number") {
|
|
270
|
-
flatChildren.push(child);
|
|
271
|
-
}
|
|
272
|
-
else if (child === null ||
|
|
273
|
-
child === undefined ||
|
|
274
|
-
typeof child === "boolean") {
|
|
275
|
-
// Ignore null or undefined children
|
|
276
|
-
}
|
|
277
|
-
else {
|
|
278
|
-
flatChildren.push(child);
|
|
279
|
-
}
|
|
280
|
-
};
|
|
281
|
-
children.forEach(flatten);
|
|
282
|
-
if (flatChildren.length > 0) {
|
|
283
|
-
// Only set children if dangerouslySetInnerHTML is not present
|
|
284
|
-
if (!normalizedProps.dangerouslySetInnerHTML) {
|
|
285
|
-
normalizedProps.children = flatChildren;
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
console.warn("WebJSX: Ignoring children since dangerouslySetInnerHTML is set.");
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
return {
|
|
292
|
-
type,
|
|
293
|
-
props: normalizedProps,
|
|
294
|
-
};
|
|
295
|
-
}
|
|
57
|
+
.dateline{display:flex;gap:var(--space-5);flex-wrap:wrap;padding:var(--space-2) var(--space-5);border-bottom:1px solid var(--ink);background:var(--paper);}
|
|
58
|
+
.page{max-width:1100px;margin:0 auto;padding:0 var(--space-5);}
|
|
59
|
+
.hero{padding:var(--space-8) 0 var(--space-7) 0;}
|
|
60
|
+
.hero .stamp{margin-bottom:var(--space-4);}
|
|
61
|
+
.hero .lede{margin-top:var(--space-4);color:var(--fg-2);}
|
|
62
|
+
.hero-cta{margin-top:var(--space-6);}
|
|
296
63
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Flattens the list of virtual nodes by replacing Fragments with their children.
|
|
310
|
-
* @param vnodes The array of virtual nodes to flatten.
|
|
311
|
-
* @returns A new array of virtual nodes with Fragments flattened.
|
|
312
|
-
*/
|
|
313
|
-
function flattenVNodes(vnodes) {
|
|
314
|
-
const flat = [];
|
|
315
|
-
const arrayVNodes = vnodes;
|
|
316
|
-
arrayVNodes.forEach((vnode) => {
|
|
317
|
-
if (isFragment(vnode)) {
|
|
318
|
-
const children = vnode.props.children ? vnode.props.children : [];
|
|
319
|
-
flat.push(...children);
|
|
320
|
-
}
|
|
321
|
-
else {
|
|
322
|
-
flat.push(vnode);
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
return flat;
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Type guard to check if a VNode is a Fragment.
|
|
329
|
-
* @param vnode The virtual node to check.
|
|
330
|
-
* @returns True if vnode is a Fragment, false otherwise.
|
|
331
|
-
*/
|
|
332
|
-
function isFragment(vnode) {
|
|
333
|
-
return typeof vnode === "object" && vnode !== null && vnode.type === Fragment;
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Diffs and updates the children of a DOM node based on the new virtual nodes.
|
|
337
|
-
* @param parent The parent DOM node whose children will be diffed.
|
|
338
|
-
* @param newVNodes An array of new virtual nodes.
|
|
339
|
-
*/
|
|
340
|
-
function diffChildren(parent, newVNodes) {
|
|
341
|
-
const flattenedVNodes = flattenVNodes(newVNodes);
|
|
342
|
-
const existingNodes = Array.from(parent.childNodes);
|
|
343
|
-
const keyedMap = new Map();
|
|
344
|
-
// Populate keyedMap with existing keyed nodes
|
|
345
|
-
existingNodes.forEach((node) => {
|
|
346
|
-
const key = node.__webjsx_key;
|
|
347
|
-
if (key != null) {
|
|
348
|
-
keyedMap.set(key, node);
|
|
349
|
-
}
|
|
350
|
-
});
|
|
351
|
-
const newKeys = flattenedVNodes
|
|
352
|
-
.filter(isVElementWithKey)
|
|
353
|
-
.map((vnode) => vnode.props.key);
|
|
354
|
-
existingNodes.forEach((node) => {
|
|
355
|
-
const key = node.__webjsx_key;
|
|
356
|
-
if (key != null && !newKeys.includes(key)) {
|
|
357
|
-
parent.removeChild(node);
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
flattenedVNodes.forEach((newVNode, i) => {
|
|
361
|
-
const newKey = isVElement(newVNode) ? newVNode.props.key : undefined;
|
|
362
|
-
let existingNode = null;
|
|
363
|
-
if (newKey != null) {
|
|
364
|
-
existingNode = keyedMap.get(newKey) || null;
|
|
365
|
-
}
|
|
366
|
-
if (!existingNode && newKey == null) {
|
|
367
|
-
existingNode = parent.childNodes[i] || null;
|
|
368
|
-
}
|
|
369
|
-
if (existingNode) {
|
|
370
|
-
if (existingNode !== parent.childNodes[i]) {
|
|
371
|
-
parent.insertBefore(existingNode, parent.childNodes[i] || null);
|
|
372
|
-
}
|
|
373
|
-
updateNode(existingNode, newVNode);
|
|
374
|
-
}
|
|
375
|
-
else {
|
|
376
|
-
const newDomNode = createNode(newVNode, getNamespaceURI(parent));
|
|
377
|
-
if (isVElement(newVNode) && newVNode.props.key != null) {
|
|
378
|
-
newDomNode.__webjsx_key = newVNode.props.key;
|
|
379
|
-
newDomNode.setAttribute("data-key", String(newVNode.props.key));
|
|
380
|
-
}
|
|
381
|
-
parent.insertBefore(newDomNode, parent.childNodes[i] || null);
|
|
382
|
-
}
|
|
383
|
-
});
|
|
384
|
-
const updatedChildNodes = Array.from(parent.childNodes);
|
|
385
|
-
const newUnkeyed = flattenedVNodes.filter((vnode) => !isVElementWithKey(vnode));
|
|
386
|
-
const existingUnkeyed = updatedChildNodes.filter((node) => !node.__webjsx_key);
|
|
387
|
-
if (newUnkeyed.length < existingUnkeyed.length) {
|
|
388
|
-
for (let i = newUnkeyed.length; i < existingUnkeyed.length; i++) {
|
|
389
|
-
parent.removeChild(existingUnkeyed[i]);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Updates a DOM node to match the new virtual node.
|
|
395
|
-
* @param domNode The existing DOM node to be updated.
|
|
396
|
-
* @param newVNode The new virtual node to apply.
|
|
397
|
-
*/
|
|
398
|
-
function updateNode(domNode, newVNode) {
|
|
399
|
-
if (typeof newVNode === "string" ||
|
|
400
|
-
typeof newVNode === "number" ||
|
|
401
|
-
typeof newVNode === "boolean") {
|
|
402
|
-
if (domNode.nodeType !== Node.TEXT_NODE ||
|
|
403
|
-
domNode.textContent !== String(newVNode)) {
|
|
404
|
-
const newTextNode = document.createTextNode(String(newVNode));
|
|
405
|
-
domNode.parentNode?.replaceChild(newTextNode, domNode);
|
|
406
|
-
}
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
if (newVNode.type === Fragment) {
|
|
410
|
-
if (domNode instanceof DocumentFragment) {
|
|
411
|
-
diffChildren(domNode, newVNode.props.children ? newVNode.props.children : []);
|
|
412
|
-
}
|
|
413
|
-
else {
|
|
414
|
-
const fragment = document.createDocumentFragment();
|
|
415
|
-
const children = newVNode.props.children ? newVNode.props.children : [];
|
|
416
|
-
children.forEach((child) => {
|
|
417
|
-
fragment.appendChild(createNode(child, undefined));
|
|
418
|
-
});
|
|
419
|
-
domNode.parentNode?.replaceChild(fragment, domNode);
|
|
420
|
-
}
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
if (domNode instanceof HTMLElement &&
|
|
424
|
-
domNode.tagName.toLowerCase() === newVNode.type.toLowerCase()) {
|
|
425
|
-
const oldProps = domNode.__webjsx_props || {};
|
|
426
|
-
const newProps = newVNode.props || {};
|
|
427
|
-
updateAttributes(domNode, newProps, oldProps);
|
|
428
|
-
if (isVElement(newVNode) && newVNode.props.key != null) {
|
|
429
|
-
domNode.__webjsx_key = newVNode.props.key;
|
|
430
|
-
domNode.setAttribute("data-key", String(newVNode.props.key));
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
433
|
-
delete domNode.__webjsx_key;
|
|
434
|
-
domNode.removeAttribute("data-key");
|
|
435
|
-
}
|
|
436
|
-
if (newProps.ref) {
|
|
437
|
-
assignRef(domNode, newProps.ref);
|
|
438
|
-
}
|
|
439
|
-
if (!newProps.dangerouslySetInnerHTML && newProps.children != null) {
|
|
440
|
-
diffChildren(domNode, newProps.children);
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
else {
|
|
444
|
-
const newDomNode = createNode(newVNode, domNode.parentNode ? getNamespaceURI(domNode.parentNode) : undefined);
|
|
445
|
-
if (isVElement(newVNode) && newVNode.props.key != null) {
|
|
446
|
-
newDomNode.__webjsx_key = newVNode.props.key;
|
|
447
|
-
newDomNode.setAttribute("data-key", String(newVNode.props.key));
|
|
448
|
-
}
|
|
449
|
-
if (isVElement(newVNode) && newVNode.props.ref) {
|
|
450
|
-
assignRef(newDomNode, newVNode.props.ref);
|
|
451
|
-
}
|
|
452
|
-
domNode.parentNode?.replaceChild(newDomNode, domNode);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
/**
|
|
456
|
-
* Assigns a ref to a node.
|
|
457
|
-
* @param node The DOM node.
|
|
458
|
-
* @param ref The ref to assign.
|
|
459
|
-
*/
|
|
460
|
-
function assignRef(node, ref) {
|
|
461
|
-
const currentRef = node.__webjsx_assignedRef;
|
|
462
|
-
// Only assign the ref if it's different
|
|
463
|
-
if (currentRef !== ref) {
|
|
464
|
-
if (typeof ref === "function") {
|
|
465
|
-
ref(node);
|
|
466
|
-
}
|
|
467
|
-
else if (ref && typeof ref === "object") {
|
|
468
|
-
ref.current = node;
|
|
469
|
-
}
|
|
470
|
-
// Store the assigned ref
|
|
471
|
-
node.__webjsx_assignedRef = ref;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Type guard to check if a VNode is a VElement.
|
|
476
|
-
* @param vnode The virtual node to check.
|
|
477
|
-
* @returns True if vnode is a VElement, false otherwise.
|
|
478
|
-
*/
|
|
479
|
-
function isVElement(vnode) {
|
|
480
|
-
return typeof vnode === "object" && vnode !== null && "props" in vnode;
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Type guard to check if a VNode is a VElement with a key.
|
|
484
|
-
* @param vnode The virtual node to check.
|
|
485
|
-
* @returns True if vnode is a VElement with a key, false otherwise.
|
|
486
|
-
*/
|
|
487
|
-
function isVElementWithKey(vnode) {
|
|
488
|
-
return isVElement(vnode) && vnode.props.key != null;
|
|
489
|
-
}
|
|
490
|
-
function getNamespaceURI(node) {
|
|
491
|
-
return node instanceof Element && node.namespaceURI !== HTML_NAMESPACE
|
|
492
|
-
? node.namespaceURI ?? undefined
|
|
493
|
-
: undefined;
|
|
494
|
-
}
|
|
64
|
+
.section{padding:var(--space-7) 0;border-top:1px solid var(--ink);}
|
|
65
|
+
.section-head{display:flex;align-items:center;gap:var(--space-4);margin-bottom:var(--space-5);}
|
|
66
|
+
.section-lede{margin-bottom:var(--space-5);color:var(--fg-2);}
|
|
67
|
+
|
|
68
|
+
.receipt{border:1px solid var(--ink);background:color-mix(in srgb,var(--paper) 94%,var(--ink));}
|
|
69
|
+
.receipt-row{display:grid;grid-template-columns:48px 1fr;gap:var(--space-4);padding:var(--space-4);border-bottom:1px dashed var(--ink);}
|
|
70
|
+
.receipt-row:last-child{border-bottom:0;}
|
|
71
|
+
.receipt-row .num{align-self:start;padding-top:2px;}
|
|
72
|
+
.receipt-cmd{font-family:var(--ff-mono);font-size:var(--fs-body);background:var(--ink);color:var(--acid);padding:var(--space-3);margin:var(--space-2) 0 0 0;overflow-x:auto;}
|
|
73
|
+
.receipt-cmd code{background:transparent;color:inherit;}
|
|
495
74
|
|
|
496
|
-
|
|
75
|
+
.feat-list,.phase-list,.idx-list{list-style:none;margin:0;padding:0;}
|
|
76
|
+
.feat-row,.phase-row{display:grid;grid-template-columns:180px 1fr;gap:var(--space-4);padding:var(--space-3) 0;border-top:1px solid var(--ink);}
|
|
77
|
+
.feat-row:last-child,.phase-row:last-child{border-bottom:1px solid var(--ink);}
|
|
78
|
+
.feat-tag,.phase-name{padding-top:2px;}
|
|
497
79
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
</
|
|
530
|
-
|
|
531
|
-
|
|
80
|
+
.platform-cols{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-6);}
|
|
81
|
+
@media (max-width:720px){.platform-cols{grid-template-columns:1fr;}.feat-row,.phase-row,.receipt-row{grid-template-columns:1fr;gap:var(--space-1);}.receipt-row{grid-template-columns:48px 1fr;}}
|
|
82
|
+
.col-head{margin-bottom:var(--space-3);color:var(--fg-2);}
|
|
83
|
+
.idx-row{display:grid;grid-template-columns:24px 1fr auto;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-3);border-top:1px solid var(--ink);color:var(--ink);text-decoration:none;transition:background var(--dur-snap) var(--ease);}
|
|
84
|
+
.idx-row:last-child{border-bottom:1px solid var(--ink);}
|
|
85
|
+
.idx-row:hover{background:var(--ink);color:var(--paper);text-decoration:none;}
|
|
86
|
+
.idx-row:hover .idx-tag{color:var(--paper);}
|
|
87
|
+
.idx-active{background:var(--acid);color:var(--ink);}
|
|
88
|
+
.idx-active:hover{background:var(--acid);color:var(--ink);}
|
|
89
|
+
.idx-mark{font-family:var(--ff-mono);color:var(--fg-3);}
|
|
90
|
+
.idx-label{font-family:var(--ff-mono);text-transform:uppercase;letter-spacing:var(--tr-label);font-size:var(--fs-body);}
|
|
91
|
+
.idx-tag{font-family:var(--ff-mono);}
|
|
92
|
+
|
|
93
|
+
.app-foot{margin-top:var(--space-8);padding:var(--space-5) var(--space-5) var(--space-7) var(--space-5);}
|
|
94
|
+
.foot-row{display:flex;justify-content:space-between;gap:var(--space-4);padding-top:var(--space-3);}
|
|
95
|
+
</style>
|
|
96
|
+
</head>
|
|
97
|
+
<body>
|
|
98
|
+
<header class="app-top">
|
|
99
|
+
<span class="brand">247420<span class="slash">/</span>gm<span class="slash">/</span>copilot cli</span>
|
|
100
|
+
<nav>
|
|
101
|
+
<a href="https://anentrypoint.github.io/gm">← all platforms</a>
|
|
102
|
+
<a href="https://github.com/AnEntrypoint/gm-copilot-cli">source ↗</a>
|
|
103
|
+
</nav>
|
|
104
|
+
</header>
|
|
105
|
+
<div class="dateline">
|
|
106
|
+
<span class="t-micro">247420 / anentrypoint</span>
|
|
107
|
+
<span class="t-micro">Copilot CLI</span>
|
|
108
|
+
<span class="t-micro">v2.0.539</span>
|
|
109
|
+
<span class="t-micro">2026-04-21</span>
|
|
110
|
+
<span class="t-micro">probably emerging 🌀</span>
|
|
111
|
+
</div>
|
|
112
|
+
<main class="page">
|
|
113
|
+
<section class="hero">
|
|
114
|
+
<span class="stamp ink">cli tool</span>
|
|
115
|
+
<h1 class="t-hero">gm <span class="slash">/</span> copilot cli</h1>
|
|
116
|
+
<p class="t-prose lede">State machine agent with hooks, skills, and automated git enforcement</p>
|
|
117
|
+
<div class="hero-cta">
|
|
118
|
+
<a class="btn-stamp" href="https://github.com/AnEntrypoint/gm-copilot-cli">source ↗</a>
|
|
119
|
+
</div>
|
|
120
|
+
</section>
|
|
121
|
+
<section class="section">
|
|
122
|
+
<div class="section-head"><span class="t-label">§ install</span><hr class="rule"/></div>
|
|
123
|
+
<div class="receipt"><div class="receipt-row"><span class="t-label num">01</span><div class="receipt-body"><p class="t-body">install via GitHub CLI</p><pre class="receipt-cmd"><code>gh extension install AnEntrypoint/gm-copilot-cli</code></pre></div></div>
|
|
124
|
+
<div class="receipt-row"><span class="t-label num">02</span><div class="receipt-body"><p class="t-body">restart your terminal — activates automatically</p></div></div></div>
|
|
125
|
+
</section>
|
|
126
|
+
<section class="section">
|
|
127
|
+
<div class="section-head"><span class="t-label">§ features</span><hr class="rule"/></div>
|
|
128
|
+
<ul class="feat-list"><li class="feat-row"><span class="t-label feat-tag">state machine</span><span class="t-body feat-desc">immutable PLAN→EXECUTE→EMIT→VERIFY→COMPLETE phases with full mutable tracking</span></li>
|
|
129
|
+
<li class="feat-row"><span class="t-label feat-tag">semantic search</span><span class="t-body feat-desc">natural language codebase exploration via codesearch skill — no grep needed</span></li>
|
|
130
|
+
<li class="feat-row"><span class="t-label feat-tag">hooks</span><span class="t-body feat-desc">pre-tool, session-start, prompt-submit, and stop hooks for full lifecycle control</span></li>
|
|
131
|
+
<li class="feat-row"><span class="t-label feat-tag">agents</span><span class="t-body feat-desc">gm, codesearch, and websearch agents pre-configured and ready to use</span></li>
|
|
132
|
+
<li class="feat-row"><span class="t-label feat-tag">mcp integration</span><span class="t-body feat-desc">model context protocol server support built in</span></li>
|
|
133
|
+
<li class="feat-row"><span class="t-label feat-tag">auto-recovery</span><span class="t-body feat-desc">supervisor hierarchy ensures the system never crashes</span></li></ul>
|
|
134
|
+
</section>
|
|
135
|
+
<section class="section">
|
|
136
|
+
<div class="section-head"><span class="t-label">§ state machine</span><hr class="rule"/></div>
|
|
137
|
+
<p class="t-prose section-lede">every task follows the same five-phase cycle — no skipping, no shortcuts.</p>
|
|
138
|
+
<ol class="phase-list"><li class="phase-row"><span class="t-label phase-name">01 plan</span><span class="t-body phase-desc">write .gm/prd.yml with every unknown named before any work begins</span></li>
|
|
139
|
+
<li class="phase-row"><span class="t-label phase-name">02 execute</span><span class="t-body phase-desc">prove every hypothesis via witnessed execution, import real modules</span></li>
|
|
140
|
+
<li class="phase-row"><span class="t-label phase-name">03 emit</span><span class="t-body phase-desc">write files only after all tests pass — pre- and post-emit gates</span></li>
|
|
141
|
+
<li class="phase-row"><span class="t-label phase-name">04 verify</span><span class="t-body phase-desc">end-to-end execution confirms all changes work in real context</span></li>
|
|
142
|
+
<li class="phase-row"><span class="t-label phase-name">05 complete</span><span class="t-body phase-desc">.prd empty, git clean, all output pushed</span></li></ol>
|
|
143
|
+
</section>
|
|
144
|
+
<section class="section">
|
|
145
|
+
<div class="section-head"><span class="t-label">§ also available</span><hr class="rule"/></div>
|
|
146
|
+
<div class="platform-cols">
|
|
147
|
+
<div class="platform-col">
|
|
148
|
+
<p class="t-label col-head">cli tools</p>
|
|
149
|
+
<div class="idx-list"><a class="idx-row" href="https://anentrypoint.github.io/gm-cc"><span class="idx-mark">›</span><span class="idx-label">claude code</span><span class="idx-tag t-meta">gm-cc</span></a>
|
|
150
|
+
<a class="idx-row" href="https://anentrypoint.github.io/gm-gc"><span class="idx-mark">›</span><span class="idx-label">gemini cli</span><span class="idx-tag t-meta">gm-gc</span></a>
|
|
151
|
+
<a class="idx-row" href="https://anentrypoint.github.io/gm-oc"><span class="idx-mark">›</span><span class="idx-label">opencode</span><span class="idx-tag t-meta">gm-oc</span></a>
|
|
152
|
+
<a class="idx-row" href="https://anentrypoint.github.io/gm-kilo"><span class="idx-mark">›</span><span class="idx-label">kilo code</span><span class="idx-tag t-meta">gm-kilo</span></a>
|
|
153
|
+
<a class="idx-row" href="https://anentrypoint.github.io/gm-codex"><span class="idx-mark">›</span><span class="idx-label">codex</span><span class="idx-tag t-meta">gm-codex</span></a>
|
|
154
|
+
<a class="idx-row idx-active" href="#"><span class="idx-mark">◆</span><span class="idx-label">copilot cli</span><span class="idx-tag t-meta">gm-copilot-cli</span></a>
|
|
155
|
+
<a class="idx-row" href="https://anentrypoint.github.io/gm-qwen"><span class="idx-mark">›</span><span class="idx-label">qwen code</span><span class="idx-tag t-meta">gm-qwen</span></a>
|
|
156
|
+
<a class="idx-row" href="https://anentrypoint.github.io/gm-hermes"><span class="idx-mark">›</span><span class="idx-label">hermes agent</span><span class="idx-tag t-meta">gm-hermes</span></a></div>
|
|
157
|
+
</div>
|
|
158
|
+
<div class="platform-col">
|
|
159
|
+
<p class="t-label col-head">ide extensions</p>
|
|
160
|
+
<div class="idx-list"><a class="idx-row" href="https://anentrypoint.github.io/gm-vscode"><span class="idx-mark">›</span><span class="idx-label">vs code</span><span class="idx-tag t-meta">gm-vscode</span></a>
|
|
161
|
+
<a class="idx-row" href="https://anentrypoint.github.io/gm-cursor"><span class="idx-mark">›</span><span class="idx-label">cursor</span><span class="idx-tag t-meta">gm-cursor</span></a>
|
|
162
|
+
<a class="idx-row" href="https://anentrypoint.github.io/gm-zed"><span class="idx-mark">›</span><span class="idx-label">zed</span><span class="idx-tag t-meta">gm-zed</span></a>
|
|
163
|
+
<a class="idx-row" href="https://anentrypoint.github.io/gm-jetbrains"><span class="idx-mark">›</span><span class="idx-label">jetbrains</span><span class="idx-tag t-meta">gm-jetbrains</span></a></div>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
</section>
|
|
167
|
+
</main>
|
|
168
|
+
<footer class="app-foot">
|
|
169
|
+
<hr class="rule-double"/>
|
|
170
|
+
<div class="foot-row">
|
|
171
|
+
<span class="t-micro">generated by gm — convention-driven multi-platform plugin generator</span>
|
|
172
|
+
<span class="t-micro">probably emerging 🌀</span>
|
|
173
|
+
</div>
|
|
174
|
+
</footer>
|
|
175
|
+
</body></html>
|
package/manifest.yml
CHANGED
package/package.json
CHANGED