@matteeh/osq 0.1.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/LICENSE +21 -0
- package/README.md +183 -0
- package/dist/cli/approve.d.ts +6 -0
- package/dist/cli/approve.d.ts.map +1 -0
- package/dist/cli/approve.js +26 -0
- package/dist/cli/approve.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +5 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +76 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +4 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +19 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/new.d.ts +4 -0
- package/dist/cli/new.d.ts.map +1 -0
- package/dist/cli/new.js +15 -0
- package/dist/cli/new.js.map +1 -0
- package/dist/cli/report.d.ts +10 -0
- package/dist/cli/report.d.ts.map +1 -0
- package/dist/cli/report.js +84 -0
- package/dist/cli/report.js.map +1 -0
- package/dist/cli/setup.d.ts +2 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +10 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli/show.d.ts +7 -0
- package/dist/cli/show.d.ts.map +1 -0
- package/dist/cli/show.js +27 -0
- package/dist/cli/show.js.map +1 -0
- package/dist/cli/status.d.ts +7 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +23 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/watch.d.ts +9 -0
- package/dist/cli/watch.d.ts.map +1 -0
- package/dist/cli/watch.js +20 -0
- package/dist/cli/watch.js.map +1 -0
- package/dist/core/approve.d.ts +11 -0
- package/dist/core/approve.d.ts.map +1 -0
- package/dist/core/approve.js +52 -0
- package/dist/core/approve.js.map +1 -0
- package/dist/core/config.d.ts +53 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +124 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/hasher.d.ts +4 -0
- package/dist/core/hasher.d.ts.map +1 -0
- package/dist/core/hasher.js +49 -0
- package/dist/core/hasher.js.map +1 -0
- package/dist/core/init.d.ts +12 -0
- package/dist/core/init.d.ts.map +1 -0
- package/dist/core/init.js +151 -0
- package/dist/core/init.js.map +1 -0
- package/dist/core/linter.d.ts +8 -0
- package/dist/core/linter.d.ts.map +1 -0
- package/dist/core/linter.js +100 -0
- package/dist/core/linter.js.map +1 -0
- package/dist/core/lock.d.ts +17 -0
- package/dist/core/lock.d.ts.map +1 -0
- package/dist/core/lock.js +104 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/logger.d.ts +32 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +106 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/new.d.ts +11 -0
- package/dist/core/new.d.ts.map +1 -0
- package/dist/core/new.js +79 -0
- package/dist/core/new.js.map +1 -0
- package/dist/core/parser.d.ts +32 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +87 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/report.d.ts +54 -0
- package/dist/core/report.d.ts.map +1 -0
- package/dist/core/report.js +475 -0
- package/dist/core/report.js.map +1 -0
- package/dist/core/show.d.ts +50 -0
- package/dist/core/show.d.ts.map +1 -0
- package/dist/core/show.js +374 -0
- package/dist/core/show.js.map +1 -0
- package/dist/core/state.d.ts +25 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +180 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/status.d.ts +10 -0
- package/dist/core/status.d.ts.map +1 -0
- package/dist/core/status.js +106 -0
- package/dist/core/status.js.map +1 -0
- package/dist/harness/agy.d.ts +31 -0
- package/dist/harness/agy.d.ts.map +1 -0
- package/dist/harness/agy.js +251 -0
- package/dist/harness/agy.js.map +1 -0
- package/dist/harness/index.d.ts +7 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +20 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/harness/mock.d.ts +19 -0
- package/dist/harness/mock.d.ts.map +1 -0
- package/dist/harness/mock.js +62 -0
- package/dist/harness/mock.js.map +1 -0
- package/dist/harness/opencode.d.ts +39 -0
- package/dist/harness/opencode.d.ts.map +1 -0
- package/dist/harness/opencode.js +394 -0
- package/dist/harness/opencode.js.map +1 -0
- package/dist/harness/process.d.ts +26 -0
- package/dist/harness/process.d.ts.map +1 -0
- package/dist/harness/process.js +99 -0
- package/dist/harness/process.js.map +1 -0
- package/dist/harness/stream.d.ts +34 -0
- package/dist/harness/stream.d.ts.map +1 -0
- package/dist/harness/stream.js +75 -0
- package/dist/harness/stream.js.map +1 -0
- package/dist/harness/types.d.ts +53 -0
- package/dist/harness/types.d.ts.map +1 -0
- package/dist/harness/types.js +10 -0
- package/dist/harness/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/watcher/archiver.d.ts +5 -0
- package/dist/watcher/archiver.d.ts.map +1 -0
- package/dist/watcher/archiver.js +66 -0
- package/dist/watcher/archiver.js.map +1 -0
- package/dist/watcher/loop.d.ts +34 -0
- package/dist/watcher/loop.d.ts.map +1 -0
- package/dist/watcher/loop.js +235 -0
- package/dist/watcher/loop.js.map +1 -0
- package/dist/watcher/runner.d.ts +70 -0
- package/dist/watcher/runner.d.ts.map +1 -0
- package/dist/watcher/runner.js +604 -0
- package/dist/watcher/runner.js.map +1 -0
- package/package.json +66 -0
- package/templates/.env.example +3 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/cli/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE5E,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAgF,EAAE;IAElF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAEzD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,SAAS,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type LogLevel } from '../core/logger.js';
|
|
2
|
+
export interface WatchCommandOptions {
|
|
3
|
+
once?: boolean;
|
|
4
|
+
verbose?: boolean;
|
|
5
|
+
quiet?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function resolveLogLevel(options: WatchCommandOptions): LogLevel;
|
|
8
|
+
export declare function watchCommand(options: WatchCommandOptions): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=watch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/cli/watch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAgB,MAAM,mBAAmB,CAAC;AAIhE,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,QAAQ,CAItE;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAO9E"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { loadConfig } from '../core/config.js';
|
|
2
|
+
import { createLogger } from '../core/logger.js';
|
|
3
|
+
import { getHarnessAdapter } from '../harness/index.js';
|
|
4
|
+
import { startWatcher } from '../watcher/loop.js';
|
|
5
|
+
export function resolveLogLevel(options) {
|
|
6
|
+
if (options.quiet)
|
|
7
|
+
return 'quiet';
|
|
8
|
+
if (options.verbose)
|
|
9
|
+
return 'verbose';
|
|
10
|
+
return 'normal';
|
|
11
|
+
}
|
|
12
|
+
export async function watchCommand(options) {
|
|
13
|
+
const cwd = process.cwd();
|
|
14
|
+
const config = await loadConfig(cwd);
|
|
15
|
+
const adapter = getHarnessAdapter(config.harness);
|
|
16
|
+
const logger = createLogger(resolveLogLevel(options), 'osq');
|
|
17
|
+
const watcherOptions = { ...options, logger };
|
|
18
|
+
await startWatcher(cwd, config, adapter, watcherOptions);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/cli/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAiB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAQlD,MAAM,UAAU,eAAe,CAAC,OAA4B;IAC1D,IAAI,OAAO,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC;IAClC,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACtC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,YAAY,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7D,MAAM,cAAc,GAAG,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,CAAC;IAC9C,MAAM,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { OsqConfig } from './config.js';
|
|
2
|
+
export declare function findSpecFolder(specsDir: string, idOrPrefix: string): Promise<string>;
|
|
3
|
+
export interface ApproveResult {
|
|
4
|
+
specId: string;
|
|
5
|
+
folderName: string;
|
|
6
|
+
folderPath: string;
|
|
7
|
+
hash: string;
|
|
8
|
+
warnings: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function approveSpec(projectRoot: string, specIdOrPrefix: string, config: OsqConfig): Promise<ApproveResult>;
|
|
11
|
+
//# sourceMappingURL=approve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../src/core/approve.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4B1F;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,aAAa,CAAC,CA4BxB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { hashChangeFolder } from './hasher.js';
|
|
4
|
+
import { lintChangeFolder } from './linter.js';
|
|
5
|
+
export async function findSpecFolder(specsDir, idOrPrefix) {
|
|
6
|
+
let entries = [];
|
|
7
|
+
try {
|
|
8
|
+
entries = await fs.readdir(specsDir);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
throw new Error(`Specs directory not found at ${specsDir}`);
|
|
12
|
+
}
|
|
13
|
+
const trimmed = idOrPrefix.trim();
|
|
14
|
+
const num = Number.parseInt(trimmed, 10);
|
|
15
|
+
const padded = !Number.isNaN(num) ? String(num).padStart(3, '0') : trimmed;
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
if (entry === trimmed ||
|
|
18
|
+
entry === padded ||
|
|
19
|
+
entry.startsWith(`${trimmed}-`) ||
|
|
20
|
+
entry.startsWith(`${padded}-`)) {
|
|
21
|
+
const fullPath = path.join(specsDir, entry);
|
|
22
|
+
const stat = await fs.stat(fullPath);
|
|
23
|
+
if (stat.isDirectory()) {
|
|
24
|
+
return fullPath;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`Spec "${idOrPrefix}" not found in ${specsDir}`);
|
|
29
|
+
}
|
|
30
|
+
export async function approveSpec(projectRoot, specIdOrPrefix, config) {
|
|
31
|
+
const specsDir = path.join(projectRoot, config.paths.specs);
|
|
32
|
+
const folderPath = await findSpecFolder(specsDir, specIdOrPrefix);
|
|
33
|
+
const folderName = path.basename(folderPath);
|
|
34
|
+
const specId = folderName.match(/^(\d+)/)?.[1] || folderName;
|
|
35
|
+
const lintResult = await lintChangeFolder(projectRoot, folderPath, config);
|
|
36
|
+
if (!lintResult.valid) {
|
|
37
|
+
throw new Error(`Lint failed for spec "${folderName}":\n - ${lintResult.errors.join('\n - ')}`);
|
|
38
|
+
}
|
|
39
|
+
const hash = await hashChangeFolder(folderPath);
|
|
40
|
+
const runDir = path.join(folderPath, '.run');
|
|
41
|
+
await fs.mkdir(runDir, { recursive: true });
|
|
42
|
+
const approvedPath = path.join(runDir, 'approved');
|
|
43
|
+
await fs.writeFile(approvedPath, `${hash}\n`, 'utf8');
|
|
44
|
+
return {
|
|
45
|
+
specId,
|
|
46
|
+
folderName,
|
|
47
|
+
folderPath,
|
|
48
|
+
hash,
|
|
49
|
+
warnings: lintResult.warnings,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=approve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/core/approve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface OsqLimits {
|
|
2
|
+
readonly maxScopeFiles: number;
|
|
3
|
+
readonly maxFeatureWrites: number;
|
|
4
|
+
readonly maxContractTables: number;
|
|
5
|
+
readonly maxAcceptanceLines: number;
|
|
6
|
+
}
|
|
7
|
+
export interface OsqPaths {
|
|
8
|
+
readonly specs: string;
|
|
9
|
+
readonly archive: string;
|
|
10
|
+
readonly features: string;
|
|
11
|
+
readonly decisions: string;
|
|
12
|
+
readonly templates: string;
|
|
13
|
+
}
|
|
14
|
+
export interface OsqTimeouts {
|
|
15
|
+
readonly staleLockSeconds: number;
|
|
16
|
+
readonly taskTimeoutSeconds: number;
|
|
17
|
+
readonly verifyTimeoutSeconds: number;
|
|
18
|
+
}
|
|
19
|
+
export interface AgyConfig {
|
|
20
|
+
readonly model?: string;
|
|
21
|
+
readonly dangerouslySkipPermissions?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface OpencodeConfig {
|
|
24
|
+
readonly bin?: string;
|
|
25
|
+
readonly model?: string;
|
|
26
|
+
readonly agent?: string;
|
|
27
|
+
readonly variant?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface LogConfig {
|
|
30
|
+
readonly heartbeatSeconds?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface OsqConfig {
|
|
33
|
+
readonly harness: string;
|
|
34
|
+
readonly maxConcurrency: number;
|
|
35
|
+
readonly limits: OsqLimits;
|
|
36
|
+
readonly paths: OsqPaths;
|
|
37
|
+
readonly timeouts: OsqTimeouts;
|
|
38
|
+
readonly agy?: AgyConfig;
|
|
39
|
+
readonly opencode?: OpencodeConfig;
|
|
40
|
+
readonly log?: LogConfig;
|
|
41
|
+
}
|
|
42
|
+
export type OsqUserConfig = Partial<Omit<OsqConfig, 'limits' | 'paths' | 'timeouts' | 'agy' | 'opencode' | 'log'>> & {
|
|
43
|
+
readonly limits?: Partial<OsqLimits>;
|
|
44
|
+
readonly paths?: Partial<OsqPaths>;
|
|
45
|
+
readonly timeouts?: Partial<OsqTimeouts>;
|
|
46
|
+
readonly agy?: Partial<AgyConfig>;
|
|
47
|
+
readonly opencode?: Partial<OpencodeConfig>;
|
|
48
|
+
readonly log?: Partial<LogConfig>;
|
|
49
|
+
};
|
|
50
|
+
export declare const DEFAULT_CONFIG: OsqConfig;
|
|
51
|
+
export declare function defineConfig(config: OsqUserConfig): OsqConfig;
|
|
52
|
+
export declare function loadConfig(projectRoot: string): Promise<OsqConfig>;
|
|
53
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACvC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,0BAA0B,CAAC,EAAE,OAAO,CAAC;CAC/C;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC;CAC1B;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,CACjC,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,KAAK,GAAG,UAAU,GAAG,KAAK,CAAC,CAC9E,GAAG;IACF,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACzC,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5C,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,SAiC5B,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CA6B7D;AAED,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CA2DxE"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createJiti } from 'jiti';
|
|
4
|
+
export const DEFAULT_CONFIG = {
|
|
5
|
+
harness: 'agy',
|
|
6
|
+
maxConcurrency: 1,
|
|
7
|
+
agy: {
|
|
8
|
+
model: 'gemini-3.8-flash-high',
|
|
9
|
+
dangerouslySkipPermissions: true,
|
|
10
|
+
},
|
|
11
|
+
opencode: {
|
|
12
|
+
bin: 'opencode',
|
|
13
|
+
model: 'deepseek/deepseek-flash',
|
|
14
|
+
agent: 'osq-coder',
|
|
15
|
+
},
|
|
16
|
+
log: {
|
|
17
|
+
heartbeatSeconds: 60,
|
|
18
|
+
},
|
|
19
|
+
limits: {
|
|
20
|
+
maxScopeFiles: 8,
|
|
21
|
+
maxFeatureWrites: 2,
|
|
22
|
+
maxContractTables: 1,
|
|
23
|
+
maxAcceptanceLines: 7,
|
|
24
|
+
},
|
|
25
|
+
paths: {
|
|
26
|
+
specs: 'specs',
|
|
27
|
+
archive: 'specs/archive',
|
|
28
|
+
features: 'features',
|
|
29
|
+
decisions: 'decisions',
|
|
30
|
+
templates: 'templates',
|
|
31
|
+
},
|
|
32
|
+
timeouts: {
|
|
33
|
+
staleLockSeconds: 2700,
|
|
34
|
+
taskTimeoutSeconds: 1800,
|
|
35
|
+
verifyTimeoutSeconds: 600,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
export function defineConfig(config) {
|
|
39
|
+
return {
|
|
40
|
+
...DEFAULT_CONFIG,
|
|
41
|
+
...config,
|
|
42
|
+
agy: {
|
|
43
|
+
...DEFAULT_CONFIG.agy,
|
|
44
|
+
...(config.agy || {}),
|
|
45
|
+
},
|
|
46
|
+
opencode: {
|
|
47
|
+
...DEFAULT_CONFIG.opencode,
|
|
48
|
+
...(config.opencode || {}),
|
|
49
|
+
},
|
|
50
|
+
log: {
|
|
51
|
+
...DEFAULT_CONFIG.log,
|
|
52
|
+
...(config.log || {}),
|
|
53
|
+
},
|
|
54
|
+
limits: {
|
|
55
|
+
...DEFAULT_CONFIG.limits,
|
|
56
|
+
...(config.limits || {}),
|
|
57
|
+
},
|
|
58
|
+
paths: {
|
|
59
|
+
...DEFAULT_CONFIG.paths,
|
|
60
|
+
...(config.paths || {}),
|
|
61
|
+
},
|
|
62
|
+
timeouts: {
|
|
63
|
+
...DEFAULT_CONFIG.timeouts,
|
|
64
|
+
...(config.timeouts || {}),
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export async function loadConfig(projectRoot) {
|
|
69
|
+
try {
|
|
70
|
+
const envPath = path.join(projectRoot, '.env');
|
|
71
|
+
if (typeof process.loadEnvFile === 'function') {
|
|
72
|
+
process.loadEnvFile(envPath);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch { }
|
|
76
|
+
const configFiles = ['osq.config.ts', 'osq.config.js', 'osq.config.mjs'];
|
|
77
|
+
let userConfig = {};
|
|
78
|
+
for (const file of configFiles) {
|
|
79
|
+
const fullPath = path.join(projectRoot, file);
|
|
80
|
+
const exists = await fs
|
|
81
|
+
.stat(fullPath)
|
|
82
|
+
.then(() => true)
|
|
83
|
+
.catch(() => false);
|
|
84
|
+
if (exists) {
|
|
85
|
+
try {
|
|
86
|
+
const jiti = createJiti(import.meta.url, {
|
|
87
|
+
moduleCache: false,
|
|
88
|
+
interopDefault: true,
|
|
89
|
+
});
|
|
90
|
+
const loaded = await jiti.import(fullPath);
|
|
91
|
+
const resolved = loaded?.default || loaded;
|
|
92
|
+
if (typeof resolved === 'object' && resolved !== null) {
|
|
93
|
+
userConfig = resolved;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
if (process.env.DEBUG_OSQ) {
|
|
98
|
+
console.error(`Warning: Failed to load config from ${file}:`, err);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const harness = userConfig.harness || process.env.OSQ_HARNESS || DEFAULT_CONFIG.harness;
|
|
105
|
+
const model = userConfig.agy?.model || process.env.OSQ_MODEL || DEFAULT_CONFIG.agy?.model;
|
|
106
|
+
const opencodeModel = userConfig.opencode?.model ||
|
|
107
|
+
(harness === 'opencode' && process.env.OSQ_MODEL ? process.env.OSQ_MODEL : undefined) ||
|
|
108
|
+
DEFAULT_CONFIG.opencode?.model;
|
|
109
|
+
return defineConfig({
|
|
110
|
+
...userConfig,
|
|
111
|
+
harness,
|
|
112
|
+
agy: {
|
|
113
|
+
...DEFAULT_CONFIG.agy,
|
|
114
|
+
...(userConfig.agy || {}),
|
|
115
|
+
...(model ? { model } : {}),
|
|
116
|
+
},
|
|
117
|
+
opencode: {
|
|
118
|
+
...DEFAULT_CONFIG.opencode,
|
|
119
|
+
...(userConfig.opencode || {}),
|
|
120
|
+
...(opencodeModel ? { model: opencodeModel } : {}),
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function normalizeTasksMd(content: string): string;
|
|
2
|
+
export declare function hashChangeFolder(folderPath: string): Promise<string>;
|
|
3
|
+
export declare function verifyFolderHash(folderPath: string, expectedHash: string): Promise<boolean>;
|
|
4
|
+
//# sourceMappingURL=hasher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hasher.d.ts","sourceRoot":"","sources":["../../src/core/hasher.ts"],"names":[],"mappings":"AA0BA,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB1E;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGjG"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
async function collectFiles(dir, baseDir) {
|
|
5
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
6
|
+
const files = [];
|
|
7
|
+
for (const entry of entries) {
|
|
8
|
+
if (entry.name === '.run' || entry.name === '.git' || entry.name === '.DS_Store') {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
const fullPath = path.join(dir, entry.name);
|
|
12
|
+
if (entry.isDirectory()) {
|
|
13
|
+
const nested = await collectFiles(fullPath, baseDir);
|
|
14
|
+
files.push(...nested);
|
|
15
|
+
}
|
|
16
|
+
else if (entry.isFile()) {
|
|
17
|
+
const relPath = path.relative(baseDir, fullPath).replace(/\\/g, '/');
|
|
18
|
+
files.push(relPath);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return files;
|
|
22
|
+
}
|
|
23
|
+
export function normalizeTasksMd(content) {
|
|
24
|
+
const lfContent = content.replace(/\r\n/g, '\n');
|
|
25
|
+
return lfContent.replace(/^(\s*-\s*\[)[xX](\])/gm, (_m, p1, p2) => `${p1} ${p2}`);
|
|
26
|
+
}
|
|
27
|
+
export async function hashChangeFolder(folderPath) {
|
|
28
|
+
const relFiles = await collectFiles(folderPath, folderPath);
|
|
29
|
+
relFiles.sort();
|
|
30
|
+
const hash = crypto.createHash('sha256');
|
|
31
|
+
for (const relFile of relFiles) {
|
|
32
|
+
const fullPath = path.join(folderPath, relFile);
|
|
33
|
+
const content = await fs.readFile(fullPath, 'utf8');
|
|
34
|
+
let normalizedContent = content.replace(/\r\n/g, '\n');
|
|
35
|
+
if (relFile === 'tasks.md') {
|
|
36
|
+
normalizedContent = normalizeTasksMd(normalizedContent);
|
|
37
|
+
}
|
|
38
|
+
hash.update(relFile);
|
|
39
|
+
hash.update('\0');
|
|
40
|
+
hash.update(normalizedContent);
|
|
41
|
+
hash.update('\0');
|
|
42
|
+
}
|
|
43
|
+
return `sha256:${hash.digest('hex')}`;
|
|
44
|
+
}
|
|
45
|
+
export async function verifyFolderHash(folderPath, expectedHash) {
|
|
46
|
+
const currentHash = await hashChangeFolder(folderPath);
|
|
47
|
+
return currentHash === expectedHash.trim();
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=hasher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hasher.js","sourceRoot":"","sources":["../../src/core/hasher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const OSQ_START_MARKER = "<!-- OSQ:START -->";
|
|
2
|
+
export declare const OSQ_END_MARKER = "<!-- OSQ:END -->";
|
|
3
|
+
export declare const MANAGED_AGENTS_BLOCK = "<!-- OSQ:START -->\n## Executing a spec\n\n1. Read your task file, its parent `spec.md`, then only the docs listed under `features`. Nothing else.\n2. Too big for one pass? Write why in `.run/results/<n>.md`, exit without code.\n3. Read a previous result file for this task if present. Run the task's `verify`. Start from what fails.\n4. Tests for each acceptance line before implementing.\n5. Minimal code to pass. Stay inside `scope`.\n6. Run the task's `verify` command before exiting.\n\n## Exiting\n\nWrite `.run/results/<n>.md` first: changed, deviated, drift against `features/`, missing context, and for unfinished work which acceptance line is next. Omit empty sections. Then exit. One attempt. Never write to `features/`, `tasks.md`, or anything in `specs/` outside `.run/results/`. Do not ask questions.\n<!-- OSQ:END -->";
|
|
4
|
+
export interface InitResult {
|
|
5
|
+
createdDirs: string[];
|
|
6
|
+
createdFiles: string[];
|
|
7
|
+
skippedFiles: string[];
|
|
8
|
+
updatedAgentsMd: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function updateAgentsMd(targetDir: string): Promise<boolean>;
|
|
11
|
+
export declare function scaffoldProject(targetDir: string): Promise<InitResult>;
|
|
12
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/core/init.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AACrD,eAAO,MAAM,cAAc,qBAAqB,CAAC;AAEjD,eAAO,MAAM,oBAAoB,q0BAaf,CAAC;AAyDnB,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiCxE;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAsD5E"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export const OSQ_START_MARKER = '<!-- OSQ:START -->';
|
|
4
|
+
export const OSQ_END_MARKER = '<!-- OSQ:END -->';
|
|
5
|
+
export const MANAGED_AGENTS_BLOCK = `${OSQ_START_MARKER}
|
|
6
|
+
## Executing a spec
|
|
7
|
+
|
|
8
|
+
1. Read your task file, its parent \`spec.md\`, then only the docs listed under \`features\`. Nothing else.
|
|
9
|
+
2. Too big for one pass? Write why in \`.run/results/<n>.md\`, exit without code.
|
|
10
|
+
3. Read a previous result file for this task if present. Run the task's \`verify\`. Start from what fails.
|
|
11
|
+
4. Tests for each acceptance line before implementing.
|
|
12
|
+
5. Minimal code to pass. Stay inside \`scope\`.
|
|
13
|
+
6. Run the task's \`verify\` command before exiting.
|
|
14
|
+
|
|
15
|
+
## Exiting
|
|
16
|
+
|
|
17
|
+
Write \`.run/results/<n>.md\` first: changed, deviated, drift against \`features/\`, missing context, and for unfinished work which acceptance line is next. Omit empty sections. Then exit. One attempt. Never write to \`features/\`, \`tasks.md\`, or anything in \`specs/\` outside \`.run/results/\`. Do not ask questions.
|
|
18
|
+
${OSQ_END_MARKER}`;
|
|
19
|
+
const TEMPLATE_SPEC_MD = `---
|
|
20
|
+
title: Change title
|
|
21
|
+
depends_on: []
|
|
22
|
+
features:
|
|
23
|
+
reads: []
|
|
24
|
+
writes: []
|
|
25
|
+
---
|
|
26
|
+
## Goal
|
|
27
|
+
|
|
28
|
+
What problem this change solves and why.
|
|
29
|
+
|
|
30
|
+
## Contract
|
|
31
|
+
|
|
32
|
+
| Input | Expected Output |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Sample input | Sample output |
|
|
35
|
+
|
|
36
|
+
## Non-goals
|
|
37
|
+
|
|
38
|
+
What this change deliberately does not do.
|
|
39
|
+
|
|
40
|
+
## Delta
|
|
41
|
+
|
|
42
|
+
What changes in each doc under features.writes. Applied by the watcher when the last task is done.
|
|
43
|
+
`;
|
|
44
|
+
const TEMPLATE_TASKS_MD = `# Tasks
|
|
45
|
+
|
|
46
|
+
- [ ] 1. When initial condition, expected outcome
|
|
47
|
+
`;
|
|
48
|
+
const TEMPLATE_TASK_1_MD = `---
|
|
49
|
+
title: When initial condition, expected outcome
|
|
50
|
+
verify: node -e "process.exit(0)"
|
|
51
|
+
scope: []
|
|
52
|
+
entry: []
|
|
53
|
+
skills: []
|
|
54
|
+
---
|
|
55
|
+
## Acceptance
|
|
56
|
+
- [ ] Acceptance criterion 1
|
|
57
|
+
`;
|
|
58
|
+
const DEFAULT_CONFIG_CONTENT = `import { defineConfig } from '@matteeh/osq';
|
|
59
|
+
|
|
60
|
+
export default defineConfig({
|
|
61
|
+
harness: process.env.OSQ_HARNESS || 'agy',
|
|
62
|
+
maxConcurrency: 1,
|
|
63
|
+
});
|
|
64
|
+
`;
|
|
65
|
+
const DEFAULT_ENV_EXAMPLE = `OSQ_HARNESS=agy
|
|
66
|
+
# GEMINI_API_KEY=
|
|
67
|
+
# ANTHROPIC_API_KEY=
|
|
68
|
+
`;
|
|
69
|
+
export async function updateAgentsMd(targetDir) {
|
|
70
|
+
const agentsPath = path.join(targetDir, 'AGENTS.md');
|
|
71
|
+
const exists = await fs
|
|
72
|
+
.stat(agentsPath)
|
|
73
|
+
.then(() => true)
|
|
74
|
+
.catch(() => false);
|
|
75
|
+
if (!exists) {
|
|
76
|
+
const initialContent = `# AGENTS\n\n${MANAGED_AGENTS_BLOCK}\n`;
|
|
77
|
+
await fs.writeFile(agentsPath, initialContent, 'utf8');
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
const currentContent = await fs.readFile(agentsPath, 'utf8');
|
|
81
|
+
const startIndex = currentContent.indexOf(OSQ_START_MARKER);
|
|
82
|
+
const endIndex = currentContent.indexOf(OSQ_END_MARKER);
|
|
83
|
+
if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
|
|
84
|
+
const before = currentContent.slice(0, startIndex);
|
|
85
|
+
const after = currentContent.slice(endIndex + OSQ_END_MARKER.length);
|
|
86
|
+
const updated = `${before}${MANAGED_AGENTS_BLOCK}${after}`;
|
|
87
|
+
await fs.writeFile(agentsPath, updated, 'utf8');
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const separator = currentContent.endsWith('\n\n')
|
|
91
|
+
? ''
|
|
92
|
+
: currentContent.endsWith('\n')
|
|
93
|
+
? '\n'
|
|
94
|
+
: '\n\n';
|
|
95
|
+
const updated = `${currentContent}${separator}${MANAGED_AGENTS_BLOCK}\n`;
|
|
96
|
+
await fs.writeFile(agentsPath, updated, 'utf8');
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
export async function scaffoldProject(targetDir) {
|
|
101
|
+
const result = {
|
|
102
|
+
createdDirs: [],
|
|
103
|
+
createdFiles: [],
|
|
104
|
+
skippedFiles: [],
|
|
105
|
+
updatedAgentsMd: false,
|
|
106
|
+
};
|
|
107
|
+
const dirsToCreate = [
|
|
108
|
+
'specs',
|
|
109
|
+
'specs/_template',
|
|
110
|
+
'specs/_template/tasks',
|
|
111
|
+
'specs/archive',
|
|
112
|
+
'features',
|
|
113
|
+
'decisions',
|
|
114
|
+
];
|
|
115
|
+
for (const relDir of dirsToCreate) {
|
|
116
|
+
const fullDir = path.join(targetDir, relDir);
|
|
117
|
+
const exists = await fs
|
|
118
|
+
.stat(fullDir)
|
|
119
|
+
.then(() => true)
|
|
120
|
+
.catch(() => false);
|
|
121
|
+
if (!exists) {
|
|
122
|
+
await fs.mkdir(fullDir, { recursive: true });
|
|
123
|
+
result.createdDirs.push(relDir);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const filesToCreate = [
|
|
127
|
+
{ relPath: 'osq.config.ts', content: DEFAULT_CONFIG_CONTENT },
|
|
128
|
+
{ relPath: '.env.example', content: DEFAULT_ENV_EXAMPLE },
|
|
129
|
+
{ relPath: path.join('specs', '_template', 'spec.md'), content: TEMPLATE_SPEC_MD },
|
|
130
|
+
{ relPath: path.join('specs', '_template', 'tasks.md'), content: TEMPLATE_TASKS_MD },
|
|
131
|
+
{ relPath: path.join('specs', '_template', 'tasks', '1.md'), content: TEMPLATE_TASK_1_MD },
|
|
132
|
+
];
|
|
133
|
+
for (const file of filesToCreate) {
|
|
134
|
+
const fullPath = path.join(targetDir, file.relPath);
|
|
135
|
+
const exists = await fs
|
|
136
|
+
.stat(fullPath)
|
|
137
|
+
.then(() => true)
|
|
138
|
+
.catch(() => false);
|
|
139
|
+
if (!exists) {
|
|
140
|
+
await fs.mkdir(path.dirname(fullPath), { recursive: true });
|
|
141
|
+
await fs.writeFile(fullPath, file.content, 'utf8');
|
|
142
|
+
result.createdFiles.push(file.relPath);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
result.skippedFiles.push(file.relPath);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
result.updatedAgentsMd = await updateAgentsMd(targetDir);
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/core/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { OsqConfig } from './config.js';
|
|
2
|
+
export interface LintResult {
|
|
3
|
+
readonly valid: boolean;
|
|
4
|
+
readonly errors: string[];
|
|
5
|
+
readonly warnings: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function lintChangeFolder(projectRoot: string, folderPath: string, config: OsqConfig): Promise<LintResult>;
|
|
8
|
+
//# sourceMappingURL=linter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linter.d.ts","sourceRoot":"","sources":["../../src/core/linter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;CAC7B;AA6BD,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,UAAU,CAAC,CAgGrB"}
|