@nexrall/code-core 1.4.76 → 1.4.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/effortCap.d.ts +24 -0
- package/dist/agent/effortCap.d.ts.map +1 -0
- package/dist/agent/effortCap.js +66 -0
- package/dist/agent/goal.d.ts +55 -0
- package/dist/agent/goal.d.ts.map +1 -0
- package/dist/agent/goal.js +120 -0
- package/dist/agent/handoffBrief.d.ts +82 -0
- package/dist/agent/handoffBrief.d.ts.map +1 -0
- package/dist/agent/handoffBrief.js +121 -0
- package/dist/agent/hooks.d.ts +10 -2
- package/dist/agent/hooks.d.ts.map +1 -1
- package/dist/agent/hooks.js +9 -3
- package/dist/agent/modelCatalogue.d.ts +23 -0
- package/dist/agent/modelCatalogue.d.ts.map +1 -1
- package/dist/agent/modelCatalogue.js +28 -0
- package/dist/agent/outputStyles.d.ts +27 -0
- package/dist/agent/outputStyles.d.ts.map +1 -0
- package/dist/agent/outputStyles.js +174 -0
- package/dist/agent/skills.d.ts.map +1 -1
- package/dist/agent/skills.js +21 -1
- package/dist/api/billingLines.d.ts +11 -0
- package/dist/api/billingLines.d.ts.map +1 -0
- package/dist/api/billingLines.js +56 -0
- package/dist/api/client.d.ts +2 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/scheduleLines.d.ts +53 -0
- package/dist/api/scheduleLines.d.ts.map +1 -0
- package/dist/api/scheduleLines.js +150 -0
- package/dist/context/contextFiles.d.ts +81 -0
- package/dist/context/contextFiles.d.ts.map +1 -0
- package/dist/context/contextFiles.js +310 -0
- package/dist/diff/collect.d.ts +25 -0
- package/dist/diff/collect.d.ts.map +1 -0
- package/dist/diff/collect.js +169 -0
- package/dist/diff/diffView.d.ts +57 -0
- package/dist/diff/diffView.d.ts.map +1 -0
- package/dist/diff/diffView.js +231 -0
- package/dist/diff/reviewQueue.d.ts +53 -0
- package/dist/diff/reviewQueue.d.ts.map +1 -0
- package/dist/diff/reviewQueue.js +349 -0
- package/dist/events/recap.d.ts +54 -0
- package/dist/events/recap.d.ts.map +1 -0
- package/dist/events/recap.js +161 -0
- package/dist/events/sessionEvents.d.ts +54 -0
- package/dist/events/sessionEvents.d.ts.map +1 -0
- package/dist/events/sessionEvents.js +324 -0
- package/dist/events/sessionStats.d.ts +89 -0
- package/dist/events/sessionStats.d.ts.map +1 -0
- package/dist/events/sessionStats.js +264 -0
- package/dist/import/claudeImport.d.ts +44 -0
- package/dist/import/claudeImport.d.ts.map +1 -0
- package/dist/import/claudeImport.js +337 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -0
- package/dist/mcp/manager.d.ts +8 -0
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +64 -57
- package/dist/permissions/destructiveTokens.d.ts +1 -0
- package/dist/permissions/destructiveTokens.d.ts.map +1 -1
- package/dist/permissions/destructiveTokens.js +93 -0
- package/dist/permissions/rules.d.ts +12 -0
- package/dist/permissions/rules.d.ts.map +1 -1
- package/dist/permissions/rules.js +89 -7
- package/dist/plugins/configStore.d.ts +43 -0
- package/dist/plugins/configStore.d.ts.map +1 -0
- package/dist/plugins/configStore.js +253 -0
- package/dist/plugins/files.d.ts +10 -0
- package/dist/plugins/files.d.ts.map +1 -0
- package/dist/plugins/files.js +85 -0
- package/dist/plugins/index.d.ts +3 -22
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +30 -40
- package/dist/plugins/resolve.d.ts +18 -0
- package/dist/plugins/resolve.d.ts.map +1 -0
- package/dist/plugins/resolve.js +152 -0
- package/dist/plugins/userConfig.d.ts +90 -0
- package/dist/plugins/userConfig.d.ts.map +1 -0
- package/dist/plugins/userConfig.js +332 -0
- package/dist/plugins/validate.d.ts +14 -0
- package/dist/plugins/validate.d.ts.map +1 -0
- package/dist/plugins/validate.js +222 -0
- package/dist/project/projectCommands.d.ts +33 -0
- package/dist/project/projectCommands.d.ts.map +1 -0
- package/dist/project/projectCommands.js +246 -0
- package/dist/search/conversationTurns.d.ts +53 -0
- package/dist/search/conversationTurns.d.ts.map +1 -0
- package/dist/search/conversationTurns.js +170 -0
- package/dist/search/globalSearch.d.ts +144 -0
- package/dist/search/globalSearch.d.ts.map +1 -0
- package/dist/search/globalSearch.js +350 -0
- package/dist/share/sessionChannel.d.ts +136 -0
- package/dist/share/sessionChannel.d.ts.map +1 -0
- package/dist/share/sessionChannel.js +373 -0
- package/dist/share/sessionShare.d.ts +104 -0
- package/dist/share/sessionShare.d.ts.map +1 -0
- package/dist/share/sessionShare.js +336 -0
- package/dist/ui/configCmd.d.ts +48 -0
- package/dist/ui/configCmd.d.ts.map +1 -0
- package/dist/ui/configCmd.js +146 -0
- package/dist/ui/deployPanel.d.ts +91 -0
- package/dist/ui/deployPanel.d.ts.map +1 -0
- package/dist/ui/deployPanel.js +442 -0
- package/dist/ui/mergeAssistant.d.ts +120 -0
- package/dist/ui/mergeAssistant.d.ts.map +1 -0
- package/dist/ui/mergeAssistant.js +391 -0
- package/dist/ui/notify.d.ts +114 -0
- package/dist/ui/notify.d.ts.map +1 -0
- package/dist/ui/notify.js +235 -0
- package/dist/ui/promptSuggest.d.ts +56 -0
- package/dist/ui/promptSuggest.d.ts.map +1 -0
- package/dist/ui/promptSuggest.js +160 -0
- package/dist/ui/taskGraph.d.ts +44 -0
- package/dist/ui/taskGraph.d.ts.map +1 -0
- package/dist/ui/taskGraph.js +289 -0
- package/dist/util/addDir.d.ts +31 -0
- package/dist/util/addDir.d.ts.map +1 -0
- package/dist/util/addDir.js +124 -0
- package/dist/util/batch.d.ts +16 -0
- package/dist/util/batch.d.ts.map +1 -0
- package/dist/util/batch.js +92 -0
- package/dist/util/cellWidth.d.ts +12 -0
- package/dist/util/cellWidth.d.ts.map +1 -0
- package/dist/util/cellWidth.js +161 -0
- package/dist/util/duration.d.ts +8 -0
- package/dist/util/duration.d.ts.map +1 -0
- package/dist/util/duration.js +50 -0
- package/dist/util/loopJobs.d.ts +67 -0
- package/dist/util/loopJobs.d.ts.map +1 -0
- package/dist/util/loopJobs.js +169 -0
- package/dist/util/settingsFile.d.ts +14 -0
- package/dist/util/settingsFile.d.ts.map +1 -0
- package/dist/util/settingsFile.js +99 -0
- package/dist/util/toolLabel.d.ts +2 -0
- package/dist/util/toolLabel.d.ts.map +1 -0
- package/dist/util/toolLabel.js +17 -0
- package/dist/verify/failureTimeline.d.ts +100 -0
- package/dist/verify/failureTimeline.d.ts.map +1 -0
- package/dist/verify/failureTimeline.js +253 -0
- package/dist/verify/verification.d.ts +75 -0
- package/dist/verify/verification.d.ts.map +1 -0
- package/dist/verify/verification.js +315 -0
- package/package.json +5 -4
|
@@ -58,6 +58,8 @@ exports.liveReasoningEffortStyle = liveReasoningEffortStyle;
|
|
|
58
58
|
exports.liveVendorFor = liveVendorFor;
|
|
59
59
|
exports.liveLabelFor = liveLabelFor;
|
|
60
60
|
exports.liveCostMultiplierFor = liveCostMultiplierFor;
|
|
61
|
+
exports.livePriceFor = livePriceFor;
|
|
62
|
+
exports.formatModelPrice = formatModelPrice;
|
|
61
63
|
exports.liveSelectableModelIds = liveSelectableModelIds;
|
|
62
64
|
exports._resetModelCatalogueCacheForTests = _resetModelCatalogueCacheForTests;
|
|
63
65
|
exports.cheapestSameVendorModel = cheapestSameVendorModel;
|
|
@@ -171,6 +173,32 @@ function liveCostMultiplierFor(id, fallback) {
|
|
|
171
173
|
const m = findModel(id);
|
|
172
174
|
return m && typeof m.costMultiplier === 'number' ? m.costMultiplier : fallback;
|
|
173
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Live per-1M-token prices (USD, input/output) for `id`, or `fallback` when
|
|
178
|
+
* the catalogue has not loaded or predates the price fields. Mirrors
|
|
179
|
+
* liveCostMultiplierFor's contract exactly; render the result with
|
|
180
|
+
* formatModelPrice below so every client shows the identical string.
|
|
181
|
+
*/
|
|
182
|
+
function livePriceFor(id, fallback) {
|
|
183
|
+
const m = findModel(id);
|
|
184
|
+
if (m && typeof m.inputPrice === 'number' && typeof m.outputPrice === 'number') {
|
|
185
|
+
return { input: m.inputPrice, output: m.outputPrice };
|
|
186
|
+
}
|
|
187
|
+
return fallback;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* `$2/$10` — the ONE label for a per-1M price pair (USD, vendor list before
|
|
191
|
+
* markup). Trailing zeros are trimmed on purpose to fit the fixed-width
|
|
192
|
+
* picker rows. The VS Code webview's inline twin and web/app's
|
|
193
|
+
* formatModelPrice must render the identical string; keep all three in step.
|
|
194
|
+
*/
|
|
195
|
+
function formatModelPrice(p) {
|
|
196
|
+
// '—' rather than 'NaN' if a caller ever hands in a non-finite number: the
|
|
197
|
+
// wire cannot actually carry one (JSON turns NaN into null, and a null pair
|
|
198
|
+
// fails livePriceFor's typeof check), so this is display insurance only.
|
|
199
|
+
const fmt = (n) => (Number.isFinite(n) ? String(Math.round(n * 1000) / 1000) : '—');
|
|
200
|
+
return `$${fmt(p.input)}/$${fmt(p.output)}`;
|
|
201
|
+
}
|
|
174
202
|
/**
|
|
175
203
|
* The list of selectable model ids the live catalogue offers, or null when
|
|
176
204
|
* no catalogue has been fetched yet — callers fall back to their own static
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface OutputStyle {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
/** The instructions added to the system prompt. Empty for the default style. */
|
|
5
|
+
prompt: string;
|
|
6
|
+
source: 'built-in' | 'user' | 'project';
|
|
7
|
+
}
|
|
8
|
+
export declare const DEFAULT_STYLE = "default";
|
|
9
|
+
/** A style is injected into every prompt; cap it so a stray huge file cannot eat the context. */
|
|
10
|
+
export declare const MAX_STYLE_CHARS = 4000;
|
|
11
|
+
export declare const BUILT_IN_STYLES: readonly OutputStyle[];
|
|
12
|
+
/** Splits optional `---` front matter off a style file. Unknown keys are ignored. */
|
|
13
|
+
export declare function parseStyleFile(text: string): {
|
|
14
|
+
description: string;
|
|
15
|
+
body: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function listOutputStyles(workDir: string, home?: string): OutputStyle[];
|
|
18
|
+
export declare function findOutputStyle(styles: readonly OutputStyle[], name: string): OutputStyle | undefined;
|
|
19
|
+
/** The settings value → a style name, defaulting safely for anything unusable. */
|
|
20
|
+
export declare function readStyleSetting(raw: Record<string, unknown> | undefined | null): string;
|
|
21
|
+
/**
|
|
22
|
+
* The text to add to the system prompt for the chosen style, or undefined for none.
|
|
23
|
+
* A style that no longer exists (file deleted) resolves to none rather than failing the session.
|
|
24
|
+
*/
|
|
25
|
+
export declare function styleInstructions(styles: readonly OutputStyle[], name: string): string | undefined;
|
|
26
|
+
export declare function formatStyleList(styles: readonly OutputStyle[], current: string): string[];
|
|
27
|
+
//# sourceMappingURL=outputStyles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputStyles.d.ts","sourceRoot":"","sources":["../../src/agent/outputStyles.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;CACzC;AAED,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,iGAAiG;AACjG,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC,eAAO,MAAM,eAAe,EAAE,SAAS,WAAW,EAuBjD,CAAC;AAEF,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAUlF;AAsCD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAqB,GAAG,WAAW,EAAE,CAS5F;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAKrG;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAGxF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIlG;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAUzF"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Output styles — a named block of instructions that changes HOW the agent answers
|
|
3
|
+
// (terse, teaching, ...) without changing what it can do. It rides in the same slot as
|
|
4
|
+
// the project brief, so it never touches the tool list or the permission rules.
|
|
5
|
+
//
|
|
6
|
+
// Sources, later wins on a name clash:
|
|
7
|
+
// built-in → ~/.nexrall/output-styles/<name>.md → <project>/.nexrall/output-styles/<name>.md
|
|
8
|
+
// A file may start with `---` front matter carrying `description:`; the rest is the style.
|
|
9
|
+
//
|
|
10
|
+
// Lives in core (moved from the CLI's ui/outputStyles.ts, 2026-10-04) so the VS Code
|
|
11
|
+
// panel composes the SAME styles into its brief — the CLI module is a re-export shim.
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.BUILT_IN_STYLES = exports.MAX_STYLE_CHARS = exports.DEFAULT_STYLE = void 0;
|
|
47
|
+
exports.parseStyleFile = parseStyleFile;
|
|
48
|
+
exports.listOutputStyles = listOutputStyles;
|
|
49
|
+
exports.findOutputStyle = findOutputStyle;
|
|
50
|
+
exports.readStyleSetting = readStyleSetting;
|
|
51
|
+
exports.styleInstructions = styleInstructions;
|
|
52
|
+
exports.formatStyleList = formatStyleList;
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const path = __importStar(require("path"));
|
|
55
|
+
const os = __importStar(require("os"));
|
|
56
|
+
exports.DEFAULT_STYLE = 'default';
|
|
57
|
+
/** A style is injected into every prompt; cap it so a stray huge file cannot eat the context. */
|
|
58
|
+
exports.MAX_STYLE_CHARS = 4000;
|
|
59
|
+
exports.BUILT_IN_STYLES = [
|
|
60
|
+
{ name: exports.DEFAULT_STYLE, description: 'The standard coding-assistant voice', prompt: '', source: 'built-in' },
|
|
61
|
+
{
|
|
62
|
+
name: 'concise',
|
|
63
|
+
description: 'Shortest correct answer — no preamble, no recap',
|
|
64
|
+
source: 'built-in',
|
|
65
|
+
prompt: 'Answer style: be as brief as correctness allows. No preamble, no restating the question, no closing summary of what you just did. Prefer one sentence or a short list. Show code, not prose about code. Never drop a warning the user must know to avoid breaking something.',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'explanatory',
|
|
69
|
+
description: 'Explains the why behind each choice as it works',
|
|
70
|
+
source: 'built-in',
|
|
71
|
+
prompt: 'Answer style: while you work, add a short "Why" for each non-obvious decision (a trade-off, a pattern, a gotcha in this codebase) so the user learns the reasoning, not just the result. Keep each explanation to 1-3 sentences and tied to the code in front of you.',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'learning',
|
|
75
|
+
description: 'Teaches: leaves small, well-marked pieces for you to write',
|
|
76
|
+
source: 'built-in',
|
|
77
|
+
prompt: 'Answer style: teach while building. Do the routine work yourself, but for a small, meaningful decision (a core function body, a design choice) stop and ask the user to write it, naming exactly where it goes and what it must do. Explain the concept first in 2-3 sentences. Never block on this for trivial code.',
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
/** Splits optional `---` front matter off a style file. Unknown keys are ignored. */
|
|
81
|
+
function parseStyleFile(text) {
|
|
82
|
+
const src = String(text ?? '').replace(/^\uFEFF/, '');
|
|
83
|
+
const m = /^---\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/.exec(src);
|
|
84
|
+
if (!m)
|
|
85
|
+
return { description: '', body: src.trim() };
|
|
86
|
+
const desc = /^description:\s*(.*)$/m
|
|
87
|
+
.exec(m[1])?.[1]
|
|
88
|
+
?.trim()
|
|
89
|
+
.replace(/^["']|["']$/g, '') ?? '';
|
|
90
|
+
return { description: desc, body: src.slice(m[0].length).trim() };
|
|
91
|
+
}
|
|
92
|
+
/** `Concise.md` → `concise`. Names are file stems, lower-cased, so lookup is forgiving. */
|
|
93
|
+
function styleName(file) {
|
|
94
|
+
if (!/\.md$/i.test(file))
|
|
95
|
+
return null;
|
|
96
|
+
const stem = file.slice(0, -3).trim().toLowerCase().replace(/\s+/g, '-');
|
|
97
|
+
return /^[a-z0-9][a-z0-9._-]*$/.test(stem) ? stem : null;
|
|
98
|
+
}
|
|
99
|
+
function readDir(dir, source) {
|
|
100
|
+
let files;
|
|
101
|
+
try {
|
|
102
|
+
files = fs.readdirSync(dir);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
const out = [];
|
|
108
|
+
for (const f of files.sort()) {
|
|
109
|
+
const name = styleName(f);
|
|
110
|
+
if (!name)
|
|
111
|
+
continue;
|
|
112
|
+
let text;
|
|
113
|
+
try {
|
|
114
|
+
text = fs.readFileSync(path.join(dir, f), 'utf8');
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const { description, body } = parseStyleFile(text);
|
|
120
|
+
if (!body)
|
|
121
|
+
continue;
|
|
122
|
+
out.push({
|
|
123
|
+
name,
|
|
124
|
+
description: description || `Custom style (${source})`,
|
|
125
|
+
prompt: body.length > exports.MAX_STYLE_CHARS ? body.slice(0, exports.MAX_STYLE_CHARS) : body,
|
|
126
|
+
source,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
function listOutputStyles(workDir, home = os.homedir()) {
|
|
132
|
+
const byName = new Map();
|
|
133
|
+
for (const s of exports.BUILT_IN_STYLES)
|
|
134
|
+
byName.set(s.name, s);
|
|
135
|
+
for (const s of readDir(path.join(home, '.nexrall', 'output-styles'), 'user'))
|
|
136
|
+
byName.set(s.name, s);
|
|
137
|
+
for (const s of readDir(path.join(workDir, '.nexrall', 'output-styles'), 'project'))
|
|
138
|
+
byName.set(s.name, s);
|
|
139
|
+
// The default style is always the empty one: a file named default.md must not be able
|
|
140
|
+
// to hide the way back to "no style".
|
|
141
|
+
byName.set(exports.DEFAULT_STYLE, exports.BUILT_IN_STYLES[0]);
|
|
142
|
+
return [...byName.values()];
|
|
143
|
+
}
|
|
144
|
+
function findOutputStyle(styles, name) {
|
|
145
|
+
const n = String(name ?? '')
|
|
146
|
+
.trim()
|
|
147
|
+
.toLowerCase();
|
|
148
|
+
return styles.find((s) => s.name === n);
|
|
149
|
+
}
|
|
150
|
+
/** The settings value → a style name, defaulting safely for anything unusable. */
|
|
151
|
+
function readStyleSetting(raw) {
|
|
152
|
+
const v = (raw ?? {}).outputStyle;
|
|
153
|
+
return typeof v === 'string' && v.trim() ? v.trim().toLowerCase() : exports.DEFAULT_STYLE;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The text to add to the system prompt for the chosen style, or undefined for none.
|
|
157
|
+
* A style that no longer exists (file deleted) resolves to none rather than failing the session.
|
|
158
|
+
*/
|
|
159
|
+
function styleInstructions(styles, name) {
|
|
160
|
+
const s = findOutputStyle(styles, name);
|
|
161
|
+
if (!s || !s.prompt)
|
|
162
|
+
return undefined;
|
|
163
|
+
return `[Output style: ${s.name}]\n${s.prompt}`;
|
|
164
|
+
}
|
|
165
|
+
function formatStyleList(styles, current) {
|
|
166
|
+
const width = Math.max(...styles.map((s) => s.name.length));
|
|
167
|
+
const lines = ['Output styles:', ''];
|
|
168
|
+
for (const s of styles) {
|
|
169
|
+
lines.push(` ${s.name === current ? '●' : ' '} ${s.name.padEnd(width)} ${s.description}${s.source === 'built-in' ? '' : ` [${s.source}]`}`);
|
|
170
|
+
}
|
|
171
|
+
lines.push('', 'Switch: /output-style <name> Add your own: .nexrall/output-styles/<name>.md');
|
|
172
|
+
return lines;
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=outputStyles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/agent/skills.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/agent/skills.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/skills.js
CHANGED
|
@@ -50,6 +50,7 @@ const path = __importStar(require("path"));
|
|
|
50
50
|
const os = __importStar(require("os"));
|
|
51
51
|
const child_process_1 = require("child_process");
|
|
52
52
|
const index_1 = require("../plugins/index");
|
|
53
|
+
const resolve_1 = require("../plugins/resolve");
|
|
53
54
|
const loader_1 = require("../commands/loader");
|
|
54
55
|
const frontmatter_1 = require("../util/frontmatter");
|
|
55
56
|
const agentTypes_1 = require("./agentTypes");
|
|
@@ -507,12 +508,19 @@ function watchSkills(workDir, onChange, opts = {}) {
|
|
|
507
508
|
try {
|
|
508
509
|
const w = fs.watch(root, { recursive: true }, fire);
|
|
509
510
|
w.on('error', () => { });
|
|
511
|
+
// A background convenience watcher must never be the handle that pins a
|
|
512
|
+
// process open at exit. Events still fire while anything else keeps the
|
|
513
|
+
// loop alive (the CLI's readline, the VS Code host, a test runner); but a
|
|
514
|
+
// host that answers 'dispose' by simply letting the loop drain — or a
|
|
515
|
+
// test embedding this panel — is not held hostage by the watcher it armed.
|
|
516
|
+
w.unref();
|
|
510
517
|
watchers.push(w);
|
|
511
518
|
}
|
|
512
519
|
catch {
|
|
513
520
|
try {
|
|
514
521
|
const w = fs.watch(root, fire);
|
|
515
522
|
w.on('error', () => { });
|
|
523
|
+
w.unref();
|
|
516
524
|
watchers.push(w);
|
|
517
525
|
}
|
|
518
526
|
catch {
|
|
@@ -723,7 +731,19 @@ function resolveNestedSkill(workDir, ref) {
|
|
|
723
731
|
* guidance without loading them into context up front.
|
|
724
732
|
*/
|
|
725
733
|
function expandSkill(skill, argString, workDir) {
|
|
726
|
-
|
|
734
|
+
let expanded = (0, loader_1.expandBody)(skill.body, argString, workDir);
|
|
735
|
+
// S24: a PLUGIN skill's body may embed ${user_config.KEY} references — that is
|
|
736
|
+
// how a skill targets the value the user configured for its plugin. Only
|
|
737
|
+
// NON-sensitive values are substituted here: a sensitive reference stays the
|
|
738
|
+
// literal token, so a token never rides a skill into model context (the
|
|
739
|
+
// command/agent can still read it from NEXRALL_PLUGIN_OPTION_<KEY> in its own
|
|
740
|
+
// processes). Flat plugin commands have no `dir` and cannot be attributed to
|
|
741
|
+
// one plugin — they are skipped.
|
|
742
|
+
if (skill.source === 'plugin' && skill.dir) {
|
|
743
|
+
const cfg = (0, resolve_1.pluginConfigForSkillDir)(workDir, skill.dir);
|
|
744
|
+
if (cfg)
|
|
745
|
+
expanded = (0, resolve_1.substituteSkillBody)(expanded, cfg);
|
|
746
|
+
}
|
|
727
747
|
if (!skill.dir)
|
|
728
748
|
return expanded;
|
|
729
749
|
let siblings = [];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { OrgsResult } from './client';
|
|
2
|
+
export declare function formatMoney(usd: number): string;
|
|
3
|
+
/** Parse the argument of `/team use <x>`: `personal` → null, digits → team id, else undefined. */
|
|
4
|
+
export declare function parseTeamTarget(raw: string): number | null | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* Plain-text lines describing what is paying for usage right now, and which teams
|
|
7
|
+
* could. Shared by `/team` and `/balance` so the two can never disagree.
|
|
8
|
+
* `pinned` is the NEXRALL_BILLING_TEAM override (undefined when unset).
|
|
9
|
+
*/
|
|
10
|
+
export declare function billingLines(orgs: OrgsResult, pinned?: number | null): string[];
|
|
11
|
+
//# sourceMappingURL=billingLines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"billingLines.d.ts","sourceRoot":"","sources":["../../src/api/billingLines.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,kGAAkG;AAClG,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAKtE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CA6B/E"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatMoney = formatMoney;
|
|
4
|
+
exports.parseTeamTarget = parseTeamTarget;
|
|
5
|
+
exports.billingLines = billingLines;
|
|
6
|
+
function formatMoney(usd) {
|
|
7
|
+
// Sub-cent spend is the common case for a short turn; "$0.00" would hide it.
|
|
8
|
+
if (usd > 0 && usd < 0.01)
|
|
9
|
+
return '$' + usd.toFixed(4);
|
|
10
|
+
return '$' + usd.toFixed(2);
|
|
11
|
+
}
|
|
12
|
+
/** Parse the argument of `/team use <x>`: `personal` → null, digits → team id, else undefined. */
|
|
13
|
+
function parseTeamTarget(raw) {
|
|
14
|
+
const s = raw.trim();
|
|
15
|
+
if (/^(personal|null|0)$/i.test(s))
|
|
16
|
+
return null;
|
|
17
|
+
if (/^\d+$/.test(s))
|
|
18
|
+
return Number(s);
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Plain-text lines describing what is paying for usage right now, and which teams
|
|
23
|
+
* could. Shared by `/team` and `/balance` so the two can never disagree.
|
|
24
|
+
* `pinned` is the NEXRALL_BILLING_TEAM override (undefined when unset).
|
|
25
|
+
*/
|
|
26
|
+
function billingLines(orgs, pinned) {
|
|
27
|
+
const targetId = orgs.billingTargetTeamId ?? null;
|
|
28
|
+
const team = targetId == null ? null : (orgs.teams.find((t) => t.id === targetId) ?? null);
|
|
29
|
+
const lines = [];
|
|
30
|
+
if (team) {
|
|
31
|
+
lines.push(`Billing to team "${team.name}" — ${formatMoney(team.remainingUsd)} left this month`);
|
|
32
|
+
if (team.remainingUsd <= 0)
|
|
33
|
+
lines.push('! This team has no budget left — ask a team admin to add funds.');
|
|
34
|
+
}
|
|
35
|
+
else if (targetId != null) {
|
|
36
|
+
lines.push(`Billing to team ${targetId} — not available to this account, usage falls back to your wallet`);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
lines.push('Billing to your personal wallet');
|
|
40
|
+
}
|
|
41
|
+
lines.push(`Personal wallet: ${formatMoney(orgs.personal.balance)}`);
|
|
42
|
+
if (orgs.teams.length) {
|
|
43
|
+
lines.push('', 'Teams you can bill to:');
|
|
44
|
+
for (const t of orgs.teams) {
|
|
45
|
+
const cur = t.id === targetId ? ' <- current' : '';
|
|
46
|
+
const left = t.remainingUsd > 0 ? `${formatMoney(t.remainingUsd)} left` : 'no budget left';
|
|
47
|
+
lines.push(` ${t.id} ${t.name} ${left}${cur}`);
|
|
48
|
+
}
|
|
49
|
+
lines.push('', 'Switch with /team use <id> or /team use personal.');
|
|
50
|
+
}
|
|
51
|
+
if (pinned !== undefined) {
|
|
52
|
+
lines.push('', `Note: NEXRALL_BILLING_TEAM pins this run to ${pinned === null ? 'your personal wallet' : `team ${pinned}`}, ignoring the account setting.`);
|
|
53
|
+
}
|
|
54
|
+
return lines;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=billingLines.js.map
|
package/dist/api/client.d.ts
CHANGED
package/dist/api/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { CloudSchedule, CloudScheduleRun } from './client';
|
|
2
|
+
/** Same units as /loop (s, m, h, d) so one syntax covers both commands. */
|
|
3
|
+
export declare function parseScheduleEvery(raw: string): {
|
|
4
|
+
minutes: number;
|
|
5
|
+
} | {
|
|
6
|
+
error: string;
|
|
7
|
+
};
|
|
8
|
+
/** Minutes → the same human spelling /loop uses: 90 → "90m", 120 → "2h", 1440 → "1d". */
|
|
9
|
+
export declare function formatEvery(minutes: number): string;
|
|
10
|
+
/** Local wall-clock, always absolute — for things that already happened. */
|
|
11
|
+
export declare function fmtLocal(iso: string | null): string;
|
|
12
|
+
/** For "next run": relative while it is near, absolute once it is far away. */
|
|
13
|
+
export declare function fmtScheduleWhen(iso: string | null, now?: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* The list rendered by `nex schedule list` and `/schedule` (no colour — callers
|
|
16
|
+
* decide). Columns are fixed-width so rows scan; the task takes what's left.
|
|
17
|
+
*/
|
|
18
|
+
export declare function scheduleListLines(list: CloudSchedule[], opts?: {
|
|
19
|
+
now?: number;
|
|
20
|
+
cols?: number;
|
|
21
|
+
}): string[];
|
|
22
|
+
/** Run history for `nex schedule runs <id>` and `/schedule runs <id>`. */
|
|
23
|
+
export declare function scheduleRunsLines(runs: CloudScheduleRun[], opts?: {
|
|
24
|
+
cols?: number;
|
|
25
|
+
}): string[];
|
|
26
|
+
export declare const SCHEDULE_USAGE: string;
|
|
27
|
+
export type ScheduleChatAction = {
|
|
28
|
+
kind: 'list';
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'add';
|
|
31
|
+
intervalMinutes: number;
|
|
32
|
+
task: string;
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'pause';
|
|
35
|
+
id: string;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'resume';
|
|
38
|
+
id: string;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'run';
|
|
41
|
+
id: string;
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'rm';
|
|
44
|
+
id: string;
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'runs';
|
|
47
|
+
id: string;
|
|
48
|
+
} | {
|
|
49
|
+
kind: 'error';
|
|
50
|
+
message: string;
|
|
51
|
+
};
|
|
52
|
+
export declare function parseScheduleChatArg(arg: string): ScheduleChatAction;
|
|
53
|
+
//# sourceMappingURL=scheduleLines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduleLines.d.ts","sourceRoot":"","sources":["../../src/api/scheduleLines.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAIhE,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAgBvF;AAED,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAMD,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAMnD;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,SAAa,GAAG,MAAM,CAS5E;AAOD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,EAAE,CAuB7G;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,EAAE,CAYlG;AAID,eAAO,MAAM,cAAc,QAEkB,CAAC;AAE9C,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CA0BpE"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SCHEDULE_USAGE = void 0;
|
|
4
|
+
exports.parseScheduleEvery = parseScheduleEvery;
|
|
5
|
+
exports.formatEvery = formatEvery;
|
|
6
|
+
exports.fmtLocal = fmtLocal;
|
|
7
|
+
exports.fmtScheduleWhen = fmtScheduleWhen;
|
|
8
|
+
exports.scheduleListLines = scheduleListLines;
|
|
9
|
+
exports.scheduleRunsLines = scheduleRunsLines;
|
|
10
|
+
exports.parseScheduleChatArg = parseScheduleChatArg;
|
|
11
|
+
const client_1 = require("./client");
|
|
12
|
+
const loopJobs_1 = require("../util/loopJobs");
|
|
13
|
+
/** Same units as /loop (s, m, h, d) so one syntax covers both commands. */
|
|
14
|
+
function parseScheduleEvery(raw) {
|
|
15
|
+
const tok = String(raw ?? '').trim();
|
|
16
|
+
const ms = (0, loopJobs_1.parseInterval)(tok);
|
|
17
|
+
if (ms === null) {
|
|
18
|
+
return { error: `Not an interval: "${tok}". Units s, m, h, d — e.g. 90m, 2h, 1d.` };
|
|
19
|
+
}
|
|
20
|
+
const minutes = ms / 60000;
|
|
21
|
+
if (!Number.isInteger(minutes)) {
|
|
22
|
+
return { error: `Intervals must be whole minutes, at least ${client_1.SCHEDULE_MIN_MINUTES}m (the server's floor).` };
|
|
23
|
+
}
|
|
24
|
+
if (minutes < client_1.SCHEDULE_MIN_MINUTES || minutes > client_1.SCHEDULE_MAX_MINUTES) {
|
|
25
|
+
return {
|
|
26
|
+
error: `Interval ${tok} is outside the server's range (${client_1.SCHEDULE_MIN_MINUTES} minutes – ${client_1.SCHEDULE_MAX_MINUTES / (24 * 60)} days).`,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return { minutes };
|
|
30
|
+
}
|
|
31
|
+
/** Minutes → the same human spelling /loop uses: 90 → "90m", 120 → "2h", 1440 → "1d". */
|
|
32
|
+
function formatEvery(minutes) {
|
|
33
|
+
return (0, loopJobs_1.formatInterval)(Math.round(minutes) * 60000);
|
|
34
|
+
}
|
|
35
|
+
function pad2(n) {
|
|
36
|
+
return String(n).padStart(2, '0');
|
|
37
|
+
}
|
|
38
|
+
/** Local wall-clock, always absolute — for things that already happened. */
|
|
39
|
+
function fmtLocal(iso) {
|
|
40
|
+
if (!iso)
|
|
41
|
+
return '-';
|
|
42
|
+
const t = Date.parse(iso);
|
|
43
|
+
if (!Number.isFinite(t))
|
|
44
|
+
return '-';
|
|
45
|
+
const d = new Date(t);
|
|
46
|
+
return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())} ${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
|
|
47
|
+
}
|
|
48
|
+
/** For "next run": relative while it is near, absolute once it is far away. */
|
|
49
|
+
function fmtScheduleWhen(iso, now = Date.now()) {
|
|
50
|
+
if (!iso)
|
|
51
|
+
return '-';
|
|
52
|
+
const t = Date.parse(iso);
|
|
53
|
+
if (!Number.isFinite(t))
|
|
54
|
+
return '-';
|
|
55
|
+
const delta = t - now;
|
|
56
|
+
if (delta <= 0)
|
|
57
|
+
return 'due now';
|
|
58
|
+
if (delta < 60 * 60000)
|
|
59
|
+
return `in ${Math.max(1, Math.round(delta / 60000))}m`;
|
|
60
|
+
if (delta < 24 * 3600000)
|
|
61
|
+
return `in ${Math.round(delta / 3600000)}h`;
|
|
62
|
+
return fmtLocal(iso);
|
|
63
|
+
}
|
|
64
|
+
function truncate(text, width) {
|
|
65
|
+
if (width <= 1)
|
|
66
|
+
return '';
|
|
67
|
+
return text.length > width ? text.slice(0, width - 1) + '…' : text;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The list rendered by `nex schedule list` and `/schedule` (no colour — callers
|
|
71
|
+
* decide). Columns are fixed-width so rows scan; the task takes what's left.
|
|
72
|
+
*/
|
|
73
|
+
function scheduleListLines(list, opts = {}) {
|
|
74
|
+
if (!list.length) {
|
|
75
|
+
return [
|
|
76
|
+
'No cloud schedules.',
|
|
77
|
+
"Create one with: /schedule add 1d <task> (runs on Nexrall's servers, not this laptop)",
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
const now = opts.now ?? Date.now();
|
|
81
|
+
const cols = opts.cols ?? 100;
|
|
82
|
+
// 16, not 15: an absolute next-run is "YYYY-MM-DD HH:mm" — one cell wider.
|
|
83
|
+
// The rows pad NEXT RUN to the same 16, or a relative value sits a cell short of the header.
|
|
84
|
+
const head = `${'ID'.padEnd(20)}${'STATE'.padEnd(7)}${'EVERY'.padEnd(7)}${'NEXT RUN'.padEnd(16)}${'LAST'.padEnd(8)}TASK`;
|
|
85
|
+
const taskWidth = Math.max(12, cols - 60);
|
|
86
|
+
const lines = [head];
|
|
87
|
+
for (const s of list) {
|
|
88
|
+
const state = s.enabled ? 'on' : 'off';
|
|
89
|
+
const last = s.lastStatus ?? '-';
|
|
90
|
+
lines.push(`${s.id.padEnd(20)}${state.padEnd(7)}${formatEvery(s.intervalMinutes).padEnd(7)}` +
|
|
91
|
+
`${fmtScheduleWhen(s.nextRunAt, now).padEnd(16)}${last.padEnd(8)}${truncate(s.task, taskWidth)}`);
|
|
92
|
+
}
|
|
93
|
+
return lines;
|
|
94
|
+
}
|
|
95
|
+
/** Run history for `nex schedule runs <id>` and `/schedule runs <id>`. */
|
|
96
|
+
function scheduleRunsLines(runs, opts = {}) {
|
|
97
|
+
if (!runs.length)
|
|
98
|
+
return ['No runs yet — the first one happens at the "next run" time on the schedule.'];
|
|
99
|
+
const cols = opts.cols ?? 100;
|
|
100
|
+
const lines = [`${'WHEN'.padEnd(19)}${'STATUS'.padEnd(8)}${'STEPS'.padEnd(7)}SUMMARY`];
|
|
101
|
+
const summaryWidth = Math.max(12, cols - 34);
|
|
102
|
+
for (const r of runs) {
|
|
103
|
+
lines.push(`${fmtLocal(r.createdAt).padEnd(19)}${r.status.padEnd(8)}${String(r.steps).padEnd(7)}` +
|
|
104
|
+
truncate(r.summary ?? '-', summaryWidth));
|
|
105
|
+
}
|
|
106
|
+
return lines;
|
|
107
|
+
}
|
|
108
|
+
// ─── The /schedule chat command's argument grammar ───────────────────────────
|
|
109
|
+
exports.SCHEDULE_USAGE = 'Usage: /schedule [list | add <interval> <task> | pause|resume|run|rm|runs <id>]' +
|
|
110
|
+
' — e.g. /schedule add 1d triage the repo';
|
|
111
|
+
function parseScheduleChatArg(arg) {
|
|
112
|
+
const text = String(arg ?? '').trim();
|
|
113
|
+
if (!text || /^(list|ls)$/i.test(text))
|
|
114
|
+
return { kind: 'list' };
|
|
115
|
+
const head = /^(\S+)\s+([\s\S]*)$/.exec(text);
|
|
116
|
+
if (head) {
|
|
117
|
+
const verb = head[1].toLowerCase();
|
|
118
|
+
const rest = head[2].trim();
|
|
119
|
+
if (verb === 'add')
|
|
120
|
+
return parseScheduleAdd(rest);
|
|
121
|
+
if (verb === 'pause' || verb === 'resume' || verb === 'run' || verb === 'runs') {
|
|
122
|
+
if (!/^\d+$/.test(rest)) {
|
|
123
|
+
return { kind: 'error', message: `Which schedule? /schedule ${verb} takes the digit id from /schedule list.` };
|
|
124
|
+
}
|
|
125
|
+
return { kind: verb, id: rest };
|
|
126
|
+
}
|
|
127
|
+
if (verb === 'rm' || verb === 'remove') {
|
|
128
|
+
if (!/^\d+$/.test(rest)) {
|
|
129
|
+
return { kind: 'error', message: 'Which schedule? /schedule rm takes the digit id from /schedule list.' };
|
|
130
|
+
}
|
|
131
|
+
return { kind: 'rm', id: rest };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Bare form: "/schedule 2h triage the repo" — the same leading-interval shape
|
|
135
|
+
// /loop accepts, so muscle memory carries over.
|
|
136
|
+
return parseScheduleAdd(text);
|
|
137
|
+
}
|
|
138
|
+
function parseScheduleAdd(rest) {
|
|
139
|
+
const lead = /^(\S+)\s+([\s\S]+)$/.exec(rest.trim());
|
|
140
|
+
if (!lead)
|
|
141
|
+
return { kind: 'error', message: exports.SCHEDULE_USAGE };
|
|
142
|
+
const interval = parseScheduleEvery(lead[1]);
|
|
143
|
+
if ('error' in interval)
|
|
144
|
+
return { kind: 'error', message: interval.error };
|
|
145
|
+
const task = lead[2].trim();
|
|
146
|
+
if (!task)
|
|
147
|
+
return { kind: 'error', message: 'Nothing to run — add a task after the interval.' };
|
|
148
|
+
return { kind: 'add', intervalMinutes: interval.minutes, task };
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=scheduleLines.js.map
|