codiedev 0.7.10 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +84 -7
- package/dist/commands/ask.js +12 -0
- package/dist/commands/createTicket.d.ts +27 -0
- package/dist/commands/createTicket.js +198 -0
- package/dist/commands/delete.js +12 -0
- package/dist/commands/doctor.js +6 -31
- package/dist/commands/inbox.js +30 -0
- package/dist/commands/library.d.ts +2 -0
- package/dist/commands/library.js +105 -0
- package/dist/commands/note.js +12 -0
- package/dist/commands/ping.js +12 -0
- package/dist/commands/post.d.ts +2 -0
- package/dist/commands/post.js +96 -0
- package/dist/commands/promote.js +12 -0
- package/dist/commands/pull.js +12 -0
- package/dist/commands/push.js +12 -0
- package/dist/commands/react.d.ts +2 -0
- package/dist/commands/react.js +40 -0
- package/dist/commands/reverseTicket.js +30 -0
- package/dist/commands/search.d.ts +2 -0
- package/dist/commands/search.js +72 -0
- package/dist/commands/send.d.ts +2 -0
- package/dist/commands/send.js +67 -0
- package/dist/commands/share.d.ts +2 -0
- package/dist/commands/share.js +87 -0
- package/dist/commands/shared.d.ts +27 -1
- package/dist/commands/shared.js +63 -2
- package/dist/connect.js +49 -38
- package/dist/createTicketSkill.d.ts +12 -0
- package/dist/createTicketSkill.js +146 -0
- package/dist/detection.d.ts +18 -0
- package/dist/detection.js +28 -0
- package/dist/mcp.js +7 -7
- package/dist/utils.d.ts +22 -0
- package/dist/utils.js +128 -32
- package/package.json +1 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// `codiedev library [--scope mine|shared|all] [--kind doc|skill] [--tag X]
|
|
3
|
+
// [--type spec|...] [--limit N]` — list artifacts in your CodieDev workspace.
|
|
4
|
+
// Server applies companyId scoping; --scope filters within that.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runLibrary = runLibrary;
|
|
7
|
+
const shared_1 = require("./shared");
|
|
8
|
+
const VALID_SCOPES = new Set(["mine", "shared", "all"]);
|
|
9
|
+
const VALID_KINDS = new Set(["doc", "skill"]);
|
|
10
|
+
const VALID_TYPES = new Set([
|
|
11
|
+
"spec",
|
|
12
|
+
"bugfix",
|
|
13
|
+
"decision",
|
|
14
|
+
"proposal",
|
|
15
|
+
"review",
|
|
16
|
+
"message",
|
|
17
|
+
"note",
|
|
18
|
+
]);
|
|
19
|
+
function readFlag(args, i, flag) {
|
|
20
|
+
const a = args[i];
|
|
21
|
+
if (a === flag && i + 1 < args.length)
|
|
22
|
+
return { value: args[i + 1], next: i + 2 };
|
|
23
|
+
if (a.startsWith(flag + "="))
|
|
24
|
+
return { value: a.slice(flag.length + 1), next: i + 1 };
|
|
25
|
+
return { value: undefined, next: i + 1 };
|
|
26
|
+
}
|
|
27
|
+
function parseArgs(args) {
|
|
28
|
+
const out = {};
|
|
29
|
+
let i = 0;
|
|
30
|
+
while (i < args.length) {
|
|
31
|
+
const a = args[i];
|
|
32
|
+
let consumed = 1;
|
|
33
|
+
for (const flag of ["--scope", "--kind", "--tag", "--type", "--limit"]) {
|
|
34
|
+
const { value, next } = readFlag(args, i, flag);
|
|
35
|
+
if (value !== undefined) {
|
|
36
|
+
const key = flag.slice(2);
|
|
37
|
+
if (key === "limit") {
|
|
38
|
+
const n = Number(value);
|
|
39
|
+
if (Number.isInteger(n) && n > 0)
|
|
40
|
+
out.limit = n;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
out[key] = value;
|
|
44
|
+
}
|
|
45
|
+
consumed = next - i;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
i += consumed;
|
|
50
|
+
}
|
|
51
|
+
if (out.scope && !VALID_SCOPES.has(out.scope)) {
|
|
52
|
+
console.error(`Invalid --scope. Valid: ${[...VALID_SCOPES].join(", ")}`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
if (out.kind && !VALID_KINDS.has(out.kind)) {
|
|
56
|
+
console.error(`Invalid --kind. Valid: ${[...VALID_KINDS].join(", ")}`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
if (out.type && !VALID_TYPES.has(out.type)) {
|
|
60
|
+
console.error(`Invalid --type. Valid: ${[...VALID_TYPES].join(", ")}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
async function runLibrary(args, configOverride) {
|
|
66
|
+
const parsed = parseArgs(args);
|
|
67
|
+
const config = configOverride ?? (0, shared_1.requireConfig)();
|
|
68
|
+
const start = Date.now();
|
|
69
|
+
try {
|
|
70
|
+
const res = await (0, shared_1.apiRequest)("GET", "/api/cli/library", {
|
|
71
|
+
config,
|
|
72
|
+
query: {
|
|
73
|
+
scope: parsed.scope,
|
|
74
|
+
kind: parsed.kind,
|
|
75
|
+
tag: parsed.tag,
|
|
76
|
+
type: parsed.type,
|
|
77
|
+
limit: parsed.limit,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
81
|
+
tool: "codiedev_get_library",
|
|
82
|
+
ok: true,
|
|
83
|
+
latencyMs: Date.now() - start,
|
|
84
|
+
});
|
|
85
|
+
if (!res.artifacts || res.artifacts.length === 0) {
|
|
86
|
+
console.log("No artifacts found.");
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
for (const a of res.artifacts) {
|
|
90
|
+
const tagStr = a.tags.length > 0 ? ` [${a.tags.join(", ")}]` : "";
|
|
91
|
+
console.log(` ${a.kind === "skill" ? "/" : "•"} ${a.title} (${a.type})${tagStr}`);
|
|
92
|
+
console.log(` ${a.key} · v${a.version} · ${(0, shared_1.timeAgo)(a.updatedAt)}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
97
|
+
tool: "codiedev_get_library",
|
|
98
|
+
ok: false,
|
|
99
|
+
latencyMs: Date.now() - start,
|
|
100
|
+
error: err.message,
|
|
101
|
+
});
|
|
102
|
+
console.error(`Library listing failed: ${err.message}`);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
package/dist/commands/note.js
CHANGED
|
@@ -14,14 +14,26 @@ async function runNote(args) {
|
|
|
14
14
|
process.exit(1);
|
|
15
15
|
}
|
|
16
16
|
const config = (0, shared_1.requireConfig)();
|
|
17
|
+
const start = Date.now();
|
|
17
18
|
try {
|
|
18
19
|
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/note", {
|
|
19
20
|
config,
|
|
20
21
|
body: { body },
|
|
21
22
|
});
|
|
23
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
24
|
+
tool: "codiedev_note",
|
|
25
|
+
ok: true,
|
|
26
|
+
latencyMs: Date.now() - start,
|
|
27
|
+
});
|
|
22
28
|
console.log(`✓ Noted (${res.key})`);
|
|
23
29
|
}
|
|
24
30
|
catch (err) {
|
|
31
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
32
|
+
tool: "codiedev_note",
|
|
33
|
+
ok: false,
|
|
34
|
+
latencyMs: Date.now() - start,
|
|
35
|
+
error: err.message,
|
|
36
|
+
});
|
|
25
37
|
console.error(`Note failed: ${err.message}`);
|
|
26
38
|
process.exit(1);
|
|
27
39
|
}
|
package/dist/commands/ping.js
CHANGED
|
@@ -31,15 +31,27 @@ function parseArgs(args) {
|
|
|
31
31
|
async function runPing(args) {
|
|
32
32
|
const { to, body, subjectKey } = parseArgs(args);
|
|
33
33
|
const config = (0, shared_1.requireConfig)();
|
|
34
|
+
const start = Date.now();
|
|
34
35
|
try {
|
|
35
36
|
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/ping", {
|
|
36
37
|
config,
|
|
37
38
|
body: { to, body, subjectKey },
|
|
38
39
|
});
|
|
40
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
41
|
+
tool: "codiedev_ping",
|
|
42
|
+
ok: true,
|
|
43
|
+
latencyMs: Date.now() - start,
|
|
44
|
+
});
|
|
39
45
|
console.log(`✓ Pinged ${res.recipient.name} <${res.recipient.email}>${subjectKey ? ` on ${subjectKey}` : ""}`);
|
|
40
46
|
}
|
|
41
47
|
catch (err) {
|
|
42
48
|
const e = err;
|
|
49
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
50
|
+
tool: "codiedev_ping",
|
|
51
|
+
ok: false,
|
|
52
|
+
latencyMs: Date.now() - start,
|
|
53
|
+
error: e.message,
|
|
54
|
+
});
|
|
43
55
|
if (e.status === 409 && e.body?.candidates?.length) {
|
|
44
56
|
console.error(`${e.message}: multiple matches for "${to}":`);
|
|
45
57
|
for (const c of e.body.candidates) {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// `codiedev post --title ... --body ... [--intent share|...] [--filename ...]
|
|
3
|
+
// [--mention NAME ...] [--tag X ...]` — publish to the team feed. Intended
|
|
4
|
+
// for broad-team reach: announcing a skill, asking who knows about X,
|
|
5
|
+
// proposing a change. Use `codiedev send` to address a single teammate.
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.runPost = runPost;
|
|
8
|
+
const shared_1 = require("./shared");
|
|
9
|
+
const VALID_INTENTS = new Set([
|
|
10
|
+
"share",
|
|
11
|
+
"request_review",
|
|
12
|
+
"request_expertise",
|
|
13
|
+
"link_share",
|
|
14
|
+
"rfc",
|
|
15
|
+
]);
|
|
16
|
+
const VALID_FORMATS = new Set(["article", "quick", "workflow", "review"]);
|
|
17
|
+
function parseArgs(args) {
|
|
18
|
+
let title;
|
|
19
|
+
let body;
|
|
20
|
+
let intent;
|
|
21
|
+
let filename;
|
|
22
|
+
let format;
|
|
23
|
+
const mentions = [];
|
|
24
|
+
const tags = [];
|
|
25
|
+
for (let i = 0; i < args.length; i++) {
|
|
26
|
+
const a = args[i];
|
|
27
|
+
const next = (k) => a === k && i + 1 < args.length ? args[++i] : a.startsWith(k + "=") ? a.slice(k.length + 1) : undefined;
|
|
28
|
+
let v;
|
|
29
|
+
if ((v = next("--title")) !== undefined)
|
|
30
|
+
title = v;
|
|
31
|
+
else if ((v = next("--body")) !== undefined)
|
|
32
|
+
body = v;
|
|
33
|
+
else if ((v = next("--intent")) !== undefined)
|
|
34
|
+
intent = v;
|
|
35
|
+
else if ((v = next("--filename")) !== undefined)
|
|
36
|
+
filename = v;
|
|
37
|
+
else if ((v = next("--format")) !== undefined)
|
|
38
|
+
format = v;
|
|
39
|
+
else if ((v = next("--mention")) !== undefined)
|
|
40
|
+
mentions.push(v);
|
|
41
|
+
else if ((v = next("--tag")) !== undefined)
|
|
42
|
+
tags.push(v);
|
|
43
|
+
}
|
|
44
|
+
if (!title || !title.trim()) {
|
|
45
|
+
console.error('Usage: codiedev post --title "<title>" --body "<body>" [--intent share|request_review|request_expertise|link_share|rfc] [--filename <key>] [--mention <name>]...');
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
if (!body || !body.trim()) {
|
|
49
|
+
console.error("--body required");
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
if (intent && !VALID_INTENTS.has(intent)) {
|
|
53
|
+
console.error(`Invalid --intent. Valid: ${[...VALID_INTENTS].join(", ")}`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
if (format && !VALID_FORMATS.has(format)) {
|
|
57
|
+
console.error(`Invalid --format. Valid: ${[...VALID_FORMATS].join(", ")}`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
return { title, body, intent, filename, format, mentions, tags };
|
|
61
|
+
}
|
|
62
|
+
async function runPost(args, configOverride) {
|
|
63
|
+
const parsed = parseArgs(args);
|
|
64
|
+
const config = configOverride ?? (0, shared_1.requireConfig)();
|
|
65
|
+
const start = Date.now();
|
|
66
|
+
try {
|
|
67
|
+
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/post-to-feed", {
|
|
68
|
+
config,
|
|
69
|
+
body: {
|
|
70
|
+
title: parsed.title,
|
|
71
|
+
body: parsed.body,
|
|
72
|
+
intent: parsed.intent,
|
|
73
|
+
filename: parsed.filename,
|
|
74
|
+
format: parsed.format,
|
|
75
|
+
mentions: parsed.mentions.length > 0 ? parsed.mentions : undefined,
|
|
76
|
+
tags: parsed.tags.length > 0 ? parsed.tags : undefined,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
80
|
+
tool: "codiedev_post_to_feed",
|
|
81
|
+
ok: true,
|
|
82
|
+
latencyMs: Date.now() - start,
|
|
83
|
+
});
|
|
84
|
+
console.log(`Posted to the team feed${res.postId ? ` (id: ${res.postId})` : ""}.`);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
88
|
+
tool: "codiedev_post_to_feed",
|
|
89
|
+
ok: false,
|
|
90
|
+
latencyMs: Date.now() - start,
|
|
91
|
+
error: err.message,
|
|
92
|
+
});
|
|
93
|
+
console.error(`Post failed: ${err.message}`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
package/dist/commands/promote.js
CHANGED
|
@@ -26,15 +26,27 @@ function parseArgs(args) {
|
|
|
26
26
|
async function runPromote(args) {
|
|
27
27
|
const { artifactId, keyOverride } = parseArgs(args);
|
|
28
28
|
const config = (0, shared_1.requireConfig)();
|
|
29
|
+
const start = Date.now();
|
|
29
30
|
try {
|
|
30
31
|
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/promote", {
|
|
31
32
|
config,
|
|
32
33
|
body: { artifactId, keyOverride },
|
|
33
34
|
});
|
|
35
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
36
|
+
tool: "codiedev_promote",
|
|
37
|
+
ok: true,
|
|
38
|
+
latencyMs: Date.now() - start,
|
|
39
|
+
});
|
|
34
40
|
console.log(`✓ Promoted to authored artifact ${res.key}`);
|
|
35
41
|
console.log(` id: ${res.artifactId}`);
|
|
36
42
|
}
|
|
37
43
|
catch (err) {
|
|
44
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
45
|
+
tool: "codiedev_promote",
|
|
46
|
+
ok: false,
|
|
47
|
+
latencyMs: Date.now() - start,
|
|
48
|
+
error: err.message,
|
|
49
|
+
});
|
|
38
50
|
console.error(`Promote failed: ${err.message}`);
|
|
39
51
|
process.exit(1);
|
|
40
52
|
}
|
package/dist/commands/pull.js
CHANGED
|
@@ -72,11 +72,17 @@ function parseArgs(args) {
|
|
|
72
72
|
async function runPull(args) {
|
|
73
73
|
const { key, version, out } = parseArgs(args);
|
|
74
74
|
const config = (0, shared_1.requireConfig)();
|
|
75
|
+
const start = Date.now();
|
|
75
76
|
try {
|
|
76
77
|
const res = await (0, shared_1.apiRequest)("GET", "/api/cli/pull", {
|
|
77
78
|
config,
|
|
78
79
|
query: { key, version },
|
|
79
80
|
});
|
|
81
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
82
|
+
tool: "codiedev_pull",
|
|
83
|
+
ok: true,
|
|
84
|
+
latencyMs: Date.now() - start,
|
|
85
|
+
});
|
|
80
86
|
const a = res.artifact;
|
|
81
87
|
if (out) {
|
|
82
88
|
const absolute = path.isAbsolute(out) ? out : path.resolve(process.cwd(), out);
|
|
@@ -95,6 +101,12 @@ async function runPull(args) {
|
|
|
95
101
|
}
|
|
96
102
|
catch (err) {
|
|
97
103
|
const e = err;
|
|
104
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
105
|
+
tool: "codiedev_pull",
|
|
106
|
+
ok: false,
|
|
107
|
+
latencyMs: Date.now() - start,
|
|
108
|
+
error: e.message,
|
|
109
|
+
});
|
|
98
110
|
if (e.status === 404) {
|
|
99
111
|
console.error(`Not found: ${key}${version ? ` v${version}` : ""}`);
|
|
100
112
|
}
|
package/dist/commands/push.js
CHANGED
|
@@ -113,6 +113,7 @@ async function runPush(args) {
|
|
|
113
113
|
}
|
|
114
114
|
const filename = path.basename(absolute);
|
|
115
115
|
const gitRemoteUrl = (0, utils_1.getGitRemoteUrl)(process.cwd()) ?? undefined;
|
|
116
|
+
const start = Date.now();
|
|
116
117
|
try {
|
|
117
118
|
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/push", {
|
|
118
119
|
config,
|
|
@@ -126,6 +127,11 @@ async function runPush(args) {
|
|
|
126
127
|
gitRemoteUrl,
|
|
127
128
|
},
|
|
128
129
|
});
|
|
130
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
131
|
+
tool: "codiedev_push",
|
|
132
|
+
ok: true,
|
|
133
|
+
latencyMs: Date.now() - start,
|
|
134
|
+
});
|
|
129
135
|
(0, scope_1.printScope)({ workspaceName: res.workspaceName, matchedRepo: res.matchedRepo });
|
|
130
136
|
const tagSummary = res.tags && res.tags.length > 0 ? ` tags=[${res.tags.join(", ")}]` : "";
|
|
131
137
|
console.log(`✓ Pushed ${filename} (kind=${res.kind}${tagSummary}).`);
|
|
@@ -133,6 +139,12 @@ async function runPush(args) {
|
|
|
133
139
|
console.log(` Pull with: codiedev pull ${filename}`);
|
|
134
140
|
}
|
|
135
141
|
catch (err) {
|
|
142
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
143
|
+
tool: "codiedev_push",
|
|
144
|
+
ok: false,
|
|
145
|
+
latencyMs: Date.now() - start,
|
|
146
|
+
error: err.message,
|
|
147
|
+
});
|
|
136
148
|
console.error(`Push failed: ${err.message}`);
|
|
137
149
|
process.exit(1);
|
|
138
150
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// `codiedev react <postId> <emoji>` — toggle a reaction on a feed post.
|
|
3
|
+
// Calling twice with the same emoji removes it.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.runReact = runReact;
|
|
6
|
+
const shared_1 = require("./shared");
|
|
7
|
+
async function runReact(args, configOverride) {
|
|
8
|
+
const positionals = args.filter((a) => !a.startsWith("--"));
|
|
9
|
+
const [postId, emoji] = positionals;
|
|
10
|
+
if (!postId || !emoji) {
|
|
11
|
+
console.error("Usage: codiedev react <postId> <emoji>");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const config = configOverride ?? (0, shared_1.requireConfig)();
|
|
15
|
+
const start = Date.now();
|
|
16
|
+
try {
|
|
17
|
+
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/react", {
|
|
18
|
+
config,
|
|
19
|
+
body: { postId, emoji },
|
|
20
|
+
});
|
|
21
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
22
|
+
tool: "codiedev_react",
|
|
23
|
+
ok: true,
|
|
24
|
+
latencyMs: Date.now() - start,
|
|
25
|
+
});
|
|
26
|
+
console.log(res.action === "removed"
|
|
27
|
+
? `Removed ${res.emoji ?? emoji} from post ${postId}.`
|
|
28
|
+
: `Reacted to post ${postId} with ${res.emoji ?? emoji}.`);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
32
|
+
tool: "codiedev_react",
|
|
33
|
+
ok: false,
|
|
34
|
+
latencyMs: Date.now() - start,
|
|
35
|
+
error: err.message,
|
|
36
|
+
});
|
|
37
|
+
console.error(`React failed: ${err.message}`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -183,6 +183,7 @@ async function runReverseTicket(args) {
|
|
|
183
183
|
console.log("");
|
|
184
184
|
console.log("Generating ticket…");
|
|
185
185
|
console.log("");
|
|
186
|
+
const start = Date.now();
|
|
186
187
|
try {
|
|
187
188
|
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/reverseTicket", {
|
|
188
189
|
config,
|
|
@@ -191,6 +192,11 @@ async function runReverseTicket(args) {
|
|
|
191
192
|
forcedArtifactKey: forcedKey,
|
|
192
193
|
},
|
|
193
194
|
});
|
|
195
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
196
|
+
tool: "codiedev_reverse_ticket",
|
|
197
|
+
ok: true,
|
|
198
|
+
latencyMs: Date.now() - start,
|
|
199
|
+
});
|
|
194
200
|
if (res.match) {
|
|
195
201
|
console.log(`✓ Matched artifact: ${res.match.key} (score=${res.match.score.toFixed(2)})`);
|
|
196
202
|
console.log(` signals · body=${res.match.signals.bodyMention} · files=${res.match.signals.fileOverlap.toFixed(2)} · transcript=${res.match.signals.transcriptEdit}`);
|
|
@@ -212,6 +218,12 @@ async function runReverseTicket(args) {
|
|
|
212
218
|
console.log(res.ticket);
|
|
213
219
|
}
|
|
214
220
|
catch (err) {
|
|
221
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
222
|
+
tool: "codiedev_reverse_ticket",
|
|
223
|
+
ok: false,
|
|
224
|
+
latencyMs: Date.now() - start,
|
|
225
|
+
error: err.message,
|
|
226
|
+
});
|
|
215
227
|
console.error(`Reverse-ticket failed: ${err.message}`);
|
|
216
228
|
process.exit(1);
|
|
217
229
|
}
|
|
@@ -367,6 +379,7 @@ async function runBranchMode(opts) {
|
|
|
367
379
|
console.log("Generating ticket draft…");
|
|
368
380
|
console.log("");
|
|
369
381
|
const config = (0, shared_1.requireConfig)();
|
|
382
|
+
const start = Date.now();
|
|
370
383
|
try {
|
|
371
384
|
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/reverseTicketFromBranch", {
|
|
372
385
|
config,
|
|
@@ -387,9 +400,20 @@ async function runBranchMode(opts) {
|
|
|
387
400
|
},
|
|
388
401
|
});
|
|
389
402
|
if (!res.ok || !res.artifactId) {
|
|
403
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
404
|
+
tool: "codiedev_reverse_ticket",
|
|
405
|
+
ok: false,
|
|
406
|
+
latencyMs: Date.now() - start,
|
|
407
|
+
error: "no result",
|
|
408
|
+
});
|
|
390
409
|
console.error("Reverse-ticket generation returned no result. The writer may have skipped due to missing context.");
|
|
391
410
|
process.exit(1);
|
|
392
411
|
}
|
|
412
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
413
|
+
tool: "codiedev_reverse_ticket",
|
|
414
|
+
ok: true,
|
|
415
|
+
latencyMs: Date.now() - start,
|
|
416
|
+
});
|
|
393
417
|
const portalHost = (process.env.CODIEDEV_PORTAL_URL || "https://codiedev.com").replace(/\/$/, "");
|
|
394
418
|
const portalLink = res.portalUrl.startsWith("http")
|
|
395
419
|
? res.portalUrl
|
|
@@ -403,6 +427,12 @@ async function runBranchMode(opts) {
|
|
|
403
427
|
console.log("Each call creates a fresh draft — clean up duplicates from the portal if needed.");
|
|
404
428
|
}
|
|
405
429
|
catch (err) {
|
|
430
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
431
|
+
tool: "codiedev_reverse_ticket",
|
|
432
|
+
ok: false,
|
|
433
|
+
latencyMs: Date.now() - start,
|
|
434
|
+
error: err.message,
|
|
435
|
+
});
|
|
406
436
|
console.error(`Reverse-ticket failed: ${err.message}`);
|
|
407
437
|
process.exit(1);
|
|
408
438
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// `codiedev search "<query>"` — semantic + keyword search across the org's
|
|
3
|
+
// captured sessions, artifacts, and skills. Hits are filtered by companyId
|
|
4
|
+
// server-side, so a single search surfaces results from every teammate's
|
|
5
|
+
// prior sessions in the same workspace.
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.runSearch = runSearch;
|
|
8
|
+
const shared_1 = require("./shared");
|
|
9
|
+
function parseArgs(args) {
|
|
10
|
+
let query;
|
|
11
|
+
let limit;
|
|
12
|
+
for (let i = 0; i < args.length; i++) {
|
|
13
|
+
const a = args[i];
|
|
14
|
+
if (a === "--limit" && i + 1 < args.length) {
|
|
15
|
+
const n = Number(args[++i]);
|
|
16
|
+
if (Number.isInteger(n) && n > 0)
|
|
17
|
+
limit = n;
|
|
18
|
+
}
|
|
19
|
+
else if (a.startsWith("--limit=")) {
|
|
20
|
+
const n = Number(a.slice("--limit=".length));
|
|
21
|
+
if (Number.isInteger(n) && n > 0)
|
|
22
|
+
limit = n;
|
|
23
|
+
}
|
|
24
|
+
else if (!a.startsWith("--") && query === undefined) {
|
|
25
|
+
query = a;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (!query || !query.trim()) {
|
|
29
|
+
console.error('Usage: codiedev search "<query>" [--limit N]');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
return { query: query.trim(), limit };
|
|
33
|
+
}
|
|
34
|
+
async function runSearch(args, configOverride) {
|
|
35
|
+
const { query, limit } = parseArgs(args);
|
|
36
|
+
const config = configOverride ?? (0, shared_1.requireConfig)();
|
|
37
|
+
const start = Date.now();
|
|
38
|
+
try {
|
|
39
|
+
const res = await (0, shared_1.apiRequest)("GET", "/api/cli/search", {
|
|
40
|
+
config,
|
|
41
|
+
query: { q: query, limit },
|
|
42
|
+
});
|
|
43
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
44
|
+
tool: "codiedev_search",
|
|
45
|
+
ok: true,
|
|
46
|
+
latencyMs: Date.now() - start,
|
|
47
|
+
});
|
|
48
|
+
if (!res.hits || res.hits.length === 0) {
|
|
49
|
+
console.log(`No matches for "${query}".`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
console.log(`Found ${res.hits.length} match${res.hits.length === 1 ? "" : "es"} for "${query}":\n`);
|
|
53
|
+
for (const h of res.hits) {
|
|
54
|
+
const keyOrId = h.key ?? h._id;
|
|
55
|
+
console.log(` ${h.title} (${h.type}, score ${h.score.toFixed(2)})`);
|
|
56
|
+
console.log(` ${keyOrId}`);
|
|
57
|
+
if (h.snippet)
|
|
58
|
+
console.log(` ${h.snippet.slice(0, 240)}`);
|
|
59
|
+
console.log();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
64
|
+
tool: "codiedev_search",
|
|
65
|
+
ok: false,
|
|
66
|
+
latencyMs: Date.now() - start,
|
|
67
|
+
error: err.message,
|
|
68
|
+
});
|
|
69
|
+
console.error(`Search failed: ${err.message}`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// `codiedev send <filename> <recipient> [message]` — share an artifact AND
|
|
3
|
+
// send a short message that lands in the teammate's inbox. The active-
|
|
4
|
+
// handoff version of `codiedev share`. Use this when the user is actively
|
|
5
|
+
// looping someone in.
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.runSend = runSend;
|
|
8
|
+
const shared_1 = require("./shared");
|
|
9
|
+
function parseArgs(args) {
|
|
10
|
+
const positionals = args.filter((a) => !a.startsWith("--"));
|
|
11
|
+
const [filename, to, ...rest] = positionals;
|
|
12
|
+
if (!filename || !to) {
|
|
13
|
+
console.error('Usage: codiedev send <filename> <recipient> ["<message>"]');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
// Recombine remaining tokens — supports both quoted and unquoted messages.
|
|
17
|
+
const message = rest.length > 0 ? (0, shared_1.stripQuotes)(rest.join(" ")) : undefined;
|
|
18
|
+
return { filename, to, message };
|
|
19
|
+
}
|
|
20
|
+
async function runSend(args, configOverride) {
|
|
21
|
+
const parsed = parseArgs(args);
|
|
22
|
+
const config = configOverride ?? (0, shared_1.requireConfig)();
|
|
23
|
+
const start = Date.now();
|
|
24
|
+
try {
|
|
25
|
+
const body = {
|
|
26
|
+
filename: parsed.filename,
|
|
27
|
+
to: parsed.to,
|
|
28
|
+
};
|
|
29
|
+
if (parsed.message)
|
|
30
|
+
body.message = parsed.message;
|
|
31
|
+
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/send-to", {
|
|
32
|
+
config,
|
|
33
|
+
body,
|
|
34
|
+
});
|
|
35
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
36
|
+
tool: "codiedev_send_to",
|
|
37
|
+
ok: true,
|
|
38
|
+
latencyMs: Date.now() - start,
|
|
39
|
+
});
|
|
40
|
+
const who = res.recipient ? `${res.recipient.name} (${res.recipient.email})` : parsed.to;
|
|
41
|
+
if (parsed.message) {
|
|
42
|
+
console.log(`Sent ${parsed.filename} to ${who}.`);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.log(`Shared ${parsed.filename} with ${who} (no message).`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
(0, shared_1.recordAgentEvent)(config, {
|
|
50
|
+
tool: "codiedev_send_to",
|
|
51
|
+
ok: false,
|
|
52
|
+
latencyMs: Date.now() - start,
|
|
53
|
+
error: err.message,
|
|
54
|
+
});
|
|
55
|
+
const body = err.body;
|
|
56
|
+
if (body && Array.isArray(body.candidates) && body.candidates.length > 0) {
|
|
57
|
+
console.error(`Recipient "${parsed.to}" is ambiguous. Candidates:`);
|
|
58
|
+
for (const c of body.candidates) {
|
|
59
|
+
console.error(` - ${c.name} (${c.email})`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
console.error(`Send failed: ${err.message}`);
|
|
64
|
+
}
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|